added Information-Field to TV Shows
This commit is contained in:
@@ -254,6 +254,7 @@ class BackendApi {
|
||||
String? resolution,
|
||||
String? downloadPath,
|
||||
bool? cliffhanger,
|
||||
String? information,
|
||||
}) async {
|
||||
final payload = <String, dynamic>{
|
||||
'action': 'set_show_meta',
|
||||
@@ -261,6 +262,7 @@ class BackendApi {
|
||||
if (resolution != null) 'resolution': resolution,
|
||||
if (downloadPath != null) 'download_path': downloadPath,
|
||||
if (cliffhanger != null) 'cliffhanger': cliffhanger,
|
||||
if (information != null) 'information': information,
|
||||
};
|
||||
await _post(payload);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class EpisodeItem {
|
||||
final String? posterPath;
|
||||
final int? showId;
|
||||
final String? downloadPath;
|
||||
final String? showInformation;
|
||||
|
||||
EpisodeItem({
|
||||
required this.id,
|
||||
@@ -31,6 +32,7 @@ class EpisodeItem {
|
||||
this.posterPath,
|
||||
this.showId,
|
||||
this.downloadPath,
|
||||
this.showInformation,
|
||||
});
|
||||
|
||||
factory EpisodeItem.fromJson(Map<String, dynamic> j) => EpisodeItem(
|
||||
@@ -48,6 +50,7 @@ class EpisodeItem {
|
||||
posterPath: j['poster_path'] as String?,
|
||||
showId: (j['show_id'] as num?)?.toInt(),
|
||||
downloadPath: j['download_path'] as String?,
|
||||
showInformation: j['show_information'] as String?,
|
||||
);
|
||||
|
||||
static bool? _parseBool(dynamic v) {
|
||||
|
||||
@@ -46,7 +46,10 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
String? _origResolution;
|
||||
String? _origDownloadPath;
|
||||
bool? _origCliffhanger;
|
||||
String? _information;
|
||||
String? _origInformation;
|
||||
late final TextEditingController _downloadCtrl;
|
||||
late final TextEditingController _infoCtrl;
|
||||
String? _overview;
|
||||
List<Map<String, dynamic>> _cast = const [];
|
||||
List<Map<String, dynamic>> _crew = const [];
|
||||
@@ -63,6 +66,13 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
setState(() => _downloadPath = v);
|
||||
}
|
||||
});
|
||||
_infoCtrl = TextEditingController(text: _information ?? '');
|
||||
_infoCtrl.addListener(() {
|
||||
final v = _infoCtrl.text;
|
||||
if (v != (_information ?? '')) {
|
||||
setState(() => _information = v);
|
||||
}
|
||||
});
|
||||
// Quick-fill from seasonsEps for instant UI while fetching real data
|
||||
if (widget.seasonsEps != null && widget.seasonsEps!.isNotEmpty) {
|
||||
final map = <int, List<EpisodeItem>>{};
|
||||
@@ -93,6 +103,13 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
_load();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_downloadCtrl.dispose();
|
||||
_infoCtrl.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
try {
|
||||
int? showId = widget.showId;
|
||||
@@ -120,13 +137,18 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
_resolution ??= first.resolution;
|
||||
_downloadPath ??= first.downloadPath;
|
||||
_cliffhanger ??= first.showCliffhanger;
|
||||
_information ??= first.showInformation;
|
||||
_showId ??= first.showId ?? showId;
|
||||
_origResolution ??= _resolution;
|
||||
_origDownloadPath ??= _downloadPath;
|
||||
_origCliffhanger ??= _cliffhanger;
|
||||
_origInformation ??= _information;
|
||||
if (_downloadCtrl.text != (_downloadPath ?? '')) {
|
||||
_downloadCtrl.text = _downloadPath ?? '';
|
||||
}
|
||||
if (_infoCtrl.text != (_information ?? '')) {
|
||||
_infoCtrl.text = _information ?? '';
|
||||
}
|
||||
if (first.showJson != null && first.showJson!.isNotEmpty) {
|
||||
try {
|
||||
final m = jsonDecode(first.showJson!) as Map<String, dynamic>;
|
||||
@@ -178,12 +200,14 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
futures.add(api.setStatus(type: 'episode', refId: epId, status: st.name));
|
||||
});
|
||||
// show meta
|
||||
if (_showId != null && (_resolution != _origResolution || _downloadPath != _origDownloadPath || _cliffhanger != _origCliffhanger)) {
|
||||
final infoChanged = _information != _origInformation;
|
||||
if (_showId != null && (_resolution != _origResolution || _downloadPath != _origDownloadPath || _cliffhanger != _origCliffhanger || infoChanged)) {
|
||||
futures.add(api.setShowMeta(
|
||||
showId: _showId!,
|
||||
resolution: _resolution,
|
||||
downloadPath: _downloadPath,
|
||||
cliffhanger: _cliffhanger,
|
||||
information: infoChanged ? _information : null,
|
||||
));
|
||||
}
|
||||
await Future.wait(futures);
|
||||
@@ -202,6 +226,7 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
_origResolution = _resolution;
|
||||
_origDownloadPath = _downloadPath;
|
||||
_origCliffhanger = _cliffhanger;
|
||||
_origInformation = _information;
|
||||
});
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Gespeichert')));
|
||||
}
|
||||
@@ -240,6 +265,7 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
posterPath: it.posterPath,
|
||||
showId: it.showId,
|
||||
downloadPath: it.downloadPath,
|
||||
showInformation: it.showInformation,
|
||||
))
|
||||
.toList()
|
||||
: e.value,
|
||||
@@ -257,7 +283,8 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
final dirty = _pending.isNotEmpty ||
|
||||
_resolution != _origResolution ||
|
||||
_downloadPath != _origDownloadPath ||
|
||||
_cliffhanger != _origCliffhanger;
|
||||
_cliffhanger != _origCliffhanger ||
|
||||
_information != _origInformation;
|
||||
return PopScope(
|
||||
canPop: true,
|
||||
onPopInvokedWithResult: (didPop, result) async {
|
||||
@@ -535,6 +562,18 @@ class _SeriesDetailScreenState extends ConsumerState<SeriesDetailScreen> {
|
||||
focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.white)),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _infoCtrl,
|
||||
style: const TextStyle(color: Colors.white),
|
||||
maxLines: 3,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Information',
|
||||
labelStyle: TextStyle(color: Colors.white70),
|
||||
enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.white54)),
|
||||
focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.white)),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
|
||||
@@ -154,6 +154,26 @@ function gameHasColumn(string $col): bool {
|
||||
return in_array($col, gameColumns(), true);
|
||||
}
|
||||
|
||||
function showColumns(): array {
|
||||
static $cols = null;
|
||||
if ($cols !== null) return $cols;
|
||||
$cols = [];
|
||||
try {
|
||||
$pdo = getDb();
|
||||
$stmt = $pdo->query('DESCRIBE shows');
|
||||
foreach ($stmt as $row) {
|
||||
if (isset($row['Field'])) $cols[] = $row['Field'];
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$cols = [];
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
function showHasColumn(string $col): bool {
|
||||
return in_array($col, showColumns(), true);
|
||||
}
|
||||
|
||||
function getLocalization(int $igdbId, string $lang = 'de'): ?array {
|
||||
$pdo = getDb();
|
||||
$stmt = $pdo->prepare('SELECT * FROM igdb_localizations WHERE igdb_id = :id AND lang = :lang LIMIT 1');
|
||||
@@ -1007,6 +1027,8 @@ try {
|
||||
$s = strtolower($status);
|
||||
if ($s==='init') $statusVal = 0; elseif ($s==='progress') $statusVal = 1; elseif ($s==='done') $statusVal = 2;
|
||||
}
|
||||
$hasInfo = showHasColumn('information');
|
||||
$infoSelect = $hasInfo ? 'sh.information AS show_information' : 'NULL AS show_information';
|
||||
$base = "FROM episodes e
|
||||
JOIN seasons se ON se.id = e.season_id
|
||||
JOIN shows sh ON sh.id = se.show_id
|
||||
@@ -1018,6 +1040,7 @@ try {
|
||||
sh.poster_path AS poster_path,
|
||||
sh.id AS show_id,
|
||||
sh.download_path AS download_path,
|
||||
".$infoSelect.",
|
||||
JSON_UNQUOTE(JSON_EXTRACT(sh.json, '$.status')) AS show_status,
|
||||
sh.cliffhanger AS show_cliffhanger,
|
||||
sh.json AS show_json,
|
||||
@@ -1029,6 +1052,7 @@ try {
|
||||
sh.poster_path AS poster_path,
|
||||
sh.id AS show_id,
|
||||
sh.download_path AS download_path,
|
||||
".$infoSelect.",
|
||||
sh.cliffhanger AS show_cliffhanger,
|
||||
sh.json AS show_json,
|
||||
se.season_number, sh.name AS show_name ".$base;
|
||||
@@ -1176,6 +1200,8 @@ try {
|
||||
case 'get_show_episodes': {
|
||||
$showId = (int)($in['show_id'] ?? 0);
|
||||
if (!$showId) fail('bad params');
|
||||
$hasInfo = showHasColumn('information');
|
||||
$infoSelect = $hasInfo ? 'sh.information AS show_information' : 'NULL AS show_information';
|
||||
$base = "FROM episodes e
|
||||
JOIN seasons se ON se.id = e.season_id
|
||||
JOIN shows sh ON sh.id = se.show_id
|
||||
@@ -1186,6 +1212,7 @@ try {
|
||||
sh.poster_path AS poster_path,
|
||||
sh.id AS show_id,
|
||||
sh.download_path AS download_path,
|
||||
".$infoSelect.",
|
||||
JSON_UNQUOTE(JSON_EXTRACT(sh.json, '$.status')) AS show_status,
|
||||
sh.cliffhanger AS show_cliffhanger,
|
||||
sh.json AS show_json,
|
||||
@@ -1197,6 +1224,7 @@ try {
|
||||
sh.poster_path AS poster_path,
|
||||
sh.id AS show_id,
|
||||
sh.download_path AS download_path,
|
||||
".$infoSelect.",
|
||||
sh.cliffhanger AS show_cliffhanger,
|
||||
sh.json AS show_json,
|
||||
se.season_number, sh.name AS show_name ".$base.
|
||||
@@ -1324,9 +1352,15 @@ try {
|
||||
if (!$showId) fail('bad params');
|
||||
$fields = [];
|
||||
$params = [];
|
||||
$hasInfo = showHasColumn('information');
|
||||
if (isset($in['resolution'])) { $fields[] = 'resolution = ?'; $params[] = $in['resolution']; }
|
||||
if (array_key_exists('download_path', $in)) { $fields[] = 'download_path = ?'; $params[] = $in['download_path']; }
|
||||
if (isset($in['cliffhanger'])) { $fields[] = 'cliffhanger = ?'; $params[] = (int)!!$in['cliffhanger']; }
|
||||
if (array_key_exists('information', $in)) {
|
||||
if (!$hasInfo) fail('shows.information column missing');
|
||||
$fields[] = 'information = ?';
|
||||
$params[] = $in['information'];
|
||||
}
|
||||
if (empty($fields)) fail('no fields');
|
||||
$sql = 'UPDATE shows SET '.implode(', ', $fields).' WHERE id = ?';
|
||||
$params[] = $showId;
|
||||
|
||||
Reference in New Issue
Block a user