feat: Initialize XtremFlow project with core structure, IPTV features, authentication, and video player.

This commit is contained in:
Michael committed 2025-12-05 09:17:11 +01:00
commit 2a28eb44d8
28 files changed
+3279

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
import 'package:hive/hive.dart';
part 'app_user.g.dart';
@HiveType(typeId: 0)
class AppUser {
@HiveField(0)
final String id;
@HiveField(1)
final String username;
@HiveField(2)
final String passwordHash; // SHA-256 hash
@HiveField(3)
final bool isAdmin;
@HiveField(4)
final List<String> assignedPlaylistIds;
@HiveField(5)
final DateTime createdAt;
const AppUser({
required this.id,
required this.username,
required this.passwordHash,
required this.isAdmin,
required this.assignedPlaylistIds,
required this.createdAt,
});
AppUser copyWith({
String? id,
String? username,
String? passwordHash,
bool? isAdmin,
List<String>? assignedPlaylistIds,
DateTime? createdAt,
}) {
return AppUser(
id: id ?? this.id,
username: username ?? this.username,
passwordHash: passwordHash ?? this.passwordHash,
isAdmin: isAdmin ?? this.isAdmin,
assignedPlaylistIds: assignedPlaylistIds ?? this.assignedPlaylistIds,
createdAt: createdAt ?? this.createdAt,
);
}
}
+56
View File
@@ -0,0 +1,56 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'app_user.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class AppUserAdapter extends TypeAdapter<AppUser> {
@override
final int typeId = 0;
@override
AppUser read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return AppUser(
id: fields[0] as String,
username: fields[1] as String,
passwordHash: fields[2] as String,
isAdmin: fields[3] as bool,
assignedPlaylistIds: (fields[4] as List).cast<String>(),
createdAt: fields[5] as DateTime,
);
}
@override
void write(BinaryWriter writer, AppUser obj) {
writer
..writeByte(6)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.username)
..writeByte(2)
..write(obj.passwordHash)
..writeByte(3)
..write(obj.isAdmin)
..writeByte(4)
..write(obj.assignedPlaylistIds)
..writeByte(5)
..write(obj.createdAt);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AppUserAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
+60
View File
@@ -0,0 +1,60 @@
import 'package:hive/hive.dart';
part 'playlist_config.g.dart';
@HiveType(typeId: 1)
class PlaylistConfig {
@HiveField(0)
final String id;
@HiveField(1)
final String name;
@HiveField(2)
final String dns; // Xtream server URL (without trailing slash)
@HiveField(3)
final String username;
@HiveField(4)
final String password; // Will be encrypted by Hive
@HiveField(5)
final DateTime createdAt;
@HiveField(6)
final bool isActive;
const PlaylistConfig({
required this.id,
required this.name,
required this.dns,
required this.username,
required this.password,
required this.createdAt,
this.isActive = true,
});
PlaylistConfig copyWith({
String? id,
String? name,
String? dns,
String? username,
String? password,
DateTime? createdAt,
bool? isActive,
}) {
return PlaylistConfig(
id: id ?? this.id,
name: name ?? this.name,
dns: dns ?? this.dns,
username: username ?? this.username,
password: password ?? this.password,
createdAt: createdAt ?? this.createdAt,
isActive: isActive ?? this.isActive,
);
}
/// Generate Xtream API base URL
String get apiBaseUrl => '$dns/player_api.php';
}
+59
View File
@@ -0,0 +1,59 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'playlist_config.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class PlaylistConfigAdapter extends TypeAdapter<PlaylistConfig> {
@override
final int typeId = 1;
@override
PlaylistConfig read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return PlaylistConfig(
id: fields[0] as String,
name: fields[1] as String,
dns: fields[2] as String,
username: fields[3] as String,
password: fields[4] as String,
createdAt: fields[5] as DateTime,
isActive: fields[6] as bool,
);
}
@override
void write(BinaryWriter writer, PlaylistConfig obj) {
writer
..writeByte(7)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.name)
..writeByte(2)
..write(obj.dns)
..writeByte(3)
..write(obj.username)
..writeByte(4)
..write(obj.password)
..writeByte(5)
..write(obj.createdAt)
..writeByte(6)
..write(obj.isActive);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PlaylistConfigAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}