subtracks/lib/app/screens/settings_screen.dart
2025-11-18 19:01:25 +09:00

425 lines
12 KiB
Dart

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../l10n/generated/app_localizations.dart';
const kHorizontalPadding = 16.0;
class SettingsScreen extends HookConsumerWidget {
const SettingsScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
return Scaffold(
body: ListView(
children: [
const SizedBox(height: 96),
_SectionHeader(l.settingsServersName),
// const _Sources(),
// _SectionHeader(l.settingsNetworkName),
// const _Network(),
// _SectionHeader(l.settingsAboutName),
// _About(),
],
),
);
}
}
class _Section extends StatelessWidget {
final List<Widget> children;
const _Section({required this.children});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
...children,
const SizedBox(height: 32),
],
);
}
}
class _SectionHeader extends StatelessWidget {
final String title;
const _SectionHeader(this.title);
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
children: [
SizedBox(
width: double.infinity,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: kHorizontalPadding),
child: Text(
title,
style: theme.textTheme.displaySmall,
),
),
),
const SizedBox(height: 12),
],
);
}
}
// class _Network extends StatelessWidget {
// const _Network();
// @override
// Widget build(BuildContext context) {
// return const _Section(
// children: [
// _OfflineMode(),
// _MaxBitrateWifi(),
// _MaxBitrateMobile(),
// _StreamFormat(),
// ],
// );
// }
// }
// class _About extends HookConsumerWidget {
// _About();
// final _homepage = Uri.parse('https://github.com/austinried/subtracks');
// final _donate = Uri.parse('https://ko-fi.com/austinried');
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final l = AppLocalizations.of(context);
// final pkg = ref.watch(packageInfoProvider).requireValue;
// return _Section(
// children: [
// ListTile(
// title: const Text('subtracks'),
// subtitle: Text(l.settingsAboutVersion(pkg.version)),
// ),
// ListTile(
// title: Text(l.settingsAboutActionsLicenses),
// // trailing: const Icon(Icons.open_in_new_rounded),
// onTap: () {},
// ),
// ListTile(
// title: Text(l.settingsAboutActionsProjectHomepage),
// subtitle: Text(_homepage.toString()),
// trailing: const Icon(Icons.open_in_new_rounded),
// onTap: () => launchUrl(
// _homepage,
// mode: LaunchMode.externalApplication,
// ),
// ),
// ListTile(
// title: Text(l.settingsAboutActionsSupport),
// subtitle: Text(_donate.toString()),
// trailing: const Icon(Icons.open_in_new_rounded),
// onTap: () => launchUrl(
// _donate,
// mode: LaunchMode.externalApplication,
// ),
// ),
// const SizedBox(height: 12),
// const _ShareLogsButton(),
// ],
// );
// }
// }
// class _ShareLogsButton extends StatelessWidget {
// const _ShareLogsButton();
// @override
// Widget build(BuildContext context) {
// final l = AppLocalizations.of(context);
// return Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// OutlinedButton.icon(
// icon: const Icon(Icons.share),
// label: Text(l.settingsAboutShareLogs),
// onPressed: () async {
// final files = await logFiles();
// if (files.isEmpty) return;
// // ignore: use_build_context_synchronously
// final value = await showDialog<String>(
// context: context,
// builder: (context) => MultipleChoiceDialog<String>(
// title: l.settingsAboutChooseLog,
// current: files.first.path,
// options: files
// .map(
// (e) => MultiChoiceOption.string(
// title: path.basename(e.path),
// option: e.path,
// ),
// )
// .toIList(),
// ),
// );
// if (value == null) return;
// Share.shareXFiles(
// [XFile(value, mimeType: 'text/plain')],
// subject:
// 'Logs from subtracks: ${String.fromCharCodes(
// List.generate(8, (_) => Random().nextInt(26) + 65),
// )}',
// );
// },
// ),
// ],
// );
// }
// }
// class _MaxBitrateWifi extends HookConsumerWidget {
// const _MaxBitrateWifi();
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final bitrate = ref.watch(
// settingsServiceProvider.select(
// (value) => value.app.maxBitrateWifi,
// ),
// );
// final l = AppLocalizations.of(context);
// return _MaxBitrateOption(
// title: l.settingsNetworkOptionsMaxBitrateWifiTitle,
// bitrate: bitrate,
// onChange: (value) {
// ref.read(settingsServiceProvider.notifier).setMaxBitrateWifi(value);
// },
// );
// }
// }
// class _MaxBitrateMobile extends HookConsumerWidget {
// const _MaxBitrateMobile();
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final bitrate = ref.watch(
// settingsServiceProvider.select(
// (value) => value.app.maxBitrateMobile,
// ),
// );
// final l = AppLocalizations.of(context);
// return _MaxBitrateOption(
// title: l.settingsNetworkOptionsMaxBitrateMobileTitle,
// bitrate: bitrate,
// onChange: (value) {
// ref.read(settingsServiceProvider.notifier).setMaxBitrateMobile(value);
// },
// );
// }
// }
// class _MaxBitrateOption extends HookConsumerWidget {
// final String title;
// final int bitrate;
// final void Function(int value) onChange;
// const _MaxBitrateOption({
// required this.title,
// required this.bitrate,
// required this.onChange,
// });
// static const options = [0, 24, 32, 64, 96, 128, 192, 256, 320];
// String _bitrateText(AppLocalizations l, int bitrate) {
// return bitrate == 0
// ? l.settingsNetworkValuesUnlimitedKbps
// : l.settingsNetworkValuesKbps(bitrate.toString());
// }
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final l = AppLocalizations.of(context);
// return ListTile(
// title: Text(title),
// subtitle: Text(_bitrateText(l, bitrate)),
// onTap: () async {
// final value = await showDialog<int>(
// context: context,
// builder: (context) => MultipleChoiceDialog<int>(
// title: title,
// current: bitrate,
// options: options
// .map(
// (opt) => MultiChoiceOption.int(
// title: _bitrateText(l, opt),
// option: opt,
// ),
// )
// .toIList(),
// ),
// );
// if (value != null) {
// onChange(value);
// }
// },
// );
// }
// }
// class _StreamFormat extends HookConsumerWidget {
// const _StreamFormat();
// static const options = ['', 'mp3', 'opus', 'ogg'];
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final streamFormat = ref.watch(
// settingsServiceProvider.select((value) => value.app.streamFormat),
// );
// final l = AppLocalizations.of(context);
// return ListTile(
// title: Text(l.settingsNetworkOptionsStreamFormat),
// subtitle: Text(
// streamFormat ?? l.settingsNetworkOptionsStreamFormatServerDefault,
// ),
// onTap: () async {
// final value = await showDialog<String>(
// context: context,
// builder: (context) => MultipleChoiceDialog<String>(
// title: l.settingsNetworkOptionsStreamFormat,
// current: streamFormat ?? '',
// options: options
// .map(
// (opt) => MultiChoiceOption.string(
// title: opt == ''
// ? l.settingsNetworkOptionsStreamFormatServerDefault
// : opt,
// option: opt,
// ),
// )
// .toIList(),
// ),
// );
// if (value != null) {
// ref
// .read(settingsServiceProvider.notifier)
// .setStreamFormat(value == '' ? null : value);
// }
// },
// );
// }
// }
// class _OfflineMode extends HookConsumerWidget {
// const _OfflineMode();
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final offline = ref.watch(offlineModeProvider);
// final l = AppLocalizations.of(context);
// return SwitchListTile(
// value: offline,
// title: Text(l.settingsNetworkOptionsOfflineMode),
// subtitle: offline
// ? Text(l.settingsNetworkOptionsOfflineModeOn)
// : Text(l.settingsNetworkOptionsOfflineModeOff),
// onChanged: (value) {
// ref.read(offlineModeProvider.notifier).setMode(value);
// },
// );
// }
// }
// class _Sources extends HookConsumerWidget {
// const _Sources();
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final sources = ref.watch(
// settingsServiceProvider.select(
// (value) => value.sources,
// ),
// );
// final activeSource = ref.watch(
// settingsServiceProvider.select(
// (value) => value.activeSource,
// ),
// );
// final l = AppLocalizations.of(context);
// return _Section(
// children: [
// for (var source in sources)
// RadioListTile<int>(
// value: source.id,
// groupValue: activeSource?.id,
// onChanged: (value) {
// ref
// .read(settingsServiceProvider.notifier)
// .setActiveSource(source.id);
// },
// title: Text(source.name),
// subtitle: Text(
// source.address.toString(),
// maxLines: 1,
// softWrap: false,
// overflow: TextOverflow.fade,
// ),
// secondary: IconButton(
// icon: const Icon(Icons.edit_rounded),
// onPressed: () {
// context.pushRoute(SourceRoute(id: source.id));
// },
// ),
// ),
// const SizedBox(height: 8),
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// OutlinedButton.icon(
// icon: const Icon(Icons.add_rounded),
// label: Text(l.settingsServersActionsAdd),
// onPressed: () {
// context.pushRoute(SourceRoute());
// },
// ),
// ],
// ),
// // TODO: remove
// if (kDebugMode)
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// OutlinedButton.icon(
// icon: const Icon(Icons.add_rounded),
// label: const Text('Add TEST'),
// onPressed: () {
// ref
// .read(settingsServiceProvider.notifier)
// .addTestSource('TEST');
// },
// ),
// ],
// ),
// ],
// );
// }
// }