feat: Android TV support (#503)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2025-09-28 21:07:49 +02:00 committed by GitHub
parent 7ab8c015b9
commit c299492d6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
168 changed files with 12019 additions and 3073 deletions

View file

@ -10,6 +10,7 @@ import 'package:fladder/screens/settings/widgets/settings_label_divider.dart';
import 'package:fladder/screens/settings/widgets/settings_list_group.dart';
import 'package:fladder/util/localization_helper.dart';
import 'package:fladder/widgets/shared/enum_selection.dart';
import 'package:fladder/widgets/shared/item_actions.dart';
List<Widget> buildClientSettingsDashboard(BuildContext context, WidgetRef ref) {
final clientSettings = ref.watch(clientSettingsProvider);
@ -28,10 +29,9 @@ List<Widget> buildClientSettingsDashboard(BuildContext context, WidgetRef ref) {
),
itemBuilder: (context) => HomeBanner.values
.map(
(entry) => PopupMenuItem(
value: entry,
child: Text(entry.label(context)),
onTap: () =>
(entry) => ItemActionButton(
label: Text(entry.label(context)),
action: () =>
ref.read(homeSettingsProvider.notifier).update((context) => context.copyWith(homeBanner: entry)),
),
)
@ -48,10 +48,9 @@ List<Widget> buildClientSettingsDashboard(BuildContext context, WidgetRef ref) {
),
itemBuilder: (context) => HomeCarouselSettings.values
.map(
(entry) => PopupMenuItem(
value: entry,
child: Text(entry.label(context)),
onTap: () => ref
(entry) => ItemActionButton(
label: Text(entry.label(context)),
action: () => ref
.read(homeSettingsProvider.notifier)
.update((context) => context.copyWith(carouselSettings: entry)),
),
@ -70,10 +69,9 @@ List<Widget> buildClientSettingsDashboard(BuildContext context, WidgetRef ref) {
),
itemBuilder: (context) => HomeNextUp.values
.map(
(entry) => PopupMenuItem(
value: entry,
child: Text(entry.label(context)),
onTap: () =>
(entry) => ItemActionButton(
label: Text(entry.label(context)),
action: () =>
ref.read(homeSettingsProvider.notifier).update((context) => context.copyWith(nextUp: entry)),
),
)

View file

@ -89,6 +89,21 @@ List<Widget> buildClientSettingsDownload(BuildContext context, WidgetRef ref, Fu
return SettingsListTile(
label: Text(context.localized.downloadsSyncedData),
subLabel: Text(data.byteFormat ?? ""),
onTap: () {
showDefaultAlertDialog(
context,
context.localized.downloadsClearTitle,
context.localized.downloadsClearDesc,
(context) async {
await ref.read(syncProvider.notifier).removeAllSyncedData();
setState(() {});
Navigator.of(context).pop();
},
context.localized.clear,
(context) => Navigator.of(context).pop(),
context.localized.cancel,
);
},
trailing: FilledButton(
onPressed: () {
showDefaultAlertDialog(
@ -123,21 +138,22 @@ List<Widget> buildClientSettingsDownload(BuildContext context, WidgetRef ref, Fu
label: Text(context.localized.maxConcurrentDownloadsTitle),
subLabel: Text(context.localized.maxConcurrentDownloadsDesc),
trailing: SizedBox(
width: 100,
child: IntInputField(
controller: TextEditingController(text: clientSettings.maxConcurrentDownloads.toString()),
onSubmitted: (value) {
if (value != null) {
ref.read(clientSettingsProvider.notifier).update(
(current) => current.copyWith(
maxConcurrentDownloads: value,
),
);
width: 150,
child: IntInputField(
controller: TextEditingController(text: clientSettings.maxConcurrentDownloads.toString()),
onSubmitted: (value) {
if (value != null) {
ref.read(clientSettingsProvider.notifier).update(
(current) => current.copyWith(
maxConcurrentDownloads: value,
),
);
ref.read(backgroundDownloaderProvider.notifier).setMaxConcurrent(value);
}
},
)),
ref.read(backgroundDownloaderProvider.notifier).setMaxConcurrent(value);
}
},
),
),
),
]),
const SizedBox(height: 12),

View file

@ -13,6 +13,7 @@ import 'package:fladder/util/adaptive_layout/adaptive_layout.dart';
import 'package:fladder/util/localization_helper.dart';
import 'package:fladder/widgets/shared/enum_selection.dart';
import 'package:fladder/widgets/shared/fladder_slider.dart';
import 'package:fladder/widgets/shared/item_actions.dart';
List<Widget> buildClientSettingsVisual(
BuildContext context,
@ -41,16 +42,15 @@ List<Widget> buildClientSettingsVisual(
itemBuilder: (context) {
return [
...AppLocalizations.supportedLocales.map(
(entry) => PopupMenuItem(
value: entry,
child: Localizations.override(
(entry) => ItemActionButton(
label: Localizations.override(
context: context,
locale: entry,
child: Builder(builder: (context) {
return Text("${context.localized.nativeName} (${entry.toDisplayCode()})");
}),
),
onTap: () => ref
action: () => ref
.read(clientSettingsProvider.notifier)
.update((state) => state.copyWith(selectedLocale: entry)),
),
@ -95,10 +95,9 @@ List<Widget> buildClientSettingsVisual(
current: clientSettings.backgroundImage.label(context),
itemBuilder: (context) => BackgroundType.values
.map(
(e) => PopupMenuItem(
value: e,
child: Text(e.label(context)),
onTap: () =>
(e) => ItemActionButton(
label: Text(e.label(context)),
action: () =>
ref.read(clientSettingsProvider.notifier).update((cb) => cb.copyWith(backgroundImage: e)),
),
)