mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
219 lines
8.6 KiB
Dart
219 lines
8.6 KiB
Dart
import 'package:collection/collection.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:piped_client/piped_client.dart';
|
|
import 'package:spotube/collections/spotube_icons.dart';
|
|
import 'package:spotube/components/settings/section_card_with_heading.dart';
|
|
import 'package:spotube/components/shared/adaptive/adaptive_select_tile.dart';
|
|
import 'package:spotube/extensions/context.dart';
|
|
import 'package:spotube/models/matched_track.dart';
|
|
import 'package:spotube/provider/piped_instances_provider.dart';
|
|
import 'package:spotube/provider/user_preferences_provider.dart';
|
|
|
|
class SettingsPlaybackSection extends HookConsumerWidget {
|
|
const SettingsPlaybackSection({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context, ref) {
|
|
final preferences = ref.watch(userPreferencesProvider);
|
|
final theme = Theme.of(context);
|
|
|
|
return SectionCardWithHeading(
|
|
heading: context.l10n.playback,
|
|
children: [
|
|
AdaptiveSelectTile<AudioQuality>(
|
|
secondary: const Icon(SpotubeIcons.audioQuality),
|
|
title: Text(context.l10n.audio_quality),
|
|
value: preferences.audioQuality,
|
|
options: [
|
|
DropdownMenuItem(
|
|
value: AudioQuality.high,
|
|
child: Text(context.l10n.high),
|
|
),
|
|
DropdownMenuItem(
|
|
value: AudioQuality.low,
|
|
child: Text(context.l10n.low),
|
|
),
|
|
],
|
|
onChanged: (value) {
|
|
if (value != null) {
|
|
preferences.setAudioQuality(value);
|
|
}
|
|
},
|
|
),
|
|
AdaptiveSelectTile<YoutubeApiType>(
|
|
secondary: const Icon(SpotubeIcons.api),
|
|
title: Text(context.l10n.youtube_api_type),
|
|
value: preferences.youtubeApiType,
|
|
options: YoutubeApiType.values
|
|
.map((e) => DropdownMenuItem(
|
|
value: e,
|
|
child: Text(e.label),
|
|
))
|
|
.toList(),
|
|
onChanged: (value) {
|
|
if (value == null) return;
|
|
preferences.setYoutubeApiType(value);
|
|
},
|
|
),
|
|
AnimatedSwitcher(
|
|
duration: const Duration(milliseconds: 300),
|
|
child: preferences.youtubeApiType == YoutubeApiType.youtube
|
|
? const SizedBox.shrink()
|
|
: Consumer(builder: (context, ref, child) {
|
|
final instanceList = ref.watch(pipedInstancesFutureProvider);
|
|
|
|
return instanceList.when(
|
|
data: (data) {
|
|
return AdaptiveSelectTile<String>(
|
|
secondary: const Icon(SpotubeIcons.piped),
|
|
title: Text(context.l10n.piped_instance),
|
|
subtitle: RichText(
|
|
text: TextSpan(
|
|
children: [
|
|
TextSpan(
|
|
text: context.l10n.piped_description,
|
|
style: theme.textTheme.bodyMedium,
|
|
),
|
|
const TextSpan(text: "\n"),
|
|
TextSpan(
|
|
text: context.l10n.piped_warning,
|
|
style: theme.textTheme.labelMedium,
|
|
)
|
|
],
|
|
),
|
|
),
|
|
value: preferences.pipedInstance,
|
|
showValueWhenUnfolded: false,
|
|
options: data
|
|
.sortedBy((e) => e.name)
|
|
.map(
|
|
(e) => DropdownMenuItem(
|
|
value: e.apiUrl,
|
|
child: RichText(
|
|
text: TextSpan(
|
|
children: [
|
|
TextSpan(
|
|
text: "${e.name.trim()}\n",
|
|
style: theme.textTheme.labelLarge,
|
|
),
|
|
TextSpan(
|
|
text: e.locations
|
|
.map(countryCodeToEmoji)
|
|
.join(""),
|
|
style: GoogleFonts.notoColorEmoji(),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
)
|
|
.toList(),
|
|
onChanged: (value) {
|
|
if (value != null) {
|
|
preferences.setPipedInstance(value);
|
|
}
|
|
},
|
|
);
|
|
},
|
|
loading: () => const Center(
|
|
child: CircularProgressIndicator(),
|
|
),
|
|
error: (error, stackTrace) => Text(error.toString()),
|
|
);
|
|
}),
|
|
),
|
|
AnimatedSwitcher(
|
|
duration: const Duration(milliseconds: 300),
|
|
child: preferences.youtubeApiType == YoutubeApiType.youtube
|
|
? const SizedBox.shrink()
|
|
: AdaptiveSelectTile<SearchMode>(
|
|
secondary: const Icon(SpotubeIcons.search),
|
|
title: Text(context.l10n.search_mode),
|
|
value: preferences.searchMode,
|
|
options: SearchMode.values
|
|
.map((e) => DropdownMenuItem(
|
|
value: e,
|
|
child: Text(e.label),
|
|
))
|
|
.toList(),
|
|
onChanged: (value) {
|
|
if (value == null) return;
|
|
preferences.setSearchMode(value);
|
|
},
|
|
),
|
|
),
|
|
AnimatedSwitcher(
|
|
duration: const Duration(milliseconds: 300),
|
|
child: preferences.searchMode == SearchMode.youtubeMusic &&
|
|
preferences.youtubeApiType == YoutubeApiType.piped
|
|
? const SizedBox.shrink()
|
|
: SwitchListTile(
|
|
secondary: const Icon(SpotubeIcons.skip),
|
|
title: Text(context.l10n.skip_non_music),
|
|
value: preferences.skipNonMusic,
|
|
onChanged: (state) {
|
|
preferences.setSkipNonMusic(state);
|
|
},
|
|
),
|
|
),
|
|
ListTile(
|
|
leading: const Icon(SpotubeIcons.playlistRemove),
|
|
title: Text(context.l10n.blacklist),
|
|
subtitle: Text(context.l10n.blacklist_description),
|
|
onTap: () {
|
|
GoRouter.of(context).push("/settings/blacklist");
|
|
},
|
|
trailing: const Icon(SpotubeIcons.angleRight),
|
|
),
|
|
SwitchListTile(
|
|
secondary: const Icon(SpotubeIcons.normalize),
|
|
title: Text(context.l10n.normalize_audio),
|
|
value: preferences.normalizeAudio,
|
|
onChanged: preferences.setNormalizeAudio,
|
|
),
|
|
AdaptiveSelectTile<MusicCodec>(
|
|
secondary: const Icon(SpotubeIcons.stream),
|
|
title: Text(context.l10n.streaming_music_codec),
|
|
value: preferences.streamMusicCodec,
|
|
showValueWhenUnfolded: false,
|
|
options: MusicCodec.values
|
|
.map((e) => DropdownMenuItem(
|
|
value: e,
|
|
child: Text(
|
|
e.label,
|
|
style: theme.textTheme.labelMedium,
|
|
),
|
|
))
|
|
.toList(),
|
|
onChanged: (value) {
|
|
if (value == null) return;
|
|
preferences.setStreamMusicCodec(value);
|
|
},
|
|
),
|
|
AdaptiveSelectTile<MusicCodec>(
|
|
secondary: const Icon(SpotubeIcons.file),
|
|
title: Text(context.l10n.download_music_codec),
|
|
value: preferences.downloadMusicCodec,
|
|
showValueWhenUnfolded: false,
|
|
options: MusicCodec.values
|
|
.map((e) => DropdownMenuItem(
|
|
value: e,
|
|
child: Text(
|
|
e.label,
|
|
style: theme.textTheme.labelMedium,
|
|
),
|
|
))
|
|
.toList(),
|
|
onChanged: (value) {
|
|
if (value == null) return;
|
|
preferences.setDownloadMusicCodec(value);
|
|
},
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|