mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-05-08 16:24:36 +00:00
feat: index multiple folders of local music
If you used a previous commit from this branch, this is a breaking change, because it changes the type of a configuration field. but since this is still in development, it should be fine. Signed-off-by: Blake Leonard <me@blakes.dev>
This commit is contained in:
parent
b051ad4637
commit
20be5dbbcc
@ -36,6 +36,7 @@ import 'package:spotube/pages/desktop_login/desktop_login.dart';
|
|||||||
import 'package:spotube/pages/lyrics/lyrics.dart';
|
import 'package:spotube/pages/lyrics/lyrics.dart';
|
||||||
import 'package:spotube/pages/root/root_app.dart';
|
import 'package:spotube/pages/root/root_app.dart';
|
||||||
import 'package:spotube/pages/settings/settings.dart';
|
import 'package:spotube/pages/settings/settings.dart';
|
||||||
|
import 'package:spotube/pages/settings/library.dart';
|
||||||
import 'package:spotube/pages/mobile_login/mobile_login.dart';
|
import 'package:spotube/pages/mobile_login/mobile_login.dart';
|
||||||
|
|
||||||
final rootNavigatorKey = Catcher2.navigatorKey;
|
final rootNavigatorKey = Catcher2.navigatorKey;
|
||||||
@ -132,6 +133,12 @@ final routerProvider = Provider((ref) {
|
|||||||
child: const BlackListPage(),
|
child: const BlackListPage(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: "local_library",
|
||||||
|
pageBuilder: (context, state) => SpotubeSlidePage(
|
||||||
|
child: const LocalLibrariesPage(),
|
||||||
|
),
|
||||||
|
),
|
||||||
if (!kIsWeb)
|
if (!kIsWeb)
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: "logs",
|
path: "logs",
|
||||||
|
|||||||
@ -71,20 +71,17 @@ final localTracksProvider = FutureProvider<List<LocalTrack>>((ref) async {
|
|||||||
await downloadDir.create(recursive: true);
|
await downloadDir.create(recursive: true);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
final downloadEntities = downloadDir.listSync(recursive: true);
|
final entities = downloadDir.listSync(recursive: true);
|
||||||
|
|
||||||
final localLibraryLocation = ref.watch(
|
final localLibraryLocations = ref.watch(
|
||||||
userPreferencesProvider.select((s) => s.localLibraryLocation),
|
userPreferencesProvider.select((s) => s.localLibraryLocation),
|
||||||
);
|
);
|
||||||
if (localLibraryLocation.isEmpty) return [];
|
for (final location in localLibraryLocations) {
|
||||||
final localLibraryDir = Directory(localLibraryLocation);
|
final dir = Directory(location);
|
||||||
if (!await localLibraryDir.exists()) {
|
if (await Directory(location).exists()) {
|
||||||
await localLibraryDir.create(recursive: true);
|
entities.addAll(Directory(location).listSync(recursive: true));
|
||||||
return [];
|
}
|
||||||
}
|
}
|
||||||
final localLibraryEntities = localLibraryDir.listSync(recursive: true);
|
|
||||||
|
|
||||||
final entities = [...downloadEntities, ...localLibraryEntities];
|
|
||||||
|
|
||||||
final filesWithMetadata = (await Future.wait(
|
final filesWithMetadata = (await Future.wait(
|
||||||
entities.map((e) => File(e.path)).where((file) {
|
entities.map((e) => File(e.path)).where((file) {
|
||||||
|
|||||||
@ -107,7 +107,10 @@
|
|||||||
"always_on_top": "Always on top",
|
"always_on_top": "Always on top",
|
||||||
"exit_mini_player": "Exit Mini player",
|
"exit_mini_player": "Exit Mini player",
|
||||||
"download_location": "Download location",
|
"download_location": "Download location",
|
||||||
"local_library_location": "Local library location",
|
"local_library": "Local library",
|
||||||
|
"local_library_description": "Music saved on your device that wasn't downloaded from Spotube",
|
||||||
|
"add_library_location": "Add to library",
|
||||||
|
"remove_library_location": "Remove from library",
|
||||||
"account": "Account",
|
"account": "Account",
|
||||||
"login_with_spotify": "Login with your Spotify account",
|
"login_with_spotify": "Login with your Spotify account",
|
||||||
"connect_with_spotify": "Connect with Spotify",
|
"connect_with_spotify": "Connect with Spotify",
|
||||||
|
|||||||
100
lib/pages/settings/library.dart
Normal file
100
lib/pages/settings/library.dart
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import 'package:file_selector/file_selector.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:fuzzywuzzy/fuzzywuzzy.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
|
import 'package:spotube/collections/spotube_icons.dart';
|
||||||
|
import 'package:spotube/components/shared/inter_scrollbar/inter_scrollbar.dart';
|
||||||
|
import 'package:spotube/components/shared/page_window_title_bar.dart';
|
||||||
|
import 'package:spotube/extensions/context.dart';
|
||||||
|
import 'package:spotube/provider/blacklist_provider.dart';
|
||||||
|
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||||
|
|
||||||
|
class LocalLibrariesPage extends HookConsumerWidget {
|
||||||
|
const LocalLibrariesPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, ref) {
|
||||||
|
final controller = useScrollController();
|
||||||
|
// final blacklist = ref.watch(blacklistProvider);
|
||||||
|
// final searchText = useState("");
|
||||||
|
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||||
|
final preferences = ref.watch(userPreferencesProvider);
|
||||||
|
|
||||||
|
final addLocalLibraryLocation = useCallback(() async {
|
||||||
|
if (DesktopTools.platform.isMobile || DesktopTools.platform.isMacOS) {
|
||||||
|
final dirStr = await FilePicker.platform.getDirectoryPath(
|
||||||
|
initialDirectory: preferences.downloadLocation,
|
||||||
|
);
|
||||||
|
if (dirStr == null) return;
|
||||||
|
preferencesNotifier.setLocalLibraryLocation([...preferences.localLibraryLocation, dirStr]);
|
||||||
|
} else {
|
||||||
|
String? dirStr = await getDirectoryPath(
|
||||||
|
initialDirectory: preferences.downloadLocation,
|
||||||
|
);
|
||||||
|
if (dirStr == null) return;
|
||||||
|
preferencesNotifier.setLocalLibraryLocation([...preferences.localLibraryLocation, dirStr]);
|
||||||
|
}
|
||||||
|
}, [preferences.localLibraryLocation]);
|
||||||
|
|
||||||
|
final removeLocalLibraryLocation = useCallback((int index) {
|
||||||
|
if (index < 0 || index >= preferences.localLibraryLocation.length) return;
|
||||||
|
preferencesNotifier.setLocalLibraryLocation([...preferences.localLibraryLocation]..removeAt(index));
|
||||||
|
}, [preferences.localLibraryLocation]);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: PageWindowTitleBar(
|
||||||
|
title: Text(context.l10n.local_library),
|
||||||
|
centerTitle: true,
|
||||||
|
leading: const BackButton(),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
/* Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: TextField(
|
||||||
|
onChanged: (value) => searchText.value = value,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: context.l10n.search,
|
||||||
|
prefixIcon: const Icon(SpotubeIcons.search),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
), */
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: FilledButton(
|
||||||
|
child: const Icon(SpotubeIcons.add),
|
||||||
|
onPressed: addLocalLibraryLocation,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InterScrollbar(
|
||||||
|
controller: controller,
|
||||||
|
child: ListView.builder(
|
||||||
|
controller: controller,
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: preferences.localLibraryLocation.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final item = preferences.localLibraryLocation.elementAt(index);
|
||||||
|
return ListTile(
|
||||||
|
title: Text(item),
|
||||||
|
trailing: Tooltip(
|
||||||
|
message: context.l10n.remove_library_location,
|
||||||
|
child: IconButton(
|
||||||
|
icon: Icon(SpotubeIcons.trash, color: Colors.red[400]),
|
||||||
|
onPressed: () => removeLocalLibraryLocation(index),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ import 'package:file_selector/file_selector.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:spotube/collections/spotube_icons.dart';
|
import 'package:spotube/collections/spotube_icons.dart';
|
||||||
import 'package:spotube/components/settings/section_card_with_heading.dart';
|
import 'package:spotube/components/settings/section_card_with_heading.dart';
|
||||||
import 'package:spotube/extensions/context.dart';
|
import 'package:spotube/extensions/context.dart';
|
||||||
@ -33,22 +34,6 @@ class SettingsDownloadsSection extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}, [preferences.downloadLocation]);
|
}, [preferences.downloadLocation]);
|
||||||
|
|
||||||
final pickLocalLibraryLocation = useCallback(() async {
|
|
||||||
if (DesktopTools.platform.isMobile || DesktopTools.platform.isMacOS) {
|
|
||||||
final dirStr = await FilePicker.platform.getDirectoryPath(
|
|
||||||
initialDirectory: preferences.localLibraryLocation,
|
|
||||||
);
|
|
||||||
if (dirStr == null) return;
|
|
||||||
preferencesNotifier.setLocalLibraryLocation(dirStr);
|
|
||||||
} else {
|
|
||||||
String? dirStr = await getDirectoryPath(
|
|
||||||
initialDirectory: preferences.localLibraryLocation,
|
|
||||||
);
|
|
||||||
if (dirStr == null) return;
|
|
||||||
preferencesNotifier.setLocalLibraryLocation(dirStr);
|
|
||||||
}
|
|
||||||
}, [preferences.localLibraryLocation]);
|
|
||||||
|
|
||||||
return SectionCardWithHeading(
|
return SectionCardWithHeading(
|
||||||
heading: context.l10n.downloads,
|
heading: context.l10n.downloads,
|
||||||
children: [
|
children: [
|
||||||
@ -64,13 +49,12 @@ class SettingsDownloadsSection extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(SpotubeIcons.folder),
|
leading: const Icon(SpotubeIcons.folder),
|
||||||
title: Text(context.l10n.local_library_location),
|
title: Text(context.l10n.local_library),
|
||||||
subtitle: Text(preferences.localLibraryLocation),
|
subtitle: Text(context.l10n.local_library_description),
|
||||||
trailing: FilledButton(
|
onTap: () {
|
||||||
onPressed: pickLocalLibraryLocation,
|
GoRouter.of(context).push("/settings/local_library");
|
||||||
child: const Icon(SpotubeIcons.folder),
|
},
|
||||||
),
|
trailing: const Icon(SpotubeIcons.angleRight),
|
||||||
onTap: pickLocalLibraryLocation,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -69,9 +69,9 @@ class UserPreferencesNotifier extends PersistedStateNotifier<UserPreferences> {
|
|||||||
state = state.copyWith(downloadLocation: downloadDir);
|
state = state.copyWith(downloadLocation: downloadDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLocalLibraryLocation(String localLibraryDir) {
|
void setLocalLibraryLocation(List<String> localLibraryDirs) {
|
||||||
if (localLibraryDir.isEmpty) return;
|
//if (localLibraryDir.isEmpty) return;
|
||||||
state = state.copyWith(localLibraryLocation: localLibraryDir);
|
state = state.copyWith(localLibraryLocation: localLibraryDirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLayoutMode(LayoutMode mode) {
|
void setLayoutMode(LayoutMode mode) {
|
||||||
|
|||||||
@ -84,7 +84,7 @@ class UserPreferences with _$UserPreferences {
|
|||||||
@Default(Market.US) Market recommendationMarket,
|
@Default(Market.US) Market recommendationMarket,
|
||||||
@Default(SearchMode.youtube) SearchMode searchMode,
|
@Default(SearchMode.youtube) SearchMode searchMode,
|
||||||
@Default("") String downloadLocation,
|
@Default("") String downloadLocation,
|
||||||
@Default("") String localLibraryLocation,
|
@Default([]) List<String> localLibraryLocation,
|
||||||
@Default("https://pipedapi.kavin.rocks") String pipedInstance,
|
@Default("https://pipedapi.kavin.rocks") String pipedInstance,
|
||||||
@Default(ThemeMode.system) ThemeMode themeMode,
|
@Default(ThemeMode.system) ThemeMode themeMode,
|
||||||
@Default(AudioSource.youtube) AudioSource audioSource,
|
@Default(AudioSource.youtube) AudioSource audioSource,
|
||||||
|
|||||||
@ -43,7 +43,7 @@ mixin _$UserPreferences {
|
|||||||
Market get recommendationMarket => throw _privateConstructorUsedError;
|
Market get recommendationMarket => throw _privateConstructorUsedError;
|
||||||
SearchMode get searchMode => throw _privateConstructorUsedError;
|
SearchMode get searchMode => throw _privateConstructorUsedError;
|
||||||
String get downloadLocation => throw _privateConstructorUsedError;
|
String get downloadLocation => throw _privateConstructorUsedError;
|
||||||
String get localLibraryLocation => throw _privateConstructorUsedError;
|
List<String> get localLibraryLocation => throw _privateConstructorUsedError;
|
||||||
String get pipedInstance => throw _privateConstructorUsedError;
|
String get pipedInstance => throw _privateConstructorUsedError;
|
||||||
ThemeMode get themeMode => throw _privateConstructorUsedError;
|
ThemeMode get themeMode => throw _privateConstructorUsedError;
|
||||||
AudioSource get audioSource => throw _privateConstructorUsedError;
|
AudioSource get audioSource => throw _privateConstructorUsedError;
|
||||||
@ -89,7 +89,7 @@ abstract class $UserPreferencesCopyWith<$Res> {
|
|||||||
Market recommendationMarket,
|
Market recommendationMarket,
|
||||||
SearchMode searchMode,
|
SearchMode searchMode,
|
||||||
String downloadLocation,
|
String downloadLocation,
|
||||||
String localLibraryLocation,
|
List<String> localLibraryLocation,
|
||||||
String pipedInstance,
|
String pipedInstance,
|
||||||
ThemeMode themeMode,
|
ThemeMode themeMode,
|
||||||
AudioSource audioSource,
|
AudioSource audioSource,
|
||||||
@ -202,7 +202,7 @@ class _$UserPreferencesCopyWithImpl<$Res, $Val extends UserPreferences>
|
|||||||
localLibraryLocation: null == localLibraryLocation
|
localLibraryLocation: null == localLibraryLocation
|
||||||
? _value.localLibraryLocation
|
? _value.localLibraryLocation
|
||||||
: localLibraryLocation // ignore: cast_nullable_to_non_nullable
|
: localLibraryLocation // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as List<String>,
|
||||||
pipedInstance: null == pipedInstance
|
pipedInstance: null == pipedInstance
|
||||||
? _value.pipedInstance
|
? _value.pipedInstance
|
||||||
: pipedInstance // ignore: cast_nullable_to_non_nullable
|
: pipedInstance // ignore: cast_nullable_to_non_nullable
|
||||||
@ -271,7 +271,7 @@ abstract class _$$UserPreferencesImplCopyWith<$Res>
|
|||||||
Market recommendationMarket,
|
Market recommendationMarket,
|
||||||
SearchMode searchMode,
|
SearchMode searchMode,
|
||||||
String downloadLocation,
|
String downloadLocation,
|
||||||
String localLibraryLocation,
|
List<String> localLibraryLocation,
|
||||||
String pipedInstance,
|
String pipedInstance,
|
||||||
ThemeMode themeMode,
|
ThemeMode themeMode,
|
||||||
AudioSource audioSource,
|
AudioSource audioSource,
|
||||||
@ -380,9 +380,9 @@ class __$$UserPreferencesImplCopyWithImpl<$Res>
|
|||||||
: downloadLocation // ignore: cast_nullable_to_non_nullable
|
: downloadLocation // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
localLibraryLocation: null == localLibraryLocation
|
localLibraryLocation: null == localLibraryLocation
|
||||||
? _value.localLibraryLocation
|
? _value._localLibraryLocation
|
||||||
: localLibraryLocation // ignore: cast_nullable_to_non_nullable
|
: localLibraryLocation // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as List<String>,
|
||||||
pipedInstance: null == pipedInstance
|
pipedInstance: null == pipedInstance
|
||||||
? _value.pipedInstance
|
? _value.pipedInstance
|
||||||
: pipedInstance // ignore: cast_nullable_to_non_nullable
|
: pipedInstance // ignore: cast_nullable_to_non_nullable
|
||||||
@ -446,7 +446,7 @@ class _$UserPreferencesImpl implements _UserPreferences {
|
|||||||
this.recommendationMarket = Market.US,
|
this.recommendationMarket = Market.US,
|
||||||
this.searchMode = SearchMode.youtube,
|
this.searchMode = SearchMode.youtube,
|
||||||
this.downloadLocation = "",
|
this.downloadLocation = "",
|
||||||
this.localLibraryLocation = "",
|
final List<String> localLibraryLocation = const [],
|
||||||
this.pipedInstance = "https://pipedapi.kavin.rocks",
|
this.pipedInstance = "https://pipedapi.kavin.rocks",
|
||||||
this.themeMode = ThemeMode.system,
|
this.themeMode = ThemeMode.system,
|
||||||
this.audioSource = AudioSource.youtube,
|
this.audioSource = AudioSource.youtube,
|
||||||
@ -454,7 +454,8 @@ class _$UserPreferencesImpl implements _UserPreferences {
|
|||||||
this.downloadMusicCodec = SourceCodecs.m4a,
|
this.downloadMusicCodec = SourceCodecs.m4a,
|
||||||
this.discordPresence = true,
|
this.discordPresence = true,
|
||||||
this.endlessPlayback = true,
|
this.endlessPlayback = true,
|
||||||
this.enableConnect = false});
|
this.enableConnect = false})
|
||||||
|
: _localLibraryLocation = localLibraryLocation;
|
||||||
|
|
||||||
factory _$UserPreferencesImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$UserPreferencesImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$UserPreferencesImplFromJson(json);
|
_$$UserPreferencesImplFromJson(json);
|
||||||
@ -510,9 +511,16 @@ class _$UserPreferencesImpl implements _UserPreferences {
|
|||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final String downloadLocation;
|
final String downloadLocation;
|
||||||
|
final List<String> _localLibraryLocation;
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final String localLibraryLocation;
|
List<String> get localLibraryLocation {
|
||||||
|
if (_localLibraryLocation is EqualUnmodifiableListView)
|
||||||
|
return _localLibraryLocation;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_localLibraryLocation);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final String pipedInstance;
|
final String pipedInstance;
|
||||||
@ -577,8 +585,8 @@ class _$UserPreferencesImpl implements _UserPreferences {
|
|||||||
other.searchMode == searchMode) &&
|
other.searchMode == searchMode) &&
|
||||||
(identical(other.downloadLocation, downloadLocation) ||
|
(identical(other.downloadLocation, downloadLocation) ||
|
||||||
other.downloadLocation == downloadLocation) &&
|
other.downloadLocation == downloadLocation) &&
|
||||||
(identical(other.localLibraryLocation, localLibraryLocation) ||
|
const DeepCollectionEquality()
|
||||||
other.localLibraryLocation == localLibraryLocation) &&
|
.equals(other._localLibraryLocation, _localLibraryLocation) &&
|
||||||
(identical(other.pipedInstance, pipedInstance) ||
|
(identical(other.pipedInstance, pipedInstance) ||
|
||||||
other.pipedInstance == pipedInstance) &&
|
other.pipedInstance == pipedInstance) &&
|
||||||
(identical(other.themeMode, themeMode) ||
|
(identical(other.themeMode, themeMode) ||
|
||||||
@ -616,7 +624,7 @@ class _$UserPreferencesImpl implements _UserPreferences {
|
|||||||
recommendationMarket,
|
recommendationMarket,
|
||||||
searchMode,
|
searchMode,
|
||||||
downloadLocation,
|
downloadLocation,
|
||||||
localLibraryLocation,
|
const DeepCollectionEquality().hash(_localLibraryLocation),
|
||||||
pipedInstance,
|
pipedInstance,
|
||||||
themeMode,
|
themeMode,
|
||||||
audioSource,
|
audioSource,
|
||||||
@ -667,7 +675,7 @@ abstract class _UserPreferences implements UserPreferences {
|
|||||||
final Market recommendationMarket,
|
final Market recommendationMarket,
|
||||||
final SearchMode searchMode,
|
final SearchMode searchMode,
|
||||||
final String downloadLocation,
|
final String downloadLocation,
|
||||||
final String localLibraryLocation,
|
final List<String> localLibraryLocation,
|
||||||
final String pipedInstance,
|
final String pipedInstance,
|
||||||
final ThemeMode themeMode,
|
final ThemeMode themeMode,
|
||||||
final AudioSource audioSource,
|
final AudioSource audioSource,
|
||||||
@ -719,7 +727,7 @@ abstract class _UserPreferences implements UserPreferences {
|
|||||||
@override
|
@override
|
||||||
String get downloadLocation;
|
String get downloadLocation;
|
||||||
@override
|
@override
|
||||||
String get localLibraryLocation;
|
List<String> get localLibraryLocation;
|
||||||
@override
|
@override
|
||||||
String get pipedInstance;
|
String get pipedInstance;
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -44,7 +44,10 @@ _$UserPreferencesImpl _$$UserPreferencesImplFromJson(
|
|||||||
$enumDecodeNullable(_$SearchModeEnumMap, json['searchMode']) ??
|
$enumDecodeNullable(_$SearchModeEnumMap, json['searchMode']) ??
|
||||||
SearchMode.youtube,
|
SearchMode.youtube,
|
||||||
downloadLocation: json['downloadLocation'] as String? ?? "",
|
downloadLocation: json['downloadLocation'] as String? ?? "",
|
||||||
localLibraryLocation: json['localLibraryLocation'] as String? ?? "",
|
localLibraryLocation: (json['localLibraryLocation'] as List<dynamic>?)
|
||||||
|
?.map((e) => e as String)
|
||||||
|
.toList() ??
|
||||||
|
const [],
|
||||||
pipedInstance:
|
pipedInstance:
|
||||||
json['pipedInstance'] as String? ?? "https://pipedapi.kavin.rocks",
|
json['pipedInstance'] as String? ?? "https://pipedapi.kavin.rocks",
|
||||||
themeMode: $enumDecodeNullable(_$ThemeModeEnumMap, json['themeMode']) ??
|
themeMode: $enumDecodeNullable(_$ThemeModeEnumMap, json['themeMode']) ??
|
||||||
|
|||||||
@ -1,89 +1,155 @@
|
|||||||
{
|
{
|
||||||
"ar": [
|
"ar": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"bn": [
|
"bn": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ca": [
|
"ca": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"cs": [
|
"cs": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"de": [
|
"de": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"es": [
|
"es": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fa": [
|
"fa": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fr": [
|
"fr": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"hi": [
|
"hi": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"it": [
|
"it": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ko": [
|
"ko": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ne": [
|
"ne": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"nl": [
|
"nl": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pl": [
|
"pl": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ru": [
|
"ru": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"th": [
|
"th": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"tr": [
|
"tr": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"uk": [
|
"uk": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"vi": [
|
"vi": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
"local_library_location"
|
"local_library",
|
||||||
|
"local_library_description",
|
||||||
|
"add_library_location",
|
||||||
|
"remove_library_location"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user