mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
fix(layout): Fix adaptive UI not working correctly by providing a overriding option
This commit is contained in:
parent
192acc169e
commit
8c7adde890
@ -43,13 +43,14 @@ class Home extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final int titleBarDragMaxWidth = useBreakpointValue(
|
final double titleBarWidth = useBreakpointValue(
|
||||||
md: 80,
|
sm: 0.0,
|
||||||
lg: 256,
|
md: 80.0,
|
||||||
sm: 0,
|
lg: 256.0,
|
||||||
xl: 256,
|
xl: 256.0,
|
||||||
xxl: 256,
|
xxl: 256.0,
|
||||||
);
|
);
|
||||||
|
final extended = ref.watch(sidebarExtendedStateProvider);
|
||||||
final _selectedIndex = useState(0);
|
final _selectedIndex = useState(0);
|
||||||
_onSelectedIndexChanged(int index) => _selectedIndex.value = index;
|
_onSelectedIndexChanged(int index) => _selectedIndex.value = index;
|
||||||
|
|
||||||
@ -82,7 +83,9 @@ class Home extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: titleBarDragMaxWidth.toDouble(),
|
maxWidth: extended == null
|
||||||
|
? titleBarWidth
|
||||||
|
: (extended ? 256 : 80),
|
||||||
),
|
),
|
||||||
color: Theme.of(context).navigationRailTheme.backgroundColor,
|
color: Theme.of(context).navigationRailTheme.backgroundColor,
|
||||||
child: MoveWindow(),
|
child: MoveWindow(),
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
import 'package:badges/badges.dart';
|
import 'package:badges/badges.dart';
|
||||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:spotube/components/Shared/UniversalImage.dart';
|
import 'package:spotube/components/Shared/UniversalImage.dart';
|
||||||
import 'package:spotube/hooks/useBreakpointValue.dart';
|
|
||||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||||
import 'package:spotube/models/sideBarTiles.dart';
|
import 'package:spotube/models/sideBarTiles.dart';
|
||||||
import 'package:spotube/provider/Auth.dart';
|
import 'package:spotube/provider/Auth.dart';
|
||||||
import 'package:spotube/provider/Downloader.dart';
|
import 'package:spotube/provider/Downloader.dart';
|
||||||
import 'package:spotube/provider/SpotifyRequests.dart';
|
import 'package:spotube/provider/SpotifyRequests.dart';
|
||||||
|
import 'package:spotube/provider/UserPreferences.dart';
|
||||||
import 'package:spotube/utils/platform.dart';
|
import 'package:spotube/utils/platform.dart';
|
||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||||
|
|
||||||
|
final sidebarExtendedStateProvider = StateProvider<bool?>((ref) => null);
|
||||||
|
|
||||||
class Sidebar extends HookConsumerWidget {
|
class Sidebar extends HookConsumerWidget {
|
||||||
final int selectedIndex;
|
final int selectedIndex;
|
||||||
final void Function(int) onSelectedIndexChanged;
|
final void Function(int) onSelectedIndexChanged;
|
||||||
@ -46,16 +47,15 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
final downloadCount = ref.watch(
|
final downloadCount = ref.watch(
|
||||||
downloaderProvider.select((s) => s.currentlyRunning),
|
downloaderProvider.select((s) => s.currentlyRunning),
|
||||||
);
|
);
|
||||||
|
final forceExtended = ref.watch(sidebarExtendedStateProvider);
|
||||||
final int titleBarDragMaxWidth = useBreakpointValue(
|
|
||||||
md: 80,
|
|
||||||
lg: 256,
|
|
||||||
sm: 0,
|
|
||||||
xl: 256,
|
|
||||||
xxl: 256,
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
|
if (forceExtended != null) {
|
||||||
|
if (extended.value != forceExtended) {
|
||||||
|
extended.value = forceExtended;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (breakpoints.isMd && extended.value) {
|
if (breakpoints.isMd && extended.value) {
|
||||||
extended.value = false;
|
extended.value = false;
|
||||||
} else if (breakpoints.isMoreThanOrEqualTo(Breakpoints.lg) &&
|
} else if (breakpoints.isMoreThanOrEqualTo(Breakpoints.lg) &&
|
||||||
@ -65,7 +65,17 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (breakpoints.isSm) return Container();
|
final layoutMode =
|
||||||
|
ref.watch(userPreferencesProvider.select((s) => s.layoutMode));
|
||||||
|
|
||||||
|
if (layoutMode == LayoutMode.compact ||
|
||||||
|
(breakpoints.isSm && layoutMode == LayoutMode.adaptive)) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleExtended() =>
|
||||||
|
ref.read(sidebarExtendedStateProvider.notifier).state =
|
||||||
|
!(forceExtended ?? extended.value);
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Material(
|
child: Material(
|
||||||
@ -76,11 +86,11 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
if (selectedIndex == 3 && kIsDesktop)
|
if (selectedIndex == 3 && kIsDesktop)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: appWindow.titleBarHeight,
|
height: appWindow.titleBarHeight,
|
||||||
width: titleBarDragMaxWidth.toDouble(),
|
width: extended.value ? 256 : 80,
|
||||||
child: MoveWindow(),
|
child: MoveWindow(),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 15),
|
padding: const EdgeInsets.only(left: 10),
|
||||||
child: (extended.value)
|
child: (extended.value)
|
||||||
? Row(
|
? Row(
|
||||||
children: [
|
children: [
|
||||||
@ -88,11 +98,25 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
Text("Spotube",
|
Text(
|
||||||
style: Theme.of(context).textTheme.headline4),
|
"Spotube",
|
||||||
|
style: Theme.of(context).textTheme.headline4,
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.menu_rounded),
|
||||||
|
onPressed: toggleExtended,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: _buildSmallLogo(),
|
: Column(
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.menu_rounded),
|
||||||
|
onPressed: toggleExtended,
|
||||||
|
),
|
||||||
|
_buildSmallLogo(),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NavigationRail(
|
child: NavigationRail(
|
||||||
@ -130,7 +154,7 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: titleBarDragMaxWidth.toDouble(),
|
width: extended.value ? 256 : 80,
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final data = meSnapshot.asData?.value;
|
final data = meSnapshot.asData?.value;
|
||||||
|
@ -5,6 +5,7 @@ import 'package:spotube/components/Home/Sidebar.dart';
|
|||||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||||
import 'package:spotube/models/sideBarTiles.dart';
|
import 'package:spotube/models/sideBarTiles.dart';
|
||||||
import 'package:spotube/provider/Downloader.dart';
|
import 'package:spotube/provider/Downloader.dart';
|
||||||
|
import 'package:spotube/provider/UserPreferences.dart';
|
||||||
|
|
||||||
class SpotubeNavigationBar extends HookConsumerWidget {
|
class SpotubeNavigationBar extends HookConsumerWidget {
|
||||||
final int selectedIndex;
|
final int selectedIndex;
|
||||||
@ -22,8 +23,12 @@ class SpotubeNavigationBar extends HookConsumerWidget {
|
|||||||
downloaderProvider.select((s) => s.currentlyRunning),
|
downloaderProvider.select((s) => s.currentlyRunning),
|
||||||
);
|
);
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
|
final layoutMode =
|
||||||
|
ref.watch(userPreferencesProvider.select((s) => s.layoutMode));
|
||||||
|
|
||||||
if (breakpoint.isMoreThan(Breakpoints.sm)) return const SizedBox();
|
if (layoutMode == LayoutMode.extended ||
|
||||||
|
(breakpoint.isMoreThan(Breakpoints.sm) &&
|
||||||
|
layoutMode == LayoutMode.adaptive)) return const SizedBox();
|
||||||
return NavigationBar(
|
return NavigationBar(
|
||||||
destinations: [
|
destinations: [
|
||||||
...sidebarTileList.map(
|
...sidebarTileList.map(
|
||||||
|
@ -8,6 +8,7 @@ import 'package:spotube/hooks/useBreakpoints.dart';
|
|||||||
import 'package:spotube/models/Logger.dart';
|
import 'package:spotube/models/Logger.dart';
|
||||||
import 'package:spotube/provider/Playback.dart';
|
import 'package:spotube/provider/Playback.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:spotube/provider/UserPreferences.dart';
|
||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||||
|
|
||||||
class Player extends HookConsumerWidget {
|
class Player extends HookConsumerWidget {
|
||||||
@ -17,6 +18,8 @@ class Player extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
Playback playback = ref.watch(playbackProvider);
|
Playback playback = ref.watch(playbackProvider);
|
||||||
|
final layoutMode =
|
||||||
|
ref.watch(userPreferencesProvider.select((s) => s.layoutMode));
|
||||||
|
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
|
|
||||||
@ -51,7 +54,9 @@ class Player extends HookConsumerWidget {
|
|||||||
WidgetsBinding.instance.addPostFrameCallback((time) {
|
WidgetsBinding.instance.addPostFrameCallback((time) {
|
||||||
// clearing the overlay-entry as passing the already available
|
// clearing the overlay-entry as passing the already available
|
||||||
// entry will result in splashing while resizing the window
|
// entry will result in splashing while resizing the window
|
||||||
if (breakpoint.isLessThanOrEqualTo(Breakpoints.md) &&
|
if ((layoutMode == LayoutMode.compact ||
|
||||||
|
(breakpoint.isLessThanOrEqualTo(Breakpoints.md) &&
|
||||||
|
layoutMode == LayoutMode.adaptive)) &&
|
||||||
entryRef.value == null &&
|
entryRef.value == null &&
|
||||||
playback.track != null) {
|
playback.track != null) {
|
||||||
entryRef.value = OverlayEntry(
|
entryRef.value = OverlayEntry(
|
||||||
@ -75,11 +80,13 @@ class Player extends HookConsumerWidget {
|
|||||||
return () {
|
return () {
|
||||||
disposeOverlay();
|
disposeOverlay();
|
||||||
};
|
};
|
||||||
}, [breakpoint, playback.track]);
|
}, [breakpoint, playback.track, layoutMode]);
|
||||||
|
|
||||||
// returning an empty non spacious Container as the overlay will take
|
// returning an empty non spacious Container as the overlay will take
|
||||||
// place in the global overlay stack aka [_entries]
|
// place in the global overlay stack aka [_entries]
|
||||||
if (breakpoint.isLessThanOrEqualTo(Breakpoints.md)) {
|
if (layoutMode == LayoutMode.compact ||
|
||||||
|
(breakpoint.isLessThanOrEqualTo(Breakpoints.md) &&
|
||||||
|
layoutMode == LayoutMode.adaptive)) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import 'package:spotube/hooks/playback.dart';
|
|||||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||||
import 'package:spotube/hooks/usePaletteColor.dart';
|
import 'package:spotube/hooks/usePaletteColor.dart';
|
||||||
import 'package:spotube/provider/Playback.dart';
|
import 'package:spotube/provider/Playback.dart';
|
||||||
|
import 'package:spotube/provider/UserPreferences.dart';
|
||||||
|
|
||||||
class PlayerOverlay extends HookConsumerWidget {
|
class PlayerOverlay extends HookConsumerWidget {
|
||||||
final String albumArt;
|
final String albumArt;
|
||||||
@ -21,6 +22,9 @@ class PlayerOverlay extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
final paletteColor = usePaletteColor(albumArt, ref);
|
final paletteColor = usePaletteColor(albumArt, ref);
|
||||||
|
final layoutMode = ref.watch(
|
||||||
|
userPreferencesProvider.select((s) => s.layoutMode),
|
||||||
|
);
|
||||||
|
|
||||||
var isHome = GoRouter.of(context).location == "/";
|
var isHome = GoRouter.of(context).location == "/";
|
||||||
final isAllowedPage = ["/playlist/", "/album/"].any(
|
final isAllowedPage = ["/playlist/", "/album/"].any(
|
||||||
@ -36,8 +40,17 @@ class PlayerOverlay extends HookConsumerWidget {
|
|||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
duration: const Duration(milliseconds: 2500),
|
duration: const Duration(milliseconds: 2500),
|
||||||
right: (breakpoint.isMd && !isAllowedPage ? 10 : 5),
|
right: (breakpoint.isMd && !isAllowedPage ? 10 : 5),
|
||||||
left: (breakpoint.isSm || isAllowedPage ? 5 : 90),
|
left: (layoutMode == LayoutMode.compact ||
|
||||||
bottom: (breakpoint.isSm && !isAllowedPage ? 63 : 10),
|
(breakpoint.isSm && layoutMode == LayoutMode.adaptive) ||
|
||||||
|
isAllowedPage
|
||||||
|
? 5
|
||||||
|
: 90),
|
||||||
|
bottom: (layoutMode == LayoutMode.compact && !isAllowedPage) ||
|
||||||
|
(breakpoint.isSm &&
|
||||||
|
layoutMode == LayoutMode.adaptive &&
|
||||||
|
!isAllowedPage)
|
||||||
|
? 63
|
||||||
|
: 10,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onVerticalDragEnd: (details) {
|
onVerticalDragEnd: (details) {
|
||||||
int sensitivity = 8;
|
int sensitivity = 8;
|
||||||
|
@ -123,6 +123,40 @@ class Settings extends HookConsumerWidget {
|
|||||||
style:
|
style:
|
||||||
TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||||
),
|
),
|
||||||
|
AdaptiveListTile(
|
||||||
|
leading: const Icon(Icons.dashboard_rounded),
|
||||||
|
title: const Text("Layout Mode"),
|
||||||
|
subtitle: const Text(
|
||||||
|
"Override responsive layout mode settings",
|
||||||
|
),
|
||||||
|
trailing: (context, update) => DropdownButton<LayoutMode>(
|
||||||
|
value: preferences.layoutMode,
|
||||||
|
items: const [
|
||||||
|
DropdownMenuItem(
|
||||||
|
child: Text(
|
||||||
|
"Adaptive",
|
||||||
|
),
|
||||||
|
value: LayoutMode.adaptive,
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
child: Text(
|
||||||
|
"Compact",
|
||||||
|
),
|
||||||
|
value: LayoutMode.compact,
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
child: Text("Extended"),
|
||||||
|
value: LayoutMode.extended,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
preferences.setLayoutMode(value);
|
||||||
|
update?.call(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
AdaptiveListTile(
|
AdaptiveListTile(
|
||||||
leading: const Icon(Icons.dark_mode_outlined),
|
leading: const Icon(Icons.dark_mode_outlined),
|
||||||
title: const Text("Theme"),
|
title: const Text("Theme"),
|
||||||
|
@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:spotube/utils/platform.dart';
|
||||||
|
|
||||||
final _loggerFactory = _SpotubeLogger();
|
final _loggerFactory = _SpotubeLogger();
|
||||||
|
|
||||||
@ -18,8 +19,11 @@ class _SpotubeLogger extends Logger {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void log(Level level, message, [error, StackTrace? stackTrace]) {
|
void log(Level level, message, [error, StackTrace? stackTrace]) {
|
||||||
getApplicationDocumentsDirectory().then((dir) async {
|
(kIsAndroid
|
||||||
final file = File(path.join(dir.path, ".spotube_logs"));
|
? getExternalStorageDirectory()
|
||||||
|
: getApplicationDocumentsDirectory())
|
||||||
|
.then((dir) async {
|
||||||
|
final file = File(path.join(dir!.path, ".spotube_logs"));
|
||||||
if (level == Level.error) {
|
if (level == Level.error) {
|
||||||
await file.writeAsString("[${DateTime.now()}]\n$message\n$stackTrace",
|
await file.writeAsString("[${DateTime.now()}]\n$message\n$stackTrace",
|
||||||
mode: FileMode.writeOnlyAppend);
|
mode: FileMode.writeOnlyAppend);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@ -14,6 +13,12 @@ import 'package:spotube/utils/platform.dart';
|
|||||||
import 'package:spotube/utils/primitive_utils.dart';
|
import 'package:spotube/utils/primitive_utils.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
enum LayoutMode {
|
||||||
|
compact,
|
||||||
|
extended,
|
||||||
|
adaptive,
|
||||||
|
}
|
||||||
|
|
||||||
class UserPreferences extends PersistedChangeNotifier {
|
class UserPreferences extends PersistedChangeNotifier {
|
||||||
ThemeMode themeMode;
|
ThemeMode themeMode;
|
||||||
String ytSearchFormat;
|
String ytSearchFormat;
|
||||||
@ -30,11 +35,14 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
|
|
||||||
String downloadLocation;
|
String downloadLocation;
|
||||||
|
|
||||||
|
LayoutMode layoutMode;
|
||||||
|
|
||||||
UserPreferences({
|
UserPreferences({
|
||||||
required this.geniusAccessToken,
|
required this.geniusAccessToken,
|
||||||
required this.recommendationMarket,
|
required this.recommendationMarket,
|
||||||
required this.themeMode,
|
required this.themeMode,
|
||||||
required this.ytSearchFormat,
|
required this.ytSearchFormat,
|
||||||
|
required this.layoutMode,
|
||||||
this.saveTrackLyrics = false,
|
this.saveTrackLyrics = false,
|
||||||
this.accentColorScheme = Colors.green,
|
this.accentColorScheme = Colors.green,
|
||||||
this.backgroundColorScheme = Colors.grey,
|
this.backgroundColorScheme = Colors.grey,
|
||||||
@ -126,6 +134,12 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
updatePersistence();
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setLayoutMode(LayoutMode mode) {
|
||||||
|
layoutMode = mode;
|
||||||
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> _getDefaultDownloadDirectory() async {
|
Future<String> _getDefaultDownloadDirectory() async {
|
||||||
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
||||||
return getDownloadsDirectory().then((dir) {
|
return getDownloadsDirectory().then((dir) {
|
||||||
@ -158,6 +172,11 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
skipSponsorSegments = map["skipSponsorSegments"] ?? skipSponsorSegments;
|
skipSponsorSegments = map["skipSponsorSegments"] ?? skipSponsorSegments;
|
||||||
downloadLocation =
|
downloadLocation =
|
||||||
map["downloadLocation"] ?? await _getDefaultDownloadDirectory();
|
map["downloadLocation"] ?? await _getDefaultDownloadDirectory();
|
||||||
|
|
||||||
|
layoutMode = LayoutMode.values.firstWhere(
|
||||||
|
(mode) => mode.name == map["layoutMode"],
|
||||||
|
orElse: () => kIsDesktop ? LayoutMode.extended : LayoutMode.compact,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -175,6 +194,7 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
"audioQuality": audioQuality.index,
|
"audioQuality": audioQuality.index,
|
||||||
"skipSponsorSegments": skipSponsorSegments,
|
"skipSponsorSegments": skipSponsorSegments,
|
||||||
"downloadLocation": downloadLocation,
|
"downloadLocation": downloadLocation,
|
||||||
|
"layoutMode": layoutMode.name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,5 +205,6 @@ final userPreferencesProvider = ChangeNotifierProvider(
|
|||||||
recommendationMarket: 'US',
|
recommendationMarket: 'US',
|
||||||
themeMode: ThemeMode.system,
|
themeMode: ThemeMode.system,
|
||||||
ytSearchFormat: "\$MAIN_ARTIST - \$TITLE \$FEATURED_ARTISTS",
|
ytSearchFormat: "\$MAIN_ARTIST - \$TITLE \$FEATURED_ARTISTS",
|
||||||
|
layoutMode: kIsMobile ? LayoutMode.compact : LayoutMode.adaptive,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user