Files
plezy/lib/utils/live_tv_grouping.dart
T
edde746 9429a76acc refactor: share search field, auth dialog, and list-download plumbing
The search screens, the out-of-band auth dialogs, the live TV guide and the
list-download paths each carried their own copy of the same shell. Extracts
SearchInputField and PendingAuthDialog and routes the duplicated download
and guide helpers through one implementation.
2026-07-26 06:09:49 +02:00

79 lines
2.5 KiB
Dart

import '../models/livetv_channel.dart';
import 'live_tv_matching.dart';
class LiveTvChannelGroup {
final String key;
final String label;
final List<LiveTvChannel> channels;
const LiveTvChannelGroup({required this.key, required this.label, required this.channels});
LiveTvChannelGroup copyWith({String? label}) {
return LiveTvChannelGroup(key: key, label: label ?? this.label, channels: channels);
}
}
List<LiveTvChannelGroup> groupLiveTvChannelsBySource(List<LiveTvChannel> channels) {
final order = <String>[];
final bySource = <String, List<LiveTvChannel>>{};
final labels = <String, String>{};
for (final channel in channels) {
final key = liveTvChannelSourceKey(channel);
if (!bySource.containsKey(key)) {
order.add(key);
bySource[key] = [];
labels[key] = liveTvChannelSourceLabel(channel);
}
bySource[key]!.add(channel);
}
final groups = [
for (final key in order)
LiveTvChannelGroup(key: key, label: labels[key]!, channels: List.unmodifiable(bySource[key]!)),
];
final labelCounts = <String, int>{};
for (final group in groups) {
labelCounts[group.label] = (labelCounts[group.label] ?? 0) + 1;
}
return [
for (final group in groups)
if ((labelCounts[group.label] ?? 0) > 1) group.copyWith(label: _deduplicatedLabel(group)) else group,
];
}
String liveTvChannelSourceKey(LiveTvChannel channel) {
final serverId = liveTvNonEmpty(channel.serverId) ?? '';
final providerSource = liveTvNonEmpty(channel.favoriteSource) ?? liveTvNonEmpty(channel.lineup) ?? '';
final dvrSource = liveTvNonEmpty(channel.liveDvrKey) ?? '';
return '$serverId\u0000$providerSource\u0000$dvrSource';
}
String liveTvChannelSourceLabel(LiveTvChannel channel) {
final serverLabel = liveTvNonEmpty(channel.serverName) ?? liveTvNonEmpty(channel.serverId) ?? 'Live TV';
final sourceTitle = liveTvNonEmpty(channel.liveTvSourceTitle);
if (sourceTitle == null || sourceTitle == serverLabel) return serverLabel;
return '$serverLabel - $sourceTitle';
}
String _deduplicatedLabel(LiveTvChannelGroup group) {
if (group.channels.isEmpty) return group.label;
final first = group.channels.first;
final suffixes = [
liveTvNonEmpty(first.liveTvSourceTitle),
liveTvNonEmpty(first.liveDvrKey),
liveTvProviderIdentifierForChannel(first),
];
String? suffix;
for (final value in suffixes) {
if (value != null && !group.label.contains(value)) {
suffix = value;
break;
}
}
if (suffix == null || group.label.contains(suffix)) return group.label;
return '${group.label} - $suffix';
}