From 5ad151932ab6684e3fe1c1ba2a22a8a8d64bb05b Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 09:22:30 +0600 Subject: [PATCH 01/81] feat: initial integration of shadcn-ui --- lib/main.dart | 57 ++-- lib/models/database/database.dart | 3 +- lib/modules/root/sidebar.dart | 250 ++++---------- lib/pages/settings/sections/appearance.dart | 3 +- .../user_preferences_provider.dart | 3 +- lib/utils/migrations/hive.dart | 319 ------------------ linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + macos/Podfile.lock | 31 +- pubspec.lock | 128 +++++++ pubspec.yaml | 48 +++ web/flutter_bootstrap.js | 238 +++++++++++++ .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 15 files changed, 549 insertions(+), 542 deletions(-) delete mode 100644 lib/utils/migrations/hive.dart create mode 100644 web/flutter_bootstrap.js diff --git a/lib/main.dart b/lib/main.dart index fa567129..3ed4314b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,7 +3,6 @@ import 'dart:ui'; import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_discord_rpc/flutter_discord_rpc.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -34,7 +33,6 @@ import 'package:spotube/provider/server/server.dart'; import 'package:spotube/provider/tray_manager/tray_manager.dart'; import 'package:spotube/l10n/l10n.dart'; import 'package:spotube/provider/connect/clients.dart'; -import 'package:spotube/provider/palette_provider.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/services/cli/cli.dart'; @@ -42,8 +40,6 @@ import 'package:spotube/services/kv_store/encrypted_kv_store.dart'; import 'package:spotube/services/kv_store/kv_store.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/services/wm_tools/wm_tools.dart'; -import 'package:spotube/themes/theme.dart'; -import 'package:spotube/utils/migrations/hive.dart'; import 'package:spotube/utils/migrations/sandbox.dart'; import 'package:spotube/utils/platform.dart'; import 'package:system_theme/system_theme.dart'; @@ -53,6 +49,7 @@ import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:timezone/data/latest.dart' as tz; import 'package:window_manager/window_manager.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; Future main(List rawArgs) async { if (rawArgs.contains("web_view_title_bar")) { @@ -110,8 +107,6 @@ Future main(List rawArgs) async { final database = AppDatabase(); - await migrateFromHiveToDrift(database); - if (kIsDesktop) { await localNotifier.setup(appName: "Spotube"); await WindowManagerTools.initialize(); @@ -142,13 +137,13 @@ class Spotube extends HookConsumerWidget { Widget build(BuildContext context, ref) { final themeMode = ref.watch(userPreferencesProvider.select((s) => s.themeMode)); - final accentMaterialColor = - ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme)); - final isAmoledTheme = - ref.watch(userPreferencesProvider.select((s) => s.amoledDarkTheme)); final locale = ref.watch(userPreferencesProvider.select((s) => s.locale)); - final paletteColor = - ref.watch(paletteProvider.select((s) => s?.dominantColor?.color)); + // final accentMaterialColor = + // ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme)); + // final isAmoledTheme = + // ref.watch(userPreferencesProvider.select((s) => s.amoledDarkTheme)); + // final paletteColor = + // ref.watch(paletteProvider.select((s) => s?.dominantColor?.color)); final router = ref.watch(routerProvider); final hasTouchSupport = useHasTouch(); @@ -178,20 +173,20 @@ class Spotube extends HookConsumerWidget { }; }, []); - final lightTheme = useMemoized( - () => theme(paletteColor ?? accentMaterialColor, Brightness.light, false), - [paletteColor, accentMaterialColor], - ); - final darkTheme = useMemoized( - () => theme( - paletteColor ?? accentMaterialColor, - Brightness.dark, - isAmoledTheme, - ), - [paletteColor, accentMaterialColor, isAmoledTheme], - ); + // final lightTheme = useMemoized( + // () => theme(paletteColor ?? accentMaterialColor, Brightness.light, false), + // [paletteColor, accentMaterialColor], + // ); + // final darkTheme = useMemoized( + // () => theme( + // paletteColor ?? accentMaterialColor, + // Brightness.dark, + // isAmoledTheme, + // ), + // [paletteColor, accentMaterialColor, isAmoledTheme], + // ); - return MaterialApp.router( + return ShadcnApp.router( supportedLocales: L10n.all, locale: locale.languageCode == "system" ? null : locale, localizationsDelegates: const [ @@ -221,9 +216,17 @@ class Spotube extends HookConsumerWidget { return child; }, + theme: ThemeData( + radius: .5, + iconTheme: const IconThemeProperties(), + colorScheme: ColorSchemes.lightNeutral(), + ), + darkTheme: ThemeData( + radius: .5, + iconTheme: const IconThemeProperties(), + colorScheme: ColorSchemes.darkNeutral(), + ), themeMode: themeMode, - theme: lightTheme, - darkTheme: darkTheme, shortcuts: { ...WidgetsApp.defaultShortcuts.map((key, value) { return MapEntry( diff --git a/lib/models/database/database.dart b/lib/models/database/database.dart index 0f30df19..f76d25bc 100644 --- a/lib/models/database/database.dart +++ b/lib/models/database/database.dart @@ -8,13 +8,14 @@ import 'package:encrypt/encrypt.dart'; import 'package:media_kit/media_kit.dart' hide Track; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' show ThemeMode, Colors; import 'package:spotify/spotify.dart' hide Playlist; import 'package:spotube/models/database/database.steps.dart'; import 'package:spotube/models/lyrics.dart'; import 'package:spotube/services/kv_store/encrypted_kv_store.dart'; import 'package:spotube/services/kv_store/kv_store.dart'; import 'package:spotube/services/sourced_track/enums.dart'; -import 'package:flutter/material.dart' hide Table, Key, View; +import 'package:flutter/widgets.dart' hide Table, Key, View; import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; import 'package:drift/native.dart'; import 'package:sqlite3/sqlite3.dart'; diff --git a/lib/modules/root/sidebar.dart b/lib/modules/root/sidebar.dart index f29644fb..4f3c4442 100644 --- a/lib/modules/root/sidebar.dart +++ b/lib/modules/root/sidebar.dart @@ -1,33 +1,28 @@ -import 'package:collection/collection.dart'; +import 'package:flutter/material.dart' show Badge; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:flutter/material.dart'; -import 'package:sidebarx/sidebarx.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/models/database/database.dart'; -import 'package:spotube/modules/connect/connect_device.dart'; import 'package:spotube/components/image/universal_image.dart'; +import 'package:spotube/extensions/image.dart'; +import 'package:spotube/models/database/database.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/extensions/image.dart'; -import 'package:spotube/hooks/utils/use_brightness_value.dart'; -import 'package:spotube/hooks/controllers/use_sidebarx_controller.dart'; +import 'package:spotube/modules/connect/connect_device.dart'; import 'package:spotube/pages/profile/profile.dart'; import 'package:spotube/pages/settings/settings.dart'; -import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/authentication/authentication.dart'; +import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; -import 'package:spotube/utils/platform.dart'; import 'package:spotube/utils/service_utils.dart'; -import 'package:window_manager/window_manager.dart'; class Sidebar extends HookConsumerWidget { final Widget child; @@ -66,173 +61,65 @@ class Sidebar extends HookConsumerWidget { (e) => routerState.namedLocation(e.name) == routerState.matchedLocation, ); - final controller = useSidebarXController( - selectedIndex: selectedIndex, - extended: mediaQuery.lgAndUp, - ); - - final theme = Theme.of(context); - final bg = theme.colorScheme.surfaceContainerHighest; - - final bgColor = useBrightnessValue( - Color.lerp(bg, Colors.white, 0.6), - Color.lerp(bg, Colors.black, 0.45)!, - ); - - useEffect(() { - if (!context.mounted) return; - if (mediaQuery.lgAndUp && !controller.extended) { - controller.setExtended(true); - } else if (mediaQuery.mdAndDown && controller.extended) { - controller.setExtended(false); - } - return null; - }, [mediaQuery, controller]); - - useEffect(() { - if (controller.selectedIndex != selectedIndex) { - controller.selectIndex(selectedIndex); - } - return null; - }, [selectedIndex]); - if (layoutMode == LayoutMode.compact || (mediaQuery.smAndDown && layoutMode == LayoutMode.adaptive)) { - return Scaffold(body: child); + return Scaffold(child: child); } - return Row( - children: [ - SafeArea( - child: SidebarX( - controller: controller, - items: sidebarTileList.mapIndexed( - (index, e) { - return SidebarXItem( - onTap: () { - context.goNamed(e.name); - }, - iconBuilder: (selected, hovered) { - return Badge( - backgroundColor: theme.colorScheme.primary, - isLabelVisible: e.title == "Library" && downloadCount > 0, - label: Text( - downloadCount.toString(), - style: const TextStyle( - color: Colors.white, - fontSize: 10, - ), - ), - child: Icon( - e.icon, - color: selected || hovered - ? theme.colorScheme.primary - : null, - ), - ); - }, - label: e.title, - ); - }, - ).toList(), - headerBuilder: (_, __) => const SidebarHeader(), - footerBuilder: (_, __) => const Padding( - padding: EdgeInsets.only(bottom: 5), - child: SidebarFooter(), - ), - showToggleButton: false, - theme: SidebarXTheme( - width: 50, - margin: EdgeInsets.only(bottom: 10, top: kIsMacOS ? 35 : 5), - selectedItemDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: theme.colorScheme.primary.withOpacity(0.1), - ), - selectedIconTheme: IconThemeData( - color: theme.colorScheme.primary, - ), - ), - extendedTheme: SidebarXTheme( - width: 250, - margin: EdgeInsets.only( - bottom: 10, - left: 0, - top: kIsMacOS ? 0 : 5, - ), - padding: const EdgeInsets.symmetric(horizontal: 6), - decoration: BoxDecoration( - color: bgColor?.withOpacity(0.8), - borderRadius: const BorderRadius.only( - topRight: Radius.circular(10), - bottomRight: Radius.circular(10), - ), - ), - selectedItemDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: theme.colorScheme.primary.withOpacity(0.1), - ), - selectedIconTheme: IconThemeData( - color: theme.colorScheme.primary, - ), - selectedTextStyle: theme.textTheme.bodyMedium?.copyWith( - color: theme.colorScheme.primary, - fontWeight: FontWeight.w600, - ), - itemTextPadding: const EdgeInsets.only(left: 10), - selectedItemTextPadding: const EdgeInsets.only(left: 10), - hoverTextStyle: theme.textTheme.bodyMedium?.copyWith( - color: theme.colorScheme.primary, - ), - ), - ), - ), - Expanded(child: child) - ], - ); - } -} - -class SidebarHeader extends HookWidget { - const SidebarHeader({super.key}); - - @override - Widget build(BuildContext context) { - final mediaQuery = MediaQuery.of(context); - final theme = Theme.of(context); - - if (mediaQuery.mdAndDown) { - return Container( - height: 40, - width: 40, - margin: const EdgeInsets.only(bottom: 5), - child: Sidebar.brandLogo(), - ); - } - - return DragToMoveArea( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - if (kIsMacOS) const SizedBox(height: 25), - Row( + return LayoutBuilder(builder: (context, constrains) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SafeArea( + child: Column( children: [ - Sidebar.brandLogo(), - const SizedBox(width: 10), - Text( - "Spotube", - style: theme.textTheme.titleLarge, + Expanded( + child: NavigationSidebar( + index: selectedIndex, + onSelected: (index) { + final tile = sidebarTileList[index]; + ServiceUtils.pushNamed(context, tile.name); + }, + children: [ + const NavigationLabel(child: Text("Spotube")), + for (final tile in sidebarTileList) + NavigationButton( + label: Text(tile.title), + child: Badge( + backgroundColor: context.theme.colorScheme.primary, + isLabelVisible: + tile.title == "Library" && downloadCount > 0, + label: Text( + downloadCount.toString(), + style: const TextStyle( + color: Colors.white, + fontSize: 10, + ), + ), + child: Icon(tile.icon), + ), + onChanged: (value) { + if (value) { + context.goNamed(tile.name); + } + }, + ), + ], + ), ), + const SidebarFooter(), ], ), - ], - ), - ), - ); + ), + const VerticalDivider(), + Expanded(child: child), + ], + ); + }); } } -class SidebarFooter extends HookConsumerWidget { +class SidebarFooter extends HookConsumerWidget implements NavigationBarItem { const SidebarFooter({ super.key, }); @@ -253,6 +140,7 @@ class SidebarFooter extends HookConsumerWidget { if (mediaQuery.mdAndDown) { return IconButton( + variance: ButtonVariance.ghost, icon: const Icon(SpotubeIcons.settings), onPressed: () => ServiceUtils.navigateNamed(context, SettingsPage.name), ); @@ -260,8 +148,9 @@ class SidebarFooter extends HookConsumerWidget { return Container( padding: const EdgeInsets.only(left: 12), - width: 250, + width: 180, child: Column( + mainAxisSize: MainAxisSize.min, children: [ const ConnectDeviceButton.sidebar(), const Gap(10), @@ -273,21 +162,16 @@ class SidebarFooter extends HookConsumerWidget { const CircularProgressIndicator() else if (data != null) Flexible( - child: InkWell( + child: GestureDetector( onTap: () { ServiceUtils.pushNamed(context, ProfilePage.name); }, - borderRadius: BorderRadius.circular(30), child: Row( children: [ - CircleAvatar( - backgroundImage: - UniversalImage.imageProvider(avatarImg), - onBackgroundImageError: (exception, stackTrace) => - Assets.userPlaceholder.image( - height: 16, - width: 16, - ), + Avatar( + initials: + Avatar.getInitials(data.displayName ?? "User"), + provider: UniversalImage.imageProvider(avatarImg), ), const SizedBox(width: 10), Flexible( @@ -296,8 +180,8 @@ class SidebarFooter extends HookConsumerWidget { maxLines: 1, softWrap: false, overflow: TextOverflow.fade, - style: theme.textTheme.bodyMedium - ?.copyWith(fontWeight: FontWeight.bold), + style: theme.typography.normal + .copyWith(fontWeight: FontWeight.bold), ), ), ], @@ -305,6 +189,7 @@ class SidebarFooter extends HookConsumerWidget { ), ), IconButton( + variance: ButtonVariance.ghost, icon: const Icon(SpotubeIcons.settings), onPressed: () { ServiceUtils.pushNamed(context, SettingsPage.name); @@ -316,4 +201,7 @@ class SidebarFooter extends HookConsumerWidget { ), ); } + + @override + bool get selectable => false; } diff --git a/lib/pages/settings/sections/appearance.dart b/lib/pages/settings/sections/appearance.dart index f97add42..9a95e60b 100644 --- a/lib/pages/settings/sections/appearance.dart +++ b/lib/pages/settings/sections/appearance.dart @@ -1,4 +1,5 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' hide ThemeMode; +import 'package:shadcn_flutter/shadcn_flutter.dart' show ThemeMode; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; diff --git a/lib/provider/user_preferences/user_preferences_provider.dart b/lib/provider/user_preferences/user_preferences_provider.dart index 053f0994..0f9efce1 100644 --- a/lib/provider/user_preferences/user_preferences_provider.dart +++ b/lib/provider/user_preferences/user_preferences_provider.dart @@ -1,8 +1,9 @@ import 'package:drift/drift.dart'; -import 'package:flutter/material.dart'; + import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart' as paths; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide join; import 'package:spotify/spotify.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; diff --git a/lib/utils/migrations/hive.dart b/lib/utils/migrations/hive.dart deleted file mode 100644 index e5781931..00000000 --- a/lib/utils/migrations/hive.dart +++ /dev/null @@ -1,319 +0,0 @@ -import 'package:drift/drift.dart'; -import 'package:flutter/foundation.dart'; -import 'package:hive/hive.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:spotube/models/database/database.dart' - hide - SourceType, - AudioSource, - CloseBehavior, - MusicCodec, - LayoutMode, - SearchMode, - BlacklistedType; -import 'package:spotube/models/database/database.dart' as db; -import 'package:spotube/services/kv_store/kv_store.dart'; -import 'package:spotube/services/logger/logger.dart'; -import 'package:spotube/utils/migrations/adapters.dart'; -import 'package:spotube/utils/migrations/cache_box.dart'; - -late AppDatabase _database; - -Future getHiveCacheDir() async => - kIsWeb ? null : (await getApplicationSupportDirectory()).path; - -Future migrateAuthenticationInfo() async { - AppLogger.log.i("🔵 Migrating authentication info.."); - - final box = PersistenceCacheBox( - "authentication", - encrypted: true, - fromJson: (json) => AuthenticationCredentials.fromJson(json), - ); - - final credentials = await box.getData(); - - if (credentials == null) return; - - await _database.into(_database.authenticationTable).insert( - AuthenticationTableCompanion.insert( - accessToken: DecryptedText(credentials.accessToken), - cookie: DecryptedText(credentials.cookie), - expiration: credentials.expiration, - id: const Value(0), - ), - mode: InsertMode.insertOrReplace, - ); - - AppLogger.log.i("✅ Migrated authentication info"); -} - -Future migratePreferences() async { - AppLogger.log.i("🔵 Migrating preferences.."); - final box = PersistenceCacheBox( - "preferences", - fromJson: (json) => UserPreferences.fromJson(json), - ); - - final preferences = await box.getData(); - - if (preferences == null) return; - - await _database.into(_database.preferencesTable).insert( - PreferencesTableCompanion.insert( - id: const Value(0), - accentColorScheme: Value(preferences.accentColorScheme), - albumColorSync: Value(preferences.albumColorSync), - amoledDarkTheme: Value(preferences.amoledDarkTheme), - audioQuality: Value(preferences.audioQuality), - audioSource: Value( - switch (preferences.audioSource) { - AudioSource.youtube => db.AudioSource.youtube, - AudioSource.piped => db.AudioSource.piped, - AudioSource.jiosaavn => db.AudioSource.jiosaavn, - }, - ), - checkUpdate: Value(preferences.checkUpdate), - closeBehavior: Value( - switch (preferences.closeBehavior) { - CloseBehavior.minimizeToTray => db.CloseBehavior.minimizeToTray, - CloseBehavior.close => db.CloseBehavior.close, - }, - ), - discordPresence: Value(preferences.discordPresence), - downloadLocation: Value(preferences.downloadLocation), - downloadMusicCodec: Value(preferences.downloadMusicCodec), - enableConnect: Value(preferences.enableConnect), - endlessPlayback: Value(preferences.endlessPlayback), - layoutMode: Value( - switch (preferences.layoutMode) { - LayoutMode.adaptive => db.LayoutMode.adaptive, - LayoutMode.compact => db.LayoutMode.compact, - LayoutMode.extended => db.LayoutMode.extended, - }, - ), - localLibraryLocation: Value(preferences.localLibraryLocation), - locale: Value(preferences.locale), - market: Value(preferences.recommendationMarket), - normalizeAudio: Value(preferences.normalizeAudio), - pipedInstance: Value(preferences.pipedInstance), - searchMode: Value( - switch (preferences.searchMode) { - SearchMode.youtube => db.SearchMode.youtube, - SearchMode.youtubeMusic => db.SearchMode.youtubeMusic, - }, - ), - showSystemTrayIcon: Value(preferences.showSystemTrayIcon), - skipNonMusic: Value(preferences.skipNonMusic), - streamMusicCodec: Value(preferences.streamMusicCodec), - systemTitleBar: Value(preferences.systemTitleBar), - themeMode: Value(preferences.themeMode), - ), - mode: InsertMode.replace, - ); - - AppLogger.log.i("✅ Migrated preferences"); -} - -Future migrateSkipSegment() async { - AppLogger.log.i("🔵 Migrating skip segments.."); - Hive.registerAdapter(SkipSegmentAdapter()); - - final box = await Hive.openLazyBox( - SkipSegment.boxName, - path: await getHiveCacheDir(), - ); - - final skipSegments = await Future.wait( - box.keys.map( - (key) async => ( - id: key as String, - data: await box.get(key), - ), - ), - ); - - await _database.batch((batch) { - batch.insertAll( - _database.skipSegmentTable, - skipSegments - .where((element) => element.data != null) - .expand((element) => (element.data as List).map( - (segment) => SkipSegmentTableCompanion.insert( - trackId: element.id, - start: segment["start"], - end: segment["end"], - ), - )) - .toList(), - ); - }); - - AppLogger.log.i("✅ Migrated skip segments"); -} - -Future migrateSourceMatches() async { - AppLogger.log.i("🔵 Migrating source matches.."); - - Hive.registerAdapter(SourceMatchAdapter()); - Hive.registerAdapter(SourceTypeAdapter()); - - final box = await Hive.openBox( - SourceMatch.boxName, - path: await getHiveCacheDir(), - ); - - final sourceMatches = - box.keys.map((key) => (data: box.get(key), trackId: key)); - - await _database.batch((batch) { - batch.insertAll( - _database.sourceMatchTable, - sourceMatches - .where((element) => element.data != null) - .map( - (sourceMatch) => SourceMatchTableCompanion.insert( - sourceId: sourceMatch.data!.sourceId, - trackId: sourceMatch.trackId, - sourceType: Value( - switch (sourceMatch.data!.sourceType) { - SourceType.jiosaavn => db.SourceType.jiosaavn, - SourceType.youtube => db.SourceType.youtube, - SourceType.youtubeMusic => db.SourceType.youtubeMusic, - }, - ), - ), - ) - .toList(), - ); - }); - - AppLogger.log.i("✅ Migrated source matches"); -} - -Future migrateBlacklist() async { - AppLogger.log.i("🔵 Migrating blacklist.."); - - final box = PersistenceCacheBox>( - "blacklist", - fromJson: (json) => (json["blacklist"] as List) - .map((e) => BlacklistedElement.fromJson(e)) - .toSet(), - ); - - final data = await box.getData(); - - if (data == null) return; - - await _database.batch((batch) { - batch.insertAll( - _database.blacklistTable, - data.map( - (element) => BlacklistTableCompanion.insert( - name: element.name, - elementId: element.id, - elementType: switch (element.type) { - BlacklistedType.artist => db.BlacklistedType.artist, - BlacklistedType.track => db.BlacklistedType.track, - }, - ), - ), - ); - }); - - AppLogger.log.i("✅ Migrated blacklist"); -} - -Future migrateLastFmCredentials() async { - AppLogger.log.i("🔵 Migrating Last.fm credentials.."); - - final box = PersistenceCacheBox( - "scrobbler", - fromJson: (json) => ScrobblerState.fromJson(json), - encrypted: true, - ); - - final data = await box.getData(); - - if (data == null) return; - - await _database.into(_database.scrobblerTable).insert( - ScrobblerTableCompanion.insert( - id: const Value(0), - passwordHash: DecryptedText(data.passwordHash), - username: data.username, - ), - mode: InsertMode.replace, - ); - - AppLogger.log.i("✅ Migrated Last.fm credentials"); -} - -Future migratePlaybackHistory() async { - AppLogger.log.i("🔵 Migrating playback history.."); - - final box = PersistenceCacheBox( - "playback_history", - fromJson: (json) => PlaybackHistoryState.fromJson(json), - ); - - final data = await box.getData(); - - if (data == null) return; - - await _database.batch((batch) { - batch.insertAll( - _database.historyTable, - data.items.map( - (item) => switch (item) { - PlaybackHistoryAlbum() => HistoryTableCompanion.insert( - createdAt: Value(item.date), - itemId: item.album.id!, - data: item.album.toJson(), - type: db.HistoryEntryType.album, - ), - PlaybackHistoryPlaylist() => HistoryTableCompanion.insert( - createdAt: Value(item.date), - itemId: item.playlist.id!, - data: item.playlist.toJson(), - type: db.HistoryEntryType.playlist, - ), - PlaybackHistoryTrack() => HistoryTableCompanion.insert( - createdAt: Value(item.date), - itemId: item.track.id!, - data: item.track.toJson(), - type: db.HistoryEntryType.track, - ), - _ => throw Exception("Unknown history item type"), - }, - ), - ); - }); - - AppLogger.log.i("✅ Migrated playback history"); -} - -Future migrateFromHiveToDrift(AppDatabase database) async { - if (KVStoreService.hasMigratedToDrift) return; - - await PersistenceCacheBox.initializeBoxes( - path: await getHiveCacheDir(), - ); - - _database = database; - - await migrateAuthenticationInfo(); - await migratePreferences(); - - await migrateSkipSegment(); - await migrateSourceMatches(); - - await migrateBlacklist(); - await migratePlaybackHistory(); - - await migrateLastFmCredentials(); - - await KVStoreService.setHasMigratedToDrift(true); - - AppLogger.log.i("🚀 Migrated all data to Drift"); -} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 06c33e05..476ff787 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,7 @@ #include "generated_plugin_registrant.h" +#include #include #include #include @@ -21,6 +22,9 @@ #include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin"); + audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar); g_autoptr(FlPluginRegistrar) desktop_webview_window_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopWebviewWindowPlugin"); desktop_webview_window_plugin_register_with_registrar(desktop_webview_window_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index e98b18eb..a875e8f5 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + audioplayers_linux desktop_webview_window file_selector_linux flutter_secure_storage_linux diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 608a854e..12972107 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,6 +8,7 @@ import Foundation import app_links import audio_service import audio_session +import audioplayers_darwin import bonsoir_darwin import desktop_webview_window import device_info_plus @@ -32,6 +33,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) AudioServicePlugin.register(with: registry.registrar(forPlugin: "AudioServicePlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) + AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) SwiftBonsoirPlugin.register(with: registry.registrar(forPlugin: "SwiftBonsoirPlugin")) DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index fee42515..db8ed79c 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -5,6 +5,8 @@ PODS: - FlutterMacOS - audio_session (0.0.1): - FlutterMacOS + - audioplayers_darwin (0.0.1): + - FlutterMacOS - bonsoir_darwin (0.0.1): - Flutter - FlutterMacOS @@ -46,20 +48,21 @@ PODS: - sqflite_darwin (0.0.4): - Flutter - FlutterMacOS - - sqlite3 (3.47.0): - - sqlite3/common (= 3.47.0) - - sqlite3/common (3.47.0) - - sqlite3/dbstatvtab (3.47.0): + - sqlite3 (3.47.2): + - sqlite3/common (= 3.47.2) + - sqlite3/common (3.47.2) + - sqlite3/dbstatvtab (3.47.2): - sqlite3/common - - sqlite3/fts5 (3.47.0): + - sqlite3/fts5 (3.47.2): - sqlite3/common - - sqlite3/perf-threadsafe (3.47.0): + - sqlite3/perf-threadsafe (3.47.2): - sqlite3/common - - sqlite3/rtree (3.47.0): + - sqlite3/rtree (3.47.2): - sqlite3/common - sqlite3_flutter_libs (0.0.1): + - Flutter - FlutterMacOS - - sqlite3 (~> 3.47.0) + - sqlite3 (~> 3.47.1) - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/perf-threadsafe @@ -77,6 +80,7 @@ DEPENDENCIES: - app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`) - audio_service (from `Flutter/ephemeral/.symlinks/plugins/audio_service/macos`) - audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`) + - audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos`) - bonsoir_darwin (from `Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin`) - desktop_webview_window (from `Flutter/ephemeral/.symlinks/plugins/desktop_webview_window/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) @@ -95,7 +99,7 @@ DEPENDENCIES: - screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`) - - sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`) + - sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin`) - system_theme (from `Flutter/ephemeral/.symlinks/plugins/system_theme/macos`) - tray_manager (from `Flutter/ephemeral/.symlinks/plugins/tray_manager/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) @@ -113,6 +117,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/audio_service/macos audio_session: :path: Flutter/ephemeral/.symlinks/plugins/audio_session/macos + audioplayers_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos bonsoir_darwin: :path: Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin desktop_webview_window: @@ -150,7 +156,7 @@ EXTERNAL SOURCES: sqflite_darwin: :path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin sqlite3_flutter_libs: - :path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos + :path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin system_theme: :path: Flutter/ephemeral/.symlinks/plugins/system_theme/macos tray_manager: @@ -164,6 +170,7 @@ SPEC CHECKSUMS: app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a audio_service: b88ff778e0e3915efd4cd1a5ad6f0beef0c950a9 audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72 + audioplayers_darwin: dcad41de4fbd0099cb3749f7ab3b0cb8f70b810c bonsoir_darwin: e3b8526c42ca46a885142df84229131dfabea842 desktop_webview_window: 89bb3d691f4c80314a10be312f4cd35db93a9d5a device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215 @@ -183,8 +190,8 @@ SPEC CHECKSUMS: screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d - sqlite3: 0aa20658a9b238a3b1ff7175eb7bdd863b0ab4fd - sqlite3_flutter_libs: f0b7a85544d8bac7b8bac12eac7d05bcfdd786d0 + sqlite3: 7559e33dae4c78538df563795af3a86fc887ee71 + sqlite3_flutter_libs: 1b4e98da20ebd4e9b1240269b78cdcf492dbe9f3 system_theme: c7b9f6659a5caa26c9bc2284da096781e9a6fcbc tray_manager: 9064e219c56d75c476e46b9a21182087930baf90 url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 diff --git a/pubspec.lock b/pubspec.lock index 5aa4f9b4..b58c16b8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -142,6 +142,62 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.21" + audioplayers: + dependency: transitive + description: + name: audioplayers + sha256: c346ba5a39dc208f1bab55fc239855f573d69b0e832402114bf0b793622adc4d + url: "https://pub.dev" + source: hosted + version: "6.1.0" + audioplayers_android: + dependency: transitive + description: + name: audioplayers_android + sha256: de576b890befe27175c2f511ba8b742bec83765fa97c3ce4282bba46212f58e4 + url: "https://pub.dev" + source: hosted + version: "5.0.0" + audioplayers_darwin: + dependency: transitive + description: + name: audioplayers_darwin + sha256: e507887f3ff18d8e5a10a668d7bedc28206b12e10b98347797257c6ae1019c3b + url: "https://pub.dev" + source: hosted + version: "6.0.0" + audioplayers_linux: + dependency: transitive + description: + name: audioplayers_linux + sha256: "3d3d244c90436115417f170426ce768856d8fe4dfc5ed66a049d2890acfa82f9" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + audioplayers_platform_interface: + dependency: transitive + description: + name: audioplayers_platform_interface + sha256: "6834dd48dfb7bc6c2404998ebdd161f79cd3774a7e6779e1348d54a3bfdcfaa5" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + audioplayers_web: + dependency: transitive + description: + name: audioplayers_web + sha256: "3609bdf0e05e66a3d9750ee40b1e37f2a622c4edb796cc600b53a90a30a2ace4" + url: "https://pub.dev" + source: hosted + version: "5.0.1" + audioplayers_windows: + dependency: transitive + description: + name: audioplayers_windows + sha256: "8605762dddba992138d476f6a0c3afd9df30ac5b96039929063eceed416795c2" + url: "https://pub.dev" + source: hosted + version: "4.0.0" auto_size_text: dependency: "direct main" description: @@ -390,6 +446,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + country_flags: + dependency: transitive + description: + name: country_flags + sha256: dad797491167a5b8dee465b969cb756795d842fdfc3fc1ff93f22e9c1884b73d + url: "https://pub.dev" + source: hosted + version: "3.1.0" coverage: dependency: transitive description: @@ -462,6 +526,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + data_widget: + dependency: transitive + description: + name: data_widget + sha256: "95388df890189014f702b7e93f9de6bcf7d45143a99f6288f31899f10be441ba" + url: "https://pub.dev" + source: hosted + version: "0.0.2" dbus: dependency: transitive description: @@ -552,6 +624,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.15" + email_validator: + dependency: transitive + description: + name: email_validator + sha256: b19aa5d92fdd76fbc65112060c94d45ba855105a28bb6e462de7ff03b12fa1fb + url: "https://pub.dev" + source: hosted + version: "3.0.0" encrypt: dependency: "direct main" description: @@ -1276,6 +1356,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.0" + jovial_misc: + dependency: transitive + description: + name: jovial_misc + sha256: "4b10a4cac4f492d9692e97699bff775efa84abdba29909124cbccf3126e31cea" + url: "https://pub.dev" + source: hosted + version: "0.9.0" + jovial_svg: + dependency: transitive + description: + name: jovial_svg + sha256: ca14d42956b9949c36333065c9141f100e930c918f57f4bd8dd59d35581bd3fc + url: "https://pub.dev" + source: hosted + version: "1.1.24" js: dependency: transitive description: @@ -1740,6 +1836,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.2" + phonecodes: + dependency: transitive + description: + name: phonecodes + sha256: "094a76b0ba3d8f9c1c83044ae8783d46e6906703c86eb08facd876844c264bf5" + url: "https://pub.dev" + source: hosted + version: "0.0.3" piped_client: dependency: "direct main" description: @@ -1748,6 +1852,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.1" + pixel_snap: + dependency: transitive + description: + name: pixel_snap + sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0" + url: "https://pub.dev" + source: hosted + version: "0.1.5" platform: dependency: transitive description: @@ -1925,6 +2037,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + shadcn_flutter: + dependency: "direct main" + description: + name: shadcn_flutter + sha256: eaf10ec804beddf2059dd55b802188b64277a5e4fc577defbc7c012253caef1a + url: "https://pub.dev" + source: hosted + version: "0.0.23" shared_preferences: dependency: "direct main" description: @@ -2258,6 +2378,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.0+3" + syntax_highlight: + dependency: transitive + description: + name: syntax_highlight + sha256: ee33b6aa82cc722bb9b40152a792181dee222353b486c0255fde666a3e3a4997 + url: "https://pub.dev" + source: hosted + version: "0.4.0" system_theme: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 3866e410..c9a6f341 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -102,6 +102,7 @@ dependencies: ref: dart-3-support url: https://github.com/KRTirtho/scrobblenaut.git scroll_to_index: ^3.0.1 + shadcn_flutter: ^0.0.23 shared_preferences: ^2.2.3 shelf: ^1.4.1 shelf_router: ^1.1.4 @@ -165,6 +166,53 @@ flutter: - assets/logos/ - assets/backgrounds/ - LICENSE + fonts: + - family: GeistSans + fonts: + - asset: packages/shadcn_flutter/fonts/Geist-Black.otf + weight: 800 + - asset: packages/shadcn_flutter/fonts/Geist-Bold.otf + weight: 700 + - asset: packages/shadcn_flutter/fonts/Geist-Light.otf + weight: 300 + - asset: packages/shadcn_flutter/fonts/Geist-Medium.otf + weight: 500 + - asset: packages/shadcn_flutter/fonts/Geist-SemiBold.otf + weight: 600 + - asset: packages/shadcn_flutter/fonts/Geist-Thin.otf + weight: 100 + - asset: packages/shadcn_flutter/fonts/Geist-UltraBlack.otf + weight: 900 + - asset: packages/shadcn_flutter/fonts/Geist-UltraLight.otf + weight: 200 + - asset: packages/shadcn_flutter/fonts/Geist-Regular.otf + weight: 400 + - family: GeistMono + fonts: + - asset: packages/shadcn_flutter/fonts/GeistMono-Black.otf + weight: 800 + - asset: packages/shadcn_flutter/fonts/GeistMono-Bold.otf + weight: 700 + - asset: packages/shadcn_flutter/fonts/GeistMono-Light.otf + weight: 300 + - asset: packages/shadcn_flutter/fonts/GeistMono-Medium.otf + weight: 500 + - asset: packages/shadcn_flutter/fonts/GeistMono-Regular.otf + weight: 400 + - asset: packages/shadcn_flutter/fonts/GeistMono-SemiBold.otf + weight: 600 + - asset: packages/shadcn_flutter/fonts/GeistMono-Thin.otf + weight: 100 + - asset: packages/shadcn_flutter/fonts/GeistMono-UltraBlack.otf + weight: 900 + - asset: packages/shadcn_flutter/fonts/GeistMono-UltraLight.otf + weight: 200 + - family: RadixIcons + fonts: + - asset: packages/shadcn_flutter/icons/RadixIcons.otf + - family: BootstrapIcons + fonts: + - asset: packages/shadcn_flutter/icons/BootstrapIcons.otf flutter_gen: output: lib/collections diff --git a/web/flutter_bootstrap.js b/web/flutter_bootstrap.js new file mode 100644 index 00000000..a9f703d6 --- /dev/null +++ b/web/flutter_bootstrap.js @@ -0,0 +1,238 @@ +const words = [ + 'Something is happening. Please wait.', + 'Please be patient. This may take a while.', + 'While you wait, please consider that this is a good time to take a break.', + 'Please wait. This is a good time to go grab a cup of coffee.', + 'Sometimes the things that are worth waiting for take time.', + 'Please wait. This is a good time to stretch your legs.', + 'Posture check! Please wait while we load the application.', +]; + +const loaderWidget = ` +
+ Loading Application... +
+ ${words[Math.floor(Math.random() * words.length)]} +
+
` + +const shadcn_flutter_config = { + loaderWidget: loaderWidget, + backgroundColor: null, + foregroundColor: null, + loaderColor: null, + fontFamily: 'Geist Sans', + fontSize: '24px', + fontWeight: '400', + mainAxisAlignment: 'end', + crossAxisAlignment: 'end', + externalScripts: [ + { + src: 'https://cdn.jsdelivr.net/npm/@fontsource/geist-sans@5.0.3/400.min.css', + type: 'stylesheet', + }, + { + src: 'https://cdn.jsdelivr.net/npm/@fontsource/geist-sans@5.0.3/300.min.css', + type: 'stylesheet', + }, + ] +}; + +{{flutter_js}} +{{flutter_build_config}} + +class ShadcnAppConfig { + background; + foreground; + fontFamily; + fontSize; + fontWeight; + mainAxisAlignment; + crossAxisAlignment; + loaderWidget; + loaderColor; + externalScripts; + + constructor({ background, foreground, fontFamily, fontSize, fontWeight, mainAxisAlignment, crossAxisAlignment, loaderWidget, loaderColor, externalScripts }) { + this.background = background; + this.foreground = foreground; + this.fontFamily = fontFamily; + this.fontSize = fontSize; + this.fontWeight = fontWeight; + this.mainAxisAlignment = mainAxisAlignment; + this.crossAxisAlignment = crossAxisAlignment; + this.loaderWidget = loaderWidget; + this.loaderColor = loaderColor; + this.externalScripts = externalScripts; + + if (this.background == null) { + this.background = localStorage.getItem('shadcn_flutter.background') || '#09090b'; + } + if (this.foreground == null) { + this.foreground = localStorage.getItem('shadcn_flutter.foreground') || '#ffffff'; + } + if (this.loaderColor == null) { + this.loaderColor = localStorage.getItem('shadcn_flutter.primary') || '#3c83f6'; + } + } +} + +class ShadcnAppThemeChangedEvent extends CustomEvent { + constructor(theme) { + super('shadcn_flutter_theme_changed', { detail: theme }); + } +} + +class ShadcnAppTheme { + background; + foreground; + primary; + + constructor(background, foreground, primary) { + this.background = background; + this.foreground = foreground; + this.primary = primary; + } +} + +class ShadcnApp { + config; + + constructor(config) { + this.config = config; + } + + loadApp() { + window.addEventListener('shadcn_flutter_app_ready', this.onAppReady); + window.addEventListener('shadcn_flutter_theme_changed', this.onThemeChanged); + this.#initializeDocument(); + let externalScriptIndex = 0; + this.#loadExternalScripts(externalScriptIndex, () => { + _flutter.loader.load({ + onEntrypointLoaded: async function(engineInitializer) { + const appRunner = await engineInitializer.initializeEngine(); + await appRunner.runApp(); + } + }); + }); + } + + #loadExternalScripts(index, onDone) { + if (index >= this.config.externalScripts.length) { + onDone(); + return; + } + this.#loadScriptDynamically(this.config.externalScripts[index], () => { + this.#loadExternalScripts(index + 1, onDone); + }); + } + + #createStyleSheet(css) { + const style = document.createElement('style'); + style.type = 'text/css'; + style.appendChild(document.createTextNode(css)); + document.head.appendChild(style); + } + + #loadScriptDynamically(src, callback) { + if (typeof src === 'string') { + src = { src: src, type: 'script' }; + } + if (src.type === 'script') { + const script = document.createElement('script'); + script.src = src.src; + script.onload = callback; + document.body.appendChild(script); + } else if (src.type === 'module') { + const script = document.createElement('script'); + script.type = 'module'; + script.src = src.src; + script.onload = callback; + document.body.appendChild(script); + } else if (src.type === 'stylesheet') { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = src.src; + link.onload = callback; + document.head.appendChild(link); + } else { + throw new Error('Unknown type of file to load: ' + src); + } + } + + #initializeDocument() { + const loaderStyle = ` + display: flex; + justify-content: ${this.config.mainAxisAlignment}; + align-items: ${this.config.crossAxisAlignment}; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: ${this.config.background}; + color: ${this.config.foreground}; + z-index: 9998; + font-family: ${this.config.fontFamily}; + font-size: ${this.config.fontSize}; + font-weight: ${this.config.fontWeight}; + text-align: center; + transition: opacity 0.5s; + opacity: 1; + pointer-events: initial; + `; + + const loaderBarCss = ` + .loader { + height: 7px; + background: repeating-linear-gradient(-45deg,${this.config.loaderColor} 0 15px,#000 0 20px) left/200% 100%; + animation: l3 20s infinite linear; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 9999; + } + @keyframes l3 { + 100% {background-position:right} + }`; + + const loaderDiv = document.createElement('div'); + loaderDiv.style.cssText = loaderStyle; + loaderDiv.innerHTML = this.config.loaderWidget; + + document.body.appendChild(loaderDiv); + + document.body.style.backgroundColor = this.config.background; + + const loaderBarDiv = document.createElement('div'); + loaderBarDiv.className = 'loader'; + loaderDiv.appendChild(loaderBarDiv); + + this.#createStyleSheet(loaderBarCss); + } + + onAppReady() { + const loaderDiv = document.querySelector('div'); + loaderDiv.style.opacity = 0; + loaderDiv.style.pointerEvents = 'none'; + } + + onThemeChanged(event) { + let theme = event.detail; + let background = theme['background']; + let foreground = theme['foreground']; + let primary = theme['primary']; + localStorage.setItem('shadcn_flutter.background', background); + localStorage.setItem('shadcn_flutter.foreground', foreground); + localStorage.setItem('shadcn_flutter.primary', primary); + } +} + +globalThis.ShadcnApp = ShadcnApp; +globalThis.ShadcnAppConfig = ShadcnAppConfig; +globalThis.ShadcnAppThemeChangedEvent = ShadcnAppThemeChangedEvent; +globalThis.ShadcnAppTheme = ShadcnAppTheme; + +const shadcn_flutter = new ShadcnApp(new ShadcnAppConfig(shadcn_flutter_config)); +shadcn_flutter.loadApp(); \ No newline at end of file diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 42fa2129..7c490ef1 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include #include @@ -25,6 +26,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { AppLinksPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("AppLinksPluginCApi")); + AudioplayersWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); BonsoirWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("BonsoirWindowsPluginCApi")); DesktopWebviewWindowPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index cf14ec52..dfcc70cf 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST app_links + audioplayers_windows bonsoir_windows desktop_webview_window file_selector_windows From e73d2d06d8a6cbedcede47c12c4bed38b3ff8c99 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 09:28:55 +0600 Subject: [PATCH 02/81] refactor: use shadcn NavigationBar for mobile navigation bar --- lib/modules/root/spotube_navigation_bar.dart | 63 ++++++-------------- 1 file changed, 17 insertions(+), 46 deletions(-) diff --git a/lib/modules/root/spotube_navigation_bar.dart b/lib/modules/root/spotube_navigation_bar.dart index 978891b8..c2cf4b5a 100644 --- a/lib/modules/root/spotube_navigation_bar.dart +++ b/lib/modules/root/spotube_navigation_bar.dart @@ -1,10 +1,8 @@ -import 'dart:ui'; - -import 'package:curved_navigation_bar/curved_navigation_bar.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show Badge; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/extensions/constrains.dart'; @@ -25,7 +23,6 @@ class SpotubeNavigationBar extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final theme = Theme.of(context); final routerState = GoRouterState.of(context); final downloadCount = ref.watch(downloadManagerProvider).$downloadCount; @@ -33,11 +30,6 @@ class SpotubeNavigationBar extends HookConsumerWidget { final layoutMode = ref.watch(userPreferencesProvider.select((s) => s.layoutMode)); - final buttonColor = useBrightnessValue( - theme.colorScheme.inversePrimary, - theme.colorScheme.primary.withOpacity(0.2), - ); - final navbarTileList = useMemoized( () => getNavbarTileList(context.l10n), [context.l10n], @@ -61,42 +53,21 @@ class SpotubeNavigationBar extends HookConsumerWidget { return AnimatedContainer( duration: const Duration(milliseconds: 100), - height: panelHeight, - child: ClipRect( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), - child: CurvedNavigationBar( - backgroundColor: - theme.colorScheme.secondaryContainer.withOpacity(0.72), - buttonBackgroundColor: buttonColor, - color: theme.colorScheme.surface, - height: panelHeight, - animationDuration: const Duration(milliseconds: 350), - items: navbarTileList.map( - (e) { - /// Using this [Builder] as an workaround for the first item's - /// icon color not updating unless navigating to another page - return Builder(builder: (context) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: Badge( - isLabelVisible: e.id == "library" && downloadCount > 0, - label: Text(downloadCount.toString()), - child: Icon( - e.icon, - color: Theme.of(context).colorScheme.primary, - ), - ), - ); - }); - }, - ).toList(), - index: selectedIndex, - onTap: (i) { - ServiceUtils.navigateNamed(context, navbarTileList[i].name); - }, - ), - ), + child: NavigationBar( + index: selectedIndex, + onSelected: (i) { + ServiceUtils.navigateNamed(context, navbarTileList[i].name); + }, + children: [ + for (final tile in navbarTileList) + NavigationButton( + child: Badge( + isLabelVisible: tile.id == "library" && downloadCount > 0, + label: Text(downloadCount.toString()), + child: Icon(tile.icon), + ), + ) + ], ), ); } From fe2f0a373f9c0e01c95fc64c744120bd359d646b Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 09:34:56 +0600 Subject: [PATCH 03/81] refactor: use NavigationSidebar and NavigationRail for desktop sidebar --- lib/modules/root/sidebar.dart | 107 +++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 48 deletions(-) diff --git a/lib/modules/root/sidebar.dart b/lib/modules/root/sidebar.dart index 4f3c4442..79e8d6d4 100644 --- a/lib/modules/root/sidebar.dart +++ b/lib/modules/root/sidebar.dart @@ -66,56 +66,67 @@ class Sidebar extends HookConsumerWidget { return Scaffold(child: child); } - return LayoutBuilder(builder: (context, constrains) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SafeArea( - child: Column( - children: [ - Expanded( - child: NavigationSidebar( - index: selectedIndex, - onSelected: (index) { - final tile = sidebarTileList[index]; - ServiceUtils.pushNamed(context, tile.name); - }, - children: [ - const NavigationLabel(child: Text("Spotube")), - for (final tile in sidebarTileList) - NavigationButton( - label: Text(tile.title), - child: Badge( - backgroundColor: context.theme.colorScheme.primary, - isLabelVisible: - tile.title == "Library" && downloadCount > 0, - label: Text( - downloadCount.toString(), - style: const TextStyle( - color: Colors.white, - fontSize: 10, - ), - ), - child: Icon(tile.icon), - ), - onChanged: (value) { - if (value) { - context.goNamed(tile.name); - } - }, - ), - ], - ), - ), - const SidebarFooter(), - ], + final navigationButtons = [ + NavigationLabel( + child: mediaQuery.lgAndUp ? const Text("Spotube") : const Text(""), + ), + for (final tile in sidebarTileList) + NavigationButton( + label: mediaQuery.lgAndUp ? Text(tile.title) : null, + child: Badge( + backgroundColor: context.theme.colorScheme.primary, + isLabelVisible: tile.title == "Library" && downloadCount > 0, + label: Text( + downloadCount.toString(), + style: const TextStyle( + color: Colors.white, + fontSize: 10, + ), ), + child: Icon(tile.icon), ), - const VerticalDivider(), - Expanded(child: child), - ], - ); - }); + onChanged: (value) { + if (value) { + context.goNamed(tile.name); + } + }, + ), + ]; + + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SafeArea( + child: Column( + children: [ + Expanded( + child: mediaQuery.lgAndUp + ? NavigationSidebar( + index: selectedIndex, + onSelected: (index) { + final tile = sidebarTileList[index]; + ServiceUtils.pushNamed(context, tile.name); + }, + children: navigationButtons, + ) + : NavigationRail( + alignment: NavigationRailAlignment.start, + index: selectedIndex, + onSelected: (index) { + final tile = sidebarTileList[index]; + ServiceUtils.pushNamed(context, tile.name); + }, + children: navigationButtons, + ), + ), + const SidebarFooter(), + ], + ), + ), + const VerticalDivider(), + Expanded(child: child), + ], + ); } } From 04190f2ddaa644c511edce7e55c0d4e749b6de70 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 12:42:51 +0600 Subject: [PATCH 04/81] refactor: use DropdownMenu for adaptive pop sheet list, shadcn widgets for bottom player and player controls and actions --- .../adaptive/adaptive_pop_sheet_list.dart | 284 +++++++----------- lib/components/sort_tracks_dropdown.dart | 32 +- lib/components/track_tile/track_options.dart | 85 +++--- .../sections/body/track_view_options.dart | 16 +- lib/main.dart | 6 +- lib/modules/player/player_actions.dart | 132 ++++---- lib/modules/player/player_controls.dart | 240 +++++++-------- lib/modules/player/volume_slider.dart | 20 +- lib/modules/root/bottom_player.dart | 103 +++---- 9 files changed, 438 insertions(+), 480 deletions(-) diff --git a/lib/components/adaptive/adaptive_pop_sheet_list.dart b/lib/components/adaptive/adaptive_pop_sheet_list.dart index 97dc6132..5345199e 100644 --- a/lib/components/adaptive/adaptive_pop_sheet_list.dart +++ b/lib/components/adaptive/adaptive_pop_sheet_list.dart @@ -1,56 +1,34 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show ListTile, showModalBottomSheet; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/extensions/constrains.dart'; -_emptyCB() {} - -class PopSheetEntry extends ListTile { +class AdaptiveMenuButton extends MenuButton { final T? value; - const PopSheetEntry({ - this.value, + const AdaptiveMenuButton({ super.key, - super.leading, - super.title, - super.subtitle, + this.value, + required super.child, + super.subMenu, + super.onPressed, super.trailing, - super.isThreeLine = false, - super.dense, - super.visualDensity, - super.shape, - super.style, - super.selectedColor, - super.iconColor, - super.textColor, - super.titleTextStyle, - super.subtitleTextStyle, - super.leadingAndTrailingTextStyle, - super.contentPadding, + super.leading, super.enabled = true, - super.onTap = _emptyCB, - super.onLongPress, - super.onFocusChange, - super.mouseCursor, - super.selected = false, - super.focusColor, - super.hoverColor, - super.splashColor, super.focusNode, - super.autofocus = false, - super.tileColor, - super.selectedTileColor, - super.enableFeedback, - super.horizontalTitleGap, - super.minVerticalPadding, - super.minLeadingWidth, - super.titleAlignment, - }); + super.autoClose = true, + super.popoverController, + }) : assert( + value != null || onPressed != null, + 'Either value or onPressed must be provided', + ); } /// An adaptive widget that shows a [PopupMenuButton] when screen size is above /// or equal to 640px /// In smaller screen, a [IconButton] with a [showModalBottomSheet] is shown class AdaptivePopSheetList extends StatelessWidget { - final List> children; + final List> children; final Widget? icon; final Widget? child; final bool useRootNavigator; @@ -59,7 +37,6 @@ class AdaptivePopSheetList extends StatelessWidget { final String? tooltip; final ValueChanged? onSelected; - final BorderRadius borderRadius; final Offset offset; const AdaptivePopSheetList({ @@ -70,7 +47,6 @@ class AdaptivePopSheetList extends StatelessWidget { this.useRootNavigator = true, this.headings, this.onSelected, - this.borderRadius = const BorderRadius.all(Radius.circular(999)), this.tooltip, this.offset = Offset.zero, }) : assert( @@ -78,158 +54,128 @@ class AdaptivePopSheetList extends StatelessWidget { 'Either icon or child must be provided', ); - Future showPopupMenu(BuildContext context, RelativeRect position) { + Future showDropdownMenu(BuildContext context, Offset position) async { final mediaQuery = MediaQuery.of(context); + final childrenModified = children.map((s) { + if (s.onPressed == null) { + return MenuButton( + key: s.key, + autoClose: s.autoClose, + enabled: s.enabled, + leading: s.leading, + focusNode: s.focusNode, + onPressed: (context) { + if (s.value != null) { + onSelected?.call(s.value as T); + } + }, + popoverController: s.popoverController, + subMenu: s.subMenu, + trailing: s.trailing, + child: s.child, + ); + } + return s; + }).toList(); - return showMenu( + if (mediaQuery.mdAndUp) { + await showDropdown( + context: context, + rootOverlay: useRootNavigator, + // heightConstraint: PopoverConstraint.anchorFixedSize, + // constraints: BoxConstraints( + // maxHeight: mediaQuery.size.height * 0.6, + // ), + position: position, + builder: (context) { + return DropdownMenu( + children: childrenModified, + ); + }, + ).future; + return; + } + + showModalBottomSheet( context: context, - useRootNavigator: useRootNavigator, - constraints: BoxConstraints( - maxHeight: mediaQuery.size.height * 0.6, + enableDrag: true, + showDragHandle: true, + useRootNavigator: true, + shape: RoundedRectangleBorder( + borderRadius: context.theme.borderRadiusMd, ), - position: position, - items: children - .map( - (item) => PopupMenuItem( - padding: EdgeInsets.zero, - enabled: false, - child: _AdaptivePopSheetListItem( - item: item, - onSelected: onSelected, - ), - ), - ) - .toList(), + backgroundColor: context.theme.colorScheme.card, + builder: (context) { + return ListView.builder( + physics: const NeverScrollableScrollPhysics(), + itemCount: childrenModified.length, + shrinkWrap: true, + itemBuilder: (context, index) { + final data = childrenModified[index]; + + return ListTile( + dense: true, + leading: data.leading, + title: data.child, + enabled: data.enabled, + trailing: data.trailing, + focusNode: data.focusNode, + onTap: () { + data.onPressed?.call(context); + if (data.autoClose) { + Navigator.of(context).pop(); + } + }, + ); + }, + ); + }, ); } @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); - final theme = Theme.of(context); if (mediaQuery.mdAndUp) { - return PopupMenuButton( - icon: icon, - tooltip: tooltip, - offset: offset, - child: child == null ? null : IgnorePointer(child: child), - itemBuilder: (context) => children - .map( - (item) => PopupMenuItem( - padding: EdgeInsets.zero, - enabled: false, - child: _AdaptivePopSheetListItem( - item: item, - onSelected: onSelected, - ), + return Tooltip( + tooltip: Text(tooltip ?? ''), + child: IconButton.ghost( + icon: icon ?? const Icon(SpotubeIcons.moreVertical), + onPressed: () { + final renderBox = context.findRenderObject() as RenderBox; + final position = RelativeRect.fromRect( + Rect.fromPoints( + renderBox.localToGlobal(Offset.zero, + ancestor: context.findRenderObject()), + renderBox.localToGlobal(renderBox.size.bottomRight(Offset.zero), + ancestor: context.findRenderObject()), ), - ) - .toList(), - ); - } - - void showSheet() { - showModalBottomSheet( - context: context, - useRootNavigator: useRootNavigator, - isScrollControlled: true, - showDragHandle: true, - constraints: BoxConstraints( - maxHeight: mediaQuery.size.height * 0.6, + Offset.zero & mediaQuery.size, + ); + final offset = Offset(position.left, position.top); + showDropdownMenu(context, offset); + }, ), - builder: (context) { - return Padding( - padding: const EdgeInsets.all(8.0).copyWith(top: 0), - child: DefaultTextStyle( - style: theme.textTheme.titleMedium!, - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (headings != null) ...[ - ...headings!, - const SizedBox(height: 8), - Divider( - color: theme.colorScheme.primary, - thickness: 0.3, - endIndent: 16, - indent: 16, - ), - ], - ...children.map( - (item) => _AdaptivePopSheetListItem( - item: item, - onSelected: onSelected, - ), - ) - ], - ), - ), - ), - ); - }, ); } if (child != null) { return Tooltip( - message: tooltip ?? '', - child: InkWell( - onTap: showSheet, - borderRadius: borderRadius, + tooltip: Text(tooltip ?? ''), + child: Button( + onPressed: () => showDropdownMenu(context, Offset.zero), + style: const ButtonStyle.ghost(), child: IgnorePointer(child: child), ), ); } - return IconButton( - icon: icon ?? const Icon(SpotubeIcons.moreVertical), - tooltip: tooltip, - style: theme.iconButtonTheme.style?.copyWith( - shape: WidgetStatePropertyAll( - RoundedRectangleBorder( - borderRadius: borderRadius, - ), - ), - ), - onPressed: showSheet, - ); - } -} - -class _AdaptivePopSheetListItem extends StatelessWidget { - final PopSheetEntry item; - final ValueChanged? onSelected; - const _AdaptivePopSheetListItem({ - super.key, - required this.item, - this.onSelected, - }); - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - - return InkWell( - borderRadius: (theme.listTileTheme.shape as RoundedRectangleBorder?) - ?.borderRadius as BorderRadius? ?? - const BorderRadius.all(Radius.circular(10)), - onTap: !item.enabled - ? null - : () { - item.onTap?.call(); - if (item.value != null) { - Navigator.pop(context); - onSelected?.call(item.value as T); - } - }, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: IconTheme.merge( - data: const IconThemeData(opacity: 1), - child: IgnorePointer(child: item), - ), + return Tooltip( + tooltip: Text(tooltip ?? ''), + child: IconButton.ghost( + icon: icon ?? const Icon(SpotubeIcons.moreVertical), + onPressed: () => showDropdownMenu(context, Offset.zero), ), ); } diff --git a/lib/components/sort_tracks_dropdown.dart b/lib/components/sort_tracks_dropdown.dart index 16727013..4f65e738 100644 --- a/lib/components/sort_tracks_dropdown.dart +++ b/lib/components/sort_tracks_dropdown.dart @@ -23,45 +23,45 @@ class SortTracksDropdown extends StatelessWidget { ), child: AdaptivePopSheetList( children: [ - PopSheetEntry( + AdaptiveMenuButton( value: SortBy.none, enabled: value != SortBy.none, - title: Text(context.l10n.none), + child: Text(context.l10n.none), ), - PopSheetEntry( + AdaptiveMenuButton( value: SortBy.ascending, enabled: value != SortBy.ascending, - title: Text(context.l10n.sort_a_z), + child: Text(context.l10n.sort_a_z), ), - PopSheetEntry( + AdaptiveMenuButton( value: SortBy.descending, enabled: value != SortBy.descending, - title: Text(context.l10n.sort_z_a), + child: Text(context.l10n.sort_z_a), ), - PopSheetEntry( + AdaptiveMenuButton( value: SortBy.newest, enabled: value != SortBy.newest, - title: Text(context.l10n.sort_newest), + child: Text(context.l10n.sort_newest), ), - PopSheetEntry( + AdaptiveMenuButton( value: SortBy.oldest, enabled: value != SortBy.oldest, - title: Text(context.l10n.sort_oldest), + child: Text(context.l10n.sort_oldest), ), - PopSheetEntry( + AdaptiveMenuButton( value: SortBy.duration, enabled: value != SortBy.duration, - title: Text(context.l10n.sort_duration), + child: Text(context.l10n.sort_duration), ), - PopSheetEntry( + AdaptiveMenuButton( value: SortBy.artist, enabled: value != SortBy.artist, - title: Text(context.l10n.sort_artist), + child: Text(context.l10n.sort_artist), ), - PopSheetEntry( + AdaptiveMenuButton( value: SortBy.album, enabled: value != SortBy.album, - title: Text(context.l10n.sort_album), + child: Text(context.l10n.sort_album), ), ], headings: [ diff --git a/lib/components/track_tile/track_options.dart b/lib/components/track_tile/track_options.dart index d2cb92cf..28a85fd1 100644 --- a/lib/components/track_tile/track_options.dart +++ b/lib/components/track_tile/track_options.dart @@ -5,7 +5,8 @@ import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotify/spotify.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotify/spotify.dart' hide Offset; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; @@ -332,38 +333,46 @@ class TrackOptions extends HookConsumerWidget { ], children: [ if (isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.delete, leading: const Icon(SpotubeIcons.trash), - title: Text(context.l10n.delete), + child: Text(context.l10n.delete), ), if (mediaQuery.smAndDown && !isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.album, leading: const Icon(SpotubeIcons.album), - title: Text(context.l10n.go_to_album), - subtitle: Text(track.album!.name!), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(context.l10n.go_to_album), + Text( + track.album!.name!, + style: context.theme.typography.xSmall, + ), + ], + ), ), if (!playlist.containsTrack(track)) ...[ - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.addToQueue, leading: const Icon(SpotubeIcons.queueAdd), - title: Text(context.l10n.add_to_queue), + child: Text(context.l10n.add_to_queue), ), - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.playNext, leading: const Icon(SpotubeIcons.lightning), - title: Text(context.l10n.play_next), + child: Text(context.l10n.play_next), ), ] else - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.removeFromQueue, enabled: playlist.activeTrack?.id != track.id, leading: const Icon(SpotubeIcons.queueRemove), - title: Text(context.l10n.remove_from_queue), + child: Text(context.l10n.remove_from_queue), ), if (me.asData?.value != null && !isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.favorite, leading: favorites.isLiked ? const Icon( @@ -371,32 +380,32 @@ class TrackOptions extends HookConsumerWidget { color: Colors.pink, ) : const Icon(SpotubeIcons.heart), - title: Text( + child: Text( favorites.isLiked ? context.l10n.remove_from_favorites : context.l10n.save_as_favorite, ), ), if (auth.asData?.value != null && !isLocalTrack) ...[ - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.startRadio, leading: const Icon(SpotubeIcons.radio), - title: Text(context.l10n.start_a_radio), + child: Text(context.l10n.start_a_radio), ), - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.addToPlaylist, leading: const Icon(SpotubeIcons.playlistAdd), - title: Text(context.l10n.add_to_playlist), + child: Text(context.l10n.add_to_playlist), ), ], if (userPlaylist && auth.asData?.value != null && !isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.removeFromPlaylist, leading: const Icon(SpotubeIcons.removeFilled), - title: Text(context.l10n.remove_from_playlist), + child: Text(context.l10n.remove_from_playlist), ), if (!isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.download, enabled: !isInQueue, leading: isInQueue @@ -407,48 +416,56 @@ class TrackOptions extends HookConsumerWidget { ); }) : const Icon(SpotubeIcons.download), - title: Text(context.l10n.download_track), + child: Text(context.l10n.download_track), ), if (!isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.blacklist, - leading: const Icon(SpotubeIcons.playlistRemove), - iconColor: isBlackListed != true ? Colors.red[400] : null, - textColor: isBlackListed != true ? Colors.red[400] : null, - title: Text( + leading: Icon( + SpotubeIcons.playlistRemove, + color: isBlackListed != true ? Colors.red[400] : null, + ), + child: Text( isBlackListed == true ? context.l10n.remove_from_blacklist : context.l10n.add_to_blacklist, + style: TextStyle( + color: isBlackListed != true ? Colors.red[400] : null, + ), ), ), if (!isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.share, leading: const Icon(SpotubeIcons.share), - title: Text(context.l10n.share), + child: Text(context.l10n.share), ), if (!isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.songlink, leading: Assets.logos.songlinkTransparent.image( width: 22, height: 22, color: colorScheme.onSurface.withOpacity(0.5), ), - title: Text(context.l10n.song_link), + child: Text(context.l10n.song_link), ), if (!isLocalTrack) - PopSheetEntry( + AdaptiveMenuButton( value: TrackOptionValue.details, leading: const Icon(SpotubeIcons.info), - title: Text(context.l10n.details), + child: Text(context.l10n.details), ), ], ); //! This is the most ANTI pattern I've ever done, but it works showMenuCbRef?.value = (relativeRect) { - adaptivePopSheetList.showPopupMenu(context, relativeRect); + final offsetFromRect = Offset( + relativeRect.left, + relativeRect.top, + ); + adaptivePopSheetList.showDropdownMenu(context, offsetFromRect); }; return ListTileTheme( diff --git a/lib/components/tracks_view/sections/body/track_view_options.dart b/lib/components/tracks_view/sections/body/track_view_options.dart index 23198aec..7114d713 100644 --- a/lib/components/tracks_view/sections/body/track_view_options.dart +++ b/lib/components/tracks_view/sections/body/track_view_options.dart @@ -102,35 +102,35 @@ class TrackViewBodyOptions extends HookConsumerWidget { }, icon: const Icon(SpotubeIcons.moreVertical), children: [ - PopSheetEntry( + AdaptiveMenuButton( value: "download", leading: const Icon(SpotubeIcons.download), enabled: selectedTracks.isNotEmpty, - title: Text( + child: Text( context.l10n.download_count(selectedTracks.length), ), ), - PopSheetEntry( + AdaptiveMenuButton( value: "add-to-playlist", leading: const Icon(SpotubeIcons.playlistAdd), enabled: selectedTracks.isNotEmpty, - title: Text( + child: Text( context.l10n.add_count_to_playlist(selectedTracks.length), ), ), - PopSheetEntry( + AdaptiveMenuButton( enabled: selectedTracks.isNotEmpty, value: "add-to-queue", leading: const Icon(SpotubeIcons.queueAdd), - title: Text( + child: Text( context.l10n.add_count_to_queue(selectedTracks.length), ), ), - PopSheetEntry( + AdaptiveMenuButton( enabled: selectedTracks.isNotEmpty, value: "play-next", leading: const Icon(SpotubeIcons.lightning), - title: Text( + child: Text( context.l10n.play_count_next(selectedTracks.length), ), ), diff --git a/lib/main.dart b/lib/main.dart index 3ed4314b..cd9acec2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -219,12 +219,16 @@ class Spotube extends HookConsumerWidget { theme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), - colorScheme: ColorSchemes.lightNeutral(), + colorScheme: ColorSchemes.lightBlue(), + surfaceOpacity: .9, + surfaceBlur: 10, ), darkTheme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), colorScheme: ColorSchemes.darkNeutral(), + surfaceOpacity: .9, + surfaceBlur: 10, ), themeMode: themeMode, shortcuts: { diff --git a/lib/modules/player/player_actions.dart b/lib/modules/player/player_actions.dart index a47c992d..7db65c23 100644 --- a/lib/modules/player/player_actions.dart +++ b/lib/modules/player/player_actions.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/player/sibling_tracks_sheet.dart'; @@ -76,38 +76,37 @@ class PlayerActions extends HookConsumerWidget { mainAxisAlignment: mainAxisAlignment, children: [ if (showQueue) - IconButton( - icon: const Icon(SpotubeIcons.queue), - tooltip: context.l10n.queue, - onPressed: playlist.activeTrack != null - ? () { - Scaffold.of(context).openEndDrawer(); - } - : null, + Tooltip( + tooltip: Text(context.l10n.queue), + child: IconButton.ghost( + icon: const Icon(SpotubeIcons.queue), + enabled: playlist.activeTrack != null, + onPressed: () { + // Scaffold.of(context).openEndDrawer(); + }, + ), ), if (!isLocalTrack) - IconButton( - icon: const Icon(SpotubeIcons.alternativeRoute), - tooltip: context.l10n.alternative_track_sources, - onPressed: playlist.activeTrack != null - ? () { - showModalBottomSheet( - context: context, - isDismissible: true, - enableDrag: true, - isScrollControlled: true, - backgroundColor: Colors.black12, - barrierColor: Colors.black12, - elevation: 0, - shape: RoundedRectangleBorder( + Tooltip( + tooltip: Text(context.l10n.alternative_track_sources), + child: IconButton.ghost( + icon: const Icon(SpotubeIcons.alternativeRoute), + onPressed: playlist.activeTrack != null + ? () { + openDrawer( + context: context, + position: OverlayPosition.bottom, + barrierDismissible: true, + draggable: true, + barrierColor: Colors.black.withValues(alpha: .2), borderRadius: BorderRadius.circular(10), - ), - builder: (context) { - return SiblingTracksSheet(floating: floatingQueue); - }, - ); - } - : null, + builder: (context) { + return SiblingTracksSheet(floating: floatingQueue); + }, + ); + } + : null, + ), ), if (!kIsWeb && !isLocalTrack) if (isInQueue) @@ -115,24 +114,26 @@ class PlayerActions extends HookConsumerWidget { height: 20, width: 20, child: CircularProgressIndicator( - strokeWidth: 2, + size: 2, ), ) else - IconButton( - tooltip: context.l10n.download_track, - icon: Icon( - isDownloaded ? SpotubeIcons.done : SpotubeIcons.download, + Tooltip( + tooltip: Text(context.l10n.download_track), + child: IconButton.ghost( + icon: Icon( + isDownloaded ? SpotubeIcons.done : SpotubeIcons.download, + ), + onPressed: playlist.activeTrack != null + ? () => downloader.addToQueue(playlist.activeTrack!) + : null, ), - onPressed: playlist.activeTrack != null - ? () => downloader.addToQueue(playlist.activeTrack!) - : null, ), if (playlist.activeTrack != null && !isLocalTrack && auth.asData?.value != null) TrackHeartButton(track: playlist.activeTrack!), - AdaptivePopSheetList( + AdaptivePopSheetList( offset: Offset(0, -50 * (sleepTimerEntries.values.length + 2)), headings: [ Text(context.l10n.sleep_timer), @@ -150,24 +151,40 @@ class PlayerActions extends HookConsumerWidget { }, children: [ for (final entry in sleepTimerEntries.entries) - PopSheetEntry( + AdaptiveMenuButton( value: entry.value, enabled: sleepTimer != entry.value, - title: Text(entry.key), + child: Text(entry.key), ), - PopSheetEntry( - title: Text( - customHoursEnabled - ? context.l10n.custom_hours - : sleepTimer.format(abbreviated: true), - ), - // only enabled when there's no preset timers selected + AdaptiveMenuButton( enabled: customHoursEnabled, - onTap: () async { + onPressed: (context) async { final currentTime = TimeOfDay.now(); - final time = await showTimePicker( + final time = await showDialog( context: context, - initialTime: currentTime, + builder: (context) => HookBuilder(builder: (context) { + final timeRef = useRef(null); + return AlertDialog( + title: Text( + ShadcnLocalizations.of(context).placeholderTimePicker, + ), + content: TimePickerDialog( + use24HourFormat: false, + initialValue: TimeOfDay.fromDateTime( + DateTime.now().add(sleepTimer ?? Duration.zero), + ), + onChanged: (value) => timeRef.value = value, + ), + actions: [ + Button.primary( + onPressed: () { + Navigator.of(context).pop(timeRef.value); + }, + child: Text(context.l10n.save), + ), + ], + ); + }), ); if (time != null) { @@ -179,12 +196,19 @@ class PlayerActions extends HookConsumerWidget { ); } }, + child: Text( + customHoursEnabled + ? context.l10n.custom_hours + : sleepTimer.format(abbreviated: true), + ), ), - PopSheetEntry( + AdaptiveMenuButton( value: Duration.zero, enabled: sleepTimer != Duration.zero && sleepTimer != null, - textColor: Colors.green, - title: Text(context.l10n.cancel), + child: Text( + context.l10n.cancel, + style: const TextStyle(color: Colors.green), + ), ), ], ), diff --git a/lib/modules/player/player_controls.dart b/lib/modules/player/player_controls.dart index 12288a3d..0b3f5c2b 100644 --- a/lib/modules/player/player_controls.dart +++ b/lib/modules/player/player_controls.dart @@ -1,9 +1,9 @@ -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:media_kit/media_kit.dart'; import 'package:palette_generator/palette_generator.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide ThemeData; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/intents.dart'; @@ -47,44 +47,6 @@ class PlayerControls extends HookConsumerWidget { useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying; final theme = Theme.of(context); - final isDominantColorDark = ThemeData.estimateBrightnessForColor( - palette?.dominantColor?.color ?? theme.colorScheme.primary, - ) == - Brightness.dark; - - final dominantColor = isDominantColorDark - ? palette?.mutedColor ?? palette?.dominantColor - : palette?.dominantColor; - - final sliderColor = - palette?.dominantColor?.titleTextColor ?? theme.colorScheme.primary; - - final buttonStyle = IconButton.styleFrom( - backgroundColor: dominantColor?.color.withOpacity(0.2) ?? - theme.colorScheme.surface.withOpacity(0.4), - minimumSize: const Size(28, 28), - ); - - final activeButtonStyle = IconButton.styleFrom( - backgroundColor: - dominantColor?.titleTextColor ?? theme.colorScheme.primaryContainer, - foregroundColor: - dominantColor?.color ?? theme.colorScheme.onPrimaryContainer, - minimumSize: const Size(28, 28), - ); - - final accentColor = palette?.lightVibrantColor ?? - palette?.darkVibrantColor ?? - dominantColor; - - final resumePauseStyle = IconButton.styleFrom( - backgroundColor: accentColor?.color ?? theme.colorScheme.primary, - foregroundColor: - accentColor?.titleTextColor ?? theme.colorScheme.onPrimary, - padding: EdgeInsets.all(compact ? 10 : 12), - iconSize: compact ? 18 : 24, - ); - return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { @@ -122,45 +84,41 @@ class PlayerControls extends HookConsumerWidget { return Column( children: [ Tooltip( - message: context.l10n.slide_to_seek, + tooltip: Text(context.l10n.slide_to_seek), child: Slider( - // cannot divide by zero - // there's an edge case for value being bigger - // than total duration. Keeping it resolved - value: progress.value.toDouble(), - secondaryTrackValue: bufferProgress, + value: + SliderValue.single(progress.value.toDouble()), onChanged: isFetchingActiveTrack ? null : (v) { - progress.value = v; + progress.value = v.value; }, onChangeEnd: (value) async { await audioPlayer.seek( Duration( - seconds: (value * duration.inSeconds).toInt(), + seconds: (value.value * duration.inSeconds) + .toInt(), ), ); }, - activeColor: sliderColor, - secondaryActiveColor: sliderColor.withOpacity(0.2), - inactiveColor: sliderColor.withOpacity(0.15), ), ), Padding( padding: const EdgeInsets.symmetric( horizontal: 8.0, ), - child: DefaultTextStyle( - style: theme.textTheme.bodySmall!.copyWith( - color: palette?.dominantColor?.bodyTextColor, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(position.toHumanReadableString()), - Text(duration.toHumanReadableString()), - ], - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + position.toHumanReadableString(), + style: theme.typography.xSmall, + ), + Text( + duration.toHumanReadableString(), + style: theme.typography.xSmall, + ), + ], ), ), ], @@ -173,92 +131,104 @@ class PlayerControls extends HookConsumerWidget { Consumer(builder: (context, ref, _) { final shuffled = ref .watch(audioPlayerProvider.select((s) => s.shuffled)); - return IconButton( - tooltip: shuffled - ? context.l10n.unshuffle_playlist - : context.l10n.shuffle_playlist, - icon: const Icon(SpotubeIcons.shuffle), - style: shuffled ? activeButtonStyle : buttonStyle, - onPressed: isFetchingActiveTrack - ? null - : () { - if (shuffled) { - audioPlayer.setShuffle(false); - } else { - audioPlayer.setShuffle(true); - } - }, + return Tooltip( + tooltip: Text( + shuffled + ? context.l10n.unshuffle_playlist + : context.l10n.shuffle_playlist, + ), + child: IconButton( + icon: const Icon(SpotubeIcons.shuffle), + variance: shuffled + ? ButtonVariance.secondary + : ButtonVariance.ghost, + onPressed: isFetchingActiveTrack + ? null + : () { + if (shuffled) { + audioPlayer.setShuffle(false); + } else { + audioPlayer.setShuffle(true); + } + }, + ), ); }), - IconButton( - tooltip: context.l10n.previous_track, - icon: const Icon(SpotubeIcons.skipBack), - style: buttonStyle, - onPressed: isFetchingActiveTrack - ? null - : audioPlayer.skipToPrevious, + Tooltip( + tooltip: Text(context.l10n.previous_track), + child: IconButton.ghost( + enabled: !isFetchingActiveTrack, + icon: const Icon(SpotubeIcons.skipBack), + onPressed: audioPlayer.skipToPrevious, + ), ), - IconButton( - tooltip: playing - ? context.l10n.pause_playback - : context.l10n.resume_playback, - icon: isFetchingActiveTrack - ? SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator( - color: accentColor?.titleTextColor ?? - theme.colorScheme.onPrimary, + Tooltip( + tooltip: Text( + playing + ? context.l10n.pause_playback + : context.l10n.resume_playback, + ), + child: IconButton.primary( + shape: ButtonShape.circle, + icon: isFetchingActiveTrack + ? const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator(), + ) + : Icon( + playing ? SpotubeIcons.pause : SpotubeIcons.play, ), - ) - : Icon( - playing ? SpotubeIcons.pause : SpotubeIcons.play, - ), - style: resumePauseStyle, - onPressed: isFetchingActiveTrack - ? null - : Actions.handler( - context, - PlayPauseIntent(ref), - ), + onPressed: isFetchingActiveTrack + ? null + : Actions.handler( + context, + PlayPauseIntent(ref), + ), + ), ), - IconButton( - tooltip: context.l10n.next_track, - icon: const Icon(SpotubeIcons.skipForward), - style: buttonStyle, - onPressed: - isFetchingActiveTrack ? null : audioPlayer.skipToNext, + Tooltip( + tooltip: Text(context.l10n.next_track), + child: IconButton.ghost( + icon: const Icon(SpotubeIcons.skipForward), + onPressed: + isFetchingActiveTrack ? null : audioPlayer.skipToNext, + ), ), Consumer(builder: (context, ref, _) { final loopMode = ref .watch(audioPlayerProvider.select((s) => s.loopMode)); - return IconButton( - tooltip: loopMode == PlaylistMode.single - ? context.l10n.loop_track - : loopMode == PlaylistMode.loop - ? context.l10n.repeat_playlist - : null, - icon: Icon( + return Tooltip( + tooltip: Text( loopMode == PlaylistMode.single - ? SpotubeIcons.repeatOne - : SpotubeIcons.repeat, + ? context.l10n.loop_track + : loopMode == PlaylistMode.loop + ? context.l10n.repeat_playlist + : "", + ), + child: IconButton( + icon: Icon( + loopMode == PlaylistMode.single + ? SpotubeIcons.repeatOne + : SpotubeIcons.repeat, + ), + variance: loopMode == PlaylistMode.single || + loopMode == PlaylistMode.loop + ? ButtonVariance.secondary + : ButtonVariance.ghost, + onPressed: isFetchingActiveTrack + ? null + : () async { + await audioPlayer.setLoopMode( + switch (loopMode) { + PlaylistMode.loop => PlaylistMode.single, + PlaylistMode.single => PlaylistMode.none, + PlaylistMode.none => PlaylistMode.loop, + }, + ); + }, ), - style: loopMode == PlaylistMode.single || - loopMode == PlaylistMode.loop - ? activeButtonStyle - : buttonStyle, - onPressed: isFetchingActiveTrack - ? null - : () async { - await audioPlayer.setLoopMode( - switch (loopMode) { - PlaylistMode.loop => PlaylistMode.single, - PlaylistMode.single => PlaylistMode.none, - PlaylistMode.none => PlaylistMode.loop, - }, - ); - }, ); }), ], diff --git a/lib/modules/player/volume_slider.dart b/lib/modules/player/volume_slider.dart index 8483143b..515f1fbc 100644 --- a/lib/modules/player/volume_slider.dart +++ b/lib/modules/player/volume_slider.dart @@ -1,6 +1,7 @@ import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; + import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; class VolumeSlider extends HookConsumerWidget { @@ -30,17 +31,11 @@ class VolumeSlider extends HookConsumerWidget { } } }, - child: SliderTheme( - data: const SliderThemeData( - showValueIndicator: ShowValueIndicator.always, - ), - child: Slider( - min: 0, - max: 1, - label: (value * 100).toStringAsFixed(0), - value: value, - onChanged: onChanged, - ), + child: Slider( + min: 0, + max: 1, + value: SliderValue.single(value), + onChanged: (v) => onChanged(v.value), ), ); return Row( @@ -48,6 +43,7 @@ class VolumeSlider extends HookConsumerWidget { !fullWidth ? MainAxisAlignment.center : MainAxisAlignment.start, children: [ IconButton( + variance: ButtonVariance.ghost, icon: Icon( value == 0 ? SpotubeIcons.volumeMute diff --git a/lib/modules/root/bottom_player.dart b/lib/modules/root/bottom_player.dart index a2f45449..f435eefb 100644 --- a/lib/modules/root/bottom_player.dart +++ b/lib/modules/root/bottom_player.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -16,7 +17,6 @@ import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/hooks/utils/use_brightness_value.dart'; -import 'package:flutter/material.dart'; import 'package:spotube/provider/audio_player/audio_player.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; @@ -46,7 +46,7 @@ class BottomPlayer extends HookConsumerWidget { ); final theme = Theme.of(context); - final bg = theme.colorScheme.surfaceContainerHighest; + final bg = theme.colorScheme.background; final bgColor = useBrightnessValue( Color.lerp(bg, Colors.white, 0.7), @@ -64,31 +64,30 @@ class BottomPlayer extends HookConsumerWidget { child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), child: DecoratedBox( - decoration: BoxDecoration(color: bgColor?.withOpacity(0.8)), - child: Material( - type: MaterialType.transparency, - textStyle: theme.textTheme.bodyMedium!, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: PlayerTrackDetails(track: playlist.activeTrack), + decoration: BoxDecoration(color: bgColor?.withValues(alpha: .8)), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: PlayerTrackDetails(track: playlist.activeTrack), + ), + // controls + const Flexible( + flex: 3, + child: Padding( + padding: EdgeInsets.only(top: 5), + child: PlayerControls(), ), - // controls - const Flexible( - flex: 3, - child: Padding( - padding: EdgeInsets.only(top: 5), - child: PlayerControls(), - ), - ), - // add to saved tracks - Column( - children: [ - PlayerActions( - extraActions: [ - IconButton( - tooltip: context.l10n.mini_player, + ), + // add to saved tracks + Column( + children: [ + PlayerActions( + extraActions: [ + Tooltip( + tooltip: Text(context.l10n.mini_player), + child: IconButton( + variance: ButtonVariance.ghost, icon: const Icon(SpotubeIcons.miniPlayer), onPressed: () async { if (!kIsDesktop) return; @@ -107,35 +106,37 @@ class BottomPlayer extends HookConsumerWidget { await Future.delayed( const Duration(milliseconds: 100), () async { - GoRouter.of(context).go( - '/mini-player', - extra: prevSize, - ); + if (context.mounted) { + context.go( + '/mini-player', + extra: prevSize, + ); + } }, ); }, ), - ], - ), - Container( - height: 40, - constraints: const BoxConstraints(maxWidth: 250), - padding: const EdgeInsets.only(right: 10), - child: Consumer(builder: (context, ref, _) { - final volume = ref.watch(volumeProvider); - return VolumeSlider( - fullWidth: true, - value: volume, - onChanged: (value) { - ref.read(volumeProvider.notifier).setVolume(value); - }, - ); - }), - ) - ], - ), - ], - ), + ), + ], + ), + Container( + height: 40, + constraints: const BoxConstraints(maxWidth: 250), + padding: const EdgeInsets.only(right: 10), + child: Consumer(builder: (context, ref, _) { + final volume = ref.watch(volumeProvider); + return VolumeSlider( + fullWidth: true, + value: volume, + onChanged: (value) { + ref.read(volumeProvider.notifier).setVolume(value); + }, + ); + }), + ) + ], + ), + ], ), ), ), From 2488da2279b9fa5d65c101989e5a45e96b06188a Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 14:38:54 +0600 Subject: [PATCH 05/81] refactor: bottom player border, player queue using shadcn drawer --- .vscode/settings.json | 1 + lib/collections/spotube_icons.dart | 1 + lib/main.dart | 4 +- lib/modules/player/player.dart | 95 +++---- lib/modules/player/player_actions.dart | 30 ++- lib/modules/player/player_queue.dart | 350 +++++++++++-------------- lib/modules/player/volume_slider.dart | 15 +- lib/modules/root/bottom_player.dart | 148 +++++------ lib/modules/root/sidebar.dart | 51 ++-- lib/pages/root/root_app.dart | 159 +++++------ 10 files changed, 397 insertions(+), 457 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 1f47bada..57413df4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,7 @@ "RGBO", "riverpod", "Scrobblenaut", + "shadcn", "skeletonizer", "songlink", "speechiness", diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index 5c4df85f..a1c6d69f 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -127,4 +127,5 @@ abstract class SpotubeIcons { static const cache = FeatherIcons.hardDrive; static const export = Icons.file_open_outlined; static const delete = FeatherIcons.trash2; + static const open = FeatherIcons.externalLink; } diff --git a/lib/main.dart b/lib/main.dart index cd9acec2..d1275577 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -220,14 +220,14 @@ class Spotube extends HookConsumerWidget { radius: .5, iconTheme: const IconThemeProperties(), colorScheme: ColorSchemes.lightBlue(), - surfaceOpacity: .9, + surfaceOpacity: .8, surfaceBlur: 10, ), darkTheme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), colorScheme: ColorSchemes.darkNeutral(), - surfaceOpacity: .9, + surfaceOpacity: .8, surfaceBlur: 10, ), themeMode: themeMode, diff --git a/lib/modules/player/player.dart b/lib/modules/player/player.dart index 925afadc..a79934d9 100644 --- a/lib/modules/player/player.dart +++ b/lib/modules/player/player.dart @@ -3,6 +3,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' + show openDrawer, OverlayPosition; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -289,53 +292,53 @@ class PlayerView extends HookConsumerWidget { const SizedBox(width: 10), Expanded( child: OutlinedButton.icon( - icon: const Icon(SpotubeIcons.queue), - label: Text(context.l10n.queue), - style: OutlinedButton.styleFrom( - foregroundColor: bodyTextColor, - side: BorderSide( - color: bodyTextColor ?? Colors.white, - ), + icon: const Icon(SpotubeIcons.queue), + label: Text(context.l10n.queue), + style: OutlinedButton.styleFrom( + foregroundColor: bodyTextColor, + side: BorderSide( + color: bodyTextColor ?? Colors.white, ), - onPressed: currentTrack != null - ? () { - showModalBottomSheet( - context: context, - isDismissible: true, - enableDrag: true, - isScrollControlled: true, - backgroundColor: Colors.black12, - barrierColor: Colors.black12, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10), - ), - constraints: BoxConstraints( - maxHeight: - MediaQuery.of(context) - .size - .height * - .7, - ), - builder: (context) => Consumer( - builder: (context, ref, _) { - final playlist = ref.watch( - audioPlayerProvider, - ); - final playlistNotifier = ref - .read(audioPlayerProvider - .notifier); - return PlayerQueue - .fromAudioPlayerNotifier( - floating: false, - playlist: playlist, - notifier: playlistNotifier, - ); - }, - ), - ); - } - : null), + ), + // enabled: currentTrack != null, + onPressed: () { + openDrawer( + context: context, + barrierDismissible: true, + draggable: true, + barrierColor: Colors.black12, + borderRadius: BorderRadius.circular(10), + transformBackdrop: false, + position: OverlayPosition.bottom, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: 0.7, + expands: true, + builder: (context) => Consumer( + builder: (context, ref, _) { + final playlist = ref.watch( + audioPlayerProvider, + ); + final playlistNotifier = ref.read( + audioPlayerProvider.notifier); + return ConstrainedBox( + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context) + .size + .height * + 0.8, + ), + child: PlayerQueue + .fromAudioPlayerNotifier( + floating: false, + playlist: playlist, + notifier: playlistNotifier, + ), + ); + }, + ), + ); + }, + ), ), if (auth.asData?.value != null) const SizedBox(width: 10), diff --git a/lib/modules/player/player_actions.dart b/lib/modules/player/player_actions.dart index 7db65c23..dbdfa11b 100644 --- a/lib/modules/player/player_actions.dart +++ b/lib/modules/player/player_actions.dart @@ -2,8 +2,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/modules/player/player_queue.dart'; import 'package:spotube/modules/player/sibling_tracks_sheet.dart'; import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; import 'package:spotube/components/heart_button/heart_button.dart'; @@ -82,7 +84,32 @@ class PlayerActions extends HookConsumerWidget { icon: const Icon(SpotubeIcons.queue), enabled: playlist.activeTrack != null, onPressed: () { - // Scaffold.of(context).openEndDrawer(); + openDrawer( + context: context, + position: OverlayPosition.right, + transformBackdrop: false, + draggable: false, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: 0.7, + builder: (context) { + return Container( + constraints: const BoxConstraints(maxWidth: 800), + child: Consumer( + builder: (context, ref, _) { + final playlist = ref.watch(audioPlayerProvider); + final playlistNotifier = + ref.read(audioPlayerProvider.notifier); + + return PlayerQueue.fromAudioPlayerNotifier( + floating: true, + playlist: playlist, + notifier: playlistNotifier, + ); + }, + ), + ); + }, + ); }, ), ), @@ -100,6 +127,7 @@ class PlayerActions extends HookConsumerWidget { draggable: true, barrierColor: Colors.black.withValues(alpha: .2), borderRadius: BorderRadius.circular(10), + transformBackdrop: false, builder: (context) { return SiblingTracksSheet(floating: floatingQueue); }, diff --git a/lib/modules/player/player_queue.dart b/lib/modules/player/player_queue.dart index 369b95d2..49279d5c 100644 --- a/lib/modules/player/player_queue.dart +++ b/lib/modules/player/player_queue.dart @@ -1,14 +1,12 @@ -import 'dart:ui'; - +import 'package:auto_size_text/auto_size_text.dart'; import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/fallbacks/not_found.dart'; @@ -60,16 +58,6 @@ class PlayerQueue extends HookConsumerWidget { final isSearching = useState(false); final tracks = playlist.tracks; - final borderRadius = floating - ? const BorderRadius.only( - topLeft: Radius.circular(10), - ) - : const BorderRadius.only( - topLeft: Radius.circular(10), - topRight: Radius.circular(10), - ); - final theme = Theme.of(context); - final headlineColor = theme.textTheme.headlineSmall?.color; final filteredTracks = useMemoized( () { @@ -92,217 +80,173 @@ class PlayerQueue extends HookConsumerWidget { [tracks, searchText.value], ); - useEffect(() { - if (playlist.activeTrack == null) return null; - - controller.scrollToIndex( - playlist.playlist.index, - preferPosition: AutoScrollPosition.middle, - ); - return null; - }, []); - if (tracks.isEmpty) { return const NotFound(vertical: true); } - return LayoutBuilder( - builder: (context, constrains) { - return ClipRRect( - borderRadius: borderRadius, - clipBehavior: Clip.hardEdge, - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 15, - sigmaY: 15, - ), - child: Container( - padding: const EdgeInsets.only( - top: 5.0, + return Stack( + children: [ + LayoutBuilder( + builder: (context, constrains) { + final searchBar = ConstrainedBox( + constraints: BoxConstraints( + maxHeight: 40, + maxWidth: + mediaQuery.smAndDown ? mediaQuery.size.width - 40 : 300, ), - decoration: BoxDecoration( - color: - theme.colorScheme.surfaceContainerHighest.withOpacity(0.5), - borderRadius: borderRadius, - ), - child: CallbackShortcuts( - bindings: { - LogicalKeySet(LogicalKeyboardKey.escape): () { - if (!isSearching.value) { - Navigator.of(context).pop(); - } - isSearching.value = false; - searchText.value = ''; - } + child: TextField( + onChanged: (value) { + searchText.value = value; }, - child: InterScrollbar( - controller: controller, - child: CustomScrollView( - controller: controller, - slivers: [ - if (!floating) - SliverToBoxAdapter( - child: Center( - child: Container( - height: 5, - width: 100, - margin: const EdgeInsets.only(bottom: 5, top: 2), - decoration: BoxDecoration( - color: headlineColor, - borderRadius: BorderRadius.circular(20), - ), + placeholder: Text(context.l10n.search), + ), + ); + return CallbackShortcuts( + bindings: { + LogicalKeySet(LogicalKeyboardKey.escape): () { + if (!isSearching.value) { + Navigator.of(context).pop(); + } + isSearching.value = false; + searchText.value = ''; + } + }, + child: Column( + children: [ + if (isSearching.value && mediaQuery.smAndDown) + AppBar( + backgroundColor: Colors.transparent, + leading: [ + if (mediaQuery.smAndDown) + IconButton.ghost( + icon: const Icon( + Icons.arrow_back_ios_new_outlined, ), - ), - ), - SliverAppBar( - floating: true, - pinned: false, - snap: false, - backgroundColor: Colors.transparent, - elevation: 0, - automaticallyImplyLeading: false, - title: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: SizedBox( - height: kToolbarHeight, - child: mediaQuery.mdAndUp || !isSearching.value - ? Align( - alignment: Alignment.centerLeft, - child: Text( - context.l10n - .tracks_in_queue(tracks.length), - style: TextStyle( - color: headlineColor, - fontWeight: FontWeight.bold, - fontSize: 18, - ), - ), - ) - : null, - ), - ), - actions: [ - if (mediaQuery.mdAndUp || isSearching.value) - TextField( - onChanged: (value) { - searchText.value = value; - }, - decoration: InputDecoration( - hintText: context.l10n.search, - isDense: true, - prefixIcon: mediaQuery.smAndDown - ? IconButton( - icon: const Icon( - Icons.arrow_back_ios_new_outlined, - ), - onPressed: () { - isSearching.value = false; - searchText.value = ''; - }, - style: IconButton.styleFrom( - padding: EdgeInsets.zero, - minimumSize: const Size.square(20), - ), - ) - : const Icon(SpotubeIcons.filter), - constraints: BoxConstraints( - maxHeight: 40, - maxWidth: mediaQuery.smAndDown - ? mediaQuery.size.width - 40 - : 300, - ), + onPressed: () { + isSearching.value = false; + searchText.value = ''; + }, + ) + ], + surfaceBlur: 0, + surfaceOpacity: 0, + child: searchBar, + ) + else + AppBar( + trailingGap: 0, + backgroundColor: Colors.transparent, + surfaceBlur: 0, + surfaceOpacity: 0, + title: mediaQuery.mdAndUp || !isSearching.value + ? SizedBox( + height: 30, + child: AutoSizeText( + context.l10n.tracks_in_queue(tracks.length), + maxLines: 1, ), ) - else - IconButton.filledTonal( - icon: const Icon(SpotubeIcons.filter), - onPressed: () { - isSearching.value = !isSearching.value; - }, - ), - if (mediaQuery.mdAndUp || !isSearching.value) ...[ - const SizedBox(width: 10), - FilledButton( - style: FilledButton.styleFrom( - backgroundColor: theme.scaffoldBackgroundColor - .withOpacity(0.5), - foregroundColor: - theme.textTheme.headlineSmall?.color, - ), - child: Row( - children: [ - const Icon(SpotubeIcons.playlistRemove), - const SizedBox(width: 5), - Text(context.l10n.clear_all), - ], - ), + : null, + trailing: [ + if (mediaQuery.mdAndUp) + searchBar + else + IconButton.ghost( + icon: const Icon(SpotubeIcons.filter), + onPressed: () { + isSearching.value = !isSearching.value; + }, + ), + if (mediaQuery.mdAndUp || !isSearching.value) ...[ + const SizedBox(width: 10), + Tooltip( + tooltip: Text(context.l10n.clear_all), + child: IconButton.outline( + icon: const Icon(SpotubeIcons.playlistRemove), onPressed: () { onStop(); Navigator.of(context).pop(); }, ), - const SizedBox(width: 10), - ], + ), ], - ), - const SliverGap(10), - SliverReorderableList( - onReorder: onReorder, - itemCount: filteredTracks.length, - onReorderStart: (index) { - HapticFeedback.selectionClick(); - }, - onReorderEnd: (index) { - HapticFeedback.selectionClick(); - }, - itemBuilder: (context, i) { - final track = filteredTracks.elementAt(i); - return AutoScrollTag( - key: ValueKey(i), - controller: controller, - index: i, - child: Material( - color: Colors.transparent, - child: TrackTile( - playlist: playlist, + ], + ), + const Divider(), + Expanded( + child: InterScrollbar( + controller: controller, + child: CustomScrollView( + controller: controller, + slivers: [ + const SliverGap(10), + SliverReorderableList( + onReorder: onReorder, + itemCount: filteredTracks.length, + onReorderStart: (index) { + HapticFeedback.selectionClick(); + }, + onReorderEnd: (index) { + HapticFeedback.selectionClick(); + }, + itemBuilder: (context, i) { + final track = filteredTracks.elementAt(i); + return AutoScrollTag( + key: ValueKey(i), + controller: controller, index: i, - track: track, - onTap: () async { - if (playlist.activeTrack?.id == track.id) { - return; - } - await onJump(track); - }, - leadingActions: [ - if (!isSearching.value && - searchText.value.isEmpty) - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: ReorderableDragStartListener( - index: i, - child: const Icon( - SpotubeIcons.dragHandle, + child: TrackTile( + playlist: playlist, + index: i, + track: track, + onTap: () async { + if (playlist.activeTrack?.id == track.id) { + return; + } + await onJump(track); + }, + leadingActions: [ + if (!isSearching.value && + searchText.value.isEmpty) + Padding( + padding: + const EdgeInsets.only(left: 8.0), + child: ReorderableDragStartListener( + index: i, + child: const Icon( + SpotubeIcons.dragHandle, + ), ), ), - ), - ], - ), - ), - ); - }, + ], + ), + ); + }, + ), + const SliverGap(100), + ], ), - const SliverGap(100), - ], + ), ), - ), + ], ), - ), + ); + }, + ), + Positioned( + right: 20, + bottom: 20, + child: IconButton.secondary( + icon: const Icon(SpotubeIcons.open), + onPressed: () { + controller.scrollToIndex( + playlist.playlist.index, + preferPosition: AutoScrollPosition.middle, + ); + }, ), - ); - }, + ) + ], ); } } diff --git a/lib/modules/player/volume_slider.dart b/lib/modules/player/volume_slider.dart index 515f1fbc..ee4ac9c5 100644 --- a/lib/modules/player/volume_slider.dart +++ b/lib/modules/player/volume_slider.dart @@ -31,13 +31,18 @@ class VolumeSlider extends HookConsumerWidget { } } }, - child: Slider( - min: 0, - max: 1, - value: SliderValue.single(value), - onChanged: (v) => onChanged(v.value), + child: SizedBox( + height: 20, + width: 100, + child: Slider( + min: 0, + max: 1, + value: SliderValue.single(value), + onChanged: (v) => onChanged(v.value), + ), ), ); + return Row( mainAxisAlignment: !fullWidth ? MainAxisAlignment.center : MainAxisAlignment.start, diff --git a/lib/modules/root/bottom_player.dart b/lib/modules/root/bottom_player.dart index f435eefb..8a22cc7a 100644 --- a/lib/modules/root/bottom_player.dart +++ b/lib/modules/root/bottom_player.dart @@ -1,9 +1,8 @@ -import 'dart:ui'; - import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -16,7 +15,6 @@ import 'package:spotube/modules/player/volume_slider.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; -import 'package:spotube/hooks/utils/use_brightness_value.dart'; import 'package:spotube/provider/audio_player/audio_player.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; @@ -45,14 +43,6 @@ class BottomPlayer extends HookConsumerWidget { [playlist.activeTrack?.album?.images], ); - final theme = Theme.of(context); - final bg = theme.colorScheme.background; - - final bgColor = useBrightnessValue( - Color.lerp(bg, Colors.white, 0.7), - Color.lerp(bg, Colors.black, 0.45)!, - ); - // returning an empty non spacious Container as the overlay will take // place in the global overlay stack aka [_entries] if (layoutMode == LayoutMode.compact || @@ -60,85 +50,81 @@ class BottomPlayer extends HookConsumerWidget { return PlayerOverlay(albumArt: albumArt); } - return ClipRect( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), - child: DecoratedBox( - decoration: BoxDecoration(color: bgColor?.withValues(alpha: .8)), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + return SurfaceCard( + borderRadius: BorderRadius.zero, + surfaceBlur: context.theme.surfaceBlur, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: PlayerTrackDetails(track: playlist.activeTrack), + ), + // controls + const Flexible( + flex: 3, + child: Padding( + padding: EdgeInsets.only(top: 5), + child: PlayerControls(), + ), + ), + // add to saved tracks + Column( + mainAxisSize: MainAxisSize.min, children: [ - Expanded( - child: PlayerTrackDetails(track: playlist.activeTrack), - ), - // controls - const Flexible( - flex: 3, - child: Padding( - padding: EdgeInsets.only(top: 5), - child: PlayerControls(), - ), - ), - // add to saved tracks - Column( - children: [ - PlayerActions( - extraActions: [ - Tooltip( - tooltip: Text(context.l10n.mini_player), - child: IconButton( - variance: ButtonVariance.ghost, - icon: const Icon(SpotubeIcons.miniPlayer), - onPressed: () async { - if (!kIsDesktop) return; + PlayerActions( + extraActions: [ + Tooltip( + tooltip: Text(context.l10n.mini_player), + child: IconButton( + variance: ButtonVariance.ghost, + icon: const Icon(SpotubeIcons.miniPlayer), + onPressed: () async { + if (!kIsDesktop) return; - final prevSize = await windowManager.getSize(); - await windowManager.setMinimumSize( - const Size(300, 300), - ); - await windowManager.setAlwaysOnTop(true); - if (!kIsLinux) { - await windowManager.setHasShadow(false); + final prevSize = await windowManager.getSize(); + await windowManager.setMinimumSize( + const Size(300, 300), + ); + await windowManager.setAlwaysOnTop(true); + if (!kIsLinux) { + await windowManager.setHasShadow(false); + } + await windowManager.setAlignment(Alignment.topRight); + await windowManager.setSize(const Size(400, 500)); + await Future.delayed( + const Duration(milliseconds: 100), + () async { + if (context.mounted) { + context.go( + '/mini-player', + extra: prevSize, + ); } - await windowManager - .setAlignment(Alignment.topRight); - await windowManager.setSize(const Size(400, 500)); - await Future.delayed( - const Duration(milliseconds: 100), - () async { - if (context.mounted) { - context.go( - '/mini-player', - extra: prevSize, - ); - } - }, - ); }, - ), - ), - ], + ); + }, + ), ), - Container( - height: 40, - constraints: const BoxConstraints(maxWidth: 250), - padding: const EdgeInsets.only(right: 10), - child: Consumer(builder: (context, ref, _) { - final volume = ref.watch(volumeProvider); - return VolumeSlider( - fullWidth: true, - value: volume, - onChanged: (value) { - ref.read(volumeProvider.notifier).setVolume(value); - }, - ); - }), - ) ], ), + Container( + height: 40, + constraints: const BoxConstraints(maxWidth: 250), + padding: const EdgeInsets.only(right: 10), + child: Consumer(builder: (context, ref, _) { + final volume = ref.watch(volumeProvider); + return VolumeSlider( + fullWidth: true, + value: volume, + onChanged: (value) { + ref.read(volumeProvider.notifier).setVolume(value); + }, + ); + }), + ) ], ), - ), + ], ), ); } diff --git a/lib/modules/root/sidebar.dart b/lib/modules/root/sidebar.dart index 79e8d6d4..f045c23d 100644 --- a/lib/modules/root/sidebar.dart +++ b/lib/modules/root/sidebar.dart @@ -96,32 +96,31 @@ class Sidebar extends HookConsumerWidget { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SafeArea( - child: Column( - children: [ - Expanded( - child: mediaQuery.lgAndUp - ? NavigationSidebar( - index: selectedIndex, - onSelected: (index) { - final tile = sidebarTileList[index]; - ServiceUtils.pushNamed(context, tile.name); - }, - children: navigationButtons, - ) - : NavigationRail( - alignment: NavigationRailAlignment.start, - index: selectedIndex, - onSelected: (index) { - final tile = sidebarTileList[index]; - ServiceUtils.pushNamed(context, tile.name); - }, - children: navigationButtons, - ), - ), - const SidebarFooter(), - ], - ), + Column( + children: [ + Expanded( + child: mediaQuery.lgAndUp + ? NavigationSidebar( + index: selectedIndex, + onSelected: (index) { + final tile = sidebarTileList[index]; + ServiceUtils.pushNamed(context, tile.name); + }, + children: navigationButtons, + ) + : NavigationRail( + alignment: NavigationRailAlignment.start, + index: selectedIndex, + onSelected: (index) { + final tile = sidebarTileList[index]; + ServiceUtils.pushNamed(context, tile.name); + }, + children: navigationButtons, + ), + ), + const SidebarFooter(), + const Gap(130) + ], ), const VerticalDivider(), Expanded(child: child), diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index 2a6c36f0..84c40a2f 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -1,14 +1,13 @@ import 'dart:async'; -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/framework/app_pop_scope.dart'; -import 'package:spotube/modules/player/player_queue.dart'; import 'package:spotube/components/dialogs/replace_downloaded_dialog.dart'; import 'package:spotube/modules/root/bottom_player.dart'; import 'package:spotube/modules/root/sidebar.dart'; @@ -17,7 +16,6 @@ import 'package:spotube/extensions/context.dart'; import 'package:spotube/hooks/configurators/use_endless_playback.dart'; import 'package:spotube/pages/home/home.dart'; import 'package:spotube/provider/download_manager_provider.dart'; -import 'package:spotube/provider/audio_player/audio_player.dart'; import 'package:spotube/provider/glance/glance.dart'; import 'package:spotube/provider/server/routes/connect.dart'; import 'package:spotube/services/connectivity_adapter.dart'; @@ -37,7 +35,7 @@ class RootApp extends HookConsumerWidget { final showingDialogCompleter = useRef(Completer()..complete()); final downloader = ref.watch(downloadManagerProvider); - final scaffoldMessenger = ScaffoldMessenger.of(context); + final connectRoutes = ref.watch(serverConnectRoutesProvider); ref.listen(glanceProvider, (_, __) {}); @@ -50,64 +48,70 @@ class RootApp extends HookConsumerWidget { final subscriptions = [ ConnectionCheckerService.instance.onConnectivityChanged .listen((status) { + if (!context.mounted) return; if (status) { - scaffoldMessenger.showSnackBar( - SnackBar( - content: Row( - children: [ - Icon( - SpotubeIcons.wifi, - color: theme.colorScheme.onPrimary, - ), - const SizedBox(width: 10), - Text(context.l10n.connection_restored), - ], - ), - backgroundColor: theme.colorScheme.primary, - showCloseIcon: true, - width: 350, - ), + showToast( + context: context, + builder: (context, overlay) { + return SurfaceCard( + fillColor: theme.colorScheme.primary, + child: Row( + children: [ + Icon( + SpotubeIcons.wifi, + color: theme.colorScheme.primaryForeground, + ), + const SizedBox(width: 10), + Text(context.l10n.connection_restored), + ], + ), + ); + }, ); } else { - scaffoldMessenger.showSnackBar( - SnackBar( - content: Row( - children: [ - Icon( - SpotubeIcons.noWifi, - color: theme.colorScheme.onError, - ), - const SizedBox(width: 10), - Text(context.l10n.you_are_offline), - ], - ), - backgroundColor: theme.colorScheme.error, - showCloseIcon: true, - width: 300, - ), + showToast( + context: context, + builder: (context, overlay) { + return SurfaceCard( + fillColor: theme.colorScheme.destructive, + child: Row( + children: [ + Icon( + SpotubeIcons.noWifi, + color: theme.colorScheme.destructiveForeground, + ), + const SizedBox(width: 10), + Text(context.l10n.you_are_offline), + ], + ), + ); + }, ); } }), connectRoutes.connectClientStream.listen((clientOrigin) { - scaffoldMessenger.showSnackBar( - SnackBar( - backgroundColor: Colors.yellow[600], - behavior: SnackBarBehavior.floating, - content: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - SpotubeIcons.error, - color: Colors.black, - ), - const SizedBox(width: 10), - Text( - context.l10n.connect_client_alert(clientOrigin), - style: const TextStyle(color: Colors.black), - ), - ], - ), - ), + if (!context.mounted) return; + showToast( + context: context, + builder: (context, overlay) { + return SurfaceCard( + fillColor: Colors.yellow[600], + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + SpotubeIcons.error, + color: Colors.black, + ), + const SizedBox(width: 10), + Text( + context.l10n.connect_client_alert(clientOrigin), + style: const TextStyle(color: Colors.black), + ), + ], + ), + ); + }, ); }) ]; @@ -156,7 +160,7 @@ class RootApp extends HookConsumerWidget { useEndlessPlayback(ref); - final backgroundColor = Theme.of(context).scaffoldBackgroundColor; + final backgroundColor = Theme.of(context).colorScheme.background; useEffect(() { SystemChrome.setSystemUIOverlayStyle( @@ -175,43 +179,12 @@ class RootApp extends HookConsumerWidget { }, []); final scaffold = Scaffold( - body: Sidebar(child: child), - extendBody: true, - drawerScrimColor: Colors.transparent, - endDrawer: kIsDesktop - ? Container( - constraints: const BoxConstraints(maxWidth: 800), - decoration: BoxDecoration( - boxShadow: theme.brightness == Brightness.light - ? null - : kElevationToShadow[8], - ), - margin: const EdgeInsets.only( - top: 40, - bottom: 100, - ), - child: Consumer( - builder: (context, ref, _) { - final playlist = ref.watch(audioPlayerProvider); - final playlistNotifier = - ref.read(audioPlayerProvider.notifier); - - return PlayerQueue.fromAudioPlayerNotifier( - floating: true, - playlist: playlist, - notifier: playlistNotifier, - ); - }, - ), - ) - : null, - bottomNavigationBar: const Column( - mainAxisSize: MainAxisSize.min, - children: [ - BottomPlayer(), - SpotubeNavigationBar(), - ], - ), + footers: const [ + BottomPlayer(), + SpotubeNavigationBar(), + ], + floatingFooter: true, + child: Sidebar(child: child), ); if (!kIsAndroid) { From 1089e905116714accaf9db97c36134a7108da7af Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 15:21:13 +0600 Subject: [PATCH 06/81] refactor: use shadcn CardImage for playbutton card --- .../horizontal_playbutton_card_view.dart | 2 + lib/components/playbutton_card.dart | 237 +++++------------- 2 files changed, 65 insertions(+), 174 deletions(-) diff --git a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart index 16204952..1093fff0 100644 --- a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart +++ b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:gap/gap.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/fake.dart'; @@ -90,6 +91,7 @@ class HorizontalPlaybuttonCardView extends HookWidget { ), isLoading: isLoadingNextPage, hasReachedMax: !hasNextPage, + separatorBuilder: (context, index) => const Gap(8.0), itemBuilder: (context, index) { final item = items[index]; diff --git a/lib/components/playbutton_card.dart b/lib/components/playbutton_card.dart index ae9050d8..0b942564 100644 --- a/lib/components/playbutton_card.dart +++ b/lib/components/playbutton_card.dart @@ -1,16 +1,9 @@ -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; -import 'package:skeletonizer/skeletonizer.dart'; + +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/components/hover_builder.dart'; import 'package:spotube/components/image/universal_image.dart'; -import 'package:spotube/extensions/constrains.dart'; -import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/string.dart'; -import 'package:spotube/hooks/utils/use_breakpoint_value.dart'; -import 'package:spotube/hooks/utils/use_brightness_value.dart'; class PlaybuttonCard extends HookWidget { final void Function()? onTap; @@ -40,180 +33,76 @@ class PlaybuttonCard extends HookWidget { @override Widget build(BuildContext context) { - final textsKey = useMemoized(() => GlobalKey(), []); - final theme = Theme.of(context); - final mediaQuery = MediaQuery.of(context); - final radius = BorderRadius.circular(15); - - final double size = useBreakpointValue( - xs: 130, - sm: 130, - md: 150, - others: 170, - ); - - final end = useBreakpointValue( - xs: 7, - sm: 7, - others: 15, - ); - final unescapeHtml = description?.unescapeHtml().cleanHtml(); + return Container( - constraints: BoxConstraints(maxWidth: size), - margin: margin, - child: Material( - color: Color.lerp( - theme.colorScheme.surfaceContainerHighest, - theme.colorScheme.surface, - useBrightnessValue(.9, .7), - ), - borderRadius: radius, - shadowColor: theme.colorScheme.surface, - elevation: 3, - child: InkWell( - mouseCursor: SystemMouseCursors.click, - onTap: onTap, - borderRadius: radius, - splashFactory: theme.splashFactory, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Stack( - clipBehavior: Clip.none, - children: [ - Container( - margin: const EdgeInsets.fromLTRB(8, 8, 8, 0), - padding: const EdgeInsets.only( - left: 8, - right: 8, - top: 8, - ), - height: mediaQuery.smAndDown - ? 120 - : mediaQuery.mdAndDown - ? 130 - : 150, - decoration: BoxDecoration( - borderRadius: radius, - image: DecorationImage( - image: UniversalImage.imageProvider(imageUrl), - fit: BoxFit.cover, + width: 150, + child: CardImage( + image: Stack( + children: [ + UniversalImage( + path: imageUrl, + fit: BoxFit.cover, + ), + StatedWidget.builder( + builder: (context, states) { + return Positioned( + right: 8, + bottom: 8, + child: Column( + children: [ + AnimatedScale( + curve: Curves.easeOutBack, + duration: const Duration(milliseconds: 300), + scale: states.contains(WidgetState.hovered) ? 1 : 0.7, + child: AnimatedOpacity( + duration: const Duration(milliseconds: 300), + opacity: states.contains(WidgetState.hovered) ? 1 : 0, + child: IconButton.secondary( + icon: const Icon(SpotubeIcons.queueAdd), + onPressed: onAddToQueuePressed, + size: ButtonSize.small, + ), + ), ), - ), - ), - if (isOwner) - Positioned( - top: 15, - left: 15, - child: AnimatedSize( + const Gap(5), + AnimatedScale( + curve: Curves.easeOutBack, duration: const Duration(milliseconds: 150), - alignment: Alignment.centerLeft, - curve: Curves.easeInExpo, - child: HoverBuilder(builder: (context, isHovered) { - return Container( - padding: const EdgeInsets.all(4), - decoration: BoxDecoration( - color: Colors.blueAccent, - borderRadius: BorderRadius.circular(20), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - SpotubeIcons.user, - color: Colors.white, - size: 16, - ), - if (isHovered) - Text( - context.l10n.owned_by_you, - style: theme.textTheme.bodySmall?.copyWith( - color: Colors.white, - ), - ), - ], - ), - ); - }), - ), - ), - Positioned( - right: end, - bottom: -15, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (!isPlaying) - Skeleton.keep( - child: IconButton( - style: IconButton.styleFrom( - backgroundColor: theme.colorScheme.surface, - foregroundColor: theme.colorScheme.primary, - minimumSize: const Size.square(10), - ), - icon: const Icon(SpotubeIcons.queueAdd), - onPressed: isLoading ? null : onAddToQueuePressed, - ), + scale: states.contains(WidgetState.hovered) ? 1 : 0.7, + child: AnimatedOpacity( + duration: const Duration(milliseconds: 150), + opacity: states.contains(WidgetState.hovered) ? 1 : 0, + child: IconButton.secondary( + icon: const Icon(SpotubeIcons.play), + onPressed: onPlaybuttonPressed, + size: ButtonSize.small, ), - const Gap(5), - IconButton( - style: IconButton.styleFrom( - backgroundColor: theme.colorScheme.primaryContainer, - foregroundColor: theme.colorScheme.primary, - minimumSize: const Size.square(10), - ), - icon: Skeleton.keep( - child: isLoading - ? SizedBox.fromSize( - size: const Size.square(15), - child: const CircularProgressIndicator( - strokeWidth: 2), - ) - : isPlaying - ? const Icon(SpotubeIcons.pause) - : const Icon(SpotubeIcons.play), - ), - onPressed: isLoading ? null : onPlaybuttonPressed, ), - ], - ), - ), - ], - ), - Column( - key: textsKey, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 15), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12.0), - child: AutoSizeText( - title, - maxLines: 1, - minFontSize: theme.textTheme.bodyMedium!.fontSize!, - overflow: TextOverflow.ellipsis, - ), - ), - if (description != null) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12.0), - child: AutoSizeText( - unescapeHtml!, - maxLines: 2, - style: theme.textTheme.bodySmall?.copyWith( - color: theme.colorScheme.onSurface.withOpacity(.5), - ), - overflow: TextOverflow.ellipsis, ), - ), - const SizedBox(height: 10), - ], - ), - ], + ], + ), + ); + }, + ) + ], + ), + title: Tooltip( + tooltip: Text(title), + child: Text( + title, + maxLines: 1, + overflow: TextOverflow.ellipsis, ), ), + subtitle: unescapeHtml == null + ? null + : Text( + unescapeHtml, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + onPressed: onTap, ), ); } From fcefce4b1bfa28221ee7d0a6a5bb815cb088d277 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 16:05:35 +0600 Subject: [PATCH 07/81] refactor: titlebar to use shadcn appbar and library tabs to use shadcn TabList --- lib/components/playbutton_card.dart | 15 +++--- lib/components/titlebar/titlebar.dart | 30 +++++------ lib/pages/library/library.dart | 78 ++++++++++++++++----------- 3 files changed, 67 insertions(+), 56 deletions(-) diff --git a/lib/components/playbutton_card.dart b/lib/components/playbutton_card.dart index 0b942564..f781066e 100644 --- a/lib/components/playbutton_card.dart +++ b/lib/components/playbutton_card.dart @@ -33,7 +33,7 @@ class PlaybuttonCard extends HookWidget { @override Widget build(BuildContext context) { - final unescapeHtml = description?.unescapeHtml().cleanHtml(); + final unescapeHtml = description?.unescapeHtml().cleanHtml() ?? ""; return Container( width: 150, @@ -42,6 +42,7 @@ class PlaybuttonCard extends HookWidget { children: [ UniversalImage( path: imageUrl, + height: 150, fit: BoxFit.cover, ), StatedWidget.builder( @@ -95,13 +96,11 @@ class PlaybuttonCard extends HookWidget { overflow: TextOverflow.ellipsis, ), ), - subtitle: unescapeHtml == null - ? null - : Text( - unescapeHtml, - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), + subtitle: Text( + unescapeHtml.isEmpty ? "\n" : unescapeHtml, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), onPressed: onTap, ), ); diff --git a/lib/components/titlebar/titlebar.dart b/lib/components/titlebar/titlebar.dart index 76a5ec8a..a3d0978c 100644 --- a/lib/components/titlebar/titlebar.dart +++ b/lib/components/titlebar/titlebar.dart @@ -1,5 +1,6 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' hide AppBar; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' show AppBar; import 'package:spotube/components/titlebar/titlebar_buttons.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/utils/platform.dart'; @@ -148,29 +149,26 @@ class _PageWindowTitleBarState extends ConsumerState { left: kIsMacOS && hasFullscreen && hasLeadingOrCanPop ? 65 : 0, ), child: AppBar( - leading: widget.leading, - automaticallyImplyLeading: widget.automaticallyImplyLeading, - actions: [ + leading: [ + if (widget.leading != null) widget.leading!, + if (widget.leading == null && + widget.automaticallyImplyLeading && + Navigator.canPop(context)) + const BackButton(), + ], + trailing: [ ...?widget.actions, WindowTitleBarButtons(foregroundColor: widget.foregroundColor), ], backgroundColor: widget.backgroundColor, - foregroundColor: widget.foregroundColor, - actionsIconTheme: widget.actionsIconTheme, - centerTitle: widget.centerTitle, - titleSpacing: widget.titleSpacing, - toolbarOpacity: widget.toolbarOpacity, - leadingWidth: widget.leadingWidth, - toolbarTextStyle: widget.toolbarTextStyle, - titleTextStyle: widget.titleTextStyle, title: SizedBox( width: double.infinity, // workaround to force dragging child: widget.title ?? const Text(""), ), - scrolledUnderElevation: 0, - shadowColor: Colors.transparent, - forceMaterialTransparency: true, - elevation: 0, + alignment: widget.centerTitle == true + ? Alignment.center + : Alignment.centerLeft, + leadingGap: widget.leadingWidth, ), ), ); diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index a0bc1bb7..02152f3d 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -1,5 +1,7 @@ -import 'package:flutter/material.dart' hide Image; +import 'package:flutter/material.dart' show Badge; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/modules/library/user_local_tracks.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -7,7 +9,6 @@ import 'package:spotube/modules/library/user_albums.dart'; import 'package:spotube/modules/library/user_artists.dart'; import 'package:spotube/modules/library/user_downloads.dart'; import 'package:spotube/modules/library/user_playlists.dart'; -import 'package:spotube/components/themed_button_tab_bar.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/download_manager_provider.dart'; @@ -18,40 +19,53 @@ class LibraryPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final downloadingCount = ref.watch(downloadManagerProvider).$downloadCount; + final index = useState(0); - return DefaultTabController( - length: 5, - child: SafeArea( - bottom: false, - child: Scaffold( - appBar: PageWindowTitleBar( - centerTitle: true, - leading: ThemedButtonsTabBar( - tabs: [ - Tab(text: " ${context.l10n.playlists} "), - Tab(text: " ${context.l10n.local_tab} "), - Tab( - child: Badge( - isLabelVisible: downloadingCount > 0, - label: Text(downloadingCount.toString()), - child: Text(" ${context.l10n.downloads} "), + final children = [ + Text(context.l10n.playlists), + Text(context.l10n.local_tab), + Badge( + isLabelVisible: downloadingCount > 0, + label: Text(downloadingCount.toString()), + child: Text(context.l10n.downloads), + ), + Text(context.l10n.artists), + Text(context.l10n.albums), + ]; + + return SafeArea( + bottom: false, + child: Scaffold( + headers: [ + PageWindowTitleBar( + leading: TabList( + index: index.value, + children: [ + for (final child in children) + TabButton( + child: child, + onPressed: () { + index.value = children.indexOf(child); + }, ), - ), - Tab(text: " ${context.l10n.artists} "), - Tab(text: " ${context.l10n.albums} "), ], ), - leadingWidth: double.infinity, - ), - body: const TabBarView( - children: [ - UserPlaylists(), - UserLocalTracks(), - UserDownloads(), - UserArtists(), - UserAlbums(), - ], - ), + ) + ], + child: IndexedStack( + index: index.value, + children: const [ + UserPlaylists(), + UserLocalTracks(), + UserDownloads(), + UserArtists(), + UserAlbums(), + // Text("UserPlaylists()"), + // Text("UserLocalTracks()"), + // Text("UserDownloads()"), + // Text("UserArtists()"), + // Text("UserAlbums()"), + ], ), ), ); From f80ea32de46c717020cba30acbab48ee4b9435e5 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 17:02:13 +0600 Subject: [PATCH 08/81] refactor: use Appbar titlebar throughout the app --- lib/components/titlebar/titlebar.dart | 222 ++++++------------ lib/components/track_tile/track_options.dart | 2 + lib/components/tracks_view/track_view.dart | 14 +- lib/modules/player/player.dart | 16 +- lib/pages/artist/artist.dart | 4 +- lib/pages/connect/connect.dart | 3 +- lib/pages/connect/control/control.dart | 2 +- .../getting_started/getting_started.dart | 4 +- lib/pages/home/feed/feed_section.dart | 4 +- lib/pages/home/genres/genre_playlists.dart | 4 +- lib/pages/home/genres/genres.dart | 3 +- lib/pages/home/home.dart | 2 +- lib/pages/lastfm_login/lastfm_login.dart | 2 +- lib/pages/library/library.dart | 33 ++- lib/pages/library/local_folder.dart | 7 +- .../playlist_generate/playlist_generate.dart | 5 +- .../playlist_generate_result.dart | 2 +- lib/pages/lyrics/lyrics.dart | 2 +- lib/pages/mobile_login/mobile_login.dart | 4 +- lib/pages/profile/profile.dart | 4 +- lib/pages/search/search.dart | 2 +- lib/pages/settings/about.dart | 4 +- lib/pages/settings/blacklist.dart | 5 +- lib/pages/settings/logs.dart | 6 +- lib/pages/settings/settings.dart | 3 +- lib/pages/stats/albums/albums.dart | 3 +- lib/pages/stats/artists/artists.dart | 3 +- lib/pages/stats/fees/fees.dart | 3 +- lib/pages/stats/minutes/minutes.dart | 3 +- lib/pages/stats/playlists/playlists.dart | 3 +- lib/pages/stats/stats.dart | 2 +- lib/pages/stats/streams/streams.dart | 3 +- lib/pages/track/track.dart | 2 +- 33 files changed, 149 insertions(+), 232 deletions(-) diff --git a/lib/components/titlebar/titlebar.dart b/lib/components/titlebar/titlebar.dart index a3d0978c..282a734d 100644 --- a/lib/components/titlebar/titlebar.dart +++ b/lib/components/titlebar/titlebar.dart @@ -1,89 +1,56 @@ import 'package:flutter/material.dart' hide AppBar; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:shadcn_flutter/shadcn_flutter.dart' show AppBar; +import 'package:shadcn_flutter/shadcn_flutter.dart' + show AppBar, WidgetExtension; import 'package:spotube/components/titlebar/titlebar_buttons.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/utils/platform.dart'; - import 'package:window_manager/window_manager.dart'; -class PageWindowTitleBar extends StatefulHookConsumerWidget - implements PreferredSizeWidget { - final Widget? leading; +class TitleBar extends HookConsumerWidget implements PreferredSizeWidget { final bool automaticallyImplyLeading; - final List? actions; + final List trailing; + final List leading; + final Widget? child; + final Widget? title; + final Widget? header; // small widget placed on top of title + final Widget? subtitle; // small widget placed below title + final bool + trailingExpanded; // expand the trailing instead of the main content + final AlignmentGeometry alignment; final Color? backgroundColor; final Color? foregroundColor; - final IconThemeData? actionsIconTheme; - final bool? centerTitle; - final double? titleSpacing; - final double toolbarOpacity; - final double? leadingWidth; - final TextStyle? toolbarTextStyle; - final TextStyle? titleTextStyle; - final double? titleWidth; - final Widget? title; + final double? leadingGap; + final double? trailingGap; + final EdgeInsetsGeometry? padding; + final double? height; + final bool useSafeArea; + final double? surfaceBlur; + final double? surfaceOpacity; - final bool _sliver; - - const PageWindowTitleBar({ + const TitleBar({ super.key, - this.actions, + this.automaticallyImplyLeading = true, + this.trailing = const [], + this.leading = const [], this.title, - this.toolbarOpacity = 1, + this.header, + this.subtitle, + this.child, + this.trailingExpanded = false, + this.alignment = Alignment.center, + this.padding, this.backgroundColor, - this.actionsIconTheme, - this.automaticallyImplyLeading = false, - this.centerTitle, this.foregroundColor, - this.leading, - this.leadingWidth, - this.titleSpacing, - this.titleTextStyle, - this.titleWidth, - this.toolbarTextStyle, - }) : _sliver = false, - pinned = false, - floating = false, - snap = false, - stretch = false; + this.leadingGap, + this.trailingGap, + this.height, + this.surfaceBlur, + this.surfaceOpacity, + this.useSafeArea = true, + }); - final bool pinned; - final bool floating; - final bool snap; - final bool stretch; - - const PageWindowTitleBar.sliver({ - super.key, - this.actions, - this.title, - this.backgroundColor, - this.actionsIconTheme, - this.automaticallyImplyLeading = false, - this.centerTitle, - this.foregroundColor, - this.leading, - this.leadingWidth, - this.titleSpacing, - this.titleTextStyle, - this.titleWidth, - this.toolbarTextStyle, - this.pinned = false, - this.floating = false, - this.snap = false, - this.stretch = false, - }) : _sliver = true, - toolbarOpacity = 1; - - @override - Size get preferredSize => const Size.fromHeight(kToolbarHeight); - - @override - ConsumerState createState() => _PageWindowTitleBarState(); -} - -class _PageWindowTitleBarState extends ConsumerState { - void onDrag(details) { + void onDrag(WidgetRef ref) { final systemTitleBar = ref.read(userPreferencesProvider.select((s) => s.systemTitleBar)); if (kIsDesktop && !systemTitleBar) { @@ -92,86 +59,53 @@ class _PageWindowTitleBarState extends ConsumerState { } @override - Widget build(BuildContext context) { - final mediaQuery = MediaQuery.of(context); + Widget build(BuildContext context, ref) { + final hasLeadingOrCanPop = leading.isNotEmpty || Navigator.canPop(context); - if (widget._sliver) { - return SliverLayoutBuilder( + return SizedBox( + height: height ?? 56, + child: LayoutBuilder( builder: (context, constraints) { final hasFullscreen = - mediaQuery.size.width == constraints.crossAxisExtent; - final hasLeadingOrCanPop = - widget.leading != null || Navigator.canPop(context); + MediaQuery.sizeOf(context).width == constraints.maxWidth; - return SliverPadding( - padding: EdgeInsets.only( - left: kIsMacOS && hasFullscreen && hasLeadingOrCanPop ? 65 : 0, - ), - sliver: SliverAppBar( - leading: widget.leading, - automaticallyImplyLeading: widget.automaticallyImplyLeading, - actions: [ - ...?widget.actions, - WindowTitleBarButtons(foregroundColor: widget.foregroundColor), + return GestureDetector( + onHorizontalDragStart: (_) => onDrag(ref), + onVerticalDragStart: (_) => onDrag(ref), + child: AppBar( + leading: leading.isEmpty && + automaticallyImplyLeading && + Navigator.canPop(context) + ? [ + const BackButton(), + ] + : leading, + trailing: [ + ...trailing, + WindowTitleBarButtons(foregroundColor: foregroundColor), ], - backgroundColor: widget.backgroundColor, - foregroundColor: widget.foregroundColor, - actionsIconTheme: widget.actionsIconTheme, - centerTitle: widget.centerTitle, - titleSpacing: widget.titleSpacing, - leadingWidth: widget.leadingWidth, - toolbarTextStyle: widget.toolbarTextStyle, - titleTextStyle: widget.titleTextStyle, - title: SizedBox( - width: double.infinity, // workaround to force dragging - child: widget.title ?? const Text(""), - ), - pinned: widget.pinned, - floating: widget.floating, - snap: widget.snap, - stretch: widget.stretch, - ), + title: title, + header: header, + subtitle: subtitle, + trailingExpanded: trailingExpanded, + alignment: alignment, + padding: padding, + backgroundColor: backgroundColor, + leadingGap: leadingGap, + trailingGap: trailingGap, + height: height, + surfaceBlur: surfaceBlur, + surfaceOpacity: surfaceOpacity, + useSafeArea: useSafeArea, + child: child, + ).withPadding( + left: kIsMacOS && hasFullscreen && hasLeadingOrCanPop ? 65 : 0), ); }, - ); - } - - return LayoutBuilder(builder: (context, constrains) { - final hasFullscreen = mediaQuery.size.width == constrains.maxWidth; - final hasLeadingOrCanPop = - widget.leading != null || Navigator.canPop(context); - - return GestureDetector( - onHorizontalDragStart: onDrag, - onVerticalDragStart: onDrag, - child: Padding( - padding: EdgeInsets.only( - left: kIsMacOS && hasFullscreen && hasLeadingOrCanPop ? 65 : 0, - ), - child: AppBar( - leading: [ - if (widget.leading != null) widget.leading!, - if (widget.leading == null && - widget.automaticallyImplyLeading && - Navigator.canPop(context)) - const BackButton(), - ], - trailing: [ - ...?widget.actions, - WindowTitleBarButtons(foregroundColor: widget.foregroundColor), - ], - backgroundColor: widget.backgroundColor, - title: SizedBox( - width: double.infinity, // workaround to force dragging - child: widget.title ?? const Text(""), - ), - alignment: widget.centerTitle == true - ? Alignment.center - : Alignment.centerLeft, - leadingGap: widget.leadingWidth, - ), - ), - ); - }); + ), + ); } + + @override + Size get preferredSize => Size.fromHeight(height ?? 56.0); } diff --git a/lib/components/track_tile/track_options.dart b/lib/components/track_tile/track_options.dart index 28a85fd1..c40ddd2a 100644 --- a/lib/components/track_tile/track_options.dart +++ b/lib/components/track_tile/track_options.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; + import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotify/spotify.dart' hide Offset; import 'package:spotube/collections/assets.gen.dart'; @@ -344,6 +345,7 @@ class TrackOptions extends HookConsumerWidget { leading: const Icon(SpotubeIcons.album), child: Column( mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(context.l10n.go_to_album), Text( diff --git a/lib/components/tracks_view/track_view.dart b/lib/components/tracks_view/track_view.dart index 2a3f5237..fa6011e0 100644 --- a/lib/components/tracks_view/track_view.dart +++ b/lib/components/tracks_view/track_view.dart @@ -20,14 +20,14 @@ class TrackView extends HookConsumerWidget { return Scaffold( appBar: kIsDesktop - ? const PageWindowTitleBar( + ? const TitleBar( backgroundColor: Colors.transparent, - foregroundColor: Colors.white, - leadingWidth: 400, - leading: Align( - alignment: Alignment.centerLeft, - child: BackButton(color: Colors.white), - ), + leading: [ + Align( + alignment: Alignment.centerLeft, + child: BackButton(color: Colors.white), + ) + ], ) : null, extendBodyBehindAppBar: true, diff --git a/lib/modules/player/player.dart b/lib/modules/player/player.dart index a79934d9..3f19fbf0 100644 --- a/lib/modules/player/player.dart +++ b/lib/modules/player/player.dart @@ -138,15 +138,15 @@ class PlayerView extends HookConsumerWidget { child: ForceDraggableWidget( child: Padding( padding: EdgeInsets.only(top: topPadding), - child: PageWindowTitleBar( + child: TitleBar( backgroundColor: Colors.transparent, - foregroundColor: titleTextColor, - toolbarOpacity: 1, - leading: IconButton( - icon: const Icon(SpotubeIcons.angleDown, size: 18), - onPressed: panelController.close, - ), - actions: [ + leading: [ + IconButton( + icon: const Icon(SpotubeIcons.angleDown, size: 18), + onPressed: panelController.close, + ) + ], + trailing: [ if (currentTrack is YoutubeSourcedTrack) TextButton.icon( icon: Assets.logos.songlinkTransparent.image( diff --git a/lib/pages/artist/artist.dart b/lib/pages/artist/artist.dart index 70ad72de..9e8b5be4 100644 --- a/lib/pages/artist/artist.dart +++ b/lib/pages/artist/artist.dart @@ -30,8 +30,8 @@ class ArtistPage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: const PageWindowTitleBar( - leading: BackButton(), + appBar: const TitleBar( + leading: [BackButton()], backgroundColor: Colors.transparent, ), extendBodyBehindAppBar: true, diff --git a/lib/pages/connect/connect.dart b/lib/pages/connect/connect.dart index d3b0d0cb..1a5dfb31 100644 --- a/lib/pages/connect/connect.dart +++ b/lib/pages/connect/connect.dart @@ -23,10 +23,9 @@ class ConnectPage extends HookConsumerWidget { final discoveredDevices = connectClients.asData?.value.services; return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( automaticallyImplyLeading: true, title: Text(context.l10n.devices), - titleSpacing: 0, ), body: ListTileTheme( shape: RoundedRectangleBorder( diff --git a/lib/pages/connect/control/control.dart b/lib/pages/connect/control/control.dart index cae0bd1b..03406546 100644 --- a/lib/pages/connect/control/control.dart +++ b/lib/pages/connect/control/control.dart @@ -88,7 +88,7 @@ class ConnectControlPage extends HookConsumerWidget { return SafeArea( child: Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(resolvedService!.name), automaticallyImplyLeading: true, ), diff --git a/lib/pages/getting_started/getting_started.dart b/lib/pages/getting_started/getting_started.dart index 0159a77f..6a8141d0 100644 --- a/lib/pages/getting_started/getting_started.dart +++ b/lib/pages/getting_started/getting_started.dart @@ -43,9 +43,9 @@ class GettingStarting extends HookConsumerWidget { return Theme( data: themeData, child: Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( backgroundColor: Colors.transparent, - actions: [ + trailing: [ ListenableBuilder( listenable: pageController, builder: (context, _) { diff --git a/lib/pages/home/feed/feed_section.dart b/lib/pages/home/feed/feed_section.dart index bcfc0b81..0249d865 100644 --- a/lib/pages/home/feed/feed_section.dart +++ b/lib/pages/home/feed/feed_section.dart @@ -23,11 +23,9 @@ class HomeFeedSectionPage extends HookConsumerWidget { return Skeletonizer( enabled: homeFeedSection.isLoading, child: Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(section.title ?? ""), - centerTitle: false, automaticallyImplyLeading: true, - titleSpacing: 0, ), body: CustomScrollView( slivers: [ diff --git a/lib/pages/home/genres/genre_playlists.dart b/lib/pages/home/genres/genre_playlists.dart index 04658965..ec478617 100644 --- a/lib/pages/home/genres/genre_playlists.dart +++ b/lib/pages/home/genres/genre_playlists.dart @@ -40,8 +40,8 @@ class GenrePlaylistsPage extends HookConsumerWidget { return Scaffold( appBar: kIsDesktop - ? const PageWindowTitleBar( - leading: BackButton(color: Colors.white), + ? const TitleBar( + leading: [BackButton(color: Colors.white)], backgroundColor: Colors.transparent, foregroundColor: Colors.white, ) diff --git a/lib/pages/home/genres/genres.dart b/lib/pages/home/genres/genres.dart index 4846d633..ed9d9351 100644 --- a/lib/pages/home/genres/genres.dart +++ b/lib/pages/home/genres/genres.dart @@ -25,10 +25,9 @@ class GenrePage extends HookConsumerWidget { final mediaQuery = MediaQuery.of(context); return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(context.l10n.explore_genres), automaticallyImplyLeading: true, - titleSpacing: 0, ), body: SafeArea( top: false, diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart index efdca4f7..eede8dfd 100644 --- a/lib/pages/home/home.dart +++ b/lib/pages/home/home.dart @@ -34,7 +34,7 @@ class HomePage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: kIsMobile || kIsMacOS ? null : const PageWindowTitleBar(), + appBar: kIsMobile || kIsMacOS ? null : const TitleBar(), body: CustomScrollView( controller: controller, slivers: [ diff --git a/lib/pages/lastfm_login/lastfm_login.dart b/lib/pages/lastfm_login/lastfm_login.dart index 8107e627..2611d771 100644 --- a/lib/pages/lastfm_login/lastfm_login.dart +++ b/lib/pages/lastfm_login/lastfm_login.dart @@ -27,7 +27,7 @@ class LastFMLoginPage extends HookConsumerWidget { final isLoading = useState(false); return Scaffold( - appBar: const PageWindowTitleBar(leading: BackButton()), + appBar: const TitleBar(leading: [BackButton()]), body: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 400), diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index 02152f3d..dbab9a87 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -37,19 +37,21 @@ class LibraryPage extends HookConsumerWidget { bottom: false, child: Scaffold( headers: [ - PageWindowTitleBar( - leading: TabList( - index: index.value, - children: [ - for (final child in children) - TabButton( - child: child, - onPressed: () { - index.value = children.indexOf(child); - }, - ), - ], - ), + TitleBar( + leading: [ + TabList( + index: index.value, + children: [ + for (final child in children) + TabButton( + child: child, + onPressed: () { + index.value = children.indexOf(child); + }, + ), + ], + ) + ], ) ], child: IndexedStack( @@ -60,11 +62,6 @@ class LibraryPage extends HookConsumerWidget { UserDownloads(), UserArtists(), UserAlbums(), - // Text("UserPlaylists()"), - // Text("UserLocalTracks()"), - // Text("UserDownloads()"), - // Text("UserArtists()"), - // Text("UserAlbums()"), ], ), ), diff --git a/lib/pages/library/local_folder.dart b/lib/pages/library/local_folder.dart index c2848b24..478eac5e 100644 --- a/lib/pages/library/local_folder.dart +++ b/lib/pages/library/local_folder.dart @@ -93,9 +93,8 @@ class LocalLibraryPage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: PageWindowTitleBar( - leading: const BackButton(), - centerTitle: true, + appBar: TitleBar( + leading: const [BackButton()], title: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -120,7 +119,7 @@ class LocalLibraryPage extends HookConsumerWidget { ], ), backgroundColor: Colors.transparent, - actions: [ + trailing: [ if (isCache) ...[ IconButton( iconSize: 16, diff --git a/lib/pages/library/playlist_generate/playlist_generate.dart b/lib/pages/library/playlist_generate/playlist_generate.dart index b62013c5..63565362 100644 --- a/lib/pages/library/playlist_generate/playlist_generate.dart +++ b/lib/pages/library/playlist_generate/playlist_generate.dart @@ -231,10 +231,9 @@ class PlaylistGeneratorPage extends HookConsumerWidget { final controller = useScrollController(); return Scaffold( - appBar: PageWindowTitleBar( - leading: const BackButton(), + appBar: TitleBar( + leading: const [BackButton()], title: Text(context.l10n.generate_playlist), - centerTitle: true, ), body: Scrollbar( controller: controller, diff --git a/lib/pages/library/playlist_generate/playlist_generate_result.dart b/lib/pages/library/playlist_generate/playlist_generate_result.dart index 3bdc3b52..f44cbee7 100644 --- a/lib/pages/library/playlist_generate/playlist_generate_result.dart +++ b/lib/pages/library/playlist_generate/playlist_generate_result.dart @@ -48,7 +48,7 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { (generatedPlaylist.asData?.value.length ?? 0); return Scaffold( - appBar: const PageWindowTitleBar(leading: BackButton()), + appBar: const TitleBar(leading: [BackButton()]), body: generatedPlaylist.isLoading ? Center( child: Column( diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index 0f4f9473..48005f6e 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -146,7 +146,7 @@ class LyricsPage extends HookConsumerWidget { child: Scaffold( extendBodyBehindAppBar: true, appBar: !kIsMacOS - ? PageWindowTitleBar( + ? TitleBar( backgroundColor: Colors.transparent, title: tabbar, ) diff --git a/lib/pages/mobile_login/mobile_login.dart b/lib/pages/mobile_login/mobile_login.dart index c45c2184..fa818dc8 100644 --- a/lib/pages/mobile_login/mobile_login.dart +++ b/lib/pages/mobile_login/mobile_login.dart @@ -24,8 +24,8 @@ class WebViewLogin extends HookConsumerWidget { } return Scaffold( - appBar: const PageWindowTitleBar( - leading: BackButton(color: Colors.white), + appBar: const TitleBar( + leading: [BackButton(color: Colors.white)], backgroundColor: Colors.transparent, ), extendBodyBehindAppBar: true, diff --git a/lib/pages/profile/profile.dart b/lib/pages/profile/profile.dart index 9e51793d..b4d72b53 100644 --- a/lib/pages/profile/profile.dart +++ b/lib/pages/profile/profile.dart @@ -42,11 +42,9 @@ class ProfilePage extends HookConsumerWidget { return SafeArea( child: Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(context.l10n.profile), - titleSpacing: 0, automaticallyImplyLeading: true, - centerTitle: false, ), body: Skeletonizer( enabled: me.isLoading, diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index d5de12f0..c413df68 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -88,7 +88,7 @@ class SearchPage extends HookConsumerWidget { bottom: false, child: Scaffold( appBar: kIsDesktop && !kIsMacOS - ? const PageWindowTitleBar(automaticallyImplyLeading: true) + ? const TitleBar(automaticallyImplyLeading: true) : null, body: auth.asData?.value == null ? const AnonymousFallback() diff --git a/lib/pages/settings/about.dart b/lib/pages/settings/about.dart index 1357c52f..491cdcf6 100644 --- a/lib/pages/settings/about.dart +++ b/lib/pages/settings/about.dart @@ -29,8 +29,8 @@ class AboutSpotube extends HookConsumerWidget { const colon = Text(":"); return Scaffold( - appBar: PageWindowTitleBar( - leading: const BackButton(), + appBar: TitleBar( + leading: const [BackButton()], title: Text(context.l10n.about_spotube), ), body: SingleChildScrollView( diff --git a/lib/pages/settings/blacklist.dart b/lib/pages/settings/blacklist.dart index 1f018dab..57a8b6fe 100644 --- a/lib/pages/settings/blacklist.dart +++ b/lib/pages/settings/blacklist.dart @@ -44,10 +44,9 @@ class BlackListPage extends HookConsumerWidget { ); return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(context.l10n.blacklist), - centerTitle: true, - leading: const BackButton(), + leading: const [BackButton()], ), body: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/pages/settings/logs.dart b/lib/pages/settings/logs.dart index 6ccbe32f..0f1260aa 100644 --- a/lib/pages/settings/logs.dart +++ b/lib/pages/settings/logs.dart @@ -21,10 +21,10 @@ class LogsPage extends HookConsumerWidget { final logsQuery = ref.watch(logsProvider); return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(context.l10n.logs), - leading: const BackButton(), - actions: [ + leading: const [BackButton()], + trailing: [ IconButton( icon: const Icon(SpotubeIcons.clipboard), iconSize: 16, diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index 8bce4bcf..a7355812 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -28,9 +28,8 @@ class SettingsPage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(context.l10n.settings), - centerTitle: true, automaticallyImplyLeading: true, ), body: Scrollbar( diff --git a/lib/pages/stats/albums/albums.dart b/lib/pages/stats/albums/albums.dart index e14a2f32..b424cd70 100644 --- a/lib/pages/stats/albums/albums.dart +++ b/lib/pages/stats/albums/albums.dart @@ -25,9 +25,8 @@ class StatsAlbumsPage extends HookConsumerWidget { final albumsData = topAlbums.asData?.value.items ?? []; return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( automaticallyImplyLeading: true, - centerTitle: false, title: Text(context.l10n.albums), ), body: Skeletonizer( diff --git a/lib/pages/stats/artists/artists.dart b/lib/pages/stats/artists/artists.dart index 436bbb57..468ddabb 100644 --- a/lib/pages/stats/artists/artists.dart +++ b/lib/pages/stats/artists/artists.dart @@ -28,9 +28,8 @@ class StatsArtistsPage extends HookConsumerWidget { () => topTracks.asData?.value.artists ?? [], [topTracks.asData?.value]); return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( automaticallyImplyLeading: true, - centerTitle: false, title: Text(context.l10n.artists), ), body: Skeletonizer( diff --git a/lib/pages/stats/fees/fees.dart b/lib/pages/stats/fees/fees.dart index da62fb30..1bbcb103 100644 --- a/lib/pages/stats/fees/fees.dart +++ b/lib/pages/stats/fees/fees.dart @@ -41,9 +41,8 @@ class StatsStreamFeesPage extends HookConsumerWidget { ); return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( automaticallyImplyLeading: true, - centerTitle: false, title: Text(context.l10n.streaming_fees_hypothetical), ), body: CustomScrollView( diff --git a/lib/pages/stats/minutes/minutes.dart b/lib/pages/stats/minutes/minutes.dart index 3ad0984b..f6cfafca 100644 --- a/lib/pages/stats/minutes/minutes.dart +++ b/lib/pages/stats/minutes/minutes.dart @@ -28,9 +28,8 @@ class StatsMinutesPage extends HookConsumerWidget { final tracksData = topTracks.asData?.value.items ?? []; return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(context.l10n.minutes_listened), - centerTitle: false, automaticallyImplyLeading: true, ), body: Skeletonizer( diff --git a/lib/pages/stats/playlists/playlists.dart b/lib/pages/stats/playlists/playlists.dart index 4e83b0a2..53885570 100644 --- a/lib/pages/stats/playlists/playlists.dart +++ b/lib/pages/stats/playlists/playlists.dart @@ -26,9 +26,8 @@ class StatsPlaylistsPage extends HookConsumerWidget { final playlistsData = topPlaylists.asData?.value.items ?? []; return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( automaticallyImplyLeading: true, - centerTitle: false, title: Text(context.l10n.playlists), ), body: Skeletonizer( diff --git a/lib/pages/stats/stats.dart b/lib/pages/stats/stats.dart index b2dc03c2..9c35df63 100644 --- a/lib/pages/stats/stats.dart +++ b/lib/pages/stats/stats.dart @@ -16,7 +16,7 @@ class StatsPage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: kIsMacOS || kIsMobile ? null : const PageWindowTitleBar(), + appBar: kIsMacOS || kIsMobile ? null : const TitleBar(), body: CustomScrollView( slivers: [ if (kIsMacOS) const SliverGap(20), diff --git a/lib/pages/stats/streams/streams.dart b/lib/pages/stats/streams/streams.dart index 059366e0..b835b3a6 100644 --- a/lib/pages/stats/streams/streams.dart +++ b/lib/pages/stats/streams/streams.dart @@ -28,9 +28,8 @@ class StatsStreamsPage extends HookConsumerWidget { final tracksData = topTracks.asData?.value.items ?? []; return Scaffold( - appBar: PageWindowTitleBar( + appBar: TitleBar( title: Text(context.l10n.streamed_songs), - centerTitle: false, automaticallyImplyLeading: true, ), body: Skeletonizer( diff --git a/lib/pages/track/track.dart b/lib/pages/track/track.dart index 84c53b74..30f2e998 100644 --- a/lib/pages/track/track.dart +++ b/lib/pages/track/track.dart @@ -53,7 +53,7 @@ class TrackPage extends HookConsumerWidget { } return Scaffold( - appBar: const PageWindowTitleBar( + appBar: const TitleBar( automaticallyImplyLeading: true, backgroundColor: Colors.transparent, ), From 2925dd6748302152d3819224a7d0164f78c94165 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 18:23:45 +0600 Subject: [PATCH 09/81] refactor: library page filter fields and update home sections --- lib/components/button/back_button.dart | 14 ++ .../horizontal_playbutton_card_view.dart | 7 +- lib/components/themed_button_tab_bar.dart | 50 ----- lib/modules/home/sections/featured.dart | 2 +- lib/modules/home/sections/feed.dart | 8 +- lib/modules/home/sections/friends.dart | 5 +- .../home/sections/friends/friend_item.dart | 27 +-- lib/modules/home/sections/genres.dart | 88 ++++---- lib/modules/home/sections/made_for_user.dart | 2 +- lib/modules/home/sections/new_releases.dart | 2 +- lib/modules/home/sections/recent.dart | 2 +- lib/modules/library/user_albums.dart | 18 +- lib/modules/library/user_artists.dart | 18 +- lib/modules/library/user_playlists.dart | 25 ++- lib/modules/root/sidebar.dart | 6 +- lib/modules/stats/top/top.dart | 3 +- lib/pages/home/home.dart | 15 +- lib/pages/lyrics/lyrics.dart | 211 +++++++++--------- lib/pages/search/search.dart | 187 +++++++--------- 19 files changed, 313 insertions(+), 377 deletions(-) create mode 100644 lib/components/button/back_button.dart delete mode 100644 lib/components/themed_button_tab_bar.dart diff --git a/lib/components/button/back_button.dart b/lib/components/button/back_button.dart new file mode 100644 index 00000000..784f8e6b --- /dev/null +++ b/lib/components/button/back_button.dart @@ -0,0 +1,14 @@ +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/collections/spotube_icons.dart'; + +class BackButton extends StatelessWidget { + const BackButton({super.key}); + + @override + Widget build(BuildContext context) { + return IconButton.ghost( + icon: const Icon(SpotubeIcons.angleLeft), + onPressed: () => Navigator.of(context).pop(), + ); + } +} diff --git a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart index 1093fff0..f41e0709 100644 --- a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart +++ b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart @@ -1,8 +1,8 @@ import 'dart:ui'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/fake.dart'; @@ -37,7 +37,6 @@ class HorizontalPlaybuttonCardView extends HookWidget { @override Widget build(BuildContext context) { - final ThemeData(:textTheme) = Theme.of(context); final scrollController = useScrollController(); final height = useBreakpointValue( xs: 226, @@ -56,7 +55,7 @@ class HorizontalPlaybuttonCardView extends HookWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ DefaultTextStyle( - style: textTheme.titleMedium!, + style: context.theme.typography.h4, child: title, ), if (titleTrailing != null) titleTrailing!, diff --git a/lib/components/themed_button_tab_bar.dart b/lib/components/themed_button_tab_bar.dart deleted file mode 100644 index c245e5f4..00000000 --- a/lib/components/themed_button_tab_bar.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:buttons_tabbar/buttons_tabbar.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:spotube/hooks/utils/use_brightness_value.dart'; - -class ThemedButtonsTabBar extends HookWidget implements PreferredSizeWidget { - final List tabs; - final TabController? controller; - const ThemedButtonsTabBar({super.key, required this.tabs, this.controller}); - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - final bgColor = useBrightnessValue( - theme.colorScheme.primaryContainer, - Color.lerp(theme.colorScheme.primary, Colors.black, 0.7)!, - ); - - return Padding( - padding: const EdgeInsets.only( - top: 8, - bottom: 8, - ), - child: ButtonsTabBar( - controller: controller, - radius: 100, - decoration: BoxDecoration( - color: bgColor, - borderRadius: BorderRadius.circular(15), - ), - labelStyle: theme.textTheme.labelLarge?.copyWith( - color: theme.colorScheme.primary, - fontWeight: FontWeight.bold, - ), - borderWidth: 0, - unselectedDecoration: BoxDecoration( - color: theme.colorScheme.surface, - borderRadius: BorderRadius.circular(15), - ), - unselectedLabelStyle: theme.textTheme.labelLarge?.copyWith( - color: theme.colorScheme.primary, - ), - tabs: tabs, - ), - ); - } - - @override - Size get preferredSize => const Size.fromHeight(50); -} diff --git a/lib/modules/home/sections/featured.dart b/lib/modules/home/sections/featured.dart index 4f30c342..9ccc8908 100644 --- a/lib/modules/home/sections/featured.dart +++ b/lib/modules/home/sections/featured.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart' hide Page; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; diff --git a/lib/modules/home/sections/feed.dart b/lib/modules/home/sections/feed.dart index 8685fe19..bce2ea5b 100644 --- a/lib/modules/home/sections/feed.dart +++ b/lib/modules/home/sections/feed.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; import 'package:spotube/extensions/context.dart'; @@ -40,9 +40,9 @@ class HomePageFeedSection extends HookConsumerWidget { onFetchMore: () {}, titleTrailing: Directionality( textDirection: TextDirection.rtl, - child: TextButton.icon( - label: Text(context.l10n.browse_more), - icon: const Icon(SpotubeIcons.angleRight), + child: Button.link( + leading: const Icon(SpotubeIcons.angleRight), + child: Text(context.l10n.browse_more), onPressed: () => ServiceUtils.pushNamed( context, HomeFeedSectionPage.name, diff --git a/lib/modules/home/sections/friends.dart b/lib/modules/home/sections/friends.dart index 6f59c209..00f4a86a 100644 --- a/lib/modules/home/sections/friends.dart +++ b/lib/modules/home/sections/friends.dart @@ -1,8 +1,9 @@ import 'dart:ui'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/modules/home/sections/friends/friend_item.dart'; @@ -75,7 +76,7 @@ class HomePageFriendsSection extends HookConsumerWidget { padding: const EdgeInsets.all(8.0), child: Text( context.l10n.friends, - style: Theme.of(context).textTheme.titleMedium, + style: context.theme.typography.h4, ), ), ), diff --git a/lib/modules/home/sections/friends/friend_item.dart b/lib/modules/home/sections/friends/friend_item.dart index 773a4a8c..42ec2909 100644 --- a/lib/modules/home/sections/friends/friend_item.dart +++ b/lib/modules/home/sections/friends/friend_item.dart @@ -1,8 +1,8 @@ import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/models/spotify_friends.dart'; @@ -20,27 +20,15 @@ class FriendItem extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData( - textTheme: textTheme, - colorScheme: colorScheme, - ) = Theme.of(context); - final spotify = ref.watch(spotifyProvider); - return Container( + return Card( padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: colorScheme.surfaceContainerHighest.withOpacity(0.3), - borderRadius: BorderRadius.circular(15), - ), - constraints: const BoxConstraints( - minWidth: 300, - ), - height: 80, child: Row( children: [ - CircleAvatar( - backgroundImage: UniversalImage.imageProvider( + Avatar( + initials: Avatar.getInitials(friend.user.name), + provider: UniversalImage.imageProvider( friend.user.imageUrl, ), ), @@ -50,11 +38,10 @@ class FriendItem extends HookConsumerWidget { children: [ Text( friend.user.name, - style: textTheme.bodyLarge, + style: context.theme.typography.bold, ), RichText( text: TextSpan( - style: textTheme.bodySmall, children: [ TextSpan( text: friend.track.name, diff --git a/lib/modules/home/sections/genres.dart b/lib/modules/home/sections/genres.dart index 5f2dfa5e..574f3294 100644 --- a/lib/modules/home/sections/genres.dart +++ b/lib/modules/home/sections/genres.dart @@ -1,10 +1,10 @@ import 'dart:math'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/fake.dart'; @@ -22,7 +22,6 @@ class HomeGenresSection extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme, :colorScheme) = Theme.of(context); final mediaQuery = MediaQuery.of(context); final categoriesQuery = ref.watch(categoriesProvider); @@ -46,21 +45,18 @@ class HomeGenresSection extends HookConsumerWidget { children: [ Text( context.l10n.genres, - style: textTheme.headlineSmall, + style: context.theme.typography.h4, ), Directionality( textDirection: TextDirection.rtl, - child: TextButton.icon( + child: Button.link( onPressed: () { context.pushNamed(GenrePage.name); }, - icon: const Icon(SpotubeIcons.angleRight), - label: Text( + leading: const Icon(SpotubeIcons.angleRight), + child: Text( context.l10n.browse_all, - style: textTheme.bodyMedium?.copyWith( - color: colorScheme.secondary, - ), - ), + ).muted(), ), ), ], @@ -96,12 +92,12 @@ class HomeGenresSection extends HookConsumerWidget { final text = gradient.colors .take(2) .any((c) => c.computeLuminance() > 0.5) - ? Colors.grey[900] + ? Colors.gray[900] : Colors.white; return ( gradient: LinearGradient( colors: gradient.colors - .map((c) => c.withOpacity(0.8)) + .map((c) => c.withAlpha((0.8 * 255).ceil())) .toList(), ), textColor: text @@ -110,40 +106,42 @@ class HomeGenresSection extends HookConsumerWidget { [], ); - return InkWell( - onTap: () { - context.pushNamed( - GenrePlaylistsPage.name, - pathParameters: { - "categoryId": category.id!, - }, - extra: category, - ); - }, - borderRadius: BorderRadius.circular(8), - child: Ink( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - image: DecorationImage( - image: UniversalImage.imageProvider( - category.icons!.first.url!, - ), - fit: BoxFit.cover, - ), - ), - child: Ink( + return MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + context.pushNamed( + GenrePlaylistsPage.name, + pathParameters: { + "categoryId": category.id!, + }, + extra: category, + ); + }, + child: Container( decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - color: colorScheme.surfaceContainerHighest, - gradient: categoriesQuery.isLoading ? null : gradient, + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + image: UniversalImage.imageProvider( + category.icons!.first.url!, + ), + fit: BoxFit.cover, + ), ), - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Align( - alignment: Alignment.centerLeft, - child: Text( - category.name!, - style: textTheme.titleMedium - ?.copyWith(color: textColor), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: context.theme.colorScheme.muted, + gradient: + categoriesQuery.isLoading ? null : gradient, + ), + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + category.name!, + style: context.theme.typography.large, + ), ), ), ), diff --git a/lib/modules/home/sections/made_for_user.dart b/lib/modules/home/sections/made_for_user.dart index 1b9854d3..4fd025d5 100644 --- a/lib/modules/home/sections/made_for_user.dart +++ b/lib/modules/home/sections/made_for_user.dart @@ -1,5 +1,5 @@ -import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; import 'package:spotube/provider/spotify/spotify.dart'; diff --git a/lib/modules/home/sections/new_releases.dart b/lib/modules/home/sections/new_releases.dart index e2b32741..2ebbbee0 100644 --- a/lib/modules/home/sections/new_releases.dart +++ b/lib/modules/home/sections/new_releases.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart' hide Page; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; import 'package:spotube/extensions/context.dart'; diff --git a/lib/modules/home/sections/recent.dart b/lib/modules/home/sections/recent.dart index 43c0459d..5420ad55 100644 --- a/lib/modules/home/sections/recent.dart +++ b/lib/modules/home/sections/recent.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; diff --git a/lib/modules/library/user_albums.dart b/lib/modules/library/user_albums.dart index 37fca7c0..4a22bbea 100644 --- a/lib/modules/library/user_albums.dart +++ b/lib/modules/library/user_albums.dart @@ -1,8 +1,8 @@ -import 'package:flutter/material.dart' hide Image; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide Image; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; -import 'package:gap/gap.dart'; + import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; @@ -52,7 +52,7 @@ class UserAlbums extends HookConsumerWidget { return SafeArea( child: Scaffold( - body: RefreshIndicator( + child: RefreshTrigger( onRefresh: () async { ref.invalidate(favoriteAlbumsProvider); }, @@ -62,13 +62,17 @@ class UserAlbums extends HookConsumerWidget { controller: controller, slivers: [ SliverAppBar( + backgroundColor: Theme.of(context).colorScheme.background, floating: true, flexibleSpace: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: SearchBar( - onChanged: (value) => searchText.value = value, - leading: const Icon(SpotubeIcons.filter), - hintText: context.l10n.filter_albums, + child: SizedBox( + height: 48, + child: TextField( + onChanged: (value) => searchText.value = value, + leading: const Icon(SpotubeIcons.filter), + placeholder: Text(context.l10n.filter_artist), + ), ), ), ), diff --git a/lib/modules/library/user_artists.dart b/lib/modules/library/user_artists.dart index 7968d91c..83a321fc 100644 --- a/lib/modules/library/user_artists.dart +++ b/lib/modules/library/user_artists.dart @@ -1,9 +1,9 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; -import 'package:gap/gap.dart'; + import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; @@ -54,7 +54,7 @@ class UserArtists extends HookConsumerWidget { return SafeArea( child: Scaffold( - body: RefreshIndicator( + child: RefreshTrigger( onRefresh: () async { ref.invalidate(followedArtistsProvider); }, @@ -66,11 +66,15 @@ class UserArtists extends HookConsumerWidget { controller: controller, slivers: [ SliverAppBar( + backgroundColor: Theme.of(context).colorScheme.background, floating: true, - flexibleSpace: SearchBar( - onChanged: (value) => searchText.value = value, - leading: const Icon(SpotubeIcons.filter), - hintText: context.l10n.filter_artist, + flexibleSpace: SizedBox( + height: 48, + child: TextField( + onChanged: (value) => searchText.value = value, + leading: const Icon(SpotubeIcons.filter), + placeholder: Text(context.l10n.filter_artist), + ), ), ), const SliverGap(10), diff --git a/lib/modules/library/user_playlists.dart b/lib/modules/library/user_playlists.dart index 577f9655..50595298 100644 --- a/lib/modules/library/user_playlists.dart +++ b/lib/modules/library/user_playlists.dart @@ -1,9 +1,10 @@ -import 'package:flutter/material.dart' hide Image; +import 'package:flutter/material.dart' show kToolbarHeight; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:collection/collection.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide Image; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; @@ -79,7 +80,7 @@ class UserPlaylists extends HookConsumerWidget { return const AnonymousFallback(); } - return RefreshIndicator( + return RefreshTrigger( onRefresh: () async { ref.invalidate(favoritePlaylistsProvider); }, @@ -91,11 +92,13 @@ class UserPlaylists extends HookConsumerWidget { slivers: [ SliverAppBar( floating: true, - flexibleSpace: Padding( + backgroundColor: context.theme.colorScheme.background, + flexibleSpace: Container( padding: const EdgeInsets.symmetric(horizontal: 8), - child: SearchBar( + height: 48, + child: TextField( onChanged: (value) => searchText.value = value, - hintText: context.l10n.filter_playlists, + placeholder: Text(context.l10n.filter_playlists), leading: const Icon(SpotubeIcons.filter), ), ), @@ -107,12 +110,14 @@ class UserPlaylists extends HookConsumerWidget { const Gap(10), const PlaylistCreateDialogButton(), const Gap(10), - ElevatedButton.icon( - icon: const Icon(SpotubeIcons.magic), - label: Text(context.l10n.generate_playlist), + Button.primary( + leading: const Icon(SpotubeIcons.magic), + child: Text(context.l10n.generate_playlist), onPressed: () { ServiceUtils.pushNamed( - context, PlaylistGeneratorPage.name); + context, + PlaylistGeneratorPage.name, + ); }, ), const Gap(10), diff --git a/lib/modules/root/sidebar.dart b/lib/modules/root/sidebar.dart index f045c23d..1afa85c5 100644 --- a/lib/modules/root/sidebar.dart +++ b/lib/modules/root/sidebar.dart @@ -104,7 +104,7 @@ class Sidebar extends HookConsumerWidget { index: selectedIndex, onSelected: (index) { final tile = sidebarTileList[index]; - ServiceUtils.pushNamed(context, tile.name); + context.goNamed(tile.name); }, children: navigationButtons, ) @@ -113,13 +113,13 @@ class Sidebar extends HookConsumerWidget { index: selectedIndex, onSelected: (index) { final tile = sidebarTileList[index]; - ServiceUtils.pushNamed(context, tile.name); + context.goNamed(tile.name); }, children: navigationButtons, ), ), const SidebarFooter(), - const Gap(130) + if (mediaQuery.lgAndUp) const Gap(130) else const Gap(65), ], ), const VerticalDivider(), diff --git a/lib/modules/stats/top/top.dart b/lib/modules/stats/top/top.dart index 643064aa..5c2cfbf9 100644 --- a/lib/modules/stats/top/top.dart +++ b/lib/modules/stats/top/top.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotube/components/themed_button_tab_bar.dart'; import 'package:spotube/modules/stats/top/albums.dart'; import 'package:spotube/modules/stats/top/artists.dart'; import 'package:spotube/modules/stats/top/tracks.dart'; @@ -23,7 +22,7 @@ class StatsPageTopSection extends HookConsumerWidget { slivers: [ SliverAppBar( floating: true, - flexibleSpace: ThemedButtonsTabBar( + flexibleSpace: TabBar( controller: tabController, tabs: [ Tab( diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart index eede8dfd..2dfbc0f3 100644 --- a/lib/pages/home/home.dart +++ b/lib/pages/home/home.dart @@ -1,7 +1,8 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; + import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/models/database/database.dart'; @@ -34,18 +35,22 @@ class HomePage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: kIsMobile || kIsMacOS ? null : const TitleBar(), - body: CustomScrollView( + headers: [ + if (kIsWindows || kIsLinux) const TitleBar(), + ], + child: CustomScrollView( controller: controller, slivers: [ if (mediaQuery.smAndDown || layoutMode == LayoutMode.compact) SliverAppBar( floating: true, title: Assets.spotubeLogoPng.image(height: 45), + backgroundColor: context.theme.colorScheme.background, + foregroundColor: context.theme.colorScheme.foreground, actions: [ const ConnectDeviceButton(), const Gap(10), - IconButton( + IconButton.ghost( icon: const Icon(SpotubeIcons.settings, size: 20), onPressed: () { ServiceUtils.pushNamed(context, SettingsPage.name); diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index 48005f6e..17e552e6 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -1,14 +1,12 @@ import 'dart:ui'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/components/image/universal_image.dart'; -import 'package:spotube/components/themed_button_tab_bar.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; @@ -39,6 +37,7 @@ class LyricsPage extends HookConsumerWidget { final palette = usePaletteColor(albumArt, ref); final mediaQuery = MediaQuery.of(context); final route = ModalRoute.of(context); + final selectedIndex = useState(0); final resetStatusBar = useCustomStatusBarColor( palette.color, @@ -46,134 +45,134 @@ class LyricsPage extends HookConsumerWidget { noSetBGColor: true, ); - PreferredSizeWidget tabbar = ThemedButtonsTabBar( - tabs: [ - Tab(text: " ${context.l10n.synced} "), - Tab(text: " ${context.l10n.plain} "), - ], + Widget tabbar = Padding( + padding: const EdgeInsets.all(10), + child: Opacity( + opacity: 0.8, + child: Tabs( + index: selectedIndex.value, + onChanged: (index) => selectedIndex.value = index, + tabs: [ + Text(context.l10n.synced), + Text(context.l10n.plain), + ], + ), + ), ); - tabbar = PreferredSize( - preferredSize: tabbar.preferredSize, - child: Row( - children: [ - tabbar, - const Spacer(), - Consumer( - builder: (context, ref, child) { - final playback = ref.watch(audioPlayerProvider); - final lyric = - ref.watch(syncedLyricsProvider(playback.activeTrack)); - final providerName = lyric.asData?.value.provider; + tabbar = Row( + children: [ + tabbar, + const Spacer(), + Consumer( + builder: (context, ref, child) { + final playback = ref.watch(audioPlayerProvider); + final lyric = ref.watch(syncedLyricsProvider(playback.activeTrack)); + final providerName = lyric.asData?.value.provider; - if (providerName == null) { - return const SizedBox.shrink(); - } + if (providerName == null) { + return const SizedBox.shrink(); + } - return Align( - alignment: Alignment.bottomRight, - child: Text(context.l10n.powered_by_provider(providerName)), - ); - }, - ), - const Gap(5), - ], - ), + return Align( + alignment: Alignment.bottomRight, + child: Text(context.l10n.powered_by_provider(providerName)), + ); + }, + ), + const Gap(5), + ], ); if (isModal) { return PopScope( canPop: true, onPopInvokedWithResult: (_, __) => resetStatusBar(), - child: DefaultTabController( - length: 2, - child: SafeArea( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), - child: Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surface.withOpacity(.4), - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(10), - topRight: Radius.circular(10), - ), + child: SafeArea( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), + child: Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.background.withOpacity(.4), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10), ), - child: Column( - children: [ - const SizedBox(height: 5), - Container( - height: 7, - width: 150, - decoration: BoxDecoration( - color: palette.titleTextColor, - borderRadius: BorderRadius.circular(10), - ), + ), + child: Column( + children: [ + const SizedBox(height: 5), + Container( + height: 7, + width: 150, + decoration: BoxDecoration( + color: palette.titleTextColor, + borderRadius: BorderRadius.circular(10), ), - AppBar( - leadingWidth: double.infinity, - leading: tabbar, - backgroundColor: Colors.transparent, - automaticallyImplyLeading: false, - actions: [ - IconButton( - icon: const Icon(SpotubeIcons.minimize), - onPressed: () => Navigator.of(context).pop(), - ), - const SizedBox(width: 5), + ), + AppBar( + leading: [tabbar], + backgroundColor: Colors.transparent, + trailing: [ + IconButton.ghost( + icon: const Icon(SpotubeIcons.minimize), + onPressed: () => Navigator.of(context).pop(), + ), + const SizedBox(width: 5), + ], + ), + Expanded( + child: IndexedStack( + index: selectedIndex.value, + children: [ + SyncedLyrics(palette: palette, isModal: isModal), + PlainLyrics(palette: palette, isModal: isModal), ], ), - Expanded( - child: TabBarView( - children: [ - SyncedLyrics(palette: palette, isModal: isModal), - PlainLyrics(palette: palette, isModal: isModal), - ], - ), - ), - ], - ), + ), + ], ), ), ), ), ); } - return DefaultTabController( - length: 2, - child: SafeArea( - bottom: mediaQuery.mdAndUp, - child: Scaffold( - extendBodyBehindAppBar: true, - appBar: !kIsMacOS + return SafeArea( + bottom: mediaQuery.mdAndUp, + child: Scaffold( + floatingHeader: true, + headers: [ + !kIsMacOS ? TitleBar( backgroundColor: Colors.transparent, title: tabbar, ) - : tabbar, - body: Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - image: DecorationImage( - image: UniversalImage.imageProvider(albumArt), - fit: BoxFit.cover, - ), - borderRadius: const BorderRadius.only( - bottomLeft: Radius.circular(10), - ), + : tabbar + ], + child: Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + image: DecorationImage( + image: UniversalImage.imageProvider(albumArt), + fit: BoxFit.cover, ), - margin: const EdgeInsets.only(bottom: 10), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: ColoredBox( - color: palette.color.withOpacity(.7), - child: SafeArea( - child: TabBarView( - children: [ - SyncedLyrics(palette: palette, isModal: isModal), - PlainLyrics(palette: palette, isModal: isModal), - ], - ), + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(10), + ), + ), + margin: const EdgeInsets.only(bottom: 10), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: ColoredBox( + color: palette.color.withOpacity(.7), + child: SafeArea( + child: IndexedStack( + index: selectedIndex.value, + children: [ + SyncedLyrics(palette: palette, isModal: isModal), + PlainLyrics(palette: palette, isModal: isModal), + ], ), ), ), diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index c413df68..ba5cce83 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -1,21 +1,17 @@ -import 'dart:async'; - -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart' hide Page; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:fuzzywuzzy/fuzzywuzzy.dart'; -import 'package:gap/gap.dart'; -import 'package:go_router/go_router.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:flutter/services.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:fuzzywuzzy/fuzzywuzzy.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; + import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/fallbacks/anonymous_fallback.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/utils/use_force_update.dart'; import 'package:spotube/pages/search/sections/albums.dart'; import 'package:spotube/pages/search/sections/artists.dart'; import 'package:spotube/pages/search/sections/playlists.dart'; @@ -23,7 +19,6 @@ import 'package:spotube/pages/search/sections/tracks.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/services/kv_store/kv_store.dart'; - import 'package:spotube/utils/platform.dart'; class SearchPage extends HookConsumerWidget { @@ -36,6 +31,7 @@ class SearchPage extends HookConsumerWidget { final theme = Theme.of(context); final searchTerm = ref.watch(searchTermStateProvider); final controller = useSearchController(); + final focusNode = useFocusNode(); final auth = ref.watch(authenticationProvider); final mediaQuery = MediaQuery.of(context); @@ -84,117 +80,92 @@ class SearchPage extends HookConsumerWidget { }, ); + void onSubmitted(String value) { + ref.read(searchTermStateProvider.notifier).state = value; + if (value.trim().isEmpty) { + return; + } + KVStoreService.setRecentSearches( + { + value, + ...KVStoreService.recentSearches, + }.toList(), + ); + } + return SafeArea( bottom: false, child: Scaffold( - appBar: kIsDesktop && !kIsMacOS - ? const TitleBar(automaticallyImplyLeading: true) - : null, - body: auth.asData?.value == null + headers: [ + if (kIsWindows || kIsLinux) + const TitleBar(automaticallyImplyLeading: true) + ], + child: auth.asData?.value == null ? const AnonymousFallback() : Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - if ((kIsMobile || kIsMacOS) && context.canPop()) - const BackButton() - else - const Gap(20), Expanded( child: Padding( - padding: const EdgeInsets.only( - right: 20, - top: 20, - bottom: 20, - ), - child: SearchAnchor( - searchController: controller, - viewBuilder: (_) => HookBuilder(builder: (context) { - final searchController = - useListenable(controller); - final update = useForceUpdate(); - final suggestions = searchController.text.isEmpty - ? KVStoreService.recentSearches - : KVStoreService.recentSearches - .where( - (s) => - weightedRatio( - s.toLowerCase(), - searchController.text - .toLowerCase(), - ) > - 50, - ) - .toList(); + padding: const EdgeInsets.all(20), + child: ListenableBuilder( + listenable: controller, + builder: (context, _) { + final suggestions = controller.text.isEmpty + ? KVStoreService.recentSearches + : KVStoreService.recentSearches + .where( + (s) => + weightedRatio( + s.toLowerCase(), + controller.text.toLowerCase(), + ) > + 50, + ) + .toList(); - return ListView.builder( - itemCount: suggestions.length, - itemBuilder: (context, index) { - final suggestion = suggestions[index]; + return KeyboardListener( + focusNode: focusNode, + autofocus: true, + onKeyEvent: (value) { + final isEnter = value.logicalKey == + LogicalKeyboardKey.enter; - return ListTile( - leading: const Icon(SpotubeIcons.history), - title: Text(suggestion), - trailing: IconButton( - icon: const Icon(SpotubeIcons.trash), + if (isEnter) { + onSubmitted(controller.text); + focusNode.unfocus(); + } + }, + child: AutoComplete( + autofocus: true, + controller: controller, + suggestions: suggestions, + leading: const Icon(SpotubeIcons.search), + textInputAction: TextInputAction.search, + placeholder: Text(context.l10n.search), + trailing: IconButton.ghost( + size: ButtonSize.small, + icon: const Icon(SpotubeIcons.close), onPressed: () { - KVStoreService.setRecentSearches( - KVStoreService.recentSearches - .where((s) => s != suggestion) - .toList(), - ); - update(); + controller.clear(); }, ), - onTap: () { - controller.closeView(suggestion); + onAcceptSuggestion: (index) { + controller.text = + KVStoreService.recentSearches[index]; ref - .read( - searchTermStateProvider.notifier) - .state = suggestion; + .read(searchTermStateProvider + .notifier) + .state = + KVStoreService.recentSearches[index]; }, - ); - }, - ); - }), - suggestionsBuilder: (context, controller) { - return []; - }, - viewOnSubmitted: (value) async { - controller.closeView(value); - Timer( - const Duration(milliseconds: 50), - () { - ref - .read(searchTermStateProvider.notifier) - .state = value; - if (value.trim().isEmpty) { - return; - } - KVStoreService.setRecentSearches( - { - value, - ...KVStoreService.recentSearches, - }.toList(), - ); - }, - ); - }, - builder: (context, controller) { - return SearchBar( - autoFocus: queries.none((s) => - s.asData?.value != null && - !s.hasError) && - !kIsMobile, - controller: controller, - leading: const Icon(SpotubeIcons.search), - hintText: "${context.l10n.search}...", - onTap: controller.openView, - onChanged: (_) => controller.openView(), - ); - }, - ), + onChanged: (value) {}, + onSubmitted: onSubmitted, + ), + ); + }), ), ), ], @@ -211,15 +182,15 @@ class SearchPage extends HookConsumerWidget { Icon( SpotubeIcons.web, size: 120, - color: theme.colorScheme.onSurface + color: theme.colorScheme.foreground .withOpacity(0.7), ), const SizedBox(height: 20), Text( context.l10n.search_to_get_results, - style: theme.textTheme.titleLarge?.copyWith( + style: theme.typography.h3.copyWith( fontWeight: FontWeight.w900, - color: theme.colorScheme.onSurface + color: theme.colorScheme.foreground .withOpacity(0.5), ), ), @@ -245,7 +216,7 @@ class SearchPage extends HookConsumerWidget { style: TextStyle( fontSize: 20, fontWeight: FontWeight.w900, - color: theme.colorScheme.onSurface + color: theme.colorScheme.foreground .withOpacity(0.7), ), ), From 418a0d29bda84b4a1479f47f2a87b7c8d3cde2e4 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 21:12:49 +0600 Subject: [PATCH 10/81] refactor: artist card to use shadcn card --- lib/modules/artist/artist_card.dart | 137 +++++++++------------------- 1 file changed, 44 insertions(+), 93 deletions(-) diff --git a/lib/modules/artist/artist_card.dart b/lib/modules/artist/artist_card.dart index add2608d..57c955c7 100644 --- a/lib/modules/artist/artist_card.dart +++ b/lib/modules/artist/artist_card.dart @@ -1,14 +1,13 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; + import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:skeletonizer/skeletonizer.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; -import 'package:spotube/hooks/utils/use_breakpoint_value.dart'; -import 'package:spotube/hooks/utils/use_brightness_value.dart'; + import 'package:spotube/pages/artist/artist.dart'; import 'package:spotube/provider/blacklist_provider.dart'; import 'package:spotube/utils/service_utils.dart'; @@ -33,98 +32,50 @@ class ArtistCard extends HookConsumerWidget { ), ); - final radius = BorderRadius.circular(15); - - final double size = useBreakpointValue( - xs: 130, - sm: 130, - md: 150, - others: 170, - ); - - return Container( - width: size, - margin: const EdgeInsets.symmetric(vertical: 5), - child: Material( - shadowColor: theme.colorScheme.surface, - color: Color.lerp( - theme.colorScheme.surfaceContainerHighest, - theme.colorScheme.surface, - useBrightnessValue(.9, .7), - ), - elevation: 3, - shape: RoundedRectangleBorder( - borderRadius: radius, - side: isBlackListed == true - ? const BorderSide( - color: Colors.red, - width: 2, - ) - : BorderSide.none, - ), - child: InkWell( - onTap: () { - ServiceUtils.pushNamed( - context, - ArtistPage.name, - pathParameters: { - "id": artist.id!, - }, - ); + return SizedBox( + width: 180, + child: Button.card( + onPressed: () { + ServiceUtils.pushNamed( + context, + ArtistPage.name, + pathParameters: { + "id": artist.id!, }, - borderRadius: radius, - child: Padding( - padding: const EdgeInsets.all(12), - child: Column( - children: [ - Stack( - children: [ - ConstrainedBox( - constraints: BoxConstraints( - maxHeight: size, - ), - child: CircleAvatar( - backgroundImage: backgroundImage, - radius: size / 2, - ), - ), - Positioned( - right: 0, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 5, - ), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(50)), - child: Skeleton.ignore( - child: Text( - context.l10n.artist, - style: const TextStyle( - color: Colors.white, - fontSize: 12, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ), - ], - ), - const SizedBox(height: 10), - AutoSizeText( - artist.name!, - maxLines: 1, - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, - style: theme.textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.bold, - ), + ); + }, + child: Column( + children: [ + Avatar( + initials: artist.name!.trim()[0].toUpperCase(), + provider: backgroundImage, + size: 130, + ), + const Gap(10), + AutoSizeText( + artist.name!, + maxLines: 2, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: theme.typography.bold, + ), + const Spacer(), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (isBlackListed == true) ...[ + DestructiveBadge( + child: Text(context.l10n.blacklisted.toUpperCase()), ), + const Gap(5), ], - ), - )), + SecondaryBadge( + child: Text(context.l10n.artist.toUpperCase()), + ) + ], + ) + ], + ), ), ); } From 7ee071f2e312beaa3ee007119881bbd50e2f70ef Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 21 Dec 2024 21:40:34 +0600 Subject: [PATCH 11/81] refactor: connected device button --- lib/modules/connect/connect_device.dart | 126 ++++++------------- lib/modules/root/spotube_navigation_bar.dart | 4 +- lib/pages/library/library.dart | 34 ++--- 3 files changed, 56 insertions(+), 108 deletions(-) diff --git a/lib/modules/connect/connect_device.dart b/lib/modules/connect/connect_device.dart index f4888534..be9826a3 100644 --- a/lib/modules/connect/connect_device.dart +++ b/lib/modules/connect/connect_device.dart @@ -1,6 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/connect/connect.dart'; @@ -14,110 +13,55 @@ class ConnectDeviceButton extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:colorScheme) = Theme.of(context); - final pixelRatio = MediaQuery.of(context).devicePixelRatio; final connectClients = ref.watch(connectClientsProvider); + final hasServices = + connectClients.asData?.value.services.isNotEmpty == true; + if (_sidebar) { return SizedBox( width: double.infinity, - child: TextButton( + child: Button.primary( onPressed: () { ServiceUtils.pushNamed(context, ConnectPage.name); }, - style: FilledButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - padding: const EdgeInsets.all(5), - ), - child: Row( - children: [ - Text(context.l10n.devices), - if (connectClients.asData?.value.services.isNotEmpty == true) - Text( - " (${connectClients.asData?.value.services.length})", - ), - const Spacer(), - const Icon(SpotubeIcons.speaker), - const Gap(5), - ], + trailing: const Icon(SpotubeIcons.speaker), + child: Text( + "${context.l10n.devices}" + "${hasServices ? " (${connectClients.asData?.value.services.length})" : ""}", ), ), ); } - return SizedBox( - height: 40 * pixelRatio, - child: Stack( - alignment: Alignment.centerRight, - fit: StackFit.loose, - children: [ - Material( - type: MaterialType.transparency, - child: Center( - child: ClipRect( - clipBehavior: Clip.hardEdge, - child: InkWell( - onTap: () { - ServiceUtils.pushNamed(context, ConnectPage.name); - }, - borderRadius: BorderRadius.circular(50), - child: Ink( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(50), - color: colorScheme.primaryContainer, - ), - padding: - const EdgeInsets.symmetric(horizontal: 10, vertical: 5), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (connectClients.asData?.value.resolvedService != - null) ...[ - Container( - width: 7, - height: 7, - decoration: BoxDecoration( - color: Colors.greenAccent, - borderRadius: BorderRadius.circular(50), - ), - ), - const Gap(5), - ], - Text(context.l10n.devices), - if (connectClients.asData?.value.services.isNotEmpty == - true) - Text( - " (${connectClients.asData?.value.services.length})", - style: TextStyle( - color: colorScheme.onPrimaryContainer - .withOpacity(0.5), - ), - ), - const Gap(35), - ], - ), + return Row( + children: [ + SecondaryBadge( + onPressed: () { + ServiceUtils.pushNamed(context, ConnectPage.name); + }, + style: const ButtonStyle.secondary(size: ButtonSize(.8)), + leading: connectClients.asData?.value.resolvedService != null + ? const Center( + child: DotItem( + size: 6, + borderRadius: 10, + color: Colors.green, ), - ), - ), - ), + ) + : null, + child: Text( + "${context.l10n.devices}" + "${hasServices ? " (${connectClients.asData?.value.services.length})" : ""}", ), - Positioned( - right: -3, - child: IconButton.filled( - icon: const Icon(SpotubeIcons.speaker), - style: IconButton.styleFrom( - visualDensity: VisualDensity.standard, - foregroundColor: colorScheme.onPrimary, - ), - onPressed: () { - ServiceUtils.pushNamed(context, ConnectPage.name); - }, - ), - ), - ], - ), + ), + IconButton.primary( + icon: const Icon(SpotubeIcons.speaker), + onPressed: () { + ServiceUtils.pushNamed(context, ConnectPage.name); + }, + ) + ], ); } } diff --git a/lib/modules/root/spotube_navigation_bar.dart b/lib/modules/root/spotube_navigation_bar.dart index c2cf4b5a..fa585054 100644 --- a/lib/modules/root/spotube_navigation_bar.dart +++ b/lib/modules/root/spotube_navigation_bar.dart @@ -7,7 +7,6 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/utils/use_brightness_value.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; @@ -61,6 +60,9 @@ class SpotubeNavigationBar extends HookConsumerWidget { children: [ for (final tile in navbarTileList) NavigationButton( + style: const ButtonStyle.muted(density: ButtonDensity.icon), + selectedStyle: + const ButtonStyle.fixed(density: ButtonDensity.icon), child: Badge( isLabelVisible: tile.id == "library" && downloadCount > 0, label: Text(downloadCount.toString()), diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index dbab9a87..e107f413 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -11,6 +11,7 @@ import 'package:spotube/modules/library/user_downloads.dart'; import 'package:spotube/modules/library/user_playlists.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/download_manager_provider.dart'; +import 'package:spotube/utils/platform.dart'; class LibraryPage extends HookConsumerWidget { static const name = "library"; @@ -37,22 +38,23 @@ class LibraryPage extends HookConsumerWidget { bottom: false, child: Scaffold( headers: [ - TitleBar( - leading: [ - TabList( - index: index.value, - children: [ - for (final child in children) - TabButton( - child: child, - onPressed: () { - index.value = children.indexOf(child); - }, - ), - ], - ) - ], - ) + if (kIsWindows || kIsLinux) const TitleBar(), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: TabList( + index: index.value, + children: [ + for (final child in children) + TabButton( + child: child, + onPressed: () { + index.value = children.indexOf(child); + }, + ), + ], + ), + ), + const Gap(10), ], child: IndexedStack( index: index.value, From 2fefd65f5171735c8abab8b7181c8423472ab124 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 22 Dec 2024 11:25:01 +0600 Subject: [PATCH 12/81] refactor: settings using shadcn components --- lib/collections/spotube_icons.dart | 2 + .../adaptive/adaptive_select_tile.dart | 103 ++--- lib/components/button/back_button.dart | 1 + lib/components/playbutton_card.dart | 19 +- lib/components/titlebar/titlebar.dart | 5 +- lib/modules/player/player_queue.dart | 2 +- .../settings/section_card_with_heading.dart | 54 ++- lib/pages/search/search.dart | 21 +- lib/pages/settings/sections/about.dart | 23 +- lib/pages/settings/sections/accounts.dart | 38 +- lib/pages/settings/sections/appearance.dart | 47 +-- lib/pages/settings/sections/desktop.dart | 38 +- lib/pages/settings/sections/developers.dart | 3 +- lib/pages/settings/sections/downloads.dart | 7 +- .../settings/sections/language_region.dart | 10 +- lib/pages/settings/sections/playback.dart | 380 +++++++++--------- lib/pages/settings/settings.dart | 54 +-- macos/Runner/AppDelegate.swift | 4 + pubspec.lock | 4 +- pubspec.yaml | 2 +- 20 files changed, 421 insertions(+), 396 deletions(-) diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index a1c6d69f..ff7092e3 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -128,4 +128,6 @@ abstract class SpotubeIcons { static const export = Icons.file_open_outlined; static const delete = FeatherIcons.trash2; static const open = FeatherIcons.externalLink; + static const radioChecked = Icons.radio_button_on_rounded; + static const radioUnchecked = Icons.radio_button_off_rounded; } diff --git a/lib/components/adaptive/adaptive_select_tile.dart b/lib/components/adaptive/adaptive_select_tile.dart index 3f6d2700..40308711 100644 --- a/lib/components/adaptive/adaptive_select_tile.dart +++ b/lib/components/adaptive/adaptive_select_tile.dart @@ -1,5 +1,6 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show ListTile, ListTileControlAffinity; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/extensions/constrains.dart'; @@ -11,7 +12,7 @@ class AdaptiveSelectTile extends HookWidget { final T value; final ValueChanged? onChanged; - final List> options; + final List> options; /// Show the smaller value when the breakpoint is reached /// @@ -39,55 +40,25 @@ class AdaptiveSelectTile extends HookWidget { Widget build(BuildContext context) { final theme = Theme.of(context); final mediaQuery = MediaQuery.of(context); - final rawControl = DecoratedBox( - decoration: BoxDecoration( - color: theme.colorScheme.secondaryContainer, - borderRadius: BorderRadius.circular(10), - ), - child: DropdownButton( - items: options, - value: value, - onChanged: onChanged, - menuMaxHeight: mediaQuery.size.height * 0.6, - underline: const SizedBox.shrink(), - padding: const EdgeInsets.symmetric(horizontal: 10), - borderRadius: BorderRadius.circular(10), - icon: const Icon(SpotubeIcons.angleDown), - dropdownColor: theme.colorScheme.secondaryContainer, - ), - ); - final controlPlaceholder = useMemoized( - () => options - .firstWhere( - (element) => element.value == value, - orElse: () => DropdownMenuItem( - value: null, - child: Container(), - ), - ) - .child, - [value, options]); - final control = breakLayout ?? mediaQuery.mdAndUp - ? rawControl - : showValueWhenUnfolded - ? Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - border: Border.all( - color: theme.colorScheme.primary, - width: 2, - ), - borderRadius: BorderRadius.circular(10), - ), - child: DefaultTextStyle( - style: TextStyle( - color: theme.colorScheme.primary, - ), - child: controlPlaceholder, - ), - ) - : const SizedBox.shrink(); + Widget? control = Select( + itemBuilder: (context, item) { + return options.firstWhere((element) => element.value == item).child; + }, + value: value, + onChanged: onChanged, + children: options, + ); + + if (mediaQuery.smAndDown) { + if (showValueWhenUnfolded) { + control = OutlineBadge( + child: options.firstWhere((element) => element.value == value).child, + ); + } else { + control = null; + } + } return ListTile( title: title, @@ -104,20 +75,26 @@ class AdaptiveSelectTile extends HookWidget { showDialog( context: context, builder: (context) { - return SimpleDialog( - title: title, - children: [ - for (final option in options) - RadioListTile( - title: option.child, - value: option.value as T, - groupValue: value, - onChanged: (v) { - Navigator.pop(context); - onChanged?.call(v); + return AlertDialog( + content: ListView.builder( + shrinkWrap: true, + itemCount: options.length, + itemBuilder: (context, index) { + final item = options[index]; + + return ListTile( + iconColor: theme.colorScheme.primary, + leading: item.value == value + ? const Icon(SpotubeIcons.radioChecked) + : const Icon(SpotubeIcons.radioUnchecked), + title: item.child, + onTap: () { + onChanged?.call(item.value); + Navigator.of(context).pop(); }, - ), - ], + ); + }, + ), ); }, ); diff --git a/lib/components/button/back_button.dart b/lib/components/button/back_button.dart index 784f8e6b..41b7d527 100644 --- a/lib/components/button/back_button.dart +++ b/lib/components/button/back_button.dart @@ -7,6 +7,7 @@ class BackButton extends StatelessWidget { @override Widget build(BuildContext context) { return IconButton.ghost( + size: const ButtonSize(.9), icon: const Icon(SpotubeIcons.angleLeft), onPressed: () => Navigator.of(context).pop(), ); diff --git a/lib/components/playbutton_card.dart b/lib/components/playbutton_card.dart index f781066e..31143ae8 100644 --- a/lib/components/playbutton_card.dart +++ b/lib/components/playbutton_card.dart @@ -4,6 +4,7 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/string.dart'; +import 'package:spotube/utils/platform.dart'; class PlaybuttonCard extends HookWidget { final void Function()? onTap; @@ -55,10 +56,15 @@ class PlaybuttonCard extends HookWidget { AnimatedScale( curve: Curves.easeOutBack, duration: const Duration(milliseconds: 300), - scale: states.contains(WidgetState.hovered) ? 1 : 0.7, + scale: states.contains(WidgetState.hovered) || kIsMobile + ? 1 + : 0.7, child: AnimatedOpacity( duration: const Duration(milliseconds: 300), - opacity: states.contains(WidgetState.hovered) ? 1 : 0, + opacity: + states.contains(WidgetState.hovered) || kIsMobile + ? 1 + : 0, child: IconButton.secondary( icon: const Icon(SpotubeIcons.queueAdd), onPressed: onAddToQueuePressed, @@ -70,10 +76,15 @@ class PlaybuttonCard extends HookWidget { AnimatedScale( curve: Curves.easeOutBack, duration: const Duration(milliseconds: 150), - scale: states.contains(WidgetState.hovered) ? 1 : 0.7, + scale: states.contains(WidgetState.hovered) || kIsMobile + ? 1 + : 0.7, child: AnimatedOpacity( duration: const Duration(milliseconds: 150), - opacity: states.contains(WidgetState.hovered) ? 1 : 0, + opacity: + states.contains(WidgetState.hovered) || kIsMobile + ? 1 + : 0, child: IconButton.secondary( icon: const Icon(SpotubeIcons.play), onPressed: onPlaybuttonPressed, diff --git a/lib/components/titlebar/titlebar.dart b/lib/components/titlebar/titlebar.dart index 282a734d..5c3f7940 100644 --- a/lib/components/titlebar/titlebar.dart +++ b/lib/components/titlebar/titlebar.dart @@ -1,7 +1,6 @@ -import 'package:flutter/material.dart' hide AppBar; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:shadcn_flutter/shadcn_flutter.dart' - show AppBar, WidgetExtension; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/components/titlebar/titlebar_buttons.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/utils/platform.dart'; diff --git a/lib/modules/player/player_queue.dart b/lib/modules/player/player_queue.dart index 49279d5c..0186d974 100644 --- a/lib/modules/player/player_queue.dart +++ b/lib/modules/player/player_queue.dart @@ -237,7 +237,7 @@ class PlayerQueue extends HookConsumerWidget { right: 20, bottom: 20, child: IconButton.secondary( - icon: const Icon(SpotubeIcons.open), + icon: const Icon(SpotubeIcons.angleDown), onPressed: () { controller.scrollToIndex( playlist.playlist.index, diff --git a/lib/modules/settings/section_card_with_heading.dart b/lib/modules/settings/section_card_with_heading.dart index 87060579..cd9428f0 100644 --- a/lib/modules/settings/section_card_with_heading.dart +++ b/lib/modules/settings/section_card_with_heading.dart @@ -1,4 +1,6 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show ListTileTheme, ListTileThemeData; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; class SectionCardWithHeading extends StatelessWidget { final String heading; @@ -11,27 +13,41 @@ class SectionCardWithHeading extends StatelessWidget { @override Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text( - heading, - style: Theme.of(context).textTheme.titleLarge?.copyWith( - fontWeight: FontWeight.w600, - ), + return ListTileTheme( + data: ListTileThemeData( + shape: RoundedRectangleBorder( + borderRadius: context.theme.borderRadiusLg, + side: BorderSide( + color: context.theme.colorScheme.border, + width: .5, ), ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Card( - clipBehavior: Clip.antiAliasWithSaveLayer, - child: Column(mainAxisSize: MainAxisSize.min, children: children), + textColor: context.theme.colorScheme.foreground, + iconColor: context.theme.colorScheme.foreground, + selectedColor: context.theme.colorScheme.accent, + subtitleTextStyle: context.theme.typography.xSmall, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Text( + heading, + style: context.theme.typography.large, + ), ), - ), - ], + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: children, + ).gap(8.0), + ), + ], + ), ); } } diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index ba5cce83..5c096a32 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -145,12 +145,21 @@ class SearchPage extends HookConsumerWidget { leading: const Icon(SpotubeIcons.search), textInputAction: TextInputAction.search, placeholder: Text(context.l10n.search), - trailing: IconButton.ghost( - size: ButtonSize.small, - icon: const Icon(SpotubeIcons.close), - onPressed: () { - controller.clear(); - }, + trailing: AnimatedCrossFade( + duration: + const Duration(milliseconds: 300), + crossFadeState: controller.text.isNotEmpty + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + firstChild: IconButton.ghost( + size: ButtonSize.small, + icon: const Icon(SpotubeIcons.close), + onPressed: () { + controller.clear(); + }, + ), + secondChild: + const SizedBox.square(dimension: 28), ), onAcceptSuggestion: (index) { controller.text = diff --git a/lib/pages/settings/sections/about.dart b/lib/pages/settings/sections/about.dart index a0a5bf30..5910fc1b 100644 --- a/lib/pages/settings/sections/about.dart +++ b/lib/pages/settings/sections/about.dart @@ -1,7 +1,9 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show FilledButton, ButtonStyle, ListTile; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide ButtonStyle; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/env.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/settings/section_card_with_heading.dart'; @@ -45,9 +47,13 @@ class SettingsAboutSection extends HookConsumerWidget { trailing: (context, update) => FilledButton( style: ButtonStyle( backgroundColor: WidgetStatePropertyAll(Colors.red[100]), - foregroundColor: - const WidgetStatePropertyAll(Colors.pinkAccent), + foregroundColor: const WidgetStatePropertyAll(Colors.pink), padding: const WidgetStatePropertyAll(EdgeInsets.all(15)), + shape: WidgetStatePropertyAll( + RoundedRectangleBorder( + borderRadius: context.theme.borderRadiusLg, + ), + ), ), onPressed: () { launchUrlString( @@ -66,11 +72,14 @@ class SettingsAboutSection extends HookConsumerWidget { ), ), if (Env.enableUpdateChecker) - SwitchListTile( - secondary: const Icon(SpotubeIcons.update), + ListTile( + leading: const Icon(SpotubeIcons.update), title: Text(context.l10n.check_for_updates), - value: preferences.checkUpdate, - onChanged: (checked) => preferencesNotifier.setCheckUpdate(checked), + trailing: Switch( + value: preferences.checkUpdate, + onChanged: (checked) => + preferencesNotifier.setCheckUpdate(checked), + ), ), ListTile( leading: const Icon(SpotubeIcons.info), diff --git a/lib/pages/settings/sections/accounts.dart b/lib/pages/settings/sections/accounts.dart index b9a26147..6132776c 100644 --- a/lib/pages/settings/sections/accounts.dart +++ b/lib/pages/settings/sections/accounts.dart @@ -1,7 +1,8 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show ListTile; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/settings/section_card_with_heading.dart'; import 'package:spotube/components/image/universal_image.dart'; @@ -28,11 +29,6 @@ class SettingsAccountSection extends HookConsumerWidget { final me = ref.watch(meProvider); final meData = me.asData?.value; - final logoutBtnStyle = FilledButton.styleFrom( - backgroundColor: Colors.red, - foregroundColor: Colors.white, - ); - final onLogin = useLoginCallback(ref); return SectionCardWithHeading( @@ -44,8 +40,9 @@ class SettingsAccountSection extends HookConsumerWidget { title: Text(context.l10n.user_profile), trailing: Padding( padding: const EdgeInsets.all(8.0), - child: CircleAvatar( - backgroundImage: UniversalImage.imageProvider( + child: Avatar( + initials: Avatar.getInitials(meData?.displayName ?? "User"), + provider: UniversalImage.imageProvider( (meData?.images).asUrlString( placeholder: ImagePlaceholder.artist, ), @@ -76,15 +73,8 @@ class SettingsAccountSection extends HookConsumerWidget { onTap: constrains.mdAndUp ? null : onLogin, trailing: constrains.smAndDown ? null - : FilledButton( + : Button.primary( onPressed: onLogin, - style: ButtonStyle( - shape: WidgetStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(25.0), - ), - ), - ), child: Text( context.l10n.connect_with_spotify.toUpperCase(), ), @@ -106,8 +96,7 @@ class SettingsAccountSection extends HookConsumerWidget { ), ), ), - trailing: FilledButton( - style: logoutBtnStyle, + trailing: Button.destructive( onPressed: () async { ref.read(authenticationProvider.notifier).logout(); GoRouter.of(context).pop(); @@ -121,27 +110,22 @@ class SettingsAccountSection extends HookConsumerWidget { leading: const Icon(SpotubeIcons.lastFm), title: Text(context.l10n.login_with_lastfm), subtitle: Text(context.l10n.scrobble_to_lastfm), - trailing: FilledButton.icon( - icon: const Icon(SpotubeIcons.lastFm), - label: Text(context.l10n.connect), + trailing: Button.secondary( + leading: const Icon(SpotubeIcons.lastFm), onPressed: () { router.push("/lastfm-login"); }, - style: FilledButton.styleFrom( - backgroundColor: const Color.fromARGB(255, 186, 0, 0), - foregroundColor: Colors.white, - ), + child: Text(context.l10n.connect), ), ) else ListTile( leading: const Icon(SpotubeIcons.lastFm), title: Text(context.l10n.disconnect_lastfm), - trailing: FilledButton( + trailing: Button.destructive( onPressed: () { ref.read(scrobblerProvider.notifier).logout(); }, - style: logoutBtnStyle, child: Text(context.l10n.disconnect), ), ), diff --git a/lib/pages/settings/sections/appearance.dart b/lib/pages/settings/sections/appearance.dart index 9a95e60b..aaa2ce8a 100644 --- a/lib/pages/settings/sections/appearance.dart +++ b/lib/pages/settings/sections/appearance.dart @@ -1,7 +1,6 @@ -import 'package:flutter/material.dart' hide ThemeMode; -import 'package:shadcn_flutter/shadcn_flutter.dart' show ThemeMode; +import 'package:flutter/material.dart' show ListTile; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/models/database/database.dart'; @@ -42,15 +41,15 @@ class SettingsAppearanceSection extends HookConsumerWidget { } }, options: [ - DropdownMenuItem( + SelectItemButton( value: LayoutMode.adaptive, child: Text(context.l10n.adaptive), ), - DropdownMenuItem( + SelectItemButton( value: LayoutMode.compact, child: Text(context.l10n.compact), ), - DropdownMenuItem( + SelectItemButton( value: LayoutMode.extended, child: Text(context.l10n.extended), ), @@ -61,15 +60,15 @@ class SettingsAppearanceSection extends HookConsumerWidget { title: Text(context.l10n.theme), value: preferences.themeMode, options: [ - DropdownMenuItem( + SelectItemButton( value: ThemeMode.dark, child: Text(context.l10n.dark), ), - DropdownMenuItem( + SelectItemButton( value: ThemeMode.light, child: Text(context.l10n.light), ), - DropdownMenuItem( + SelectItemButton( value: ThemeMode.system, child: Text(context.l10n.system), ), @@ -80,13 +79,14 @@ class SettingsAppearanceSection extends HookConsumerWidget { } }, ), - SwitchListTile( - secondary: const Icon(SpotubeIcons.amoled), - title: Text(context.l10n.use_amoled_mode), - subtitle: Text(context.l10n.pitch_dark_theme), - value: preferences.amoledDarkTheme, - onChanged: preferencesNotifier.setAmoledDarkTheme, - ), + ListTile( + leading: const Icon(SpotubeIcons.amoled), + title: Text(context.l10n.use_amoled_mode), + subtitle: Text(context.l10n.pitch_dark_theme), + trailing: Switch( + value: preferences.amoledDarkTheme, + onChanged: preferencesNotifier.setAmoledDarkTheme, + )), ListTile( leading: const Icon(SpotubeIcons.palette), title: Text(context.l10n.accent_color), @@ -101,13 +101,14 @@ class SettingsAppearanceSection extends HookConsumerWidget { ), onTap: pickColorScheme(), ), - SwitchListTile( - secondary: const Icon(SpotubeIcons.colorSync), - title: Text(context.l10n.sync_album_color), - subtitle: Text(context.l10n.sync_album_color_description), - value: preferences.albumColorSync, - onChanged: preferencesNotifier.setAlbumColorSync, - ), + ListTile( + leading: const Icon(SpotubeIcons.colorSync), + title: Text(context.l10n.sync_album_color), + subtitle: Text(context.l10n.sync_album_color_description), + trailing: Switch( + value: preferences.albumColorSync, + onChanged: preferencesNotifier.setAlbumColorSync, + )), ]; if (isGettingStarted) { diff --git a/lib/pages/settings/sections/desktop.dart b/lib/pages/settings/sections/desktop.dart index c61f0150..ad45c689 100644 --- a/lib/pages/settings/sections/desktop.dart +++ b/lib/pages/settings/sections/desktop.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; +import 'package:flutter/material.dart' show ListTile; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/modules/settings/section_card_with_heading.dart'; @@ -25,11 +25,11 @@ class SettingsDesktopSection extends HookConsumerWidget { title: Text(context.l10n.close_behavior), value: preferences.closeBehavior, options: [ - DropdownMenuItem( + SelectItemButton( value: CloseBehavior.close, child: Text(context.l10n.close), ), - DropdownMenuItem( + SelectItemButton( value: CloseBehavior.minimizeToTray, child: Text(context.l10n.minimize_to_tray), ), @@ -40,23 +40,29 @@ class SettingsDesktopSection extends HookConsumerWidget { } }, ), - SwitchListTile( - secondary: const Icon(SpotubeIcons.tray), + ListTile( + leading: const Icon(SpotubeIcons.tray), title: Text(context.l10n.show_tray_icon), - value: preferences.showSystemTrayIcon, - onChanged: preferencesNotifier.setShowSystemTrayIcon, + trailing: Switch( + value: preferences.showSystemTrayIcon, + onChanged: preferencesNotifier.setShowSystemTrayIcon, + ), ), - SwitchListTile( - secondary: const Icon(SpotubeIcons.window), + ListTile( + leading: const Icon(SpotubeIcons.window), title: Text(context.l10n.use_system_title_bar), - value: preferences.systemTitleBar, - onChanged: preferencesNotifier.setSystemTitleBar, + trailing: Switch( + value: preferences.systemTitleBar, + onChanged: preferencesNotifier.setSystemTitleBar, + ), ), - SwitchListTile( - secondary: const Icon(SpotubeIcons.discord), + ListTile( + leading: const Icon(SpotubeIcons.discord), title: Text(context.l10n.discord_rich_presence), - value: preferences.discordPresence, - onChanged: preferencesNotifier.setDiscordPresence, + trailing: Switch( + value: preferences.discordPresence, + onChanged: preferencesNotifier.setDiscordPresence, + ), ), ], ); diff --git a/lib/pages/settings/sections/developers.dart b/lib/pages/settings/sections/developers.dart index f33fe843..4d8b8ba1 100644 --- a/lib/pages/settings/sections/developers.dart +++ b/lib/pages/settings/sections/developers.dart @@ -1,6 +1,7 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show ListTile; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/settings/section_card_with_heading.dart'; import 'package:spotube/extensions/context.dart'; diff --git a/lib/pages/settings/sections/downloads.dart b/lib/pages/settings/sections/downloads.dart index 8e679a7d..516d2aca 100644 --- a/lib/pages/settings/sections/downloads.dart +++ b/lib/pages/settings/sections/downloads.dart @@ -1,8 +1,9 @@ import 'package:file_picker/file_picker.dart'; import 'package:file_selector/file_selector.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show ListTile; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/settings/section_card_with_heading.dart'; import 'package:spotube/extensions/context.dart'; @@ -40,9 +41,9 @@ class SettingsDownloadsSection extends HookConsumerWidget { leading: const Icon(SpotubeIcons.download), title: Text(context.l10n.download_location), subtitle: Text(preferences.downloadLocation), - trailing: FilledButton( + trailing: IconButton.secondary( onPressed: pickDownloadLocation, - child: const Icon(SpotubeIcons.folder), + icon: const Icon(SpotubeIcons.folder), ), onTap: pickDownloadLocation, ), diff --git a/lib/pages/settings/sections/language_region.dart b/lib/pages/settings/sections/language_region.dart index 18c2d088..26f820de 100644 --- a/lib/pages/settings/sections/language_region.dart +++ b/lib/pages/settings/sections/language_region.dart @@ -1,6 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/language_codes.dart'; import 'package:spotube/collections/spotify_markets.dart'; @@ -24,7 +23,6 @@ class SettingsLanguageRegionSection extends HookConsumerWidget { return SectionCardWithHeading( heading: context.l10n.language_region, children: [ - const Gap(10), AdaptiveSelectTile( value: preferences.locale, onChanged: (locale) { @@ -34,12 +32,12 @@ class SettingsLanguageRegionSection extends HookConsumerWidget { title: Text(context.l10n.language), secondary: const Icon(SpotubeIcons.language), options: [ - DropdownMenuItem( + SelectItemButton( value: const Locale("system", "system"), child: Text(context.l10n.system_default), ), for (final locale in L10n.all) - DropdownMenuItem( + SelectItemButton( value: locale, child: Builder(builder: (context) { final isoCodeName = LanguageLocals.getDisplayLanguage( @@ -64,7 +62,7 @@ class SettingsLanguageRegionSection extends HookConsumerWidget { }, options: spotifyMarkets .map( - (country) => DropdownMenuItem( + (country) => SelectItemButton( value: country.$1, child: Text(country.$2), ), diff --git a/lib/pages/settings/sections/playback.dart b/lib/pages/settings/sections/playback.dart index f8868789..6888e3a9 100644 --- a/lib/pages/settings/sections/playback.dart +++ b/lib/pages/settings/sections/playback.dart @@ -1,11 +1,12 @@ import 'package:collection/collection.dart'; import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; +import 'package:flutter/material.dart' show ListTile; + 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:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/modules/settings/section_card_with_heading.dart'; @@ -30,21 +31,20 @@ class SettingsPlaybackSection extends HookConsumerWidget { return SectionCardWithHeading( heading: context.l10n.playback, children: [ - const Gap(10), AdaptiveSelectTile( secondary: const Icon(SpotubeIcons.audioQuality), title: Text(context.l10n.audio_quality), value: preferences.audioQuality, options: [ - DropdownMenuItem( + SelectItemButton( value: SourceQualities.high, child: Text(context.l10n.high), ), - DropdownMenuItem( + SelectItemButton( value: SourceQualities.medium, child: Text(context.l10n.medium), ), - DropdownMenuItem( + SelectItemButton( value: SourceQualities.low, child: Text(context.l10n.low), ), @@ -55,13 +55,12 @@ class SettingsPlaybackSection extends HookConsumerWidget { } }, ), - const Gap(5), AdaptiveSelectTile( secondary: const Icon(SpotubeIcons.api), title: Text(context.l10n.audio_source), value: preferences.audioSource, options: AudioSource.values - .map((e) => DropdownMenuItem( + .map((e) => SelectItemButton( value: e, child: Text(e.label), )) @@ -71,177 +70,173 @@ class SettingsPlaybackSection extends HookConsumerWidget { preferencesNotifier.setAudioSource(value); }, ), - AnimatedSwitcher( + AnimatedCrossFade( duration: const Duration(milliseconds: 300), - child: preferences.audioSource != AudioSource.piped - ? const SizedBox.shrink() - : Consumer(builder: (context, ref, child) { - final instanceList = ref.watch(pipedInstancesFutureProvider); + crossFadeState: preferences.audioSource != AudioSource.piped + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + firstChild: const SizedBox.shrink(), + secondChild: Consumer( + builder: (context, ref, child) { + final instanceList = ref.watch(pipedInstancesFutureProvider); - return instanceList.when( - data: (data) { - return AdaptiveSelectTile( - 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) { - preferencesNotifier.setPipedInstance(value); - } - }, - ); - }, - loading: () => const Center( - child: CircularProgressIndicator(), + return instanceList.when( + data: (data) { + return AdaptiveSelectTile( + secondary: const Icon(SpotubeIcons.piped), + title: Text(context.l10n.piped_instance), + subtitle: Text( + "${context.l10n.piped_description}\n" + "${context.l10n.piped_warning}", ), - error: (error, stackTrace) => Text(error.toString()), - ); - }), - ), - AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: preferences.audioSource != AudioSource.invidious - ? const SizedBox.shrink() - : Consumer(builder: (context, ref, child) { - final instanceList = ref.watch(invidiousInstancesProvider); - - return instanceList.when( - data: (data) { - return AdaptiveSelectTile( - secondary: const Icon(SpotubeIcons.piped), - title: Text(context.l10n.invidious_instance), - subtitle: RichText( - text: TextSpan( - children: [ - TextSpan( - text: context.l10n.invidious_description, - style: theme.textTheme.bodyMedium, - ), - const TextSpan(text: "\n"), - TextSpan( - text: context.l10n.invidious_warning, - style: theme.textTheme.labelMedium, - ) - ], - ), - ), - value: preferences.invidiousInstance, - showValueWhenUnfolded: false, - options: data - .sortedBy((e) => e.name) - .map( - (e) => DropdownMenuItem( - value: e.details.uri, - child: RichText( - text: TextSpan( - children: [ - TextSpan( - text: "${e.name.trim()}\n", - style: theme.textTheme.labelLarge, - ), - TextSpan( - text: countryCodeToEmoji( - e.details.region, - ), - style: GoogleFonts.notoColorEmoji(), - ), - ], - ), + value: preferences.pipedInstance, + showValueWhenUnfolded: false, + options: data + .sortedBy((e) => e.name) + .map( + (e) => SelectItemButton( + value: e.apiUrl, + child: RichText( + text: TextSpan( + style: theme.typography.normal.copyWith( + color: theme.colorScheme.foreground, ), + children: [ + TextSpan( + text: "${e.name.trim()}\n", + ), + TextSpan( + text: e.locations + .map(countryCodeToEmoji) + .join(""), + style: GoogleFonts.notoColorEmoji(), + ), + ], ), - ) - .toList(), - onChanged: (value) { - if (value != null) { - preferencesNotifier.setInvidiousInstance(value); - } - }, - ); + ), + ), + ) + .toList(), + onChanged: (value) { + if (value != null) { + preferencesNotifier.setPipedInstance(value); + } }, - loading: () => const Center( - child: CircularProgressIndicator(), - ), - error: (error, stackTrace) => Text(error.toString()), ); - }), - ), - AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: preferences.audioSource != AudioSource.piped - ? const SizedBox.shrink() - : AdaptiveSelectTile( - 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; - preferencesNotifier.setSearchMode(value); - }, + }, + loading: () => const Center( + child: CircularProgressIndicator(), ), + error: (error, stackTrace) => Text(error.toString()), + ); + }, + ), ), - AnimatedSwitcher( + AnimatedCrossFade( duration: const Duration(milliseconds: 300), - child: preferences.searchMode == SearchMode.youtube && + crossFadeState: preferences.audioSource != AudioSource.invidious + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + firstChild: const SizedBox.shrink(), + secondChild: Consumer( + builder: (context, ref, child) { + final instanceList = ref.watch(invidiousInstancesProvider); + + return instanceList.when( + data: (data) { + return AdaptiveSelectTile( + secondary: const Icon(SpotubeIcons.piped), + title: Text(context.l10n.invidious_instance), + subtitle: Text( + "${context.l10n.invidious_description}\n" + "${context.l10n.invidious_warning}", + ), + value: preferences.invidiousInstance, + showValueWhenUnfolded: false, + options: data + .sortedBy((e) => e.name) + .map( + (e) => SelectItemButton( + value: e.details.uri, + child: RichText( + text: TextSpan( + style: theme.typography.normal.copyWith( + color: theme.colorScheme.foreground, + ), + children: [ + TextSpan( + text: "${e.name.trim()}\n", + ), + TextSpan( + text: countryCodeToEmoji( + e.details.region, + ), + style: GoogleFonts.notoColorEmoji(), + ), + ], + ), + ), + ), + ) + .toList(), + onChanged: (value) { + if (value != null) { + preferencesNotifier.setInvidiousInstance(value); + } + }, + ); + }, + loading: () => const Center( + child: CircularProgressIndicator(), + ), + error: (error, stackTrace) => Text(error.toString()), + ); + }, + ), + ), + AnimatedCrossFade( + duration: const Duration(milliseconds: 300), + crossFadeState: preferences.audioSource != AudioSource.youtube + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + firstChild: const SizedBox.shrink(), + secondChild: AdaptiveSelectTile( + secondary: const Icon(SpotubeIcons.search), + title: Text(context.l10n.search_mode), + value: preferences.searchMode, + options: SearchMode.values + .map((e) => SelectItemButton( + value: e, + child: Text(e.label), + )) + .toList(), + onChanged: (value) { + if (value == null) return; + preferencesNotifier.setSearchMode(value); + }, + ), + ), + AnimatedCrossFade( + duration: const Duration(milliseconds: 300), + crossFadeState: preferences.searchMode == SearchMode.youtube && (preferences.audioSource == AudioSource.piped || preferences.audioSource == AudioSource.youtube || preferences.audioSource == AudioSource.invidious) - ? SwitchListTile( - secondary: const Icon(SpotubeIcons.skip), - title: Text(context.l10n.skip_non_music), - value: preferences.skipNonMusic, - onChanged: (state) { - preferencesNotifier.setSkipNonMusic(state); - }, - ) - : const SizedBox.shrink(), + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + firstChild: ListTile( + leading: const Icon(SpotubeIcons.skip), + title: Text(context.l10n.skip_non_music), + trailing: Switch( + value: preferences.skipNonMusic, + onChanged: (state) { + preferencesNotifier.setSkipNonMusic(state); + }, + ), + ), + secondChild: const SizedBox.shrink(), ), - SwitchListTile( + ListTile( title: Text(context.l10n.cache_music), subtitle: kIsMobile ? null @@ -253,7 +248,7 @@ class SettingsPlaybackSection extends HookConsumerWidget { text: context.l10n.cache_folder.toLowerCase(), recognizer: TapGestureRecognizer() ..onTap = preferencesNotifier.openCacheFolder, - style: theme.textTheme.bodyMedium?.copyWith( + style: theme.typography.normal.copyWith( color: theme.colorScheme.primary, decoration: TextDecoration.underline, ), @@ -261,9 +256,11 @@ class SettingsPlaybackSection extends HookConsumerWidget { ], ), ), - secondary: const Icon(SpotubeIcons.cache), - value: preferences.cacheMusic, - onChanged: preferencesNotifier.setCacheMusic, + leading: const Icon(SpotubeIcons.cache), + trailing: Switch( + value: preferences.cacheMusic, + onChanged: preferencesNotifier.setCacheMusic, + ), ), ListTile( leading: const Icon(SpotubeIcons.playlistRemove), @@ -274,25 +271,26 @@ class SettingsPlaybackSection extends HookConsumerWidget { }, trailing: const Icon(SpotubeIcons.angleRight), ), - SwitchListTile( - secondary: const Icon(SpotubeIcons.normalize), + ListTile( + leading: const Icon(SpotubeIcons.normalize), title: Text(context.l10n.normalize_audio), - value: preferences.normalizeAudio, - onChanged: preferencesNotifier.setNormalizeAudio, + trailing: Switch( + value: preferences.normalizeAudio, + onChanged: preferencesNotifier.setNormalizeAudio, + ), ), if (preferences.audioSource != AudioSource.jiosaavn) ...[ - const Gap(5), AdaptiveSelectTile( secondary: const Icon(SpotubeIcons.stream), title: Text(context.l10n.streaming_music_codec), value: preferences.streamMusicCodec, showValueWhenUnfolded: false, options: SourceCodecs.values - .map((e) => DropdownMenuItem( + .map((e) => SelectItemButton( value: e, child: Text( e.label, - style: theme.textTheme.labelMedium, + style: theme.typography.small, ), )) .toList(), @@ -301,18 +299,17 @@ class SettingsPlaybackSection extends HookConsumerWidget { preferencesNotifier.setStreamMusicCodec(value); }, ), - const Gap(5), AdaptiveSelectTile( secondary: const Icon(SpotubeIcons.file), title: Text(context.l10n.download_music_codec), value: preferences.downloadMusicCodec, showValueWhenUnfolded: false, options: SourceCodecs.values - .map((e) => DropdownMenuItem( + .map((e) => SelectItemButton( value: e, child: Text( e.label, - style: theme.textTheme.labelMedium, + style: theme.typography.small, ), )) .toList(), @@ -320,20 +317,23 @@ class SettingsPlaybackSection extends HookConsumerWidget { if (value == null) return; preferencesNotifier.setDownloadMusicCodec(value); }, - ) + ), ], - SwitchListTile( - secondary: const Icon(SpotubeIcons.repeat), - title: Text(context.l10n.endless_playback), - value: preferences.endlessPlayback, - onChanged: preferencesNotifier.setEndlessPlayback, - ), - SwitchListTile( + ListTile( + leading: const Icon(SpotubeIcons.repeat), + title: Text(context.l10n.endless_playback), + trailing: Switch( + value: preferences.endlessPlayback, + onChanged: preferencesNotifier.setEndlessPlayback, + )), + ListTile( title: Text(context.l10n.enable_connect), subtitle: Text(context.l10n.enable_connect_description), - secondary: const Icon(SpotubeIcons.connect), - value: preferences.enableConnect, - onChanged: preferencesNotifier.setEnableConnect, + leading: const Icon(SpotubeIcons.connect), + trailing: Switch( + value: preferences.enableConnect, + onChanged: preferencesNotifier.setEnableConnect, + ), ), ], ); diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index a7355812..54c377eb 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -1,7 +1,8 @@ import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show Material, MaterialType; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/settings/sections/about.dart'; @@ -28,36 +29,41 @@ class SettingsPage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: TitleBar( - title: Text(context.l10n.settings), - automaticallyImplyLeading: true, - ), - body: Scrollbar( + headers: [ + TitleBar( + title: Text(context.l10n.settings), + automaticallyImplyLeading: true, + ) + ], + child: Scrollbar( controller: controller, child: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 1366), child: ScrollConfiguration( behavior: const ScrollBehavior().copyWith(scrollbars: false), - child: ListView( - controller: controller, - children: [ - const SettingsAccountSection(), - const SettingsLanguageRegionSection(), - const SettingsAppearanceSection(), - const SettingsPlaybackSection(), - const SettingsDownloadsSection(), - if (kIsDesktop) const SettingsDesktopSection(), - if (!kIsWeb) const SettingsDevelopersSection(), - const SettingsAboutSection(), - Center( - child: FilledButton( - onPressed: preferencesNotifier.reset, - child: Text(context.l10n.restore_defaults), + child: Material( + type: MaterialType.transparency, + child: ListView( + controller: controller, + children: [ + const SettingsAccountSection(), + const SettingsLanguageRegionSection(), + const SettingsAppearanceSection(), + const SettingsPlaybackSection(), + const SettingsDownloadsSection(), + if (kIsDesktop) const SettingsDesktopSection(), + if (!kIsWeb) const SettingsDevelopersSection(), + const SettingsAboutSection(), + Center( + child: Button.destructive( + onPressed: preferencesNotifier.reset, + child: Text(context.l10n.restore_defaults), + ), ), - ), - const SizedBox(height: 10), - ], + const SizedBox(height: 200), + ], + ), ), ), ), diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index a6f73a80..db44369c 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return false } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } } diff --git a/pubspec.lock b/pubspec.lock index b58c16b8..46ed96d6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1336,10 +1336,10 @@ packages: dependency: "direct main" description: name: invidious - sha256: "7cb879c0b4b99aa06ec720af84f6988ff0080bb0434d041f6fb0c4add680ee36" + sha256: "27ef3a001df875665de15535dbc9099f44d12a59480018fb1e17377d4af0308d" url: "https://pub.dev" source: hosted - version: "0.1.0" + version: "0.1.1" io: dependency: "direct dev" description: diff --git a/pubspec.yaml b/pubspec.yaml index c9a6f341..e1b1ada3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -78,7 +78,7 @@ dependencies: http: ^1.2.1 image_picker: ^1.1.0 intl: any - invidious: ^0.1.0 + invidious: ^0.1.1 jiosaavn: ^0.1.0 json_annotation: ^4.8.1 local_notifier: ^0.1.6 From 05d544fe5a66e63ea2fdaf0bb239a476263e8b66 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 22 Dec 2024 11:58:06 +0600 Subject: [PATCH 13/81] refactor: update FriendItem and HorizontalPlaybuttonCardView styles, remove unused imports, and clean up dependencies --- lib/collections/assets.gen.dart | 15 + lib/collections/fonts.gen.dart | 24 + .../adaptive/adaptive_popup_menu_button.dart | 106 -- lib/components/bordered_text.dart | 88 - lib/components/compact_search.dart | 52 - lib/components/dialogs/piped_down_dialog.dart | 46 - .../horizontal_playbutton_card_view.dart | 4 +- lib/extensions/page.dart | 61 - .../controllers/use_sidebarx_controller.dart | 59 - lib/main.dart | 10 +- lib/models/database/database.steps.dart | 2 +- lib/models/spotify_spotube_credentials.dart | 30 - .../home/sections/friends/friend_item.dart | 3 + lib/modules/library/user_albums.dart | 17 +- lib/modules/library/user_playlists.dart | 16 +- lib/provider/spotify/spotify.dart | 3 - lib/provider/spotify/utils/persistence.dart | 40 - lib/utils/migrations/adapters.dart | 320 ---- lib/utils/migrations/adapters.freezed.dart | 1421 ----------------- lib/utils/migrations/adapters.g.dart | 600 ------- lib/utils/migrations/cache_box.dart | 100 -- pubspec.lock | 34 +- pubspec.yaml | 5 - 23 files changed, 67 insertions(+), 2989 deletions(-) create mode 100644 lib/collections/fonts.gen.dart delete mode 100644 lib/components/adaptive/adaptive_popup_menu_button.dart delete mode 100644 lib/components/bordered_text.dart delete mode 100644 lib/components/compact_search.dart delete mode 100644 lib/components/dialogs/piped_down_dialog.dart delete mode 100644 lib/extensions/page.dart delete mode 100644 lib/hooks/controllers/use_sidebarx_controller.dart delete mode 100644 lib/models/spotify_spotube_credentials.dart delete mode 100644 lib/provider/spotify/utils/persistence.dart delete mode 100644 lib/utils/migrations/adapters.dart delete mode 100644 lib/utils/migrations/adapters.freezed.dart delete mode 100644 lib/utils/migrations/adapters.g.dart delete mode 100644 lib/utils/migrations/cache_box.dart diff --git a/lib/collections/assets.gen.dart b/lib/collections/assets.gen.dart index 6825fbd5..e098ff9a 100644 --- a/lib/collections/assets.gen.dart +++ b/lib/collections/assets.gen.dart @@ -9,6 +9,17 @@ import 'package:flutter/widgets.dart'; +class $AssetsBackgroundsGen { + const $AssetsBackgroundsGen(); + + /// File path: assets/backgrounds/xmas-effect.png + AssetGenImage get xmasEffect => + const AssetGenImage('assets/backgrounds/xmas-effect.png'); + + /// List of all assets + List get values => [xmasEffect]; +} + class $AssetsLogosGen { const $AssetsLogosGen(); @@ -46,6 +57,7 @@ class Assets { static const String license = 'LICENSE'; static const AssetGenImage albumPlaceholder = AssetGenImage('assets/album-placeholder.png'); + static const $AssetsBackgroundsGen backgrounds = $AssetsBackgroundsGen(); static const AssetGenImage bengaliPatternsBg = AssetGenImage('assets/bengali-patterns-bg.jpg'); static const AssetGenImage branding = AssetGenImage('assets/branding.png'); @@ -61,6 +73,8 @@ class Assets { AssetGenImage('assets/spotube-hero-banner.png'); static const AssetGenImage spotubeLogoForeground = AssetGenImage('assets/spotube-logo-foreground.jpg'); + static const AssetGenImage spotubeLogoMacos = + AssetGenImage('assets/spotube-logo-macos.png'); static const AssetGenImage spotubeLogoBmp = AssetGenImage('assets/spotube-logo.bmp'); static const String spotubeLogoIco = 'assets/spotube-logo.ico'; @@ -104,6 +118,7 @@ class Assets { placeholder, spotubeHeroBanner, spotubeLogoForeground, + spotubeLogoMacos, spotubeLogoBmp, spotubeLogoIco, spotubeLogoPng, diff --git a/lib/collections/fonts.gen.dart b/lib/collections/fonts.gen.dart new file mode 100644 index 00000000..811e1d36 --- /dev/null +++ b/lib/collections/fonts.gen.dart @@ -0,0 +1,24 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use + +class FontFamily { + FontFamily._(); + + /// Font family: BootstrapIcons + static const String bootstrapIcons = 'BootstrapIcons'; + + /// Font family: GeistMono + static const String geistMono = 'GeistMono'; + + /// Font family: GeistSans + static const String geistSans = 'GeistSans'; + + /// Font family: RadixIcons + static const String radixIcons = 'RadixIcons'; +} diff --git a/lib/components/adaptive/adaptive_popup_menu_button.dart b/lib/components/adaptive/adaptive_popup_menu_button.dart deleted file mode 100644 index 02fced52..00000000 --- a/lib/components/adaptive/adaptive_popup_menu_button.dart +++ /dev/null @@ -1,106 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; - -import 'package:popover/popover.dart'; -import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/extensions/constrains.dart'; - -class Action extends StatelessWidget { - final Widget text; - final Widget icon; - final void Function() onPressed; - final bool isExpanded; - final Color? backgroundColor; - const Action({ - super.key, - required this.icon, - required this.text, - required this.onPressed, - this.isExpanded = true, - this.backgroundColor, - }); - - @override - Widget build(BuildContext context) { - if (isExpanded != true) { - return IconButton( - icon: icon, - onPressed: onPressed, - style: IconButton.styleFrom( - backgroundColor: backgroundColor, - ), - tooltip: text is Text - ? (text as Text).data - : text.toStringShallow().split(",").last.replaceAll( - "\"", - "", - ), - ); - } - - return ListTile( - tileColor: backgroundColor, - onTap: onPressed, - leading: icon, - title: text, - ); - } -} - -class AdaptiveActions extends HookWidget { - final List actions; - final bool? breakOn; - const AdaptiveActions({ - required this.actions, - this.breakOn, - super.key, - }); - - @override - Widget build(BuildContext context) { - final mediaQuery = MediaQuery.of(context); - - if (breakOn ?? mediaQuery.lgAndUp) { - return IconButton( - icon: const Icon(SpotubeIcons.moreHorizontal), - onPressed: () { - showPopover( - context: context, - direction: PopoverDirection.left, - bodyBuilder: (context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: actions - .map( - (action) => SizedBox( - width: 200, - child: Row( - children: [ - Expanded(child: action), - ], - ), - ), - ) - .toList(), - ); - }, - backgroundColor: Theme.of(context).cardColor, - ); - }, - ); - } - - return Row( - children: actions.map((action) { - return Action( - icon: action.icon, - onPressed: action.onPressed, - text: action.text, - backgroundColor: action.backgroundColor, - isExpanded: false, - ); - }).toList(), - ); - } -} diff --git a/lib/components/bordered_text.dart b/lib/components/bordered_text.dart deleted file mode 100644 index f25f2208..00000000 --- a/lib/components/bordered_text.dart +++ /dev/null @@ -1,88 +0,0 @@ -library bordered_text; - -import 'package:flutter/widgets.dart'; - -/// Adds stroke to text widget -/// We can apply a very thin and subtle stroke to a [Text] -/// ```dart -/// BorderedText( -/// strokeWidth: 1.0, -/// text: Text( -/// 'Bordered Text', -/// style: TextStyle( -/// decoration: TextDecoration.none, -/// decorationStyle: TextDecorationStyle.wavy, -/// decorationColor: Colors.red, -/// ), -/// ), -/// ) -/// ``` -class BorderedText extends StatelessWidget { - const BorderedText({ - super.key, - required this.child, - this.strokeCap = StrokeCap.round, - this.strokeJoin = StrokeJoin.round, - this.strokeWidth = 6.0, - this.strokeColor = const Color.fromRGBO(53, 0, 71, 1), - }); - - /// the stroke cap style - final StrokeCap strokeCap; - - /// the stroke joint style - final StrokeJoin strokeJoin; - - /// the stroke width - final double strokeWidth; - - /// the stroke color - final Color strokeColor; - - /// the [Text] widget to apply stroke on - final Text child; - - @override - Widget build(BuildContext context) { - TextStyle style; - if (child.style != null) { - style = child.style!.copyWith( - foreground: Paint() - ..style = PaintingStyle.stroke - ..strokeCap = strokeCap - ..strokeJoin = strokeJoin - ..strokeWidth = strokeWidth - ..color = strokeColor, - color: null, - ); - } else { - style = TextStyle( - foreground: Paint() - ..style = PaintingStyle.stroke - ..strokeCap = strokeCap - ..strokeJoin = strokeJoin - ..strokeWidth = strokeWidth - ..color = strokeColor, - ); - } - return Stack( - alignment: Alignment.center, - textDirection: child.textDirection, - children: [ - Text( - child.data!, - style: style, - maxLines: child.maxLines, - overflow: child.overflow, - semanticsLabel: child.semanticsLabel, - softWrap: child.softWrap, - strutStyle: child.strutStyle, - textAlign: child.textAlign, - textDirection: child.textDirection, - textScaler: child.textScaler, - ), - child, - ], - ); - } -} diff --git a/lib/components/compact_search.dart b/lib/components/compact_search.dart deleted file mode 100644 index d37cb673..00000000 --- a/lib/components/compact_search.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; - -import 'package:popover/popover.dart'; -import 'package:spotube/collections/spotube_icons.dart'; - -class CompactSearch extends HookWidget { - final ValueChanged? onChanged; - final String placeholder; - final IconData icon; - final Color? iconColor; - - const CompactSearch({ - super.key, - this.onChanged, - this.placeholder = "Search...", - this.icon = SpotubeIcons.search, - this.iconColor, - }); - - @override - Widget build(BuildContext context) { - return IconButton( - onPressed: () { - showPopover( - context: context, - backgroundColor: Theme.of(context).cardColor, - transitionDuration: const Duration(milliseconds: 100), - barrierColor: Colors.transparent, - arrowDxOffset: -6, - bodyBuilder: (context) { - return Container( - padding: const EdgeInsets.all(8.0), - width: 300, - child: TextField( - autofocus: true, - onChanged: onChanged, - decoration: InputDecoration( - hintText: placeholder, - prefixIcon: Icon(icon), - ), - ), - ); - }, - height: 60, - ); - }, - tooltip: placeholder, - icon: Icon(icon, color: iconColor), - ); - } -} diff --git a/lib/components/dialogs/piped_down_dialog.dart b/lib/components/dialogs/piped_down_dialog.dart deleted file mode 100644 index b1717a2a..00000000 --- a/lib/components/dialogs/piped_down_dialog.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/extensions/context.dart'; -import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; - -class PipedDownDialog extends HookConsumerWidget { - const PipedDownDialog({super.key}); - - @override - Widget build(BuildContext context, ref) { - final pipedInstance = - ref.watch(userPreferencesProvider.select((s) => s.pipedInstance)); - final ThemeData(:colorScheme) = Theme.of(context); - - return AlertDialog( - insetPadding: const EdgeInsets.all(6), - contentPadding: const EdgeInsets.all(6), - icon: Icon( - SpotubeIcons.error, - color: colorScheme.error, - ), - title: Text( - context.l10n.piped_api_down, - style: TextStyle(color: colorScheme.error), - ), - content: Card( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: - Text(context.l10n.piped_down_error_instructions(pipedInstance)), - ), - ), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(context.l10n.ok), - ), - FilledButton( - onPressed: () => Navigator.pop(context), - child: Text(context.l10n.settings), - ), - ], - ); - } -} diff --git a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart index f41e0709..31c6a37c 100644 --- a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart +++ b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart @@ -55,7 +55,9 @@ class HorizontalPlaybuttonCardView extends HookWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ DefaultTextStyle( - style: context.theme.typography.h4, + style: context.theme.typography.h4.copyWith( + color: context.theme.colorScheme.foreground, + ), child: title, ), if (titleTrailing != null) titleTrailing!, diff --git a/lib/extensions/page.dart b/lib/extensions/page.dart deleted file mode 100644 index 34343fb5..00000000 --- a/lib/extensions/page.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:spotify/spotify.dart'; - -extension CursorPageJson on CursorPage { - static CursorPage fromJson( - Map json, - T Function(dynamic json) itemFromJson, - ) { - final metadata = Paging.fromJson(json["metadata"]); - final paging = CursorPaging(); - paging.cursors = Cursor.fromJson(json["metadata"])..after = json["after"]; - paging.href = metadata.href; - paging.itemsNative = paging.itemsNative; - paging.limit = metadata.limit; - paging.next = metadata.next; - return CursorPage( - paging, - itemFromJson, - ); - } - - Map toJson() { - return { - "after": after, - "metadata": metadata.toJson(), - }; - } -} - -extension PagingToJson on Paging { - Map toJson() { - return { - "items": itemsNative, - "total": total, - "next": next, - "previous": previous, - "limit": limit, - "offset": offset, - "href": href, - }; - } -} - -extension PageJson on Page { - static Page fromJson( - Map json, - T Function(dynamic json) itemFromJson, - ) { - return Page( - Paging.fromJson( - Map.castFrom(json["metadata"]), - ), - itemFromJson, - ); - } - - Map toJson() { - return { - "metadata": metadata.toJson(), - }; - } -} diff --git a/lib/hooks/controllers/use_sidebarx_controller.dart b/lib/hooks/controllers/use_sidebarx_controller.dart deleted file mode 100644 index a14c3305..00000000 --- a/lib/hooks/controllers/use_sidebarx_controller.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:sidebarx/sidebarx.dart'; - -/// Creates [SidebarXController] that will be disposed automatically. -/// -/// See also: -/// - [SidebarXController] -SidebarXController useSidebarXController({ - required int selectedIndex, - bool? extended, - List? keys, -}) { - return use( - _SidebarXControllerHook( - selectedIndex: selectedIndex, - extended: extended, - keys: keys, - ), - ); -} - -class _SidebarXControllerHook extends Hook { - const _SidebarXControllerHook({ - required this.selectedIndex, - this.extended, - super.keys, - }); - - final int selectedIndex; - final bool? extended; - - @override - HookState> createState() => - _SidebarXControllerHookState(); -} - -class _SidebarXControllerHookState - extends HookState { - late final SidebarXController controller; - - @override - void initHook() { - super.initHook(); - controller = SidebarXController( - selectedIndex: hook.selectedIndex, - extended: hook.extended, - ); - } - - @override - SidebarXController build(BuildContext context) => controller; - - @override - void dispose() => controller.dispose(); - - @override - String get debugLabel => 'useSidebarXController'; -} diff --git a/lib/main.dart b/lib/main.dart index d1275577..cae1e9fe 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,7 +7,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_discord_rpc/flutter_discord_rpc.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:hive/hive.dart'; + import 'package:home_widget/home_widget.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:local_notifier/local_notifier.dart'; @@ -43,7 +43,6 @@ import 'package:spotube/services/wm_tools/wm_tools.dart'; import 'package:spotube/utils/migrations/sandbox.dart'; import 'package:spotube/utils/platform.dart'; import 'package:system_theme/system_theme.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart'; @@ -100,11 +99,6 @@ Future main(List rawArgs) async { await KVStoreService.initialize(); await EncryptedKvStoreService.initialize(); - final hiveCacheDir = - kIsWeb ? null : (await getApplicationSupportDirectory()).path; - - Hive.init(hiveCacheDir); - final database = AppDatabase(); if (kIsDesktop) { @@ -222,6 +216,7 @@ class Spotube extends HookConsumerWidget { colorScheme: ColorSchemes.lightBlue(), surfaceOpacity: .8, surfaceBlur: 10, + typography: const Typography.geist(), ), darkTheme: ThemeData( radius: .5, @@ -229,6 +224,7 @@ class Spotube extends HookConsumerWidget { colorScheme: ColorSchemes.darkNeutral(), surfaceOpacity: .8, surfaceBlur: 10, + typography: const Typography.geist(), ), themeMode: themeMode, shortcuts: { diff --git a/lib/models/database/database.steps.dart b/lib/models/database/database.steps.dart index 40546bdb..11a564c6 100644 --- a/lib/models/database/database.steps.dart +++ b/lib/models/database/database.steps.dart @@ -4,8 +4,8 @@ import 'package:drift/drift.dart' as i1; import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import import 'package:flutter/material.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/models/database/database.dart'; import 'package:spotube/services/sourced_track/enums.dart'; -import 'package:spotube/utils/migrations/adapters.dart'; // GENERATED BY drift_dev, DO NOT MODIFY. final class Schema2 extends i0.VersionedSchema { diff --git a/lib/models/spotify_spotube_credentials.dart b/lib/models/spotify_spotube_credentials.dart deleted file mode 100644 index 982ca64a..00000000 --- a/lib/models/spotify_spotube_credentials.dart +++ /dev/null @@ -1,30 +0,0 @@ -class SpotifySpotubeCredentials { - String clientId; - String accessToken; - DateTime expiration; - bool isAnonymous; - - SpotifySpotubeCredentials({ - required this.clientId, - required this.accessToken, - required this.expiration, - required this.isAnonymous, - }); - - SpotifySpotubeCredentials.fromJson(Map json) - : clientId = json['clientId'], - accessToken = json['accessToken'], - expiration = DateTime.fromMillisecondsSinceEpoch( - json['accessTokenExpirationTimestampMs'], - ), - isAnonymous = json['isAnonymous']; - - Map toJson() { - return { - 'clientId': clientId, - 'accessToken': accessToken, - 'accessTokenExpirationTimestampMs': expiration.millisecondsSinceEpoch, - 'isAnonymous': isAnonymous, - }; - } -} diff --git a/lib/modules/home/sections/friends/friend_item.dart b/lib/modules/home/sections/friends/friend_item.dart index 42ec2909..94feb5cd 100644 --- a/lib/modules/home/sections/friends/friend_item.dart +++ b/lib/modules/home/sections/friends/friend_item.dart @@ -42,6 +42,9 @@ class FriendItem extends HookConsumerWidget { ), RichText( text: TextSpan( + style: context.theme.typography.normal.copyWith( + color: context.theme.colorScheme.foreground, + ), children: [ TextSpan( text: friend.track.name, diff --git a/lib/modules/library/user_albums.dart b/lib/modules/library/user_albums.dart index 4a22bbea..535381fc 100644 --- a/lib/modules/library/user_albums.dart +++ b/lib/modules/library/user_albums.dart @@ -12,7 +12,6 @@ import 'package:spotube/modules/album/album_card.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/fallbacks/anonymous_fallback.dart'; import 'package:spotube/components/waypoint.dart'; -import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -77,12 +76,14 @@ class UserAlbums extends HookConsumerWidget { ), ), const SliverGap(10), - SliverLayoutBuilder(builder: (context, constrains) { - return SliverGrid.builder( + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 8), + sliver: SliverGrid.builder( itemCount: albums.isEmpty ? 6 : albums.length + 1, - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 200, - mainAxisExtent: constrains.smAndDown ? 225 : 250, + gridDelegate: + const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 150, + mainAxisExtent: 225, crossAxisSpacing: 8, mainAxisSpacing: 8, ), @@ -110,8 +111,8 @@ class UserAlbums extends HookConsumerWidget { ), ); }, - ); - }), + ), + ), ], ), ), diff --git a/lib/modules/library/user_playlists.dart b/lib/modules/library/user_playlists.dart index 50595298..0f307894 100644 --- a/lib/modules/library/user_playlists.dart +++ b/lib/modules/library/user_playlists.dart @@ -15,7 +15,6 @@ import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/fallbacks/anonymous_fallback.dart'; import 'package:spotube/modules/playlist/playlist_card.dart'; import 'package:spotube/components/waypoint.dart'; -import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/library/playlist_generate/playlist_generate.dart'; import 'package:spotube/provider/authentication/authentication.dart'; @@ -126,12 +125,13 @@ class UserPlaylists extends HookConsumerWidget { ), ), const SliverGap(10), - SliverLayoutBuilder(builder: (context, constrains) { - return SliverGrid.builder( + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 8), + sliver: SliverGrid.builder( itemCount: playlists.isEmpty ? 6 : playlists.length + 1, - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 200, - mainAxisExtent: constrains.smAndDown ? 225 : 250, + gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 150, + mainAxisExtent: 225, crossAxisSpacing: 8, mainAxisSpacing: 8, ), @@ -157,8 +157,8 @@ class UserPlaylists extends HookConsumerWidget { FakeData.playlistSimple, ); }, - ); - }) + ), + ), ], ), ), diff --git a/lib/provider/spotify/spotify.dart b/lib/provider/spotify/spotify.dart index 8cf60120..dbf3802b 100644 --- a/lib/provider/spotify/spotify.dart +++ b/lib/provider/spotify/spotify.dart @@ -6,12 +6,10 @@ import 'package:drift/drift.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/database/database.dart'; -import 'package:spotube/provider/spotify/utils/json_cast.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:collection/collection.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; -import 'package:hive_flutter/hive_flutter.dart'; import 'package:intl/intl.dart'; import 'package:lrc/lrc.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -70,7 +68,6 @@ part 'views/view.dart'; part 'utils/mixin.dart'; part 'utils/state.dart'; part 'utils/provider.dart'; -part 'utils/persistence.dart'; part 'utils/async.dart'; part 'utils/provider/paginated.dart'; diff --git a/lib/provider/spotify/utils/persistence.dart b/lib/provider/spotify/utils/persistence.dart deleted file mode 100644 index 57f41dec..00000000 --- a/lib/provider/spotify/utils/persistence.dart +++ /dev/null @@ -1,40 +0,0 @@ -part of '../spotify.dart'; - -// ignore: invalid_use_of_internal_member -mixin Persistence on BuildlessAsyncNotifier { - LazyBox get store => Hive.lazyBox("spotube_cache"); - - FutureOr fromJson(Map json); - Map toJson(T data); - - FutureOr onInit() {} - - Future load() async { - final json = await store.get(runtimeType.toString()); - if (json != null || - (json is Map && json.entries.isNotEmpty) || - (json is List && json.isNotEmpty)) { - state = AsyncData( - await fromJson( - castNestedJson(json), - ), - ); - } - - await onInit(); - } - - Future save() async { - await store.put( - runtimeType.toString(), - state.value == null ? null : toJson(state.value as T), - ); - } - - @override - set state(AsyncValue value) { - if (state == value) return; - super.state = value; - save(); - } -} diff --git a/lib/utils/migrations/adapters.dart b/lib/utils/migrations/adapters.dart deleted file mode 100644 index f7f6350b..00000000 --- a/lib/utils/migrations/adapters.dart +++ /dev/null @@ -1,320 +0,0 @@ -import 'package:hive/hive.dart'; -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:spotify/spotify.dart'; -import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; -import 'package:spotube/services/sourced_track/enums.dart'; - -part 'adapters.g.dart'; -part 'adapters.freezed.dart'; - -@HiveType(typeId: 2) -class SkipSegment { - @HiveField(0) - final int start; - @HiveField(1) - final int end; - SkipSegment(this.start, this.end); - - static String version = 'v1'; - static final boxName = "oss.krtirtho.spotube.skip_segments.$version"; - static LazyBox get box => Hive.lazyBox(boxName); - - SkipSegment.fromJson(Map json) - : start = json['start'], - end = json['end']; - - Map toJson() => { - 'start': start, - 'end': end, - }; -} - -@JsonEnum() -@HiveType(typeId: 5) -enum SourceType { - @HiveField(0) - youtube._("YouTube"), - - @HiveField(1) - youtubeMusic._("YouTube Music"), - - @HiveField(2) - jiosaavn._("JioSaavn"); - - final String label; - - const SourceType._(this.label); -} - -@JsonSerializable() -@HiveType(typeId: 6) -class SourceMatch { - @HiveField(0) - String id; - - @HiveField(1) - String sourceId; - - @HiveField(2) - SourceType sourceType; - - @HiveField(3) - DateTime createdAt; - - SourceMatch({ - required this.id, - required this.sourceId, - required this.sourceType, - required this.createdAt, - }); - - factory SourceMatch.fromJson(Map json) => - _$SourceMatchFromJson(json); - - Map toJson() => _$SourceMatchToJson(this); - - static String version = 'v1'; - static final boxName = "oss.krtirtho.spotube.source_matches.$version"; - - static LazyBox get box => Hive.lazyBox(boxName); -} - -@JsonSerializable() -class AuthenticationCredentials { - String cookie; - String accessToken; - DateTime expiration; - - AuthenticationCredentials({ - required this.cookie, - required this.accessToken, - required this.expiration, - }); - - factory AuthenticationCredentials.fromJson(Map json) { - return AuthenticationCredentials( - cookie: json['cookie'] as String, - accessToken: json['accessToken'] as String, - expiration: DateTime.parse(json['expiration'] as String), - ); - } - - Map toJson() { - return { - 'cookie': cookie, - 'accessToken': accessToken, - 'expiration': expiration.toIso8601String(), - }; - } -} - -@JsonEnum() -enum LayoutMode { - compact, - extended, - adaptive, -} - -@JsonEnum() -enum CloseBehavior { - minimizeToTray, - close, -} - -@JsonEnum() -enum AudioSource { - youtube, - piped, - jiosaavn; - - String get label => name[0].toUpperCase() + name.substring(1); -} - -@JsonEnum() -enum MusicCodec { - m4a._("M4a (Best for downloaded music)"), - weba._("WebA (Best for streamed music)\nDoesn't support audio metadata"); - - final String label; - const MusicCodec._(this.label); -} - -@JsonEnum() -enum SearchMode { - youtube._("YouTube"), - youtubeMusic._("YouTube Music"); - - final String label; - - const SearchMode._(this.label); - - factory SearchMode.fromString(String key) { - return SearchMode.values.firstWhere((e) => e.name == key); - } -} - -@freezed -class UserPreferences with _$UserPreferences { - const factory UserPreferences({ - @Default(SourceQualities.high) SourceQualities audioQuality, - @Default(true) bool albumColorSync, - @Default(false) bool amoledDarkTheme, - @Default(true) bool checkUpdate, - @Default(false) bool normalizeAudio, - @Default(false) bool showSystemTrayIcon, - @Default(false) bool skipNonMusic, - @Default(false) bool systemTitleBar, - @Default(CloseBehavior.close) CloseBehavior closeBehavior, - @Default(SpotubeColor(0xFF2196F3, name: "Blue")) - @JsonKey( - fromJson: UserPreferences._accentColorSchemeFromJson, - toJson: UserPreferences._accentColorSchemeToJson, - readValue: UserPreferences._accentColorSchemeReadValue, - ) - SpotubeColor accentColorScheme, - @Default(LayoutMode.adaptive) LayoutMode layoutMode, - @Default(Locale("system", "system")) - @JsonKey( - fromJson: UserPreferences._localeFromJson, - toJson: UserPreferences._localeToJson, - readValue: UserPreferences._localeReadValue, - ) - Locale locale, - @Default(Market.US) Market recommendationMarket, - @Default(SearchMode.youtube) SearchMode searchMode, - @Default("") String downloadLocation, - @Default([]) List localLibraryLocation, - @Default("https://pipedapi.kavin.rocks") String pipedInstance, - @Default(ThemeMode.system) ThemeMode themeMode, - @Default(AudioSource.youtube) AudioSource audioSource, - @Default(SourceCodecs.weba) SourceCodecs streamMusicCodec, - @Default(SourceCodecs.m4a) SourceCodecs downloadMusicCodec, - @Default(true) bool discordPresence, - @Default(true) bool endlessPlayback, - @Default(false) bool enableConnect, - }) = _UserPreferences; - factory UserPreferences.fromJson(Map json) => - _$UserPreferencesFromJson(json); - - factory UserPreferences.withDefaults() => UserPreferences.fromJson({}); - - static SpotubeColor _accentColorSchemeFromJson(Map json) { - return SpotubeColor.fromString(json["color"]); - } - - static Map? _accentColorSchemeReadValue( - Map json, String key) { - if (json[key] is String) { - return {"color": json[key]}; - } - - return json[key] as Map?; - } - - static Map _accentColorSchemeToJson(SpotubeColor color) { - return {"color": color.toString()}; - } - - static Locale _localeFromJson(Map json) { - return Locale(json["languageCode"], json["countryCode"]); - } - - static Map _localeToJson(Locale locale) { - return { - "languageCode": locale.languageCode, - "countryCode": locale.countryCode, - }; - } - - static Map? _localeReadValue( - Map json, String key) { - if (json[key] is String) { - final map = jsonDecode(json[key]); - return { - "languageCode": map["lc"], - "countryCode": map["cc"], - }; - } - - return json[key] as Map?; - } -} - -enum BlacklistedType { - artist, - track; - - static BlacklistedType fromName(String name) => - BlacklistedType.values.firstWhere((e) => e.name == name); -} - -class BlacklistedElement { - final String id; - final String name; - final BlacklistedType type; - - BlacklistedElement.fromJson(Map json) - : id = json['id'], - name = json['name'], - type = BlacklistedType.fromName(json['type']); - - Map toJson() => {'id': id, 'type': type.name, 'name': name}; -} - -@freezed -class PlaybackHistoryItem with _$PlaybackHistoryItem { - factory PlaybackHistoryItem.playlist({ - required DateTime date, - required PlaylistSimple playlist, - }) = PlaybackHistoryPlaylist; - - factory PlaybackHistoryItem.album({ - required DateTime date, - required AlbumSimple album, - }) = PlaybackHistoryAlbum; - - factory PlaybackHistoryItem.track({ - required DateTime date, - required Track track, - }) = PlaybackHistoryTrack; - - factory PlaybackHistoryItem.fromJson(Map json) => - _$PlaybackHistoryItemFromJson(json); -} - -class PlaybackHistoryState { - final List items; - const PlaybackHistoryState({this.items = const []}); - - factory PlaybackHistoryState.fromJson(Map json) { - return PlaybackHistoryState( - items: json["items"] - ?.map( - (json) => PlaybackHistoryItem.fromJson(json), - ) - .toList() - .cast() ?? - [], - ); - } -} - -class ScrobblerState { - final String username; - final String passwordHash; - - ScrobblerState({ - required this.username, - required this.passwordHash, - }); - - factory ScrobblerState.fromJson(Map json) { - return ScrobblerState( - username: json["username"], - passwordHash: json["passwordHash"], - ); - } -} diff --git a/lib/utils/migrations/adapters.freezed.dart b/lib/utils/migrations/adapters.freezed.dart deleted file mode 100644 index 40dfd662..00000000 --- a/lib/utils/migrations/adapters.freezed.dart +++ /dev/null @@ -1,1421 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'adapters.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -UserPreferences _$UserPreferencesFromJson(Map json) { - return _UserPreferences.fromJson(json); -} - -/// @nodoc -mixin _$UserPreferences { - SourceQualities get audioQuality => throw _privateConstructorUsedError; - bool get albumColorSync => throw _privateConstructorUsedError; - bool get amoledDarkTheme => throw _privateConstructorUsedError; - bool get checkUpdate => throw _privateConstructorUsedError; - bool get normalizeAudio => throw _privateConstructorUsedError; - bool get showSystemTrayIcon => throw _privateConstructorUsedError; - bool get skipNonMusic => throw _privateConstructorUsedError; - bool get systemTitleBar => throw _privateConstructorUsedError; - CloseBehavior get closeBehavior => throw _privateConstructorUsedError; - @JsonKey( - fromJson: UserPreferences._accentColorSchemeFromJson, - toJson: UserPreferences._accentColorSchemeToJson, - readValue: UserPreferences._accentColorSchemeReadValue) - SpotubeColor get accentColorScheme => throw _privateConstructorUsedError; - LayoutMode get layoutMode => throw _privateConstructorUsedError; - @JsonKey( - fromJson: UserPreferences._localeFromJson, - toJson: UserPreferences._localeToJson, - readValue: UserPreferences._localeReadValue) - Locale get locale => throw _privateConstructorUsedError; - Market get recommendationMarket => throw _privateConstructorUsedError; - SearchMode get searchMode => throw _privateConstructorUsedError; - String get downloadLocation => throw _privateConstructorUsedError; - List get localLibraryLocation => throw _privateConstructorUsedError; - String get pipedInstance => throw _privateConstructorUsedError; - ThemeMode get themeMode => throw _privateConstructorUsedError; - AudioSource get audioSource => throw _privateConstructorUsedError; - SourceCodecs get streamMusicCodec => throw _privateConstructorUsedError; - SourceCodecs get downloadMusicCodec => throw _privateConstructorUsedError; - bool get discordPresence => throw _privateConstructorUsedError; - bool get endlessPlayback => throw _privateConstructorUsedError; - bool get enableConnect => throw _privateConstructorUsedError; - - /// Serializes this UserPreferences to a JSON map. - Map toJson() => throw _privateConstructorUsedError; - - /// Create a copy of UserPreferences - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - $UserPreferencesCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $UserPreferencesCopyWith<$Res> { - factory $UserPreferencesCopyWith( - UserPreferences value, $Res Function(UserPreferences) then) = - _$UserPreferencesCopyWithImpl<$Res, UserPreferences>; - @useResult - $Res call( - {SourceQualities audioQuality, - bool albumColorSync, - bool amoledDarkTheme, - bool checkUpdate, - bool normalizeAudio, - bool showSystemTrayIcon, - bool skipNonMusic, - bool systemTitleBar, - CloseBehavior closeBehavior, - @JsonKey( - fromJson: UserPreferences._accentColorSchemeFromJson, - toJson: UserPreferences._accentColorSchemeToJson, - readValue: UserPreferences._accentColorSchemeReadValue) - SpotubeColor accentColorScheme, - LayoutMode layoutMode, - @JsonKey( - fromJson: UserPreferences._localeFromJson, - toJson: UserPreferences._localeToJson, - readValue: UserPreferences._localeReadValue) - Locale locale, - Market recommendationMarket, - SearchMode searchMode, - String downloadLocation, - List localLibraryLocation, - String pipedInstance, - ThemeMode themeMode, - AudioSource audioSource, - SourceCodecs streamMusicCodec, - SourceCodecs downloadMusicCodec, - bool discordPresence, - bool endlessPlayback, - bool enableConnect}); -} - -/// @nodoc -class _$UserPreferencesCopyWithImpl<$Res, $Val extends UserPreferences> - implements $UserPreferencesCopyWith<$Res> { - _$UserPreferencesCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of UserPreferences - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? audioQuality = null, - Object? albumColorSync = null, - Object? amoledDarkTheme = null, - Object? checkUpdate = null, - Object? normalizeAudio = null, - Object? showSystemTrayIcon = null, - Object? skipNonMusic = null, - Object? systemTitleBar = null, - Object? closeBehavior = null, - Object? accentColorScheme = null, - Object? layoutMode = null, - Object? locale = null, - Object? recommendationMarket = null, - Object? searchMode = null, - Object? downloadLocation = null, - Object? localLibraryLocation = null, - Object? pipedInstance = null, - Object? themeMode = null, - Object? audioSource = null, - Object? streamMusicCodec = null, - Object? downloadMusicCodec = null, - Object? discordPresence = null, - Object? endlessPlayback = null, - Object? enableConnect = null, - }) { - return _then(_value.copyWith( - audioQuality: null == audioQuality - ? _value.audioQuality - : audioQuality // ignore: cast_nullable_to_non_nullable - as SourceQualities, - albumColorSync: null == albumColorSync - ? _value.albumColorSync - : albumColorSync // ignore: cast_nullable_to_non_nullable - as bool, - amoledDarkTheme: null == amoledDarkTheme - ? _value.amoledDarkTheme - : amoledDarkTheme // ignore: cast_nullable_to_non_nullable - as bool, - checkUpdate: null == checkUpdate - ? _value.checkUpdate - : checkUpdate // ignore: cast_nullable_to_non_nullable - as bool, - normalizeAudio: null == normalizeAudio - ? _value.normalizeAudio - : normalizeAudio // ignore: cast_nullable_to_non_nullable - as bool, - showSystemTrayIcon: null == showSystemTrayIcon - ? _value.showSystemTrayIcon - : showSystemTrayIcon // ignore: cast_nullable_to_non_nullable - as bool, - skipNonMusic: null == skipNonMusic - ? _value.skipNonMusic - : skipNonMusic // ignore: cast_nullable_to_non_nullable - as bool, - systemTitleBar: null == systemTitleBar - ? _value.systemTitleBar - : systemTitleBar // ignore: cast_nullable_to_non_nullable - as bool, - closeBehavior: null == closeBehavior - ? _value.closeBehavior - : closeBehavior // ignore: cast_nullable_to_non_nullable - as CloseBehavior, - accentColorScheme: null == accentColorScheme - ? _value.accentColorScheme - : accentColorScheme // ignore: cast_nullable_to_non_nullable - as SpotubeColor, - layoutMode: null == layoutMode - ? _value.layoutMode - : layoutMode // ignore: cast_nullable_to_non_nullable - as LayoutMode, - locale: null == locale - ? _value.locale - : locale // ignore: cast_nullable_to_non_nullable - as Locale, - recommendationMarket: null == recommendationMarket - ? _value.recommendationMarket - : recommendationMarket // ignore: cast_nullable_to_non_nullable - as Market, - searchMode: null == searchMode - ? _value.searchMode - : searchMode // ignore: cast_nullable_to_non_nullable - as SearchMode, - downloadLocation: null == downloadLocation - ? _value.downloadLocation - : downloadLocation // ignore: cast_nullable_to_non_nullable - as String, - localLibraryLocation: null == localLibraryLocation - ? _value.localLibraryLocation - : localLibraryLocation // ignore: cast_nullable_to_non_nullable - as List, - pipedInstance: null == pipedInstance - ? _value.pipedInstance - : pipedInstance // ignore: cast_nullable_to_non_nullable - as String, - themeMode: null == themeMode - ? _value.themeMode - : themeMode // ignore: cast_nullable_to_non_nullable - as ThemeMode, - audioSource: null == audioSource - ? _value.audioSource - : audioSource // ignore: cast_nullable_to_non_nullable - as AudioSource, - streamMusicCodec: null == streamMusicCodec - ? _value.streamMusicCodec - : streamMusicCodec // ignore: cast_nullable_to_non_nullable - as SourceCodecs, - downloadMusicCodec: null == downloadMusicCodec - ? _value.downloadMusicCodec - : downloadMusicCodec // ignore: cast_nullable_to_non_nullable - as SourceCodecs, - discordPresence: null == discordPresence - ? _value.discordPresence - : discordPresence // ignore: cast_nullable_to_non_nullable - as bool, - endlessPlayback: null == endlessPlayback - ? _value.endlessPlayback - : endlessPlayback // ignore: cast_nullable_to_non_nullable - as bool, - enableConnect: null == enableConnect - ? _value.enableConnect - : enableConnect // ignore: cast_nullable_to_non_nullable - as bool, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$UserPreferencesImplCopyWith<$Res> - implements $UserPreferencesCopyWith<$Res> { - factory _$$UserPreferencesImplCopyWith(_$UserPreferencesImpl value, - $Res Function(_$UserPreferencesImpl) then) = - __$$UserPreferencesImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {SourceQualities audioQuality, - bool albumColorSync, - bool amoledDarkTheme, - bool checkUpdate, - bool normalizeAudio, - bool showSystemTrayIcon, - bool skipNonMusic, - bool systemTitleBar, - CloseBehavior closeBehavior, - @JsonKey( - fromJson: UserPreferences._accentColorSchemeFromJson, - toJson: UserPreferences._accentColorSchemeToJson, - readValue: UserPreferences._accentColorSchemeReadValue) - SpotubeColor accentColorScheme, - LayoutMode layoutMode, - @JsonKey( - fromJson: UserPreferences._localeFromJson, - toJson: UserPreferences._localeToJson, - readValue: UserPreferences._localeReadValue) - Locale locale, - Market recommendationMarket, - SearchMode searchMode, - String downloadLocation, - List localLibraryLocation, - String pipedInstance, - ThemeMode themeMode, - AudioSource audioSource, - SourceCodecs streamMusicCodec, - SourceCodecs downloadMusicCodec, - bool discordPresence, - bool endlessPlayback, - bool enableConnect}); -} - -/// @nodoc -class __$$UserPreferencesImplCopyWithImpl<$Res> - extends _$UserPreferencesCopyWithImpl<$Res, _$UserPreferencesImpl> - implements _$$UserPreferencesImplCopyWith<$Res> { - __$$UserPreferencesImplCopyWithImpl( - _$UserPreferencesImpl _value, $Res Function(_$UserPreferencesImpl) _then) - : super(_value, _then); - - /// Create a copy of UserPreferences - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? audioQuality = null, - Object? albumColorSync = null, - Object? amoledDarkTheme = null, - Object? checkUpdate = null, - Object? normalizeAudio = null, - Object? showSystemTrayIcon = null, - Object? skipNonMusic = null, - Object? systemTitleBar = null, - Object? closeBehavior = null, - Object? accentColorScheme = null, - Object? layoutMode = null, - Object? locale = null, - Object? recommendationMarket = null, - Object? searchMode = null, - Object? downloadLocation = null, - Object? localLibraryLocation = null, - Object? pipedInstance = null, - Object? themeMode = null, - Object? audioSource = null, - Object? streamMusicCodec = null, - Object? downloadMusicCodec = null, - Object? discordPresence = null, - Object? endlessPlayback = null, - Object? enableConnect = null, - }) { - return _then(_$UserPreferencesImpl( - audioQuality: null == audioQuality - ? _value.audioQuality - : audioQuality // ignore: cast_nullable_to_non_nullable - as SourceQualities, - albumColorSync: null == albumColorSync - ? _value.albumColorSync - : albumColorSync // ignore: cast_nullable_to_non_nullable - as bool, - amoledDarkTheme: null == amoledDarkTheme - ? _value.amoledDarkTheme - : amoledDarkTheme // ignore: cast_nullable_to_non_nullable - as bool, - checkUpdate: null == checkUpdate - ? _value.checkUpdate - : checkUpdate // ignore: cast_nullable_to_non_nullable - as bool, - normalizeAudio: null == normalizeAudio - ? _value.normalizeAudio - : normalizeAudio // ignore: cast_nullable_to_non_nullable - as bool, - showSystemTrayIcon: null == showSystemTrayIcon - ? _value.showSystemTrayIcon - : showSystemTrayIcon // ignore: cast_nullable_to_non_nullable - as bool, - skipNonMusic: null == skipNonMusic - ? _value.skipNonMusic - : skipNonMusic // ignore: cast_nullable_to_non_nullable - as bool, - systemTitleBar: null == systemTitleBar - ? _value.systemTitleBar - : systemTitleBar // ignore: cast_nullable_to_non_nullable - as bool, - closeBehavior: null == closeBehavior - ? _value.closeBehavior - : closeBehavior // ignore: cast_nullable_to_non_nullable - as CloseBehavior, - accentColorScheme: null == accentColorScheme - ? _value.accentColorScheme - : accentColorScheme // ignore: cast_nullable_to_non_nullable - as SpotubeColor, - layoutMode: null == layoutMode - ? _value.layoutMode - : layoutMode // ignore: cast_nullable_to_non_nullable - as LayoutMode, - locale: null == locale - ? _value.locale - : locale // ignore: cast_nullable_to_non_nullable - as Locale, - recommendationMarket: null == recommendationMarket - ? _value.recommendationMarket - : recommendationMarket // ignore: cast_nullable_to_non_nullable - as Market, - searchMode: null == searchMode - ? _value.searchMode - : searchMode // ignore: cast_nullable_to_non_nullable - as SearchMode, - downloadLocation: null == downloadLocation - ? _value.downloadLocation - : downloadLocation // ignore: cast_nullable_to_non_nullable - as String, - localLibraryLocation: null == localLibraryLocation - ? _value._localLibraryLocation - : localLibraryLocation // ignore: cast_nullable_to_non_nullable - as List, - pipedInstance: null == pipedInstance - ? _value.pipedInstance - : pipedInstance // ignore: cast_nullable_to_non_nullable - as String, - themeMode: null == themeMode - ? _value.themeMode - : themeMode // ignore: cast_nullable_to_non_nullable - as ThemeMode, - audioSource: null == audioSource - ? _value.audioSource - : audioSource // ignore: cast_nullable_to_non_nullable - as AudioSource, - streamMusicCodec: null == streamMusicCodec - ? _value.streamMusicCodec - : streamMusicCodec // ignore: cast_nullable_to_non_nullable - as SourceCodecs, - downloadMusicCodec: null == downloadMusicCodec - ? _value.downloadMusicCodec - : downloadMusicCodec // ignore: cast_nullable_to_non_nullable - as SourceCodecs, - discordPresence: null == discordPresence - ? _value.discordPresence - : discordPresence // ignore: cast_nullable_to_non_nullable - as bool, - endlessPlayback: null == endlessPlayback - ? _value.endlessPlayback - : endlessPlayback // ignore: cast_nullable_to_non_nullable - as bool, - enableConnect: null == enableConnect - ? _value.enableConnect - : enableConnect // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$UserPreferencesImpl implements _UserPreferences { - const _$UserPreferencesImpl( - {this.audioQuality = SourceQualities.high, - this.albumColorSync = true, - this.amoledDarkTheme = false, - this.checkUpdate = true, - this.normalizeAudio = false, - this.showSystemTrayIcon = false, - this.skipNonMusic = false, - this.systemTitleBar = false, - this.closeBehavior = CloseBehavior.close, - @JsonKey( - fromJson: UserPreferences._accentColorSchemeFromJson, - toJson: UserPreferences._accentColorSchemeToJson, - readValue: UserPreferences._accentColorSchemeReadValue) - this.accentColorScheme = const SpotubeColor(0xFF2196F3, name: "Blue"), - this.layoutMode = LayoutMode.adaptive, - @JsonKey( - fromJson: UserPreferences._localeFromJson, - toJson: UserPreferences._localeToJson, - readValue: UserPreferences._localeReadValue) - this.locale = const Locale("system", "system"), - this.recommendationMarket = Market.US, - this.searchMode = SearchMode.youtube, - this.downloadLocation = "", - final List localLibraryLocation = const [], - this.pipedInstance = "https://pipedapi.kavin.rocks", - this.themeMode = ThemeMode.system, - this.audioSource = AudioSource.youtube, - this.streamMusicCodec = SourceCodecs.weba, - this.downloadMusicCodec = SourceCodecs.m4a, - this.discordPresence = true, - this.endlessPlayback = true, - this.enableConnect = false}) - : _localLibraryLocation = localLibraryLocation; - - factory _$UserPreferencesImpl.fromJson(Map json) => - _$$UserPreferencesImplFromJson(json); - - @override - @JsonKey() - final SourceQualities audioQuality; - @override - @JsonKey() - final bool albumColorSync; - @override - @JsonKey() - final bool amoledDarkTheme; - @override - @JsonKey() - final bool checkUpdate; - @override - @JsonKey() - final bool normalizeAudio; - @override - @JsonKey() - final bool showSystemTrayIcon; - @override - @JsonKey() - final bool skipNonMusic; - @override - @JsonKey() - final bool systemTitleBar; - @override - @JsonKey() - final CloseBehavior closeBehavior; - @override - @JsonKey( - fromJson: UserPreferences._accentColorSchemeFromJson, - toJson: UserPreferences._accentColorSchemeToJson, - readValue: UserPreferences._accentColorSchemeReadValue) - final SpotubeColor accentColorScheme; - @override - @JsonKey() - final LayoutMode layoutMode; - @override - @JsonKey( - fromJson: UserPreferences._localeFromJson, - toJson: UserPreferences._localeToJson, - readValue: UserPreferences._localeReadValue) - final Locale locale; - @override - @JsonKey() - final Market recommendationMarket; - @override - @JsonKey() - final SearchMode searchMode; - @override - @JsonKey() - final String downloadLocation; - final List _localLibraryLocation; - @override - @JsonKey() - List get localLibraryLocation { - if (_localLibraryLocation is EqualUnmodifiableListView) - return _localLibraryLocation; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_localLibraryLocation); - } - - @override - @JsonKey() - final String pipedInstance; - @override - @JsonKey() - final ThemeMode themeMode; - @override - @JsonKey() - final AudioSource audioSource; - @override - @JsonKey() - final SourceCodecs streamMusicCodec; - @override - @JsonKey() - final SourceCodecs downloadMusicCodec; - @override - @JsonKey() - final bool discordPresence; - @override - @JsonKey() - final bool endlessPlayback; - @override - @JsonKey() - final bool enableConnect; - - @override - String toString() { - return 'UserPreferences(audioQuality: $audioQuality, albumColorSync: $albumColorSync, amoledDarkTheme: $amoledDarkTheme, checkUpdate: $checkUpdate, normalizeAudio: $normalizeAudio, showSystemTrayIcon: $showSystemTrayIcon, skipNonMusic: $skipNonMusic, systemTitleBar: $systemTitleBar, closeBehavior: $closeBehavior, accentColorScheme: $accentColorScheme, layoutMode: $layoutMode, locale: $locale, recommendationMarket: $recommendationMarket, searchMode: $searchMode, downloadLocation: $downloadLocation, localLibraryLocation: $localLibraryLocation, pipedInstance: $pipedInstance, themeMode: $themeMode, audioSource: $audioSource, streamMusicCodec: $streamMusicCodec, downloadMusicCodec: $downloadMusicCodec, discordPresence: $discordPresence, endlessPlayback: $endlessPlayback, enableConnect: $enableConnect)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$UserPreferencesImpl && - (identical(other.audioQuality, audioQuality) || - other.audioQuality == audioQuality) && - (identical(other.albumColorSync, albumColorSync) || - other.albumColorSync == albumColorSync) && - (identical(other.amoledDarkTheme, amoledDarkTheme) || - other.amoledDarkTheme == amoledDarkTheme) && - (identical(other.checkUpdate, checkUpdate) || - other.checkUpdate == checkUpdate) && - (identical(other.normalizeAudio, normalizeAudio) || - other.normalizeAudio == normalizeAudio) && - (identical(other.showSystemTrayIcon, showSystemTrayIcon) || - other.showSystemTrayIcon == showSystemTrayIcon) && - (identical(other.skipNonMusic, skipNonMusic) || - other.skipNonMusic == skipNonMusic) && - (identical(other.systemTitleBar, systemTitleBar) || - other.systemTitleBar == systemTitleBar) && - (identical(other.closeBehavior, closeBehavior) || - other.closeBehavior == closeBehavior) && - (identical(other.accentColorScheme, accentColorScheme) || - other.accentColorScheme == accentColorScheme) && - (identical(other.layoutMode, layoutMode) || - other.layoutMode == layoutMode) && - (identical(other.locale, locale) || other.locale == locale) && - (identical(other.recommendationMarket, recommendationMarket) || - other.recommendationMarket == recommendationMarket) && - (identical(other.searchMode, searchMode) || - other.searchMode == searchMode) && - (identical(other.downloadLocation, downloadLocation) || - other.downloadLocation == downloadLocation) && - const DeepCollectionEquality() - .equals(other._localLibraryLocation, _localLibraryLocation) && - (identical(other.pipedInstance, pipedInstance) || - other.pipedInstance == pipedInstance) && - (identical(other.themeMode, themeMode) || - other.themeMode == themeMode) && - (identical(other.audioSource, audioSource) || - other.audioSource == audioSource) && - (identical(other.streamMusicCodec, streamMusicCodec) || - other.streamMusicCodec == streamMusicCodec) && - (identical(other.downloadMusicCodec, downloadMusicCodec) || - other.downloadMusicCodec == downloadMusicCodec) && - (identical(other.discordPresence, discordPresence) || - other.discordPresence == discordPresence) && - (identical(other.endlessPlayback, endlessPlayback) || - other.endlessPlayback == endlessPlayback) && - (identical(other.enableConnect, enableConnect) || - other.enableConnect == enableConnect)); - } - - @JsonKey(includeFromJson: false, includeToJson: false) - @override - int get hashCode => Object.hashAll([ - runtimeType, - audioQuality, - albumColorSync, - amoledDarkTheme, - checkUpdate, - normalizeAudio, - showSystemTrayIcon, - skipNonMusic, - systemTitleBar, - closeBehavior, - accentColorScheme, - layoutMode, - locale, - recommendationMarket, - searchMode, - downloadLocation, - const DeepCollectionEquality().hash(_localLibraryLocation), - pipedInstance, - themeMode, - audioSource, - streamMusicCodec, - downloadMusicCodec, - discordPresence, - endlessPlayback, - enableConnect - ]); - - /// Create a copy of UserPreferences - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$UserPreferencesImplCopyWith<_$UserPreferencesImpl> get copyWith => - __$$UserPreferencesImplCopyWithImpl<_$UserPreferencesImpl>( - this, _$identity); - - @override - Map toJson() { - return _$$UserPreferencesImplToJson( - this, - ); - } -} - -abstract class _UserPreferences implements UserPreferences { - const factory _UserPreferences( - {final SourceQualities audioQuality, - final bool albumColorSync, - final bool amoledDarkTheme, - final bool checkUpdate, - final bool normalizeAudio, - final bool showSystemTrayIcon, - final bool skipNonMusic, - final bool systemTitleBar, - final CloseBehavior closeBehavior, - @JsonKey( - fromJson: UserPreferences._accentColorSchemeFromJson, - toJson: UserPreferences._accentColorSchemeToJson, - readValue: UserPreferences._accentColorSchemeReadValue) - final SpotubeColor accentColorScheme, - final LayoutMode layoutMode, - @JsonKey( - fromJson: UserPreferences._localeFromJson, - toJson: UserPreferences._localeToJson, - readValue: UserPreferences._localeReadValue) - final Locale locale, - final Market recommendationMarket, - final SearchMode searchMode, - final String downloadLocation, - final List localLibraryLocation, - final String pipedInstance, - final ThemeMode themeMode, - final AudioSource audioSource, - final SourceCodecs streamMusicCodec, - final SourceCodecs downloadMusicCodec, - final bool discordPresence, - final bool endlessPlayback, - final bool enableConnect}) = _$UserPreferencesImpl; - - factory _UserPreferences.fromJson(Map json) = - _$UserPreferencesImpl.fromJson; - - @override - SourceQualities get audioQuality; - @override - bool get albumColorSync; - @override - bool get amoledDarkTheme; - @override - bool get checkUpdate; - @override - bool get normalizeAudio; - @override - bool get showSystemTrayIcon; - @override - bool get skipNonMusic; - @override - bool get systemTitleBar; - @override - CloseBehavior get closeBehavior; - @override - @JsonKey( - fromJson: UserPreferences._accentColorSchemeFromJson, - toJson: UserPreferences._accentColorSchemeToJson, - readValue: UserPreferences._accentColorSchemeReadValue) - SpotubeColor get accentColorScheme; - @override - LayoutMode get layoutMode; - @override - @JsonKey( - fromJson: UserPreferences._localeFromJson, - toJson: UserPreferences._localeToJson, - readValue: UserPreferences._localeReadValue) - Locale get locale; - @override - Market get recommendationMarket; - @override - SearchMode get searchMode; - @override - String get downloadLocation; - @override - List get localLibraryLocation; - @override - String get pipedInstance; - @override - ThemeMode get themeMode; - @override - AudioSource get audioSource; - @override - SourceCodecs get streamMusicCodec; - @override - SourceCodecs get downloadMusicCodec; - @override - bool get discordPresence; - @override - bool get endlessPlayback; - @override - bool get enableConnect; - - /// Create a copy of UserPreferences - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$UserPreferencesImplCopyWith<_$UserPreferencesImpl> get copyWith => - throw _privateConstructorUsedError; -} - -PlaybackHistoryItem _$PlaybackHistoryItemFromJson(Map json) { - switch (json['runtimeType']) { - case 'playlist': - return PlaybackHistoryPlaylist.fromJson(json); - case 'album': - return PlaybackHistoryAlbum.fromJson(json); - case 'track': - return PlaybackHistoryTrack.fromJson(json); - - default: - throw CheckedFromJsonException(json, 'runtimeType', 'PlaybackHistoryItem', - 'Invalid union type "${json['runtimeType']}"!'); - } -} - -/// @nodoc -mixin _$PlaybackHistoryItem { - DateTime get date => throw _privateConstructorUsedError; - @optionalTypeArgs - TResult when({ - required TResult Function(DateTime date, PlaylistSimple playlist) playlist, - required TResult Function(DateTime date, AlbumSimple album) album, - required TResult Function(DateTime date, Track track) track, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(DateTime date, PlaylistSimple playlist)? playlist, - TResult? Function(DateTime date, AlbumSimple album)? album, - TResult? Function(DateTime date, Track track)? track, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(DateTime date, PlaylistSimple playlist)? playlist, - TResult Function(DateTime date, AlbumSimple album)? album, - TResult Function(DateTime date, Track track)? track, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(PlaybackHistoryPlaylist value) playlist, - required TResult Function(PlaybackHistoryAlbum value) album, - required TResult Function(PlaybackHistoryTrack value) track, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(PlaybackHistoryPlaylist value)? playlist, - TResult? Function(PlaybackHistoryAlbum value)? album, - TResult? Function(PlaybackHistoryTrack value)? track, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(PlaybackHistoryPlaylist value)? playlist, - TResult Function(PlaybackHistoryAlbum value)? album, - TResult Function(PlaybackHistoryTrack value)? track, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - - /// Serializes this PlaybackHistoryItem to a JSON map. - Map toJson() => throw _privateConstructorUsedError; - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - $PlaybackHistoryItemCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $PlaybackHistoryItemCopyWith<$Res> { - factory $PlaybackHistoryItemCopyWith( - PlaybackHistoryItem value, $Res Function(PlaybackHistoryItem) then) = - _$PlaybackHistoryItemCopyWithImpl<$Res, PlaybackHistoryItem>; - @useResult - $Res call({DateTime date}); -} - -/// @nodoc -class _$PlaybackHistoryItemCopyWithImpl<$Res, $Val extends PlaybackHistoryItem> - implements $PlaybackHistoryItemCopyWith<$Res> { - _$PlaybackHistoryItemCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? date = null, - }) { - return _then(_value.copyWith( - date: null == date - ? _value.date - : date // ignore: cast_nullable_to_non_nullable - as DateTime, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$PlaybackHistoryPlaylistImplCopyWith<$Res> - implements $PlaybackHistoryItemCopyWith<$Res> { - factory _$$PlaybackHistoryPlaylistImplCopyWith( - _$PlaybackHistoryPlaylistImpl value, - $Res Function(_$PlaybackHistoryPlaylistImpl) then) = - __$$PlaybackHistoryPlaylistImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({DateTime date, PlaylistSimple playlist}); -} - -/// @nodoc -class __$$PlaybackHistoryPlaylistImplCopyWithImpl<$Res> - extends _$PlaybackHistoryItemCopyWithImpl<$Res, - _$PlaybackHistoryPlaylistImpl> - implements _$$PlaybackHistoryPlaylistImplCopyWith<$Res> { - __$$PlaybackHistoryPlaylistImplCopyWithImpl( - _$PlaybackHistoryPlaylistImpl _value, - $Res Function(_$PlaybackHistoryPlaylistImpl) _then) - : super(_value, _then); - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? date = null, - Object? playlist = null, - }) { - return _then(_$PlaybackHistoryPlaylistImpl( - date: null == date - ? _value.date - : date // ignore: cast_nullable_to_non_nullable - as DateTime, - playlist: null == playlist - ? _value.playlist - : playlist // ignore: cast_nullable_to_non_nullable - as PlaylistSimple, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$PlaybackHistoryPlaylistImpl implements PlaybackHistoryPlaylist { - _$PlaybackHistoryPlaylistImpl( - {required this.date, required this.playlist, final String? $type}) - : $type = $type ?? 'playlist'; - - factory _$PlaybackHistoryPlaylistImpl.fromJson(Map json) => - _$$PlaybackHistoryPlaylistImplFromJson(json); - - @override - final DateTime date; - @override - final PlaylistSimple playlist; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'PlaybackHistoryItem.playlist(date: $date, playlist: $playlist)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$PlaybackHistoryPlaylistImpl && - (identical(other.date, date) || other.date == date) && - (identical(other.playlist, playlist) || - other.playlist == playlist)); - } - - @JsonKey(includeFromJson: false, includeToJson: false) - @override - int get hashCode => Object.hash(runtimeType, date, playlist); - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$PlaybackHistoryPlaylistImplCopyWith<_$PlaybackHistoryPlaylistImpl> - get copyWith => __$$PlaybackHistoryPlaylistImplCopyWithImpl< - _$PlaybackHistoryPlaylistImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(DateTime date, PlaylistSimple playlist) playlist, - required TResult Function(DateTime date, AlbumSimple album) album, - required TResult Function(DateTime date, Track track) track, - }) { - return playlist(date, this.playlist); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(DateTime date, PlaylistSimple playlist)? playlist, - TResult? Function(DateTime date, AlbumSimple album)? album, - TResult? Function(DateTime date, Track track)? track, - }) { - return playlist?.call(date, this.playlist); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(DateTime date, PlaylistSimple playlist)? playlist, - TResult Function(DateTime date, AlbumSimple album)? album, - TResult Function(DateTime date, Track track)? track, - required TResult orElse(), - }) { - if (playlist != null) { - return playlist(date, this.playlist); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(PlaybackHistoryPlaylist value) playlist, - required TResult Function(PlaybackHistoryAlbum value) album, - required TResult Function(PlaybackHistoryTrack value) track, - }) { - return playlist(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(PlaybackHistoryPlaylist value)? playlist, - TResult? Function(PlaybackHistoryAlbum value)? album, - TResult? Function(PlaybackHistoryTrack value)? track, - }) { - return playlist?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(PlaybackHistoryPlaylist value)? playlist, - TResult Function(PlaybackHistoryAlbum value)? album, - TResult Function(PlaybackHistoryTrack value)? track, - required TResult orElse(), - }) { - if (playlist != null) { - return playlist(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$PlaybackHistoryPlaylistImplToJson( - this, - ); - } -} - -abstract class PlaybackHistoryPlaylist implements PlaybackHistoryItem { - factory PlaybackHistoryPlaylist( - {required final DateTime date, - required final PlaylistSimple playlist}) = _$PlaybackHistoryPlaylistImpl; - - factory PlaybackHistoryPlaylist.fromJson(Map json) = - _$PlaybackHistoryPlaylistImpl.fromJson; - - @override - DateTime get date; - PlaylistSimple get playlist; - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$PlaybackHistoryPlaylistImplCopyWith<_$PlaybackHistoryPlaylistImpl> - get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$PlaybackHistoryAlbumImplCopyWith<$Res> - implements $PlaybackHistoryItemCopyWith<$Res> { - factory _$$PlaybackHistoryAlbumImplCopyWith(_$PlaybackHistoryAlbumImpl value, - $Res Function(_$PlaybackHistoryAlbumImpl) then) = - __$$PlaybackHistoryAlbumImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({DateTime date, AlbumSimple album}); -} - -/// @nodoc -class __$$PlaybackHistoryAlbumImplCopyWithImpl<$Res> - extends _$PlaybackHistoryItemCopyWithImpl<$Res, _$PlaybackHistoryAlbumImpl> - implements _$$PlaybackHistoryAlbumImplCopyWith<$Res> { - __$$PlaybackHistoryAlbumImplCopyWithImpl(_$PlaybackHistoryAlbumImpl _value, - $Res Function(_$PlaybackHistoryAlbumImpl) _then) - : super(_value, _then); - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? date = null, - Object? album = null, - }) { - return _then(_$PlaybackHistoryAlbumImpl( - date: null == date - ? _value.date - : date // ignore: cast_nullable_to_non_nullable - as DateTime, - album: null == album - ? _value.album - : album // ignore: cast_nullable_to_non_nullable - as AlbumSimple, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$PlaybackHistoryAlbumImpl implements PlaybackHistoryAlbum { - _$PlaybackHistoryAlbumImpl( - {required this.date, required this.album, final String? $type}) - : $type = $type ?? 'album'; - - factory _$PlaybackHistoryAlbumImpl.fromJson(Map json) => - _$$PlaybackHistoryAlbumImplFromJson(json); - - @override - final DateTime date; - @override - final AlbumSimple album; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'PlaybackHistoryItem.album(date: $date, album: $album)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$PlaybackHistoryAlbumImpl && - (identical(other.date, date) || other.date == date) && - (identical(other.album, album) || other.album == album)); - } - - @JsonKey(includeFromJson: false, includeToJson: false) - @override - int get hashCode => Object.hash(runtimeType, date, album); - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$PlaybackHistoryAlbumImplCopyWith<_$PlaybackHistoryAlbumImpl> - get copyWith => - __$$PlaybackHistoryAlbumImplCopyWithImpl<_$PlaybackHistoryAlbumImpl>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(DateTime date, PlaylistSimple playlist) playlist, - required TResult Function(DateTime date, AlbumSimple album) album, - required TResult Function(DateTime date, Track track) track, - }) { - return album(date, this.album); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(DateTime date, PlaylistSimple playlist)? playlist, - TResult? Function(DateTime date, AlbumSimple album)? album, - TResult? Function(DateTime date, Track track)? track, - }) { - return album?.call(date, this.album); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(DateTime date, PlaylistSimple playlist)? playlist, - TResult Function(DateTime date, AlbumSimple album)? album, - TResult Function(DateTime date, Track track)? track, - required TResult orElse(), - }) { - if (album != null) { - return album(date, this.album); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(PlaybackHistoryPlaylist value) playlist, - required TResult Function(PlaybackHistoryAlbum value) album, - required TResult Function(PlaybackHistoryTrack value) track, - }) { - return album(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(PlaybackHistoryPlaylist value)? playlist, - TResult? Function(PlaybackHistoryAlbum value)? album, - TResult? Function(PlaybackHistoryTrack value)? track, - }) { - return album?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(PlaybackHistoryPlaylist value)? playlist, - TResult Function(PlaybackHistoryAlbum value)? album, - TResult Function(PlaybackHistoryTrack value)? track, - required TResult orElse(), - }) { - if (album != null) { - return album(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$PlaybackHistoryAlbumImplToJson( - this, - ); - } -} - -abstract class PlaybackHistoryAlbum implements PlaybackHistoryItem { - factory PlaybackHistoryAlbum( - {required final DateTime date, - required final AlbumSimple album}) = _$PlaybackHistoryAlbumImpl; - - factory PlaybackHistoryAlbum.fromJson(Map json) = - _$PlaybackHistoryAlbumImpl.fromJson; - - @override - DateTime get date; - AlbumSimple get album; - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$PlaybackHistoryAlbumImplCopyWith<_$PlaybackHistoryAlbumImpl> - get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$PlaybackHistoryTrackImplCopyWith<$Res> - implements $PlaybackHistoryItemCopyWith<$Res> { - factory _$$PlaybackHistoryTrackImplCopyWith(_$PlaybackHistoryTrackImpl value, - $Res Function(_$PlaybackHistoryTrackImpl) then) = - __$$PlaybackHistoryTrackImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({DateTime date, Track track}); -} - -/// @nodoc -class __$$PlaybackHistoryTrackImplCopyWithImpl<$Res> - extends _$PlaybackHistoryItemCopyWithImpl<$Res, _$PlaybackHistoryTrackImpl> - implements _$$PlaybackHistoryTrackImplCopyWith<$Res> { - __$$PlaybackHistoryTrackImplCopyWithImpl(_$PlaybackHistoryTrackImpl _value, - $Res Function(_$PlaybackHistoryTrackImpl) _then) - : super(_value, _then); - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? date = null, - Object? track = null, - }) { - return _then(_$PlaybackHistoryTrackImpl( - date: null == date - ? _value.date - : date // ignore: cast_nullable_to_non_nullable - as DateTime, - track: null == track - ? _value.track - : track // ignore: cast_nullable_to_non_nullable - as Track, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$PlaybackHistoryTrackImpl implements PlaybackHistoryTrack { - _$PlaybackHistoryTrackImpl( - {required this.date, required this.track, final String? $type}) - : $type = $type ?? 'track'; - - factory _$PlaybackHistoryTrackImpl.fromJson(Map json) => - _$$PlaybackHistoryTrackImplFromJson(json); - - @override - final DateTime date; - @override - final Track track; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'PlaybackHistoryItem.track(date: $date, track: $track)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$PlaybackHistoryTrackImpl && - (identical(other.date, date) || other.date == date) && - (identical(other.track, track) || other.track == track)); - } - - @JsonKey(includeFromJson: false, includeToJson: false) - @override - int get hashCode => Object.hash(runtimeType, date, track); - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$PlaybackHistoryTrackImplCopyWith<_$PlaybackHistoryTrackImpl> - get copyWith => - __$$PlaybackHistoryTrackImplCopyWithImpl<_$PlaybackHistoryTrackImpl>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(DateTime date, PlaylistSimple playlist) playlist, - required TResult Function(DateTime date, AlbumSimple album) album, - required TResult Function(DateTime date, Track track) track, - }) { - return track(date, this.track); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(DateTime date, PlaylistSimple playlist)? playlist, - TResult? Function(DateTime date, AlbumSimple album)? album, - TResult? Function(DateTime date, Track track)? track, - }) { - return track?.call(date, this.track); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(DateTime date, PlaylistSimple playlist)? playlist, - TResult Function(DateTime date, AlbumSimple album)? album, - TResult Function(DateTime date, Track track)? track, - required TResult orElse(), - }) { - if (track != null) { - return track(date, this.track); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(PlaybackHistoryPlaylist value) playlist, - required TResult Function(PlaybackHistoryAlbum value) album, - required TResult Function(PlaybackHistoryTrack value) track, - }) { - return track(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(PlaybackHistoryPlaylist value)? playlist, - TResult? Function(PlaybackHistoryAlbum value)? album, - TResult? Function(PlaybackHistoryTrack value)? track, - }) { - return track?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(PlaybackHistoryPlaylist value)? playlist, - TResult Function(PlaybackHistoryAlbum value)? album, - TResult Function(PlaybackHistoryTrack value)? track, - required TResult orElse(), - }) { - if (track != null) { - return track(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$PlaybackHistoryTrackImplToJson( - this, - ); - } -} - -abstract class PlaybackHistoryTrack implements PlaybackHistoryItem { - factory PlaybackHistoryTrack( - {required final DateTime date, - required final Track track}) = _$PlaybackHistoryTrackImpl; - - factory PlaybackHistoryTrack.fromJson(Map json) = - _$PlaybackHistoryTrackImpl.fromJson; - - @override - DateTime get date; - Track get track; - - /// Create a copy of PlaybackHistoryItem - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$PlaybackHistoryTrackImplCopyWith<_$PlaybackHistoryTrackImpl> - get copyWith => throw _privateConstructorUsedError; -} diff --git a/lib/utils/migrations/adapters.g.dart b/lib/utils/migrations/adapters.g.dart deleted file mode 100644 index ca95a840..00000000 --- a/lib/utils/migrations/adapters.g.dart +++ /dev/null @@ -1,600 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'adapters.dart'; - -// ************************************************************************** -// TypeAdapterGenerator -// ************************************************************************** - -class SkipSegmentAdapter extends TypeAdapter { - @override - final int typeId = 2; - - @override - SkipSegment read(BinaryReader reader) { - final numOfFields = reader.readByte(); - final fields = { - for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), - }; - return SkipSegment( - fields[0] as int, - fields[1] as int, - ); - } - - @override - void write(BinaryWriter writer, SkipSegment obj) { - writer - ..writeByte(2) - ..writeByte(0) - ..write(obj.start) - ..writeByte(1) - ..write(obj.end); - } - - @override - int get hashCode => typeId.hashCode; - - @override - bool operator ==(Object other) => - identical(this, other) || - other is SkipSegmentAdapter && - runtimeType == other.runtimeType && - typeId == other.typeId; -} - -class SourceMatchAdapter extends TypeAdapter { - @override - final int typeId = 6; - - @override - SourceMatch read(BinaryReader reader) { - final numOfFields = reader.readByte(); - final fields = { - for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), - }; - return SourceMatch( - id: fields[0] as String, - sourceId: fields[1] as String, - sourceType: fields[2] as SourceType, - createdAt: fields[3] as DateTime, - ); - } - - @override - void write(BinaryWriter writer, SourceMatch obj) { - writer - ..writeByte(4) - ..writeByte(0) - ..write(obj.id) - ..writeByte(1) - ..write(obj.sourceId) - ..writeByte(2) - ..write(obj.sourceType) - ..writeByte(3) - ..write(obj.createdAt); - } - - @override - int get hashCode => typeId.hashCode; - - @override - bool operator ==(Object other) => - identical(this, other) || - other is SourceMatchAdapter && - runtimeType == other.runtimeType && - typeId == other.typeId; -} - -class SourceTypeAdapter extends TypeAdapter { - @override - final int typeId = 5; - - @override - SourceType read(BinaryReader reader) { - switch (reader.readByte()) { - case 0: - return SourceType.youtube; - case 1: - return SourceType.youtubeMusic; - case 2: - return SourceType.jiosaavn; - default: - return SourceType.youtube; - } - } - - @override - void write(BinaryWriter writer, SourceType obj) { - switch (obj) { - case SourceType.youtube: - writer.writeByte(0); - break; - case SourceType.youtubeMusic: - writer.writeByte(1); - break; - case SourceType.jiosaavn: - writer.writeByte(2); - break; - } - } - - @override - int get hashCode => typeId.hashCode; - - @override - bool operator ==(Object other) => - identical(this, other) || - other is SourceTypeAdapter && - runtimeType == other.runtimeType && - typeId == other.typeId; -} - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SourceMatch _$SourceMatchFromJson(Map json) => SourceMatch( - id: json['id'] as String, - sourceId: json['sourceId'] as String, - sourceType: $enumDecode(_$SourceTypeEnumMap, json['sourceType']), - createdAt: DateTime.parse(json['createdAt'] as String), - ); - -Map _$SourceMatchToJson(SourceMatch instance) => - { - 'id': instance.id, - 'sourceId': instance.sourceId, - 'sourceType': _$SourceTypeEnumMap[instance.sourceType]!, - 'createdAt': instance.createdAt.toIso8601String(), - }; - -const _$SourceTypeEnumMap = { - SourceType.youtube: 'youtube', - SourceType.youtubeMusic: 'youtubeMusic', - SourceType.jiosaavn: 'jiosaavn', -}; - -AuthenticationCredentials _$AuthenticationCredentialsFromJson(Map json) => - AuthenticationCredentials( - cookie: json['cookie'] as String, - accessToken: json['accessToken'] as String, - expiration: DateTime.parse(json['expiration'] as String), - ); - -Map _$AuthenticationCredentialsToJson( - AuthenticationCredentials instance) => - { - 'cookie': instance.cookie, - 'accessToken': instance.accessToken, - 'expiration': instance.expiration.toIso8601String(), - }; - -_$UserPreferencesImpl _$$UserPreferencesImplFromJson(Map json) => - _$UserPreferencesImpl( - audioQuality: - $enumDecodeNullable(_$SourceQualitiesEnumMap, json['audioQuality']) ?? - SourceQualities.high, - albumColorSync: json['albumColorSync'] as bool? ?? true, - amoledDarkTheme: json['amoledDarkTheme'] as bool? ?? false, - checkUpdate: json['checkUpdate'] as bool? ?? true, - normalizeAudio: json['normalizeAudio'] as bool? ?? false, - showSystemTrayIcon: json['showSystemTrayIcon'] as bool? ?? false, - skipNonMusic: json['skipNonMusic'] as bool? ?? false, - systemTitleBar: json['systemTitleBar'] as bool? ?? false, - closeBehavior: - $enumDecodeNullable(_$CloseBehaviorEnumMap, json['closeBehavior']) ?? - CloseBehavior.close, - accentColorScheme: UserPreferences._accentColorSchemeReadValue( - json, 'accentColorScheme') == - null - ? const SpotubeColor(0xFF2196F3, name: "Blue") - : UserPreferences._accentColorSchemeFromJson( - UserPreferences._accentColorSchemeReadValue( - json, 'accentColorScheme') as Map), - layoutMode: - $enumDecodeNullable(_$LayoutModeEnumMap, json['layoutMode']) ?? - LayoutMode.adaptive, - locale: UserPreferences._localeReadValue(json, 'locale') == null - ? const Locale("system", "system") - : UserPreferences._localeFromJson( - UserPreferences._localeReadValue(json, 'locale') - as Map), - recommendationMarket: - $enumDecodeNullable(_$MarketEnumMap, json['recommendationMarket']) ?? - Market.US, - searchMode: - $enumDecodeNullable(_$SearchModeEnumMap, json['searchMode']) ?? - SearchMode.youtube, - downloadLocation: json['downloadLocation'] as String? ?? "", - localLibraryLocation: (json['localLibraryLocation'] as List?) - ?.map((e) => e as String) - .toList() ?? - const [], - pipedInstance: - json['pipedInstance'] as String? ?? "https://pipedapi.kavin.rocks", - themeMode: $enumDecodeNullable(_$ThemeModeEnumMap, json['themeMode']) ?? - ThemeMode.system, - audioSource: - $enumDecodeNullable(_$AudioSourceEnumMap, json['audioSource']) ?? - AudioSource.youtube, - streamMusicCodec: $enumDecodeNullable( - _$SourceCodecsEnumMap, json['streamMusicCodec']) ?? - SourceCodecs.weba, - downloadMusicCodec: $enumDecodeNullable( - _$SourceCodecsEnumMap, json['downloadMusicCodec']) ?? - SourceCodecs.m4a, - discordPresence: json['discordPresence'] as bool? ?? true, - endlessPlayback: json['endlessPlayback'] as bool? ?? true, - enableConnect: json['enableConnect'] as bool? ?? false, - ); - -Map _$$UserPreferencesImplToJson( - _$UserPreferencesImpl instance) => - { - 'audioQuality': _$SourceQualitiesEnumMap[instance.audioQuality]!, - 'albumColorSync': instance.albumColorSync, - 'amoledDarkTheme': instance.amoledDarkTheme, - 'checkUpdate': instance.checkUpdate, - 'normalizeAudio': instance.normalizeAudio, - 'showSystemTrayIcon': instance.showSystemTrayIcon, - 'skipNonMusic': instance.skipNonMusic, - 'systemTitleBar': instance.systemTitleBar, - 'closeBehavior': _$CloseBehaviorEnumMap[instance.closeBehavior]!, - 'accentColorScheme': - UserPreferences._accentColorSchemeToJson(instance.accentColorScheme), - 'layoutMode': _$LayoutModeEnumMap[instance.layoutMode]!, - 'locale': UserPreferences._localeToJson(instance.locale), - 'recommendationMarket': _$MarketEnumMap[instance.recommendationMarket]!, - 'searchMode': _$SearchModeEnumMap[instance.searchMode]!, - 'downloadLocation': instance.downloadLocation, - 'localLibraryLocation': instance.localLibraryLocation, - 'pipedInstance': instance.pipedInstance, - 'themeMode': _$ThemeModeEnumMap[instance.themeMode]!, - 'audioSource': _$AudioSourceEnumMap[instance.audioSource]!, - 'streamMusicCodec': _$SourceCodecsEnumMap[instance.streamMusicCodec]!, - 'downloadMusicCodec': _$SourceCodecsEnumMap[instance.downloadMusicCodec]!, - 'discordPresence': instance.discordPresence, - 'endlessPlayback': instance.endlessPlayback, - 'enableConnect': instance.enableConnect, - }; - -const _$SourceQualitiesEnumMap = { - SourceQualities.high: 'high', - SourceQualities.medium: 'medium', - SourceQualities.low: 'low', -}; - -const _$CloseBehaviorEnumMap = { - CloseBehavior.minimizeToTray: 'minimizeToTray', - CloseBehavior.close: 'close', -}; - -const _$LayoutModeEnumMap = { - LayoutMode.compact: 'compact', - LayoutMode.extended: 'extended', - LayoutMode.adaptive: 'adaptive', -}; - -const _$MarketEnumMap = { - Market.AD: 'AD', - Market.AE: 'AE', - Market.AF: 'AF', - Market.AG: 'AG', - Market.AI: 'AI', - Market.AL: 'AL', - Market.AM: 'AM', - Market.AO: 'AO', - Market.AQ: 'AQ', - Market.AR: 'AR', - Market.AS: 'AS', - Market.AT: 'AT', - Market.AU: 'AU', - Market.AW: 'AW', - Market.AX: 'AX', - Market.AZ: 'AZ', - Market.BA: 'BA', - Market.BB: 'BB', - Market.BD: 'BD', - Market.BE: 'BE', - Market.BF: 'BF', - Market.BG: 'BG', - Market.BH: 'BH', - Market.BI: 'BI', - Market.BJ: 'BJ', - Market.BL: 'BL', - Market.BM: 'BM', - Market.BN: 'BN', - Market.BO: 'BO', - Market.BQ: 'BQ', - Market.BR: 'BR', - Market.BS: 'BS', - Market.BT: 'BT', - Market.BV: 'BV', - Market.BW: 'BW', - Market.BY: 'BY', - Market.BZ: 'BZ', - Market.CA: 'CA', - Market.CC: 'CC', - Market.CD: 'CD', - Market.CF: 'CF', - Market.CG: 'CG', - Market.CH: 'CH', - Market.CI: 'CI', - Market.CK: 'CK', - Market.CL: 'CL', - Market.CM: 'CM', - Market.CN: 'CN', - Market.CO: 'CO', - Market.CR: 'CR', - Market.CU: 'CU', - Market.CV: 'CV', - Market.CW: 'CW', - Market.CX: 'CX', - Market.CY: 'CY', - Market.CZ: 'CZ', - Market.DE: 'DE', - Market.DJ: 'DJ', - Market.DK: 'DK', - Market.DM: 'DM', - Market.DO: 'DO', - Market.DZ: 'DZ', - Market.EC: 'EC', - Market.EE: 'EE', - Market.EG: 'EG', - Market.EH: 'EH', - Market.ER: 'ER', - Market.ES: 'ES', - Market.ET: 'ET', - Market.FI: 'FI', - Market.FJ: 'FJ', - Market.FK: 'FK', - Market.FM: 'FM', - Market.FO: 'FO', - Market.FR: 'FR', - Market.GA: 'GA', - Market.GB: 'GB', - Market.GD: 'GD', - Market.GE: 'GE', - Market.GF: 'GF', - Market.GG: 'GG', - Market.GH: 'GH', - Market.GI: 'GI', - Market.GL: 'GL', - Market.GM: 'GM', - Market.GN: 'GN', - Market.GP: 'GP', - Market.GQ: 'GQ', - Market.GR: 'GR', - Market.GS: 'GS', - Market.GT: 'GT', - Market.GU: 'GU', - Market.GW: 'GW', - Market.GY: 'GY', - Market.HK: 'HK', - Market.HM: 'HM', - Market.HN: 'HN', - Market.HR: 'HR', - Market.HT: 'HT', - Market.HU: 'HU', - Market.ID: 'ID', - Market.IE: 'IE', - Market.IL: 'IL', - Market.IM: 'IM', - Market.IN: 'IN', - Market.IO: 'IO', - Market.IQ: 'IQ', - Market.IR: 'IR', - Market.IS: 'IS', - Market.IT: 'IT', - Market.JE: 'JE', - Market.JM: 'JM', - Market.JO: 'JO', - Market.JP: 'JP', - Market.KE: 'KE', - Market.KG: 'KG', - Market.KH: 'KH', - Market.KI: 'KI', - Market.KM: 'KM', - Market.KN: 'KN', - Market.KP: 'KP', - Market.KR: 'KR', - Market.KW: 'KW', - Market.KY: 'KY', - Market.KZ: 'KZ', - Market.LA: 'LA', - Market.LB: 'LB', - Market.LC: 'LC', - Market.LI: 'LI', - Market.LK: 'LK', - Market.LR: 'LR', - Market.LS: 'LS', - Market.LT: 'LT', - Market.LU: 'LU', - Market.LV: 'LV', - Market.LY: 'LY', - Market.MA: 'MA', - Market.MC: 'MC', - Market.MD: 'MD', - Market.ME: 'ME', - Market.MF: 'MF', - Market.MG: 'MG', - Market.MH: 'MH', - Market.MK: 'MK', - Market.ML: 'ML', - Market.MM: 'MM', - Market.MN: 'MN', - Market.MO: 'MO', - Market.MP: 'MP', - Market.MQ: 'MQ', - Market.MR: 'MR', - Market.MS: 'MS', - Market.MT: 'MT', - Market.MU: 'MU', - Market.MV: 'MV', - Market.MW: 'MW', - Market.MX: 'MX', - Market.MY: 'MY', - Market.MZ: 'MZ', - Market.NA: 'NA', - Market.NC: 'NC', - Market.NE: 'NE', - Market.NF: 'NF', - Market.NG: 'NG', - Market.NI: 'NI', - Market.NL: 'NL', - Market.NO: 'NO', - Market.NP: 'NP', - Market.NR: 'NR', - Market.NU: 'NU', - Market.NZ: 'NZ', - Market.OM: 'OM', - Market.PA: 'PA', - Market.PE: 'PE', - Market.PF: 'PF', - Market.PG: 'PG', - Market.PH: 'PH', - Market.PK: 'PK', - Market.PL: 'PL', - Market.PM: 'PM', - Market.PN: 'PN', - Market.PR: 'PR', - Market.PS: 'PS', - Market.PT: 'PT', - Market.PW: 'PW', - Market.PY: 'PY', - Market.QA: 'QA', - Market.RE: 'RE', - Market.RO: 'RO', - Market.RS: 'RS', - Market.RU: 'RU', - Market.RW: 'RW', - Market.SA: 'SA', - Market.SB: 'SB', - Market.SC: 'SC', - Market.SD: 'SD', - Market.SE: 'SE', - Market.SG: 'SG', - Market.SH: 'SH', - Market.SI: 'SI', - Market.SJ: 'SJ', - Market.SK: 'SK', - Market.SL: 'SL', - Market.SM: 'SM', - Market.SN: 'SN', - Market.SO: 'SO', - Market.SR: 'SR', - Market.SS: 'SS', - Market.ST: 'ST', - Market.SV: 'SV', - Market.SX: 'SX', - Market.SY: 'SY', - Market.SZ: 'SZ', - Market.TC: 'TC', - Market.TD: 'TD', - Market.TF: 'TF', - Market.TG: 'TG', - Market.TH: 'TH', - Market.TJ: 'TJ', - Market.TK: 'TK', - Market.TL: 'TL', - Market.TM: 'TM', - Market.TN: 'TN', - Market.TO: 'TO', - Market.TR: 'TR', - Market.TT: 'TT', - Market.TV: 'TV', - Market.TW: 'TW', - Market.TZ: 'TZ', - Market.UA: 'UA', - Market.UG: 'UG', - Market.UM: 'UM', - Market.US: 'US', - Market.UY: 'UY', - Market.UZ: 'UZ', - Market.VA: 'VA', - Market.VC: 'VC', - Market.VE: 'VE', - Market.VG: 'VG', - Market.VI: 'VI', - Market.VN: 'VN', - Market.VU: 'VU', - Market.WF: 'WF', - Market.WS: 'WS', - Market.XK: 'XK', - Market.YE: 'YE', - Market.YT: 'YT', - Market.ZA: 'ZA', - Market.ZM: 'ZM', - Market.ZW: 'ZW', -}; - -const _$SearchModeEnumMap = { - SearchMode.youtube: 'youtube', - SearchMode.youtubeMusic: 'youtubeMusic', -}; - -const _$ThemeModeEnumMap = { - ThemeMode.system: 'system', - ThemeMode.light: 'light', - ThemeMode.dark: 'dark', -}; - -const _$AudioSourceEnumMap = { - AudioSource.youtube: 'youtube', - AudioSource.piped: 'piped', - AudioSource.jiosaavn: 'jiosaavn', -}; - -const _$SourceCodecsEnumMap = { - SourceCodecs.m4a: 'm4a', - SourceCodecs.weba: 'weba', -}; - -_$PlaybackHistoryPlaylistImpl _$$PlaybackHistoryPlaylistImplFromJson( - Map json) => - _$PlaybackHistoryPlaylistImpl( - date: DateTime.parse(json['date'] as String), - playlist: PlaylistSimple.fromJson( - Map.from(json['playlist'] as Map)), - $type: json['runtimeType'] as String?, - ); - -Map _$$PlaybackHistoryPlaylistImplToJson( - _$PlaybackHistoryPlaylistImpl instance) => - { - 'date': instance.date.toIso8601String(), - 'playlist': instance.playlist.toJson(), - 'runtimeType': instance.$type, - }; - -_$PlaybackHistoryAlbumImpl _$$PlaybackHistoryAlbumImplFromJson(Map json) => - _$PlaybackHistoryAlbumImpl( - date: DateTime.parse(json['date'] as String), - album: - AlbumSimple.fromJson(Map.from(json['album'] as Map)), - $type: json['runtimeType'] as String?, - ); - -Map _$$PlaybackHistoryAlbumImplToJson( - _$PlaybackHistoryAlbumImpl instance) => - { - 'date': instance.date.toIso8601String(), - 'album': instance.album.toJson(), - 'runtimeType': instance.$type, - }; - -_$PlaybackHistoryTrackImpl _$$PlaybackHistoryTrackImplFromJson(Map json) => - _$PlaybackHistoryTrackImpl( - date: DateTime.parse(json['date'] as String), - track: Track.fromJson(Map.from(json['track'] as Map)), - $type: json['runtimeType'] as String?, - ); - -Map _$$PlaybackHistoryTrackImplToJson( - _$PlaybackHistoryTrackImpl instance) => - { - 'date': instance.date.toIso8601String(), - 'track': instance.track.toJson(), - 'runtimeType': instance.$type, - }; diff --git a/lib/utils/migrations/cache_box.dart b/lib/utils/migrations/cache_box.dart deleted file mode 100644 index dfe1947b..00000000 --- a/lib/utils/migrations/cache_box.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'dart:convert'; - -import 'package:hive/hive.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:spotube/provider/spotify/utils/json_cast.dart'; -import 'package:spotube/services/kv_store/encrypted_kv_store.dart'; -import 'package:spotube/utils/platform.dart'; -import 'package:spotube/utils/primitive_utils.dart'; - -const kKeyBoxName = "spotube_box_name"; -const kNoEncryptionWarningShownKey = "showedNoEncryptionWarning"; -const kIsUsingEncryption = "isUsingEncryption"; -String getBoxKey(String boxName) => "spotube_box_$boxName"; - -class PersistenceCacheBox { - static late LazyBox _box; - static late LazyBox _encryptedBox; - - final String cacheKey; - final bool encrypted; - - final T Function(Map) fromJson; - - PersistenceCacheBox( - this.cacheKey, { - required this.fromJson, - this.encrypted = false, - }); - - static Future read(String key) async { - final localStorage = await SharedPreferences.getInstance(); - if (kIsMacOS || kIsIOS || (kIsLinux && !kIsFlatpak)) { - return localStorage.getString(key); - } - - try { - await localStorage.setBool(kIsUsingEncryption, true); - return await EncryptedKvStoreService.storage.read(key: key); - } catch (e) { - await localStorage.setBool(kIsUsingEncryption, false); - return localStorage.getString(key); - } - } - - static Future write(String key, String value) async { - final localStorage = await SharedPreferences.getInstance(); - if (kIsMacOS || kIsIOS || (kIsLinux && !kIsFlatpak)) { - await localStorage.setString(key, value); - return; - } - - try { - await localStorage.setBool(kIsUsingEncryption, true); - await EncryptedKvStoreService.storage.write(key: key, value: value); - } catch (e) { - await localStorage.setBool(kIsUsingEncryption, false); - await localStorage.setString(key, value); - } - } - - static Future initializeBoxes({required String? path}) async { - String? boxName = await read(kKeyBoxName); - - if (boxName == null) { - boxName = "spotube-${PrimitiveUtils.uuid.v4()}"; - await write(kKeyBoxName, boxName); - } - - String? encryptionKey = await read(getBoxKey(boxName)); - - if (encryptionKey == null) { - encryptionKey = base64Url.encode(Hive.generateSecureKey()); - await write(getBoxKey(boxName), encryptionKey); - } - - _encryptedBox = await Hive.openLazyBox( - boxName, - encryptionCipher: HiveAesCipher(base64Url.decode(encryptionKey)), - ); - - _box = await Hive.openLazyBox( - "spotube_cache", - path: path, - ); - } - - LazyBox get box => encrypted ? _encryptedBox : _box; - - Future getData() async { - final json = await box.get(cacheKey); - - if (json != null || - (json is Map && json.entries.isNotEmpty) || - (json is List && json.isNotEmpty)) { - return fromJson(castNestedJson(json)); - } - - return null; - } -} diff --git a/pubspec.lock b/pubspec.lock index 46ed96d6..91ca8765 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -334,14 +334,6 @@ packages: url: "https://pub.dev" source: hosted version: "8.9.2" - buttons_tabbar: - dependency: "direct main" - description: - name: buttons_tabbar - sha256: "6e541377ab96d4223d8f072bc4f35c9d32dafe042005cad93530e0cd9d02801f" - url: "https://pub.dev" - source: hosted - version: "1.3.14" cached_network_image: dependency: "direct main" description: @@ -486,14 +478,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" - curved_navigation_bar: - dependency: "direct main" - description: - name: curved_navigation_bar - sha256: bb4ab128fcb6f4a9f0f1f72d227db531818b20218984789777f049fcbf919279 - url: "https://pub.dev" - source: hosted - version: "1.0.6" dart_des: dependency: transitive description: @@ -1025,7 +1009,7 @@ packages: source: hosted version: "1.1.1" flutter_svg: - dependency: "direct main" + dependency: transitive description: name: flutter_svg sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" @@ -1892,14 +1876,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" - popover: - dependency: "direct main" - description: - name: popover - sha256: "0606f3e10f92fc0459f5c52fd917738c29e7552323b28694d50c2d3312d0e1a2" - url: "https://pub.dev" - source: hosted - version: "0.3.1" posix: dependency: transitive description: @@ -2149,14 +2125,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.2" - sidebarx: - dependency: "direct main" - description: - name: sidebarx - sha256: abe39d6db237fb8e25c600e8039ffab80fa7fe71acab03e9c378c31f912d2766 - url: "https://pub.dev" - source: hosted - version: "0.17.1" simple_icons: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index e1b1ada3..25ccd41c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,10 +21,8 @@ dependencies: audio_session: ^0.1.19 auto_size_text: ^3.0.0 bonsoir: ^5.1.10 - buttons_tabbar: ^1.3.8 cached_network_image: ^3.3.1 collection: ^1.18.0 - curved_navigation_bar: ^1.0.3 desktop_webview_window: git: path: packages/desktop_webview_window @@ -62,7 +60,6 @@ dependencies: flutter_riverpod: ^2.5.1 flutter_secure_storage: ^9.0.0 flutter_sharing_intent: ^1.1.0 - flutter_svg: ^1.1.6 form_validator: ^2.1.1 freezed_annotation: ^2.4.1 fuzzywuzzy: ^1.1.6 @@ -95,7 +92,6 @@ dependencies: path_provider: ^2.1.3 permission_handler: ^11.3.1 piped_client: ^0.1.1 - popover: ^0.3.0 riverpod: ^2.5.1 scrobblenaut: git: @@ -107,7 +103,6 @@ dependencies: shelf: ^1.4.1 shelf_router: ^1.1.4 shelf_web_socket: ^2.0.0 - sidebarx: ^0.17.1 simple_icons: ^10.1.3 skeletonizer: ^1.1.1 sliver_tools: ^0.2.12 From a6720d53925bfde2c1925fe040fcebf1256ace63 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 22 Dec 2024 14:48:48 +0600 Subject: [PATCH 14/81] feat: grid/list customizable playbutton view --- lib/collections/spotube_icons.dart | 2 + .../adaptive/adaptive_pop_sheet_list.dart | 8 +- lib/components/button/back_button.dart | 10 +- .../horizontal_playbutton_card_view.dart | 20 +- .../playbutton_card.dart | 60 +++-- .../playbutton_view/playbutton_tile.dart | 92 ++++++++ .../playbutton_view/playbutton_view.dart | 157 +++++++++++++ lib/l10n/app_en.arb | 3 +- lib/modules/album/album_card.dart | 193 +++++++++------- lib/modules/library/user_albums.dart | 46 +--- lib/modules/library/user_playlists.dart | 44 +--- lib/modules/player/player_actions.dart | 8 +- lib/modules/player/player_controls.dart | 43 ++-- lib/modules/player/player_queue.dart | 3 +- lib/modules/playlist/playlist_card.dart | 209 +++++++++++------- lib/modules/root/bottom_player.dart | 3 +- lib/pages/home/feed/feed_section.dart | 78 ++++--- lib/pages/home/genres/genre_playlists.dart | 193 +++++++--------- untranslated_messages.json | 106 ++++++++- 19 files changed, 849 insertions(+), 429 deletions(-) rename lib/components/{ => playbutton_view}/playbutton_card.dart (64%) create mode 100644 lib/components/playbutton_view/playbutton_tile.dart create mode 100644 lib/components/playbutton_view/playbutton_view.dart diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index ff7092e3..9239875e 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -130,4 +130,6 @@ abstract class SpotubeIcons { static const open = FeatherIcons.externalLink; static const radioChecked = Icons.radio_button_on_rounded; static const radioUnchecked = Icons.radio_button_off_rounded; + static const grid = FeatherIcons.grid; + static const list = FeatherIcons.list; } diff --git a/lib/components/adaptive/adaptive_pop_sheet_list.dart b/lib/components/adaptive/adaptive_pop_sheet_list.dart index 5345199e..fa72031e 100644 --- a/lib/components/adaptive/adaptive_pop_sheet_list.dart +++ b/lib/components/adaptive/adaptive_pop_sheet_list.dart @@ -139,7 +139,9 @@ class AdaptivePopSheetList extends StatelessWidget { if (mediaQuery.mdAndUp) { return Tooltip( - tooltip: Text(tooltip ?? ''), + tooltip: TooltipContainer( + child: Text(tooltip ?? ''), + ), child: IconButton.ghost( icon: icon ?? const Icon(SpotubeIcons.moreVertical), onPressed: () { @@ -162,7 +164,7 @@ class AdaptivePopSheetList extends StatelessWidget { if (child != null) { return Tooltip( - tooltip: Text(tooltip ?? ''), + tooltip: TooltipContainer(child: Text(tooltip ?? '')), child: Button( onPressed: () => showDropdownMenu(context, Offset.zero), style: const ButtonStyle.ghost(), @@ -172,7 +174,7 @@ class AdaptivePopSheetList extends StatelessWidget { } return Tooltip( - tooltip: Text(tooltip ?? ''), + tooltip: TooltipContainer(child: Text(tooltip ?? '')), child: IconButton.ghost( icon: icon ?? const Icon(SpotubeIcons.moreVertical), onPressed: () => showDropdownMenu(context, Offset.zero), diff --git a/lib/components/button/back_button.dart b/lib/components/button/back_button.dart index 41b7d527..17b93cea 100644 --- a/lib/components/button/back_button.dart +++ b/lib/components/button/back_button.dart @@ -2,13 +2,19 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; class BackButton extends StatelessWidget { - const BackButton({super.key}); + final Color? color; + const BackButton({ + super.key, + this.color, + }); @override Widget build(BuildContext context) { return IconButton.ghost( size: const ButtonSize(.9), - icon: const Icon(SpotubeIcons.angleLeft), + icon: color != null + ? Icon(SpotubeIcons.angleLeft, color: color) + : const Icon(SpotubeIcons.angleLeft), onPressed: () => Navigator.of(context).pop(), ); } diff --git a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart index 31c6a37c..0ebebea7 100644 --- a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart +++ b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart @@ -9,7 +9,6 @@ import 'package:spotube/collections/fake.dart'; import 'package:spotube/modules/album/album_card.dart'; import 'package:spotube/modules/artist/artist_card.dart'; import 'package:spotube/modules/playlist/playlist_card.dart'; -import 'package:spotube/hooks/utils/use_breakpoint_value.dart'; import 'package:very_good_infinite_list/very_good_infinite_list.dart'; class HorizontalPlaybuttonCardView extends HookWidget { @@ -38,12 +37,7 @@ class HorizontalPlaybuttonCardView extends HookWidget { @override Widget build(BuildContext context) { final scrollController = useScrollController(); - final height = useBreakpointValue( - xs: 226, - sm: 226, - md: 236, - others: 266, - ); + final isArtist = items.every((s) => s is Artist); return Padding( padding: const EdgeInsets.all(8.0), @@ -64,7 +58,7 @@ class HorizontalPlaybuttonCardView extends HookWidget { ], ), SizedBox( - height: height, + height: isArtist ? 250 : 225, child: NotificationListener( // disable multiple scrollbar to use this onNotification: (notification) => true, @@ -88,7 +82,9 @@ class HorizontalPlaybuttonCardView extends HookWidget { onFetchData: onFetchMore, loadingBuilder: (context) => Skeletonizer( enabled: true, - child: AlbumCard(FakeData.albumSimple), + child: isArtist + ? ArtistCard(FakeData.artist) + : AlbumCard(FakeData.albumSimple), ), isLoading: isLoadingNextPage, hasReachedMax: !hasNextPage, @@ -100,11 +96,7 @@ class HorizontalPlaybuttonCardView extends HookWidget { PlaylistSimple() => PlaylistCard(item as PlaylistSimple), AlbumSimple() => AlbumCard(item as AlbumSimple), - Artist() => Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12.0), - child: ArtistCard(item as Artist), - ), + Artist() => ArtistCard(item as Artist), _ => const SizedBox.shrink(), }; }), diff --git a/lib/components/playbutton_card.dart b/lib/components/playbutton_view/playbutton_card.dart similarity index 64% rename from lib/components/playbutton_card.dart rename to lib/components/playbutton_view/playbutton_card.dart index 31143ae8..849bab2a 100644 --- a/lib/components/playbutton_card.dart +++ b/lib/components/playbutton_view/playbutton_card.dart @@ -1,17 +1,15 @@ -import 'package:flutter_hooks/flutter_hooks.dart'; - import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/string.dart'; import 'package:spotube/utils/platform.dart'; -class PlaybuttonCard extends HookWidget { +class PlaybuttonCard extends StatelessWidget { final void Function()? onTap; final void Function()? onPlaybuttonPressed; final void Function()? onAddToQueuePressed; final String? description; - final EdgeInsetsGeometry? margin; + final String imageUrl; final bool isPlaying; final bool isLoading; @@ -23,7 +21,6 @@ class PlaybuttonCard extends HookWidget { required this.isPlaying, required this.isLoading, required this.title, - this.margin, this.description, this.onPlaybuttonPressed, this.onAddToQueuePressed, @@ -56,15 +53,18 @@ class PlaybuttonCard extends HookWidget { AnimatedScale( curve: Curves.easeOutBack, duration: const Duration(milliseconds: 300), - scale: states.contains(WidgetState.hovered) || kIsMobile + scale: (states.contains(WidgetState.hovered) || + kIsMobile) && + !isLoading ? 1 : 0.7, child: AnimatedOpacity( duration: const Duration(milliseconds: 300), - opacity: - states.contains(WidgetState.hovered) || kIsMobile - ? 1 - : 0, + opacity: (states.contains(WidgetState.hovered) || + kIsMobile) && + !isLoading + ? 1 + : 0, child: IconButton.secondary( icon: const Icon(SpotubeIcons.queueAdd), onPressed: onAddToQueuePressed, @@ -76,17 +76,29 @@ class PlaybuttonCard extends HookWidget { AnimatedScale( curve: Curves.easeOutBack, duration: const Duration(milliseconds: 150), - scale: states.contains(WidgetState.hovered) || kIsMobile + scale: states.contains(WidgetState.hovered) || + kIsMobile || + isPlaying || + isLoading ? 1 : 0.7, child: AnimatedOpacity( duration: const Duration(milliseconds: 150), - opacity: - states.contains(WidgetState.hovered) || kIsMobile - ? 1 - : 0, + opacity: states.contains(WidgetState.hovered) || + kIsMobile || + isPlaying || + isLoading + ? 1 + : 0, child: IconButton.secondary( - icon: const Icon(SpotubeIcons.play), + icon: switch ((isLoading, isPlaying)) { + (true, _) => const CircularProgressIndicator( + size: 15, + ), + (false, false) => const Icon(SpotubeIcons.play), + (false, true) => const Icon(SpotubeIcons.pause) + }, + enabled: !isLoading, onPressed: onPlaybuttonPressed, size: ButtonSize.small, ), @@ -96,11 +108,23 @@ class PlaybuttonCard extends HookWidget { ), ); }, - ) + ), + if (isOwner) + const Positioned( + right: 5, + top: 5, + child: SecondaryBadge( + style: ButtonStyle.secondaryIcon( + shape: ButtonShape.circle, + size: ButtonSize.small, + ), + child: Icon(SpotubeIcons.user), + ), + ), ], ), title: Tooltip( - tooltip: Text(title), + tooltip: TooltipContainer(child: Text(title)), child: Text( title, maxLines: 1, diff --git a/lib/components/playbutton_view/playbutton_tile.dart b/lib/components/playbutton_view/playbutton_tile.dart new file mode 100644 index 00000000..3f9d89fe --- /dev/null +++ b/lib/components/playbutton_view/playbutton_tile.dart @@ -0,0 +1,92 @@ +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/image/universal_image.dart'; +import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/string.dart'; + +class PlaybuttonTile extends StatelessWidget { + final void Function()? onTap; + final void Function()? onPlaybuttonPressed; + final void Function()? onAddToQueuePressed; + final String? description; + + final String imageUrl; + final bool isPlaying; + final bool isLoading; + final String title; + final bool isOwner; + + const PlaybuttonTile({ + required this.imageUrl, + required this.isPlaying, + required this.isLoading, + required this.title, + this.description, + this.onPlaybuttonPressed, + this.onAddToQueuePressed, + this.onTap, + this.isOwner = false, + super.key, + }); + + @override + Widget build(BuildContext context) { + final cleanDescription = description?.unescapeHtml().cleanHtml() ?? ""; + + return Button.ghost( + leading: ClipRRect( + borderRadius: context.theme.borderRadiusMd, + child: UniversalImage( + path: imageUrl, + width: 40, + height: 40, + fit: BoxFit.cover, + ), + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Tooltip( + tooltip: TooltipContainer(child: Text(context.l10n.add_to_queue)), + child: IconButton.outline( + icon: const Icon(SpotubeIcons.queueAdd), + onPressed: onAddToQueuePressed, + enabled: !isLoading, + ), + ), + const Gap(8), + Tooltip( + tooltip: TooltipContainer(child: Text(context.l10n.play)), + child: IconButton.secondary( + icon: switch ((isLoading, isPlaying)) { + (true, _) => const CircularProgressIndicator( + size: 22, + ), + (false, false) => const Icon(SpotubeIcons.play), + (false, true) => const Icon(SpotubeIcons.pause) + }, + onPressed: onPlaybuttonPressed, + enabled: !isLoading, + ), + ), + ], + ), + enabled: !isLoading, + onPressed: onTap, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title), + if (cleanDescription.isNotEmpty) + Text( + description!, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ).xSmall().muted(), + ], + ), + ); + } +} diff --git a/lib/components/playbutton_view/playbutton_view.dart b/lib/components/playbutton_view/playbutton_view.dart new file mode 100644 index 00000000..52cfb592 --- /dev/null +++ b/lib/components/playbutton_view/playbutton_view.dart @@ -0,0 +1,157 @@ +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:skeletonizer/skeletonizer.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/playbutton_view/playbutton_card.dart'; +import 'package:spotube/components/playbutton_view/playbutton_tile.dart'; +import 'package:spotube/components/waypoint.dart'; +import 'package:spotube/extensions/constrains.dart'; +import 'package:very_good_infinite_list/very_good_infinite_list.dart'; + +const _dummyPlaybuttonCard = PlaybuttonCard( + imageUrl: 'https://placehold.co/150x150.png', + isLoading: false, + isPlaying: false, + title: "Playbutton", + description: "A really cool playbutton", + isOwner: false, +); + +const _dummyPlaybuttonTile = PlaybuttonTile( + imageUrl: 'https://placehold.co/150x150.png', + isLoading: false, + isPlaying: false, + title: "Playbutton", + description: "A really cool playbutton", + isOwner: false, +); + +/// A [PlaybuttonCard] grid/list view (selectable) sliver widget +/// with support for infinite scrolling +class PlaybuttonView extends StatelessWidget { + final int itemCount; + final Widget Function(BuildContext context, int index) gridItemBuilder; + final Widget Function(BuildContext context, int index) listItemBuilder; + final bool hasMore; + final bool isLoading; + final VoidCallback onRequestMore; + final ScrollController controller; + + const PlaybuttonView({ + super.key, + required this.itemCount, + required this.gridItemBuilder, + required this.listItemBuilder, + required this.hasMore, + required this.isLoading, + required this.onRequestMore, + required this.controller, + }); + + @override + Widget build(BuildContext context) { + return SliverLayoutBuilder( + builder: (context, constrains) => HookBuilder(builder: (context) { + final isGrid = useState(constrains.mdAndUp); + final hasUserInteracted = useRef(false); + + useEffect(() { + if (hasUserInteracted.value) return null; + if (isGrid.value != constrains.mdAndUp) { + isGrid.value = constrains.mdAndUp; + } + return null; + }, [constrains]); + + return SliverMainAxisGroup( + slivers: [ + SliverToBoxAdapter( + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Toggle( + value: isGrid.value, + style: + const ButtonStyle.outline(density: ButtonDensity.icon), + onChanged: (value) { + isGrid.value = value; + hasUserInteracted.value = true; + }, + child: const Icon(SpotubeIcons.grid), + ), + const SizedBox(width: 8), + Toggle( + value: !isGrid.value, + style: + const ButtonStyle.outline(density: ButtonDensity.icon), + onChanged: (value) { + isGrid.value = !value; + hasUserInteracted.value = true; + }, + child: const Icon(SpotubeIcons.list), + ), + ], + ), + ), + const SliverGap(10), + // Toggle between grid and list view + switch ((isGrid.value, isLoading)) { + (true, _) => SliverGrid.builder( + itemCount: isLoading ? 6 : itemCount + 1, + gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 150, + mainAxisExtent: 225, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + ), + itemBuilder: (context, index) { + if (isLoading) { + return const Skeletonizer( + enabled: true, + child: _dummyPlaybuttonCard, + ); + } + + if (index == itemCount) { + if (!hasMore) return const SizedBox.shrink(); + return Waypoint( + controller: controller, + isGrid: true, + onTouchEdge: onRequestMore, + child: const Skeletonizer( + enabled: true, + child: _dummyPlaybuttonCard, + ), + ); + } + + return gridItemBuilder(context, index); + }, + ), + (false, true) => Skeletonizer.sliver( + enabled: true, + child: SliverList( + delegate: SliverChildBuilderDelegate( + (context, index) => _dummyPlaybuttonTile, + childCount: 6, + ), + ), + ), + (false, false) => SliverInfiniteList( + itemCount: itemCount, + loadingBuilder: (context) => const Skeletonizer( + enabled: true, + child: _dummyPlaybuttonTile, + ), + itemBuilder: listItemBuilder, + onFetchData: onRequestMore, + hasReachedMax: !hasMore, + isLoading: isLoading, + ), + } + ], + ); + }), + ); + } +} diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f949480e..5b9e5183 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -401,5 +401,6 @@ "export_cache_files": "Export Cached Files", "found_n_files": "Found {count} files", "export_cache_confirmation": "Do you want to export these files to", - "exported_n_out_of_m_files": "Exported {filesExported} out of {files} files" + "exported_n_out_of_m_files": "Exported {filesExported} out of {files} files", + "undo": "Undo" } \ No newline at end of file diff --git a/lib/modules/album/album_card.dart b/lib/modules/album/album_card.dart index dd914fad..86935698 100644 --- a/lib/modules/album/album_card.dart +++ b/lib/modules/album/album_card.dart @@ -1,9 +1,10 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/dialogs/select_device_dialog.dart'; -import 'package:spotube/components/playbutton_card.dart'; +import 'package:spotube/components/playbutton_view/playbutton_card.dart'; +import 'package:spotube/components/playbutton_view/playbutton_tile.dart'; import 'package:spotube/extensions/artist_simple.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; @@ -24,10 +25,16 @@ extension FormattedAlbumType on AlbumType { class AlbumCard extends HookConsumerWidget { final AlbumSimple album; + final bool _isTile; const AlbumCard( this.album, { super.key, - }); + }) : _isTile = false; + + const AlbumCard.tile( + this.album, { + super.key, + }) : _isTile = true; @override Widget build(BuildContext context, ref) { @@ -45,8 +52,6 @@ class AlbumCard extends HookConsumerWidget { final updating = useState(false); - final scaffoldMessenger = ScaffoldMessenger.maybeOf(context); - Future> fetchAllTrack() async { if (album.tracks != null && album.tracks!.isNotEmpty) { return album.tracks!.map((track) => track.asTrack(album)).toList(); @@ -55,88 +60,116 @@ class AlbumCard extends HookConsumerWidget { return ref.read(albumTracksProvider(album).notifier).fetchAll(); } - return PlaybuttonCard( - imageUrl: album.images.asUrlString( - placeholder: ImagePlaceholder.collection, - ), - margin: const EdgeInsets.symmetric(horizontal: 10), - isPlaying: isPlaylistPlaying, - isLoading: - (isPlaylistPlaying && isFetchingActiveTrack) || updating.value, - title: album.name!, - description: - "${album.albumType?.formatted} • ${album.artists?.asString() ?? ""}", - onTap: () { - ServiceUtils.pushNamed( - context, - AlbumPage.name, - pathParameters: { - "id": album.id!, - }, - extra: album, + var imageUrl = album.images.asUrlString( + placeholder: ImagePlaceholder.collection, + ); + var isLoading = + (isPlaylistPlaying && isFetchingActiveTrack) || updating.value; + var description = + "${album.albumType?.formatted} • ${album.artists?.asString() ?? ""}"; + + void onTap() { + ServiceUtils.pushNamed( + context, + AlbumPage.name, + pathParameters: { + "id": album.id!, + }, + extra: album, + ); + } + + void onPlaybuttonPressed() async { + updating.value = true; + try { + if (isPlaylistPlaying) { + return playing ? audioPlayer.pause() : audioPlayer.resume(); + } + + final fetchedTracks = await fetchAllTrack(); + + if (fetchedTracks.isEmpty || !context.mounted) return; + + final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice) { + final remotePlayback = ref.read(connectProvider.notifier); + await remotePlayback.load( + WebSocketLoadEventData.album( + tracks: fetchedTracks, + collection: album, + ), ); - }, - onPlaybuttonPressed: () async { - updating.value = true; - try { - if (isPlaylistPlaying) { - return playing ? audioPlayer.pause() : audioPlayer.resume(); - } + } else { + await playlistNotifier.load(fetchedTracks, autoPlay: true); + playlistNotifier.addCollection(album.id!); + historyNotifier.addAlbums([album]); + } + } finally { + updating.value = false; + } + } - final fetchedTracks = await fetchAllTrack(); + void onAddToQueuePressed() async { + if (isPlaylistPlaying) { + return; + } - if (fetchedTracks.isEmpty || !context.mounted) return; + updating.value = true; + try { + final fetchedTracks = await fetchAllTrack(); - final isRemoteDevice = await showSelectDeviceDialog(context, ref); - if (isRemoteDevice) { - final remotePlayback = ref.read(connectProvider.notifier); - await remotePlayback.load( - WebSocketLoadEventData.album( - tracks: fetchedTracks, - collection: album, + if (fetchedTracks.isEmpty) return; + playlistNotifier.addTracks(fetchedTracks); + playlistNotifier.addCollection(album.id!); + historyNotifier.addAlbums([album]); + if (context.mounted) { + showToast( + context: context, + builder: (context, overlay) { + return SurfaceCard( + child: Basic( + content: Text( + context.l10n.added_to_queue(fetchedTracks.length), + ), + trailing: Button.outline( + child: Text(context.l10n.undo), + onPressed: () { + playlistNotifier + .removeTracks(fetchedTracks.map((e) => e.id!)); + }, + ), ), ); - } else { - await playlistNotifier.load(fetchedTracks, autoPlay: true); - playlistNotifier.addCollection(album.id!); - historyNotifier.addAlbums([album]); - } - } finally { - updating.value = false; - } - }, - onAddToQueuePressed: () async { - if (isPlaylistPlaying) { - return; - } + }, + ); + } + } finally { + updating.value = false; + } + } - updating.value = true; - try { - final fetchedTracks = await fetchAllTrack(); + if (_isTile) { + return PlaybuttonTile( + imageUrl: imageUrl, + isPlaying: isPlaylistPlaying, + isLoading: isLoading, + title: album.name!, + description: description, + onTap: onTap, + onPlaybuttonPressed: onPlaybuttonPressed, + onAddToQueuePressed: onAddToQueuePressed, + ); + } - if (fetchedTracks.isEmpty) return; - playlistNotifier.addTracks(fetchedTracks); - playlistNotifier.addCollection(album.id!); - historyNotifier.addAlbums([album]); - if (context.mounted) { - final snackbar = SnackBar( - content: Text( - context.l10n.added_to_queue(fetchedTracks.length), - ), - action: SnackBarAction( - label: "Undo", - onPressed: () { - playlistNotifier - .removeTracks(fetchedTracks.map((e) => e.id!)); - }, - ), - ); - - scaffoldMessenger?.showSnackBar(snackbar); - } - } finally { - updating.value = false; - } - }); + return PlaybuttonCard( + imageUrl: imageUrl, + isPlaying: isPlaylistPlaying, + isLoading: isLoading, + title: album.name!, + description: description, + onTap: onTap, + onPlaybuttonPressed: onPlaybuttonPressed, + onAddToQueuePressed: onAddToQueuePressed, + ); } } diff --git a/lib/modules/library/user_albums.dart b/lib/modules/library/user_albums.dart index 535381fc..a388c0ad 100644 --- a/lib/modules/library/user_albums.dart +++ b/lib/modules/library/user_albums.dart @@ -4,14 +4,12 @@ import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:skeletonizer/skeletonizer.dart'; -import 'package:spotube/collections/fake.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/playbutton_view/playbutton_view.dart'; import 'package:spotube/modules/album/album_card.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/fallbacks/anonymous_fallback.dart'; -import 'package:spotube/components/waypoint.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -78,39 +76,17 @@ class UserAlbums extends HookConsumerWidget { const SliverGap(10), SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 8), - sliver: SliverGrid.builder( - itemCount: albums.isEmpty ? 6 : albums.length + 1, - gridDelegate: - const SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 150, - mainAxisExtent: 225, - crossAxisSpacing: 8, - mainAxisSpacing: 8, + sliver: PlaybuttonView( + controller: controller, + itemCount: albums.length, + hasMore: albumsQuery.asData?.value.hasMore == true, + isLoading: albumsQuery.isLoading, + onRequestMore: albumsQueryNotifier.fetchMore, + gridItemBuilder: (context, index) => AlbumCard( + albums[index], ), - itemBuilder: (context, index) { - if (albums.isNotEmpty && index == albums.length) { - if (albumsQuery.asData?.value.hasMore != true) { - return const SizedBox.shrink(); - } - - return Waypoint( - controller: controller, - isGrid: true, - onTouchEdge: albumsQueryNotifier.fetchMore, - child: Skeletonizer( - enabled: true, - child: AlbumCard(FakeData.albumSimple), - ), - ); - } - - return Skeletonizer( - enabled: albumsQuery.isLoading, - child: AlbumCard( - albums.elementAtOrNull(index) ?? FakeData.albumSimple, - ), - ); - }, + listItemBuilder: (context, index) => + AlbumCard.tile(albums[index]), ), ), ], diff --git a/lib/modules/library/user_playlists.dart b/lib/modules/library/user_playlists.dart index 0f307894..2a2d65e0 100644 --- a/lib/modules/library/user_playlists.dart +++ b/lib/modules/library/user_playlists.dart @@ -5,16 +5,14 @@ import 'package:collection/collection.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' hide Image; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; -import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/collections/fake.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/playbutton_view/playbutton_view.dart'; import 'package:spotube/modules/playlist/playlist_create_dialog.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/fallbacks/anonymous_fallback.dart'; import 'package:spotube/modules/playlist/playlist_card.dart'; -import 'package:spotube/components/waypoint.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/library/playlist_generate/playlist_generate.dart'; import 'package:spotube/provider/authentication/authentication.dart'; @@ -127,35 +125,17 @@ class UserPlaylists extends HookConsumerWidget { const SliverGap(10), SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 8), - sliver: SliverGrid.builder( - itemCount: playlists.isEmpty ? 6 : playlists.length + 1, - gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 150, - mainAxisExtent: 225, - crossAxisSpacing: 8, - mainAxisSpacing: 8, - ), - itemBuilder: (context, index) { - if (playlists.isNotEmpty && index == playlists.length) { - if (playlistsQuery.asData?.value.hasMore != true) { - return const SizedBox.shrink(); - } - - return Waypoint( - controller: controller, - isGrid: true, - onTouchEdge: playlistsQueryNotifier.fetchMore, - child: Skeletonizer( - enabled: true, - child: PlaylistCard(FakeData.playlistSimple), - ), - ); - } - - return PlaylistCard( - playlists.elementAtOrNull(index) ?? - FakeData.playlistSimple, - ); + sliver: PlaybuttonView( + controller: controller, + hasMore: playlistsQuery.asData?.value.hasMore == true, + isLoading: playlistsQuery.isLoading, + onRequestMore: playlistsQueryNotifier.fetchMore, + itemCount: playlists.length, + gridItemBuilder: (context, index) { + return PlaylistCard(playlists[index]); + }, + listItemBuilder: (context, index) { + return PlaylistCard.tile(playlists[index]); }, ), ), diff --git a/lib/modules/player/player_actions.dart b/lib/modules/player/player_actions.dart index dbdfa11b..5b469510 100644 --- a/lib/modules/player/player_actions.dart +++ b/lib/modules/player/player_actions.dart @@ -79,7 +79,7 @@ class PlayerActions extends HookConsumerWidget { children: [ if (showQueue) Tooltip( - tooltip: Text(context.l10n.queue), + tooltip: TooltipContainer(child: Text(context.l10n.queue)), child: IconButton.ghost( icon: const Icon(SpotubeIcons.queue), enabled: playlist.activeTrack != null, @@ -115,7 +115,8 @@ class PlayerActions extends HookConsumerWidget { ), if (!isLocalTrack) Tooltip( - tooltip: Text(context.l10n.alternative_track_sources), + tooltip: TooltipContainer( + child: Text(context.l10n.alternative_track_sources)), child: IconButton.ghost( icon: const Icon(SpotubeIcons.alternativeRoute), onPressed: playlist.activeTrack != null @@ -147,7 +148,8 @@ class PlayerActions extends HookConsumerWidget { ) else Tooltip( - tooltip: Text(context.l10n.download_track), + tooltip: + TooltipContainer(child: Text(context.l10n.download_track)), child: IconButton.ghost( icon: Icon( isDownloaded ? SpotubeIcons.done : SpotubeIcons.download, diff --git a/lib/modules/player/player_controls.dart b/lib/modules/player/player_controls.dart index 0b3f5c2b..52c40b35 100644 --- a/lib/modules/player/player_controls.dart +++ b/lib/modules/player/player_controls.dart @@ -84,7 +84,8 @@ class PlayerControls extends HookConsumerWidget { return Column( children: [ Tooltip( - tooltip: Text(context.l10n.slide_to_seek), + tooltip: TooltipContainer( + child: Text(context.l10n.slide_to_seek)), child: Slider( value: SliderValue.single(progress.value.toDouble()), @@ -132,10 +133,12 @@ class PlayerControls extends HookConsumerWidget { final shuffled = ref .watch(audioPlayerProvider.select((s) => s.shuffled)); return Tooltip( - tooltip: Text( - shuffled - ? context.l10n.unshuffle_playlist - : context.l10n.shuffle_playlist, + tooltip: TooltipContainer( + child: Text( + shuffled + ? context.l10n.unshuffle_playlist + : context.l10n.shuffle_playlist, + ), ), child: IconButton( icon: const Icon(SpotubeIcons.shuffle), @@ -155,7 +158,8 @@ class PlayerControls extends HookConsumerWidget { ); }), Tooltip( - tooltip: Text(context.l10n.previous_track), + tooltip: TooltipContainer( + child: Text(context.l10n.previous_track)), child: IconButton.ghost( enabled: !isFetchingActiveTrack, icon: const Icon(SpotubeIcons.skipBack), @@ -163,10 +167,12 @@ class PlayerControls extends HookConsumerWidget { ), ), Tooltip( - tooltip: Text( - playing - ? context.l10n.pause_playback - : context.l10n.resume_playback, + tooltip: TooltipContainer( + child: Text( + playing + ? context.l10n.pause_playback + : context.l10n.resume_playback, + ), ), child: IconButton.primary( shape: ButtonShape.circle, @@ -188,7 +194,8 @@ class PlayerControls extends HookConsumerWidget { ), ), Tooltip( - tooltip: Text(context.l10n.next_track), + tooltip: + TooltipContainer(child: Text(context.l10n.next_track)), child: IconButton.ghost( icon: const Icon(SpotubeIcons.skipForward), onPressed: @@ -200,12 +207,14 @@ class PlayerControls extends HookConsumerWidget { .watch(audioPlayerProvider.select((s) => s.loopMode)); return Tooltip( - tooltip: Text( - loopMode == PlaylistMode.single - ? context.l10n.loop_track - : loopMode == PlaylistMode.loop - ? context.l10n.repeat_playlist - : "", + tooltip: TooltipContainer( + child: Text( + loopMode == PlaylistMode.single + ? context.l10n.loop_track + : loopMode == PlaylistMode.loop + ? context.l10n.repeat_playlist + : "", + ), ), child: IconButton( icon: Icon( diff --git a/lib/modules/player/player_queue.dart b/lib/modules/player/player_queue.dart index 0186d974..58442666 100644 --- a/lib/modules/player/player_queue.dart +++ b/lib/modules/player/player_queue.dart @@ -160,7 +160,8 @@ class PlayerQueue extends HookConsumerWidget { if (mediaQuery.mdAndUp || !isSearching.value) ...[ const SizedBox(width: 10), Tooltip( - tooltip: Text(context.l10n.clear_all), + tooltip: TooltipContainer( + child: Text(context.l10n.clear_all)), child: IconButton.outline( icon: const Icon(SpotubeIcons.playlistRemove), onPressed: () { diff --git a/lib/modules/playlist/playlist_card.dart b/lib/modules/playlist/playlist_card.dart index df683a80..945f3571 100644 --- a/lib/modules/playlist/playlist_card.dart +++ b/lib/modules/playlist/playlist_card.dart @@ -1,9 +1,10 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/dialogs/select_device_dialog.dart'; -import 'package:spotube/components/playbutton_card.dart'; +import 'package:spotube/components/playbutton_view/playbutton_card.dart'; +import 'package:spotube/components/playbutton_view/playbutton_tile.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/models/connect/connect.dart'; @@ -18,10 +19,18 @@ import 'package:spotube/utils/service_utils.dart'; class PlaylistCard extends HookConsumerWidget { final PlaylistSimple playlist; + final bool _isTile; + const PlaylistCard( this.playlist, { super.key, - }); + }) : _isTile = false; + + const PlaylistCard.tile( + this.playlist, { + super.key, + }) : _isTile = true; + @override Widget build(BuildContext context, ref) { final playlistQueue = ref.watch(audioPlayerProvider); @@ -60,96 +69,128 @@ class PlaylistCard extends HookConsumerWidget { return ref.read(playlistTracksProvider(playlist.id!).notifier).fetchAll(); } - return PlaybuttonCard( - margin: const EdgeInsets.symmetric(horizontal: 10), - title: playlist.name!, - description: playlist.description, - imageUrl: playlist.images.asUrlString( - placeholder: ImagePlaceholder.collection, - ), - isPlaying: isPlaylistPlaying, - isLoading: (isPlaylistPlaying && isFetchingActiveTrack) || updating.value, - isOwner: playlist.owner?.id == me.asData?.value.id && - me.asData?.value.id != null, - onTap: () { - ServiceUtils.pushNamed( - context, - PlaylistPage.name, - pathParameters: { - "id": playlist.id!, - }, - extra: playlist, - ); - }, - onPlaybuttonPressed: () async { - try { - updating.value = true; - if (isPlaylistPlaying && playing) { - return audioPlayer.pause(); - } else if (isPlaylistPlaying && !playing) { - return audioPlayer.resume(); - } + void onTap() { + ServiceUtils.pushNamed( + context, + PlaylistPage.name, + pathParameters: { + "id": playlist.id!, + }, + extra: playlist, + ); + } - final fetchedInitialTracks = await fetchInitialTracks(); - - if (fetchedInitialTracks.isEmpty || !context.mounted) return; - - final isRemoteDevice = await showSelectDeviceDialog(context, ref); - if (isRemoteDevice) { - final remotePlayback = ref.read(connectProvider.notifier); - final allTracks = await fetchAllTracks(); - await remotePlayback.load( - WebSocketLoadEventData.playlist( - tracks: allTracks, - collection: playlist, - ), - ); - } else { - await playlistNotifier.load(fetchedInitialTracks, autoPlay: true); - playlistNotifier.addCollection(playlist.id!); - historyNotifier.addPlaylists([playlist]); - - final allTracks = await fetchAllTracks(); - - await playlistNotifier - .addTracks(allTracks.sublist(fetchedInitialTracks.length)); - } - } finally { - if (context.mounted) { - updating.value = false; - } - } - }, - onAddToQueuePressed: () async { + void onPlaybuttonPressed() async { + try { updating.value = true; - try { - if (isPlaylistPlaying) return; + if (isPlaylistPlaying && playing) { + return audioPlayer.pause(); + } else if (isPlaylistPlaying && !playing) { + return audioPlayer.resume(); + } - final fetchedInitialTracks = await fetchAllTracks(); + final fetchedInitialTracks = await fetchInitialTracks(); - if (fetchedInitialTracks.isEmpty) return; + if (fetchedInitialTracks.isEmpty || !context.mounted) return; - playlistNotifier.addTracks(fetchedInitialTracks); + final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice) { + final remotePlayback = ref.read(connectProvider.notifier); + final allTracks = await fetchAllTracks(); + await remotePlayback.load( + WebSocketLoadEventData.playlist( + tracks: allTracks, + collection: playlist, + ), + ); + } else { + await playlistNotifier.load(fetchedInitialTracks, autoPlay: true); playlistNotifier.addCollection(playlist.id!); historyNotifier.addPlaylists([playlist]); - if (context.mounted) { - final snackbar = SnackBar( - content: Text(context.l10n - .added_num_tracks_to_queue(fetchedInitialTracks.length)), - action: SnackBarAction( - label: "Undo", - onPressed: () { - playlistNotifier - .removeTracks(fetchedInitialTracks.map((e) => e.id!)); - }, - ), - ); - ScaffoldMessenger.maybeOf(context)?.showSnackBar(snackbar); - } - } finally { + + final allTracks = await fetchAllTracks(); + + await playlistNotifier + .addTracks(allTracks.sublist(fetchedInitialTracks.length)); + } + } finally { + if (context.mounted) { updating.value = false; } - }, + } + } + + void onAddToQueuePressed() async { + updating.value = true; + try { + if (isPlaylistPlaying) return; + + final fetchedInitialTracks = await fetchAllTracks(); + + if (fetchedInitialTracks.isEmpty) return; + + playlistNotifier.addTracks(fetchedInitialTracks); + playlistNotifier.addCollection(playlist.id!); + historyNotifier.addPlaylists([playlist]); + if (context.mounted) { + showToast( + context: context, + builder: (context, overlay) { + return SurfaceCard( + child: Basic( + content: Text( + context.l10n + .added_num_tracks_to_queue(fetchedInitialTracks.length), + ), + trailing: Button.outline( + child: Text(context.l10n.undo), + onPressed: () { + playlistNotifier + .removeTracks(fetchedInitialTracks.map((e) => e.id!)); + }, + ), + ), + ); + }, + ); + } + } finally { + updating.value = false; + } + } + + final imageUrl = playlist.images.asUrlString( + placeholder: ImagePlaceholder.collection, + ); + final isLoading = + (isPlaylistPlaying && isFetchingActiveTrack) || updating.value; + final isOwner = playlist.owner?.id == me.asData?.value.id && + me.asData?.value.id != null; + + if (_isTile) { + return PlaybuttonTile( + title: playlist.name!, + description: playlist.description, + imageUrl: imageUrl, + isPlaying: isPlaylistPlaying, + isLoading: isLoading, + isOwner: isOwner, + onTap: onTap, + onPlaybuttonPressed: onPlaybuttonPressed, + onAddToQueuePressed: onAddToQueuePressed, + ); + } + + return PlaybuttonCard( + title: playlist.name!, + description: playlist.description, + imageUrl: imageUrl, + isPlaying: isPlaylistPlaying, + isLoading: isLoading, + isOwner: isOwner, + onTap: onTap, + onPlaybuttonPressed: onPlaybuttonPressed, + onAddToQueuePressed: onAddToQueuePressed, ); } } diff --git a/lib/modules/root/bottom_player.dart b/lib/modules/root/bottom_player.dart index 8a22cc7a..fc581377 100644 --- a/lib/modules/root/bottom_player.dart +++ b/lib/modules/root/bottom_player.dart @@ -74,7 +74,8 @@ class BottomPlayer extends HookConsumerWidget { PlayerActions( extraActions: [ Tooltip( - tooltip: Text(context.l10n.mini_player), + tooltip: + TooltipContainer(child: Text(context.l10n.mini_player)), child: IconButton( variance: ButtonVariance.ghost, icon: const Icon(SpotubeIcons.miniPlayer), diff --git a/lib/pages/home/feed/feed_section.dart b/lib/pages/home/feed/feed_section.dart index 0249d865..38d0887c 100644 --- a/lib/pages/home/feed/feed_section.dart +++ b/lib/pages/home/feed/feed_section.dart @@ -1,12 +1,13 @@ -import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; +import 'package:spotube/components/playbutton_view/playbutton_view.dart'; import 'package:spotube/modules/album/album_card.dart'; import 'package:spotube/modules/artist/artist_card.dart'; import 'package:spotube/modules/playlist/playlist_card.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; -import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/provider/spotify/views/home_section.dart'; class HomeFeedSectionPage extends HookConsumerWidget { @@ -19,47 +20,72 @@ class HomeFeedSectionPage extends HookConsumerWidget { Widget build(BuildContext context, ref) { final homeFeedSection = ref.watch(homeSectionViewProvider(sectionUri)); final section = homeFeedSection.asData?.value ?? FakeData.feedSection; + final controller = useScrollController(); + final isArtist = section.items.every((item) => item.artist != null); return Skeletonizer( enabled: homeFeedSection.isLoading, child: Scaffold( - appBar: TitleBar( - title: Text(section.title ?? ""), - automaticallyImplyLeading: true, - ), - body: CustomScrollView( - slivers: [ - SliverLayoutBuilder( - builder: (context, constrains) { - return SliverGrid.builder( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( + headers: [ + TitleBar( + title: Text(section.title ?? ""), + automaticallyImplyLeading: true, + ) + ], + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: CustomScrollView( + controller: controller, + slivers: [ + if (isArtist) + SliverGrid.builder( + gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 200, - mainAxisExtent: constrains.smAndDown ? 225 : 250, + mainAxisExtent: 250, crossAxisSpacing: 8, mainAxisSpacing: 8, ), itemCount: section.items.length, itemBuilder: (context, index) { final item = section.items[index]; - + return ArtistCard(item.artist!.asArtist); + }, + ) + else + PlaybuttonView( + controller: controller, + itemCount: section.items.length, + hasMore: false, + isLoading: false, + onRequestMore: () => {}, + listItemBuilder: (context, index) { + final item = section.items[index]; + if (item.album != null) { + return AlbumCard.tile(item.album!.asAlbum); + } + if (item.playlist != null) { + return PlaylistCard.tile(item.playlist!.asPlaylist); + } + return const SizedBox.shrink(); + }, + gridItemBuilder: (context, index) { + final item = section.items[index]; if (item.album != null) { return AlbumCard(item.album!.asAlbum); - } else if (item.artist != null) { - return ArtistCard(item.artist!.asArtist); - } else if (item.playlist != null) { + } + if (item.playlist != null) { return PlaylistCard(item.playlist!.asPlaylist); } - return const SizedBox(); + return const SizedBox.shrink(); }, - ); - }, - ), - const SliverToBoxAdapter( - child: SafeArea( - child: SizedBox(), + ), + const SliverToBoxAdapter( + child: SafeArea( + child: SizedBox(), + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/pages/home/genres/genre_playlists.dart b/lib/pages/home/genres/genre_playlists.dart index ec478617..ebfc4450 100644 --- a/lib/pages/home/genres/genre_playlists.dart +++ b/lib/pages/home/genres/genre_playlists.dart @@ -1,19 +1,20 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show CollapseMode, FlexibleSpaceBar; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; + import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:skeletonizer/skeletonizer.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; + import 'package:spotify/spotify.dart' hide Offset; -import 'package:spotube/collections/fake.dart'; +import 'package:spotube/components/button/back_button.dart'; +import 'package:spotube/components/playbutton_view/playbutton_view.dart'; import 'package:spotube/hooks/utils/use_custom_status_bar_color.dart'; import 'package:spotube/modules/playlist/playlist_card.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; -import 'package:spotube/components/waypoint.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/provider/spotify/spotify.dart'; -import 'package:collection/collection.dart'; import 'package:spotube/utils/platform.dart'; class GenrePlaylistsPage extends HookConsumerWidget { @@ -39,123 +40,93 @@ class GenrePlaylistsPage extends HookConsumerWidget { ); return Scaffold( - appBar: kIsDesktop - ? const TitleBar( - leading: [BackButton(color: Colors.white)], - backgroundColor: Colors.transparent, - foregroundColor: Colors.white, - ) - : null, - extendBodyBehindAppBar: true, - body: DecoratedBox( + headers: [ + if (kIsDesktop) + const TitleBar( + leading: [ + BackButton(), + ], + backgroundColor: Colors.transparent, + surfaceOpacity: 0, + surfaceBlur: 0, + ) + ], + floatingHeader: true, + child: DecoratedBox( decoration: BoxDecoration( image: DecorationImage( image: UniversalImage.imageProvider(category.icons!.first.url!), alignment: Alignment.topCenter, fit: BoxFit.cover, - colorFilter: ColorFilter.mode( - Colors.black.withOpacity(0.5), - BlendMode.darken, - ), repeat: ImageRepeat.noRepeat, matchTextDirection: true, ), ), - child: CustomScrollView( - controller: scrollController, - slivers: [ - SliverAppBar( - automaticallyImplyLeading: kIsMobile, - expandedHeight: mediaQuery.mdAndDown ? 200 : 150, - title: const Text(""), - backgroundColor: Colors.transparent, - flexibleSpace: FlexibleSpaceBar( - centerTitle: kIsDesktop, - title: Text( - category.name!, - style: Theme.of(context).textTheme.headlineMedium?.copyWith( - color: Colors.white, - letterSpacing: 3, - shadows: [ - const Shadow( - offset: Offset(-1.5, -1.5), - color: Colors.black54, - ), - const Shadow( - offset: Offset(1.5, -1.5), - color: Colors.black54, - ), - const Shadow( - offset: Offset(1.5, 1.5), - color: Colors.black54, - ), - const Shadow( - offset: Offset(-1.5, 1.5), - color: Colors.black54, - ), - ], + child: SurfaceCard( + borderRadius: BorderRadius.zero, + padding: EdgeInsets.zero, + child: CustomScrollView( + controller: scrollController, + slivers: [ + SliverAppBar( + automaticallyImplyLeading: false, + leading: kIsMobile ? const BackButton() : null, + expandedHeight: mediaQuery.mdAndDown ? 200 : 150, + title: const Text(""), + backgroundColor: Colors.transparent, + flexibleSpace: FlexibleSpaceBar( + centerTitle: kIsDesktop, + title: Text( + category.name!, + style: context.theme.typography.h3.copyWith( + color: Colors.white, + letterSpacing: 3, + shadows: [ + Shadow( + offset: const Offset(-1.5, -1.5), + color: Colors.black.withAlpha(138), + ), + Shadow( + offset: const Offset(1.5, -1.5), + color: Colors.black.withAlpha(138), + ), + Shadow( + offset: const Offset(1.5, 1.5), + color: Colors.black.withAlpha(138), + ), + Shadow( + offset: const Offset(-1.5, 1.5), + color: Colors.black.withAlpha(138), + ), + ], + ), + ), + collapseMode: CollapseMode.parallax, + ), + ), + const SliverGap(20), + SliverSafeArea( + top: false, + sliver: SliverPadding( + padding: EdgeInsets.symmetric( + horizontal: mediaQuery.mdAndDown ? 12 : 24, + ), + sliver: PlaybuttonView( + controller: scrollController, + itemCount: playlists.asData?.value.items.length ?? 0, + isLoading: playlists.isLoading, + hasMore: playlists.asData?.value.hasMore == true, + onRequestMore: playlistsNotifier.fetchMore, + listItemBuilder: (context, index) => + PlaylistCard.tile(playlists.asData!.value.items[index]), + gridItemBuilder: (context, index) => + PlaylistCard(playlists.asData!.value.items[index]), ), ), - collapseMode: CollapseMode.parallax, ), - ), - const SliverGap(20), - SliverSafeArea( - top: false, - sliver: SliverPadding( - padding: EdgeInsets.symmetric( - horizontal: mediaQuery.mdAndDown ? 12 : 24, - ), - sliver: playlists.asData?.value.items.isNotEmpty != true - ? Skeletonizer.sliver( - child: SliverToBoxAdapter( - child: Wrap( - spacing: 12, - runSpacing: 12, - children: List.generate( - 6, - (index) => PlaylistCard(FakeData.playlist), - ), - ), - ), - ) - : SliverGrid.builder( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 190, - mainAxisExtent: mediaQuery.mdAndDown ? 225 : 250, - crossAxisSpacing: 12, - mainAxisSpacing: 12, - ), - itemCount: - (playlists.asData?.value.items.length ?? 0) + 1, - itemBuilder: (context, index) { - final playlist = playlists.asData?.value.items - .elementAtOrNull(index); - - if (playlist == null) { - if (playlists.asData?.value.hasMore == false) { - return const SizedBox.shrink(); - } - return Skeletonizer( - enabled: true, - child: Waypoint( - controller: scrollController, - isGrid: true, - onTouchEdge: playlistsNotifier.fetchMore, - child: PlaylistCard(FakeData.playlist), - ), - ); - } - - return Skeleton.keep( - child: PlaylistCard(playlist), - ); - }, - ), - ), - ), - const SliverGap(20), - ], + const SliverGap(20), + ], + ), ), ), ); diff --git a/untranslated_messages.json b/untranslated_messages.json index 9e26dfee..67bb4673 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1 +1,105 @@ -{} \ No newline at end of file +{ + "ar": [ + "undo" + ], + + "bn": [ + "undo" + ], + + "ca": [ + "undo" + ], + + "cs": [ + "undo" + ], + + "de": [ + "undo" + ], + + "es": [ + "undo" + ], + + "eu": [ + "undo" + ], + + "fa": [ + "undo" + ], + + "fi": [ + "undo" + ], + + "fr": [ + "undo" + ], + + "hi": [ + "undo" + ], + + "id": [ + "undo" + ], + + "it": [ + "undo" + ], + + "ja": [ + "undo" + ], + + "ka": [ + "undo" + ], + + "ko": [ + "undo" + ], + + "ne": [ + "undo" + ], + + "nl": [ + "undo" + ], + + "pl": [ + "undo" + ], + + "pt": [ + "undo" + ], + + "ru": [ + "undo" + ], + + "th": [ + "undo" + ], + + "tr": [ + "undo" + ], + + "uk": [ + "undo" + ], + + "vi": [ + "undo" + ], + + "zh": [ + "undo" + ] +} From b09263d128062efb6ad6b66c19da4f5b31377e64 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 22 Dec 2024 15:03:49 +0600 Subject: [PATCH 15/81] chore: fix queue close causing exceptions --- lib/components/adaptive/adaptive_pop_sheet_list.dart | 10 +++++----- lib/components/track_tile/track_options.dart | 1 + lib/modules/player/player_actions.dart | 10 +++++++++- lib/modules/player/player_queue.dart | 2 +- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/components/adaptive/adaptive_pop_sheet_list.dart b/lib/components/adaptive/adaptive_pop_sheet_list.dart index fa72031e..63499e8a 100644 --- a/lib/components/adaptive/adaptive_pop_sheet_list.dart +++ b/lib/components/adaptive/adaptive_pop_sheet_list.dart @@ -34,7 +34,7 @@ class AdaptivePopSheetList extends StatelessWidget { final bool useRootNavigator; final List? headings; - final String? tooltip; + final String tooltip; final ValueChanged? onSelected; final Offset offset; @@ -47,7 +47,7 @@ class AdaptivePopSheetList extends StatelessWidget { this.useRootNavigator = true, this.headings, this.onSelected, - this.tooltip, + required this.tooltip, this.offset = Offset.zero, }) : assert( !(icon != null && child != null), @@ -140,7 +140,7 @@ class AdaptivePopSheetList extends StatelessWidget { if (mediaQuery.mdAndUp) { return Tooltip( tooltip: TooltipContainer( - child: Text(tooltip ?? ''), + child: Text(tooltip), ), child: IconButton.ghost( icon: icon ?? const Icon(SpotubeIcons.moreVertical), @@ -164,7 +164,7 @@ class AdaptivePopSheetList extends StatelessWidget { if (child != null) { return Tooltip( - tooltip: TooltipContainer(child: Text(tooltip ?? '')), + tooltip: TooltipContainer(child: Text(tooltip)), child: Button( onPressed: () => showDropdownMenu(context, Offset.zero), style: const ButtonStyle.ghost(), @@ -174,7 +174,7 @@ class AdaptivePopSheetList extends StatelessWidget { } return Tooltip( - tooltip: TooltipContainer(child: Text(tooltip ?? '')), + tooltip: TooltipContainer(child: Text(tooltip)), child: IconButton.ghost( icon: icon ?? const Icon(SpotubeIcons.moreVertical), onPressed: () => showDropdownMenu(context, Offset.zero), diff --git a/lib/components/track_tile/track_options.dart b/lib/components/track_tile/track_options.dart index c40ddd2a..ec2fd2f0 100644 --- a/lib/components/track_tile/track_options.dart +++ b/lib/components/track_tile/track_options.dart @@ -204,6 +204,7 @@ class TrackOptions extends HookConsumerWidget { final isLocalTrack = track is LocalTrack; final adaptivePopSheetList = AdaptivePopSheetList( + tooltip: context.l10n.more_actions, onSelected: (value) async { switch (value) { case TrackOptionValue.album: diff --git a/lib/modules/player/player_actions.dart b/lib/modules/player/player_actions.dart index 5b469510..12965da4 100644 --- a/lib/modules/player/player_actions.dart +++ b/lib/modules/player/player_actions.dart @@ -164,6 +164,7 @@ class PlayerActions extends HookConsumerWidget { auth.asData?.value != null) TrackHeartButton(track: playlist.activeTrack!), AdaptivePopSheetList( + tooltip: context.l10n.sleep_timer, offset: Offset(0, -50 * (sleepTimerEntries.values.length + 2)), headings: [ Text(context.l10n.sleep_timer), @@ -190,11 +191,18 @@ class PlayerActions extends HookConsumerWidget { enabled: customHoursEnabled, onPressed: (context) async { final currentTime = TimeOfDay.now(); - final time = await showDialog( + final time = await showDialog( context: context, builder: (context) => HookBuilder(builder: (context) { final timeRef = useRef(null); return AlertDialog( + trailing: IconButton.ghost( + size: ButtonSize.xSmall, + icon: const Icon(SpotubeIcons.close), + onPressed: () { + Navigator.of(context).pop(); + }, + ), title: Text( ShadcnLocalizations.of(context).placeholderTimePicker, ), diff --git a/lib/modules/player/player_queue.dart b/lib/modules/player/player_queue.dart index 58442666..cdda39da 100644 --- a/lib/modules/player/player_queue.dart +++ b/lib/modules/player/player_queue.dart @@ -166,7 +166,7 @@ class PlayerQueue extends HookConsumerWidget { icon: const Icon(SpotubeIcons.playlistRemove), onPressed: () { onStop(); - Navigator.of(context).pop(); + closeDrawer(context); }, ), ), From b40c0b77729f06ecb1a1676f8f1a90cb9c91a845 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 22 Dec 2024 22:55:40 +0600 Subject: [PATCH 16/81] chore: use latest shadcn --- linux/flutter/generated_plugin_registrant.cc | 4 -- linux/flutter/generated_plugins.cmake | 1 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 - macos/Podfile.lock | 6 -- pubspec.lock | 70 +------------------ pubspec.yaml | 2 +- .../flutter/generated_plugin_registrant.cc | 3 - windows/flutter/generated_plugins.cmake | 1 - 8 files changed, 4 insertions(+), 85 deletions(-) diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 476ff787..06c33e05 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,7 +6,6 @@ #include "generated_plugin_registrant.h" -#include #include #include #include @@ -22,9 +21,6 @@ #include void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin"); - audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar); g_autoptr(FlPluginRegistrar) desktop_webview_window_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopWebviewWindowPlugin"); desktop_webview_window_plugin_register_with_registrar(desktop_webview_window_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index a875e8f5..e98b18eb 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - audioplayers_linux desktop_webview_window file_selector_linux flutter_secure_storage_linux diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 12972107..608a854e 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,7 +8,6 @@ import Foundation import app_links import audio_service import audio_session -import audioplayers_darwin import bonsoir_darwin import desktop_webview_window import device_info_plus @@ -33,7 +32,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) AudioServicePlugin.register(with: registry.registrar(forPlugin: "AudioServicePlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) - AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) SwiftBonsoirPlugin.register(with: registry.registrar(forPlugin: "SwiftBonsoirPlugin")) DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index db8ed79c..bdf530f1 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -5,8 +5,6 @@ PODS: - FlutterMacOS - audio_session (0.0.1): - FlutterMacOS - - audioplayers_darwin (0.0.1): - - FlutterMacOS - bonsoir_darwin (0.0.1): - Flutter - FlutterMacOS @@ -80,7 +78,6 @@ DEPENDENCIES: - app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`) - audio_service (from `Flutter/ephemeral/.symlinks/plugins/audio_service/macos`) - audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`) - - audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos`) - bonsoir_darwin (from `Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin`) - desktop_webview_window (from `Flutter/ephemeral/.symlinks/plugins/desktop_webview_window/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) @@ -117,8 +114,6 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/audio_service/macos audio_session: :path: Flutter/ephemeral/.symlinks/plugins/audio_session/macos - audioplayers_darwin: - :path: Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos bonsoir_darwin: :path: Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin desktop_webview_window: @@ -170,7 +165,6 @@ SPEC CHECKSUMS: app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a audio_service: b88ff778e0e3915efd4cd1a5ad6f0beef0c950a9 audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72 - audioplayers_darwin: dcad41de4fbd0099cb3749f7ab3b0cb8f70b810c bonsoir_darwin: e3b8526c42ca46a885142df84229131dfabea842 desktop_webview_window: 89bb3d691f4c80314a10be312f4cd35db93a9d5a device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215 diff --git a/pubspec.lock b/pubspec.lock index 91ca8765..aaf82934 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -142,62 +142,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.21" - audioplayers: - dependency: transitive - description: - name: audioplayers - sha256: c346ba5a39dc208f1bab55fc239855f573d69b0e832402114bf0b793622adc4d - url: "https://pub.dev" - source: hosted - version: "6.1.0" - audioplayers_android: - dependency: transitive - description: - name: audioplayers_android - sha256: de576b890befe27175c2f511ba8b742bec83765fa97c3ce4282bba46212f58e4 - url: "https://pub.dev" - source: hosted - version: "5.0.0" - audioplayers_darwin: - dependency: transitive - description: - name: audioplayers_darwin - sha256: e507887f3ff18d8e5a10a668d7bedc28206b12e10b98347797257c6ae1019c3b - url: "https://pub.dev" - source: hosted - version: "6.0.0" - audioplayers_linux: - dependency: transitive - description: - name: audioplayers_linux - sha256: "3d3d244c90436115417f170426ce768856d8fe4dfc5ed66a049d2890acfa82f9" - url: "https://pub.dev" - source: hosted - version: "4.0.0" - audioplayers_platform_interface: - dependency: transitive - description: - name: audioplayers_platform_interface - sha256: "6834dd48dfb7bc6c2404998ebdd161f79cd3774a7e6779e1348d54a3bfdcfaa5" - url: "https://pub.dev" - source: hosted - version: "7.0.0" - audioplayers_web: - dependency: transitive - description: - name: audioplayers_web - sha256: "3609bdf0e05e66a3d9750ee40b1e37f2a622c4edb796cc600b53a90a30a2ace4" - url: "https://pub.dev" - source: hosted - version: "5.0.1" - audioplayers_windows: - dependency: transitive - description: - name: audioplayers_windows - sha256: "8605762dddba992138d476f6a0c3afd9df30ac5b96039929063eceed416795c2" - url: "https://pub.dev" - source: hosted - version: "4.0.0" auto_size_text: dependency: "direct main" description: @@ -1836,14 +1780,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.1" - pixel_snap: - dependency: transitive - description: - name: pixel_snap - sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0" - url: "https://pub.dev" - source: hosted - version: "0.1.5" platform: dependency: transitive description: @@ -2017,10 +1953,10 @@ packages: dependency: "direct main" description: name: shadcn_flutter - sha256: eaf10ec804beddf2059dd55b802188b64277a5e4fc577defbc7c012253caef1a + sha256: "2b58f6ee6d15defd8d07aa1e82077c85455ddc68047368994c562006c2338ec2" url: "https://pub.dev" source: hosted - version: "0.0.23" + version: "0.0.24" shared_preferences: dependency: "direct main" description: @@ -2732,4 +2668,4 @@ packages: version: "2.3.6" sdks: dart: ">=3.5.3 <4.0.0" - flutter: ">=3.24.0" + flutter: ">=3.27.0" diff --git a/pubspec.yaml b/pubspec.yaml index 25ccd41c..3a90b3d1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -98,7 +98,7 @@ dependencies: ref: dart-3-support url: https://github.com/KRTirtho/scrobblenaut.git scroll_to_index: ^3.0.1 - shadcn_flutter: ^0.0.23 + shadcn_flutter: ^0.0.24 shared_preferences: ^2.2.3 shelf: ^1.4.1 shelf_router: ^1.1.4 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 7c490ef1..42fa2129 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,7 +7,6 @@ #include "generated_plugin_registrant.h" #include -#include #include #include #include @@ -26,8 +25,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { AppLinksPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("AppLinksPluginCApi")); - AudioplayersWindowsPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); BonsoirWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("BonsoirWindowsPluginCApi")); DesktopWebviewWindowPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index dfcc70cf..cf14ec52 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,7 +4,6 @@ list(APPEND FLUTTER_PLUGIN_LIST app_links - audioplayers_windows bonsoir_windows desktop_webview_window file_selector_windows From db3aaa4b83e4b4af46071900de987550dc2d0e45 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Mon, 23 Dec 2024 19:23:10 +0600 Subject: [PATCH 17/81] chore: upgrade to flutter 3.27.1 --- .fvm/fvm_config.json | 2 +- .fvmrc | 2 +- .vscode/settings.json | 2 +- .../main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.fvm/fvm_config.json b/.fvm/fvm_config.json index e20d18ad..41b45a53 100644 --- a/.fvm/fvm_config.json +++ b/.fvm/fvm_config.json @@ -1,3 +1,3 @@ { - "flutterSdkVersion": "3.27.0" + "flutterSdkVersion": "3.27.1" } \ No newline at end of file diff --git a/.fvmrc b/.fvmrc index 34136bbd..d1af5d57 100644 --- a/.fvmrc +++ b/.fvmrc @@ -1,4 +1,4 @@ { - "flutter": "3.27.0", + "flutter": "3.27.1", "flavors": {} } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 57413df4..4d76417f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -28,5 +28,5 @@ "README.md": "LICENSE,CODE_OF_CONDUCT.md,CONTRIBUTING.md,SECURITY.md,CONTRIBUTION.md,CHANGELOG.md,PRIVACY_POLICY.md", "*.dart": "${capture}.g.dart,${capture}.freezed.dart" }, - "dart.flutterSdkPath": ".fvm/versions/3.27.0" + "dart.flutterSdkPath": ".fvm/versions/3.27.1" } \ No newline at end of file diff --git a/android/app/src/main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt b/android/app/src/main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt index a04a0508..013723c0 100644 --- a/android/app/src/main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt +++ b/android/app/src/main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt @@ -2,6 +2,7 @@ package oss.krtirtho.spotube.glance import HomeWidgetGlanceState import HomeWidgetGlanceStateDefinition +import android.R import android.content.Context import android.graphics.drawable.Icon import android.net.Uri From e2143a0625790b9a7ec847db5e84bca90450722b Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Tue, 24 Dec 2024 20:19:10 +0600 Subject: [PATCH 18/81] chore: fix android build and player controls slider layout builder exception --- lib/extensions/constrains.dart | 19 ++++++++++++ lib/modules/player/player_controls.dart | 41 +++++++++++++++---------- pubspec.lock | 29 +++++++++-------- pubspec.yaml | 13 ++++++-- 4 files changed, 70 insertions(+), 32 deletions(-) diff --git a/lib/extensions/constrains.dart b/lib/extensions/constrains.dart index dc1027e2..b7353c4f 100644 --- a/lib/extensions/constrains.dart +++ b/lib/extensions/constrains.dart @@ -106,3 +106,22 @@ extension ScreenBreakpoints on MediaQueryData { bool get lgAndDown => isXs || isSm || isMd || isLg; bool get xlAndDown => isXs || isSm || isMd || isLg || isXl; } + +extension SizeBreakpoints on Size { + bool get isXs => width <= Breakpoints.xs; + bool get isSm => width > Breakpoints.xs && width <= Breakpoints.sm; + bool get isMd => width > Breakpoints.sm && width <= Breakpoints.md; + bool get isLg => width > Breakpoints.md && width <= Breakpoints.lg; + bool get isXl => width > Breakpoints.lg && width <= Breakpoints.xl; + bool get is2Xl => width > Breakpoints.xl; + + bool get smAndUp => isSm || isMd || isLg || isXl || is2Xl; + bool get mdAndUp => isMd || isLg || isXl || is2Xl; + bool get lgAndUp => isLg || isXl || is2Xl; + bool get xlAndUp => isXl || is2Xl; + + bool get smAndDown => isXs || isSm; + bool get mdAndDown => isXs || isSm || isMd; + bool get lgAndDown => isXs || isSm || isMd || isLg; + bool get xlAndDown => isXs || isSm || isMd || isLg || isXl; +} diff --git a/lib/modules/player/player_controls.dart b/lib/modules/player/player_controls.dart index 52c40b35..3c1cd503 100644 --- a/lib/modules/player/player_controls.dart +++ b/lib/modules/player/player_controls.dart @@ -7,6 +7,7 @@ import 'package:shadcn_flutter/shadcn_flutter.dart' hide ThemeData; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/intents.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/duration.dart'; import 'package:spotube/modules/player/use_progress.dart'; @@ -65,6 +66,8 @@ class PlayerControls extends HookConsumerWidget { if (!compact) HookBuilder( builder: (context) { + final mediaQuery = MediaQuery.sizeOf(context); + final ( :bufferProgress, :duration, @@ -85,23 +88,27 @@ class PlayerControls extends HookConsumerWidget { children: [ Tooltip( tooltip: TooltipContainer( - child: Text(context.l10n.slide_to_seek)), - child: Slider( - value: - SliderValue.single(progress.value.toDouble()), - onChanged: isFetchingActiveTrack - ? null - : (v) { - progress.value = v.value; - }, - onChangeEnd: (value) async { - await audioPlayer.seek( - Duration( - seconds: (value.value * duration.inSeconds) - .toInt(), - ), - ); - }, + child: Text(context.l10n.slide_to_seek), + ), + child: SizedBox( + width: mediaQuery.xlAndUp ? 600 : 500, + child: Slider( + value: + SliderValue.single(progress.value.toDouble()), + onChanged: isFetchingActiveTrack + ? null + : (v) { + progress.value = v.value; + }, + onChangeEnd: (value) async { + await audioPlayer.seek( + Duration( + seconds: (value.value * duration.inSeconds) + .toInt(), + ), + ); + }, + ), ), ), Padding( diff --git a/pubspec.lock b/pubspec.lock index aaf82934..ff445cad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -159,12 +159,13 @@ packages: source: hosted version: "5.1.10" bonsoir_android: - dependency: transitive + dependency: "direct overridden" description: - name: bonsoir_android - sha256: a72d83a78780c1f238e3178d0585e5604fbd9f2503206293737cdfab899ce8d0 - url: "https://pub.dev" - source: hosted + path: "packages/bonsoir_android" + ref: HEAD + resolved-ref: aa5604628ba41e3a7153769f4465a3d375488f2e + url: "https://github.com/KRTirtho/Bonsoir.git" + source: git version: "5.1.5" bonsoir_darwin: dependency: transitive @@ -514,10 +515,11 @@ packages: disable_battery_optimization: dependency: "direct main" description: - name: disable_battery_optimization - sha256: "6b2ba802f984af141faf1b6b5fb956d5ef01f9cd555597c35b9cc335a03185ba" - url: "https://pub.dev" - source: hosted + path: "." + ref: HEAD + resolved-ref: aa77a61946849fff495091fc13dcc390948cc60b + url: "https://github.com/KRTirtho/Disable-Battery-Optimizations.git" + source: git version: "1.1.1" draggable_scrollbar: dependency: "direct main" @@ -1952,10 +1954,11 @@ packages: shadcn_flutter: dependency: "direct main" description: - name: shadcn_flutter - sha256: "2b58f6ee6d15defd8d07aa1e82077c85455ddc68047368994c562006c2338ec2" - url: "https://pub.dev" - source: hosted + path: "." + ref: "5359958464a57235f0f34c43a4623356a32459a0" + resolved-ref: "5359958464a57235f0f34c43a4623356a32459a0" + url: "https://github.com/KRTirtho/shadcn_flutter.git" + source: git version: "0.0.24" shared_preferences: dependency: "direct main" diff --git a/pubspec.yaml b/pubspec.yaml index 3a90b3d1..198bc949 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,7 +30,9 @@ dependencies: url: https://github.com/KRTirtho/flutter-plugins.git device_info_plus: ^11.1.1 dio: ^5.4.3+1 - disable_battery_optimization: ^1.1.1 + disable_battery_optimization: + git: + url: https://github.com/KRTirtho/Disable-Battery-Optimizations.git draggable_scrollbar: git: ref: cfd570035bf393de541d32e9b28808b5d7e602df @@ -98,7 +100,10 @@ dependencies: ref: dart-3-support url: https://github.com/KRTirtho/scrobblenaut.git scroll_to_index: ^3.0.1 - shadcn_flutter: ^0.0.24 + shadcn_flutter: + git: + url: https://github.com/KRTirtho/shadcn_flutter.git + ref: 5359958464a57235f0f34c43a4623356a32459a0 shared_preferences: ^2.2.3 shelf: ^1.4.1 shelf_router: ^1.1.4 @@ -149,6 +154,10 @@ dev_dependencies: drift_dev: ^2.21.0 dependency_overrides: + bonsoir_android: + git: + url: https://github.com/KRTirtho/Bonsoir.git + path: packages/bonsoir_android web: ^1.1.0 meta: 1.16.0 From ced85d3f0c68a6e89ab7451f40091452e489528c Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Tue, 24 Dec 2024 21:33:24 +0600 Subject: [PATCH 19/81] chore: fix scaling issue in android and status bar being black --- .../horizontal_playbutton_card_view.dart | 12 ++- .../playbutton_view/playbutton_card.dart | 20 ++-- .../playbutton_view/playbutton_tile.dart | 17 ++-- .../playbutton_view/playbutton_view.dart | 7 +- lib/main.dart | 3 +- lib/modules/player/player_controls.dart | 2 +- lib/pages/home/genres/genres.dart | 91 ++++++++++--------- lib/pages/root/root_app.dart | 9 +- 8 files changed, 93 insertions(+), 68 deletions(-) diff --git a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart index 0ebebea7..d37bc8a0 100644 --- a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart +++ b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart @@ -48,11 +48,15 @@ class HorizontalPlaybuttonCardView extends HookWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - DefaultTextStyle( - style: context.theme.typography.h4.copyWith( - color: context.theme.colorScheme.foreground, + Flexible( + child: DefaultTextStyle( + style: context.theme.typography.h4.copyWith( + color: context.theme.colorScheme.foreground, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + child: title, ), - child: title, ), if (titleTrailing != null) titleTrailing!, ], diff --git a/lib/components/playbutton_view/playbutton_card.dart b/lib/components/playbutton_view/playbutton_card.dart index 849bab2a..21016d57 100644 --- a/lib/components/playbutton_view/playbutton_card.dart +++ b/lib/components/playbutton_view/playbutton_card.dart @@ -1,4 +1,5 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/string.dart'; @@ -32,16 +33,23 @@ class PlaybuttonCard extends StatelessWidget { @override Widget build(BuildContext context) { final unescapeHtml = description?.unescapeHtml().cleanHtml() ?? ""; + final scale = context.theme.scaling; - return Container( - width: 150, + return SizedBox( + width: 150 * scale, child: CardImage( image: Stack( children: [ - UniversalImage( - path: imageUrl, - height: 150, - fit: BoxFit.cover, + Container( + width: 150 * scale, + height: 150 * scale, + decoration: BoxDecoration( + borderRadius: context.theme.borderRadiusMd, + image: DecorationImage( + image: UniversalImage.imageProvider(imageUrl), + fit: BoxFit.cover, + ), + ), ), StatedWidget.builder( builder: (context, states) { diff --git a/lib/components/playbutton_view/playbutton_tile.dart b/lib/components/playbutton_view/playbutton_tile.dart index 3f9d89fe..e06f3689 100644 --- a/lib/components/playbutton_view/playbutton_tile.dart +++ b/lib/components/playbutton_view/playbutton_tile.dart @@ -33,15 +33,18 @@ class PlaybuttonTile extends StatelessWidget { @override Widget build(BuildContext context) { final cleanDescription = description?.unescapeHtml().cleanHtml() ?? ""; + final scale = context.theme.scaling; return Button.ghost( - leading: ClipRRect( - borderRadius: context.theme.borderRadiusMd, - child: UniversalImage( - path: imageUrl, - width: 40, - height: 40, - fit: BoxFit.cover, + leading: Container( + width: 50 * scale, + height: 50 * scale, + decoration: BoxDecoration( + borderRadius: context.theme.borderRadiusMd, + image: DecorationImage( + image: UniversalImage.imageProvider(imageUrl), + fit: BoxFit.cover, + ), ), ), trailing: Row( diff --git a/lib/components/playbutton_view/playbutton_view.dart b/lib/components/playbutton_view/playbutton_view.dart index 52cfb592..7520f313 100644 --- a/lib/components/playbutton_view/playbutton_view.dart +++ b/lib/components/playbutton_view/playbutton_view.dart @@ -1,5 +1,6 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/playbutton_view/playbutton_card.dart'; @@ -98,9 +99,9 @@ class PlaybuttonView extends StatelessWidget { switch ((isGrid.value, isLoading)) { (true, _) => SliverGrid.builder( itemCount: isLoading ? 6 : itemCount + 1, - gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 150, - mainAxisExtent: 225, + gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 150 * context.theme.scaling, + mainAxisExtent: 225 * context.theme.scaling, crossAxisSpacing: 8, mainAxisSpacing: 8, ), diff --git a/lib/main.dart b/lib/main.dart index cae1e9fe..0b84d38d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -210,13 +210,13 @@ class Spotube extends HookConsumerWidget { return child; }, + scaling: const AdaptiveScaling(1), theme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), colorScheme: ColorSchemes.lightBlue(), surfaceOpacity: .8, surfaceBlur: 10, - typography: const Typography.geist(), ), darkTheme: ThemeData( radius: .5, @@ -224,7 +224,6 @@ class Spotube extends HookConsumerWidget { colorScheme: ColorSchemes.darkNeutral(), surfaceOpacity: .8, surfaceBlur: 10, - typography: const Typography.geist(), ), themeMode: themeMode, shortcuts: { diff --git a/lib/modules/player/player_controls.dart b/lib/modules/player/player_controls.dart index 3c1cd503..acc3064e 100644 --- a/lib/modules/player/player_controls.dart +++ b/lib/modules/player/player_controls.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:media_kit/media_kit.dart'; import 'package:palette_generator/palette_generator.dart'; -import 'package:shadcn_flutter/shadcn_flutter.dart' hide ThemeData; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/intents.dart'; diff --git a/lib/pages/home/genres/genres.dart b/lib/pages/home/genres/genres.dart index ed9d9351..062852e8 100644 --- a/lib/pages/home/genres/genres.dart +++ b/lib/pages/home/genres/genres.dart @@ -1,10 +1,12 @@ import 'dart:math'; import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; + import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/gradients.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/extensions/constrains.dart'; @@ -18,19 +20,19 @@ class GenrePage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme) = Theme.of(context); final scrollController = useScrollController(); final categories = ref.watch(categoriesProvider); final mediaQuery = MediaQuery.of(context); - return Scaffold( - appBar: TitleBar( - title: Text(context.l10n.explore_genres), - automaticallyImplyLeading: true, - ), - body: SafeArea( - top: false, + return SafeArea( + child: Scaffold( + headers: [ + TitleBar( + title: Text(context.l10n.explore_genres), + automaticallyImplyLeading: true, + ) + ], child: GridView.builder( padding: const EdgeInsets.all(12), controller: scrollController, @@ -45,9 +47,8 @@ class GenrePage extends HookConsumerWidget { itemBuilder: (context, index) { final category = categories.asData!.value[index]; final gradient = gradients[Random().nextInt(gradients.length)]; - return InkWell( - borderRadius: BorderRadius.circular(8), - onTap: () { + return CardImage( + onPressed: () { context.pushNamed( GenrePlaylistsPage.name, pathParameters: { @@ -56,37 +57,45 @@ class GenrePage extends HookConsumerWidget { extra: category, ); }, - child: Ink( - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - image: DecorationImage( - image: NetworkImage(category.icons!.first.url!), - fit: BoxFit.cover, - ), - gradient: gradient, - ), - child: Align( - alignment: Alignment.bottomCenter, - child: AutoSizeText( - category.name!, - style: textTheme.titleLarge?.copyWith( - color: Colors.white, - shadows: [ - // stroke shadow - const Shadow( - color: Colors.black, - offset: Offset(1, 1), - blurRadius: 2, - ), - ], + image: Stack( + children: [ + Container( + height: 300, + width: 250, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + image: NetworkImage(category.icons!.first.url!), + fit: BoxFit.cover, + ), + gradient: gradient, ), - maxLines: 1, - textAlign: TextAlign.center, - maxFontSize: textTheme.titleLarge!.fontSize!, - minFontSize: textTheme.titleMedium!.fontSize!, ), - ), + Positioned.fill( + bottom: 10, + child: Align( + alignment: Alignment.bottomCenter, + child: AutoSizeText( + category.name!, + style: context.theme.typography.h3.copyWith( + color: Colors.white, + shadows: [ + // stroke shadow + const Shadow( + color: Colors.black, + offset: Offset(1, 1), + blurRadius: 2, + ), + ], + ), + maxLines: 1, + textAlign: TextAlign.center, + maxFontSize: context.theme.typography.h3.fontSize!, + minFontSize: context.theme.typography.large.fontSize!, + ), + ), + ), + ], ), ); }, diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index 84c40a2f..606bba34 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -161,18 +161,19 @@ class RootApp extends HookConsumerWidget { useEndlessPlayback(ref); final backgroundColor = Theme.of(context).colorScheme.background; + final brightness = Theme.of(context).brightness; useEffect(() { SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( statusBarColor: backgroundColor, // status bar color - statusBarIconBrightness: backgroundColor.computeLuminance() > 0.179 - ? Brightness.dark - : Brightness.light, + statusBarIconBrightness: brightness == Brightness.dark + ? Brightness.light + : Brightness.dark, ), ); return null; - }, [backgroundColor]); + }, [backgroundColor, brightness]); final navTileNames = useMemoized(() { return getSidebarTileList(context.l10n).map((s) => s.name).toList(); From d53782da23fb4ce44c1337b141d1c575fb739e30 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 28 Dec 2024 14:30:25 +0600 Subject: [PATCH 20/81] refactor: playlist and album pages --- .fvm/fvm_config.json | 2 +- .fvmrc | 2 +- .vscode/settings.json | 2 +- .../adaptive/adaptive_pop_sheet_list.dart | 31 +- lib/components/heart_button/heart_button.dart | 50 +-- lib/components/sort_tracks_dropdown.dart | 88 ----- .../presentation_actions.dart | 220 +++++++++++ .../track_presentation/presentation_list.dart | 84 +++++ .../presentation_modifiers.dart | 117 ++++++ .../presentation_props.dart} | 67 ++-- .../presentation_state.dart | 157 ++++++++ .../track_presentation/presentation_top.dart | 262 +++++++++++++ .../sort_tracks_dropdown.dart | 70 ++++ .../track_presentation.dart | 72 ++++ .../use_action_callbacks.dart | 135 +++++++ .../use_is_user_playlist.dart | 0 .../use_track_tile_play_callback.dart | 84 +++++ lib/components/track_tile/track_tile.dart | 354 ++++++++++-------- .../sections/body/track_view_body.dart | 192 ---------- .../body/track_view_body_headers.dart | 105 ------ .../sections/body/track_view_options.dart | 140 ------- .../sections/header/flexible_header.dart | 167 --------- .../sections/header/header_actions.dart | 111 ------ .../sections/header/header_buttons.dart | 206 ---------- lib/components/tracks_view/track_view.dart | 52 --- .../tracks_view/track_view_provider.dart | 64 ---- lib/l10n/app_en.arb | 7 +- lib/main.dart | 4 + lib/modules/root/sidebar.dart | 4 +- .../settings/section_card_with_heading.dart | 6 +- lib/pages/album/album.dart | 80 ++-- lib/pages/library/local_folder.dart | 2 +- lib/pages/playlist/liked_playlist.dart | 48 +-- lib/pages/playlist/playlist.dart | 93 ++--- .../xcshareddata/xcschemes/Runner.xcscheme | 1 + pubspec.lock | 48 +-- untranslated_messages.json | 182 +++++++-- 37 files changed, 1793 insertions(+), 1516 deletions(-) delete mode 100644 lib/components/sort_tracks_dropdown.dart create mode 100644 lib/components/track_presentation/presentation_actions.dart create mode 100644 lib/components/track_presentation/presentation_list.dart create mode 100644 lib/components/track_presentation/presentation_modifiers.dart rename lib/components/{tracks_view/track_view_props.dart => track_presentation/presentation_props.dart} (60%) create mode 100644 lib/components/track_presentation/presentation_state.dart create mode 100644 lib/components/track_presentation/presentation_top.dart create mode 100644 lib/components/track_presentation/sort_tracks_dropdown.dart create mode 100644 lib/components/track_presentation/track_presentation.dart create mode 100644 lib/components/track_presentation/use_action_callbacks.dart rename lib/components/{tracks_view/sections/body => track_presentation}/use_is_user_playlist.dart (100%) create mode 100644 lib/components/track_presentation/use_track_tile_play_callback.dart delete mode 100644 lib/components/tracks_view/sections/body/track_view_body.dart delete mode 100644 lib/components/tracks_view/sections/body/track_view_body_headers.dart delete mode 100644 lib/components/tracks_view/sections/body/track_view_options.dart delete mode 100644 lib/components/tracks_view/sections/header/flexible_header.dart delete mode 100644 lib/components/tracks_view/sections/header/header_actions.dart delete mode 100644 lib/components/tracks_view/sections/header/header_buttons.dart delete mode 100644 lib/components/tracks_view/track_view.dart delete mode 100644 lib/components/tracks_view/track_view_provider.dart diff --git a/.fvm/fvm_config.json b/.fvm/fvm_config.json index 41b45a53..7572d05e 100644 --- a/.fvm/fvm_config.json +++ b/.fvm/fvm_config.json @@ -1,3 +1,3 @@ { - "flutterSdkVersion": "3.27.1" + "flutterSdkVersion": "3.28.0-0.1.pre" } \ No newline at end of file diff --git a/.fvmrc b/.fvmrc index d1af5d57..089fa312 100644 --- a/.fvmrc +++ b/.fvmrc @@ -1,4 +1,4 @@ { - "flutter": "3.27.1", + "flutter": "3.28.0-0.1.pre", "flavors": {} } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 4d76417f..a5548411 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -28,5 +28,5 @@ "README.md": "LICENSE,CODE_OF_CONDUCT.md,CONTRIBUTING.md,SECURITY.md,CONTRIBUTION.md,CHANGELOG.md,PRIVACY_POLICY.md", "*.dart": "${capture}.g.dart,${capture}.freezed.dart" }, - "dart.flutterSdkPath": ".fvm/versions/3.27.1" + "dart.flutterSdkPath": ".fvm/versions/3.28.0-0.1.pre" } \ No newline at end of file diff --git a/lib/components/adaptive/adaptive_pop_sheet_list.dart b/lib/components/adaptive/adaptive_pop_sheet_list.dart index 63499e8a..d81ca977 100644 --- a/lib/components/adaptive/adaptive_pop_sheet_list.dart +++ b/lib/components/adaptive/adaptive_pop_sheet_list.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart' show ListTile, showModalBottomSheet; +import 'package:flutter/material.dart' show showModalBottomSheet; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -39,6 +39,8 @@ class AdaptivePopSheetList extends StatelessWidget { final Offset offset; + final ButtonVariance variance; + const AdaptivePopSheetList({ super.key, required this.children, @@ -49,6 +51,7 @@ class AdaptivePopSheetList extends StatelessWidget { this.onSelected, required this.tooltip, this.offset = Offset.zero, + this.variance = ButtonVariance.ghost, }) : assert( !(icon != null && child != null), 'Either icon or child must be provided', @@ -79,7 +82,7 @@ class AdaptivePopSheetList extends StatelessWidget { }).toList(); if (mediaQuery.mdAndUp) { - await showDropdown( + await showDropdown( context: context, rootOverlay: useRootNavigator, // heightConstraint: PopoverConstraint.anchorFixedSize, @@ -113,19 +116,21 @@ class AdaptivePopSheetList extends StatelessWidget { itemBuilder: (context, index) { final data = childrenModified[index]; - return ListTile( - dense: true, - leading: data.leading, - title: data.child, + return Button( enabled: data.enabled, - trailing: data.trailing, - focusNode: data.focusNode, - onTap: () { + style: ButtonVariance.ghost.copyWith( + padding: (context, state, value) => const EdgeInsets.all(16), + ), + onPressed: () { data.onPressed?.call(context); if (data.autoClose) { Navigator.of(context).pop(); } }, + leading: data.leading, + trailing: data.trailing, + alignment: Alignment.centerLeft, + child: data.child, ); }, ); @@ -142,7 +147,8 @@ class AdaptivePopSheetList extends StatelessWidget { tooltip: TooltipContainer( child: Text(tooltip), ), - child: IconButton.ghost( + child: IconButton( + variance: variance, icon: icon ?? const Icon(SpotubeIcons.moreVertical), onPressed: () { final renderBox = context.findRenderObject() as RenderBox; @@ -167,7 +173,7 @@ class AdaptivePopSheetList extends StatelessWidget { tooltip: TooltipContainer(child: Text(tooltip)), child: Button( onPressed: () => showDropdownMenu(context, Offset.zero), - style: const ButtonStyle.ghost(), + style: variance, child: IgnorePointer(child: child), ), ); @@ -175,7 +181,8 @@ class AdaptivePopSheetList extends StatelessWidget { return Tooltip( tooltip: TooltipContainer(child: Text(tooltip)), - child: IconButton.ghost( + child: IconButton( + variance: variance, icon: icon ?? const Icon(SpotubeIcons.moreVertical), onPressed: () => showDropdownMenu(context, Offset.zero), ), diff --git a/lib/components/heart_button/heart_button.dart b/lib/components/heart_button/heart_button.dart index fa4318cc..56cb22ab 100644 --- a/lib/components/heart_button/heart_button.dart +++ b/lib/components/heart_button/heart_button.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/heart_button/use_track_toggle_like.dart'; @@ -13,12 +13,16 @@ class HeartButton extends HookConsumerWidget { final IconData? icon; final Color? color; final String? tooltip; + final ButtonVariance variance; + final ButtonSize size; const HeartButton({ required this.isLiked, required this.onPressed, this.color, this.tooltip, this.icon, + this.variance = ButtonVariance.ghost, + this.size = ButtonSize.normal, super.key, }); @@ -28,28 +32,32 @@ class HeartButton extends HookConsumerWidget { if (auth.asData?.value == null) return const SizedBox.shrink(); - return IconButton( - tooltip: tooltip, - icon: AnimatedSwitcher( - switchInCurve: Curves.fastOutSlowIn, - switchOutCurve: Curves.fastOutSlowIn, - duration: const Duration(milliseconds: 300), - transitionBuilder: (child, animation) { - return ScaleTransition( - scale: animation, - child: child, - ); - }, - child: Icon( - icon ?? - (isLiked - ? Icons.favorite_rounded - : Icons.favorite_outline_rounded), - key: ValueKey(isLiked), - color: color ?? (isLiked ? color ?? Colors.red : null), + return Tooltip( + tooltip: TooltipContainer(child: Text(tooltip ?? "")), + child: IconButton( + variance: variance, + size: size, + icon: AnimatedSwitcher( + switchInCurve: Curves.fastOutSlowIn, + switchOutCurve: Curves.fastOutSlowIn, + duration: const Duration(milliseconds: 300), + transitionBuilder: (child, animation) { + return ScaleTransition( + scale: animation, + child: child, + ); + }, + child: Icon( + icon ?? + (isLiked + ? Icons.favorite_rounded + : Icons.favorite_outline_rounded), + key: ValueKey(isLiked), + color: color ?? (isLiked ? color ?? Colors.red : null), + ), ), + onPressed: onPressed, ), - onPressed: onPressed, ); } } diff --git a/lib/components/sort_tracks_dropdown.dart b/lib/components/sort_tracks_dropdown.dart deleted file mode 100644 index 4f65e738..00000000 --- a/lib/components/sort_tracks_dropdown.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/modules/library/user_local_tracks.dart'; -import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; -import 'package:spotube/extensions/context.dart'; - -class SortTracksDropdown extends StatelessWidget { - final SortBy? value; - final void Function(SortBy)? onChanged; - const SortTracksDropdown({ - this.onChanged, - this.value, - super.key, - }); - - @override - Widget build(BuildContext context) { - var theme = Theme.of(context); - return ListTileTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - child: AdaptivePopSheetList( - children: [ - AdaptiveMenuButton( - value: SortBy.none, - enabled: value != SortBy.none, - child: Text(context.l10n.none), - ), - AdaptiveMenuButton( - value: SortBy.ascending, - enabled: value != SortBy.ascending, - child: Text(context.l10n.sort_a_z), - ), - AdaptiveMenuButton( - value: SortBy.descending, - enabled: value != SortBy.descending, - child: Text(context.l10n.sort_z_a), - ), - AdaptiveMenuButton( - value: SortBy.newest, - enabled: value != SortBy.newest, - child: Text(context.l10n.sort_newest), - ), - AdaptiveMenuButton( - value: SortBy.oldest, - enabled: value != SortBy.oldest, - child: Text(context.l10n.sort_oldest), - ), - AdaptiveMenuButton( - value: SortBy.duration, - enabled: value != SortBy.duration, - child: Text(context.l10n.sort_duration), - ), - AdaptiveMenuButton( - value: SortBy.artist, - enabled: value != SortBy.artist, - child: Text(context.l10n.sort_artist), - ), - AdaptiveMenuButton( - value: SortBy.album, - enabled: value != SortBy.album, - child: Text(context.l10n.sort_album), - ), - ], - headings: [ - Text(context.l10n.sort_tracks), - ], - onSelected: onChanged, - tooltip: context.l10n.sort_tracks, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), - child: DefaultTextStyle( - style: theme.textTheme.titleSmall!, - child: Row( - children: [ - const Icon(SpotubeIcons.sort), - const SizedBox(width: 8), - Text(context.l10n.sort_tracks), - ], - ), - ), - ), - ), - ); - } -} diff --git a/lib/components/track_presentation/presentation_actions.dart b/lib/components/track_presentation/presentation_actions.dart new file mode 100644 index 00000000..41f518d0 --- /dev/null +++ b/lib/components/track_presentation/presentation_actions.dart @@ -0,0 +1,220 @@ +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; +import 'package:spotube/components/dialogs/confirm_download_dialog.dart'; +import 'package:spotube/components/dialogs/playlist_add_track_dialog.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/presentation_state.dart'; +import 'package:spotube/extensions/context.dart'; +import 'package:spotube/models/database/database.dart'; +import 'package:spotube/provider/download_manager_provider.dart'; +import 'package:spotube/provider/history/history.dart'; +import 'package:spotube/provider/audio_player/audio_player.dart'; +import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; + +class TrackPresentationActionsSection extends HookConsumerWidget { + const TrackPresentationActionsSection({super.key}); + + showToastForAction(BuildContext context, String action, int count) { + final message = switch (action) { + "download" => (context.l10n.download_count(count), SpotubeIcons.download), + "add-to-playlist" => ( + context.l10n.add_count_to_playlist(count), + SpotubeIcons.playlistAdd + ), + "add-to-queue" => ( + context.l10n.add_count_to_queue(count), + SpotubeIcons.queueAdd + ), + "play-next" => ( + context.l10n.play_count_next(count), + SpotubeIcons.lightning + ), + _ => ("", SpotubeIcons.error), + }; + + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Basic( + leading: Icon(message.$2), + title: Text(message.$1), + leadingAlignment: Alignment.center, + trailing: IconButton.ghost( + size: ButtonSize.small, + icon: const Icon(SpotubeIcons.close), + onPressed: () { + overlay.close(); + }, + ), + ), + ); + }, + ); + } + + @override + Widget build(BuildContext context, ref) { + final options = TrackPresentationOptions.of(context); + + ref.watch(downloadManagerProvider); + final downloader = ref.watch(downloadManagerProvider.notifier); + final playlistNotifier = ref.watch(audioPlayerProvider.notifier); + final historyNotifier = ref.watch(playbackHistoryActionsProvider); + final audioSource = + ref.watch(userPreferencesProvider.select((s) => s.audioSource)); + + final state = ref.watch(presentationStateProvider(options.collection)); + final notifier = + ref.watch(presentationStateProvider(options.collection).notifier); + final selectedTracks = state.selectedTracks; + + return AdaptivePopSheetList( + tooltip: context.l10n.more_actions, + headings: [ + Text( + context.l10n.more_actions, + style: context.theme.typography.large, + ), + ], + onSelected: (action) async { + var tracks = selectedTracks; + + if (selectedTracks.isEmpty) { + tracks = await options.pagination.onFetchAll(); + + notifier.selectAllTracks(); + } + + if (!context.mounted) return; + + switch (action) { + case "download": + { + final confirmed = audioSource == AudioSource.piped || + await showDialog( + context: context, + builder: (context) { + return const ConfirmDownloadDialog(); + }, + ); + if (confirmed != true) return; + downloader.batchAddToQueue(tracks); + notifier.deselectAllTracks(); + if (!context.mounted) return; + showToastForAction(context, action, tracks.length); + break; + } + case "add-to-playlist": + { + if (context.mounted) { + final worked = await showDialog( + context: context, + builder: (context) { + return PlaylistAddTrackDialog( + openFromPlaylist: options.collectionId, + tracks: tracks.toList(), + ); + }, + ); + + if (!context.mounted || worked != true) return; + showToastForAction(context, action, tracks.length); + } + break; + } + case "play-next": + { + playlistNotifier.addTracksAtFirst(tracks); + playlistNotifier.addCollection(options.collectionId); + if (options.collection is AlbumSimple) { + historyNotifier.addAlbums([options.collection as AlbumSimple]); + } else { + historyNotifier + .addPlaylists([options.collection as PlaylistSimple]); + } + notifier.deselectAllTracks(); + if (!context.mounted) return; + showToastForAction(context, action, tracks.length); + break; + } + case "add-to-queue": + { + playlistNotifier.addTracks(tracks); + playlistNotifier.addCollection(options.collectionId); + if (options.collection is AlbumSimple) { + historyNotifier.addAlbums([options.collection as AlbumSimple]); + } else { + historyNotifier + .addPlaylists([options.collection as PlaylistSimple]); + } + notifier.deselectAllTracks(); + if (!context.mounted) return; + showToastForAction(context, action, tracks.length); + break; + } + default: + } + + if (!context.mounted) return; + }, + icon: const Icon(SpotubeIcons.moreVertical), + variance: ButtonVariance.outline, + children: [ + AdaptiveMenuButton( + value: "download", + leading: const Icon(SpotubeIcons.download), + child: selectedTracks.isEmpty || + selectedTracks.length == options.tracks.length + ? Text( + context.l10n.download_all, + ) + : Text( + context.l10n.download_count(selectedTracks.length), + ), + ), + AdaptiveMenuButton( + value: "add-to-playlist", + leading: const Icon(SpotubeIcons.playlistAdd), + child: selectedTracks.isEmpty || + selectedTracks.length == options.tracks.length + ? Text( + context.l10n.add_all_to_playlist, + ) + : Text( + context.l10n.add_count_to_playlist(selectedTracks.length), + ), + ), + AdaptiveMenuButton( + value: "add-to-queue", + leading: const Icon(SpotubeIcons.queueAdd), + child: selectedTracks.isEmpty || + selectedTracks.length == options.tracks.length + ? Text( + context.l10n.add_all_to_queue, + ) + : Text( + context.l10n.add_count_to_queue(selectedTracks.length), + ), + ), + AdaptiveMenuButton( + value: "play-next", + leading: const Icon(SpotubeIcons.lightning), + child: selectedTracks.isEmpty || + selectedTracks.length == options.tracks.length + ? Text( + context.l10n.play_all_next, + ) + : Text( + context.l10n.play_count_next(selectedTracks.length), + ), + ), + ], + ); + } +} diff --git a/lib/components/track_presentation/presentation_list.dart b/lib/components/track_presentation/presentation_list.dart new file mode 100644 index 00000000..55b4c46d --- /dev/null +++ b/lib/components/track_presentation/presentation_list.dart @@ -0,0 +1,84 @@ +import 'package:flutter/services.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:skeletonizer/skeletonizer.dart'; +import 'package:spotube/collections/fake.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/presentation_state.dart'; +import 'package:spotube/components/track_presentation/use_track_tile_play_callback.dart'; +import 'package:spotube/components/track_tile/track_tile.dart'; +import 'package:spotube/components/track_presentation/use_is_user_playlist.dart'; +import 'package:spotube/provider/audio_player/audio_player.dart'; +import 'package:very_good_infinite_list/very_good_infinite_list.dart'; + +class PresentationListSection extends HookConsumerWidget { + const PresentationListSection({super.key}); + + @override + Widget build(BuildContext context, ref) { + final options = TrackPresentationOptions.of(context); + final playlist = ref.watch(audioPlayerProvider); + final state = ref.watch(presentationStateProvider(options.collection)); + final notifier = + ref.read(presentationStateProvider(options.collection).notifier); + final isUserPlaylist = useIsUserPlaylist(ref, options.collectionId); + + final onTileTap = useTrackTilePlayCallback(ref); + + return SliverInfiniteList( + isLoading: options.pagination.isLoading, + onFetchData: options.pagination.onFetchMore, + itemCount: state.presentationTracks.length, + hasReachedMax: !options.pagination.hasNextPage, + loadingBuilder: (context) { + return Skeletonizer( + enabled: true, + child: TrackTile( + index: 0, + playlist: playlist, + track: FakeData.track, + ), + ); + }, + emptyBuilder: (context) => Skeletonizer( + enabled: true, + child: Column( + children: List.generate( + 10, + (index) => TrackTile( + track: FakeData.track, + index: index, + playlist: playlist, + ), + ), + ), + ), + itemBuilder: (context, index) { + final track = state.presentationTracks[index]; + final isSelected = state.selectedTracks.any((e) => e.id == track.id); + return TrackTile( + userPlaylist: isUserPlaylist, + playlistId: options.collectionId, + index: index, + playlist: playlist, + track: track, + selected: isSelected, + onTap: () => onTileTap(track, index), + onChanged: state.selectedTracks.isEmpty + ? null + : (isSelected) { + if (isSelected == true) { + notifier.selectTrack(track); + } else { + notifier.deselectTrack(track); + } + }, + onLongPress: () { + notifier.selectTrack(track); + HapticFeedback.selectionClick(); + }, + ); + }, + ); + } +} diff --git a/lib/components/track_presentation/presentation_modifiers.dart b/lib/components/track_presentation/presentation_modifiers.dart new file mode 100644 index 00000000..d1678e17 --- /dev/null +++ b/lib/components/track_presentation/presentation_modifiers.dart @@ -0,0 +1,117 @@ +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/track_presentation/sort_tracks_dropdown.dart'; +import 'package:spotube/components/track_presentation/presentation_actions.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/presentation_state.dart'; +import 'package:spotube/extensions/constrains.dart'; +import 'package:spotube/extensions/context.dart'; + +class TrackPresentationModifiersSection extends HookConsumerWidget { + const TrackPresentationModifiersSection({super.key}); + + @override + Widget build(BuildContext context, ref) { + final options = TrackPresentationOptions.of(context); + final state = ref.watch(presentationStateProvider(options.collection)); + final notifier = ref.watch( + presentationStateProvider(options.collection).notifier, + ); + + final controller = useTextEditingController(); + + return LayoutBuilder(builder: (context, constrains) { + return Padding( + padding: EdgeInsets.symmetric( + horizontal: constrains.mdAndUp ? 16 : 8, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Checkbox( + state: state.selectedTracks.length == options.tracks.length + ? CheckboxState.checked + : CheckboxState.unchecked, + onChanged: (value) { + if (value == CheckboxState.checked) { + notifier.selectAllTracks(); + } else { + notifier.deselectAllTracks(); + } + }, + ), + ], + ), + Flexible( + child: Row( + mainAxisSize: MainAxisSize.min, + spacing: 8, + children: [ + Flexible( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 320, + ), + child: TextField( + controller: controller, + leading: Icon( + SpotubeIcons.search, + color: context.theme.colorScheme.mutedForeground, + ), + placeholder: Text(context.l10n.search_tracks), + onChanged: (value) { + if (value.isEmpty) { + notifier.clearFilter(); + } else { + notifier.filterTracks(value); + } + }, + trailing: ListenableBuilder( + listenable: controller, + builder: (context, _) { + return AnimatedCrossFade( + duration: const Duration(milliseconds: 300), + crossFadeState: controller.text.isEmpty + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + firstChild: + const SizedBox.square(dimension: 20), + secondChild: AnimatedScale( + duration: const Duration(milliseconds: 300), + scale: controller.text.isEmpty ? 0 : 1, + child: IconButton.ghost( + size: const ButtonSize(.6), + icon: const Icon(SpotubeIcons.close), + onPressed: () { + controller.clear(); + notifier.clearFilter(); + }, + ), + ), + ); + }), + ), + ), + ), + SortTracksDropdown( + value: state.sortBy, + onChanged: (value) { + notifier.sortTracks(value); + }, + ), + const TrackPresentationActionsSection(), + ], + ), + ), + ], + ), + ); + }); + } +} diff --git a/lib/components/tracks_view/track_view_props.dart b/lib/components/track_presentation/presentation_props.dart similarity index 60% rename from lib/components/tracks_view/track_view_props.dart rename to lib/components/track_presentation/presentation_props.dart index b0a00ae2..144cf0e8 100644 --- a/lib/components/tracks_view/track_view_props.dart +++ b/lib/components/track_presentation/presentation_props.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:flutter/material.dart' hide Page; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; class PaginationProps { @@ -38,31 +38,33 @@ class PaginationProps { onRefresh.hashCode; } -class InheritedTrackView extends InheritedWidget { +class TrackPresentationOptions { final Object collection; final String title; final String? description; + final String? owner; + final String? ownerImage; final String image; final String routePath; final List tracks; final PaginationProps pagination; final bool isLiked; - final String shareUrl; + final String? shareUrl; // events final FutureOr Function()? onHeart; // if null heart button will hidden - const InheritedTrackView({ - super.key, - required super.child, + const TrackPresentationOptions({ required this.collection, required this.title, this.description, + this.owner, + this.ownerImage, required this.image, required this.tracks, required this.pagination, required this.routePath, - required this.shareUrl, + this.shareUrl, this.isLiked = false, this.onHeart, }) : assert(collection is AlbumSimple || collection is PlaylistSimple); @@ -71,29 +73,36 @@ class InheritedTrackView extends InheritedWidget { ? (collection as AlbumSimple).id! : (collection as PlaylistSimple).id!; - @override - bool updateShouldNotify(InheritedTrackView oldWidget) { - return oldWidget.title != title || - oldWidget.description != description || - oldWidget.image != image || - oldWidget.tracks != tracks || - oldWidget.pagination != pagination || - oldWidget.isLiked != isLiked || - oldWidget.onHeart != onHeart || - oldWidget.shareUrl != shareUrl || - oldWidget.routePath != routePath || - oldWidget.collection != collection || - oldWidget.child != child; + static TrackPresentationOptions of(BuildContext context) { + return Data.of(context); } - static InheritedTrackView of(BuildContext context) { - final widget = - context.dependOnInheritedWidgetOfExactType(); - if (widget == null) { - throw Exception( - 'InheritedTrackView not found. Make sure to wrap [TrackView] with [InheritedTrackView]', - ); - } - return widget; + @override + operator ==(Object other) { + return other is TrackPresentationOptions && + other.collection == collection && + other.title == title && + other.description == description && + other.image == image && + other.routePath == routePath && + other.tracks == tracks && + other.pagination == pagination && + other.isLiked == isLiked && + other.shareUrl == shareUrl && + other.onHeart == onHeart; } + + @override + int get hashCode => + super.hashCode ^ + collection.hashCode ^ + title.hashCode ^ + description.hashCode ^ + image.hashCode ^ + routePath.hashCode ^ + tracks.hashCode ^ + pagination.hashCode ^ + isLiked.hashCode ^ + shareUrl.hashCode ^ + onHeart.hashCode; } diff --git a/lib/components/track_presentation/presentation_state.dart b/lib/components/track_presentation/presentation_state.dart new file mode 100644 index 00000000..11ca9809 --- /dev/null +++ b/lib/components/track_presentation/presentation_state.dart @@ -0,0 +1,157 @@ +import 'package:collection/collection.dart'; +import 'package:fuzzywuzzy/fuzzywuzzy.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotify/spotify.dart'; +import 'package:spotube/modules/library/user_local_tracks.dart'; +import 'package:spotube/provider/spotify/spotify.dart'; +import 'package:spotube/utils/service_utils.dart'; + +class PresentationState { + final List selectedTracks; + final List presentationTracks; + final SortBy sortBy; + + const PresentationState({ + required this.selectedTracks, + required this.presentationTracks, + required this.sortBy, + }); + + PresentationState copyWith({ + List? selectedTracks, + List? presentationTracks, + SortBy? sortBy, + }) { + return PresentationState( + selectedTracks: selectedTracks ?? this.selectedTracks, + presentationTracks: presentationTracks ?? this.presentationTracks, + sortBy: sortBy ?? this.sortBy, + ); + } +} + +class PresentationStateNotifier + extends AutoDisposeFamilyNotifier { + @override + PresentationState build(collection) { + final isPlaylist = arg is PlaylistSimple; + + if ((isPlaylist && (arg as PlaylistSimple).id != "user-liked-tracks") || + arg is AlbumSimple) { + ref.listen( + isPlaylist + ? playlistTracksProvider((arg as PlaylistSimple).id!) + : albumTracksProvider((arg as AlbumSimple)), + (previous, next) { + next.whenData((value) { + state = state.copyWith( + presentationTracks: ServiceUtils.sortTracks( + value.items, + state.sortBy, + ), + ); + }); + }, + ); + } + + return PresentationState( + selectedTracks: [], + presentationTracks: tracks, + sortBy: SortBy.none, + ); + } + + List get tracks { + assert( + arg is PlaylistSimple || arg is AlbumSimple, + "arg must be PlaylistSimple or AlbumSimple", + ); + + final isPlaylist = arg is PlaylistSimple; + final isSavedTrackPlaylist = + isPlaylist && (arg as PlaylistSimple).id == "user-liked-tracks"; + final tracks = switch ((isPlaylist, isSavedTrackPlaylist)) { + (true, true) => ref.read(likedTracksProvider).asData?.value, + (true, false) => ref + .read(playlistTracksProvider((arg as PlaylistSimple).id!)) + .asData + ?.value + .items, + _ => ref + .read(albumTracksProvider((arg as AlbumSimple))) + .asData + ?.value + .items, + } ?? + []; + + return tracks; + } + + void selectTrack(Track track) { + if (state.selectedTracks.any((e) => e.id == track.id)) { + return; + } + + state = state.copyWith( + selectedTracks: [...state.selectedTracks, track], + ); + } + + void selectAllTracks() { + state = state.copyWith( + selectedTracks: tracks, + ); + } + + void deselectTrack(Track track) { + state = state.copyWith( + selectedTracks: state.selectedTracks.where((e) => e != track).toList(), + ); + } + + void deselectAllTracks() { + state = state.copyWith( + selectedTracks: [], + ); + } + + void filterTracks(String query) { + if (query.isEmpty) { + return; + } + + state = state.copyWith( + presentationTracks: ServiceUtils.sortTracks( + tracks + .map((e) => (weightedRatio(e.name!, query), e)) + .sorted((a, b) => b.$1.compareTo(a.$1)) + .where((e) => e.$1 > 50) + .map((e) => e.$2) + .toList(), + state.sortBy, + ), + ); + } + + void clearFilter() { + state = state.copyWith( + presentationTracks: ServiceUtils.sortTracks(tracks, state.sortBy), + ); + } + + void sortTracks(SortBy sortBy) { + state = state.copyWith( + presentationTracks: sortBy == SortBy.none + ? tracks + : ServiceUtils.sortTracks(state.presentationTracks, sortBy), + sortBy: sortBy, + ); + } +} + +final presentationStateProvider = AutoDisposeNotifierProviderFamily< + PresentationStateNotifier, PresentationState, Object>( + () => PresentationStateNotifier(), +); diff --git a/lib/components/track_presentation/presentation_top.dart b/lib/components/track_presentation/presentation_top.dart new file mode 100644 index 00000000..59854aaf --- /dev/null +++ b/lib/components/track_presentation/presentation_top.dart @@ -0,0 +1,262 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/services.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/heart_button/heart_button.dart'; +import 'package:spotube/components/image/universal_image.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/use_action_callbacks.dart'; +import 'package:spotube/components/track_presentation/use_is_user_playlist.dart'; +import 'package:spotube/extensions/constrains.dart'; +import 'package:spotube/extensions/context.dart'; +import 'package:spotube/modules/playlist/playlist_create_dialog.dart'; + +class TrackPresentationTopSection extends HookConsumerWidget { + const TrackPresentationTopSection({super.key}); + + @override + Widget build(BuildContext context, ref) { + final mediaQuery = MediaQuery.sizeOf(context); + final options = TrackPresentationOptions.of(context); + final scale = context.theme.scaling; + final isUserPlaylist = useIsUserPlaylist(ref, options.collectionId); + + final imageDimension = mediaQuery.mdAndUp ? 200 : 120; + + final (:isLoading, :isActive, :onPlay, :onShuffle) = + useActionCallbacks(ref); + + final playbackActions = Row( + spacing: 8 * scale, + children: [ + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.shuffle_playlist), + ), + child: IconButton.secondary( + icon: isLoading + ? const Center( + child: + CircularProgressIndicator(onSurface: false, size: 20), + ) + : const Icon(SpotubeIcons.shuffle), + enabled: !isLoading && !isActive, + onPressed: onShuffle, + ), + ), + if (mediaQuery.width <= 320) + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.add_to_queue), + ), + child: IconButton.secondary( + icon: const Icon(SpotubeIcons.queueAdd), + enabled: !isLoading && !isActive, + onPressed: () {}, + ), + ) + else + Button.secondary( + leading: const Icon(SpotubeIcons.add), + enabled: !isLoading && !isActive, + child: Text(context.l10n.queue), + onPressed: () {}, + ), + Button.primary( + alignment: Alignment.center, + leading: switch ((isActive, isLoading)) { + (true, false) => const Icon(SpotubeIcons.pause), + (false, true) => const Center( + child: CircularProgressIndicator(onSurface: true, size: 18), + ), + _ => const Icon(SpotubeIcons.play), + }, + onPressed: onPlay, + enabled: !isLoading && !isActive, + child: isActive ? Text(context.l10n.pause) : Text(context.l10n.play), + ), + ], + ); + + final additionalActions = Row( + spacing: 8 * scale, + children: [ + if (isUserPlaylist) + IconButton.outline( + size: ButtonSize.small, + icon: const Icon(SpotubeIcons.edit), + onPressed: () { + showDialog( + context: context, + builder: (context) { + return PlaylistCreateDialog( + playlistId: options.collectionId, + trackIds: options.tracks.map((e) => e.id!).toList(), + ); + }, + ); + }, + ), + if (options.shareUrl != null) + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.share), + ), + child: IconButton.outline( + icon: const Icon(SpotubeIcons.share), + size: ButtonSize.small, + onPressed: () async { + await Clipboard.setData( + ClipboardData(text: options.shareUrl!), + ); + + if (!context.mounted) return; + + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n + .copied_shareurl_to_clipboard(options.shareUrl!), + ).small(), + ); + }, + ); + }, + ), + ), + if (options.onHeart != null) + HeartButton( + isLiked: options.isLiked, + tooltip: options.isLiked + ? context.l10n.remove_from_favorites + : context.l10n.save_as_favorite, + variance: ButtonVariance.outline, + size: ButtonSize.small, + onPressed: options.onHeart, + ), + ], + ); + + return SliverMainAxisGroup( + slivers: [ + if (mediaQuery.mdAndUp) SliverGap(16 * scale), + SliverPadding( + padding: EdgeInsets.symmetric( + horizontal: (mediaQuery.mdAndUp ? 16 : 8.0) * scale, + ), + sliver: SliverList.list( + children: [ + DecoratedBox( + decoration: BoxDecoration( + image: DecorationImage( + image: UniversalImage.imageProvider(options.image), + fit: BoxFit.cover, + ), + borderRadius: BorderRadius.circular(45), + ), + child: OutlinedContainer( + surfaceOpacity: context.theme.surfaceOpacity, + surfaceBlur: context.theme.surfaceBlur, + padding: EdgeInsets.all(24 * scale), + borderRadius: BorderRadius.circular(22 * scale), + borderWidth: 2, + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: 16 * scale, + children: [ + Row( + spacing: 16 * scale, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Container( + height: imageDimension * scale, + width: imageDimension * scale, + decoration: BoxDecoration( + borderRadius: context.theme.borderRadiusXl, + image: DecorationImage( + image: + UniversalImage.imageProvider(options.image), + fit: BoxFit.cover, + ), + ), + ), + Flexible( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AutoSizeText( + options.title, + maxLines: 2, + minFontSize: 16, + style: context.theme.typography.h3, + ), + if (options.description != null) + AutoSizeText( + options.description!, + maxLines: 2, + minFontSize: 14, + maxFontSize: 18, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: context + .theme.colorScheme.mutedForeground, + fontSize: 18, + ), + ), + const Gap(16), + Flex( + crossAxisAlignment: CrossAxisAlignment.start, + direction: mediaQuery.smAndUp + ? Axis.horizontal + : Axis.vertical, + spacing: 8 * scale, + children: [ + if (options.owner != null) + OutlineBadge( + leading: options.ownerImage != null + ? Avatar( + initials: + options.owner?[0] ?? "U", + provider: UniversalImage + .imageProvider( + options.ownerImage!, + ), + ) + : null, + child: Text( + options.owner!, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ).small(), + ), + additionalActions, + ], + ), + if (mediaQuery.mdAndUp) ...[ + const Gap(16), + playbackActions + ], + ], + ), + ), + ], + ), + if (mediaQuery.smAndDown) playbackActions, + ], + ), + ), + ), + ], + ), + ) + ], + ); + } +} diff --git a/lib/components/track_presentation/sort_tracks_dropdown.dart b/lib/components/track_presentation/sort_tracks_dropdown.dart new file mode 100644 index 00000000..543bacb3 --- /dev/null +++ b/lib/components/track_presentation/sort_tracks_dropdown.dart @@ -0,0 +1,70 @@ +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/modules/library/user_local_tracks.dart'; +import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; +import 'package:spotube/extensions/context.dart'; + +class SortTracksDropdown extends StatelessWidget { + final SortBy? value; + final void Function(SortBy)? onChanged; + const SortTracksDropdown({ + this.onChanged, + this.value, + super.key, + }); + + @override + Widget build(BuildContext context) { + return AdaptivePopSheetList( + variance: ButtonVariance.outline, + headings: [ + Text(context.l10n.sort_tracks), + ], + onSelected: onChanged, + tooltip: context.l10n.sort_tracks, + icon: const Icon(SpotubeIcons.sort), + children: [ + AdaptiveMenuButton( + value: SortBy.none, + enabled: value != SortBy.none, + child: Text(context.l10n.none), + ), + AdaptiveMenuButton( + value: SortBy.ascending, + enabled: value != SortBy.ascending, + child: Text(context.l10n.sort_a_z), + ), + AdaptiveMenuButton( + value: SortBy.descending, + enabled: value != SortBy.descending, + child: Text(context.l10n.sort_z_a), + ), + AdaptiveMenuButton( + value: SortBy.newest, + enabled: value != SortBy.newest, + child: Text(context.l10n.sort_newest), + ), + AdaptiveMenuButton( + value: SortBy.oldest, + enabled: value != SortBy.oldest, + child: Text(context.l10n.sort_oldest), + ), + AdaptiveMenuButton( + value: SortBy.duration, + enabled: value != SortBy.duration, + child: Text(context.l10n.sort_duration), + ), + AdaptiveMenuButton( + value: SortBy.artist, + enabled: value != SortBy.artist, + child: Text(context.l10n.sort_artist), + ), + AdaptiveMenuButton( + value: SortBy.album, + enabled: value != SortBy.album, + child: Text(context.l10n.sort_album), + ), + ], + ); + } +} diff --git a/lib/components/track_presentation/track_presentation.dart b/lib/components/track_presentation/track_presentation.dart new file mode 100644 index 00000000..8bc1c6df --- /dev/null +++ b/lib/components/track_presentation/track_presentation.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart' show ListTile; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotube/components/titlebar/titlebar.dart'; +import 'package:spotube/components/track_presentation/presentation_list.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/presentation_top.dart'; +import 'package:spotube/components/track_presentation/presentation_modifiers.dart'; +import 'package:spotube/extensions/constrains.dart'; +import 'package:spotube/extensions/context.dart'; + +class TrackPresentation extends HookConsumerWidget { + final TrackPresentationOptions options; + const TrackPresentation({ + super.key, + required this.options, + }); + + @override + Widget build(BuildContext context, ref) { + final headerTextStyle = context.theme.typography.small.copyWith( + color: context.theme.colorScheme.mutedForeground, + ); + + return Data.inherit( + data: options, + child: SafeArea( + child: Scaffold( + headers: const [TitleBar()], + child: CustomScrollView( + slivers: [ + const TrackPresentationTopSection(), + const SliverGap(16), + SliverLayoutBuilder( + builder: (context, constrains) { + return SliverList.list( + children: [ + const TrackPresentationModifiersSection(), + ListTile( + titleTextStyle: headerTextStyle, + subtitleTextStyle: headerTextStyle, + leadingAndTrailingTextStyle: headerTextStyle, + leading: constrains.mdAndUp ? const Text(" #") : null, + title: Row( + children: [ + Expanded( + flex: constrains.lgAndUp ? 5 : 6, + child: Text(context.l10n.title), + ), + if (constrains.mdAndUp) + Expanded( + flex: 3, + child: Text(context.l10n.album), + ), + Text(context.l10n.duration), + ], + ), + ), + ], + ); + }, + ), + const PresentationListSection(), + const SliverGap(200), + ], + ), + ), + ), + ); + } +} diff --git a/lib/components/track_presentation/use_action_callbacks.dart b/lib/components/track_presentation/use_action_callbacks.dart new file mode 100644 index 00000000..e9b9c98e --- /dev/null +++ b/lib/components/track_presentation/use_action_callbacks.dart @@ -0,0 +1,135 @@ +import 'dart:math'; + +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotify/spotify.dart'; +import 'package:spotube/components/dialogs/select_device_dialog.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; + +import 'package:spotube/models/connect/connect.dart'; +import 'package:spotube/provider/audio_player/audio_player.dart'; +import 'package:spotube/provider/connect/connect.dart'; +import 'package:spotube/provider/history/history.dart'; +import 'package:spotube/services/audio_player/audio_player.dart'; + +typedef UseActionCallbacks = ({ + bool isActive, + bool isLoading, + Future Function() onShuffle, + Future Function() onPlay, +}); + +UseActionCallbacks useActionCallbacks(WidgetRef ref) { + final isLoading = useState(false); + final context = useContext(); + final options = TrackPresentationOptions.of(context); + final playlist = ref.watch(audioPlayerProvider); + final playlistNotifier = ref.watch(audioPlayerProvider.notifier); + final historyNotifier = ref.watch(playbackHistoryActionsProvider); + + final isActive = useMemoized( + () => playlist.collections.contains(options.collectionId), + [playlist.collections, options.collectionId], + ); + + final onShuffle = useCallback(() async { + try { + isLoading.value = true; + + final initialTracks = options.tracks; + if (!context.mounted) return; + + final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice) { + final allTracks = await options.pagination.onFetchAll(); + final remotePlayback = ref.read(connectProvider.notifier); + await remotePlayback.load( + options.collection is AlbumSimple + ? WebSocketLoadEventData.album( + tracks: allTracks, + collection: options.collection as AlbumSimple, + initialIndex: Random().nextInt(allTracks.length)) + : WebSocketLoadEventData.playlist( + tracks: allTracks, + collection: options.collection as PlaylistSimple, + initialIndex: Random().nextInt(allTracks.length), + ), + ); + await remotePlayback.setShuffle(true); + } else { + await playlistNotifier.load( + initialTracks, + autoPlay: true, + initialIndex: Random().nextInt(initialTracks.length), + ); + await audioPlayer.setShuffle(true); + playlistNotifier.addCollection(options.collectionId); + if (options.collection is AlbumSimple) { + historyNotifier.addAlbums([options.collection as AlbumSimple]); + } else { + historyNotifier.addPlaylists([options.collection as PlaylistSimple]); + } + + final allTracks = await options.pagination.onFetchAll(); + + await playlistNotifier.addTracks( + allTracks.sublist(initialTracks.length), + ); + } + } finally { + isLoading.value = false; + } + }, [options, playlistNotifier, historyNotifier]); + + final onPlay = useCallback(() async { + try { + isLoading.value = true; + + final initialTracks = options.tracks; + + if (!context.mounted) return; + + final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice) { + final allTracks = await options.pagination.onFetchAll(); + final remotePlayback = ref.read(connectProvider.notifier); + await remotePlayback.load( + options.collection is AlbumSimple + ? WebSocketLoadEventData.album( + tracks: allTracks, + collection: options.collection as AlbumSimple, + ) + : WebSocketLoadEventData.playlist( + tracks: allTracks, + collection: options.collection as PlaylistSimple, + ), + ); + } else { + await playlistNotifier.load(initialTracks, autoPlay: true); + playlistNotifier.addCollection(options.collectionId); + if (options.collection is AlbumSimple) { + historyNotifier.addAlbums([options.collection as AlbumSimple]); + } else { + historyNotifier.addPlaylists([options.collection as PlaylistSimple]); + } + + final allTracks = await options.pagination.onFetchAll(); + + await playlistNotifier.addTracks( + allTracks.sublist(initialTracks.length), + ); + } + } finally { + if (context.mounted) { + isLoading.value = false; + } + } + }, [options, playlistNotifier, historyNotifier]); + + return ( + isActive: isActive, + isLoading: isLoading.value, + onShuffle: onShuffle, + onPlay: onPlay, + ); +} diff --git a/lib/components/tracks_view/sections/body/use_is_user_playlist.dart b/lib/components/track_presentation/use_is_user_playlist.dart similarity index 100% rename from lib/components/tracks_view/sections/body/use_is_user_playlist.dart rename to lib/components/track_presentation/use_is_user_playlist.dart diff --git a/lib/components/track_presentation/use_track_tile_play_callback.dart b/lib/components/track_presentation/use_track_tile_play_callback.dart new file mode 100644 index 00000000..261d01d8 --- /dev/null +++ b/lib/components/track_presentation/use_track_tile_play_callback.dart @@ -0,0 +1,84 @@ +import 'package:hooks_riverpod/hooks_riverpod.dart'; + +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:spotify/spotify.dart'; +import 'package:spotube/components/dialogs/select_device_dialog.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/presentation_state.dart'; +import 'package:spotube/extensions/list.dart'; + +import 'package:spotube/models/connect/connect.dart'; +import 'package:spotube/provider/audio_player/audio_player.dart'; +import 'package:spotube/provider/connect/connect.dart'; +import 'package:spotube/provider/history/history.dart'; + +Future Function(Track track, int index) useTrackTilePlayCallback( + WidgetRef ref, +) { + final context = useContext(); + final options = TrackPresentationOptions.of(context); + final playlist = ref.watch(audioPlayerProvider); + final playlistNotifier = ref.watch(audioPlayerProvider.notifier); + final historyNotifier = ref.watch(playbackHistoryActionsProvider); + + final isActive = useMemoized( + () => playlist.collections.contains(options.collectionId), + [playlist.collections, options.collectionId], + ); + + final onTapTrackTile = useCallback((Track track, int index) async { + final state = ref.read(presentationStateProvider(options.collection)); + final notifier = + ref.read(presentationStateProvider(options.collection).notifier); + + if (state.selectedTracks.isNotEmpty) { + notifier.selectTrack(track); + return; + } + + final isRemoteDevice = await showSelectDeviceDialog(context, ref); + + if (isRemoteDevice) { + final remotePlayback = ref.read(connectProvider.notifier); + final remoteQueue = ref.read(queueProvider); + if (remoteQueue.collections.contains(options.collectionId) || + remoteQueue.tracks.any((s) => s.id == track.id)) { + await playlistNotifier.jumpToTrack(track); + } else { + final tracks = await options.pagination.onFetchAll(); + await remotePlayback.load( + options.collection is AlbumSimple + ? WebSocketLoadEventData.album( + tracks: tracks, + collection: options.collection as AlbumSimple, + initialIndex: index, + ) + : WebSocketLoadEventData.playlist( + tracks: tracks, + collection: options.collection as PlaylistSimple, + initialIndex: index, + ), + ); + } + } else { + if (isActive || playlist.tracks.containsBy(track, (a) => a.id)) { + await playlistNotifier.jumpToTrack(track); + } else { + final tracks = await options.pagination.onFetchAll(); + await playlistNotifier.load( + tracks, + initialIndex: index, + autoPlay: true, + ); + playlistNotifier.addCollection(options.collectionId); + if (options.collection is AlbumSimple) { + historyNotifier.addAlbums([options.collection as AlbumSimple]); + } else { + historyNotifier.addPlaylists([options.collection as PlaylistSimple]); + } + } + } + }, [isActive, playlist, options, playlistNotifier, historyNotifier]); + + return onTapTrackTile; +} diff --git a/lib/components/track_tile/track_tile.dart b/lib/components/track_tile/track_tile.dart index 8ab889f8..560d2255 100644 --- a/lib/components/track_tile/track_tile.dart +++ b/lib/components/track_tile/track_tile.dart @@ -1,10 +1,11 @@ import 'dart:async'; import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show ListTile, Material, MaterialType; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; + import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -88,78 +89,98 @@ class TrackTile extends HookConsumerWidget { }, child: HoverBuilder( permanentState: isSelected || constrains.smAndDown ? true : null, - builder: (context, isHovering) => ListTile( - selected: isSelected, - onTap: () async { - try { - isLoading.value = true; - await onTap?.call(); - } finally { - if (context.mounted) { - isLoading.value = false; + builder: (context, isHovering) => Material( + type: MaterialType.transparency, + child: ListTile( + selectedColor: theme.colorScheme.primary, + selectedTileColor: theme.colorScheme.primary.withOpacity(0.1), + selected: isSelected, + onTap: () async { + try { + isLoading.value = true; + await onTap?.call(); + } finally { + if (context.mounted) { + isLoading.value = false; + } } - } - }, - onLongPress: onLongPress, - enabled: !isBlackListed, - contentPadding: EdgeInsets.zero, - tileColor: isBlackListed ? theme.colorScheme.errorContainer : null, - horizontalTitleGap: 12, - leadingAndTrailingTextStyle: theme.textTheme.bodyMedium, - leading: Row( - mainAxisSize: MainAxisSize.min, - children: [ - ...?leadingActions, - if (index != null && onChanged == null && constrains.mdAndUp) - SizedBox( - width: 50, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 6), - child: Text( - '${(index ?? 0) + 1}', - maxLines: 1, - style: theme.textTheme.bodySmall, - textAlign: TextAlign.center, - ), + }, + onLongPress: onLongPress, + enabled: !isBlackListed, + contentPadding: EdgeInsets.zero, + tileColor: isBlackListed ? theme.colorScheme.destructive : null, + horizontalTitleGap: 12, + leadingAndTrailingTextStyle: theme.typography.normal.copyWith( + color: theme.colorScheme.foreground, + ), + titleTextStyle: theme.typography.normal.copyWith( + color: theme.colorScheme.foreground, + ), + subtitleTextStyle: theme.typography.xSmall.copyWith( + color: theme.colorScheme.mutedForeground, + ), + leading: Row( + mainAxisSize: MainAxisSize.min, + children: [ + ...?leadingActions, + AnimatedCrossFade( + duration: const Duration(milliseconds: 300), + crossFadeState: index != null && onChanged == null + ? CrossFadeState.showSecond + : CrossFadeState.showFirst, + firstChild: Checkbox( + state: selected + ? CheckboxState.checked + : CheckboxState.unchecked, + onChanged: (state) => + onChanged?.call(state == CheckboxState.checked), ), - ) - else if (constrains.smAndDown) - const SizedBox(width: 16), - if (onChanged != null) - Checkbox( - value: selected, - onChanged: onChanged, - ), - Stack( - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(4), - child: AspectRatio( - aspectRatio: 1, - child: UniversalImage( - path: (track.album?.images).asUrlString( - placeholder: ImagePlaceholder.albumArt, + secondChild: constrains.smAndDown + ? const SizedBox(width: 16) + : SizedBox( + width: 50, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 6), + child: Text( + '${(index ?? 0) + 1}', + maxLines: 1, + style: theme.typography.small, + textAlign: TextAlign.center, + ), + ), ), - fit: BoxFit.cover, - ), - ), - ), - Positioned.fill( - child: AnimatedContainer( - duration: const Duration(milliseconds: 300), + ), + Stack( + children: [ + Container( + height: 40, + width: 40, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4), - color: isHovering - ? Colors.black.withOpacity(0.4) - : Colors.transparent, + borderRadius: theme.borderRadiusMd, + image: DecorationImage( + fit: BoxFit.cover, + image: UniversalImage.imageProvider( + (track.album?.images).asUrlString( + placeholder: ImagePlaceholder.albumArt, + ), + ), + ), ), ), - ), - Positioned.fill( - child: Center( - child: IconTheme( - data: theme.iconTheme - .copyWith(size: 26, color: Colors.white), + Positioned.fill( + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), + decoration: BoxDecoration( + borderRadius: theme.borderRadiusMd, + color: isHovering + ? Colors.black.withOpacity(0.4) + : Colors.transparent, + ), + ), + ), + Positioned.fill( + child: Center( child: Skeleton.ignore( child: Consumer( builder: (context, ref, _) { @@ -167,119 +188,126 @@ class TrackTile extends HookConsumerWidget { ref.watch(queryingTrackInfoProvider); return AnimatedSwitcher( duration: const Duration(milliseconds: 300), - child: (isPlaying && isFetchingActiveTrack) || - isLoading.value - ? const SizedBox( - width: 26, - height: 26, - child: CircularProgressIndicator( - strokeWidth: 1.5, - color: Colors.white, - ), - ) - : isPlaying - ? Icon( - SpotubeIcons.pause, - color: theme.colorScheme.primary, - ) - : !isHovering - ? const SizedBox.shrink() - : const Icon(SpotubeIcons.play), + child: switch (( + isPlaying, + isFetchingActiveTrack, + isPlaying, + isHovering, + isLoading.value + )) { + (true, true, _, _, _) || + (_, _, _, _, true) => + const SizedBox( + width: 26, + height: 26, + child: CircularProgressIndicator( + size: 1.5), + ), + (_, _, true, _, _) => Icon( + SpotubeIcons.pause, + color: theme.colorScheme.primary, + ), + (_, _, _, true, _) => const Icon( + SpotubeIcons.play, + color: Colors.white, + ), + _ => const SizedBox.shrink(), + }, ); }, ), ), ), ), - ), - ], - ), - ], - ), - title: Row( - children: [ - Expanded( - flex: 6, - child: switch (track) { - LocalTrack() => Text( - track.name!, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - _ => LinkText( - track.name!, - "/track/${track.id}", - push: true, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - }, - ), - if (constrains.mdAndUp) ...[ - const SizedBox(width: 8), + ], + ), + ], + ), + title: Row( + children: [ Expanded( - flex: 4, + flex: 6, child: switch (track) { LocalTrack() => Text( - track.album!.name!, + track.name!, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + _ => LinkText( + track.name!, + "/track/${track.id}", + push: true, maxLines: 1, overflow: TextOverflow.ellipsis, ), - _ => Align( - alignment: Alignment.centerLeft, - child: LinkText( - track.album!.name!, - "/album/${track.album?.id}", - extra: track.album, - push: true, - overflow: TextOverflow.ellipsis, - ), - ) }, ), + if (constrains.mdAndUp) ...[ + const SizedBox(width: 8), + Expanded( + flex: 4, + child: switch (track) { + LocalTrack() => Text( + track.album!.name!, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + _ => Align( + alignment: Alignment.centerLeft, + child: LinkText( + track.album!.name!, + "/album/${track.album?.id}", + extra: track.album, + push: true, + overflow: TextOverflow.ellipsis, + ), + ) + }, + ), + ], ], - ], - ), - subtitle: Align( - alignment: Alignment.centerLeft, - child: track is LocalTrack - ? Text( - track.artists?.asString() ?? '', - ) - : ClipRect( - child: ConstrainedBox( - constraints: const BoxConstraints(maxHeight: 40), - child: ArtistLink( - artists: track.artists ?? [], - onOverflowArtistClick: () => ServiceUtils.pushNamed( - context, - TrackPage.name, - pathParameters: { - "id": track.id!, - }, + ), + subtitle: Align( + alignment: Alignment.centerLeft, + child: track is LocalTrack + ? Text( + track.artists?.asString() ?? '', + ) + : ClipRect( + child: ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 40), + child: ArtistLink( + artists: track.artists ?? [], + onOverflowArtistClick: () => ServiceUtils.pushNamed( + context, + TrackPage.name, + pathParameters: { + "id": track.id!, + }, + ), ), ), ), - ), - ), - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox(width: 8), - Text( - Duration(milliseconds: track.durationMs ?? 0) - .toHumanReadableString(padZero: false), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - TrackOptions( - track: track, - playlistId: playlistId, - userPlaylist: userPlaylist, - showMenuCbRef: showOptionCbRef, - ), - if (kIsDesktop) const Gap(10), - ], + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(width: 8), + Text( + Duration(milliseconds: track.durationMs ?? 0) + .toHumanReadableString(padZero: false), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + TrackOptions( + track: track, + playlistId: playlistId, + userPlaylist: userPlaylist, + showMenuCbRef: showOptionCbRef, + ), + if (kIsDesktop) const Gap(10), + ], + ), ), ), ), diff --git a/lib/components/tracks_view/sections/body/track_view_body.dart b/lib/components/tracks_view/sections/body/track_view_body.dart deleted file mode 100644 index 0f161b0c..00000000 --- a/lib/components/tracks_view/sections/body/track_view_body.dart +++ /dev/null @@ -1,192 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:fuzzywuzzy/fuzzywuzzy.dart'; -import 'package:gap/gap.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:skeletonizer/skeletonizer.dart'; -import 'package:spotify/spotify.dart'; -import 'package:spotube/collections/fake.dart'; -import 'package:spotube/components/dialogs/select_device_dialog.dart'; -import 'package:spotube/components/expandable_search/expandable_search.dart'; -import 'package:spotube/components/track_tile/track_tile.dart'; -import 'package:spotube/components/tracks_view/sections/body/track_view_body_headers.dart'; -import 'package:spotube/components/tracks_view/sections/body/use_is_user_playlist.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; -import 'package:spotube/components/tracks_view/track_view_provider.dart'; -import 'package:spotube/extensions/list.dart'; -import 'package:spotube/models/connect/connect.dart'; -import 'package:spotube/provider/connect/connect.dart'; -import 'package:spotube/provider/history/history.dart'; -import 'package:spotube/provider/audio_player/audio_player.dart'; -import 'package:spotube/utils/service_utils.dart'; -import 'package:very_good_infinite_list/very_good_infinite_list.dart'; - -class TrackViewBodySection extends HookConsumerWidget { - const TrackViewBodySection({super.key}); - - @override - Widget build(BuildContext context, ref) { - final playlist = ref.watch(audioPlayerProvider); - final playlistNotifier = ref.watch(audioPlayerProvider.notifier); - final historyNotifier = ref.watch(playbackHistoryActionsProvider); - final props = InheritedTrackView.of(context); - final trackViewState = ref.watch(trackViewProvider(props.tracks)); - - final searchController = useTextEditingController(); - final searchFocus = useFocusNode(); - - useValueListenable(searchController); - final searchQuery = searchController.text; - - final isFiltering = useState(false); - - final uniqTracks = useMemoized(() { - final trackIds = props.tracks.map((e) => e.id).toSet(); - return props.tracks.where((e) => trackIds.remove(e.id)).toList(); - }, [props.tracks]); - - final tracks = useMemoized(() { - List filteredTracks; - if (searchQuery.isEmpty) { - filteredTracks = uniqTracks; - } else { - filteredTracks = uniqTracks - .map((e) => (weightedRatio(e.name!, searchQuery), e)) - .sorted((a, b) => b.$1.compareTo(a.$1)) - .where((e) => e.$1 > 50) - .map((e) => e.$2) - .toList(); - } - return ServiceUtils.sortTracks(filteredTracks, trackViewState.sortBy); - }, [trackViewState.sortBy, searchQuery, uniqTracks]); - - final isUserPlaylist = useIsUserPlaylist(ref, props.collectionId); - - final isActive = playlist.collections.contains(props.collectionId); - - final onTapTrackTile = useCallback((Track track, int index) async { - if (trackViewState.isSelecting) { - trackViewState.toggleTrackSelection(track.id!); - return; - } - - final isRemoteDevice = await showSelectDeviceDialog(context, ref); - - if (isRemoteDevice) { - final remotePlayback = ref.read(connectProvider.notifier); - final remoteQueue = ref.read(queueProvider); - if (remoteQueue.collections.contains(props.collectionId) || - remoteQueue.tracks.any((s) => s.id == track.id)) { - await playlistNotifier.jumpToTrack(track); - } else { - final tracks = await props.pagination.onFetchAll(); - await remotePlayback.load( - props.collection is AlbumSimple - ? WebSocketLoadEventData.album( - tracks: tracks, - collection: props.collection as AlbumSimple, - initialIndex: index, - ) - : WebSocketLoadEventData.playlist( - tracks: tracks, - collection: props.collection as PlaylistSimple, - initialIndex: index, - ), - ); - } - } else { - if (isActive || playlist.tracks.containsBy(track, (a) => a.id)) { - await playlistNotifier.jumpToTrack(track); - } else { - final tracks = await props.pagination.onFetchAll(); - await playlistNotifier.load( - tracks, - initialIndex: index, - autoPlay: true, - ); - playlistNotifier.addCollection(props.collectionId); - if (props.collection is AlbumSimple) { - historyNotifier.addAlbums([props.collection as AlbumSimple]); - } else { - historyNotifier.addPlaylists([props.collection as PlaylistSimple]); - } - } - } - }, [isActive, playlist, props, playlistNotifier, historyNotifier]); - - return SliverMainAxisGroup( - slivers: [ - SliverToBoxAdapter( - child: TrackViewBodyHeaders( - isFiltering: isFiltering, - searchFocus: searchFocus, - ), - ), - const SliverGap(8), - SliverToBoxAdapter( - child: ExpandableSearchField( - isFiltering: isFiltering.value, - onChangeFiltering: (value) { - isFiltering.value = value; - }, - searchController: searchController, - searchFocus: searchFocus, - ), - ), - SliverSafeArea( - top: false, - sliver: SliverInfiniteList( - itemCount: tracks.length, - onFetchData: props.pagination.onFetchMore, - isLoading: props.pagination.isLoading, - hasReachedMax: !props.pagination.hasNextPage, - loadingBuilder: (context) => Skeletonizer( - enabled: true, - child: TrackTile( - playlist: playlist, - track: FakeData.track, - index: 0, - ), - ), - emptyBuilder: (context) => Skeletonizer( - enabled: true, - child: Column( - children: List.generate( - 10, - (index) => TrackTile( - track: FakeData.track, - index: index, - playlist: playlist, - ), - ), - ), - ), - itemBuilder: (context, index) { - final track = tracks[index]; - return TrackTile( - playlist: playlist, - track: track, - index: index, - selected: trackViewState.selectedTrackIds.contains(track.id!), - playlistId: props.collectionId, - userPlaylist: isUserPlaylist, - onChanged: !trackViewState.isSelecting - ? null - : (value) { - trackViewState.toggleTrackSelection(track.id!); - }, - onLongPress: () { - trackViewState.selectTrack(track.id!); - HapticFeedback.selectionClick(); - }, - onTap: () => onTapTrackTile(track, index), - ); - }, - ), - ), - ], - ); - } -} diff --git a/lib/components/tracks_view/sections/body/track_view_body_headers.dart b/lib/components/tracks_view/sections/body/track_view_body_headers.dart deleted file mode 100644 index 82cc7706..00000000 --- a/lib/components/tracks_view/sections/body/track_view_body_headers.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotube/components/expandable_search/expandable_search.dart'; -import 'package:spotube/components/sort_tracks_dropdown.dart'; -import 'package:spotube/components/tracks_view/sections/body/track_view_options.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; -import 'package:spotube/components/tracks_view/track_view_provider.dart'; -import 'package:spotube/extensions/constrains.dart'; -import 'package:spotube/extensions/context.dart'; -import 'package:spotube/utils/platform.dart'; - -class TrackViewBodyHeaders extends HookConsumerWidget { - final ValueNotifier isFiltering; - final FocusNode searchFocus; - - const TrackViewBodyHeaders({ - super.key, - required this.isFiltering, - required this.searchFocus, - }); - - @override - Widget build(BuildContext context, ref) { - final ThemeData(:textTheme) = Theme.of(context); - final props = InheritedTrackView.of(context); - final trackViewState = ref.watch(trackViewProvider(props.tracks)); - return LayoutBuilder( - builder: (context, constrains) { - return Row( - children: [ - AnimatedSwitcher( - duration: const Duration(milliseconds: 200), - transitionBuilder: (child, animation) { - return FadeTransition( - opacity: animation, - child: ScaleTransition( - scale: animation, - child: child, - ), - ); - }, - child: Checkbox( - value: trackViewState.hasSelectedAll, - onChanged: (checked) { - if (checked == true) { - trackViewState.selectAll(); - } else { - trackViewState.deselectAll(); - } - }, - ), - ), - Expanded( - flex: 7, - child: Row( - children: [ - Text( - context.l10n.title, - style: textTheme.bodyLarge, - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - // used alignment of this table-head - if (constrains.mdAndUp) - Expanded( - flex: 3, - child: Row( - children: [ - Text( - context.l10n.album, - overflow: TextOverflow.ellipsis, - style: textTheme.bodyLarge, - ), - ], - ), - ), - SortTracksDropdown( - value: trackViewState.sortBy, - onChanged: (value) { - trackViewState.sort(value); - }, - ), - ExpandableSearchButton( - isFiltering: isFiltering.value, - searchFocus: searchFocus, - onPressed: (value) { - isFiltering.value = value; - if (value) { - searchFocus.requestFocus(); - } else { - searchFocus.unfocus(); - } - }, - ), - const TrackViewBodyOptions(), - if (kIsDesktop) const Gap(10), - ], - ); - }, - ); - } -} diff --git a/lib/components/tracks_view/sections/body/track_view_options.dart b/lib/components/tracks_view/sections/body/track_view_options.dart deleted file mode 100644 index 7114d713..00000000 --- a/lib/components/tracks_view/sections/body/track_view_options.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotify/spotify.dart'; -import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; -import 'package:spotube/components/dialogs/confirm_download_dialog.dart'; -import 'package:spotube/components/dialogs/playlist_add_track_dialog.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; -import 'package:spotube/components/tracks_view/track_view_provider.dart'; -import 'package:spotube/extensions/context.dart'; -import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/download_manager_provider.dart'; -import 'package:spotube/provider/history/history.dart'; -import 'package:spotube/provider/audio_player/audio_player.dart'; -import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; - -class TrackViewBodyOptions extends HookConsumerWidget { - const TrackViewBodyOptions({super.key}); - - @override - Widget build(BuildContext context, ref) { - final props = InheritedTrackView.of(context); - final ThemeData(:textTheme) = Theme.of(context); - - ref.watch(downloadManagerProvider); - final downloader = ref.watch(downloadManagerProvider.notifier); - final playlistNotifier = ref.watch(audioPlayerProvider.notifier); - final historyNotifier = ref.watch(playbackHistoryActionsProvider); - final audioSource = - ref.watch(userPreferencesProvider.select((s) => s.audioSource)); - - final trackViewState = ref.watch(trackViewProvider(props.tracks)); - final selectedTracks = trackViewState.selectedTracks; - - return AdaptivePopSheetList( - tooltip: context.l10n.more_actions, - headings: [ - Text( - context.l10n.more_actions, - style: textTheme.bodyLarge, - ), - ], - onSelected: (action) async { - switch (action) { - case "download": - { - final confirmed = audioSource == AudioSource.piped || - await showDialog( - context: context, - builder: (context) { - return const ConfirmDownloadDialog(); - }, - ); - if (confirmed != true) return; - await downloader.batchAddToQueue(selectedTracks); - trackViewState.deselectAll(); - break; - } - case "add-to-playlist": - { - if (context.mounted) { - await showDialog( - context: context, - builder: (context) { - return PlaylistAddTrackDialog( - openFromPlaylist: props.collectionId, - tracks: selectedTracks.toList(), - ); - }, - ); - } - break; - } - case "play-next": - { - playlistNotifier.addTracksAtFirst(selectedTracks); - playlistNotifier.addCollection(props.collectionId); - if (props.collection is AlbumSimple) { - historyNotifier.addAlbums([props.collection as AlbumSimple]); - } else { - historyNotifier - .addPlaylists([props.collection as PlaylistSimple]); - } - trackViewState.deselectAll(); - break; - } - case "add-to-queue": - { - playlistNotifier.addTracks(selectedTracks); - playlistNotifier.addCollection(props.collectionId); - if (props.collection is AlbumSimple) { - historyNotifier.addAlbums([props.collection as AlbumSimple]); - } else { - historyNotifier - .addPlaylists([props.collection as PlaylistSimple]); - } - trackViewState.deselectAll(); - break; - } - default: - } - }, - icon: const Icon(SpotubeIcons.moreVertical), - children: [ - AdaptiveMenuButton( - value: "download", - leading: const Icon(SpotubeIcons.download), - enabled: selectedTracks.isNotEmpty, - child: Text( - context.l10n.download_count(selectedTracks.length), - ), - ), - AdaptiveMenuButton( - value: "add-to-playlist", - leading: const Icon(SpotubeIcons.playlistAdd), - enabled: selectedTracks.isNotEmpty, - child: Text( - context.l10n.add_count_to_playlist(selectedTracks.length), - ), - ), - AdaptiveMenuButton( - enabled: selectedTracks.isNotEmpty, - value: "add-to-queue", - leading: const Icon(SpotubeIcons.queueAdd), - child: Text( - context.l10n.add_count_to_queue(selectedTracks.length), - ), - ), - AdaptiveMenuButton( - enabled: selectedTracks.isNotEmpty, - value: "play-next", - leading: const Icon(SpotubeIcons.lightning), - child: Text( - context.l10n.play_count_next(selectedTracks.length), - ), - ), - ], - ); - } -} diff --git a/lib/components/tracks_view/sections/header/flexible_header.dart b/lib/components/tracks_view/sections/header/flexible_header.dart deleted file mode 100644 index 508d289c..00000000 --- a/lib/components/tracks_view/sections/header/flexible_header.dart +++ /dev/null @@ -1,167 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; - -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotube/collections/assets.gen.dart'; -import 'package:spotube/components/image/universal_image.dart'; -import 'package:spotube/components/tracks_view/sections/header/header_actions.dart'; -import 'package:spotube/components/tracks_view/sections/header/header_buttons.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; -import 'package:gap/gap.dart'; -import 'package:spotube/extensions/constrains.dart'; -import 'package:spotube/extensions/string.dart'; -import 'package:spotube/hooks/utils/use_palette_color.dart'; -import 'package:spotube/utils/platform.dart'; - -class TrackViewFlexHeader extends HookConsumerWidget { - const TrackViewFlexHeader({super.key}); - - @override - Widget build(BuildContext context, ref) { - final props = InheritedTrackView.of(context); - final ThemeData(:colorScheme, :textTheme, :iconTheme) = Theme.of(context); - final defaultTextStyle = DefaultTextStyle.of(context); - final mediaQuery = MediaQuery.of(context); - - final palette = usePaletteColor(props.image, ref); - - return IconTheme( - data: iconTheme.copyWith(color: palette.bodyTextColor), - child: SliverLayoutBuilder( - builder: (context, constrains) { - final isExpanded = constrains.scrollOffset < 350; - - final headingStyle = (mediaQuery.mdAndDown - ? textTheme.headlineSmall - : textTheme.headlineMedium) - ?.copyWith( - color: palette.bodyTextColor, - ); - return SliverAppBar( - iconTheme: iconTheme.copyWith( - color: palette.bodyTextColor, - size: 16, - ), - actions: isExpanded - ? [] - : [ - const TrackViewHeaderActions(), - TrackViewHeaderButtons(compact: true, color: palette), - ], - floating: false, - pinned: true, - expandedHeight: 450, - automaticallyImplyLeading: kIsMobile, - backgroundColor: palette.color, - title: isExpanded ? null : Text(props.title, style: headingStyle), - flexibleSpace: FlexibleSpaceBar( - background: Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - image: DecorationImage( - image: UniversalImage.imageProvider(props.image), - fit: BoxFit.cover, - ), - ), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: DecoratedBox( - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - Colors.black45, - colorScheme.surface, - ], - begin: const FractionalOffset(0, 0), - end: const FractionalOffset(0, 1), - tileMode: TileMode.clamp, - ), - ), - child: SafeArea( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - ConstrainedBox( - constraints: BoxConstraints( - maxWidth: mediaQuery.mdAndDown - ? mediaQuery.size.width - : 800, - ), - child: Flex( - direction: mediaQuery.mdAndDown - ? Axis.vertical - : Axis.horizontal, - mainAxisSize: MainAxisSize.min, - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(10), - child: UniversalImage( - path: props.image, - width: 200, - height: 200, - placeholder: Assets.albumPlaceholder.path, - ), - ), - const Gap(20), - Flexible( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: mediaQuery.mdAndDown - ? CrossAxisAlignment.center - : CrossAxisAlignment.start, - children: [ - Text( - props.title, - style: headingStyle, - textAlign: mediaQuery.mdAndDown - ? TextAlign.center - : TextAlign.start, - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 10), - if (props.description != null && - props.description!.isNotEmpty) - Text( - props.description! - .unescapeHtml() - .cleanHtml(), - style: - defaultTextStyle.style.copyWith( - color: palette.bodyTextColor, - ), - textAlign: mediaQuery.mdAndDown - ? TextAlign.center - : TextAlign.start, - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - const Gap(10), - const TrackViewHeaderActions(), - const Gap(10), - TrackViewHeaderButtons(color: palette), - ], - ), - ), - ], - ), - ), - ], - ), - ), - ), - ), - ), - ), - ), - ); - }, - ), - ); - } -} diff --git a/lib/components/tracks_view/sections/header/header_actions.dart b/lib/components/tracks_view/sections/header/header_actions.dart deleted file mode 100644 index 8e378f97..00000000 --- a/lib/components/tracks_view/sections/header/header_actions.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:go_router/go_router.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotify/spotify.dart'; -import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/modules/playlist/playlist_create_dialog.dart'; -import 'package:spotube/components/heart_button/heart_button.dart'; -import 'package:spotube/components/tracks_view/sections/body/use_is_user_playlist.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; -import 'package:spotube/extensions/context.dart'; -import 'package:spotube/provider/authentication/authentication.dart'; -import 'package:spotube/provider/history/history.dart'; -import 'package:spotube/provider/audio_player/audio_player.dart'; - -class TrackViewHeaderActions extends HookConsumerWidget { - const TrackViewHeaderActions({super.key}); - - @override - Widget build(BuildContext context, ref) { - final props = InheritedTrackView.of(context); - - final playlist = ref.watch(audioPlayerProvider); - final playlistNotifier = ref.watch(audioPlayerProvider.notifier); - final historyNotifier = ref.watch(playbackHistoryActionsProvider); - - final isActive = playlist.collections.contains(props.collectionId); - - final isUserPlaylist = useIsUserPlaylist(ref, props.collectionId); - - final scaffoldMessenger = ScaffoldMessenger.of(context); - - final auth = ref.watch(authenticationProvider); - - final copiedText = - context.l10n.copied_shareurl_to_clipboard(props.shareUrl); - - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - IconButton( - tooltip: context.l10n.share, - icon: const Icon(SpotubeIcons.share), - onPressed: () async { - await Clipboard.setData( - ClipboardData(text: props.shareUrl), - ); - - scaffoldMessenger.showSnackBar( - SnackBar( - width: 300, - behavior: SnackBarBehavior.floating, - content: Text( - copiedText, - textAlign: TextAlign.center, - ), - ), - ); - }, - ), - IconButton( - icon: const Icon(SpotubeIcons.queueAdd), - tooltip: context.l10n.add_to_queue, - onPressed: isActive || props.tracks.isEmpty - ? null - : () async { - final tracks = await props.pagination.onFetchAll(); - await playlistNotifier.addTracks(tracks); - playlistNotifier.addCollection(props.collectionId); - if (props.collection is AlbumSimple) { - historyNotifier - .addAlbums([props.collection as AlbumSimple]); - } else { - historyNotifier - .addPlaylists([props.collection as PlaylistSimple]); - } - }, - ), - if (props.onHeart != null && auth.asData?.value != null) - HeartButton( - isLiked: props.isLiked, - icon: isUserPlaylist ? SpotubeIcons.trash : null, - tooltip: props.isLiked - ? context.l10n.remove_from_favorites - : context.l10n.save_as_favorite, - onPressed: () async { - final shouldPop = await props.onHeart?.call(); - if (isUserPlaylist && shouldPop == true && context.mounted) { - context.pop(); - } - }, - ), - if (isUserPlaylist) - IconButton( - icon: const Icon(SpotubeIcons.edit), - onPressed: () { - showDialog( - context: context, - builder: (context) { - return PlaylistCreateDialog( - playlistId: props.collectionId, - trackIds: props.tracks.map((e) => e.id!).toList(), - ); - }, - ); - }, - ), - ], - ); - } -} diff --git a/lib/components/tracks_view/sections/header/header_buttons.dart b/lib/components/tracks_view/sections/header/header_buttons.dart deleted file mode 100644 index 54e0f0cf..00000000 --- a/lib/components/tracks_view/sections/header/header_buttons.dart +++ /dev/null @@ -1,206 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:palette_generator/palette_generator.dart'; -import 'package:spotify/spotify.dart'; -import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/components/dialogs/select_device_dialog.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; -import 'package:spotube/extensions/context.dart'; -import 'package:spotube/models/connect/connect.dart'; -import 'package:spotube/provider/connect/connect.dart'; -import 'package:spotube/provider/history/history.dart'; -import 'package:spotube/provider/audio_player/audio_player.dart'; -import 'package:spotube/services/audio_player/audio_player.dart'; - -class TrackViewHeaderButtons extends HookConsumerWidget { - final PaletteColor color; - final bool compact; - const TrackViewHeaderButtons({ - super.key, - required this.color, - this.compact = false, - }); - - @override - Widget build(BuildContext context, ref) { - final props = InheritedTrackView.of(context); - final playlist = ref.watch(audioPlayerProvider); - final playlistNotifier = ref.watch(audioPlayerProvider.notifier); - final historyNotifier = ref.watch(playbackHistoryActionsProvider); - - final isActive = playlist.collections.contains(props.collectionId); - - final isLoading = useState(false); - - const progressIndicator = Center( - child: SizedBox.square( - dimension: 20, - child: CircularProgressIndicator(strokeWidth: .8), - ), - ); - - void onShuffle() async { - try { - isLoading.value = true; - - final initialTracks = props.tracks; - if (!context.mounted) return; - - final isRemoteDevice = await showSelectDeviceDialog(context, ref); - if (isRemoteDevice) { - final allTracks = await props.pagination.onFetchAll(); - final remotePlayback = ref.read(connectProvider.notifier); - await remotePlayback.load( - props.collection is AlbumSimple - ? WebSocketLoadEventData.album( - tracks: allTracks, - collection: props.collection as AlbumSimple, - initialIndex: Random().nextInt(allTracks.length)) - : WebSocketLoadEventData.playlist( - tracks: allTracks, - collection: props.collection as PlaylistSimple, - initialIndex: Random().nextInt(allTracks.length), - ), - ); - await remotePlayback.setShuffle(true); - } else { - await playlistNotifier.load( - initialTracks, - autoPlay: true, - initialIndex: Random().nextInt(initialTracks.length), - ); - await audioPlayer.setShuffle(true); - playlistNotifier.addCollection(props.collectionId); - if (props.collection is AlbumSimple) { - historyNotifier.addAlbums([props.collection as AlbumSimple]); - } else { - historyNotifier.addPlaylists([props.collection as PlaylistSimple]); - } - - final allTracks = await props.pagination.onFetchAll(); - - await playlistNotifier.addTracks( - allTracks.sublist(initialTracks.length), - ); - } - } finally { - isLoading.value = false; - } - } - - void onPlay() async { - try { - isLoading.value = true; - - final initialTracks = props.tracks; - - if (!context.mounted) return; - - final isRemoteDevice = await showSelectDeviceDialog(context, ref); - if (isRemoteDevice) { - final allTracks = await props.pagination.onFetchAll(); - final remotePlayback = ref.read(connectProvider.notifier); - await remotePlayback.load( - props.collection is AlbumSimple - ? WebSocketLoadEventData.album( - tracks: allTracks, - collection: props.collection as AlbumSimple, - ) - : WebSocketLoadEventData.playlist( - tracks: allTracks, - collection: props.collection as PlaylistSimple, - ), - ); - } else { - await playlistNotifier.load(initialTracks, autoPlay: true); - playlistNotifier.addCollection(props.collectionId); - if (props.collection is AlbumSimple) { - historyNotifier.addAlbums([props.collection as AlbumSimple]); - } else { - historyNotifier.addPlaylists([props.collection as PlaylistSimple]); - } - - final allTracks = await props.pagination.onFetchAll(); - - await playlistNotifier.addTracks( - allTracks.sublist(initialTracks.length), - ); - } - } finally { - if (context.mounted) { - isLoading.value = false; - } - } - } - - if (compact) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (!isActive && !isLoading.value) - IconButton( - icon: const Icon(SpotubeIcons.shuffle), - onPressed: props.tracks.isEmpty ? null : onShuffle, - ), - const Gap(10), - IconButton.filledTonal( - icon: isActive - ? const Icon(SpotubeIcons.pause) - : isLoading.value - ? progressIndicator - : const Icon(SpotubeIcons.play), - onPressed: isActive || props.tracks.isEmpty || isLoading.value - ? null - : onPlay, - ), - const Gap(10), - ], - ); - } - - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - AnimatedOpacity( - duration: const Duration(milliseconds: 300), - opacity: isActive || isLoading.value ? 0 : 1, - child: AnimatedSize( - duration: const Duration(milliseconds: 300), - child: SizedBox.square( - dimension: isActive || isLoading.value ? 0 : null, - child: FilledButton.icon( - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, - foregroundColor: Colors.black, - minimumSize: const Size(150, 40)), - label: Text(context.l10n.shuffle), - icon: const Icon(SpotubeIcons.shuffle), - onPressed: props.tracks.isEmpty ? null : onShuffle, - ), - ), - ), - ), - const Gap(10), - FilledButton.icon( - style: ElevatedButton.styleFrom( - backgroundColor: color.color, - foregroundColor: color.bodyTextColor, - minimumSize: const Size(150, 40)), - onPressed: isActive || props.tracks.isEmpty || isLoading.value - ? null - : onPlay, - icon: isActive - ? const Icon(SpotubeIcons.pause) - : isLoading.value - ? progressIndicator - : const Icon(SpotubeIcons.play), - label: Text(context.l10n.play), - ), - ], - ); - } -} diff --git a/lib/components/tracks_view/track_view.dart b/lib/components/tracks_view/track_view.dart deleted file mode 100644 index fa6011e0..00000000 --- a/lib/components/tracks_view/track_view.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:sliver_tools/sliver_tools.dart'; -import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; -import 'package:spotube/components/titlebar/titlebar.dart'; -import 'package:spotube/components/tracks_view/sections/header/flexible_header.dart'; -import 'package:spotube/components/tracks_view/sections/body/track_view_body.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; -import 'package:spotube/utils/platform.dart'; - -class TrackView extends HookConsumerWidget { - const TrackView({super.key}); - - @override - Widget build(BuildContext context, ref) { - final props = InheritedTrackView.of(context); - final controller = useScrollController(); - - return Scaffold( - appBar: kIsDesktop - ? const TitleBar( - backgroundColor: Colors.transparent, - leading: [ - Align( - alignment: Alignment.centerLeft, - child: BackButton(color: Colors.white), - ) - ], - ) - : null, - extendBodyBehindAppBar: true, - body: RefreshIndicator( - onRefresh: props.pagination.onRefresh, - child: InterScrollbar( - controller: controller, - child: CustomScrollView( - controller: controller, - slivers: const [ - TrackViewFlexHeader(), - SliverAnimatedSwitcher( - duration: Duration(milliseconds: 500), - child: TrackViewBodySection(), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/components/tracks_view/track_view_provider.dart b/lib/components/tracks_view/track_view_provider.dart deleted file mode 100644 index 16aa6d9c..00000000 --- a/lib/components/tracks_view/track_view_provider.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotify/spotify.dart'; -import 'package:spotube/modules/library/user_local_tracks.dart'; - -class TrackViewNotifier extends ChangeNotifier { - List tracks; - List selectedTrackIds; - SortBy sortBy; - String? searchQuery; - - TrackViewNotifier( - this.tracks, { - this.selectedTrackIds = const [], - this.sortBy = SortBy.none, - this.searchQuery, - }); - - bool get isSelecting => selectedTrackIds.isNotEmpty; - - bool get hasSelectedAll => - selectedTrackIds.length == tracks.length && tracks.isNotEmpty; - - List get selectedTracks => - tracks.where((e) => selectedTrackIds.contains(e.id)).toList(); - - void selectTrack(String trackId) { - selectedTrackIds = [...selectedTrackIds, trackId]; - notifyListeners(); - } - - void unselectTrack(String trackId) { - selectedTrackIds = selectedTrackIds.where((e) => e != trackId).toList(); - notifyListeners(); - } - - void toggleTrackSelection(String trackId) { - if (selectedTrackIds.contains(trackId)) { - unselectTrack(trackId); - } else { - selectTrack(trackId); - } - } - - void selectAll() { - selectedTrackIds = tracks.map((e) => e.id!).toList(); - notifyListeners(); - } - - void deselectAll() { - selectedTrackIds = []; - notifyListeners(); - } - - void sort(SortBy sortBy) { - this.sortBy = sortBy; - notifyListeners(); - } -} - -final trackViewProvider = ChangeNotifierProvider.autoDispose - .family>((ref, tracks) { - return TrackViewNotifier(tracks); -}); diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 5b9e5183..4109edb7 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -402,5 +402,10 @@ "found_n_files": "Found {count} files", "export_cache_confirmation": "Do you want to export these files to", "exported_n_out_of_m_files": "Exported {filesExported} out of {files} files", - "undo": "Undo" + "undo": "Undo", + "download_all": "Download all", + "add_all_to_playlist": "Add all to playlist", + "add_all_to_queue": "Add all to queue", + "play_all_next": "Play all next", + "pause": "Pause" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 0b84d38d..ecf2cc37 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart'; import 'package:flutter_discord_rpc/flutter_discord_rpc.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -225,6 +226,9 @@ class Spotube extends HookConsumerWidget { surfaceOpacity: .8, surfaceBlur: 10, ), + materialTheme: material.ThemeData( + splashFactory: material.NoSplash.splashFactory, + ), themeMode: themeMode, shortcuts: { ...WidgetsApp.defaultShortcuts.map((key, value) { diff --git a/lib/modules/root/sidebar.dart b/lib/modules/root/sidebar.dart index 1afa85c5..9a92a1cb 100644 --- a/lib/modules/root/sidebar.dart +++ b/lib/modules/root/sidebar.dart @@ -78,8 +78,8 @@ class Sidebar extends HookConsumerWidget { isLabelVisible: tile.title == "Library" && downloadCount > 0, label: Text( downloadCount.toString(), - style: const TextStyle( - color: Colors.white, + style: TextStyle( + color: context.theme.colorScheme.primaryForeground, fontSize: 10, ), ), diff --git a/lib/modules/settings/section_card_with_heading.dart b/lib/modules/settings/section_card_with_heading.dart index cd9428f0..c7bc1f26 100644 --- a/lib/modules/settings/section_card_with_heading.dart +++ b/lib/modules/settings/section_card_with_heading.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart' show ListTileTheme, ListTileThemeData; -import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide Theme, ThemeData; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; class SectionCardWithHeading extends StatelessWidget { @@ -35,7 +35,9 @@ class SectionCardWithHeading extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Text( heading, - style: context.theme.typography.large, + style: context.theme.typography.large.copyWith( + color: context.theme.colorScheme.foreground, + ), ), ), Padding( diff --git a/lib/pages/album/album.dart b/lib/pages/album/album.dart index 0c6cfd69..4a10268b 100644 --- a/lib/pages/album/album.dart +++ b/lib/pages/album/album.dart @@ -1,8 +1,8 @@ -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/components/tracks_view/track_view.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/track_presentation.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -23,43 +23,45 @@ class AlbumPage extends HookConsumerWidget { final favoriteAlbumsNotifier = ref.watch(favoriteAlbumsProvider.notifier); final isSavedAlbum = ref.watch(albumsIsSavedProvider(album.id!)); - return InheritedTrackView( - collection: album, - image: album.images.asUrlString( - placeholder: ImagePlaceholder.albumArt, + return TrackPresentation( + options: TrackPresentationOptions( + collection: album, + image: album.images.asUrlString( + placeholder: ImagePlaceholder.albumArt, + ), + title: album.name!, + description: + "${context.l10n.released} • ${album.releaseDate} • ${album.artists!.first.name}", + tracks: tracks.asData?.value.items ?? [], + pagination: PaginationProps( + hasNextPage: tracks.asData?.value.hasMore ?? false, + isLoading: tracks.isLoadingNextPage, + onFetchMore: () async { + await tracksNotifier.fetchMore(); + }, + onFetchAll: () async { + return tracksNotifier.fetchAll(); + }, + onRefresh: () async { + ref.invalidate(albumTracksProvider(album)); + }, + ), + routePath: "/album/${album.id}", + shareUrl: album.externalUrls?.spotify ?? + "https://open.spotify.com/album/${album.id}", + isLiked: isSavedAlbum.asData?.value ?? false, + owner: album.artists!.first.name, + onHeart: isSavedAlbum.asData?.value == null + ? null + : () async { + if (isSavedAlbum.asData!.value) { + await favoriteAlbumsNotifier.removeFavorites([album.id!]); + } else { + await favoriteAlbumsNotifier.addFavorites([album.id!]); + } + return null; + }, ), - title: album.name!, - description: - "${context.l10n.released} • ${album.releaseDate} • ${album.artists!.first.name}", - tracks: tracks.asData?.value.items ?? [], - pagination: PaginationProps( - hasNextPage: tracks.asData?.value.hasMore ?? false, - isLoading: tracks.isLoadingNextPage, - onFetchMore: () async { - await tracksNotifier.fetchMore(); - }, - onFetchAll: () async { - return tracksNotifier.fetchAll(); - }, - onRefresh: () async { - ref.invalidate(albumTracksProvider(album)); - }, - ), - routePath: "/album/${album.id}", - shareUrl: album.externalUrls?.spotify ?? - "https://open.spotify.com/album/${album.id}", - isLiked: isSavedAlbum.asData?.value ?? false, - onHeart: isSavedAlbum.asData?.value == null - ? null - : () async { - if (isSavedAlbum.asData!.value) { - await favoriteAlbumsNotifier.removeFavorites([album.id!]); - } else { - await favoriteAlbumsNotifier.addFavorites([album.id!]); - } - return null; - }, - child: const TrackView(), ); } } diff --git a/lib/pages/library/local_folder.dart b/lib/pages/library/local_folder.dart index 478eac5e..8cfec3a8 100644 --- a/lib/pages/library/local_folder.dart +++ b/lib/pages/library/local_folder.dart @@ -17,7 +17,7 @@ import 'package:spotube/components/expandable_search/expandable_search.dart'; import 'package:spotube/components/fallbacks/not_found.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; -import 'package:spotube/components/sort_tracks_dropdown.dart'; +import 'package:spotube/components/track_presentation/sort_tracks_dropdown.dart'; import 'package:spotube/components/track_tile/track_tile.dart'; import 'package:spotube/extensions/artist_simple.dart'; import 'package:spotube/extensions/context.dart'; diff --git a/lib/pages/playlist/liked_playlist.dart b/lib/pages/playlist/liked_playlist.dart index 942f46d5..3b4455d5 100644 --- a/lib/pages/playlist/liked_playlist.dart +++ b/lib/pages/playlist/liked_playlist.dart @@ -1,8 +1,8 @@ import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/components/tracks_view/track_view.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/track_presentation.dart'; import 'package:spotube/pages/playlist/playlist.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -20,28 +20,30 @@ class LikedPlaylistPage extends HookConsumerWidget { final likedTracks = ref.watch(likedTracksProvider); final tracks = likedTracks.asData?.value ?? []; - return InheritedTrackView( - collection: playlist, - image: "assets/liked-tracks.jpg", - pagination: PaginationProps( - hasNextPage: false, - isLoading: false, - onFetchMore: () {}, - onFetchAll: () async { - return tracks.toList(); - }, - onRefresh: () async { - ref.invalidate(likedTracksProvider); - }, + return TrackPresentation( + options: TrackPresentationOptions( + collection: playlist, + image: "assets/liked-tracks.jpg", + pagination: PaginationProps( + hasNextPage: false, + isLoading: false, + onFetchMore: () {}, + onFetchAll: () async { + return tracks.toList(); + }, + onRefresh: () async { + ref.invalidate(likedTracksProvider); + }, + ), + title: playlist.name!, + description: playlist.description, + tracks: tracks, + routePath: '/playlist/${playlist.id}', + isLiked: false, + shareUrl: null, + onHeart: null, + owner: playlist.owner?.displayName, ), - title: playlist.name!, - description: playlist.description, - tracks: tracks, - routePath: '/playlist/${playlist.id}', - isLiked: false, - shareUrl: "", - onHeart: null, - child: const TrackView(), ); } } diff --git a/lib/pages/playlist/playlist.dart b/lib/pages/playlist/playlist.dart index e1b33e98..da28c83c 100644 --- a/lib/pages/playlist/playlist.dart +++ b/lib/pages/playlist/playlist.dart @@ -3,9 +3,9 @@ import 'package:flutter/material.dart' hide Page; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/dialogs/prompt_dialog.dart'; -import 'package:spotube/components/tracks_view/sections/body/use_is_user_playlist.dart'; -import 'package:spotube/components/tracks_view/track_view.dart'; -import 'package:spotube/components/tracks_view/track_view_props.dart'; +import 'package:spotube/components/track_presentation/presentation_props.dart'; +import 'package:spotube/components/track_presentation/track_presentation.dart'; +import 'package:spotube/components/track_presentation/use_is_user_playlist.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -45,49 +45,52 @@ class PlaylistPage extends HookConsumerWidget { final isUserPlaylist = useIsUserPlaylist(ref, playlist.id!); - return InheritedTrackView( - collection: playlist, - image: playlist.images.asUrlString( - placeholder: ImagePlaceholder.collection, - ), - pagination: PaginationProps( - hasNextPage: tracks.asData?.value.hasMore ?? false, - isLoading: tracks.isLoadingNextPage, - onFetchMore: tracksNotifier.fetchMore, - onRefresh: () async { - ref.invalidate(playlistTracksProvider(playlist.id!)); - }, - onFetchAll: () async { - return await tracksNotifier.fetchAll(); - }, - ), - title: playlist.name!, - description: playlist.description, - tracks: tracks.asData?.value.items ?? [], - routePath: '/playlist/${playlist.id}', - isLiked: isFavoritePlaylist.asData?.value ?? false, - shareUrl: playlist.externalUrls?.spotify ?? - "https://open.spotify.com/playlist/${playlist.id}", - onHeart: isFavoritePlaylist.asData?.value == null - ? null - : () async { - final confirmed = isUserPlaylist - ? await showPromptDialog( - context: context, - title: context.l10n.delete_playlist, - message: context.l10n.delete_playlist_confirmation, - ) - : true; - if (!confirmed) return null; + return TrackPresentation( + options: TrackPresentationOptions( + collection: playlist, + image: playlist.images.asUrlString( + placeholder: ImagePlaceholder.collection, + ), + pagination: PaginationProps( + hasNextPage: tracks.asData?.value.hasMore ?? false, + isLoading: tracks.isLoadingNextPage, + onFetchMore: tracksNotifier.fetchMore, + onRefresh: () async { + ref.invalidate(playlistTracksProvider(playlist.id!)); + }, + onFetchAll: () async { + return await tracksNotifier.fetchAll(); + }, + ), + title: playlist.name!, + description: playlist.description, + owner: playlist.owner?.displayName, + ownerImage: playlist.owner?.images?.lastOrNull?.url, + tracks: tracks.asData?.value.items ?? [], + routePath: '/playlist/${playlist.id}', + isLiked: isFavoritePlaylist.asData?.value ?? false, + shareUrl: playlist.externalUrls?.spotify ?? + "https://open.spotify.com/playlist/${playlist.id}", + onHeart: isFavoritePlaylist.asData?.value == null + ? null + : () async { + final confirmed = isUserPlaylist + ? await showPromptDialog( + context: context, + title: context.l10n.delete_playlist, + message: context.l10n.delete_playlist_confirmation, + ) + : true; + if (!confirmed) return null; - if (isFavoritePlaylist.asData!.value) { - await favoritePlaylistsNotifier.removeFavorite(playlist); - } else { - await favoritePlaylistsNotifier.addFavorite(playlist); - } - return isUserPlaylist; - }, - child: const TrackView(), + if (isFavoritePlaylist.asData!.value) { + await favoritePlaylistsNotifier.removeFavorite(playlist); + } else { + await favoritePlaylistsNotifier.addFavorite(playlist); + } + return isUserPlaylist; + }, + ), ); } } diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 1407feb3..de152fbe 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -48,6 +48,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/pubspec.lock b/pubspec.lock index ff445cad..34306fef 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -98,10 +98,10 @@ packages: dependency: "direct main" description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" audio_service: dependency: "direct main" description: @@ -203,10 +203,10 @@ packages: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" build: dependency: transitive description: @@ -347,10 +347,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" code_builder: dependency: transitive description: @@ -598,10 +598,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" ffi: dependency: transitive description: @@ -614,10 +614,10 @@ packages: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" file_picker: dependency: "direct main" description: @@ -1330,18 +1330,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec url: "https://pub.dev" source: hosted - version: "10.0.7" + version: "10.0.8" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -1642,10 +1642,10 @@ packages: dependency: "direct main" description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" path_drawing: dependency: transitive description: @@ -1786,10 +1786,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -1826,10 +1826,10 @@ packages: dependency: transitive description: name: process - sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "5.0.3" process_run: dependency: "direct dev" description: @@ -2257,10 +2257,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" stroke_text: dependency: "direct main" description: @@ -2553,10 +2553,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" url: "https://pub.dev" source: hosted - version: "14.3.0" + version: "14.3.1" watcher: dependency: transitive description: diff --git a/untranslated_messages.json b/untranslated_messages.json index 67bb4673..05b5aca3 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1,105 +1,235 @@ { "ar": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "bn": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "ca": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "cs": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "de": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "es": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "eu": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "fa": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "fi": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "fr": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "hi": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "id": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "it": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "ja": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "ka": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "ko": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "ne": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "nl": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "pl": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "pt": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "ru": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "th": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "tr": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "uk": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "vi": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ], "zh": [ - "undo" + "undo", + "download_all", + "add_all_to_playlist", + "add_all_to_queue", + "play_all_next", + "pause" ] } From 2ee0ca44c79de6038f639f768cc2cf39d06534b4 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 28 Dec 2024 19:51:04 +0600 Subject: [PATCH 21/81] refactor: profile page to use shadcn design --- lib/pages/profile/profile.dart | 40 +++++++++++------------- lib/pages/search/sections/albums.dart | 2 +- lib/pages/search/sections/artists.dart | 2 +- lib/pages/search/sections/playlists.dart | 2 +- lib/pages/search/sections/tracks.dart | 5 +-- 5 files changed, 24 insertions(+), 27 deletions(-) diff --git a/lib/pages/profile/profile.dart b/lib/pages/profile/profile.dart index b4d72b53..004fbd1a 100644 --- a/lib/pages/profile/profile.dart +++ b/lib/pages/profile/profile.dart @@ -1,7 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:sliver_tools/sliver_tools.dart'; import 'package:spotube/collections/fake.dart'; @@ -21,8 +20,6 @@ class ProfilePage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme) = Theme.of(context); - final me = ref.watch(meProvider); final meData = me.asData?.value ?? FakeData.user; @@ -42,11 +39,13 @@ class ProfilePage extends HookConsumerWidget { return SafeArea( child: Scaffold( - appBar: TitleBar( - title: Text(context.l10n.profile), - automaticallyImplyLeading: true, - ), - body: Skeletonizer( + headers: [ + TitleBar( + title: Text(context.l10n.profile), + automaticallyImplyLeading: true, + ) + ], + child: Skeletonizer( enabled: me.isLoading, child: CustomScrollView( slivers: [ @@ -73,9 +72,8 @@ class ProfilePage extends HookConsumerWidget { SliverToBoxAdapter( child: Text( meData.displayName ?? context.l10n.no_name, - style: textTheme.titleLarge, textAlign: TextAlign.center, - ), + ).h4(), ), const SliverGap(20), SliverCrossAxisConstrained( @@ -84,15 +82,15 @@ class ProfilePage extends HookConsumerWidget { child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - TextButton.icon( - label: Text(context.l10n.edit), - icon: const Icon(SpotubeIcons.edit), + Button.text( + leading: const Icon(SpotubeIcons.edit), onPressed: () { launchUrlString( "https://www.spotify.com/account/profile/", mode: LaunchMode.externalApplication, ); }, + child: Text(context.l10n.edit), ), ], ), @@ -102,25 +100,22 @@ class ProfilePage extends HookConsumerWidget { maxCrossAxisExtent: 500, child: SliverToBoxAdapter( child: Card( - margin: const EdgeInsets.all(10), child: Padding( padding: const EdgeInsets.all(8.0), child: Table( columnWidths: const { - 0: FixedColumnWidth(110), + 0: FixedTableSize(120), }, - children: [ + defaultRowHeight: const FixedTableSize(40), + rows: [ for (final MapEntry(:key, :value) in userProperties.entries) TableRow( - children: [ + cells: [ TableCell( child: Padding( padding: const EdgeInsets.all(6), - child: Text( - key, - style: textTheme.titleSmall, - ), + child: Text(key).large(), ), ), TableCell( @@ -137,6 +132,7 @@ class ProfilePage extends HookConsumerWidget { ), ), ), + const SliverGap(200), ], ), ), diff --git a/lib/pages/search/sections/albums.dart b/lib/pages/search/sections/albums.dart index 857eb59c..105c23d5 100644 --- a/lib/pages/search/sections/albums.dart +++ b/lib/pages/search/sections/albums.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart' hide Page; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; diff --git a/lib/pages/search/sections/artists.dart b/lib/pages/search/sections/artists.dart index 16295580..9a94b3c1 100644 --- a/lib/pages/search/sections/artists.dart +++ b/lib/pages/search/sections/artists.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart' hide Page; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; diff --git a/lib/pages/search/sections/playlists.dart b/lib/pages/search/sections/playlists.dart index 3799f9fa..17bf4849 100644 --- a/lib/pages/search/sections/playlists.dart +++ b/lib/pages/search/sections/playlists.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart' hide Page; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; import 'package:spotube/extensions/context.dart'; diff --git a/lib/pages/search/sections/tracks.dart b/lib/pages/search/sections/tracks.dart index 6ec8f685..c0daa853 100644 --- a/lib/pages/search/sections/tracks.dart +++ b/lib/pages/search/sections/tracks.dart @@ -1,6 +1,7 @@ import 'package:collection/collection.dart'; -import 'package:flutter/material.dart' hide Page; + import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/dialogs/prompt_dialog.dart'; import 'package:spotube/components/dialogs/select_device_dialog.dart'; @@ -37,7 +38,7 @@ class SearchTracksSection extends HookConsumerWidget { padding: const EdgeInsets.symmetric(horizontal: 8), child: Text( context.l10n.songs, - style: theme.textTheme.titleLarge!, + style: theme.typography.h4, ), ), if (searchTrack.isLoading) From d845180e6039a60bc5ef174fad8285328171cc20 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 28 Dec 2024 21:18:35 +0600 Subject: [PATCH 22/81] fix: mobile keyboard overflow --- ios/Runner.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 1 + .../horizontal_playbutton_card_view.dart | 3 +- .../playbutton_view/playbutton_tile.dart | 8 +- .../presentation_modifiers.dart | 15 +- .../track_presentation.dart | 30 +++- lib/main.dart | 6 + lib/modules/library/user_albums.dart | 6 +- lib/modules/library/user_artists.dart | 6 +- lib/modules/library/user_playlists.dart | 6 +- lib/pages/lastfm_login/lastfm_login.dart | 140 +++++++++--------- lib/pages/root/root_app.dart | 18 ++- lib/pages/search/search.dart | 136 ++++++++--------- 13 files changed, 213 insertions(+), 164 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 63871a3d..bbfc1404 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 70; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 5e31d3d3..c53e2b31 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -48,6 +48,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart index d37bc8a0..47fb0f33 100644 --- a/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart +++ b/lib/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart @@ -38,6 +38,7 @@ class HorizontalPlaybuttonCardView extends HookWidget { Widget build(BuildContext context) { final scrollController = useScrollController(); final isArtist = items.every((s) => s is Artist); + final scale = context.theme.scaling; return Padding( padding: const EdgeInsets.all(8.0), @@ -92,7 +93,7 @@ class HorizontalPlaybuttonCardView extends HookWidget { ), isLoading: isLoadingNextPage, hasReachedMax: !hasNextPage, - separatorBuilder: (context, index) => const Gap(8.0), + separatorBuilder: (context, index) => Gap(12 * scale), itemBuilder: (context, index) { final item = items[index]; diff --git a/lib/components/playbutton_view/playbutton_tile.dart b/lib/components/playbutton_view/playbutton_tile.dart index e06f3689..3daaf75c 100644 --- a/lib/components/playbutton_view/playbutton_tile.dart +++ b/lib/components/playbutton_view/playbutton_tile.dart @@ -35,7 +35,7 @@ class PlaybuttonTile extends StatelessWidget { final cleanDescription = description?.unescapeHtml().cleanHtml() ?? ""; final scale = context.theme.scaling; - return Button.ghost( + return Button( leading: Container( width: 50 * scale, height: 50 * scale, @@ -47,6 +47,12 @@ class PlaybuttonTile extends StatelessWidget { ), ), ), + style: ButtonVariance.ghost.copyWith( + padding: (context, states, value) { + return (ButtonVariance.ghost.padding(context, states) as EdgeInsets) + .copyWith(right: 0, left: 0); + }, + ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/components/track_presentation/presentation_modifiers.dart b/lib/components/track_presentation/presentation_modifiers.dart index d1678e17..4d781d24 100644 --- a/lib/components/track_presentation/presentation_modifiers.dart +++ b/lib/components/track_presentation/presentation_modifiers.dart @@ -11,7 +11,11 @@ import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; class TrackPresentationModifiersSection extends HookConsumerWidget { - const TrackPresentationModifiersSection({super.key}); + final FocusNode? focusNode; + const TrackPresentationModifiersSection({ + super.key, + this.focusNode, + }); @override Widget build(BuildContext context, ref) { @@ -22,11 +26,12 @@ class TrackPresentationModifiersSection extends HookConsumerWidget { ); final controller = useTextEditingController(); + final scale = context.theme.scaling; return LayoutBuilder(builder: (context, constrains) { return Padding( padding: EdgeInsets.symmetric( - horizontal: constrains.mdAndUp ? 16 : 8, + horizontal: (constrains.mdAndUp ? 16 : 8) * scale, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -55,11 +60,13 @@ class TrackPresentationModifiersSection extends HookConsumerWidget { children: [ Flexible( child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 320, + constraints: BoxConstraints( + maxWidth: 320 * scale, + maxHeight: 38 * scale, ), child: TextField( controller: controller, + focusNode: focusNode, leading: Icon( SpotubeIcons.search, color: context.theme.colorScheme.mutedForeground, diff --git a/lib/components/track_presentation/track_presentation.dart b/lib/components/track_presentation/track_presentation.dart index 8bc1c6df..e81a2e1e 100644 --- a/lib/components/track_presentation/track_presentation.dart +++ b/lib/components/track_presentation/track_presentation.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart' show ListTile; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; @@ -9,6 +10,7 @@ import 'package:spotube/components/track_presentation/presentation_top.dart'; import 'package:spotube/components/track_presentation/presentation_modifiers.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/utils/platform.dart'; class TrackPresentation extends HookConsumerWidget { final TrackPresentationOptions options; @@ -22,6 +24,29 @@ class TrackPresentation extends HookConsumerWidget { final headerTextStyle = context.theme.typography.small.copyWith( color: context.theme.colorScheme.mutedForeground, ); + final scrollController = useScrollController(); + final focusNode = useFocusNode(); + final scale = context.theme.scaling; + + useEffect(() { + if (!kIsMobile) return null; + void listener() { + if (!scrollController.hasClients) return; + + if (focusNode.hasFocus) { + scrollController.animateTo( + 300 * scale, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + } + + focusNode.addListener(listener); + return () { + focusNode.removeListener(listener); + }; + }, [focusNode, scrollController, scale]); return Data.inherit( data: options, @@ -29,6 +54,7 @@ class TrackPresentation extends HookConsumerWidget { child: Scaffold( headers: const [TitleBar()], child: CustomScrollView( + controller: scrollController, slivers: [ const TrackPresentationTopSection(), const SliverGap(16), @@ -36,7 +62,9 @@ class TrackPresentation extends HookConsumerWidget { builder: (context, constrains) { return SliverList.list( children: [ - const TrackPresentationModifiersSection(), + TrackPresentationModifiersSection( + focusNode: focusNode, + ), ListTile( titleTextStyle: headerTextStyle, subtitleTextStyle: headerTextStyle, diff --git a/lib/main.dart b/lib/main.dart index ecf2cc37..2f93ea87 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -228,6 +228,12 @@ class Spotube extends HookConsumerWidget { ), materialTheme: material.ThemeData( splashFactory: material.NoSplash.splashFactory, + appBarTheme: const material.AppBarTheme( + surfaceTintColor: Colors.transparent, + scrolledUnderElevation: 0, + shadowColor: Colors.transparent, + elevation: 0, + ), ), themeMode: themeMode, shortcuts: { diff --git a/lib/modules/library/user_albums.dart b/lib/modules/library/user_albums.dart index a388c0ad..b460f22e 100644 --- a/lib/modules/library/user_albums.dart +++ b/lib/modules/library/user_albums.dart @@ -50,9 +50,9 @@ class UserAlbums extends HookConsumerWidget { return SafeArea( child: Scaffold( child: RefreshTrigger( - onRefresh: () async { - ref.invalidate(favoriteAlbumsProvider); - }, + // onRefresh: () async { + // ref.invalidate(favoriteAlbumsProvider); + // }, child: InterScrollbar( controller: controller, child: CustomScrollView( diff --git a/lib/modules/library/user_artists.dart b/lib/modules/library/user_artists.dart index 83a321fc..eaf5afb3 100644 --- a/lib/modules/library/user_artists.dart +++ b/lib/modules/library/user_artists.dart @@ -55,9 +55,9 @@ class UserArtists extends HookConsumerWidget { return SafeArea( child: Scaffold( child: RefreshTrigger( - onRefresh: () async { - ref.invalidate(followedArtistsProvider); - }, + // onRefresh: () async { + // ref.invalidate(followedArtistsProvider); + // }, child: InterScrollbar( controller: controller, child: Padding( diff --git a/lib/modules/library/user_playlists.dart b/lib/modules/library/user_playlists.dart index 2a2d65e0..1b1bf110 100644 --- a/lib/modules/library/user_playlists.dart +++ b/lib/modules/library/user_playlists.dart @@ -78,9 +78,9 @@ class UserPlaylists extends HookConsumerWidget { } return RefreshTrigger( - onRefresh: () async { - ref.invalidate(favoritePlaylistsProvider); - }, + // onRefresh: () async { + // ref.invalidate(favoritePlaylistsProvider); + // }, child: SafeArea( child: InterScrollbar( controller: controller, diff --git a/lib/pages/lastfm_login/lastfm_login.dart b/lib/pages/lastfm_login/lastfm_login.dart index 2611d771..d5466544 100644 --- a/lib/pages/lastfm_login/lastfm_login.dart +++ b/lib/pages/lastfm_login/lastfm_login.dart @@ -1,9 +1,10 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:form_validator/form_validator.dart'; + import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/components/dialogs/prompt_dialog.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/extensions/context.dart'; @@ -15,31 +16,59 @@ class LastFMLoginPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final theme = Theme.of(context); final router = GoRouter.of(context); final scrobblerNotifier = ref.read(scrobblerProvider.notifier); - final formKey = useMemoized(() => GlobalKey(), []); - final username = useTextEditingController(); - final password = useTextEditingController(); + final usernameKey = + useMemoized(() => const FormKey("username"), []); + final passwordKey = + useMemoized(() => const FormKey("password"), []); + final passwordVisible = useState(false); final isLoading = useState(false); return Scaffold( - appBar: const TitleBar(leading: [BackButton()]), - body: Center( - child: ConstrainedBox( + headers: const [ + SafeArea( + child: TitleBar( + leading: [BackButton()], + ), + ), + ], + child: SingleChildScrollView( + child: Container( constraints: const BoxConstraints(maxWidth: 400), + alignment: Alignment.center, + padding: const EdgeInsets.all(16), child: Card( - margin: const EdgeInsets.all(8.0), child: Padding( padding: const EdgeInsets.all(16.0).copyWith(top: 8), child: Form( - key: formKey, - autovalidateMode: AutovalidateMode.onUserInteraction, + onSubmit: (context, values) async { + try { + isLoading.value = true; + await scrobblerNotifier.login( + values[usernameKey].trim(), + values[passwordKey], + ); + router.pop(); + } catch (e) { + if (context.mounted) { + showPromptDialog( + context: context, + title: context.l10n.error("Authentication failed"), + message: e.toString(), + cancelText: null, + ); + } + } finally { + isLoading.value = false; + } + }, child: Column( mainAxisSize: MainAxisSize.min, + spacing: 10, children: [ Container( decoration: BoxDecoration( @@ -53,38 +82,35 @@ class LastFMLoginPage extends HookConsumerWidget { size: 60, ), ), - Text( - "last.fm", - style: theme.textTheme.titleLarge, - ), - const SizedBox(height: 10), + const Text("last.fm").h3(), Text(context.l10n.login_with_your_lastfm), - const SizedBox(height: 10), AutofillGroup( child: Column( + spacing: 10, children: [ - TextFormField( - autofillHints: const [ - AutofillHints.username, - AutofillHints.email, - ], - controller: username, - validator: ValidationBuilder().required().build(), - decoration: InputDecoration( - labelText: context.l10n.username, + FormField( + label: Text(context.l10n.username), + key: usernameKey, + validator: const NotEmptyValidator(), + child: TextField( + autofillHints: const [ + AutofillHints.username, + AutofillHints.email, + ], + placeholder: Text(context.l10n.username), ), ), - const SizedBox(height: 10), - TextFormField( - autofillHints: const [ - AutofillHints.password, - ], - controller: password, - validator: ValidationBuilder().required().build(), - obscureText: !passwordVisible.value, - decoration: InputDecoration( - labelText: context.l10n.password, - suffixIcon: IconButton( + FormField( + key: passwordKey, + validator: const NotEmptyValidator(), + label: Text(context.l10n.password), + child: TextField( + autofillHints: const [ + AutofillHints.password, + ], + obscureText: !passwordVisible.value, + placeholder: Text(context.l10n.password), + trailing: IconButton.ghost( icon: Icon( passwordVisible.value ? SpotubeIcons.eye @@ -98,37 +124,13 @@ class LastFMLoginPage extends HookConsumerWidget { ], ), ), - const SizedBox(height: 10), - FilledButton( - onPressed: isLoading.value - ? null - : () async { - try { - isLoading.value = true; - if (formKey.currentState?.validate() != true) { - return; - } - await scrobblerNotifier.login( - username.text.trim(), - password.text, - ); - router.pop(); - } catch (e) { - if (context.mounted) { - showPromptDialog( - context: context, - title: context.l10n - .error("Authentication failed"), - message: e.toString(), - cancelText: null, - ); - } - } finally { - isLoading.value = false; - } - }, - child: Text(context.l10n.login), - ), + FormErrorBuilder(builder: (context, errors, child) { + return Button.primary( + onPressed: () => context.submitForm(), + enabled: errors.isEmpty && !isLoading.value, + child: Text(context.l10n.login), + ); + }), ], ), ), diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index 606bba34..cdb56910 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -179,13 +179,17 @@ class RootApp extends HookConsumerWidget { return getSidebarTileList(context.l10n).map((s) => s.name).toList(); }, []); - final scaffold = Scaffold( - footers: const [ - BottomPlayer(), - SpotubeNavigationBar(), - ], - floatingFooter: true, - child: Sidebar(child: child), + final scaffold = MediaQuery.removeViewInsets( + context: context, + removeBottom: true, + child: Scaffold( + footers: const [ + BottomPlayer(), + SpotubeNavigationBar(), + ], + floatingFooter: true, + child: Sidebar(child: child), + ), ); if (!kIsAndroid) { diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index 5c096a32..9e2bf20c 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -29,13 +29,15 @@ class SearchPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final theme = Theme.of(context); - final searchTerm = ref.watch(searchTermStateProvider); + final mediaQuery = MediaQuery.sizeOf(context); + + final scrollController = useScrollController(); final controller = useSearchController(); final focusNode = useFocusNode(); final auth = ref.watch(authenticationProvider); - final mediaQuery = MediaQuery.of(context); + final searchTerm = ref.watch(searchTermStateProvider); final searchTrack = ref.watch(searchProvider(SearchType.track)); final searchAlbum = ref.watch(searchProvider(SearchType.album)); final searchPlaylist = ref.watch(searchProvider(SearchType.playlist)); @@ -51,35 +53,6 @@ class SearchPage extends HookConsumerWidget { return null; }, []); - final resultWidget = HookBuilder( - builder: (context) { - final controller = useScrollController(); - - return InterScrollbar( - controller: controller, - child: SingleChildScrollView( - controller: controller, - child: const Padding( - padding: EdgeInsets.symmetric(vertical: 8), - child: SafeArea( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SearchTracksSection(), - SearchPlaylistsSection(), - Gap(20), - SearchArtistsSection(), - Gap(20), - SearchAlbumsSection(), - ], - ), - ), - ), - ), - ); - }, - ); - void onSubmitted(String value) { ref.read(searchTermStateProvider.notifier).state = value; if (value.trim().isEmpty) { @@ -182,59 +155,80 @@ class SearchPage extends HookConsumerWidget { Expanded( child: AnimatedSwitcher( duration: const Duration(milliseconds: 300), - child: searchTerm.isEmpty - ? Column( - children: [ - SizedBox( - height: mediaQuery.size.height * 0.2, - ), - Icon( - SpotubeIcons.web, - size: 120, + child: switch ((searchTerm.isEmpty, isFetching)) { + (true, false) => Column( + children: [ + SizedBox( + height: mediaQuery.height * 0.2, + ), + Icon( + SpotubeIcons.web, + size: 120, + color: theme.colorScheme.foreground + .withOpacity(0.7), + ), + const SizedBox(height: 20), + Text( + context.l10n.search_to_get_results, + style: theme.typography.h3.copyWith( + fontWeight: FontWeight.w900, color: theme.colorScheme.foreground - .withOpacity(0.7), + .withOpacity(0.5), ), - const SizedBox(height: 20), + ), + ], + ), + (false, true) => Container( + constraints: BoxConstraints( + maxWidth: mediaQuery.lgAndUp + ? mediaQuery.width * 0.5 + : mediaQuery.width, + ), + padding: const EdgeInsets.symmetric( + horizontal: 20, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ Text( - context.l10n.search_to_get_results, - style: theme.typography.h3.copyWith( + context.l10n.crunching_results, + style: TextStyle( + fontSize: 20, fontWeight: FontWeight.w900, color: theme.colorScheme.foreground - .withOpacity(0.5), + .withOpacity(0.7), ), ), + const SizedBox(height: 20), + const LinearProgressIndicator(), ], - ) - : isFetching - ? Container( - constraints: BoxConstraints( - maxWidth: mediaQuery.lgAndUp - ? mediaQuery.size.width * 0.5 - : mediaQuery.size.width, - ), - padding: const EdgeInsets.symmetric( - horizontal: 20, - ), + ), + ), + _ => InterScrollbar( + controller: scrollController, + child: SingleChildScrollView( + controller: scrollController, + child: const Padding( + padding: EdgeInsets.symmetric(vertical: 8), + child: SafeArea( child: Column( - mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: - CrossAxisAlignment.center, + CrossAxisAlignment.start, children: [ - Text( - context.l10n.crunching_results, - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w900, - color: theme.colorScheme.foreground - .withOpacity(0.7), - ), - ), - const SizedBox(height: 20), - const LinearProgressIndicator(), + SearchTracksSection(), + SearchPlaylistsSection(), + Gap(20), + SearchArtistsSection(), + Gap(20), + SearchAlbumsSection(), ], ), - ) - : resultWidget, + ), + ), + ), + ), + }, ), ), ], From b558cc17f174705b5963193298db758bb7cbd4ec Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 28 Dec 2024 21:55:36 +0600 Subject: [PATCH 23/81] fix: SafeArea for global bottom items not working --- lib/pages/root/root_app.dart | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index cdb56910..b8d4d166 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:collection/collection.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; @@ -179,16 +180,37 @@ class RootApp extends HookConsumerWidget { return getSidebarTileList(context.l10n).map((s) => s.name).toList(); }, []); + final bottomPlayerKey = useMemoized(() => GlobalKey(), []); + final navigationBarKey = useMemoized(() => GlobalKey(), []); + + final bottomPadding = useMemoized(() { + return [bottomPlayerKey, navigationBarKey] + .map((k) => + (k.currentContext?.findRenderObject() as RenderBox?) + ?.size + .height ?? + 0) + .sum; + }, [bottomPlayerKey, navigationBarKey]); + final scaffold = MediaQuery.removeViewInsets( context: context, removeBottom: true, child: Scaffold( - footers: const [ - BottomPlayer(), - SpotubeNavigationBar(), + footers: [ + BottomPlayer(key: bottomPlayerKey), + SpotubeNavigationBar(key: navigationBarKey), ], floatingFooter: true, - child: Sidebar(child: child), + // Fix for safe are not working for bottom bar + child: MediaQuery( + data: MediaQuery.of(context).copyWith( + padding: MediaQuery.of(context).padding.copyWith( + bottom: bottomPadding, + ), + ), + child: Sidebar(child: child), + ), ), ); From 047eccfa82f96c1a967d67e4e6f80156ccc2eb0b Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 29 Dec 2024 13:36:44 +0600 Subject: [PATCH 24/81] fix: SafeArea not working for bottom floating widgets --- .../playbutton_view/playbutton_view.dart | 10 +- lib/modules/library/user_albums.dart | 2 + lib/modules/library/user_artists.dart | 2 + lib/modules/library/user_playlists.dart | 2 + lib/modules/lyrics/zoom_controls.dart | 40 +++--- lib/modules/player/player.dart | 6 - lib/pages/lyrics/lyrics.dart | 129 +++++++++--------- lib/pages/lyrics/plain_lyrics.dart | 18 +-- lib/pages/lyrics/synced_lyrics.dart | 77 +++++------ lib/pages/root/root_app.dart | 30 +--- pubspec.lock | 4 +- pubspec.yaml | 2 +- 12 files changed, 153 insertions(+), 169 deletions(-) diff --git a/lib/components/playbutton_view/playbutton_view.dart b/lib/components/playbutton_view/playbutton_view.dart index 7520f313..dd8dc371 100644 --- a/lib/components/playbutton_view/playbutton_view.dart +++ b/lib/components/playbutton_view/playbutton_view.dart @@ -51,6 +51,8 @@ class PlaybuttonView extends StatelessWidget { @override Widget build(BuildContext context) { + final scale = context.theme.scaling; + return SliverLayoutBuilder( builder: (context, constrains) => HookBuilder(builder: (context) { final isGrid = useState(constrains.mdAndUp); @@ -100,10 +102,10 @@ class PlaybuttonView extends StatelessWidget { (true, _) => SliverGrid.builder( itemCount: isLoading ? 6 : itemCount + 1, gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 150 * context.theme.scaling, - mainAxisExtent: 225 * context.theme.scaling, - crossAxisSpacing: 8, - mainAxisSpacing: 8, + maxCrossAxisExtent: 150 * scale, + mainAxisExtent: 225 * scale, + crossAxisSpacing: 12 * scale, + mainAxisSpacing: 12 * scale, ), itemBuilder: (context, index) { if (isLoading) { diff --git a/lib/modules/library/user_albums.dart b/lib/modules/library/user_albums.dart index b460f22e..a3f14fba 100644 --- a/lib/modules/library/user_albums.dart +++ b/lib/modules/library/user_albums.dart @@ -48,6 +48,7 @@ class UserAlbums extends HookConsumerWidget { } return SafeArea( + bottom: false, child: Scaffold( child: RefreshTrigger( // onRefresh: () async { @@ -89,6 +90,7 @@ class UserAlbums extends HookConsumerWidget { AlbumCard.tile(albums[index]), ), ), + const SliverSafeArea(sliver: SliverGap(10)), ], ), ), diff --git a/lib/modules/library/user_artists.dart b/lib/modules/library/user_artists.dart index eaf5afb3..576298ce 100644 --- a/lib/modules/library/user_artists.dart +++ b/lib/modules/library/user_artists.dart @@ -53,6 +53,7 @@ class UserArtists extends HookConsumerWidget { } return SafeArea( + bottom: false, child: Scaffold( child: RefreshTrigger( // onRefresh: () async { @@ -117,6 +118,7 @@ class UserArtists extends HookConsumerWidget { }, ); }), + const SliverSafeArea(sliver: SliverGap(10)), ], ), ), diff --git a/lib/modules/library/user_playlists.dart b/lib/modules/library/user_playlists.dart index 1b1bf110..58462bf9 100644 --- a/lib/modules/library/user_playlists.dart +++ b/lib/modules/library/user_playlists.dart @@ -82,6 +82,7 @@ class UserPlaylists extends HookConsumerWidget { // ref.invalidate(favoritePlaylistsProvider); // }, child: SafeArea( + bottom: false, child: InterScrollbar( controller: controller, child: CustomScrollView( @@ -139,6 +140,7 @@ class UserPlaylists extends HookConsumerWidget { }, ), ), + const SliverSafeArea(sliver: SliverGap(10)), ], ), ), diff --git a/lib/modules/lyrics/zoom_controls.dart b/lib/modules/lyrics/zoom_controls.dart index 73beb4ae..b4eeb9d6 100644 --- a/lib/modules/lyrics/zoom_controls.dart +++ b/lib/modules/lyrics/zoom_controls.dart @@ -1,5 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -32,7 +33,7 @@ class ZoomControls extends HookWidget { @override Widget build(BuildContext context) { final actions = [ - IconButton( + IconButton.ghost( icon: decreaseIcon, onPressed: () { if (value == min) return; @@ -40,7 +41,7 @@ class ZoomControls extends HookWidget { }, ), Text("$value$unit"), - IconButton( + IconButton.ghost( icon: increaseIcon, onPressed: () { if (value == max) return; @@ -50,27 +51,28 @@ class ZoomControls extends HookWidget { ]; return Container( - decoration: BoxDecoration( - color: Theme.of(context).cardColor.withOpacity(0.7), - borderRadius: BorderRadius.circular(10), - ), constraints: BoxConstraints( maxHeight: direction == Axis.horizontal ? 50 : 200, maxWidth: direction == Axis.vertical ? 50 : double.infinity, ), margin: const EdgeInsets.all(8), - child: direction == Axis.horizontal - ? Row( - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: actions, - ) - : Column( - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - verticalDirection: VerticalDirection.up, - children: actions, - ), + child: SurfaceCard( + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: context.theme.surfaceOpacity, + padding: EdgeInsets.zero, + child: direction == Axis.horizontal + ? Row( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: actions, + ) + : Column( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + verticalDirection: VerticalDirection.up, + children: actions, + ), + ), ); } } diff --git a/lib/modules/player/player.dart b/lib/modules/player/player.dart index 3f19fbf0..014e6aef 100644 --- a/lib/modules/player/player.dart +++ b/lib/modules/player/player.dart @@ -367,12 +367,6 @@ class PlayerView extends HookConsumerWidget { topRight: Radius.circular(20), ), ), - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context) - .size - .height * - 0.8, - ), builder: (context) => const LyricsPage(isModal: true), ); diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index 17e552e6..679ef78e 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -1,13 +1,11 @@ -import 'dart:ui'; - import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/components/image/universal_image.dart'; -import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/hooks/utils/use_custom_status_bar_color.dart'; @@ -35,7 +33,6 @@ class LyricsPage extends HookConsumerWidget { [playlist.activeTrack?.album?.images], ); final palette = usePaletteColor(albumArt, ref); - final mediaQuery = MediaQuery.of(context); final route = ModalRoute.of(context); final selectedIndex = useState(0); @@ -47,17 +44,28 @@ class LyricsPage extends HookConsumerWidget { Widget tabbar = Padding( padding: const EdgeInsets.all(10), - child: Opacity( - opacity: 0.8, - child: Tabs( - index: selectedIndex.value, - onChanged: (index) => selectedIndex.value = index, - tabs: [ - Text(context.l10n.synced), - Text(context.l10n.plain), - ], - ), - ), + child: isModal + ? TabList( + index: selectedIndex.value, + children: [ + TabButton( + onPressed: () => selectedIndex.value = 0, + child: Text(context.l10n.synced), + ), + TabButton( + onPressed: () => selectedIndex.value = 1, + child: Text(context.l10n.plain), + ), + ], + ) + : Tabs( + index: selectedIndex.value, + onChanged: (index) => selectedIndex.value = index, + tabs: [ + Text(context.l10n.synced), + Text(context.l10n.plain), + ], + ), ); tabbar = Row( @@ -89,57 +97,53 @@ class LyricsPage extends HookConsumerWidget { canPop: true, onPopInvokedWithResult: (_, __) => resetStatusBar(), child: SafeArea( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), - child: Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background.withOpacity(.4), - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(10), - topRight: Radius.circular(10), - ), - ), - child: Column( - children: [ - const SizedBox(height: 5), - Container( - height: 7, - width: 150, - decoration: BoxDecoration( - color: palette.titleTextColor, - borderRadius: BorderRadius.circular(10), - ), + bottom: false, + child: SurfaceCard( + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: context.theme.surfaceOpacity, + padding: EdgeInsets.zero, + borderRadius: BorderRadius.zero, + borderWidth: 0, + child: Column( + children: [ + const SizedBox(height: 5), + Container( + height: 7, + width: 150, + decoration: BoxDecoration( + color: palette.titleTextColor, + borderRadius: BorderRadius.circular(10), ), - AppBar( - leading: [tabbar], - backgroundColor: Colors.transparent, - trailing: [ - IconButton.ghost( - icon: const Icon(SpotubeIcons.minimize), - onPressed: () => Navigator.of(context).pop(), - ), - const SizedBox(width: 5), + ), + Row( + children: [ + Expanded( + child: tabbar, + ), + IconButton.ghost( + icon: const Icon(SpotubeIcons.minimize), + onPressed: () => Navigator.of(context).pop(), + ), + const SizedBox(width: 5), + ], + ), + Expanded( + child: IndexedStack( + index: selectedIndex.value, + children: [ + SyncedLyrics(palette: palette, isModal: isModal), + PlainLyrics(palette: palette, isModal: isModal), ], ), - Expanded( - child: IndexedStack( - index: selectedIndex.value, - children: [ - SyncedLyrics(palette: palette, isModal: isModal), - PlainLyrics(palette: palette, isModal: isModal), - ], - ), - ), - ], - ), + ), + ], ), ), ), ); } return SafeArea( - bottom: mediaQuery.mdAndUp, + bottom: false, child: Scaffold( floatingHeader: true, headers: [ @@ -157,13 +161,14 @@ class LyricsPage extends HookConsumerWidget { image: UniversalImage.imageProvider(albumArt), fit: BoxFit.cover, ), - borderRadius: const BorderRadius.only( - bottomLeft: Radius.circular(10), - ), ), margin: const EdgeInsets.only(bottom: 10), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: SurfaceCard( + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: context.theme.surfaceOpacity, + padding: EdgeInsets.zero, + borderRadius: BorderRadius.zero, + borderWidth: 0, child: ColoredBox( color: palette.color.withOpacity(.7), child: SafeArea( diff --git a/lib/pages/lyrics/plain_lyrics.dart b/lib/pages/lyrics/plain_lyrics.dart index 7c571d5f..6246fd79 100644 --- a/lib/pages/lyrics/plain_lyrics.dart +++ b/lib/pages/lyrics/plain_lyrics.dart @@ -1,9 +1,8 @@ import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:palette_generator/palette_generator.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/lyrics/zoom_controls.dart'; import 'package:spotube/components/shimmers/shimmer_lyrics.dart'; @@ -30,7 +29,7 @@ class PlainLyrics extends HookConsumerWidget { final playlist = ref.watch(audioPlayerProvider); final lyricsQuery = ref.watch(syncedLyricsProvider(playlist.activeTrack)); final mediaQuery = MediaQuery.of(context); - final textTheme = Theme.of(context).textTheme; + final typography = Theme.of(context).typography; final textZoomLevel = useState(defaultTextZoom); @@ -44,9 +43,8 @@ class PlainLyrics extends HookConsumerWidget { child: Text( playlist.activeTrack?.name ?? "", style: mediaQuery.mdAndUp - ? textTheme.displaySmall - : textTheme.headlineMedium?.copyWith( - fontSize: 25, + ? typography.h3 + : typography.h4.copyWith( color: palette.titleTextColor, ), ), @@ -54,10 +52,8 @@ class PlainLyrics extends HookConsumerWidget { Center( child: Text( playlist.activeTrack?.artists?.asString() ?? "", - style: (mediaQuery.mdAndUp - ? textTheme.headlineSmall - : textTheme.titleLarge) - ?.copyWith(color: palette.bodyTextColor), + style: (mediaQuery.mdAndUp ? typography.h4 : typography.large) + .copyWith(color: palette.bodyTextColor), ), ) ], @@ -79,7 +75,7 @@ class PlainLyrics extends HookConsumerWidget { children: [ Text( context.l10n.no_lyrics_available, - style: textTheme.bodyLarge?.copyWith( + style: typography.large.copyWith( color: palette.bodyTextColor, ), textAlign: TextAlign.center, diff --git a/lib/pages/lyrics/synced_lyrics.dart b/lib/pages/lyrics/synced_lyrics.dart index 59bd863a..1367fa5a 100644 --- a/lib/pages/lyrics/synced_lyrics.dart +++ b/lib/pages/lyrics/synced_lyrics.dart @@ -1,10 +1,9 @@ import 'dart:async'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:palette_generator/palette_generator.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/lyrics/zoom_controls.dart'; import 'package:spotube/components/shimmers/shimmer_lyrics.dart'; @@ -37,7 +36,7 @@ class SyncedLyrics extends HookConsumerWidget { Widget build(BuildContext context, ref) { final playlist = ref.watch(audioPlayerProvider); - final mediaQuery = MediaQuery.of(context); + final mediaQuery = MediaQuery.sizeOf(context); final controller = useAutoScrollController(); final delay = ref.watch(syncedLyricsDelayProvider); @@ -54,7 +53,7 @@ class SyncedLyrics extends HookConsumerWidget { useSyncedLyrics(ref, lyricsState.asData?.value.lyricsMap ?? {}, delay); final textZoomLevel = useState(defaultTextZoom); - final textTheme = Theme.of(context).textTheme; + final typography = Theme.of(context).typography; ref.listen( audioPlayerProvider.select((s) => s.activeTrack), @@ -69,11 +68,11 @@ class SyncedLyrics extends HookConsumerWidget { ); final headlineTextStyle = (mediaQuery.mdAndUp - ? textTheme.displaySmall - : textTheme.headlineMedium?.copyWith(fontSize: 25)) - ?.copyWith(color: palette.titleTextColor); + ? typography.h3 + : typography.h4.copyWith(fontSize: 25)) + .copyWith(color: palette.titleTextColor); - final bodyTextTheme = textTheme.bodyLarge?.copyWith( + final bodyTextTheme = typography.large.copyWith( color: palette.bodyTextColor, ); @@ -115,9 +114,8 @@ class SyncedLyrics extends HookConsumerWidget { preferredSize: const Size.fromHeight(40), child: Text( playlist.activeTrack?.artists?.asString() ?? "", - style: mediaQuery.mdAndUp - ? textTheme.headlineSmall - : textTheme.titleLarge, + style: + mediaQuery.mdAndUp ? typography.h4 : typography.x2Large, ), ), ), @@ -144,7 +142,7 @@ class SyncedLyrics extends HookConsumerWidget { ? Container( padding: index == lyricValue.lyrics.length - 1 ? EdgeInsets.only( - bottom: mediaQuery.size.height / 2, + bottom: mediaQuery.height / 2, ) : null, ) @@ -165,31 +163,34 @@ class SyncedLyrics extends HookConsumerWidget { (textZoomLevel.value / 100), ), textAlign: TextAlign.center, - child: InkWell( - onTap: () async { - final time = Duration( - seconds: - lyricSlice.time.inSeconds - delay, - ); - if (time > audioPlayer.duration || - time.isNegative) { - return; - } - audioPlayer.seek(time); - }, - child: Builder(builder: (context) { - return StrokeText( - text: lyricSlice.text, - textStyle: - DefaultTextStyle.of(context).style, - textColor: isActive - ? Colors.white - : palette.bodyTextColor, - strokeColor: isActive - ? Colors.black - : Colors.transparent, - ); - }), + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () async { + final time = Duration( + seconds: + lyricSlice.time.inSeconds - delay, + ); + if (time > audioPlayer.duration || + time.isNegative) { + return; + } + audioPlayer.seek(time); + }, + child: Builder(builder: (context) { + return StrokeText( + text: lyricSlice.text, + textStyle: + DefaultTextStyle.of(context).style, + textColor: isActive + ? Colors.white + : palette.bodyTextColor, + strokeColor: isActive + ? Colors.black + : Colors.transparent, + ); + }), + ), ), ), ), @@ -231,7 +232,7 @@ class SyncedLyrics extends HookConsumerWidget { ), TextSpan( text: " Plain Lyrics ", - style: textTheme.bodyLarge?.copyWith( + style: typography.large.copyWith( color: palette.bodyTextColor, fontWeight: FontWeight.bold, ), diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index b8d4d166..cdb56910 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:collection/collection.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; @@ -180,37 +179,16 @@ class RootApp extends HookConsumerWidget { return getSidebarTileList(context.l10n).map((s) => s.name).toList(); }, []); - final bottomPlayerKey = useMemoized(() => GlobalKey(), []); - final navigationBarKey = useMemoized(() => GlobalKey(), []); - - final bottomPadding = useMemoized(() { - return [bottomPlayerKey, navigationBarKey] - .map((k) => - (k.currentContext?.findRenderObject() as RenderBox?) - ?.size - .height ?? - 0) - .sum; - }, [bottomPlayerKey, navigationBarKey]); - final scaffold = MediaQuery.removeViewInsets( context: context, removeBottom: true, child: Scaffold( - footers: [ - BottomPlayer(key: bottomPlayerKey), - SpotubeNavigationBar(key: navigationBarKey), + footers: const [ + BottomPlayer(), + SpotubeNavigationBar(), ], floatingFooter: true, - // Fix for safe are not working for bottom bar - child: MediaQuery( - data: MediaQuery.of(context).copyWith( - padding: MediaQuery.of(context).padding.copyWith( - bottom: bottomPadding, - ), - ), - child: Sidebar(child: child), - ), + child: Sidebar(child: child), ), ); diff --git a/pubspec.lock b/pubspec.lock index 34306fef..d441371d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1955,8 +1955,8 @@ packages: dependency: "direct main" description: path: "." - ref: "5359958464a57235f0f34c43a4623356a32459a0" - resolved-ref: "5359958464a57235f0f34c43a4623356a32459a0" + ref: fix-scaffold-footer-safearea + resolved-ref: "8ede34e1e3270ec3839192a7a6453e19cd00f9ab" url: "https://github.com/KRTirtho/shadcn_flutter.git" source: git version: "0.0.24" diff --git a/pubspec.yaml b/pubspec.yaml index 198bc949..f00c298f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -103,7 +103,7 @@ dependencies: shadcn_flutter: git: url: https://github.com/KRTirtho/shadcn_flutter.git - ref: 5359958464a57235f0f34c43a4623356a32459a0 + ref: fix-scaffold-footer-safearea shared_preferences: ^2.2.3 shelf: ^1.4.1 shelf_router: ^1.1.4 From 684e595d1687ec422695d6cd29737ab726ab8f03 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 29 Dec 2024 15:07:48 +0600 Subject: [PATCH 25/81] refactor: use shadcn widgets for create playlist and add tracks to playlist dialog --- .../dialogs/playlist_add_track_dialog.dart | 134 +++--- lib/components/form/checkbox_form_field.dart | 45 ++ lib/components/form/text_form_field.dart | 187 ++++++++ .../track_presentation.dart | 2 +- .../playlist/playlist_create_dialog.dart | 442 +++++++++--------- pubspec.lock | 18 +- pubspec.yaml | 2 + 7 files changed, 542 insertions(+), 288 deletions(-) create mode 100644 lib/components/form/checkbox_form_field.dart create mode 100644 lib/components/form/text_form_field.dart diff --git a/lib/components/dialogs/playlist_add_track_dialog.dart b/lib/components/dialogs/playlist_add_track_dialog.dart index 5af9c9e4..5098bf9d 100644 --- a/lib/components/dialogs/playlist_add_track_dialog.dart +++ b/lib/components/dialogs/playlist_add_track_dialog.dart @@ -1,7 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/modules/playlist/playlist_create_dialog.dart'; @@ -22,7 +21,7 @@ class PlaylistAddTrackDialog extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme) = Theme.of(context); + final typography = Theme.of(context).typography; final userPlaylists = ref.watch(favoritePlaylistsProvider); final favoritePlaylistsNotifier = ref.watch(favoritePlaylistsProvider.notifier); @@ -64,67 +63,86 @@ class PlaylistAddTrackDialog extends HookConsumerWidget { tracks.map((e) => e.id!).toList(), ), ), - ).then((_) => Navigator.pop(context, true)); + ).then((_) => context.mounted ? Navigator.pop(context, true) : null); } - return AlertDialog( - insetPadding: EdgeInsets.zero, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - context.l10n.add_to_playlist, - style: textTheme.titleMedium, + return ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 400), + child: AlertDialog( + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + context.l10n.add_to_playlist, + style: typography.large, + ), + const Spacer(), + const PlaylistCreateDialogButton(), + ], + ), + actions: [ + OutlineButton( + child: Text(context.l10n.cancel), + onPressed: () { + Navigator.pop(context, false); + }, + ), + PrimaryButton( + onPressed: onAdd, + child: Text(context.l10n.add), ), - const Gap(20), - const PlaylistCreateDialogButton(), ], - ), - actions: [ - OutlinedButton( - child: Text(context.l10n.cancel), - onPressed: () { - Navigator.pop(context, false); - }, - ), - FilledButton( - onPressed: onAdd, - child: Text(context.l10n.add), - ), - ], - content: SizedBox( - height: 300, - width: 300, - child: userPlaylists.isLoading - ? const Center(child: CircularProgressIndicator()) - : ListView.builder( - shrinkWrap: true, - itemCount: filteredPlaylists.length, - itemBuilder: (context, index) { - final playlist = filteredPlaylists.elementAt(index); - return CheckboxListTile( - secondary: CircleAvatar( - backgroundImage: UniversalImage.imageProvider( - playlist.images.asUrlString( - placeholder: ImagePlaceholder.collection, + content: SizedBox( + height: 300, + child: userPlaylists.isLoading + ? const Center(child: CircularProgressIndicator()) + : ListView.builder( + shrinkWrap: true, + itemCount: filteredPlaylists.length, + itemBuilder: (context, index) { + final playlist = filteredPlaylists.elementAt(index); + return Button.ghost( + style: ButtonVariance.ghost.copyWith( + padding: (context, _, __) { + return const EdgeInsets.symmetric(vertical: 8); + }, + ), + leading: Avatar( + initials: + Avatar.getInitials(playlist.name ?? "Playlist"), + provider: UniversalImage.imageProvider( + playlist.images.asUrlString( + placeholder: ImagePlaceholder.collection, + ), ), ), - ), - contentPadding: EdgeInsets.zero, - title: Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Text(playlist.name!), - ), - value: playlistsCheck.value[playlist.id] ?? false, - onChanged: (val) { - playlistsCheck.value = { - ...playlistsCheck.value, - playlist.id!: val == true - }; - }, - ); - }, - ), + trailing: Checkbox( + state: (playlistsCheck.value[playlist.id] ?? false) + ? CheckboxState.checked + : CheckboxState.unchecked, + onChanged: (val) { + playlistsCheck.value = { + ...playlistsCheck.value, + playlist.id!: val == CheckboxState.checked, + }; + }, + ), + onPressed: () { + playlistsCheck.value = { + ...playlistsCheck.value, + playlist.id!: + !(playlistsCheck.value[playlist.id] ?? false), + }; + }, + child: Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Text(playlist.name!), + ), + ); + }, + ), + ), ), ); } diff --git a/lib/components/form/checkbox_form_field.dart b/lib/components/form/checkbox_form_field.dart new file mode 100644 index 00000000..0e794833 --- /dev/null +++ b/lib/components/form/checkbox_form_field.dart @@ -0,0 +1,45 @@ +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; + +class CheckboxFormBuilderField extends StatelessWidget { + final String name; + final FormFieldValidator? validator; + + final ValueChanged? onChanged; + final Widget? leading; + final Widget? trailing; + final bool tristate; + const CheckboxFormBuilderField({ + super.key, + required this.name, + this.validator, + this.onChanged, + this.leading, + this.trailing, + this.tristate = false, + }); + + @override + Widget build(BuildContext context) { + return FormBuilderField( + name: name, + validator: validator, + builder: (field) { + return Checkbox( + state: tristate && field.value == null + ? CheckboxState.indeterminate + : field.value == true + ? CheckboxState.checked + : CheckboxState.unchecked, + onChanged: (state) { + field.didChange(state == CheckboxState.checked); + onChanged?.call(state); + }, + leading: leading, + trailing: trailing, + tristate: tristate, + ); + }, + ); + } +} diff --git a/lib/components/form/text_form_field.dart b/lib/components/form/text_form_field.dart new file mode 100644 index 00000000..ef3514c5 --- /dev/null +++ b/lib/components/form/text_form_field.dart @@ -0,0 +1,187 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; + +class TextFormBuilderField extends StatelessWidget { + final String name; + final FormFieldValidator? validator; + final Widget? label; + + final TextEditingController? controller; + final bool filled; + final Widget? placeholder; + final AlignmentGeometry? placeholderAlignment; + final AlignmentGeometry? leadingAlignment; + final AlignmentGeometry? trailingAlignment; + final bool border; + final Widget? leading; + final Widget? trailing; + final EdgeInsetsGeometry? padding; + final ValueChanged? onSubmitted; + final VoidCallback? onEditingComplete; + final FocusNode? focusNode; + final VoidCallback? onTap; + final bool enabled; + final bool readOnly; + final bool obscureText; + final String obscuringCharacter; + final String? initialValue; + final int? maxLength; + final MaxLengthEnforcement? maxLengthEnforcement; + final int? maxLines; + final int? minLines; + final BorderRadiusGeometry? borderRadius; + final TextAlign textAlign; + final bool expands; + final TextAlignVertical? textAlignVertical; + final UndoHistoryController? undoController; + final ValueChanged? onChanged; + final Iterable? autofillHints; + final void Function(PointerDownEvent event)? onTapOutside; + final List? inputFormatters; + final TextStyle? style; + final EditableTextContextMenuBuilder? contextMenuBuilder; + final bool useNativeContextMenu; + final bool? isCollapsed; + final TextInputType? keyboardType; + final TextInputAction? textInputAction; + final Clip clipBehavior; + final bool autofocus; + final WidgetStatesController? statesController; + + const TextFormBuilderField({ + super.key, + required this.name, + this.label, + this.validator, + this.controller, + this.maxLength, + this.maxLengthEnforcement, + this.maxLines = 1, + this.minLines, + this.filled = false, + this.placeholder, + this.border = true, + this.leading, + this.trailing, + this.padding, + this.onSubmitted, + this.onEditingComplete, + this.focusNode, + this.onTap, + this.enabled = true, + this.readOnly = false, + this.obscureText = false, + this.obscuringCharacter = '•', + this.initialValue, + this.borderRadius, + this.keyboardType, + this.textAlign = TextAlign.start, + this.expands = false, + this.textAlignVertical = TextAlignVertical.center, + this.autofillHints, + this.undoController, + this.onChanged, + this.onTapOutside, + this.inputFormatters, + this.style, + this.contextMenuBuilder = TextField.defaultContextMenuBuilder, + this.useNativeContextMenu = false, + this.isCollapsed, + this.textInputAction, + this.clipBehavior = Clip.hardEdge, + this.autofocus = false, + this.placeholderAlignment, + this.leadingAlignment, + this.trailingAlignment, + this.statesController, + }); + + @override + Widget build(BuildContext context) { + return FormBuilderField( + name: name, + validator: validator, + onChanged: (value) { + if (value == null) return; + onChanged?.call(value); + }, + builder: (field) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + spacing: 5, + children: [ + if (label != null) + DefaultTextStyle( + style: context.theme.typography.semiBold.copyWith( + color: field.hasError + ? context.theme.colorScheme.destructive + : context.theme.colorScheme.foreground, + ), + child: label!, + ), + TextField( + controller: controller, + maxLength: maxLength, + maxLengthEnforcement: maxLengthEnforcement, + maxLines: maxLines, + minLines: minLines, + filled: filled, + placeholder: placeholder, + border: border, + leading: leading, + trailing: trailing, + padding: padding, + onSubmitted: (value) { + field.validate(); + field.save(); + onSubmitted?.call(value); + }, + onEditingComplete: () { + field.save(); + onEditingComplete?.call(); + }, + focusNode: focusNode, + onTap: onTap, + enabled: enabled, + readOnly: readOnly, + obscureText: obscureText, + obscuringCharacter: obscuringCharacter, + initialValue: field.value, + borderRadius: borderRadius, + textAlign: textAlign, + expands: expands, + textAlignVertical: textAlignVertical, + autofillHints: autofillHints, + undoController: undoController, + onChanged: (value) { + field.didChange(value); + }, + onTapOutside: onTapOutside, + inputFormatters: inputFormatters, + style: style, + contextMenuBuilder: contextMenuBuilder, + useNativeContextMenu: useNativeContextMenu, + isCollapsed: isCollapsed, + keyboardType: keyboardType, + textInputAction: textInputAction, + clipBehavior: clipBehavior, + autofocus: autofocus, + placeholderAlignment: placeholderAlignment, + leadingAlignment: leadingAlignment, + trailingAlignment: trailingAlignment, + statesController: statesController, + ), + if (field.hasError) + Text( + field.errorText ?? "", + style: TextStyle( + color: context.theme.colorScheme.destructive, + ), + ), + ], + ), + ); + } +} diff --git a/lib/components/track_presentation/track_presentation.dart b/lib/components/track_presentation/track_presentation.dart index e81a2e1e..96f5f964 100644 --- a/lib/components/track_presentation/track_presentation.dart +++ b/lib/components/track_presentation/track_presentation.dart @@ -90,7 +90,7 @@ class TrackPresentation extends HookConsumerWidget { }, ), const PresentationListSection(), - const SliverGap(200), + const SliverSafeArea(sliver: SliverGap(10)), ], ), ), diff --git a/lib/modules/playlist/playlist_create_dialog.dart b/lib/modules/playlist/playlist_create_dialog.dart index 78680a1c..8b231b84 100644 --- a/lib/modules/playlist/playlist_create_dialog.dart +++ b/lib/modules/playlist/playlist_create_dialog.dart @@ -2,20 +2,23 @@ import 'dart:convert'; import 'dart:io'; import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:form_validator/form_validator.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:image_picker/image_picker.dart'; +import 'package:path/path.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/form/checkbox_form_field.dart'; +import 'package:spotube/components/form/text_form_field.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; -import 'package:spotube/extensions/string.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/provider/spotify_provider.dart'; @@ -23,241 +26,227 @@ class PlaylistCreateDialog extends HookConsumerWidget { /// Track ids to add to the playlist final List trackIds; final String? playlistId; - PlaylistCreateDialog({ + const PlaylistCreateDialog({ super.key, this.trackIds = const [], this.playlistId, }); - final formKey = GlobalKey(); - @override Widget build(BuildContext context, ref) { - return ScaffoldMessenger( - child: Scaffold( - backgroundColor: Colors.transparent, - body: HookBuilder(builder: (context) { - final userPlaylists = ref.watch(favoritePlaylistsProvider); - final playlist = ref.watch(playlistProvider(playlistId ?? "")); - final playlistNotifier = - ref.watch(playlistProvider(playlistId ?? "").notifier); + final userPlaylists = ref.watch(favoritePlaylistsProvider); + final playlist = ref.watch(playlistProvider(playlistId ?? "")); + final playlistNotifier = + ref.watch(playlistProvider(playlistId ?? "").notifier); - final updatingPlaylist = useMemoized( - () => userPlaylists.asData?.value.items - .firstWhereOrNull((playlist) => playlist.id == playlistId), - [ - userPlaylists.asData?.value.items, - playlistId, - ], - ); + final isSubmitting = useState(false); - final playlistName = useTextEditingController( - text: updatingPlaylist?.name, - ); - final description = useTextEditingController( - text: updatingPlaylist?.description?.unescapeHtml(), - ); - final public = useState( - updatingPlaylist?.public ?? false, - ); - final collaborative = useState( - updatingPlaylist?.collaborative ?? false, - ); - final image = useState(null); + final formKey = useMemoized(() => GlobalKey(), []); - final isUpdatingPlaylist = playlistId != null; + final updatingPlaylist = useMemoized( + () => userPlaylists.asData?.value.items + .firstWhereOrNull((playlist) => playlist.id == playlistId), + [ + userPlaylists.asData?.value.items, + playlistId, + ], + ); - final l10n = context.l10n; - final theme = Theme.of(context); - final scaffold = ScaffoldMessenger.of(context); + final isUpdatingPlaylist = playlistId != null; - final onError = useCallback((error) { - if (error is SpotifyError || error is SpotifyException) { - scaffold.showSnackBar( - SnackBar( - content: Text( - l10n.error(error.message ?? context.l10n.epic_failure), - style: theme.textTheme.bodyMedium!.copyWith( - color: theme.colorScheme.onError, - ), + final l10n = context.l10n; + final theme = Theme.of(context); + + final onError = useCallback((error) { + if (error is SpotifyError || error is SpotifyException) { + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Basic( + title: Text( + l10n.error(error.message ?? l10n.epic_failure), + style: theme.typography.normal.copyWith( + color: theme.colorScheme.destructive, ), - backgroundColor: theme.colorScheme.error, ), - ); - } - }, [scaffold, l10n, theme]); - - Future onCreate() async { - if (!formKey.currentState!.validate()) return; - - final PlaylistInput payload = ( - playlistName: playlistName.text, - collaborative: collaborative.value, - public: public.value, - description: description.text, - base64Image: image.value?.path != null - ? await image.value! - .readAsBytes() - .then((bytes) => base64Encode(bytes)) - : null, + ), ); + }, + ); + } + }, [l10n, theme]); - if (isUpdatingPlaylist) { - await playlistNotifier.modify(payload, onError); - } else { - await playlistNotifier.create(payload, onError); - } + Future onCreate() async { + if (!formKey.currentState!.saveAndValidate()) return; - if (context.mounted && - !ref.read(playlistProvider(playlistId ?? "")).hasError) { - context.pop(); - } - } + try { + isSubmitting.value = true; + final values = formKey.currentState!.value; - return AlertDialog( - title: Text( - isUpdatingPlaylist - ? context.l10n.update_playlist - : context.l10n.create_a_playlist, - ), - actions: [ - OutlinedButton( - child: Text(context.l10n.cancel), - onPressed: () { - Navigator.pop(context); + final PlaylistInput payload = ( + playlistName: values['playlistName'], + collaborative: values['collaborative'], + public: values['public'], + description: values['description'], + base64Image: (values['image'] as XFile?)?.path != null + ? await (values['image'] as XFile) + .readAsBytes() + .then((bytes) => base64Encode(bytes)) + : null, + ); + + if (isUpdatingPlaylist) { + await playlistNotifier.modify(payload, onError); + } else { + await playlistNotifier.create(payload, onError); + } + } finally { + isSubmitting.value = false; + if (context.mounted && + !ref.read(playlistProvider(playlistId ?? "")).hasError) { + context.pop(); + } + } + } + + return AlertDialog( + title: Text( + isUpdatingPlaylist + ? context.l10n.update_playlist + : context.l10n.create_a_playlist, + ), + actions: [ + Button.outline( + child: Text(context.l10n.cancel), + onPressed: () { + Navigator.pop(context); + }, + ), + Button.primary( + onPressed: onCreate, + enabled: !playlist.isLoading & !isSubmitting.value, + child: Text( + isUpdatingPlaylist ? context.l10n.update : context.l10n.create, + ), + ), + ], + content: Container( + width: MediaQuery.of(context).size.width, + constraints: const BoxConstraints(maxWidth: 500), + child: FormBuilder( + key: formKey, + initialValue: { + 'playlistName': updatingPlaylist?.name, + 'description': updatingPlaylist?.description, + 'public': updatingPlaylist?.public ?? false, + 'collaborative': updatingPlaylist?.collaborative ?? false, + }, + child: ListView( + shrinkWrap: true, + children: [ + FormBuilderField( + name: 'image', + validator: (value) { + if (value == null) return null; + final file = File(value.path); + + if (file.lengthSync() > 256000) { + return "Image size should be less than 256kb"; + } + + if (extension(file.path) != ".png") { + return "Image should be in PNG format"; + } + return null; + }, + builder: (field) { + return Column( + spacing: 10, + children: [ + UniversalImage( + path: field.value?.path ?? + (updatingPlaylist?.images).asUrlString( + placeholder: ImagePlaceholder.collection, + ), + height: 200, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Button.secondary( + leading: const Icon(SpotubeIcons.edit), + child: Text( + field.value?.path != null || + updatingPlaylist?.images != null + ? context.l10n.change_cover + : context.l10n.add_cover, + ), + onPressed: () async { + final imageFile = await ImagePicker().pickImage( + source: ImageSource.gallery, + ); + + if (imageFile != null) { + field.didChange(imageFile); + field.validate(); + field.save(); + } + }, + ), + const SizedBox(width: 10), + IconButton.destructive( + icon: const Icon(SpotubeIcons.trash), + enabled: field.value != null, + onPressed: () { + field.didChange(null); + field.validate(); + field.save(); + }, + ), + ], + ), + if (field.hasError) + Text( + field.errorText ?? "", + style: theme.typography.normal.copyWith( + color: theme.colorScheme.destructive, + ), + ) + ], + ); }, ), - FilledButton( - onPressed: playlist.isLoading ? null : onCreate, - child: Text( - isUpdatingPlaylist - ? context.l10n.update - : context.l10n.create, - ), + const Gap(20), + TextFormBuilderField( + name: 'playlistName', + label: Text(context.l10n.playlist_name), + placeholder: Text(context.l10n.name_of_playlist), + validator: FormBuilderValidators.required(), + ), + const Gap(20), + TextFormBuilderField( + name: 'description', + label: Text(context.l10n.description), + validator: FormBuilderValidators.required(), + placeholder: Text(context.l10n.description), + keyboardType: TextInputType.multiline, + maxLines: 5, + ), + const Gap(20), + CheckboxFormBuilderField( + name: 'public', + trailing: Text(context.l10n.public), + ), + const Gap(10), + CheckboxFormBuilderField( + name: 'collaborative', + trailing: Text(context.l10n.collaborative), ), ], - insetPadding: const EdgeInsets.all(8), - content: Container( - width: MediaQuery.of(context).size.width, - constraints: const BoxConstraints(maxWidth: 500), - child: Form( - key: formKey, - child: ListView( - shrinkWrap: true, - children: [ - FormField( - initialValue: image.value, - onSaved: (newValue) { - image.value = newValue; - }, - validator: (value) { - if (value == null) return null; - final file = File(value.path); - - if (file.lengthSync() > 256000) { - return "Image size should be less than 256kb"; - } - return null; - }, - builder: (field) { - return Column( - children: [ - UniversalImage( - path: field.value?.path ?? - (updatingPlaylist?.images).asUrlString( - placeholder: ImagePlaceholder.collection, - ), - height: 200, - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - FilledButton.icon( - icon: const Icon(SpotubeIcons.edit), - label: Text( - field.value?.path != null || - updatingPlaylist?.images != null - ? context.l10n.change_cover - : context.l10n.add_cover, - ), - onPressed: () async { - final imageFile = await ImagePicker() - .pickImage( - source: ImageSource.gallery); - - if (imageFile != null) { - field.didChange(imageFile); - field.validate(); - field.save(); - } - }, - ), - const SizedBox(width: 10), - IconButton.filled( - icon: const Icon(SpotubeIcons.trash), - style: IconButton.styleFrom( - backgroundColor: - theme.colorScheme.errorContainer, - foregroundColor: theme.colorScheme.error, - ), - onPressed: field.value == null - ? null - : () { - field.didChange(null); - field.validate(); - field.save(); - }, - ), - ], - ), - if (field.hasError) - Text( - field.errorText ?? "", - style: theme.textTheme.bodyMedium!.copyWith( - color: theme.colorScheme.error, - ), - ) - ], - ); - }), - const SizedBox(height: 10), - TextFormField( - controller: playlistName, - decoration: InputDecoration( - hintText: context.l10n.name_of_playlist, - labelText: context.l10n.name_of_playlist, - ), - validator: ValidationBuilder().required().build(), - ), - const SizedBox(height: 10), - TextFormField( - controller: description, - decoration: InputDecoration( - hintText: context.l10n.description, - ), - keyboardType: TextInputType.multiline, - validator: ValidationBuilder().required().build(), - maxLines: 5, - ), - const SizedBox(height: 10), - CheckboxListTile( - title: Text(context.l10n.public), - value: public.value, - onChanged: (val) => public.value = val ?? false, - ), - const SizedBox(height: 10), - CheckboxListTile( - title: Text(context.l10n.collaborative), - value: collaborative.value, - onChanged: (val) => collaborative.value = val ?? false, - ), - ], - ), - ), - ), - ); - }), + ), + ), ), ); } @@ -269,7 +258,10 @@ class PlaylistCreateDialogButton extends HookConsumerWidget { showPlaylistDialog(BuildContext context, SpotifyApi spotify) { showDialog( context: context, - builder: (context) => PlaylistCreateDialog(), + alignment: Alignment.center, + builder: (context) => const ToastLayer( + child: PlaylistCreateDialog(), + ), ); } @@ -279,21 +271,15 @@ class PlaylistCreateDialogButton extends HookConsumerWidget { final spotify = ref.watch(spotifyProvider); if (mediaQuery.smAndDown) { - return ElevatedButton( - style: FilledButton.styleFrom( - foregroundColor: Theme.of(context).colorScheme.primary, - ), - child: const Icon(SpotubeIcons.addFilled), + return IconButton.secondary( + icon: const Icon(SpotubeIcons.addFilled), onPressed: () => showPlaylistDialog(context, spotify), ); } - return FilledButton.tonalIcon( - style: FilledButton.styleFrom( - foregroundColor: Theme.of(context).colorScheme.primary, - ), - icon: const Icon(SpotubeIcons.addFilled), - label: Text(context.l10n.create_playlist), + return Button.secondary( + leading: const Icon(SpotubeIcons.addFilled), + child: Text(context.l10n.create_playlist), onPressed: () => showPlaylistDialog(context, spotify), ); } diff --git a/pubspec.lock b/pubspec.lock index d441371d..8c8c30be 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -757,6 +757,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0+1" + flutter_form_builder: + dependency: "direct main" + description: + name: flutter_form_builder + sha256: "39aee5a2548df0b3979a83eea38468116a888341fbca8a92c4be18a486a7bb57" + url: "https://pub.dev" + source: hosted + version: "9.6.0" flutter_gen_core: dependency: transitive description: @@ -972,6 +980,14 @@ packages: description: flutter source: sdk version: "0.0.0" + form_builder_validators: + dependency: "direct main" + description: + name: form_builder_validators + sha256: "517fb884183fff7a0ef3db7d375981011da26ee452f20fb3d2e788ad527ad01d" + url: "https://pub.dev" + source: hosted + version: "11.1.1" form_validator: dependency: "direct main" description: @@ -2670,5 +2686,5 @@ packages: source: hosted version: "2.3.6" sdks: - dart: ">=3.5.3 <4.0.0" + dart: ">=3.6.0 <4.0.0" flutter: ">=3.27.0" diff --git a/pubspec.yaml b/pubspec.yaml index f00c298f..e06cf96c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,6 +54,7 @@ dependencies: flutter_discord_rpc: ^1.0.0 flutter_displaymode: ^0.6.0 flutter_feather_icons: ^2.0.0+1 + flutter_form_builder: ^9.6.0 flutter_hooks: ^0.20.5 flutter_inappwebview: ^6.1.3 flutter_localizations: @@ -62,6 +63,7 @@ dependencies: flutter_riverpod: ^2.5.1 flutter_secure_storage: ^9.0.0 flutter_sharing_intent: ^1.1.0 + form_builder_validators: ^11.1.1 form_validator: ^2.1.1 freezed_annotation: ^2.4.1 fuzzywuzzy: ^1.1.6 From f96b5eae974432be782c0f6be3b5fa87f69a1416 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 3 Jan 2025 21:11:36 +0600 Subject: [PATCH 26/81] refactor: floating player to use shadcn --- .../dialogs/track_details_dialog.dart | 83 +-- lib/components/panels/controller.dart | 146 ---- lib/components/panels/helpers.dart | 95 --- lib/components/panels/sliding_up_panel.dart | 685 ------------------ .../track_presentation.dart | 1 + lib/main.dart | 2 +- lib/modules/player/player.dart | 546 ++++++-------- lib/modules/player/player_overlay.dart | 187 +---- .../player/player_overlay_collapsed.dart | 118 +++ lib/modules/root/spotube_navigation_bar.dart | 42 +- lib/pages/lyrics/plain_lyrics.dart | 9 +- lib/pages/lyrics/synced_lyrics.dart | 20 +- pubspec.lock | 8 + pubspec.yaml | 1 + 14 files changed, 457 insertions(+), 1486 deletions(-) delete mode 100644 lib/components/panels/controller.dart delete mode 100644 lib/components/panels/helpers.dart delete mode 100644 lib/components/panels/sliding_up_panel.dart create mode 100644 lib/modules/player/player_overlay_collapsed.dart diff --git a/lib/components/dialogs/track_details_dialog.dart b/lib/components/dialogs/track_details_dialog.dart index 61bca7b1..1296ae0e 100644 --- a/lib/components/dialogs/track_details_dialog.dart +++ b/lib/components/dialogs/track_details_dialog.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/links/artist_link.dart'; @@ -73,17 +73,15 @@ class TrackDetailsDialog extends HookWidget { }; return AlertDialog( - contentPadding: const EdgeInsets.all(16), - insetPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 100), - scrollable: true, + surfaceBlur: 0, + surfaceOpacity: 1, title: Row( - mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, children: [ const Icon(SpotubeIcons.info), - const SizedBox(width: 8), Text( context.l10n.details, - style: theme.textTheme.titleMedium, + style: theme.typography.h4, ), ], ), @@ -91,65 +89,64 @@ class TrackDetailsDialog extends HookWidget { width: mediaQuery.mdAndUp ? double.infinity : 700, child: Table( columnWidths: const { - 0: FixedColumnWidth(95), - 1: FixedColumnWidth(10), - 2: FlexColumnWidth(1), + 0: FixedTableSize(95), + 1: FixedTableSize(10), + 2: FlexTableSize(), }, - defaultVerticalAlignment: TableCellVerticalAlignment.middle, - children: [ + theme: const TableTheme( + backgroundColor: Colors.transparent, + cellTheme: TableCellTheme( + backgroundColor: WidgetStatePropertyAll(Colors.transparent), + ), + ), + rowHeights: const {0: FixedTableSize(40)}, + rows: [ for (final entry in detailsMap.entries) TableRow( - children: [ + cells: [ TableCell( - verticalAlignment: TableCellVerticalAlignment.top, child: Text( entry.key, - style: theme.textTheme.titleMedium, + style: theme.typography.bold, ), ), const TableCell( - verticalAlignment: TableCellVerticalAlignment.top, child: Text(":"), ), - if (entry.value is Widget) - entry.value as Widget - else if (entry.value is String) - Text( - entry.value as String, - style: theme.textTheme.bodyMedium, - ), + TableCell( + child: entry.value is Widget + ? entry.value as Widget + : (entry.value is String) + ? Text( + entry.value as String, + style: theme.typography.normal, + ) + : const Text(""), + ), ], ), - const TableRow( - children: [ - SizedBox(height: 16), - SizedBox(height: 16), - SizedBox(height: 16), - ], - ), for (final entry in ytTracksDetailsMap.entries) TableRow( - children: [ + cells: [ TableCell( - verticalAlignment: TableCellVerticalAlignment.top, child: Text( entry.key, - style: theme.textTheme.titleMedium, + style: theme.typography.bold, ), ), const TableCell( - verticalAlignment: TableCellVerticalAlignment.top, child: Text(":"), ), - if (entry.value is Widget) - entry.value as Widget - else - Text( - entry.value, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: theme.textTheme.bodyMedium, - ), + TableCell( + child: entry.value is Widget + ? entry.value as Widget + : Text( + entry.value, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: theme.typography.normal, + ), + ), ], ), ], diff --git a/lib/components/panels/controller.dart b/lib/components/panels/controller.dart deleted file mode 100644 index 4e367701..00000000 --- a/lib/components/panels/controller.dart +++ /dev/null @@ -1,146 +0,0 @@ -part of 'sliding_up_panel.dart'; - -class PanelController extends ChangeNotifier { - SlidingUpPanelState? _panelState; - - void _addState(SlidingUpPanelState panelState) { - _panelState = panelState; - notifyListeners(); - } - - bool _forceScrollChange = false; - - /// use this function when scroll change in func - /// Example: - /// panelController.forseScrollChange(scrollController.animateTo(100, duration: Duration(milliseconds: 400), curve: Curves.ease)) - Future forceScrollChange(Future func) async { - _forceScrollChange = true; - _panelState!._scrollingEnabled = true; - await func; - // if (_panelState!._sc.offset == 0) { - // _panelState!._scrollingEnabled = true; - // } - if (panelPosition < 1) { - _panelState!._scMinOffset = _panelState!._scrollController.offset; - } - _forceScrollChange = false; - } - - bool __nowTargetForceDraggable = false; - - bool get _nowTargetForceDraggable => __nowTargetForceDraggable; - - set _nowTargetForceDraggable(bool value) { - __nowTargetForceDraggable = value; - notifyListeners(); - } - - /// Determine if the panelController is attached to an instance - /// of the SlidingUpPanel (this property must return true before any other - /// functions can be used) - bool get isAttached => _panelState != null; - - /// Closes the sliding panel to its collapsed state (i.e. to the minHeight) - Future close() async { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - await _panelState!._close(); - notifyListeners(); - } - - /// Opens the sliding panel fully - /// (i.e. to the maxHeight) - Future open() async { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - await _panelState!._open(); - notifyListeners(); - } - - /// Hides the sliding panel (i.e. is invisible) - Future hide() async { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - await _panelState!._hide(); - notifyListeners(); - } - - /// Shows the sliding panel in its collapsed state - /// (i.e. "un-hide" the sliding panel) - Future show() async { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - await _panelState!._show(); - notifyListeners(); - } - - /// Animates the panel position to the value. - /// The value must between 0.0 and 1.0 - /// where 0.0 is fully collapsed and 1.0 is completely open. - /// (optional) duration specifies the time for the animation to complete - /// (optional) curve specifies the easing behavior of the animation. - Future animatePanelToPosition(double value, - {Duration? duration, Curve curve = Curves.linear}) { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - assert(0.0 <= value && value <= 1.0); - return _panelState! - ._animatePanelToPosition(value, duration: duration, curve: curve); - } - - /// Animates the panel position to the snap point - /// Requires that the SlidingUpPanel snapPoint property is not null - /// (optional) duration specifies the time for the animation to complete - /// (optional) curve specifies the easing behavior of the animation. - Future animatePanelToSnapPoint( - {Duration? duration, Curve curve = Curves.linear}) { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - assert(_panelState!.widget.snapPoint != null, - "SlidingUpPanel snapPoint property must not be null"); - return _panelState! - ._animatePanelToSnapPoint(duration: duration, curve: curve); - } - - /// Sets the panel position (without animation). - /// The value must between 0.0 and 1.0 - /// where 0.0 is fully collapsed and 1.0 is completely open. - set panelPosition(double value) { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - assert(0.0 <= value && value <= 1.0); - _panelState!._panelPosition = value; - } - - /// Gets the current panel position. - /// Returns the % offset from collapsed state - /// to the open state - /// as a decimal between 0.0 and 1.0 - /// where 0.0 is fully collapsed and - /// 1.0 is full open. - double get panelPosition { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - return _panelState!._panelPosition; - } - - /// Returns whether or not the panel is - /// currently animating. - bool get isPanelAnimating { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - return _panelState!._isPanelAnimating; - } - - /// Returns whether or not the - /// panel is open. - bool get isPanelOpen { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - return _panelState!._isPanelOpen; - } - - /// Returns whether or not the - /// panel is closed. - bool get isPanelClosed { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - return _panelState!._isPanelClosed; - } - - /// Returns whether or not the - /// panel is shown/hidden. - bool get isPanelShown { - assert(isAttached, "PanelController must be attached to a SlidingUpPanel"); - return _panelState!._isPanelShown; - } -} diff --git a/lib/components/panels/helpers.dart b/lib/components/panels/helpers.dart deleted file mode 100644 index d79fa97c..00000000 --- a/lib/components/panels/helpers.dart +++ /dev/null @@ -1,95 +0,0 @@ -part of "sliding_up_panel.dart"; - -/// if you want to prevent the panel from being dragged using the widget, -/// wrap the widget with this -class IgnoreDraggableWidget extends SingleChildRenderObjectWidget { - const IgnoreDraggableWidget({ - super.key, - required super.child, - }); - - @override - IgnoreDraggableWidgetWidgetRenderBox createRenderObject( - BuildContext context, - ) { - return IgnoreDraggableWidgetWidgetRenderBox(); - } -} - -class IgnoreDraggableWidgetWidgetRenderBox extends RenderPointerListener { - @override - HitTestBehavior get behavior => HitTestBehavior.opaque; -} - -/// if you want to force the panel to be dragged using the widget, -/// wrap the widget with this -/// For example, use [Scrollable] inside to allow the panel to be dragged -/// even if the scroll is not at position 0. -class ForceDraggableWidget extends SingleChildRenderObjectWidget { - const ForceDraggableWidget({ - super.key, - required super.child, - }); - - @override - ForceDraggableWidgetRenderBox createRenderObject( - BuildContext context, - ) { - return ForceDraggableWidgetRenderBox(); - } -} - -class ForceDraggableWidgetRenderBox extends RenderPointerListener { - @override - HitTestBehavior get behavior => HitTestBehavior.opaque; -} - -/// To make [ForceDraggableWidget] work in [Scrollable] widgets -class PanelScrollPhysics extends ScrollPhysics { - final PanelController controller; - const PanelScrollPhysics({required this.controller, super.parent}); - @override - PanelScrollPhysics applyTo(ScrollPhysics? ancestor) { - return PanelScrollPhysics( - controller: controller, parent: buildParent(ancestor)); - } - - @override - double applyPhysicsToUserOffset(ScrollMetrics position, double offset) { - if (controller._nowTargetForceDraggable) return 0.0; - return super.applyPhysicsToUserOffset(position, offset); - } - - @override - Simulation? createBallisticSimulation( - ScrollMetrics position, double velocity) { - if (controller._nowTargetForceDraggable) { - return super.createBallisticSimulation(position, 0); - } - return super.createBallisticSimulation(position, velocity); - } - - @override - bool get allowImplicitScrolling => false; -} - -/// if you want to prevent unwanted panel dragging when scrolling widgets [Scrollable] with horizontal axis -/// wrap the widget with this -class HorizontalScrollableWidget extends SingleChildRenderObjectWidget { - const HorizontalScrollableWidget({ - super.key, - required super.child, - }); - - @override - HorizontalScrollableWidgetRenderBox createRenderObject( - BuildContext context, - ) { - return HorizontalScrollableWidgetRenderBox(); - } -} - -class HorizontalScrollableWidgetRenderBox extends RenderPointerListener { - @override - HitTestBehavior get behavior => HitTestBehavior.opaque; -} diff --git a/lib/components/panels/sliding_up_panel.dart b/lib/components/panels/sliding_up_panel.dart deleted file mode 100644 index e99fe261..00000000 --- a/lib/components/panels/sliding_up_panel.dart +++ /dev/null @@ -1,685 +0,0 @@ -/* -Name: Zotov Vladimir -Date: 18/06/22 -Purpose: Defines the package: sliding_up_panel2 -Copyright: © 2022, Zotov Vladimir. All rights reserved. -Licensing: More information can be found here: https://github.com/Zotov-VD/sliding_up_panel/blob/master/LICENSE - -This product includes software developed by Akshath Jain (https://akshathjain.com) -*/ - -library panels; - -import 'dart:math'; - -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/physics.dart'; -import 'package:flutter/rendering.dart'; - -part 'controller.dart'; -part 'helpers.dart'; - -enum SlideDirection { up, down } - -enum PanelState { open, closed } - -class SlidingUpPanel extends StatefulWidget { - /// Returns the Widget that slides into view. When the - /// panel is collapsed and if [collapsed] is null, - /// then top portion of this Widget will be displayed; - /// otherwise, [collapsed] will be displayed overtop - /// of this Widget. - final Widget? Function(double position)? panelBuilder; - - /// The Widget displayed overtop the [panel] when collapsed. - /// This fades out as the panel is opened. - final Widget? collapsed; - - /// The Widget that lies underneath the sliding panel. - /// This Widget automatically sizes itself - /// to fill the screen. - final Widget? body; - - /// Optional persistent widget that floats above the [panel] and attaches - /// to the top of the [panel]. Content at the top of the panel will be covered - /// by this widget. Add padding to the bottom of the `panel` to - /// avoid coverage. - final Widget? header; - - /// Optional persistent widget that floats above the [panel] and - /// attaches to the bottom of the [panel]. Content at the bottom of the panel - /// will be covered by this widget. Add padding to the bottom of the `panel` - /// to avoid coverage. - final Widget? footer; - - /// The height of the sliding panel when fully collapsed. - final double minHeight; - - /// The height of the sliding panel when fully open. - final double maxHeight; - - /// A point between [minHeight] and [maxHeight] that the panel snaps to - /// while animating. A fast swipe on the panel will disregard this point - /// and go directly to the open/close position. This value is represented as a - /// percentage of the total animation distance ([maxHeight] - [minHeight]), - /// so it must be between 0.0 and 1.0, exclusive. - final double? snapPoint; - - /// The amount to inset the children of the sliding panel sheet. - final EdgeInsetsGeometry? padding; - - /// Empty space surrounding the sliding panel sheet. - final EdgeInsetsGeometry? margin; - - /// Set to false to disable the panel from snapping open or closed. - final bool panelSnapping; - - /// Disable panel draggable on scrolling. Defaults to false. - final bool disableDraggableOnScrolling; - - /// If non-null, this can be used to control the state of the panel. - final PanelController? controller; - - /// If non-null, shows a darkening shadow over the [body] as the panel slides open. - final bool backdropEnabled; - - /// Shows a darkening shadow of this [Color] over the [body] as the panel slides open. - final Color backdropColor; - - /// The opacity of the backdrop when the panel is fully open. - /// This value can range from 0.0 to 1.0 where 0.0 is completely transparent - /// and 1.0 is completely opaque. - final double backdropOpacity; - - /// Flag that indicates whether or not tapping the - /// backdrop closes the panel. Defaults to true. - final bool backdropTapClosesPanel; - - /// If non-null, this callback - /// is called as the panel slides around with the - /// current position of the panel. The position is a double - /// between 0.0 and 1.0 where 0.0 is fully collapsed and 1.0 is fully open. - final void Function(double position)? onPanelSlide; - - /// If non-null, this callback is called when the - /// panel is fully opened - final VoidCallback? onPanelOpened; - - /// If non-null, this callback is called when the panel - /// is fully collapsed. - final VoidCallback? onPanelClosed; - - /// If non-null and true, the SlidingUpPanel exhibits a - /// parallax effect as the panel slides up. Essentially, - /// the body slides up as the panel slides up. - final bool parallaxEnabled; - - /// Allows for specifying the extent of the parallax effect in terms - /// of the percentage the panel has slid up/down. Recommended values are - /// within 0.0 and 1.0 where 0.0 is no parallax and 1.0 mimics a - /// one-to-one scrolling effect. Defaults to a 10% parallax. - final double parallaxOffset; - - /// Allows toggling of the draggability of the SlidingUpPanel. - /// Set this to false to prevent the user from being able to drag - /// the panel up and down. Defaults to true. - final bool isDraggable; - - /// Either SlideDirection.UP or SlideDirection.DOWN. Indicates which way - /// the panel should slide. Defaults to UP. If set to DOWN, the panel attaches - /// itself to the top of the screen and is fully opened when the user swipes - /// down on the panel. - final SlideDirection slideDirection; - - /// The default state of the panel; either PanelState.OPEN or PanelState.CLOSED. - /// This value defaults to PanelState.CLOSED which indicates that the panel is - /// in the closed position and must be opened. PanelState.OPEN indicates that - /// by default the Panel is open and must be swiped closed by the user. - final PanelState defaultPanelState; - - /// To attach to a [Scrollable] on a panel that - /// links the panel's position to the scroll position. Useful for implementing - /// infinite scroll behavior - final ScrollController? scrollController; - - final BoxDecoration? panelDecoration; - - const SlidingUpPanel( - {super.key, - this.body, - this.collapsed, - this.minHeight = 100.0, - this.maxHeight = 500.0, - this.snapPoint, - this.padding, - this.margin, - this.panelDecoration, - this.panelSnapping = true, - this.disableDraggableOnScrolling = false, - this.controller, - this.backdropEnabled = false, - this.backdropColor = Colors.black, - this.backdropOpacity = 0.5, - this.backdropTapClosesPanel = true, - this.onPanelSlide, - this.onPanelOpened, - this.onPanelClosed, - this.parallaxEnabled = false, - this.parallaxOffset = 0.1, - this.isDraggable = true, - this.slideDirection = SlideDirection.up, - this.defaultPanelState = PanelState.closed, - this.header, - this.footer, - this.scrollController, - this.panelBuilder}) - : assert(panelBuilder != null), - assert(0 <= backdropOpacity && backdropOpacity <= 1.0), - assert(snapPoint == null || 0 < snapPoint && snapPoint < 1.0); - - @override - SlidingUpPanelState createState() => SlidingUpPanelState(); -} - -class SlidingUpPanelState extends State - with SingleTickerProviderStateMixin { - late AnimationController _animationController; - late final ScrollController _scrollController; - - bool _scrollingEnabled = false; - final VelocityTracker _velocityTracker = - VelocityTracker.withKind(PointerDeviceKind.touch); - - bool _isPanelVisible = true; - - @override - void initState() { - super.initState(); - - _animationController = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 300), - value: widget.defaultPanelState == PanelState.closed - ? 0.0 - : 1.0 //set the default panel state (i.e. set initial value of _ac) - ) - ..addListener(() { - if (widget.onPanelSlide != null) { - widget.onPanelSlide!(_animationController.value); - } - - if (widget.onPanelOpened != null && - (_animationController.value == 1.0 || - _animationController.value == 0.0)) { - widget.onPanelOpened!(); - } - }); - - // prevent the panel content from being scrolled only if the widget is - // draggable and panel scrolling is enabled - _scrollController = widget.scrollController ?? ScrollController(); - _scrollController.addListener(() { - if (widget.isDraggable && - !widget.disableDraggableOnScrolling && - (!_scrollingEnabled || _panelPosition < 1) && - widget.controller?._forceScrollChange != true) { - _scrollController.jumpTo(_scMinOffset); - } - }); - - widget.controller?._addState(this); - } - - @override - Widget build(BuildContext context) { - final mediaQuery = MediaQuery.of(context); - - return Stack( - alignment: widget.slideDirection == SlideDirection.up - ? Alignment.bottomCenter - : Alignment.topCenter, - children: [ - //make the back widget take up the entire back side - if (widget.body != null) - AnimatedBuilder( - animation: _animationController, - builder: (context, child) { - return Positioned( - top: widget.parallaxEnabled ? _getParallax() : 0.0, - child: child ?? const SizedBox(), - ); - }, - child: SizedBox( - height: mediaQuery.size.height, - width: mediaQuery.size.width, - child: widget.body, - ), - ), - - //the backdrop to overlay on the body - if (widget.backdropEnabled) - GestureDetector( - onVerticalDragEnd: widget.backdropTapClosesPanel - ? (DragEndDetails details) { - // only trigger a close if the drag is towards panel close position - if ((widget.slideDirection == SlideDirection.up ? 1 : -1) * - details.velocity.pixelsPerSecond.dy > - 0) _close(); - } - : null, - onTap: widget.backdropTapClosesPanel ? () => _close() : null, - child: AnimatedBuilder( - animation: _animationController, - builder: (context, _) { - return Container( - height: mediaQuery.size.height, - width: mediaQuery.size.width, - - //set color to null so that touch events pass through - //to the body when the panel is closed, otherwise, - //if a color exists, then touch events won't go through - color: _animationController.value == 0.0 - ? null - : widget.backdropColor.withOpacity( - widget.backdropOpacity * _animationController.value, - ), - ); - }), - ), - - //the actual sliding part - if (_isPanelVisible) - _gestureHandler( - child: AnimatedBuilder( - animation: _animationController, - builder: (context, child) { - return Container( - height: _animationController.value * - (widget.maxHeight - widget.minHeight) + - widget.minHeight, - margin: widget.margin, - padding: widget.padding, - decoration: widget.panelDecoration, - child: child, - ); - }, - child: Stack( - children: [ - //open panel - Positioned( - top: - widget.slideDirection == SlideDirection.up ? 0.0 : null, - bottom: widget.slideDirection == SlideDirection.down - ? 0.0 - : null, - width: mediaQuery.size.width - - (widget.margin != null - ? widget.margin!.horizontal - : 0) - - (widget.padding != null - ? widget.padding!.horizontal - : 0), - child: SizedBox( - height: widget.maxHeight, - child: widget.panelBuilder!( - _animationController.value, - ), - ), - ), - - // footer - if (widget.footer != null) - Positioned( - top: widget.slideDirection == SlideDirection.up - ? null - : 0.0, - bottom: widget.slideDirection == SlideDirection.down - ? null - : 0.0, - child: widget.footer ?? const SizedBox()), - - // header - if (widget.header != null) - Positioned( - top: widget.slideDirection == SlideDirection.up - ? 0.0 - : null, - bottom: widget.slideDirection == SlideDirection.down - ? 0.0 - : null, - child: widget.header ?? const SizedBox(), - ), - - // collapsed panel - Positioned( - top: - widget.slideDirection == SlideDirection.up ? 0.0 : null, - bottom: widget.slideDirection == SlideDirection.down - ? 0.0 - : null, - width: mediaQuery.size.width - - (widget.margin != null - ? widget.margin!.horizontal - : 0) - - (widget.padding != null - ? widget.padding!.horizontal - : 0), - child: AnimatedContainer( - duration: const Duration(milliseconds: 250), - height: widget.minHeight, - child: widget.collapsed == null - ? null - : FadeTransition( - opacity: Tween(begin: 1.0, end: 0.0) - .animate(_animationController), - - // if the panel is open ignore pointers (touch events) on the collapsed - // child so that way touch events go through to whatever is underneath - child: IgnorePointer( - ignoring: _animationController.value == 1.0, - child: widget.collapsed, - ), - ), - ), - ), - ], - ), - ), - ), - ], - ); - } - - @override - void dispose() { - _animationController.dispose(); - super.dispose(); - } - - double _getParallax() { - if (widget.slideDirection == SlideDirection.up) { - return -_animationController.value * - (widget.maxHeight - widget.minHeight) * - widget.parallaxOffset; - } else { - return _animationController.value * - (widget.maxHeight - widget.minHeight) * - widget.parallaxOffset; - } - } - - bool _ignoreScrollable = false; - bool _isHorizontalScrollableWidget = false; - Axis? _scrollableAxis; - - // returns a gesture detector if panel is used - // and a listener if panelBuilder is used. - // this is because the listener is designed only for use with linking the scrolling of - // panels and using it for panels that don't want to linked scrolling yields odd results - Widget _gestureHandler({required Widget child}) { - if (!widget.isDraggable) return child; - - return Listener( - onPointerDown: (PointerDownEvent e) { - var rb = context.findRenderObject() as RenderBox; - var result = BoxHitTestResult(); - rb.hitTest(result, position: e.position); - - if (_panelPosition == 1) { - _scMinOffset = 0.0; - } - // if there any widget in the path that must force graggable, - // stop it right here - if (result.path.any((entry) => - entry.target.runtimeType == ForceDraggableWidgetRenderBox)) { - widget.controller?._nowTargetForceDraggable = true; - _scMinOffset = _scrollController.offset; - _isHorizontalScrollableWidget = false; - } else if (result.path.any((entry) => - entry.target.runtimeType == HorizontalScrollableWidgetRenderBox)) { - _isHorizontalScrollableWidget = true; - widget.controller?._nowTargetForceDraggable = false; - } else if (result.path.any((entry) => - entry.target.runtimeType == IgnoreDraggableWidgetWidgetRenderBox)) { - _ignoreScrollable = true; - widget.controller?._nowTargetForceDraggable = false; - _isHorizontalScrollableWidget = false; - return; - } else { - widget.controller?._nowTargetForceDraggable = false; - _isHorizontalScrollableWidget = false; - } - _ignoreScrollable = false; - _velocityTracker.addPosition(e.timeStamp, e.position); - }, - onPointerMove: (PointerMoveEvent e) { - if (_scrollableAxis == null) { - if (e.delta.dx.abs() > e.delta.dy.abs()) { - _scrollableAxis = Axis.horizontal; - } else { - _scrollableAxis = Axis.vertical; - } - } - - if (_isHorizontalScrollableWidget && - _scrollableAxis == Axis.horizontal) { - return; - } - - if (_ignoreScrollable) return; - _velocityTracker.addPosition( - e.timeStamp, - e.position, - ); // add current position for velocity tracking - _onGestureSlide(e.delta.dy); - }, - onPointerUp: (PointerUpEvent e) { - if (_ignoreScrollable) return; - _scrollableAxis = null; - _onGestureEnd(_velocityTracker.getVelocity()); - }, - child: child, - ); - } - - double _scMinOffset = 0.0; - - // handles the sliding gesture - void _onGestureSlide(double dy) { - // only slide the panel if scrolling is not enabled - if (widget.controller?._nowTargetForceDraggable == false && - widget.disableDraggableOnScrolling) { - return; - } - if ((!_scrollingEnabled) || - _panelPosition < 1 || - widget.controller?._nowTargetForceDraggable == true) { - if (widget.slideDirection == SlideDirection.up) { - _animationController.value -= - dy / (widget.maxHeight - widget.minHeight); - } else { - _animationController.value += - dy / (widget.maxHeight - widget.minHeight); - } - } - - // if the panel is open and the user hasn't scrolled, we need to determine - // whether to enable scrolling if the user swipes up, or disable closing and - // begin to close the panel if the user swipes down - if (_isPanelOpen && - _scrollController.hasClients && - _scrollController.offset <= _scMinOffset) { - setState(() { - if (dy < 0) { - _scrollingEnabled = true; - } else { - _scrollingEnabled = false; - } - }); - } - } - - // handles when user stops sliding - void _onGestureEnd(Velocity v) { - if (widget.controller?._nowTargetForceDraggable == false && - widget.disableDraggableOnScrolling) { - return; - } - double minFlingVelocity = 365.0; - double kSnap = 8; - - //let the current animation finish before starting a new one - if (_animationController.isAnimating) return; - - // if scrolling is allowed and the panel is open, we don't want to close - // the panel if they swipe up on the scrollable - if (_isPanelOpen && _scrollingEnabled) return; - - //check if the velocity is sufficient to constitute fling to end - double visualVelocity = - -v.pixelsPerSecond.dy / (widget.maxHeight - widget.minHeight); - - // reverse visual velocity to account for slide direction - if (widget.slideDirection == SlideDirection.down) { - visualVelocity = -visualVelocity; - } - - // get minimum distances to figure out where the panel is at - double d2Close = _animationController.value; - double d2Open = 1 - _animationController.value; - double d2Snap = ((widget.snapPoint ?? 3) - _animationController.value) - .abs(); // large value if null results in not every being the min - double minDistance = min(d2Close, min(d2Snap, d2Open)); - - // check if velocity is sufficient for a fling - if (v.pixelsPerSecond.dy.abs() >= minFlingVelocity) { - // snapPoint exists - if (widget.panelSnapping && widget.snapPoint != null) { - if (v.pixelsPerSecond.dy.abs() >= kSnap * minFlingVelocity || - minDistance == d2Snap) { - _animationController.fling(velocity: visualVelocity); - } else { - _flingPanelToPosition(widget.snapPoint!, visualVelocity); - } - - // no snap point exists - } else if (widget.panelSnapping) { - _animationController.fling(velocity: visualVelocity); - - // panel snapping disabled - } else { - _animationController.animateTo( - _animationController.value + visualVelocity * 0.16, - duration: const Duration(milliseconds: 410), - curve: Curves.decelerate, - ); - } - - return; - } - - // check if the controller is already halfway there - if (widget.panelSnapping) { - if (minDistance == d2Close) { - _close(); - } else if (minDistance == d2Snap) { - _flingPanelToPosition(widget.snapPoint!, visualVelocity); - } else { - _open(); - } - } - } - - void _flingPanelToPosition(double targetPos, double velocity) { - final Simulation simulation = SpringSimulation( - SpringDescription.withDampingRatio( - mass: 1.0, - stiffness: 500.0, - ratio: 1.0, - ), - _animationController.value, - targetPos, - velocity); - - _animationController.animateWith(simulation); - } - - //--------------------------------- - //PanelController related functions - //--------------------------------- - - //close the panel - Future _close() { - return _animationController.fling(velocity: -1.0); - } - - //open the panel - Future _open() { - return _animationController.fling(velocity: 1.0); - } - - //hide the panel (completely offscreen) - Future _hide() { - return _animationController.fling(velocity: -1.0).then((x) { - setState(() { - _isPanelVisible = false; - }); - }); - } - - //show the panel (in collapsed mode) - Future _show() { - return _animationController.fling(velocity: -1.0).then((x) { - setState(() { - _isPanelVisible = true; - }); - }); - } - - //animate the panel position to value - must - //be between 0.0 and 1.0 - Future _animatePanelToPosition(double value, - {Duration? duration, Curve curve = Curves.linear}) { - assert(0.0 <= value && value <= 1.0); - return _animationController.animateTo(value, - duration: duration, curve: curve); - } - - //animate the panel position to the snap point - //REQUIRES that widget.snapPoint != null - Future _animatePanelToSnapPoint( - {Duration? duration, Curve curve = Curves.linear}) { - assert(widget.snapPoint != null); - return _animationController.animateTo(widget.snapPoint!, - duration: duration, curve: curve); - } - - //set the panel position to value - must - //be between 0.0 and 1.0 - set _panelPosition(double value) { - assert(0.0 <= value && value <= 1.0); - _animationController.value = value; - } - - //get the current panel position - //returns the % offset from collapsed state - //as a decimal between 0.0 and 1.0 - double get _panelPosition => _animationController.value; - - //returns whether or not - //the panel is still animating - bool get _isPanelAnimating => _animationController.isAnimating; - - //returns whether or not the - //panel is open - bool get _isPanelOpen => _animationController.value == 1.0; - - //returns whether or not the - //panel is closed - bool get _isPanelClosed => _animationController.value == 0.0; - - //returns whether or not the - //panel is shown/hidden - bool get _isPanelShown => _isPanelVisible; -} diff --git a/lib/components/track_presentation/track_presentation.dart b/lib/components/track_presentation/track_presentation.dart index 96f5f964..4f1db832 100644 --- a/lib/components/track_presentation/track_presentation.dart +++ b/lib/components/track_presentation/track_presentation.dart @@ -51,6 +51,7 @@ class TrackPresentation extends HookConsumerWidget { return Data.inherit( data: options, child: SafeArea( + bottom: false, child: Scaffold( headers: const [TitleBar()], child: CustomScrollView( diff --git a/lib/main.dart b/lib/main.dart index 2f93ea87..57cfbd88 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -222,7 +222,7 @@ class Spotube extends HookConsumerWidget { darkTheme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), - colorScheme: ColorSchemes.darkNeutral(), + colorScheme: ColorSchemes.darkOrange(), surfaceOpacity: .8, surfaceBlur: 10, ), diff --git a/lib/modules/player/player.dart b/lib/modules/player/player.dart index 014e6aef..0c915b08 100644 --- a/lib/modules/player/player.dart +++ b/lib/modules/player/player.dart @@ -1,11 +1,11 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show showModalBottomSheet; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:shadcn_flutter/shadcn_flutter.dart' - show openDrawer, OverlayPosition; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:sliding_up_panel/sliding_up_panel.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -14,19 +14,16 @@ import 'package:spotube/modules/player/player_actions.dart'; import 'package:spotube/modules/player/player_controls.dart'; import 'package:spotube/modules/player/player_queue.dart'; import 'package:spotube/modules/player/volume_slider.dart'; -import 'package:spotube/components/animated_gradient.dart'; import 'package:spotube/components/dialogs/track_details_dialog.dart'; import 'package:spotube/components/links/artist_link.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/components/image/universal_image.dart'; -import 'package:spotube/components/panels/sliding_up_panel.dart'; import 'package:spotube/extensions/artist_simple.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; -import 'package:spotube/hooks/utils/use_custom_status_bar_color.dart'; -import 'package:spotube/hooks/utils/use_palette_color.dart'; import 'package:spotube/models/local_track.dart'; +import 'package:spotube/modules/root/spotube_navigation_bar.dart'; import 'package:spotube/pages/lyrics/lyrics.dart'; import 'package:spotube/pages/track/track.dart'; import 'package:spotube/provider/authentication/authentication.dart'; @@ -58,6 +55,16 @@ class PlayerView extends HookConsumerWidget { final isLocalTrack = currentTrack is LocalTrack; final mediaQuery = MediaQuery.of(context); + final shouldHide = useState(true); + + ref.listen(navigationPanelHeight, (_, height) { + shouldHide.value = height.ceil() == 50; + }); + + if (shouldHide.value) { + return const SizedBox(); + } + useEffect(() { if (mediaQuery.lgAndUp) { WidgetsBinding.instance.addPostFrameCallback((_) { @@ -74,15 +81,6 @@ class PlayerView extends HookConsumerWidget { [currentTrack?.album?.images], ); - final palette = usePaletteGenerator(albumArt); - final titleTextColor = palette.dominantColor?.titleTextColor; - final bodyTextColor = palette.dominantColor?.bodyTextColor; - - final bgColor = palette.dominantColor?.color ?? theme.colorScheme.primary; - - final GlobalKey scaffoldKey = - useMemoized(() => GlobalKey(), []); - useEffect(() { for (final renderView in WidgetsBinding.instance.renderViews) { renderView.automaticSystemUiAdjustment = false; @@ -93,324 +91,230 @@ class PlayerView extends HookConsumerWidget { renderView.automaticSystemUiAdjustment = true; } }; - }, [panelController.isPanelOpen]); - - useCustomStatusBarColor( - bgColor, - panelController.isPanelOpen, - noSetBGColor: true, - automaticSystemUiAdjustment: false, - ); - - final topPadding = MediaQueryData.fromView(View.of(context)).padding.top; + }, [panelController.isAttached && panelController.isPanelOpen]); return AppPopScope( canPop: context.canPop(), onPopInvoked: (didPop) async { await panelController.close(); }, - child: IconTheme( - data: theme.iconTheme.copyWith(color: bodyTextColor), - child: AnimateGradient( - animateAlignments: true, - primaryBegin: Alignment.topLeft, - primaryEnd: Alignment.bottomLeft, - secondaryBegin: Alignment.bottomRight, - secondaryEnd: Alignment.topRight, - duration: const Duration(seconds: 15), - primaryColors: [ - palette.dominantColor?.color ?? theme.colorScheme.primary, - palette.mutedColor?.color ?? theme.colorScheme.secondary, - ], - secondaryColors: [ - (palette.darkVibrantColor ?? palette.lightVibrantColor)?.color ?? - theme.colorScheme.primaryContainer, - (palette.darkMutedColor ?? palette.lightMutedColor)?.color ?? - theme.colorScheme.secondaryContainer, - ], - child: Scaffold( - key: scaffoldKey, - backgroundColor: Colors.transparent, - appBar: PreferredSize( - preferredSize: Size.fromHeight( - kToolbarHeight + topPadding, - ), - child: ForceDraggableWidget( - child: Padding( - padding: EdgeInsets.only(top: topPadding), - child: TitleBar( - backgroundColor: Colors.transparent, - leading: [ - IconButton( - icon: const Icon(SpotubeIcons.angleDown, size: 18), - onPressed: panelController.close, - ) - ], - trailing: [ - if (currentTrack is YoutubeSourcedTrack) - TextButton.icon( - icon: Assets.logos.songlinkTransparent.image( - width: 20, - height: 20, - color: bodyTextColor, - ), - label: Text(context.l10n.song_link), - style: TextButton.styleFrom( - foregroundColor: bodyTextColor, - padding: const EdgeInsets.symmetric(horizontal: 10), - ), - onPressed: () { - final url = - "https://song.link/s/${currentTrack.id}"; + child: Scaffold( + headers: [ + SafeArea( + child: TitleBar( + surfaceOpacity: 0, + surfaceBlur: 0, + leading: [ + IconButton.ghost( + icon: const Icon(SpotubeIcons.angleDown, size: 18), + onPressed: panelController.close, + ) + ], + trailing: [ + if (currentTrack is YoutubeSourcedTrack) + TextButton( + leading: Assets.logos.songlinkTransparent.image( + width: 20, + height: 20, + color: theme.colorScheme.foreground, + ), + onPressed: () { + final url = "https://song.link/s/${currentTrack.id}"; - launchUrlString(url); + launchUrlString(url); + }, + child: Text(context.l10n.song_link), + ), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.details), + ), + child: IconButton.ghost( + icon: const Icon(SpotubeIcons.info, size: 18), + onPressed: currentTrack == null + ? null + : () { + showDialog( + context: context, + builder: (context) { + return TrackDetailsDialog( + track: currentTrack, + ); + }); }, - ), - IconButton( - icon: const Icon(SpotubeIcons.info, size: 18), - tooltip: context.l10n.details, - style: IconButton.styleFrom( - foregroundColor: bodyTextColor, - ), - onPressed: currentTrack == null - ? null - : () { - showDialog( - context: context, - builder: (context) { - return TrackDetailsDialog( - track: currentTrack, - ); - }); - }, - ) + ), + ) + ], + ), + ), + ], + child: SingleChildScrollView( + controller: scrollController, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Container( + margin: const EdgeInsets.all(8), + constraints: + const BoxConstraints(maxHeight: 300, maxWidth: 300), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(100), + spreadRadius: 2, + blurRadius: 10, + offset: Offset.zero, + ), ], ), - ), - ), - ), - extendBodyBehindAppBar: true, - body: SingleChildScrollView( - controller: scrollController, - child: Container( - alignment: Alignment.center, - width: double.infinity, - child: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 580), - child: SafeArea( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - ForceDraggableWidget( - child: Container( - margin: const EdgeInsets.all(8), - constraints: const BoxConstraints( - maxHeight: 300, maxWidth: 300), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - boxShadow: const [ - BoxShadow( - color: Colors.black26, - spreadRadius: 2, - blurRadius: 10, - offset: Offset(0, 0), - ), - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(20), - child: UniversalImage( - path: albumArt, - placeholder: Assets.albumPlaceholder.path, - fit: BoxFit.cover, - ), - ), - ), - ), - const SizedBox(height: 60), - Container( - padding: const EdgeInsets.symmetric(horizontal: 16), - alignment: Alignment.centerLeft, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AutoSizeText( - currentTrack?.name ?? - context.l10n.not_playing, - style: TextStyle( - color: titleTextColor, - fontSize: 22, - ), - maxFontSize: 22, - maxLines: 1, - textAlign: TextAlign.start, - ), - if (isLocalTrack) - Text( - currentTrack.artists?.asString() ?? "", - style: theme.textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.bold, - color: bodyTextColor, - ), - ) - else - ArtistLink( - artists: currentTrack?.artists ?? [], - textStyle: - theme.textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.bold, - color: bodyTextColor, - ), - onRouteChange: (route) { - panelController.close(); - GoRouter.of(context).push(route); - }, - onOverflowArtistClick: () => - ServiceUtils.pushNamed( - context, - TrackPage.name, - pathParameters: { - "id": currentTrack!.id!, - }, - ), - ), - ], - ), - ), - const SizedBox(height: 10), - PlayerControls(palette: palette), - const SizedBox(height: 25), - const PlayerActions( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - showQueue: false, - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - const SizedBox(width: 10), - Expanded( - child: OutlinedButton.icon( - icon: const Icon(SpotubeIcons.queue), - label: Text(context.l10n.queue), - style: OutlinedButton.styleFrom( - foregroundColor: bodyTextColor, - side: BorderSide( - color: bodyTextColor ?? Colors.white, - ), - ), - // enabled: currentTrack != null, - onPressed: () { - openDrawer( - context: context, - barrierDismissible: true, - draggable: true, - barrierColor: Colors.black12, - borderRadius: BorderRadius.circular(10), - transformBackdrop: false, - position: OverlayPosition.bottom, - surfaceBlur: context.theme.surfaceBlur, - surfaceOpacity: 0.7, - expands: true, - builder: (context) => Consumer( - builder: (context, ref, _) { - final playlist = ref.watch( - audioPlayerProvider, - ); - final playlistNotifier = ref.read( - audioPlayerProvider.notifier); - return ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context) - .size - .height * - 0.8, - ), - child: PlayerQueue - .fromAudioPlayerNotifier( - floating: false, - playlist: playlist, - notifier: playlistNotifier, - ), - ); - }, - ), - ); - }, - ), - ), - if (auth.asData?.value != null) - const SizedBox(width: 10), - if (auth.asData?.value != null) - Expanded( - child: OutlinedButton.icon( - label: Text(context.l10n.lyrics), - icon: const Icon(SpotubeIcons.music), - style: OutlinedButton.styleFrom( - foregroundColor: bodyTextColor, - side: BorderSide( - color: bodyTextColor ?? Colors.white, - ), - ), - onPressed: () { - showModalBottomSheet( - context: context, - isDismissible: true, - enableDrag: true, - isScrollControlled: true, - backgroundColor: Colors.black38, - barrierColor: Colors.black12, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20), - topRight: Radius.circular(20), - ), - ), - builder: (context) => - const LyricsPage(isModal: true), - ); - }, - ), - ), - const SizedBox(width: 10), - ], - ), - const SizedBox(height: 25), - SliderTheme( - data: theme.sliderTheme.copyWith( - activeTrackColor: titleTextColor, - inactiveTrackColor: bodyTextColor, - thumbColor: titleTextColor, - overlayColor: titleTextColor?.withOpacity(0.2), - trackHeight: 2, - thumbShape: const RoundSliderThumbShape( - enabledThumbRadius: 8, - ), - ), - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 16), - child: Consumer(builder: (context, ref, _) { - final volume = ref.watch(volumeProvider); - return VolumeSlider( - fullWidth: true, - value: volume, - onChanged: (value) { - ref - .read(volumeProvider.notifier) - .setVolume(value); - }, - ); - }), - ), - ), - ], - ), + child: ClipRRect( + borderRadius: BorderRadius.circular(20), + child: UniversalImage( + path: albumArt, + placeholder: Assets.albumPlaceholder.path, + fit: BoxFit.cover, ), ), ), - ), + const SizedBox(height: 60), + Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + alignment: Alignment.centerLeft, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AutoSizeText( + currentTrack?.name ?? context.l10n.not_playing, + style: const TextStyle(fontSize: 22), + maxFontSize: 22, + maxLines: 1, + textAlign: TextAlign.start, + ), + if (isLocalTrack) + Text( + currentTrack.artists?.asString() ?? "", + style: theme.typography.normal + .copyWith(fontWeight: FontWeight.bold), + ) + else + ArtistLink( + artists: currentTrack?.artists ?? [], + textStyle: theme.typography.normal + .copyWith(fontWeight: FontWeight.bold), + onRouteChange: (route) { + panelController.close(); + GoRouter.of(context).push(route); + }, + onOverflowArtistClick: () => ServiceUtils.pushNamed( + context, + TrackPage.name, + pathParameters: { + "id": currentTrack!.id!, + }, + ), + ), + ], + ), + ), + const SizedBox(height: 10), + const PlayerControls(), + const SizedBox(height: 25), + const PlayerActions( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + showQueue: false, + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const SizedBox(width: 10), + Expanded( + child: OutlineButton( + leading: const Icon(SpotubeIcons.queue), + child: Text(context.l10n.queue), + onPressed: () { + openDrawer( + context: context, + barrierDismissible: true, + draggable: true, + barrierColor: Colors.black.withAlpha(100), + borderRadius: BorderRadius.circular(10), + transformBackdrop: false, + position: OverlayPosition.bottom, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: 0.7, + expands: true, + builder: (context) => Consumer( + builder: (context, ref, _) { + final playlist = ref.watch( + audioPlayerProvider, + ); + final playlistNotifier = + ref.read(audioPlayerProvider.notifier); + return ConstrainedBox( + constraints: BoxConstraints( + maxHeight: + MediaQuery.of(context).size.height * + 0.8, + ), + child: PlayerQueue.fromAudioPlayerNotifier( + floating: false, + playlist: playlist, + notifier: playlistNotifier, + ), + ); + }, + ), + ); + }, + ), + ), + if (auth.asData?.value != null) const SizedBox(width: 10), + if (auth.asData?.value != null) + Expanded( + child: OutlineButton( + leading: const Icon(SpotubeIcons.music), + child: Text(context.l10n.lyrics), + onPressed: () { + showModalBottomSheet( + context: context, + isDismissible: true, + enableDrag: true, + isScrollControlled: true, + backgroundColor: Colors.black.withAlpha(100), + barrierColor: Colors.black.withAlpha(100), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + builder: (context) => + const LyricsPage(isModal: true), + ); + }, + ), + ), + const SizedBox(width: 10), + ], + ), + const SizedBox(height: 25), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Consumer(builder: (context, ref, _) { + final volume = ref.watch(volumeProvider); + return VolumeSlider( + fullWidth: true, + value: volume, + onChanged: (value) { + ref.read(volumeProvider.notifier).setVolume(value); + }, + ); + }), + ), + ], ), ), ), diff --git a/lib/modules/player/player_overlay.dart b/lib/modules/player/player_overlay.dart index 2322bcba..a37ac5bc 100644 --- a/lib/modules/player/player_overlay.dart +++ b/lib/modules/player/player_overlay.dart @@ -1,19 +1,12 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:sliding_up_panel/sliding_up_panel.dart'; +import 'package:spotube/modules/player/player_overlay_collapsed.dart'; -import 'package:spotube/modules/player/player_track_details.dart'; import 'package:spotube/modules/root/spotube_navigation_bar.dart'; -import 'package:spotube/components/panels/sliding_up_panel.dart'; -import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/collections/intents.dart'; -import 'package:spotube/modules/player/use_progress.dart'; import 'package:spotube/modules/player/player.dart'; import 'package:spotube/provider/audio_player/audio_player.dart'; -import 'package:spotube/provider/audio_player/querying_track_info.dart'; -import 'package:spotube/services/audio_player/audio_player.dart'; class PlayerOverlay extends HookConsumerWidget { final String albumArt; @@ -25,180 +18,34 @@ class PlayerOverlay extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final isFetchingActiveTrack = ref.watch(queryingTrackInfoProvider); final playlist = ref.watch(audioPlayerProvider); final canShow = playlist.activeTrack != null; - final playing = - useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying; - - final theme = Theme.of(context); - final textColor = theme.colorScheme.primary; - - const radius = BorderRadius.only( - topLeft: Radius.circular(10), - topRight: Radius.circular(10), - ); - - final mediaQuery = MediaQuery.of(context); + final screenSize = MediaQuery.sizeOf(context); final panelController = useMemoized(() => PanelController(), []); - final scrollController = useScrollController(); - - useEffect(() { - return () { - panelController.dispose(); - }; - }, []); return SlidingUpPanel( - maxHeight: mediaQuery.size.height, + maxHeight: screenSize.height, backdropEnabled: false, - minHeight: canShow ? 53 : 0, + minHeight: canShow ? 63 : 0, onPanelSlide: (position) { final invertedPosition = 1 - position; ref.read(navigationPanelHeight.notifier).state = 50 * invertedPosition; }, controller: panelController, - collapsed: ClipRRect( - borderRadius: radius, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), - child: AnimatedContainer( - duration: const Duration(milliseconds: 250), - width: mediaQuery.size.width, - decoration: BoxDecoration( - color: theme.colorScheme.secondaryContainer.withOpacity(.8), - borderRadius: radius, - ), - child: AnimatedOpacity( - duration: const Duration(milliseconds: 250), - opacity: canShow ? 1 : 0, - child: Material( - type: MaterialType.transparency, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - HookBuilder( - builder: (context) { - final progress = useProgress(ref); - // animated - return TweenAnimationBuilder( - duration: const Duration(milliseconds: 250), - tween: Tween( - begin: 0, - end: progress.progressStatic, - ), - builder: (context, value, child) { - return LinearProgressIndicator( - value: value, - minHeight: 2, - backgroundColor: Colors.transparent, - valueColor: AlwaysStoppedAnimation( - theme.colorScheme.primary, - ), - ); - }, - ); - }, - ), - Expanded( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: GestureDetector( - onTap: () { - panelController.open(); - }, - child: Container( - width: double.infinity, - color: Colors.transparent, - child: PlayerTrackDetails( - track: playlist.activeTrack, - color: textColor, - ), - ), - ), - ), - Row( - children: [ - IconButton( - icon: Icon( - SpotubeIcons.skipBack, - color: textColor, - ), - onPressed: isFetchingActiveTrack - ? null - : audioPlayer.skipToPrevious, - ), - Consumer( - builder: (context, ref, _) { - return IconButton( - icon: isFetchingActiveTrack - ? const SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator(), - ) - : Icon( - playing - ? SpotubeIcons.pause - : SpotubeIcons.play, - color: textColor, - ), - onPressed: Actions.handler( - context, - PlayPauseIntent(ref), - ), - ); - }, - ), - IconButton( - icon: Icon( - SpotubeIcons.skipForward, - color: textColor, - ), - onPressed: isFetchingActiveTrack - ? null - : audioPlayer.skipToNext, - ), - ], - ), - ], - ), - ), - ], - ), - ), - ), - ), - ), + color: Colors.transparent, + parallaxEnabled: true, + renderPanelSheet: false, + header: SizedBox( + height: 63, + width: screenSize.width, + child: PlayerOverlayCollapsedSection(panelController: panelController), + ), + panelBuilder: (scrollController) => PlayerView( + panelController: panelController, + scrollController: scrollController, ), - scrollController: scrollController, - panelBuilder: (position) { - // this is the reason we're getting an update - final navigationHeight = ref.watch(navigationPanelHeight); - - if (navigationHeight == 50) return const SizedBox(); - - return IgnorePointer( - ignoring: !panelController.isPanelOpen, - child: AnimatedContainer( - clipBehavior: Clip.antiAlias, - duration: const Duration(milliseconds: 250), - decoration: navigationHeight == 0 - ? const BoxDecoration(borderRadius: BorderRadius.zero) - : const BoxDecoration(borderRadius: radius), - child: IgnoreDraggableWidget( - child: PlayerView( - panelController: panelController, - scrollController: scrollController, - ), - ), - ), - ); - }, ); } } diff --git a/lib/modules/player/player_overlay_collapsed.dart b/lib/modules/player/player_overlay_collapsed.dart new file mode 100644 index 00000000..52847c40 --- /dev/null +++ b/lib/modules/player/player_overlay_collapsed.dart @@ -0,0 +1,118 @@ +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:sliding_up_panel/sliding_up_panel.dart'; +import 'package:spotube/collections/intents.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/modules/player/player_track_details.dart'; +import 'package:spotube/modules/root/spotube_navigation_bar.dart'; +import 'package:spotube/provider/audio_player/audio_player.dart'; +import 'package:spotube/provider/audio_player/querying_track_info.dart'; +import 'package:spotube/services/audio_player/audio_player.dart'; + +class PlayerOverlayCollapsedSection extends HookConsumerWidget { + final PanelController panelController; + const PlayerOverlayCollapsedSection({ + super.key, + required this.panelController, + }); + + @override + Widget build(BuildContext context, ref) { + final playlist = ref.watch(audioPlayerProvider); + final canShow = playlist.activeTrack != null; + + final isFetchingActiveTrack = ref.watch(queryingTrackInfoProvider); + final playing = + useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying; + + final theme = Theme.of(context); + + final shouldShow = useState(true); + + ref.listen(navigationPanelHeight, (_, height) { + shouldShow.value = height.ceil() == 50; + }); + + return AnimatedSwitcher( + duration: const Duration(milliseconds: 250), + child: canShow && shouldShow.value + ? Padding( + padding: const EdgeInsets.all(5), + child: SurfaceCard( + borderWidth: 0, + surfaceBlur: theme.surfaceBlur, + surfaceOpacity: theme.surfaceOpacity, + padding: EdgeInsets.zero, + borderRadius: theme.borderRadiusLg, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + panelController.open(); + }, + child: Container( + width: double.infinity, + color: Colors.transparent, + child: PlayerTrackDetails( + track: playlist.activeTrack, + color: theme.colorScheme.foreground, + ), + ), + ), + ), + Row( + children: [ + IconButton.ghost( + icon: const Icon(SpotubeIcons.skipBack), + onPressed: isFetchingActiveTrack + ? null + : audioPlayer.skipToPrevious, + ), + Consumer( + builder: (context, ref, _) { + return IconButton.ghost( + icon: isFetchingActiveTrack + ? const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator(), + ) + : Icon( + playing + ? SpotubeIcons.pause + : SpotubeIcons.play, + ), + onPressed: Actions.handler( + context, + PlayPauseIntent(ref), + ), + ); + }, + ), + IconButton.ghost( + icon: const Icon(SpotubeIcons.skipForward), + onPressed: isFetchingActiveTrack + ? null + : audioPlayer.skipToNext, + ), + const Gap(5), + ], + ), + ], + ), + ), + ], + ), + ), + ) + : const SizedBox.shrink(), + ); + } +} diff --git a/lib/modules/root/spotube_navigation_bar.dart b/lib/modules/root/spotube_navigation_bar.dart index fa585054..8d3e71f4 100644 --- a/lib/modules/root/spotube_navigation_bar.dart +++ b/lib/modules/root/spotube_navigation_bar.dart @@ -3,6 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/extensions/constrains.dart'; @@ -52,24 +53,29 @@ class SpotubeNavigationBar extends HookConsumerWidget { return AnimatedContainer( duration: const Duration(milliseconds: 100), - child: NavigationBar( - index: selectedIndex, - onSelected: (i) { - ServiceUtils.navigateNamed(context, navbarTileList[i].name); - }, - children: [ - for (final tile in navbarTileList) - NavigationButton( - style: const ButtonStyle.muted(density: ButtonDensity.icon), - selectedStyle: - const ButtonStyle.fixed(density: ButtonDensity.icon), - child: Badge( - isLabelVisible: tile.id == "library" && downloadCount > 0, - label: Text(downloadCount.toString()), - child: Icon(tile.icon), - ), - ) - ], + height: panelHeight, + child: SingleChildScrollView( + child: NavigationBar( + index: selectedIndex, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: context.theme.surfaceOpacity, + onSelected: (i) { + ServiceUtils.navigateNamed(context, navbarTileList[i].name); + }, + children: [ + for (final tile in navbarTileList) + NavigationButton( + style: const ButtonStyle.muted(density: ButtonDensity.icon), + selectedStyle: + const ButtonStyle.fixed(density: ButtonDensity.icon), + child: Badge( + isLabelVisible: tile.id == "library" && downloadCount > 0, + label: Text(downloadCount.toString()), + child: Icon(tile.icon), + ), + ) + ], + ), ), ); } diff --git a/lib/pages/lyrics/plain_lyrics.dart b/lib/pages/lyrics/plain_lyrics.dart index 6246fd79..0b5354a0 100644 --- a/lib/pages/lyrics/plain_lyrics.dart +++ b/lib/pages/lyrics/plain_lyrics.dart @@ -3,6 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:palette_generator/palette_generator.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/lyrics/zoom_controls.dart'; import 'package:spotube/components/shimmers/shimmer_lyrics.dart'; @@ -53,7 +54,9 @@ class PlainLyrics extends HookConsumerWidget { child: Text( playlist.activeTrack?.artists?.asString() ?? "", style: (mediaQuery.mdAndUp ? typography.h4 : typography.large) - .copyWith(color: palette.bodyTextColor), + .copyWith( + color: palette.bodyTextColor, + ), ), ) ], @@ -103,7 +106,9 @@ class PlainLyrics extends HookConsumerWidget { return AnimatedDefaultTextStyle( duration: const Duration(milliseconds: 200), style: TextStyle( - color: palette.bodyTextColor, + color: isModal == true + ? context.theme.colorScheme.foreground + : palette.bodyTextColor, fontSize: 24 * textZoomLevel.value / 100, height: textZoomLevel.value < 70 ? 1.5 diff --git a/lib/pages/lyrics/synced_lyrics.dart b/lib/pages/lyrics/synced_lyrics.dart index 1367fa5a..b7423e14 100644 --- a/lib/pages/lyrics/synced_lyrics.dart +++ b/lib/pages/lyrics/synced_lyrics.dart @@ -34,9 +34,11 @@ class SyncedLyrics extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { + final mediaQuery = MediaQuery.sizeOf(context); + final theme = Theme.of(context); + final playlist = ref.watch(audioPlayerProvider); - final mediaQuery = MediaQuery.sizeOf(context); final controller = useAutoScrollController(); final delay = ref.watch(syncedLyricsDelayProvider); @@ -70,7 +72,9 @@ class SyncedLyrics extends HookConsumerWidget { final headlineTextStyle = (mediaQuery.mdAndUp ? typography.h3 : typography.h4.copyWith(fontSize: 25)) - .copyWith(color: palette.titleTextColor); + .copyWith( + color: palette.titleTextColor, + ); final bodyTextTheme = typography.large.copyWith( color: palette.bodyTextColor, @@ -182,9 +186,15 @@ class SyncedLyrics extends HookConsumerWidget { text: lyricSlice.text, textStyle: DefaultTextStyle.of(context).style, - textColor: isActive - ? Colors.white - : palette.bodyTextColor, + textColor: switch (( + isActive, + isModal == true + )) { + (true, _) => Colors.white, + (_, true) => + theme.colorScheme.mutedForeground, + (_, _) => palette.bodyTextColor, + }, strokeColor: isActive ? Colors.black : Colors.transparent, diff --git a/pubspec.lock b/pubspec.lock index 8c8c30be..a43f4f2c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -2101,6 +2101,14 @@ packages: description: flutter source: sdk version: "0.0.0" + sliding_up_panel: + dependency: "direct main" + description: + name: sliding_up_panel + sha256: "578e90956a6212d1e406373250b2436a0f3afece29aee3c24c8360094d6cf968" + url: "https://pub.dev" + source: hosted + version: "2.0.0+1" sliver_tools: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index e06cf96c..35738548 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -112,6 +112,7 @@ dependencies: shelf_web_socket: ^2.0.0 simple_icons: ^10.1.3 skeletonizer: ^1.1.1 + sliding_up_panel: ^2.0.0+1 sliver_tools: ^0.2.12 smtc_windows: ^1.0.0 spotify: ^0.13.7 From 30e03786bfb0071aa57969a88a979536804ba12a Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 3 Jan 2025 23:10:26 +0600 Subject: [PATCH 27/81] refactor: alternative track sheet to use shadcn --- lib/modules/player/player.dart | 402 ++++++++++--------- lib/modules/player/player_actions.dart | 62 ++- lib/modules/player/sibling_tracks_sheet.dart | 257 ++++++------ 3 files changed, 378 insertions(+), 343 deletions(-) diff --git a/lib/modules/player/player.dart b/lib/modules/player/player.dart index 0c915b08..16ee6c72 100644 --- a/lib/modules/player/player.dart +++ b/lib/modules/player/player.dart @@ -98,223 +98,229 @@ class PlayerView extends HookConsumerWidget { onPopInvoked: (didPop) async { await panelController.close(); }, - child: Scaffold( - headers: [ - SafeArea( - child: TitleBar( - surfaceOpacity: 0, - surfaceBlur: 0, - leading: [ - IconButton.ghost( - icon: const Icon(SpotubeIcons.angleDown, size: 18), - onPressed: panelController.close, - ) - ], - trailing: [ - if (currentTrack is YoutubeSourcedTrack) - TextButton( - leading: Assets.logos.songlinkTransparent.image( - width: 20, - height: 20, - color: theme.colorScheme.foreground, - ), - onPressed: () { - final url = "https://song.link/s/${currentTrack.id}"; + child: SurfaceCard( + borderWidth: 0, + surfaceOpacity: 0.9, + padding: EdgeInsets.zero, + child: Scaffold( + backgroundColor: Colors.transparent, + headers: [ + SafeArea( + child: TitleBar( + surfaceOpacity: 0, + surfaceBlur: 0, + leading: [ + IconButton.ghost( + icon: const Icon(SpotubeIcons.angleDown, size: 18), + onPressed: panelController.close, + ) + ], + trailing: [ + if (currentTrack is YoutubeSourcedTrack) + TextButton( + leading: Assets.logos.songlinkTransparent.image( + width: 20, + height: 20, + color: theme.colorScheme.foreground, + ), + onPressed: () { + final url = "https://song.link/s/${currentTrack.id}"; - launchUrlString(url); - }, - child: Text(context.l10n.song_link), - ), - Tooltip( - tooltip: TooltipContainer( - child: Text(context.l10n.details), - ), - child: IconButton.ghost( - icon: const Icon(SpotubeIcons.info, size: 18), - onPressed: currentTrack == null - ? null - : () { - showDialog( - context: context, - builder: (context) { - return TrackDetailsDialog( - track: currentTrack, - ); - }); - }, - ), - ) - ], + launchUrlString(url); + }, + child: Text(context.l10n.song_link), + ), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.details), + ), + child: IconButton.ghost( + icon: const Icon(SpotubeIcons.info, size: 18), + onPressed: currentTrack == null + ? null + : () { + showDialog( + context: context, + builder: (context) { + return TrackDetailsDialog( + track: currentTrack, + ); + }); + }, + ), + ) + ], + ), ), - ), - ], - child: SingleChildScrollView( - controller: scrollController, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Container( - margin: const EdgeInsets.all(8), - constraints: - const BoxConstraints(maxHeight: 300, maxWidth: 300), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - boxShadow: [ - BoxShadow( - color: Colors.black.withAlpha(100), - spreadRadius: 2, - blurRadius: 10, - offset: Offset.zero, + ], + child: SingleChildScrollView( + controller: scrollController, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Container( + margin: const EdgeInsets.all(8), + constraints: + const BoxConstraints(maxHeight: 300, maxWidth: 300), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(100), + spreadRadius: 2, + blurRadius: 10, + offset: Offset.zero, + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(20), + child: UniversalImage( + path: albumArt, + placeholder: Assets.albumPlaceholder.path, + fit: BoxFit.cover, ), - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(20), - child: UniversalImage( - path: albumArt, - placeholder: Assets.albumPlaceholder.path, - fit: BoxFit.cover, ), ), - ), - const SizedBox(height: 60), - Container( - padding: const EdgeInsets.symmetric(horizontal: 16), - alignment: Alignment.centerLeft, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AutoSizeText( - currentTrack?.name ?? context.l10n.not_playing, - style: const TextStyle(fontSize: 22), - maxFontSize: 22, - maxLines: 1, - textAlign: TextAlign.start, - ), - if (isLocalTrack) - Text( - currentTrack.artists?.asString() ?? "", - style: theme.typography.normal - .copyWith(fontWeight: FontWeight.bold), - ) - else - ArtistLink( - artists: currentTrack?.artists ?? [], - textStyle: theme.typography.normal - .copyWith(fontWeight: FontWeight.bold), - onRouteChange: (route) { - panelController.close(); - GoRouter.of(context).push(route); - }, - onOverflowArtistClick: () => ServiceUtils.pushNamed( - context, - TrackPage.name, - pathParameters: { - "id": currentTrack!.id!, - }, - ), + const SizedBox(height: 60), + Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + alignment: Alignment.centerLeft, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AutoSizeText( + currentTrack?.name ?? context.l10n.not_playing, + style: const TextStyle(fontSize: 22), + maxFontSize: 22, + maxLines: 1, + textAlign: TextAlign.start, ), - ], - ), - ), - const SizedBox(height: 10), - const PlayerControls(), - const SizedBox(height: 25), - const PlayerActions( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - showQueue: false, - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - const SizedBox(width: 10), - Expanded( - child: OutlineButton( - leading: const Icon(SpotubeIcons.queue), - child: Text(context.l10n.queue), - onPressed: () { - openDrawer( - context: context, - barrierDismissible: true, - draggable: true, - barrierColor: Colors.black.withAlpha(100), - borderRadius: BorderRadius.circular(10), - transformBackdrop: false, - position: OverlayPosition.bottom, - surfaceBlur: context.theme.surfaceBlur, - surfaceOpacity: 0.7, - expands: true, - builder: (context) => Consumer( - builder: (context, ref, _) { - final playlist = ref.watch( - audioPlayerProvider, - ); - final playlistNotifier = - ref.read(audioPlayerProvider.notifier); - return ConstrainedBox( - constraints: BoxConstraints( - maxHeight: - MediaQuery.of(context).size.height * - 0.8, - ), - child: PlayerQueue.fromAudioPlayerNotifier( - floating: false, - playlist: playlist, - notifier: playlistNotifier, - ), - ); + if (isLocalTrack) + Text( + currentTrack.artists?.asString() ?? "", + style: theme.typography.normal + .copyWith(fontWeight: FontWeight.bold), + ) + else + ArtistLink( + artists: currentTrack?.artists ?? [], + textStyle: theme.typography.normal + .copyWith(fontWeight: FontWeight.bold), + onRouteChange: (route) { + panelController.close(); + GoRouter.of(context).push(route); + }, + onOverflowArtistClick: () => ServiceUtils.pushNamed( + context, + TrackPage.name, + pathParameters: { + "id": currentTrack!.id!, }, ), - ); - }, - ), + ), + ], ), - if (auth.asData?.value != null) const SizedBox(width: 10), - if (auth.asData?.value != null) + ), + const SizedBox(height: 10), + const PlayerControls(), + const SizedBox(height: 25), + const PlayerActions( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + showQueue: false, + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const SizedBox(width: 10), Expanded( child: OutlineButton( - leading: const Icon(SpotubeIcons.music), - child: Text(context.l10n.lyrics), + leading: const Icon(SpotubeIcons.queue), + child: Text(context.l10n.queue), onPressed: () { - showModalBottomSheet( + openDrawer( context: context, - isDismissible: true, - enableDrag: true, - isScrollControlled: true, - backgroundColor: Colors.black.withAlpha(100), + barrierDismissible: true, + draggable: true, barrierColor: Colors.black.withAlpha(100), - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20), - topRight: Radius.circular(20), - ), + borderRadius: BorderRadius.circular(10), + transformBackdrop: false, + position: OverlayPosition.bottom, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: 0.7, + expands: true, + builder: (context) => Consumer( + builder: (context, ref, _) { + final playlist = ref.watch( + audioPlayerProvider, + ); + final playlistNotifier = + ref.read(audioPlayerProvider.notifier); + return ConstrainedBox( + constraints: BoxConstraints( + maxHeight: + MediaQuery.of(context).size.height * + 0.8, + ), + child: PlayerQueue.fromAudioPlayerNotifier( + floating: false, + playlist: playlist, + notifier: playlistNotifier, + ), + ); + }, ), - builder: (context) => - const LyricsPage(isModal: true), ); }, ), ), - const SizedBox(width: 10), - ], - ), - const SizedBox(height: 25), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Consumer(builder: (context, ref, _) { - final volume = ref.watch(volumeProvider); - return VolumeSlider( - fullWidth: true, - value: volume, - onChanged: (value) { - ref.read(volumeProvider.notifier).setVolume(value); - }, - ); - }), - ), - ], + if (auth.asData?.value != null) const SizedBox(width: 10), + if (auth.asData?.value != null) + Expanded( + child: OutlineButton( + leading: const Icon(SpotubeIcons.music), + child: Text(context.l10n.lyrics), + onPressed: () { + showModalBottomSheet( + context: context, + isDismissible: true, + enableDrag: true, + isScrollControlled: true, + backgroundColor: Colors.black.withAlpha(100), + barrierColor: Colors.black.withAlpha(100), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + builder: (context) => + const LyricsPage(isModal: true), + ); + }, + ), + ), + const SizedBox(width: 10), + ], + ), + const SizedBox(height: 25), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Consumer(builder: (context, ref, _) { + final volume = ref.watch(volumeProvider); + return VolumeSlider( + fullWidth: true, + value: volume, + onChanged: (value) { + ref.read(volumeProvider.notifier).setVolume(value); + }, + ); + }), + ), + ], + ), ), ), ), diff --git a/lib/modules/player/player_actions.dart b/lib/modules/player/player_actions.dart index 12965da4..584af70d 100644 --- a/lib/modules/player/player_actions.dart +++ b/lib/modules/player/player_actions.dart @@ -5,6 +5,7 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/modules/player/player_queue.dart'; import 'package:spotube/modules/player/sibling_tracks_sheet.dart'; import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; @@ -118,23 +119,54 @@ class PlayerActions extends HookConsumerWidget { tooltip: TooltipContainer( child: Text(context.l10n.alternative_track_sources)), child: IconButton.ghost( + enabled: playlist.activeTrack != null, icon: const Icon(SpotubeIcons.alternativeRoute), - onPressed: playlist.activeTrack != null - ? () { - openDrawer( - context: context, - position: OverlayPosition.bottom, - barrierDismissible: true, - draggable: true, - barrierColor: Colors.black.withValues(alpha: .2), - borderRadius: BorderRadius.circular(10), - transformBackdrop: false, - builder: (context) { - return SiblingTracksSheet(floating: floatingQueue); - }, + onPressed: () { + final screenSize = MediaQuery.sizeOf(context); + if (screenSize.mdAndUp) { + showPopover( + alignment: Alignment.bottomCenter, + context: context, + builder: (context) { + return SurfaceCard( + padding: EdgeInsets.zero, + child: ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 600, + maxWidth: 500, + ), + child: SiblingTracksSheet(floating: floatingQueue), + ), ); - } - : null, + }, + ); + } else { + openDrawer( + context: context, + position: OverlayPosition.bottom, + barrierDismissible: true, + draggable: true, + barrierColor: Colors.black.withValues(alpha: .2), + borderRadius: BorderRadius.circular(10), + transformBackdrop: false, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: context.theme.surfaceOpacity, + builder: (context) { + return Card( + borderWidth: 0, + borderColor: Colors.transparent, + padding: EdgeInsets.zero, + child: ConstrainedBox( + constraints: BoxConstraints( + maxHeight: screenSize.height * .8, + ), + child: SiblingTracksSheet(floating: floatingQueue), + ), + ); + }, + ); + } + }, ), ), if (!kIsWeb && !isLocalTrack) diff --git a/lib/modules/player/sibling_tracks_sheet.dart b/lib/modules/player/sibling_tracks_sheet.dart index 3a31d88e..9bd1ea22 100644 --- a/lib/modules/player/sibling_tracks_sheet.dart +++ b/lib/modules/player/sibling_tracks_sheet.dart @@ -1,16 +1,15 @@ -import 'dart:ui'; - import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show ListTile, Material, MaterialType; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/extensions/artist_simple.dart'; -import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/duration.dart'; import 'package:spotube/hooks/utils/use_debounce.dart'; @@ -152,13 +151,6 @@ class SiblingTracksSheet extends HookConsumerWidget { [activeTrack, isFetchingActiveTrack], ); - final borderRadius = floating - ? BorderRadius.circular(10) - : const BorderRadius.only( - topLeft: Radius.circular(10), - topRight: Radius.circular(10), - ); - useEffect(() { if (activeTrack is SourcedTrack && activeTrack.siblings.isEmpty) { activeTrackNotifier.populateSibling(); @@ -170,9 +162,17 @@ class SiblingTracksSheet extends HookConsumerWidget { (SourceInfo sourceInfo) { final icon = sourceInfoToIconMap[sourceInfo.runtimeType]; return ListTile( + hoverColor: theme.colorScheme.primary.withOpacity(.1), + dense: true, + subtitleTextStyle: theme.typography.small.copyWith( + color: theme.colorScheme.mutedForeground, + ), + titleTextStyle: theme.typography.normal, + leadingAndTrailingTextStyle: theme.typography.normal, title: Text(sourceInfo.title), + horizontalTitleGap: 0, leading: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.only(top: 8.0, right: 8.0), child: UniversalImage( path: sourceInfo.thumbnail, height: 60, @@ -192,12 +192,13 @@ class SiblingTracksSheet extends HookConsumerWidget { enabled: !isFetchingActiveTrack, selected: !isFetchingActiveTrack && sourceInfo.id == (activeTrack as SourcedTrack).sourceInfo.id, - selectedTileColor: theme.popupMenuTheme.color, + selectedTileColor: theme.colorScheme.primary.withOpacity(.1), + selectedColor: theme.colorScheme.primary, onTap: () { if (!isFetchingActiveTrack && sourceInfo.id != (activeTrack as SourcedTrack).sourceInfo.id) { activeTrackNotifier.swapSibling(sourceInfo); - Navigator.of(context).pop(); + closeDrawer(context); } }, ); @@ -205,131 +206,127 @@ class SiblingTracksSheet extends HookConsumerWidget { [activeTrack, siblings], ); - final mediaQuery = MediaQuery.of(context); - return SafeArea( - child: ClipRRect( - borderRadius: borderRadius, - clipBehavior: Clip.hardEdge, - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 12.0, - sigmaY: 12.0, - ), - child: AnimatedSize( - duration: const Duration(milliseconds: 300), - child: Container( - height: isSearching.value && mediaQuery.smAndDown - ? mediaQuery.size.height - 50 - : mediaQuery.size.height * .6, - decoration: BoxDecoration( - borderRadius: borderRadius, - color: - theme.colorScheme.surfaceContainerHighest.withOpacity(.5), - ), - child: Scaffold( - backgroundColor: Colors.transparent, - appBar: AppBar( - centerTitle: true, - title: AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: !isSearching.value - ? Text( - context.l10n.alternative_track_sources, - style: theme.textTheme.headlineSmall, - ) - : TextField( - autofocus: true, - controller: searchController, - decoration: InputDecoration( - hintText: context.l10n.search, - hintStyle: theme.textTheme.headlineSmall, - border: InputBorder.none, - ), - style: theme.textTheme.headlineSmall, - ), - ), - automaticallyImplyLeading: false, - backgroundColor: Colors.transparent, - actions: [ - if (!isSearching.value) - IconButton( - icon: const Icon(SpotubeIcons.search, size: 18), - onPressed: () { - isSearching.value = true; - }, - ) - else ...[ - if (preferences.audioSource == AudioSource.piped) - PopupMenuButton( - icon: const Icon(SpotubeIcons.filter, size: 18), - onSelected: (SearchMode mode) { - searchMode.value = mode; - }, - initialValue: searchMode.value, - itemBuilder: (context) => SearchMode.values - .map( - (e) => PopupMenuItem( - value: e, - child: Text(e.label), - ), - ) - .toList(), - ), - IconButton( - icon: const Icon(SpotubeIcons.close, size: 18), - onPressed: () { - isSearching.value = false; - }, - ), - ] - ], - ), - body: Padding( - padding: const EdgeInsets.all(8.0), - child: AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - transitionBuilder: (child, animation) => - FadeTransition(opacity: animation, child: child), - child: InterScrollbar( - controller: controller, - child: switch (isSearching.value) { - false => ListView.builder( - controller: controller, - itemCount: siblings.length, - itemBuilder: (context, index) => - itemBuilder(siblings[index]), - ), - true => FutureBuilder( - future: searchRequest, - builder: (context, snapshot) { - if (snapshot.hasError) { - return Center( - child: Text(snapshot.error.toString()), - ); - } else if (!snapshot.hasData) { - return const Center( - child: CircularProgressIndicator()); - } + final scale = context.theme.scaling; - return InterScrollbar( - controller: controller, - child: ListView.builder( - controller: controller, - itemCount: snapshot.data!.length, - itemBuilder: (context, index) => - itemBuilder(snapshot.data![index]), - ), - ); - }, + return SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 16), + child: Row( + spacing: 5, + children: [ + AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + child: !isSearching.value + ? Text( + context.l10n.alternative_track_sources, + style: theme.typography.bold, + ) + : Flexible( + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: 320 * scale, + maxHeight: 38 * scale, + ), + child: TextField( + autofocus: true, + controller: searchController, + placeholder: Text(context.l10n.search), + style: theme.typography.bold, + ), ), + ), + ), + const Spacer(), + if (!isSearching.value) + IconButton.outline( + icon: const Icon(SpotubeIcons.search, size: 18), + onPressed: () { + isSearching.value = true; + }, + ) + else ...[ + if (preferences.audioSource == AudioSource.piped) + IconButton.outline( + icon: const Icon(SpotubeIcons.filter, size: 18), + onPressed: () { + showPopover( + context: context, + alignment: Alignment.bottomRight, + builder: (context) { + return DropdownMenu( + children: SearchMode.values + .map( + (e) => MenuButton( + onPressed: (context) { + searchMode.value = e; + }, + enabled: searchMode.value != e, + child: Text(e.label), + ), + ) + .toList(), + ); + }, + ); }, ), + IconButton.outline( + icon: const Icon(SpotubeIcons.close, size: 18), + onPressed: () { + isSearching.value = false; + }, ), + ] + ], + ), + ), + Expanded( + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + transitionBuilder: (child, animation) => + FadeTransition(opacity: animation, child: child), + child: InterScrollbar( + controller: controller, + child: Material( + type: MaterialType.transparency, + child: switch (isSearching.value) { + false => ListView.builder( + padding: const EdgeInsets.all(8.0), + controller: controller, + itemCount: siblings.length, + itemBuilder: (context, index) => + itemBuilder(siblings[index]), + ), + true => FutureBuilder( + future: searchRequest, + builder: (context, snapshot) { + if (snapshot.hasError) { + return Center( + child: Text(snapshot.error.toString()), + ); + } else if (!snapshot.hasData) { + return const Center( + child: CircularProgressIndicator()); + } + + return ListView.builder( + padding: const EdgeInsets.all(8.0), + controller: controller, + itemCount: snapshot.data!.length, + itemBuilder: (context, index) => + itemBuilder(snapshot.data![index]), + ); + }, + ), + }, ), ), ), ), - ), + ], ), ); } From 780f5dee2e01316e127047e8d277e6d6820c2845 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 4 Jan 2025 20:34:42 +0600 Subject: [PATCH 28/81] cd: upgrade flutter version to 3.28.0-0.1.pre --- .github/workflows/spotube-release-binary.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 6a1c713f..eb251d2a 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -20,7 +20,8 @@ on: description: Dry run without uploading to release env: - FLUTTER_VERSION: 3.27.0 + FLUTTER_VERSION: 3.28.0-0.1.pre + FLUTTER_CHANNEL: beta permissions: contents: write @@ -68,6 +69,7 @@ jobs: cache: true cache-key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.yaml') }} flutter-version: ${{ env.FLUTTER_VERSION }} + channel: ${{ env.FLUTTER_CHANNEL }} - name: Setup Java if: ${{matrix.platform == 'android'}} uses: actions/setup-java@v4 From af295be8c62962f01f82c7def787e4cf6f4c5329 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 4 Jan 2025 23:31:09 +0600 Subject: [PATCH 29/81] refactor: remote playback page to shadcn --- lib/components/titlebar/titlebar.dart | 19 ++ lib/components/ui/button_tile.dart | 95 ++++++++ lib/l10n/app_en.arb | 1 + lib/modules/connect/local_devices.dart | 22 +- lib/modules/player/player_queue.dart | 2 +- lib/pages/connect/connect.dart | 129 +++++------ lib/pages/connect/control/control.dart | 306 ++++++++++++++----------- untranslated_messages.json | 26 +++ 8 files changed, 385 insertions(+), 215 deletions(-) create mode 100644 lib/components/ui/button_tile.dart diff --git a/lib/components/titlebar/titlebar.dart b/lib/components/titlebar/titlebar.dart index 5c3f7940..cba33ab4 100644 --- a/lib/components/titlebar/titlebar.dart +++ b/lib/components/titlebar/titlebar.dart @@ -1,3 +1,4 @@ +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/button/back_button.dart'; @@ -60,6 +61,7 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget { @override Widget build(BuildContext context, ref) { final hasLeadingOrCanPop = leading.isNotEmpty || Navigator.canPop(context); + final lastClicked = useRef(DateTime.now().millisecondsSinceEpoch); return SizedBox( height: height ?? 56, @@ -71,6 +73,23 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget { return GestureDetector( onHorizontalDragStart: (_) => onDrag(ref), onVerticalDragStart: (_) => onDrag(ref), + onTapDown: (details) async { + final systemTitlebar = ref.read( + userPreferencesProvider.select((s) => s.systemTitleBar)); + if (!kIsDesktop || systemTitlebar) return; + + int currMills = DateTime.now().millisecondsSinceEpoch; + + if ((currMills - lastClicked.value) < 500) { + if (await windowManager.isMaximized()) { + await windowManager.unmaximize(); + } else { + await windowManager.maximize(); + } + } else { + lastClicked.value = currMills; + } + }, child: AppBar( leading: leading.isEmpty && automaticallyImplyLeading && diff --git a/lib/components/ui/button_tile.dart b/lib/components/ui/button_tile.dart new file mode 100644 index 00000000..d865b583 --- /dev/null +++ b/lib/components/ui/button_tile.dart @@ -0,0 +1,95 @@ +import 'package:shadcn_flutter/shadcn_flutter.dart'; + +class ButtonTile extends StatelessWidget { + final Widget? title; + final Widget? subtitle; + final Widget? leading; + final Widget? trailing; + final bool enabled; + final void Function()? onPressed; + final bool selected; + final ButtonVariance style; + + const ButtonTile({ + super.key, + this.title, + this.subtitle, + this.leading, + this.trailing, + this.enabled = true, + this.onPressed, + this.selected = false, + this.style = ButtonVariance.outline, + }); + + @override + Widget build(BuildContext context) { + final ThemeData(:colorScheme, :typography) = Theme.of(context); + + return Button( + enabled: enabled, + onPressed: onPressed, + style: style.copyWith( + decoration: (context, states, value) { + final decoration = ButtonVariance.outline.decoration(context, states) + as BoxDecoration; + + if (selected && style == ButtonVariance.outline) { + return decoration.copyWith( + border: Border.all( + color: colorScheme.primary, + width: 1.0, + ), + color: colorScheme.primary.withAlpha(25), + ); + } + + return decoration; + }, + iconTheme: (context, states, value) { + final iconTheme = ButtonVariance.outline.iconTheme(context, states); + + if (selected && style == ButtonVariance.outline) { + return iconTheme.copyWith( + color: colorScheme.primary, + ); + } + + return iconTheme; + }, + textStyle: (context, states, value) { + final textStyle = ButtonVariance.outline.textStyle(context, states); + + if (selected && style == ButtonVariance.outline) { + return textStyle.copyWith( + color: colorScheme.primary, + ); + } + + return textStyle; + }, + ), + alignment: Alignment.centerLeft, + child: SizedBox( + width: double.infinity, + child: Basic( + padding: EdgeInsets.zero, + leadingAlignment: Alignment.center, + trailingAlignment: Alignment.center, + leading: leading, + title: title, + subtitle: + style == ButtonVariance.outline && selected && subtitle != null + ? DefaultTextStyle( + style: typography.xSmall.copyWith( + color: colorScheme.primary, + ), + child: subtitle!, + ) + : subtitle, + trailing: trailing, + ), + ), + ); + } +} diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 4109edb7..0be79bda 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -97,6 +97,7 @@ "pause_playback": "Pause Playback", "resume_playback": "Resume Playback", "loop_track": "Loop track", + "no_loop": "No loop", "repeat_playlist": "Repeat playlist", "queue": "Queue", "alternative_track_sources": "Alternative track sources", diff --git a/lib/modules/connect/local_devices.dart b/lib/modules/connect/local_devices.dart index dd7db971..138e9e13 100644 --- a/lib/modules/connect/local_devices.dart +++ b/lib/modules/connect/local_devices.dart @@ -1,7 +1,7 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; @@ -10,7 +10,7 @@ class ConnectPageLocalDevices extends HookWidget { @override Widget build(BuildContext context) { - final ThemeData(:textTheme) = Theme.of(context); + final ThemeData(:typography) = Theme.of(context); final devicesFuture = useFuture(audioPlayer.devices); final devicesStream = useStream(audioPlayer.devicesStream); final selectedDeviceFuture = useFuture(audioPlayer.selectedDevice); @@ -32,7 +32,7 @@ class ConnectPageLocalDevices extends HookWidget { sliver: SliverToBoxAdapter( child: Text( context.l10n.this_device, - style: textTheme.titleMedium, + style: typography.bold, ), ), ), @@ -43,14 +43,12 @@ class ConnectPageLocalDevices extends HookWidget { itemBuilder: (context, index) { final device = devices[index]; - return Card( - child: ListTile( - leading: const Icon(SpotubeIcons.speaker), - title: Text(device.description), - subtitle: Text(device.name), - selected: selectedDevice == device, - onTap: () => audioPlayer.setAudioDevice(device), - ), + return ButtonTile( + selected: selectedDevice == device, + onPressed: () => audioPlayer.setAudioDevice(device), + leading: const Icon(SpotubeIcons.speaker), + title: Text(device.description), + subtitle: Text(device.name), ); }, ), diff --git a/lib/modules/player/player_queue.dart b/lib/modules/player/player_queue.dart index cdda39da..a91c883d 100644 --- a/lib/modules/player/player_queue.dart +++ b/lib/modules/player/player_queue.dart @@ -224,7 +224,7 @@ class PlayerQueue extends HookConsumerWidget { ); }, ), - const SliverGap(100), + const SliverSafeArea(sliver: SliverGap(100)), ], ), ), diff --git a/lib/pages/connect/connect.dart b/lib/pages/connect/connect.dart index 1a5dfb31..55c72026 100644 --- a/lib/pages/connect/connect.dart +++ b/lib/pages/connect/connect.dart @@ -1,7 +1,7 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/modules/connect/local_devices.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/extensions/context.dart'; @@ -16,79 +16,74 @@ class ConnectPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:colorScheme, :textTheme) = Theme.of(context); + final ThemeData(:colorScheme, :typography) = Theme.of(context); final connectClients = ref.watch(connectClientsProvider); final connectClientsNotifier = ref.read(connectClientsProvider.notifier); final discoveredDevices = connectClients.asData?.value.services; return Scaffold( - appBar: TitleBar( - automaticallyImplyLeading: true, - title: Text(context.l10n.devices), - ), - body: ListTileTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - selectedTileColor: colorScheme.secondary.withOpacity(0.1), - child: Padding( - padding: const EdgeInsets.all(10.0), - child: CustomScrollView( - slivers: [ - SliverPadding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - sliver: SliverToBoxAdapter( - child: Text( - context.l10n.remote, - style: textTheme.titleMedium, - ), + headers: [ + TitleBar( + automaticallyImplyLeading: true, + title: Text(context.l10n.devices), + ) + ], + child: Padding( + padding: const EdgeInsets.all(10.0), + child: CustomScrollView( + slivers: [ + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + sliver: SliverToBoxAdapter( + child: Text( + context.l10n.remote, + style: typography.bold, ), ), - const SliverGap(10), - SliverList.separated( - itemCount: discoveredDevices?.length ?? 0, - separatorBuilder: (context, index) => const Gap(10), - itemBuilder: (context, index) { - final device = discoveredDevices![index]; - final selected = - connectClients.asData?.value.resolvedService?.name == - device.name; - return Card( - child: ListTile( - leading: const Icon(SpotubeIcons.monitor), - title: Text(device.name), - subtitle: selected - ? Text( - "${connectClients.asData?.value.resolvedService?.host}" - ":${connectClients.asData?.value.resolvedService?.port}", - ) - : null, - selected: selected, - onTap: () { - if (selected) { - ServiceUtils.pushNamed( - context, - ConnectControlPage.name, - ); - } else { - connectClientsNotifier.resolveService(device); - } - }, - trailing: selected - ? IconButton( - icon: const Icon(SpotubeIcons.power), - onPressed: () => - connectClientsNotifier.clearResolvedService(), - ) - : null, - ), - ); - }, - ), - const ConnectPageLocalDevices(), - ], - ), + ), + const SliverGap(10), + SliverList.separated( + itemCount: discoveredDevices?.length ?? 0, + separatorBuilder: (context, index) => const Gap(10), + itemBuilder: (context, index) { + final device = discoveredDevices![index]; + final selected = + connectClients.asData?.value.resolvedService?.name == + device.name; + return ButtonTile( + selected: selected, + leading: const Icon(SpotubeIcons.monitor), + title: Text(device.name), + subtitle: selected + ? Text( + "${connectClients.asData?.value.resolvedService?.host}" + ":${connectClients.asData?.value.resolvedService?.port}", + ) + : null, + trailing: selected + ? IconButton.outline( + icon: const Icon(SpotubeIcons.power), + size: ButtonSize.small, + onPressed: () => + connectClientsNotifier.clearResolvedService(), + ) + : null, + onPressed: () { + if (selected) { + ServiceUtils.pushNamed( + context, + ConnectControlPage.name, + ); + } else { + connectClientsNotifier.resolveService(device); + } + }, + ); + }, + ), + const ConnectPageLocalDevices(), + ], ), ), ); diff --git a/lib/pages/connect/control/control.dart b/lib/pages/connect/control/control.dart index 03406546..b92a5482 100644 --- a/lib/pages/connect/control/control.dart +++ b/lib/pages/connect/control/control.dart @@ -1,7 +1,7 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/player/player_queue.dart'; import 'package:spotube/modules/player/volume_slider.dart'; @@ -53,7 +53,7 @@ class ConnectControlPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme, :colorScheme) = Theme.of(context); + final ThemeData(:typography, :colorScheme) = Theme.of(context); final resolvedService = ref.watch(connectClientsProvider).asData?.value.resolvedService; @@ -63,23 +63,6 @@ class ConnectControlPage extends HookConsumerWidget { final shuffled = ref.watch(shuffleProvider); final loopMode = ref.watch(loopModeProvider); - final resumePauseStyle = IconButton.styleFrom( - backgroundColor: colorScheme.primary, - foregroundColor: colorScheme.onPrimary, - padding: const EdgeInsets.all(12), - iconSize: 24, - ); - final buttonStyle = IconButton.styleFrom( - backgroundColor: colorScheme.surface.withOpacity(0.4), - minimumSize: const Size(28, 28), - ); - - final activeButtonStyle = IconButton.styleFrom( - backgroundColor: colorScheme.primaryContainer, - foregroundColor: colorScheme.onPrimaryContainer, - minimumSize: const Size(28, 28), - ); - ref.listen(connectClientsProvider, (prev, next) { if (next.asData?.value.resolvedService == null) { context.pop(); @@ -87,12 +70,15 @@ class ConnectControlPage extends HookConsumerWidget { }); return SafeArea( + bottom: false, child: Scaffold( - appBar: TitleBar( - title: Text(resolvedService!.name), - automaticallyImplyLeading: true, - ), - body: LayoutBuilder(builder: (context, constrains) { + headers: [ + TitleBar( + title: Text(resolvedService!.name), + automaticallyImplyLeading: true, + ) + ], + child: LayoutBuilder(builder: (context, constrains) { return Row( children: [ Expanded( @@ -106,7 +92,7 @@ class ConnectControlPage extends HookConsumerWidget { vertical: 10, ).copyWith(top: 0), constraints: - const BoxConstraints(maxHeight: 400, maxWidth: 400), + const BoxConstraints(maxHeight: 350, maxWidth: 350), child: ClipRRect( borderRadius: BorderRadius.circular(20), child: UniversalImage( @@ -126,7 +112,7 @@ class ConnectControlPage extends HookConsumerWidget { SliverToBoxAdapter( child: AnchorButton( playlist.activeTrack?.name ?? "", - style: textTheme.titleLarge!, + style: typography.h4, onTap: () { if (playlist.activeTrack == null) return; ServiceUtils.pushNamed( @@ -142,7 +128,7 @@ class ConnectControlPage extends HookConsumerWidget { SliverToBoxAdapter( child: ArtistLink( artists: playlist.activeTrack?.artists ?? [], - textStyle: textTheme.bodyMedium!, + textStyle: typography.normal, mainAxisAlignment: WrapAlignment.start, onOverflowArtistClick: () => ServiceUtils.pushNamed( @@ -164,19 +150,25 @@ class ConnectControlPage extends HookConsumerWidget { final position = ref.watch(positionProvider); final duration = ref.watch(durationProvider); + final progress = duration.inSeconds == 0 + ? 0 + : position.inSeconds / duration.inSeconds; + return Padding( padding: const EdgeInsets.symmetric(horizontal: 12), child: Column( children: [ Slider( - value: position > duration - ? 0 - : position.inSeconds.toDouble(), - min: 0, - max: duration.inSeconds.toDouble(), + value: + SliderValue.single(progress.toDouble()), onChanged: (value) { - connectNotifier - .seek(Duration(seconds: value.toInt())); + connectNotifier.seek( + Duration( + seconds: + (value.value * duration.inSeconds) + .toInt(), + ), + ); }, ), Row( @@ -197,93 +189,155 @@ class ConnectControlPage extends HookConsumerWidget { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - IconButton( - tooltip: shuffled - ? context.l10n.unshuffle_playlist - : context.l10n.shuffle_playlist, - icon: const Icon(SpotubeIcons.shuffle), - style: shuffled ? activeButtonStyle : buttonStyle, - onPressed: playlist.activeTrack == null - ? null - : () { - connectNotifier.setShuffle(!shuffled); - }, - ), - IconButton( - tooltip: context.l10n.previous_track, - icon: const Icon(SpotubeIcons.skipBack), - onPressed: playlist.activeTrack == null - ? null - : connectNotifier.previous, - ), - IconButton( - tooltip: playing - ? context.l10n.pause_playback - : context.l10n.resume_playback, - icon: playlist.activeTrack == null - ? SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator( - color: colorScheme.onPrimary, - ), - ) - : Icon( - playing - ? SpotubeIcons.pause - : SpotubeIcons.play, - ), - style: resumePauseStyle, - onPressed: playlist.activeTrack == null - ? null - : () { - if (playing) { - connectNotifier.pause(); - } else { - connectNotifier.resume(); - } - }, - ), - IconButton( - tooltip: context.l10n.next_track, - icon: const Icon(SpotubeIcons.skipForward), - onPressed: playlist.activeTrack == null - ? null - : connectNotifier.next, - ), - IconButton( - tooltip: loopMode == PlaylistMode.single - ? context.l10n.loop_track - : loopMode == PlaylistMode.loop - ? context.l10n.repeat_playlist - : null, - icon: Icon( - loopMode == PlaylistMode.single - ? SpotubeIcons.repeatOne - : SpotubeIcons.repeat, + Tooltip( + tooltip: TooltipContainer( + child: Text( + shuffled + ? context.l10n.unshuffle_playlist + : context.l10n.shuffle_playlist, + ), + ), + child: IconButton( + icon: const Icon(SpotubeIcons.shuffle), + variance: shuffled + ? ButtonVariance.secondary + : ButtonVariance.ghost, + onPressed: playlist.activeTrack == null + ? null + : () { + connectNotifier.setShuffle(!shuffled); + }, + ), + ), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.previous_track), + ), + child: IconButton.ghost( + icon: const Icon(SpotubeIcons.skipBack), + onPressed: playlist.activeTrack == null + ? null + : connectNotifier.previous, + ), + ), + Tooltip( + tooltip: TooltipContainer( + child: Text( + playing + ? context.l10n.pause_playback + : context.l10n.resume_playback, + ), + ), + child: IconButton.primary( + shape: ButtonShape.circle, + icon: playlist.activeTrack == null + ? const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator( + onSurface: false), + ) + : Icon( + playing + ? SpotubeIcons.pause + : SpotubeIcons.play, + ), + onPressed: playlist.activeTrack == null + ? null + : () { + if (playing) { + connectNotifier.pause(); + } else { + connectNotifier.resume(); + } + }, + ), + ), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.next_track)), + child: IconButton.ghost( + icon: const Icon(SpotubeIcons.skipForward), + onPressed: playlist.activeTrack == null + ? null + : connectNotifier.next, + ), + ), + Tooltip( + tooltip: TooltipContainer( + child: Text( + loopMode == PlaylistMode.single + ? context.l10n.loop_track + : loopMode == PlaylistMode.loop + ? context.l10n.repeat_playlist + : context.l10n.no_loop, + ), + ), + child: IconButton( + icon: Icon( + loopMode == PlaylistMode.single + ? SpotubeIcons.repeatOne + : SpotubeIcons.repeat, + ), + variance: loopMode == PlaylistMode.single || + loopMode == PlaylistMode.loop + ? ButtonVariance.secondary + : ButtonVariance.ghost, + onPressed: playlist.activeTrack == null + ? null + : () async { + connectNotifier.setLoopMode( + switch (loopMode) { + PlaylistMode.loop => + PlaylistMode.single, + PlaylistMode.single => + PlaylistMode.none, + PlaylistMode.none => + PlaylistMode.loop, + }, + ); + }, ), - style: loopMode == PlaylistMode.single || - loopMode == PlaylistMode.loop - ? activeButtonStyle - : buttonStyle, - onPressed: playlist.activeTrack == null - ? null - : () async { - connectNotifier.setLoopMode( - switch (loopMode) { - PlaylistMode.loop => - PlaylistMode.single, - PlaylistMode.single => - PlaylistMode.none, - PlaylistMode.none => PlaylistMode.loop, - }, - ); - }, ) ], ), ), const SliverGap(30), + if (constrains.mdAndDown) + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 20), + sliver: SliverToBoxAdapter( + child: Button.outline( + leading: const Icon(SpotubeIcons.queue), + child: Text(context.l10n.queue), + onPressed: () { + openDrawer( + context: context, + barrierDismissible: true, + draggable: true, + barrierColor: Colors.black.withAlpha(100), + borderRadius: BorderRadius.circular(10), + transformBackdrop: false, + position: OverlayPosition.bottom, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: 0.7, + expands: true, + builder: (context) { + return ConstrainedBox( + constraints: BoxConstraints( + maxHeight: + MediaQuery.sizeOf(context).height * + 0.8, + ), + child: const RemotePlayerQueue(), + ); + }, + ); + }, + ), + ), + ), + const SliverGap(30), SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 20), sliver: SliverToBoxAdapter( @@ -300,25 +354,7 @@ class ConnectControlPage extends HookConsumerWidget { }), ), ), - const SliverGap(30), - if (constrains.mdAndDown) - SliverPadding( - padding: const EdgeInsets.symmetric(horizontal: 20), - sliver: SliverToBoxAdapter( - child: OutlinedButton.icon( - icon: const Icon(SpotubeIcons.queue), - label: Text(context.l10n.queue), - onPressed: () { - showModalBottomSheet( - context: context, - builder: (context) { - return const RemotePlayerQueue(); - }, - ); - }, - ), - ), - ) + const SliverSafeArea(sliver: SliverGap(10)), ], ), ), diff --git a/untranslated_messages.json b/untranslated_messages.json index 05b5aca3..fae95f00 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1,5 +1,6 @@ { "ar": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -9,6 +10,7 @@ ], "bn": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -18,6 +20,7 @@ ], "ca": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -27,6 +30,7 @@ ], "cs": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -36,6 +40,7 @@ ], "de": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -45,6 +50,7 @@ ], "es": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -54,6 +60,7 @@ ], "eu": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -63,6 +70,7 @@ ], "fa": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -72,6 +80,7 @@ ], "fi": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -81,6 +90,7 @@ ], "fr": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -90,6 +100,7 @@ ], "hi": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -99,6 +110,7 @@ ], "id": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -108,6 +120,7 @@ ], "it": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -117,6 +130,7 @@ ], "ja": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -126,6 +140,7 @@ ], "ka": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -135,6 +150,7 @@ ], "ko": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -144,6 +160,7 @@ ], "ne": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -153,6 +170,7 @@ ], "nl": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -162,6 +180,7 @@ ], "pl": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -171,6 +190,7 @@ ], "pt": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -180,6 +200,7 @@ ], "ru": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -189,6 +210,7 @@ ], "th": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -198,6 +220,7 @@ ], "tr": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -207,6 +230,7 @@ ], "uk": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -216,6 +240,7 @@ ], "vi": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", @@ -225,6 +250,7 @@ ], "zh": [ + "no_loop", "undo", "download_all", "add_all_to_playlist", From bbad701c074b44594dff3fa8cc96067a91f5f013 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 5 Jan 2025 08:58:57 +0600 Subject: [PATCH 30/81] refactor: dialogs to shadcn dialog --- .../dialogs/confirm_download_dialog.dart | 106 +++++++++--------- lib/components/dialogs/prompt_dialog.dart | 6 +- .../dialogs/replace_downloaded_dialog.dart | 60 +++++----- .../dialogs/select_device_dialog.dart | 53 ++++----- .../presentation_actions.dart | 13 ++- .../use_action_callbacks.dart | 2 + .../use_track_tile_play_callback.dart | 1 + lib/modules/album/album_card.dart | 1 + lib/modules/playlist/playlist_card.dart | 1 + lib/pages/artist/section/top_tracks.dart | 3 + lib/pages/connect/control/control.dart | 1 + lib/pages/search/sections/tracks.dart | 2 + 12 files changed, 124 insertions(+), 125 deletions(-) diff --git a/lib/components/dialogs/confirm_download_dialog.dart b/lib/components/dialogs/confirm_download_dialog.dart index 897c64cb..a2df0e9c 100644 --- a/lib/components/dialogs/confirm_download_dialog.dart +++ b/lib/components/dialogs/confirm_download_dialog.dart @@ -1,5 +1,4 @@ -import 'package:flutter/material.dart'; - +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; @@ -9,13 +8,15 @@ class ConfirmDownloadDialog extends StatelessWidget { @override Widget build(BuildContext context) { - return AlertDialog( - title: Padding( - padding: const EdgeInsets.all(15), - child: Row( + final screenSize = MediaQuery.sizeOf(context); + + return ConstrainedBox( + constraints: BoxConstraints(maxWidth: Breakpoints.sm), + child: AlertDialog( + title: Row( + spacing: 10, children: [ Text(context.l10n.are_you_sure), - const SizedBox(width: 10), const UniversalImage( path: "https://c.tenor.com/kHcmsxlKHEAAAAAM/rock-one-eyebrow-raised-rock-staring.gif", @@ -24,58 +25,53 @@ class ConfirmDownloadDialog extends StatelessWidget { ) ], ), - ), - content: Container( - padding: const EdgeInsets.all(15), - constraints: BoxConstraints(maxWidth: Breakpoints.sm), - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - context.l10n.download_warning, - textAlign: TextAlign.justify, - ), - const SizedBox(height: 10), - Text( - context.l10n.download_ip_ban_warning, - style: const TextStyle( - color: Colors.red, - fontWeight: FontWeight.bold, + content: Expanded( + flex: screenSize.smAndUp ? 0 : 1, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + context.l10n.download_warning, + textAlign: TextAlign.justify, ), - textAlign: TextAlign.justify, - ), - const SizedBox(height: 10), - Text( - context.l10n.by_clicking_accept_terms, - ), - const SizedBox(height: 10), - BulletPoint(context.l10n.download_agreement_1), - const SizedBox(height: 10), - BulletPoint(context.l10n.download_agreement_2), - const SizedBox(height: 10), - BulletPoint(context.l10n.download_agreement_3), - ], + const SizedBox(height: 10), + Text( + context.l10n.download_ip_ban_warning, + style: const TextStyle( + color: Colors.red, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.justify, + ), + const SizedBox(height: 10), + Text( + context.l10n.by_clicking_accept_terms, + ), + const SizedBox(height: 10), + BulletPoint(context.l10n.download_agreement_1), + const SizedBox(height: 10), + BulletPoint(context.l10n.download_agreement_2), + const SizedBox(height: 10), + BulletPoint(context.l10n.download_agreement_3), + ], + ), ), ), + actions: [ + Button.outline( + child: Text(context.l10n.decline), + onPressed: () { + Navigator.pop(context, false); + }, + ), + Button.destructive( + onPressed: () => Navigator.of(context).pop(true), + child: Text(context.l10n.accept), + ), + ], ), - actions: [ - OutlinedButton( - child: Text(context.l10n.decline), - onPressed: () { - Navigator.pop(context, false); - }, - ), - FilledButton( - style: FilledButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.red, - ), - onPressed: () => Navigator.of(context).pop(true), - child: Text(context.l10n.accept), - ), - ], ); } } diff --git a/lib/components/dialogs/prompt_dialog.dart b/lib/components/dialogs/prompt_dialog.dart index 30a63bcf..3498bf02 100644 --- a/lib/components/dialogs/prompt_dialog.dart +++ b/lib/components/dialogs/prompt_dialog.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/extensions/context.dart'; Future showPromptDialog({ @@ -16,13 +16,13 @@ Future showPromptDialog({ content: Text(message), actions: [ if (cancelText != null) - OutlinedButton( + Button.outline( onPressed: () => Navigator.of(context).pop(false), child: Text( cancelText == "Cancel" ? context.l10n.cancel : cancelText, ), ), - FilledButton( + Button.primary( child: Text(okText == "Ok" ? context.l10n.ok : okText), onPressed: () => Navigator.of(context).pop(true), ), diff --git a/lib/components/dialogs/replace_downloaded_dialog.dart b/lib/components/dialogs/replace_downloaded_dialog.dart index 00461d34..3a0f3a1d 100644 --- a/lib/components/dialogs/replace_downloaded_dialog.dart +++ b/lib/components/dialogs/replace_downloaded_dialog.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/extensions/context.dart'; @@ -13,45 +13,35 @@ class ReplaceDownloadedDialog extends ConsumerWidget { @override Widget build(BuildContext context, ref) { final groupValue = ref.watch(replaceDownloadedFileState); - final theme = Theme.of(context); final replaceAll = ref.watch(replaceDownloadedFileState); return AlertDialog( title: Text(context.l10n.track_exists(track.name ?? "")), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(context.l10n.do_you_want_to_replace), - RadioListTile( - dense: true, - contentPadding: EdgeInsets.zero, - activeColor: theme.colorScheme.primary, - value: true, - groupValue: groupValue, - onChanged: (value) { - if (value != null) { - ref.read(replaceDownloadedFileState.notifier).state = true; - } - }, - title: Text(context.l10n.replace_downloaded_tracks), - ), - RadioListTile( - dense: true, - contentPadding: EdgeInsets.zero, - activeColor: theme.colorScheme.primary, - value: false, - groupValue: groupValue, - onChanged: (value) { - if (value != null) { - ref.read(replaceDownloadedFileState.notifier).state = false; - } - }, - title: Text(context.l10n.skip_download_tracks), - ), - ], + content: RadioGroup( + value: groupValue, + onChanged: (value) { + ref.read(replaceDownloadedFileState.notifier).state = value; + }, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(context.l10n.do_you_want_to_replace), + const Gap(16), + RadioItem( + value: true, + trailing: Text(context.l10n.replace_downloaded_tracks), + ), + const Gap(8), + RadioItem( + value: false, + trailing: Text(context.l10n.skip_download_tracks), + ), + ], + ), ), actions: [ - OutlinedButton( + Button.outline( onPressed: replaceAll == true ? null : () { @@ -59,7 +49,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget { }, child: Text(context.l10n.skip), ), - FilledButton( + Button.primary( onPressed: replaceAll == false ? null : () { diff --git a/lib/components/dialogs/select_device_dialog.dart b/lib/components/dialogs/select_device_dialog.dart index 3a3bde60..5392a403 100644 --- a/lib/components/dialogs/select_device_dialog.dart +++ b/lib/components/dialogs/select_device_dialog.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/connect/clients.dart'; @@ -16,31 +16,31 @@ class SelectDeviceDialog extends HookConsumerWidget { return AlertDialog( title: Text(context.l10n.choose_the_device), - insetPadding: const EdgeInsets.all(16), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(context.l10n.multiple_device_connected), - RadioListTile.adaptive( - title: Text(remoteService.name), - value: true, - groupValue: isRemoteService.value, - onChanged: (value) { - isRemoteService.value = value!; - }, - ), - RadioListTile.adaptive( - title: Text(context.l10n.this_device), - value: false, - groupValue: isRemoteService.value, - onChanged: (value) { - isRemoteService.value = !value!; - }, - ), - ], + content: RadioGroup( + value: isRemoteService.value, + onChanged: (value) { + isRemoteService.value = value; + }, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(context.l10n.multiple_device_connected), + const Gap(16), + RadioItem( + trailing: Text(remoteService.name), + value: true, + ), + const Gap(8), + RadioItem( + trailing: Text(context.l10n.this_device), + value: false, + ), + ], + ), ), actions: [ - TextButton( + Button.primary( onPressed: () { Navigator.of(context).pop(isRemoteService.value); }, @@ -51,7 +51,8 @@ class SelectDeviceDialog extends HookConsumerWidget { } } -Future showSelectDeviceDialog(BuildContext context, WidgetRef ref) async { +Future showSelectDeviceDialog( + BuildContext context, WidgetRef ref) async { final connectClients = ref.read(connectClientsProvider); if (connectClients.asData?.value.resolvedService == null) { @@ -63,5 +64,5 @@ Future showSelectDeviceDialog(BuildContext context, WidgetRef ref) async { builder: (context) => const SelectDeviceDialog(), ); - return isRemote ?? false; + return isRemote; } diff --git a/lib/components/track_presentation/presentation_actions.dart b/lib/components/track_presentation/presentation_actions.dart index 41f518d0..01228524 100644 --- a/lib/components/track_presentation/presentation_actions.dart +++ b/lib/components/track_presentation/presentation_actions.dart @@ -97,12 +97,13 @@ class TrackPresentationActionsSection extends HookConsumerWidget { case "download": { final confirmed = audioSource == AudioSource.piped || - await showDialog( - context: context, - builder: (context) { - return const ConfirmDownloadDialog(); - }, - ); + (await showDialog( + context: context, + builder: (context) { + return const ConfirmDownloadDialog(); + }, + ) ?? + false); if (confirmed != true) return; downloader.batchAddToQueue(tracks); notifier.deselectAllTracks(); diff --git a/lib/components/track_presentation/use_action_callbacks.dart b/lib/components/track_presentation/use_action_callbacks.dart index e9b9c98e..0012594a 100644 --- a/lib/components/track_presentation/use_action_callbacks.dart +++ b/lib/components/track_presentation/use_action_callbacks.dart @@ -40,6 +40,7 @@ UseActionCallbacks useActionCallbacks(WidgetRef ref) { if (!context.mounted) return; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final allTracks = await options.pagination.onFetchAll(); final remotePlayback = ref.read(connectProvider.notifier); @@ -90,6 +91,7 @@ UseActionCallbacks useActionCallbacks(WidgetRef ref) { if (!context.mounted) return; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final allTracks = await options.pagination.onFetchAll(); final remotePlayback = ref.read(connectProvider.notifier); diff --git a/lib/components/track_presentation/use_track_tile_play_callback.dart b/lib/components/track_presentation/use_track_tile_play_callback.dart index 261d01d8..74608205 100644 --- a/lib/components/track_presentation/use_track_tile_play_callback.dart +++ b/lib/components/track_presentation/use_track_tile_play_callback.dart @@ -37,6 +37,7 @@ Future Function(Track track, int index) useTrackTilePlayCallback( } final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); diff --git a/lib/modules/album/album_card.dart b/lib/modules/album/album_card.dart index 86935698..2efacbfd 100644 --- a/lib/modules/album/album_card.dart +++ b/lib/modules/album/album_card.dart @@ -91,6 +91,7 @@ class AlbumCard extends HookConsumerWidget { if (fetchedTracks.isEmpty || !context.mounted) return; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); await remotePlayback.load( diff --git a/lib/modules/playlist/playlist_card.dart b/lib/modules/playlist/playlist_card.dart index 945f3571..43f2ee4e 100644 --- a/lib/modules/playlist/playlist_card.dart +++ b/lib/modules/playlist/playlist_card.dart @@ -94,6 +94,7 @@ class PlaylistCard extends HookConsumerWidget { if (fetchedInitialTracks.isEmpty || !context.mounted) return; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); final allTracks = await fetchAllTracks(); diff --git a/lib/pages/artist/section/top_tracks.dart b/lib/pages/artist/section/top_tracks.dart index d52ed470..5ef68c9c 100644 --- a/lib/pages/artist/section/top_tracks.dart +++ b/lib/pages/artist/section/top_tracks.dart @@ -44,6 +44,9 @@ class ArtistPageTopTracks extends HookConsumerWidget { currentTrack ??= tracks.first; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + + if (isRemoteDevice == null) return; + if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); final remotePlaylist = ref.read(queueProvider); diff --git a/lib/pages/connect/control/control.dart b/lib/pages/connect/control/control.dart index b92a5482..afe68b16 100644 --- a/lib/pages/connect/control/control.dart +++ b/lib/pages/connect/control/control.dart @@ -188,6 +188,7 @@ class ConnectControlPage extends HookConsumerWidget { SliverToBoxAdapter( child: Row( mainAxisAlignment: MainAxisAlignment.center, + spacing: 20, children: [ Tooltip( tooltip: TooltipContainer( diff --git a/lib/pages/search/sections/tracks.dart b/lib/pages/search/sections/tracks.dart index c0daa853..bacbbb57 100644 --- a/lib/pages/search/sections/tracks.dart +++ b/lib/pages/search/sections/tracks.dart @@ -55,6 +55,8 @@ class SearchTracksSection extends HookConsumerWidget { final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; + if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); final remotePlaylist = ref.read(queueProvider); From 4afe0cca68d0b6f18cb1812cb776deb7b340f63b Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 5 Jan 2025 09:47:32 +0600 Subject: [PATCH 31/81] refactor: artist page --- lib/modules/artist/artist_album_list.dart | 4 +- lib/pages/artist/artist.dart | 41 ++- lib/pages/artist/section/footer.dart | 2 +- lib/pages/artist/section/header.dart | 372 +++++++++++----------- lib/pages/artist/section/top_tracks.dart | 39 ++- 5 files changed, 222 insertions(+), 236 deletions(-) diff --git a/lib/modules/artist/artist_album_list.dart b/lib/modules/artist/artist_album_list.dart index a2dd8006..7131aa3b 100644 --- a/lib/modules/artist/artist_album_list.dart +++ b/lib/modules/artist/artist_album_list.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart' hide Page; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; import 'package:spotube/extensions/context.dart'; @@ -30,7 +30,7 @@ class ArtistAlbumList extends HookConsumerWidget { onFetchMore: albumsQueryNotifier.fetchMore, title: Text( context.l10n.albums, - style: theme.textTheme.headlineSmall, + style: theme.typography.h4, ), ); } diff --git a/lib/pages/artist/artist.dart b/lib/pages/artist/artist.dart index 9e8b5be4..5565d897 100644 --- a/lib/pages/artist/artist.dart +++ b/lib/pages/artist/artist.dart @@ -1,8 +1,8 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; +import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/modules/artist/artist_album_list.dart'; @@ -30,12 +30,14 @@ class ArtistPage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: const TitleBar( - leading: [BackButton()], - backgroundColor: Colors.transparent, - ), - extendBodyBehindAppBar: true, - body: Builder(builder: (context) { + headers: const [ + TitleBar( + leading: [BackButton()], + backgroundColor: Colors.transparent, + ) + ], + floatingHeader: true, + child: Builder(builder: (context) { if (artistQuery.hasError && artistQuery.asData?.value == null) { return Center(child: Text(artistQuery.error.toString())); } @@ -50,31 +52,26 @@ class ArtistPage extends HookConsumerWidget { child: ArtistPageHeader(artistId: artistId), ), ), - const SliverGap(50), - ArtistPageTopTracks(artistId: artistId), - const SliverGap(50), - SliverToBoxAdapter(child: ArtistAlbumList(artistId)), const SliverGap(20), + ArtistPageTopTracks(artistId: artistId), + const SliverGap(20), + SliverToBoxAdapter(child: ArtistAlbumList(artistId)), SliverPadding( padding: const EdgeInsets.all(8.0), sliver: SliverToBoxAdapter( child: Text( context.l10n.fans_also_like, - style: theme.textTheme.headlineSmall, + style: theme.typography.h4, ), ), ), - SliverSafeArea( - sliver: ArtistPageRelatedArtists(artistId: artistId), - ), + ArtistPageRelatedArtists(artistId: artistId), + const SliverGap(20), if (artistQuery.asData?.value != null) - SliverSafeArea( - top: false, - sliver: SliverToBoxAdapter( - child: - ArtistPageFooter(artist: artistQuery.asData!.value), - ), + SliverToBoxAdapter( + child: ArtistPageFooter(artist: artistQuery.asData!.value), ), + const SliverSafeArea(sliver: SliverGap(10)), ], ), ); diff --git a/lib/pages/artist/section/footer.dart b/lib/pages/artist/section/footer.dart index abe86410..61d9d100 100644 --- a/lib/pages/artist/section/footer.dart +++ b/lib/pages/artist/section/footer.dart @@ -26,7 +26,7 @@ class ArtistPageFooter extends ConsumerWidget { if (summary.asData?.value == null) return const SizedBox.shrink(); return Container( - margin: const EdgeInsets.all(16), + margin: const EdgeInsets.all(8), padding: mediaQuery.smAndDown ? const EdgeInsets.all(20) : const EdgeInsets.all(30), diff --git a/lib/pages/artist/section/header.dart b/lib/pages/artist/section/header.dart index 713e0d26..b6224428 100644 --- a/lib/pages/artist/section/header.dart +++ b/lib/pages/artist/section/header.dart @@ -1,7 +1,7 @@ -import 'package:flutter/material.dart'; +import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/services.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -9,7 +9,6 @@ import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; -import 'package:spotube/hooks/utils/use_breakpoint_value.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/blacklist_provider.dart'; @@ -25,19 +24,8 @@ class ArtistPageHeader extends HookConsumerWidget { final artistQuery = ref.watch(artistProvider(artistId)); final artist = artistQuery.asData?.value ?? FakeData.artist; - final scaffoldMessenger = ScaffoldMessenger.of(context); - final mediaQuery = MediaQuery.of(context); final theme = Theme.of(context); - final ThemeData(:textTheme) = theme; - - final chipTextVariant = useBreakpointValue( - xs: textTheme.bodySmall, - sm: textTheme.bodySmall, - md: textTheme.bodyMedium, - lg: textTheme.bodyLarge, - xl: textTheme.titleSmall, - xxl: textTheme.titleMedium, - ); + final ThemeData(:typography) = theme; final auth = ref.watch(authenticationProvider); ref.watch(blacklistProvider); @@ -48,190 +36,192 @@ class ArtistPageHeader extends HookConsumerWidget { placeholder: ImagePlaceholder.artist, ); + final actions = Skeleton.keep( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (auth.asData?.value != null) + Consumer( + builder: (context, ref, _) { + final isFollowingQuery = ref.watch( + artistIsFollowingProvider(artist.id!), + ); + final followingArtistNotifier = ref.watch( + followedArtistsProvider.notifier, + ); + + return switch (isFollowingQuery) { + AsyncData(value: final following) => Builder( + builder: (context) { + if (following) { + return Button.outline( + onPressed: () async { + await followingArtistNotifier + .removeArtists([artist.id!]); + }, + child: Text(context.l10n.following), + ); + } + + return Button.primary( + onPressed: () async { + await followingArtistNotifier + .saveArtists([artist.id!]); + }, + child: Text(context.l10n.follow), + ); + }, + ), + AsyncError() => const SizedBox(), + _ => const SizedBox.square( + dimension: 20, + child: CircularProgressIndicator(), + ) + }; + }, + ), + const SizedBox(width: 5), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.add_artist_to_blacklist), + ), + child: IconButton( + icon: Icon( + SpotubeIcons.userRemove, + color: !isBlackListed ? Colors.red[400] : null, + ), + variance: isBlackListed + ? ButtonVariance.destructive + : ButtonVariance.ghost, + onPressed: () async { + if (isBlackListed) { + await ref.read(blacklistProvider.notifier).remove(artist.id!); + } else { + await ref.read(blacklistProvider.notifier).add( + BlacklistTableCompanion.insert( + name: artist.name!, + elementId: artist.id!, + elementType: BlacklistedType.artist, + ), + ); + } + }, + ), + ), + IconButton.ghost( + icon: const Icon(SpotubeIcons.share), + onPressed: () async { + if (artist.externalUrls?.spotify != null) { + await Clipboard.setData( + ClipboardData( + text: artist.externalUrls!.spotify!, + ), + ); + } + + if (!context.mounted) return; + + showToast( + context: context, + location: ToastLocation.topRight, + dismissible: true, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n.artist_url_copied, + textAlign: TextAlign.center, + ), + ); + }, + ); + }, + ) + ], + ), + ); + return LayoutBuilder( builder: (context, constrains) { - return Center( - child: Flex( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: constrains.smAndDown - ? CrossAxisAlignment.start - : CrossAxisAlignment.center, - direction: constrains.smAndDown ? Axis.vertical : Axis.horizontal, - children: [ - DecoratedBox( - decoration: BoxDecoration( - boxShadow: kElevationToShadow[2], - borderRadius: BorderRadius.circular(35), - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(35), - child: UniversalImage( - path: image, - width: 250, - height: 250, - fit: BoxFit.cover, - ), - ), - ), - const Gap(20), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 5), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(50)), - child: Skeleton.keep( - child: Text( - artist.type!.toUpperCase(), - style: chipTextVariant.copyWith( - color: Colors.white, - ), - ), - ), - ), - if (isBlackListed) ...[ - const SizedBox(width: 5), - Container( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 5), - decoration: BoxDecoration( - color: Colors.red[400], - borderRadius: BorderRadius.circular(50)), - child: Text( - context.l10n.blacklisted, - style: chipTextVariant.copyWith( - color: Colors.white, - ), - ), - ), - ] - ], - ), - Text( - artist.name!, - style: mediaQuery.smAndDown - ? textTheme.headlineSmall - : textTheme.headlineMedium, - ), - Text( - context.l10n.followers( - PrimitiveUtils.toReadableNumber( - artist.followers!.total!.toDouble(), + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Card( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipRRect( + borderRadius: theme.borderRadiusXl, + child: UniversalImage( + path: image, + width: constrains.mdAndUp ? 200 : 120, + height: constrains.mdAndUp ? 200 : 120, + fit: BoxFit.cover, ), ), - style: textTheme.bodyMedium?.copyWith( - fontWeight: mediaQuery.mdAndUp ? FontWeight.bold : null, - ), - ), - const Gap(20), - Skeleton.keep( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (auth.asData?.value != null) - Consumer( - builder: (context, ref, _) { - final isFollowingQuery = ref - .watch(artistIsFollowingProvider(artist.id!)); - final followingArtistNotifier = - ref.watch(followedArtistsProvider.notifier); - - return switch (isFollowingQuery) { - AsyncData(value: final following) => Builder( - builder: (context) { - if (following) { - return OutlinedButton( - onPressed: () async { - await followingArtistNotifier - .removeArtists([artist.id!]); - }, - child: Text(context.l10n.following), - ); - } - - return FilledButton( - onPressed: () async { - await followingArtistNotifier - .saveArtists([artist.id!]); - }, - child: Text(context.l10n.follow), - ); - }, - ), - AsyncError() => const SizedBox(), - _ => const SizedBox.square( - dimension: 20, - child: CircularProgressIndicator(), - ) - }; - }, - ), - const SizedBox(width: 5), - IconButton( - tooltip: context.l10n.add_artist_to_blacklist, - icon: Icon( - SpotubeIcons.userRemove, - color: - !isBlackListed ? Colors.red[400] : Colors.white, - ), - style: IconButton.styleFrom( - backgroundColor: - isBlackListed ? Colors.red[400] : null, - ), - onPressed: () async { - if (isBlackListed) { - await ref - .read(blacklistProvider.notifier) - .remove(artist.id!); - } else { - await ref.read(blacklistProvider.notifier).add( - BlacklistTableCompanion.insert( - name: artist.name!, - elementId: artist.id!, - elementType: BlacklistedType.artist, - ), - ); - } - }, - ), - IconButton( - icon: const Icon(SpotubeIcons.share), - onPressed: () async { - if (artist.externalUrls?.spotify != null) { - await Clipboard.setData( - ClipboardData( - text: artist.externalUrls!.spotify!, + const Gap(20), + Flexible( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + OutlineBadge( + child: + Text(context.l10n.artist).small().muted(), + ), + if (isBlackListed) ...[ + const Gap(5), + DestructiveBadge( + child: Text(context.l10n.blacklisted).small(), ), - ); - } - - if (!context.mounted) return; - - scaffoldMessenger.showSnackBar( - SnackBar( - width: 300, - behavior: SnackBarBehavior.floating, - content: Text( - context.l10n.artist_url_copied, - textAlign: TextAlign.center, + ] + ], + ), + const Gap(10), + Flexible( + child: AutoSizeText( + artist.name!, + style: constrains.smAndDown + ? typography.h4 + : typography.h3, + maxLines: 2, + overflow: TextOverflow.ellipsis, + minFontSize: 14, + ), + ), + const Gap(5), + Flexible( + child: AutoSizeText( + context.l10n.followers( + PrimitiveUtils.toReadableNumber( + artist.followers!.total!.toDouble(), ), ), - ); - }, - ) - ], + maxLines: 1, + overflow: TextOverflow.ellipsis, + minFontSize: 12, + ).muted(), + ), + if (constrains.mdAndUp) ...[ + const Gap(20), + actions, + ] + ], + ), ), - ) - ], - ), - ], + ], + ), + if (constrains.smAndDown) ...[ + const Gap(20), + actions, + ] + ], + ), ), ); }, diff --git a/lib/pages/artist/section/top_tracks.dart b/lib/pages/artist/section/top_tracks.dart index 5ef68c9c..72709751 100644 --- a/lib/pages/artist/section/top_tracks.dart +++ b/lib/pages/artist/section/top_tracks.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/fake.dart'; @@ -19,7 +19,6 @@ class ArtistPageTopTracks extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final theme = Theme.of(context); - final scaffoldMessenger = ScaffoldMessenger.of(context); final playlist = ref.watch(audioPlayerProvider); final playlistNotifier = ref.watch(audioPlayerProvider.notifier); @@ -93,46 +92,46 @@ class ArtistPageTopTracks extends HookConsumerWidget { padding: const EdgeInsets.all(8.0), child: Text( context.l10n.top_tracks, - style: theme.textTheme.headlineSmall, + style: theme.typography.h4, ), ), if (!isPlaylistPlaying) - IconButton( + IconButton.outline( icon: const Icon( SpotubeIcons.queueAdd, ), onPressed: () { playlistNotifier.addTracks(topTracks.toList()); - scaffoldMessenger.showSnackBar( - SnackBar( - width: 300, - behavior: SnackBarBehavior.floating, - content: Text( - context.l10n.added_to_queue( - topTracks.length, + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n.added_to_queue( + topTracks.length, + ), ), - textAlign: TextAlign.center, - ), - ), + ); + }, ); }, ), const SizedBox(width: 5), - IconButton( + IconButton.primary( + shape: ButtonShape.circle, + enabled: !isPlaylistPlaying, icon: Skeleton.keep( child: Icon( - isPlaylistPlaying ? SpotubeIcons.stop : SpotubeIcons.play, - color: Colors.white, + isPlaylistPlaying ? SpotubeIcons.pause : SpotubeIcons.play, ), ), - style: IconButton.styleFrom( - backgroundColor: theme.colorScheme.primary, - ), onPressed: () => playPlaylist(topTracks.toList()), ) ], ), ), + const SliverGap(10), SliverList.builder( itemCount: topTracks.length, itemBuilder: (context, index) { From b8f2495acb995eb5eeace35a2f58eb582748ca2a Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 5 Jan 2025 11:54:50 +0600 Subject: [PATCH 32/81] refactor: user local library --- .../expandable_search/expandable_search.dart | 18 +- lib/main.dart | 2 +- .../local_folder/local_folder_item.dart | 206 +++---- lib/modules/library/user_local_tracks.dart | 88 ++- lib/pages/library/local_folder.dart | 566 +++++++++--------- 5 files changed, 441 insertions(+), 439 deletions(-) diff --git a/lib/components/expandable_search/expandable_search.dart b/lib/components/expandable_search/expandable_search.dart index 157e180f..0c40b843 100644 --- a/lib/components/expandable_search/expandable_search.dart +++ b/lib/components/expandable_search/expandable_search.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/extensions/context.dart'; @@ -39,11 +39,8 @@ class ExpandableSearchField extends StatelessWidget { child: TextField( focusNode: searchFocus, controller: searchController, - decoration: InputDecoration( - hintText: context.l10n.search_tracks, - isDense: true, - prefixIcon: const Icon(SpotubeIcons.search), - ), + placeholder: Text(context.l10n.search_tracks), + leading: const Icon(SpotubeIcons.search), ), ), ), @@ -69,16 +66,9 @@ class ExpandableSearchButton extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = Theme.of(context); - return IconButton( icon: icon, - style: IconButton.styleFrom( - backgroundColor: - isFiltering ? theme.colorScheme.secondaryContainer : null, - foregroundColor: isFiltering ? theme.colorScheme.secondary : null, - minimumSize: const Size(25, 25), - ), + variance: isFiltering ? ButtonVariance.secondary : ButtonVariance.outline, onPressed: () { if (isFiltering) { searchFocus.requestFocus(); diff --git a/lib/main.dart b/lib/main.dart index 57cfbd88..5b20acd8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -215,7 +215,7 @@ class Spotube extends HookConsumerWidget { theme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), - colorScheme: ColorSchemes.lightBlue(), + colorScheme: ColorSchemes.lightOrange(), surfaceOpacity: .8, surfaceBlur: 10, ), diff --git a/lib/modules/library/local_folder/local_folder_item.dart b/lib/modules/library/local_folder/local_folder_item.dart index a965a42d..84e43e96 100644 --- a/lib/modules/library/local_folder/local_folder_item.dart +++ b/lib/modules/library/local_folder/local_folder_item.dart @@ -1,18 +1,17 @@ import 'dart:math'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; + import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:path/path.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/extensions/string.dart'; -import 'package:spotube/hooks/utils/use_brightness_value.dart'; import 'package:spotube/pages/library/local_folder.dart'; import 'package:spotube/provider/local_tracks/local_tracks_provider.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; @@ -26,8 +25,6 @@ class LocalFolderItem extends HookConsumerWidget { final ThemeData(:colorScheme) = Theme.of(context); final mediaQuery = MediaQuery.of(context); - final lerpValue = useBrightnessValue(.9, .7); - final downloadFolder = ref.watch(userPreferencesProvider.select((s) => s.downloadLocation)); final cacheFolder = useFuture(UserPreferencesNotifier.getMusicCacheDir()); @@ -60,8 +57,8 @@ class LocalFolderItem extends HookConsumerWidget { final tracks = trackSnapshot.value ?? []; - return InkWell( - onTap: () { + return Button( + onPressed: () { context.goNamed( LocalLibraryPage.name, queryParameters: { @@ -71,58 +68,54 @@ class LocalFolderItem extends HookConsumerWidget { extra: folder, ); }, - borderRadius: BorderRadius.circular(8), - child: Ink( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - color: Color.lerp( - colorScheme.surfaceContainerHighest, - colorScheme.surface, - lerpValue, - ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (tracks.isEmpty) - Card( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Icon( - SpotubeIcons.folder, - size: mediaQuery.smAndDown - ? 95 - : mediaQuery.mdAndDown - ? 100 - : 142, - ), - ), - ) - else - ClipRRect( - borderRadius: BorderRadius.circular(8), - child: GridView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: max((tracks.length / 2).ceil(), 2), - ), - itemCount: tracks.length, - itemBuilder: (context, index) { - final track = tracks[index]; - return UniversalImage( - path: (track.album?.images).asUrlString( - placeholder: ImagePlaceholder.albumArt, - ), - fit: BoxFit.cover, - ); - }, - ), + style: ButtonVariance.card.copyWith( + padding: (context, states, value) { + return const EdgeInsets.all(8); + }, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (tracks.isEmpty) + Card( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Icon( + SpotubeIcons.folder, + size: mediaQuery.smAndDown + ? 95 + : mediaQuery.mdAndDown + ? 100 + : 142, ), - const Gap(8), - Stack( + ), + ) + else + ClipRRect( + borderRadius: BorderRadius.circular(8), + child: GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: max((tracks.length / 2).ceil(), 2), + ), + itemCount: tracks.length, + itemBuilder: (context, index) { + final track = tracks[index]; + return UniversalImage( + path: (track.album?.images).asUrlString( + placeholder: ImagePlaceholder.albumArt, + ), + fit: BoxFit.cover, + ); + }, + ), + ), + const Gap(8), + Stack( + children: [ + Column( + mainAxisSize: MainAxisSize.min, children: [ Center( child: Text( @@ -133,25 +126,47 @@ class LocalFolderItem extends HookConsumerWidget { : basename(folder), style: const TextStyle(fontWeight: FontWeight.bold), textAlign: TextAlign.center, + maxLines: 1, + overflow: TextOverflow.ellipsis, ), ), - if (!isDownloadFolder) - Align( - alignment: Alignment.topRight, - child: PopupMenuButton( - child: const Padding( - padding: EdgeInsets.all(3), - child: Icon(Icons.more_vert), - ), - itemBuilder: (context) { - return [ - PopupMenuItem( - child: ListTile( - leading: const Icon(SpotubeIcons.folderRemove), - iconColor: colorScheme.error, - title: + Wrap( + spacing: 2, + runSpacing: 2, + children: [ + for (final MapEntry(key: index, value: segment) + in segments.asMap().entries) + Text.rich( + TextSpan( + children: [ + if (index != 0) const TextSpan(text: "/ "), + TextSpan(text: segment), + ], + ), + maxLines: 2, + ).xSmall().muted(), + ], + ), + ], + ), + if (!isDownloadFolder && !isCacheFolder) + Align( + alignment: Alignment.topRight, + child: IconButton.ghost( + icon: const Icon(Icons.more_vert), + size: ButtonSize.small, + onPressed: () { + showDropdown( + context: context, + builder: (context) { + return DropdownMenu( + children: [ + MenuButton( + leading: Icon(SpotubeIcons.folderRemove, + color: colorScheme.destructive), + child: Text(context.l10n.remove_library_location), - onTap: () { + onPressed: (context) { final libraryLocations = ref .read(userPreferencesProvider) .localLibraryLocation; @@ -163,43 +178,18 @@ class LocalFolderItem extends HookConsumerWidget { .toList(), ); }, - ), - ) - ]; + ) + ], + ); }, - ), - ), - ], - ), - const Spacer(), - Wrap( - spacing: 2, - runSpacing: 2, - children: [ - for (final MapEntry(key: index, value: segment) - in segments.asMap().entries) - Text.rich( - TextSpan( - children: [ - if (index != 0) - TextSpan( - text: "/ ", - style: TextStyle(color: colorScheme.primary), - ), - TextSpan(text: segment), - ], - ), - style: TextStyle( - fontSize: 10, - color: colorScheme.tertiary, - ), - ), - ], - ), - const Spacer(), + ); + }, + ), + ), ], ), - ), + const Spacer(), + ], ), ); } diff --git a/lib/modules/library/user_local_tracks.dart b/lib/modules/library/user_local_tracks.dart index 23fb3be0..86b36dfb 100644 --- a/lib/modules/library/user_local_tracks.dart +++ b/lib/modules/library/user_local_tracks.dart @@ -1,9 +1,8 @@ import 'package:file_picker/file_picker.dart'; import 'package:file_selector/file_selector.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/library/local_folder/local_folder_item.dart'; @@ -58,49 +57,48 @@ class UserLocalTracks extends HookConsumerWidget { // For now, this gets all of them. ref.watch(localTracksProvider); - return LayoutBuilder(builder: (context, constrains) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 12.0), - child: Column( - children: [ - Align( - alignment: Alignment.centerRight, - child: TextButton.icon( - icon: const Icon(SpotubeIcons.folderAdd), - label: Text(context.l10n.add_library_location), - onPressed: addLocalLibraryLocation, + final locations = [ + preferences.downloadLocation, + if (cacheDir.hasData) cacheDir.data!, + ...preferences.localLibraryLocation, + ]; + + return LayoutBuilder( + builder: (context, constrains) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: Column( + children: [ + Align( + alignment: Alignment.centerRight, + child: Button.secondary( + leading: const Icon(SpotubeIcons.folderAdd), + onPressed: addLocalLibraryLocation, + child: Text(context.l10n.add_library_location), + ), + ), + const Gap(8), + Expanded( + child: GridView.builder( + gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 200, + mainAxisExtent: constrains.isXs + ? 210 + : constrains.mdAndDown + ? 280 + : 250, + crossAxisSpacing: 10, + mainAxisSpacing: 10, + ), + itemCount: locations.length, + itemBuilder: (context, index) { + return LocalFolderItem( + folder: locations[index], + ); + }, + ), + ), + ], ), - ), - const Gap(8), - Expanded( - child: GridView.builder( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 200, - mainAxisExtent: constrains.isXs - ? 210 - : constrains.mdAndDown - ? 280 - : 250, - crossAxisSpacing: 10, - mainAxisSpacing: 10, - ), - itemCount: preferences.localLibraryLocation.length + - 1 + - (cacheDir.hasData ? 1 : 0), - itemBuilder: (context, index) { - return LocalFolderItem( - folder: index == 0 - ? preferences.downloadLocation - : index == 1 && cacheDir.hasData - ? cacheDir.data! - : preferences.localLibraryLocation[index - 1], - ); - }, - ), - ), - ], - ), - ); - }); + )); } } diff --git a/lib/pages/library/local_folder.dart b/lib/pages/library/local_folder.dart index 8cfec3a8..23326c68 100644 --- a/lib/pages/library/local_folder.dart +++ b/lib/pages/library/local_folder.dart @@ -3,13 +3,16 @@ import 'dart:math'; import 'package:collection/collection.dart'; import 'package:file_picker/file_picker.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/button/back_button.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/string.dart'; import 'package:spotube/modules/library/local_folder/cache_export_dialog.dart'; import 'package:spotube/modules/library/user_local_tracks.dart'; @@ -65,7 +68,7 @@ class LocalLibraryPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme) = Theme.of(context); + final scale = context.theme.scaling; final sortBy = useState(SortBy.none); final playlist = ref.watch(audioPlayerProvider); @@ -93,282 +96,303 @@ class LocalLibraryPage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: TitleBar( - leading: const [BackButton()], - title: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - isDownloads - ? context.l10n.downloads - : isCache - ? context.l10n.cache_folder.capitalize() - : location, - style: textTheme.titleLarge, - ), - FutureBuilder( - future: directorySize, - builder: (context, snapshot) { - return Text( - "${(snapshot.data ?? 0)} GB", - style: textTheme.labelSmall, - ); - }, - ) + headers: [ + TitleBar( + padding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 0, + ), + surfaceBlur: 0, + leading: const [BackButton()], + title: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + isDownloads + ? context.l10n.downloads + : isCache + ? context.l10n.cache_folder.capitalize() + : location, + ), + FutureBuilder( + future: directorySize, + builder: (context, snapshot) { + return Text( + "${(snapshot.data ?? 0)} GB", + ).xSmall().muted(); + }, + ) + ], + ), + backgroundColor: Colors.transparent, + trailingGap: 10, + trailing: [ + if (isCache) ...[ + IconButton.outline( + size: ButtonSize.small, + icon: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(SpotubeIcons.delete), + Text(context.l10n.clear_cache) + ], + ).xSmall().iconSmall(), + onPressed: () async { + final accepted = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(context.l10n.clear_cache_confirmation), + actions: [ + Button.outline( + onPressed: () { + Navigator.of(context).pop(false); + }, + child: Text(context.l10n.decline), + ), + Button.destructive( + onPressed: () async { + Navigator.of(context).pop(true); + }, + child: Text(context.l10n.accept), + ), + ], + ), + ); + + if (accepted ?? false) return; + + final cacheDir = Directory( + await UserPreferencesNotifier.getMusicCacheDir(), + ); + + if (cacheDir.existsSync()) { + await cacheDir.delete(recursive: true); + } + }, + ), + IconButton.outline( + size: ButtonSize.small, + icon: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(SpotubeIcons.export), + Text( + context.l10n.export, + ) + ], + ).xSmall().iconSmall(), + onPressed: () async { + final exportPath = + await FilePicker.platform.getDirectoryPath(); + + if (exportPath == null) return; + final exportDirectory = Directory(exportPath); + + if (!exportDirectory.existsSync()) { + await exportDirectory.create(recursive: true); + } + + final cacheDir = Directory( + await UserPreferencesNotifier.getMusicCacheDir()); + + if (!context.mounted) return; + await showDialog( + context: context, + builder: (context) { + return LocalFolderCacheExportDialog( + cacheDir: cacheDir, + exportDir: exportDirectory, + ); + }, + ); + }, + ), + ] ], ), - backgroundColor: Colors.transparent, - trailing: [ - if (isCache) ...[ - IconButton( - iconSize: 16, - icon: Column( - mainAxisSize: MainAxisSize.min, + ], + child: LayoutBuilder( + builder: (context, constraints) => Column( children: [ - const Icon(SpotubeIcons.delete), - Text( - context.l10n.clear_cache, - style: textTheme.labelSmall, - ) - ], - ), - onPressed: () async { - final accepted = await showDialog( - context: context, - builder: (context) => AlertDialog.adaptive( - title: Text(context.l10n.clear_cache_confirmation), - actions: [ - TextButton( - onPressed: () { - Navigator.of(context).pop(false); - }, - child: Text(context.l10n.decline), - ), - TextButton( - onPressed: () async { - Navigator.of(context).pop(true); - }, - child: Text(context.l10n.accept), - ), - ], - ), - ); - - if (accepted ?? false) return; - - final cacheDir = Directory( - await UserPreferencesNotifier.getMusicCacheDir(), - ); - - if (cacheDir.existsSync()) { - await cacheDir.delete(recursive: true); - } - }, - ), - IconButton( - iconSize: 16, - icon: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(SpotubeIcons.export), - Text( - context.l10n.export, - style: textTheme.labelSmall, - ) - ], - ), - onPressed: () async { - final exportPath = - await FilePicker.platform.getDirectoryPath(); - - if (exportPath == null) return; - final exportDirectory = Directory(exportPath); - - if (!exportDirectory.existsSync()) { - await exportDirectory.create(recursive: true); - } - - final cacheDir = Directory( - await UserPreferencesNotifier.getMusicCacheDir()); - - if (!context.mounted) return; - await showDialog( - context: context, - builder: (context) { - return LocalFolderCacheExportDialog( - cacheDir: cacheDir, - exportDir: exportDirectory, - ); - }, - ); - }, - ), - ] - ], - ), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - const SizedBox(width: 5), - FilledButton( - onPressed: trackSnapshot.asData?.value != null - ? () async { - if (trackSnapshot.asData?.value.isNotEmpty == - true) { - if (!isPlaylistPlaying) { - await playLocalTracks( - ref, - trackSnapshot.asData!.value[location] ?? [], - ); - } - } - } - : null, - child: Row( - children: [ - Text(context.l10n.play), - Icon( - isPlaylistPlaying - ? SpotubeIcons.stop - : SpotubeIcons.play, - ) - ], - ), - ), - const Spacer(), - ExpandableSearchButton( - isFiltering: isFiltering.value, - onPressed: (value) => isFiltering.value = value, - searchFocus: searchFocus, - ), - const SizedBox(width: 10), - SortTracksDropdown( - value: sortBy.value, - onChanged: (value) { - sortBy.value = value; - }, - ), - const SizedBox(width: 5), - FilledButton( - child: const Icon(SpotubeIcons.refresh), - onPressed: () { - ref.invalidate(localTracksProvider); - }, - ) - ], - ), - ), - ExpandableSearchField( - searchController: searchController, - searchFocus: searchFocus, - isFiltering: isFiltering.value, - onChangeFiltering: (value) => isFiltering.value = value, - ), - trackSnapshot.when( - data: (tracks) { - final sortedTracks = useMemoized(() { - return ServiceUtils.sortTracks( - tracks[location] ?? [], sortBy.value); - }, [sortBy.value, tracks]); - - final filteredTracks = useMemoized(() { - if (searchController.text.isEmpty) { - return sortedTracks; - } - return sortedTracks - .map((e) => ( - weightedRatio( - "${e.name} - ${e.artists?.asString() ?? ""}", - searchController.text, + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + const Gap(5), + Button.primary( + onPressed: trackSnapshot.asData?.value != null + ? () async { + if (trackSnapshot + .asData?.value.isNotEmpty == + true) { + if (!isPlaylistPlaying) { + await playLocalTracks( + ref, + trackSnapshot + .asData!.value[location] ?? + [], + ); + } + } + } + : null, + leading: Icon( + isPlaylistPlaying + ? SpotubeIcons.stop + : SpotubeIcons.play, ), - e, - )) - .toList() - .sorted( - (a, b) => b.$1.compareTo(a.$1), - ) - .where((e) => e.$1 > 50) - .map((e) => e.$2) - .toList() - .toList(); - }, [searchController.text, sortedTracks]); - - if (!trackSnapshot.isLoading && filteredTracks.isEmpty) { - return const Expanded( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [NotFound()], - ), - ); - } - - return Expanded( - child: RefreshIndicator( - onRefresh: () async { - ref.invalidate(localTracksProvider); - }, - child: InterScrollbar( - controller: controller, - child: Skeletonizer( - enabled: trackSnapshot.isLoading, - child: ListView.builder( - controller: controller, - physics: const AlwaysScrollableScrollPhysics(), - itemCount: trackSnapshot.isLoading - ? 5 - : filteredTracks.length, - itemBuilder: (context, index) { - if (trackSnapshot.isLoading) { - return TrackTile( - playlist: playlist, - track: FakeData.track, - index: index, - ); - } - - final track = filteredTracks[index]; - return TrackTile( - index: index, - playlist: playlist, - track: track, - userPlaylist: false, - onTap: () async { - await playLocalTracks( - ref, - sortedTracks, - currentTrack: track, - ); - }, - ); - }, - ), + child: Text(context.l10n.play), + ), + const Spacer(), + if (constraints.smAndDown) + ExpandableSearchButton( + isFiltering: isFiltering.value, + onPressed: (value) => isFiltering.value = value, + searchFocus: searchFocus, + ) + else + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: 300 * scale, + maxHeight: 38 * scale, + ), + child: ExpandableSearchField( + isFiltering: true, + onChangeFiltering: (value) {}, + searchController: searchController, + searchFocus: searchFocus, + ), + ), + const Gap(5), + SortTracksDropdown( + value: sortBy.value, + onChanged: (value) { + sortBy.value = value; + }, + ), + const Gap(5), + IconButton.outline( + icon: const Icon(SpotubeIcons.refresh), + onPressed: () { + ref.invalidate(localTracksProvider); + }, + ) + ], ), ), - ), - ); - }, - loading: () => Expanded( - child: Skeletonizer( - enabled: true, - child: ListView.builder( - itemCount: 5, - itemBuilder: (context, index) => TrackTile( - track: FakeData.track, - index: index, - playlist: playlist, + ExpandableSearchField( + searchController: searchController, + searchFocus: searchFocus, + isFiltering: isFiltering.value, + onChangeFiltering: (value) => isFiltering.value = value, ), - ), - ), - ), - error: (error, stackTrace) => - Text(error.toString() + stackTrace.toString()), - ) - ], - )), + HookBuilder(builder: (context) { + return trackSnapshot.when( + data: (tracks) { + final sortedTracks = useMemoized(() { + return ServiceUtils.sortTracks( + tracks[location] ?? [], + sortBy.value); + }, [sortBy.value, tracks]); + + final filteredTracks = useMemoized(() { + if (searchController.text.isEmpty) { + return sortedTracks; + } + return sortedTracks + .map((e) => ( + weightedRatio( + "${e.name} - ${e.artists?.asString() ?? ""}", + searchController.text, + ), + e, + )) + .toList() + .sorted( + (a, b) => b.$1.compareTo(a.$1), + ) + .where((e) => e.$1 > 50) + .map((e) => e.$2) + .toList() + .toList(); + }, [searchController.text, sortedTracks]); + + if (!trackSnapshot.isLoading && + filteredTracks.isEmpty) { + return const Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [NotFound()], + ), + ); + } + + return Expanded( + child: RefreshTrigger( + onRefresh: () async { + // ref.invalidate(localTracksProvider); + }, + child: InterScrollbar( + controller: controller, + child: Skeletonizer( + enabled: trackSnapshot.isLoading, + child: ListView.builder( + controller: controller, + physics: + const AlwaysScrollableScrollPhysics(), + itemCount: trackSnapshot.isLoading + ? 5 + : filteredTracks.length, + itemBuilder: (context, index) { + if (trackSnapshot.isLoading) { + return TrackTile( + playlist: playlist, + track: FakeData.track, + index: index, + ); + } + + final track = filteredTracks[index]; + return TrackTile( + index: index, + playlist: playlist, + track: track, + userPlaylist: false, + onTap: () async { + await playLocalTracks( + ref, + sortedTracks, + currentTrack: track, + ); + }, + ); + }, + ), + ), + ), + ), + ); + }, + loading: () => Expanded( + child: Skeletonizer( + enabled: true, + child: ListView.builder( + itemCount: 5, + itemBuilder: (context, index) => TrackTile( + track: FakeData.track, + index: index, + playlist: playlist, + ), + ), + ), + ), + error: (error, stackTrace) => + Text(error.toString() + stackTrace.toString()), + ); + }) + ], + ))), ); } } From dd0bb01af53c7d62bc7681e17d5e4de8438a9bda Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 5 Jan 2025 16:16:57 +0600 Subject: [PATCH 33/81] refactor: generate playlist to shadcn --- lib/components/ui/button_tile.dart | 7 +- lib/l10n/app_en.arb | 4 +- .../recommendation_attribute_dials.dart | 185 ++-- .../recommendation_attribute_fields.dart | 240 ++--- .../seeds_multi_autocomplete.dart | 60 +- .../playlist_generate/simple_track_tile.dart | 10 +- lib/modules/library/user_playlists.dart | 2 +- .../playlist/playlist_create_dialog.dart | 11 +- .../playlist_generate/playlist_generate.dart | 917 +++++++++--------- .../playlist_generate_result.dart | 141 +-- untranslated_messages.json | 52 + 11 files changed, 868 insertions(+), 761 deletions(-) diff --git a/lib/components/ui/button_tile.dart b/lib/components/ui/button_tile.dart index d865b583..099691d0 100644 --- a/lib/components/ui/button_tile.dart +++ b/lib/components/ui/button_tile.dart @@ -31,8 +31,7 @@ class ButtonTile extends StatelessWidget { onPressed: onPressed, style: style.copyWith( decoration: (context, states, value) { - final decoration = ButtonVariance.outline.decoration(context, states) - as BoxDecoration; + final decoration = style.decoration(context, states) as BoxDecoration; if (selected && style == ButtonVariance.outline) { return decoration.copyWith( @@ -47,7 +46,7 @@ class ButtonTile extends StatelessWidget { return decoration; }, iconTheme: (context, states, value) { - final iconTheme = ButtonVariance.outline.iconTheme(context, states); + final iconTheme = style.iconTheme(context, states); if (selected && style == ButtonVariance.outline) { return iconTheme.copyWith( @@ -58,7 +57,7 @@ class ButtonTile extends StatelessWidget { return iconTheme; }, textStyle: (context, states, value) { - final textStyle = ButtonVariance.outline.textStyle(context, states); + final textStyle = style.textStyle(context, states); if (selected && style == ButtonVariance.outline) { return textStyle.copyWith( diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 0be79bda..45a8d78f 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -22,7 +22,7 @@ "filter_playlists": "Filter your playlists...", "liked_tracks": "Liked Tracks", "liked_tracks_description": "All your liked tracks", - "create_playlist": "Create Playlist", + "playlist": "Playlist", "create_a_playlist": "Create a playlist", "update_playlist": "Update playlist", "create": "Create", @@ -194,7 +194,7 @@ "invidious_instance": "Invidious Server Instance", "invidious_description": "The Invidious server instance to use for track matching", "invidious_warning": "Some of them might not work well. So use at your own risk", - "generate_playlist": "Generate Playlist", + "generate": "Generate", "track_exists": "Track {track} already exists", "replace_downloaded_tracks": "Replace all downloaded tracks", "skip_download_tracks": "Skip downloading all downloaded tracks", diff --git a/lib/modules/library/playlist_generate/recommendation_attribute_dials.dart b/lib/modules/library/playlist_generate/recommendation_attribute_dials.dart index d7f51ffb..564bfb55 100644 --- a/lib/modules/library/playlist_generate/recommendation_attribute_dials.dart +++ b/lib/modules/library/playlist_generate/recommendation_attribute_dials.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/library/playlist_generate/playlist_generate.dart'; @@ -29,23 +29,21 @@ class RecommendationAttributeDials extends HookWidget { @override Widget build(BuildContext context) { - final animation = useAnimationController( - duration: const Duration(milliseconds: 300), - ); - final labelStyle = Theme.of(context).textTheme.labelSmall?.copyWith( + final labelStyle = Theme.of(context).typography.small.copyWith( fontWeight: FontWeight.w500, ); final minSlider = Row( + spacing: 5, children: [ Text(context.l10n.min, style: labelStyle), Expanded( child: Slider( - value: values.min / base, + value: SliderValue.single(values.min / base), min: 0, max: 1, onChanged: (value) => onChanged(( - min: value * base, + min: value.value * base, target: values.target, max: values.max, )), @@ -55,16 +53,17 @@ class RecommendationAttributeDials extends HookWidget { ); final targetSlider = Row( + spacing: 5, children: [ Text(context.l10n.target, style: labelStyle), Expanded( child: Slider( - value: values.target / base, + value: SliderValue.single(values.target / base), min: 0, max: 1, onChanged: (value) => onChanged(( min: values.min, - target: value * base, + target: value.value * base, max: values.max, )), ), @@ -73,109 +72,111 @@ class RecommendationAttributeDials extends HookWidget { ); final maxSlider = Row( + spacing: 5, children: [ Text(context.l10n.max, style: labelStyle), Expanded( child: Slider( - value: values.max / base, + value: SliderValue.single(values.max / base), min: 0, max: 1, onChanged: (value) => onChanged(( min: values.min, target: values.target, - max: value * base, + max: value.value * base, )), ), ), ], ); - return LayoutBuilder(builder: (context, constrain) { - return Card( - child: ExpansionTile( - title: DefaultTextStyle( - style: Theme.of(context).textTheme.titleSmall!, - child: title, - ), - shape: const Border(), - leading: AnimatedBuilder( - animation: animation, - builder: (context, child) { - return Transform.rotate( - angle: (animation.value * 3.14) / 2, - child: child, - ); - }, - child: const Icon(Icons.chevron_right), - ), - trailing: Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: ToggleButtons( - borderRadius: BorderRadius.circular(8), - textStyle: labelStyle, - isSelected: [ - values == lowValues(base), - values == moderateValues(base), - values == highValues(base), - ], - onPressed: (index) { - RecommendationAttribute newValues = zeroValues; - switch (index) { - case 0: - newValues = lowValues(base); - break; - case 1: - newValues = moderateValues(base); - break; - case 2: - newValues = highValues(base); - break; - } + void onSelected(int index) { + RecommendationAttribute newValues = zeroValues; + switch (index) { + case 0: + newValues = lowValues(base); + break; + case 1: + newValues = moderateValues(base); + break; + case 2: + newValues = highValues(base); + break; + } - if (newValues == values) { - onChanged(zeroValues); - } else { - onChanged(newValues); - } - }, + if (newValues == values) { + onChanged(zeroValues); + } else { + onChanged(newValues); + } + } + + return LayoutBuilder(builder: (context, constrain) { + return Accordion( + items: [ + AccordionItem( + trigger: AccordionTrigger( + child: SizedBox( + width: double.infinity, + child: Basic( + title: title.semiBold(), + trailing: Row( + spacing: 5, + children: [ + Toggle( + value: values == lowValues(base), + onChanged: (value) => onSelected(0), + style: + const ButtonStyle.outline(size: ButtonSize.small), + child: Text(context.l10n.low), + ), + Toggle( + value: values == moderateValues(base), + onChanged: (value) => onSelected(1), + style: + const ButtonStyle.outline(size: ButtonSize.small), + child: Text(context.l10n.moderate), + ), + Toggle( + value: values == highValues(base), + onChanged: (value) => onSelected(2), + style: + const ButtonStyle.outline(size: ButtonSize.small), + child: Text(context.l10n.high), + ), + ], + ), + ), + ), + ), + content: Column( + mainAxisSize: MainAxisSize.min, children: [ - Text(context.l10n.low), - Text(" ${context.l10n.moderate} "), - Text(context.l10n.high), + if (constrain.mdAndUp) + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const SizedBox(width: 16), + Expanded(child: minSlider), + Expanded(child: targetSlider), + Expanded(child: maxSlider), + ], + ) + else + Padding( + padding: const EdgeInsets.only(left: 16), + child: Column( + children: [ + minSlider, + targetSlider, + maxSlider, + ], + ), + ), ], ), ), - onExpansionChanged: (value) { - if (value) { - animation.forward(); - } else { - animation.reverse(); - } - }, - children: [ - if (constrain.mdAndUp) - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - const SizedBox(width: 16), - Expanded(child: minSlider), - Expanded(child: targetSlider), - Expanded(child: maxSlider), - ], - ) - else - Padding( - padding: const EdgeInsets.only(left: 16), - child: Column( - children: [ - minSlider, - targetSlider, - maxSlider, - ], - ), - ), - ], - ), + ], ); }); } diff --git a/lib/modules/library/playlist_generate/recommendation_attribute_fields.dart b/lib/modules/library/playlist_generate/recommendation_attribute_fields.dart index 7feff03a..351fde1e 100644 --- a/lib/modules/library/playlist_generate/recommendation_attribute_fields.dart +++ b/lib/modules/library/playlist_generate/recommendation_attribute_fields.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/modules/library/playlist_generate/recommendation_attribute_dials.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; @@ -21,13 +21,6 @@ class RecommendationAttributeFields extends HookWidget { @override Widget build(BuildContext context) { - final animation = useAnimationController( - duration: const Duration(milliseconds: 300), - ); - final labelStyle = Theme.of(context).textTheme.labelSmall?.copyWith( - fontWeight: FontWeight.w500, - ); - final minController = useTextEditingController(text: values.min.toString()); final targetController = useTextEditingController(text: values.target.toString()); @@ -53,126 +46,133 @@ class RecommendationAttributeFields extends HookWidget { }; }, [values]); - final minField = TextField( - controller: minController, - decoration: InputDecoration( - labelText: context.l10n.min, - isDense: true, - ), - keyboardType: const TextInputType.numberWithOptions( - decimal: false, - signed: true, - ), + final minField = Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text(context.l10n.min).semiBold(), + NumberInput( + controller: minController, + allowDecimals: false, + ), + ], ); - final targetField = TextField( - controller: targetController, - decoration: InputDecoration( - labelText: context.l10n.target, - isDense: true, - ), - keyboardType: const TextInputType.numberWithOptions( - decimal: false, - signed: true, - ), + final targetField = Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text(context.l10n.target).semiBold(), + NumberInput( + controller: targetController, + allowDecimals: false, + ), + ], ); - final maxField = TextField( - controller: maxController, - decoration: InputDecoration( - labelText: context.l10n.max, - isDense: true, - ), - keyboardType: const TextInputType.numberWithOptions( - decimal: false, - signed: true, - ), + final maxField = Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text(context.l10n.max).semiBold(), + NumberInput( + controller: maxController, + allowDecimals: false, + ), + ], ); - return LayoutBuilder(builder: (context, constrain) { - return Card( - child: ExpansionTile( - title: DefaultTextStyle( - style: Theme.of(context).textTheme.titleSmall!, - child: title, - ), - shape: const Border(), - leading: AnimatedBuilder( - animation: animation, - builder: (context, child) { - return Transform.rotate( - angle: (animation.value * 3.14) / 2, - child: child, - ); - }, - child: const Icon(Icons.chevron_right), - ), - trailing: presets == null - ? const SizedBox.shrink() - : Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: ToggleButtons( - borderRadius: BorderRadius.circular(8), - textStyle: labelStyle, - isSelected: presets!.values - .map((value) => value == values) - .toList(), - onPressed: (index) { - RecommendationAttribute newValues = - presets!.values.elementAt(index); - if (newValues == values) { - onChanged(zeroValues); - minController.text = zeroValues.min.toString(); - targetController.text = zeroValues.target.toString(); - maxController.text = zeroValues.max.toString(); - } else { - onChanged(newValues); - minController.text = newValues.min.toString(); - targetController.text = newValues.target.toString(); - maxController.text = newValues.max.toString(); - } - }, - children: presets!.keys.map((key) => Text(key)).toList(), - ), - ), - onExpansionChanged: (value) { - if (value) { - animation.forward(); - } else { - animation.reverse(); - } - }, - children: [ - const SizedBox(height: 8), - if (constrain.mdAndUp) - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - const SizedBox(width: 16), - Expanded(child: minField), - const SizedBox(width: 16), - Expanded(child: targetField), - const SizedBox(width: 16), - Expanded(child: maxField), - const SizedBox(width: 16), - ], - ) - else - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Column( - children: [ - minField, - const SizedBox(height: 16), - targetField, - const SizedBox(height: 16), - maxField, - ], + void onSelected(int index) { + RecommendationAttribute newValues = presets!.values.elementAt(index); + if (newValues == values) { + onChanged(zeroValues); + minController.text = zeroValues.min.toString(); + targetController.text = zeroValues.target.toString(); + maxController.text = zeroValues.max.toString(); + } else { + onChanged(newValues); + minController.text = newValues.min.toString(); + targetController.text = newValues.target.toString(); + maxController.text = newValues.max.toString(); + } + } + + return LayoutBuilder(builder: (context, constraints) { + return Accordion( + items: [ + AccordionItem( + trigger: AccordionTrigger( + child: SizedBox( + width: double.infinity, + child: Basic( + title: title.semiBold(), + trailing: presets == null + ? const SizedBox.shrink() + : Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Row( + spacing: 5, + children: [ + for (final presetEntry in presets?.entries + .toList() ?? + >[]) + Toggle( + value: presetEntry.value == values, + style: const ButtonStyle.outline( + size: ButtonSize.small, + ), + onChanged: (value) { + onSelected( + presets!.entries.toList().indexWhere( + (s) => s.key == presetEntry.key), + ); + }, + child: Text(presetEntry.key), + ), + ], + ), + ), ), ), - const SizedBox(height: 8), - ], - ), + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 8), + if (constraints.mdAndUp) + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const SizedBox(width: 16), + Expanded(child: minField), + const SizedBox(width: 16), + Expanded(child: targetField), + const SizedBox(width: 16), + Expanded(child: maxField), + const SizedBox(width: 16), + ], + ) + else + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + minField, + const SizedBox(height: 16), + targetField, + const SizedBox(height: 16), + maxField, + ], + ), + ), + const SizedBox(height: 8), + ], + ), + ), + ], ); }); } diff --git a/lib/modules/library/playlist_generate/seeds_multi_autocomplete.dart b/lib/modules/library/playlist_generate/seeds_multi_autocomplete.dart index 73c58deb..8c19ca6c 100644 --- a/lib/modules/library/playlist_generate/seeds_multi_autocomplete.dart +++ b/lib/modules/library/playlist_generate/seeds_multi_autocomplete.dart @@ -1,8 +1,9 @@ import 'dart:async'; import 'dart:math'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' show Autocomplete; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/extensions/constrains.dart'; enum SelectedItemDisplayType { @@ -20,10 +21,13 @@ class SeedsMultiAutocomplete extends HookWidget { final Widget Function(T option) selectedSeedBuilder; final String Function(T option) displayStringForOption; - final InputDecoration? inputDecoration; final bool enabled; final SelectedItemDisplayType selectedItemDisplayType; + final Widget? placeholder; + final Widget? leading; + final Widget? trailing; + final Widget? label; const SeedsMultiAutocomplete({ super.key, @@ -32,9 +36,12 @@ class SeedsMultiAutocomplete extends HookWidget { required this.autocompleteOptionBuilder, required this.displayStringForOption, required this.selectedSeedBuilder, - this.inputDecoration, this.enabled = true, this.selectedItemDisplayType = SelectedItemDisplayType.wrap, + this.placeholder, + this.leading, + this.trailing, + this.label, }); @override @@ -61,6 +68,10 @@ class SeedsMultiAutocomplete extends HookWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ + if (label != null) ...[ + label!.semiBold(), + const Gap(8), + ], LayoutBuilder(builder: (context, constrains) { return Container( key: containerKey.value, @@ -101,13 +112,15 @@ class SeedsMultiAutocomplete extends HookWidget { focusNode, onFieldSubmitted, ) { - return TextFormField( + return TextField( controller: seedController, onChanged: (value) => textEditingController.text = value, focusNode: focusNode, - onFieldSubmitted: (_) => onFieldSubmitted(), + onSubmitted: (_) => onFieldSubmitted(), enabled: enabled, - decoration: inputDecoration, + leading: leading, + trailing: trailing, + placeholder: placeholder, ); }, ), @@ -120,22 +133,27 @@ class SeedsMultiAutocomplete extends HookWidget { runSpacing: 4, children: seeds.value.map(selectedSeedBuilder).toList(), ), - SelectedItemDisplayType.list => Card( - margin: EdgeInsets.zero, - child: Column( - children: [ - for (final seed in seeds.value) ...[ - selectedSeedBuilder(seed), - if (seeds.value.length > 1 && seed != seeds.value.last) - Divider( - color: theme.colorScheme.primaryContainer, - height: 1, - indent: 12, - endIndent: 12, + SelectedItemDisplayType.list => AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + child: seeds.value.isEmpty + ? const SizedBox.shrink() + : Card( + child: Column( + children: [ + for (final seed in seeds.value) ...[ + selectedSeedBuilder(seed), + if (seeds.value.length > 1 && + seed != seeds.value.last) + Divider( + color: theme.colorScheme.secondary, + height: 1, + indent: 12, + endIndent: 12, + ), + ], + ], ), - ], - ], - ), + ), ), }, ], diff --git a/lib/modules/library/playlist_generate/simple_track_tile.dart b/lib/modules/library/playlist_generate/simple_track_tile.dart index e6cc281f..afa723f3 100644 --- a/lib/modules/library/playlist_generate/simple_track_tile.dart +++ b/lib/modules/library/playlist_generate/simple_track_tile.dart @@ -1,9 +1,10 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/image.dart'; class SimpleTrackTile extends HookWidget { @@ -17,7 +18,7 @@ class SimpleTrackTile extends HookWidget { @override Widget build(BuildContext context) { - return ListTile( + return ButtonTile( leading: ClipRRect( borderRadius: BorderRadius.circular(8), child: UniversalImage( @@ -28,18 +29,17 @@ class SimpleTrackTile extends HookWidget { width: 40, ), ), - horizontalTitleGap: 10, - contentPadding: const EdgeInsets.symmetric(horizontal: 8), title: Text(track.name!), trailing: onDelete == null ? null - : IconButton( + : IconButton.ghost( icon: const Icon(SpotubeIcons.close), onPressed: onDelete, ), subtitle: Text( track.artists?.map((e) => e.name).join(", ") ?? track.album?.name ?? "", ), + style: ButtonVariance.ghost, ); } } diff --git a/lib/modules/library/user_playlists.dart b/lib/modules/library/user_playlists.dart index 58462bf9..06f08ab6 100644 --- a/lib/modules/library/user_playlists.dart +++ b/lib/modules/library/user_playlists.dart @@ -110,7 +110,7 @@ class UserPlaylists extends HookConsumerWidget { const Gap(10), Button.primary( leading: const Icon(SpotubeIcons.magic), - child: Text(context.l10n.generate_playlist), + child: Text(context.l10n.generate), onPressed: () { ServiceUtils.pushNamed( context, diff --git a/lib/modules/playlist/playlist_create_dialog.dart b/lib/modules/playlist/playlist_create_dialog.dart index 8b231b84..55e7ce77 100644 --- a/lib/modules/playlist/playlist_create_dialog.dart +++ b/lib/modules/playlist/playlist_create_dialog.dart @@ -16,7 +16,6 @@ import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/form/checkbox_form_field.dart'; import 'package:spotube/components/form/text_form_field.dart'; import 'package:spotube/components/image/universal_image.dart'; -import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -267,19 +266,11 @@ class PlaylistCreateDialogButton extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final mediaQuery = MediaQuery.of(context); final spotify = ref.watch(spotifyProvider); - if (mediaQuery.smAndDown) { - return IconButton.secondary( - icon: const Icon(SpotubeIcons.addFilled), - onPressed: () => showPlaylistDialog(context, spotify), - ); - } - return Button.secondary( leading: const Icon(SpotubeIcons.addFilled), - child: Text(context.l10n.create_playlist), + child: Text(context.l10n.playlist), onPressed: () => showPlaylistDialog(context, spotify), ); } diff --git a/lib/pages/library/playlist_generate/playlist_generate.dart b/lib/pages/library/playlist_generate/playlist_generate.dart index 63565362..2b1e7512 100644 --- a/lib/pages/library/playlist_generate/playlist_generate.dart +++ b/lib/pages/library/playlist_generate/playlist_generate.dart @@ -1,12 +1,15 @@ import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; + import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotify_markets.dart'; import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/modules/library/playlist_generate/multi_select_field.dart'; +import 'package:spotube/components/button/back_button.dart'; +import 'package:spotube/components/ui/button_tile.dart'; + import 'package:spotube/modules/library/playlist_generate/recommendation_attribute_dials.dart'; import 'package:spotube/modules/library/playlist_generate/recommendation_attribute_fields.dart'; import 'package:spotube/modules/library/playlist_generate/seeds_multi_autocomplete.dart'; @@ -33,7 +36,7 @@ class PlaylistGeneratorPage extends HookConsumerWidget { final spotify = ref.watch(spotifyProvider); final theme = Theme.of(context); - final textTheme = theme.textTheme; + final typography = theme.typography; final preferences = ref.watch(userPreferencesProvider); final genresCollection = ref.watch(categoryGenresProvider); @@ -59,14 +62,11 @@ class PlaylistGeneratorPage extends HookConsumerWidget { final artistAutoComplete = SeedsMultiAutocomplete( seeds: artists, enabled: enabled, - inputDecoration: InputDecoration( - labelText: context.l10n.artists, - labelStyle: textTheme.titleMedium, - helperText: context.l10n.select_up_to_count_type( - leftSeedCount, - context.l10n.artists, - ), - ), + label: Text(context.l10n.artists), + placeholder: Text(context.l10n.select_up_to_count_type( + leftSeedCount, + context.l10n.artists, + )), fetchSeeds: (textEditingValue) => spotify.search .get( textEditingValue.text, @@ -83,15 +83,15 @@ class PlaylistGeneratorPage extends HookConsumerWidget { ) .toList(), ), - autocompleteOptionBuilder: (option, onSelected) => ListTile( - leading: CircleAvatar( - backgroundImage: UniversalImage.imageProvider( + autocompleteOptionBuilder: (option, onSelected) => ButtonTile( + leading: Avatar( + initials: "O", + provider: UniversalImage.imageProvider( option.images.asUrlString( placeholder: ImagePlaceholder.artist, ), ), ), - horizontalTitleGap: 20, title: Text(option.name!), subtitle: option.genres?.isNotEmpty != true ? null @@ -101,34 +101,36 @@ class PlaylistGeneratorPage extends HookConsumerWidget { children: option.genres!.mapIndexed( (index, genre) { return Chip( - label: Text(genre), - labelStyle: textTheme.bodySmall?.copyWith( - color: theme.colorScheme.secondary, - fontWeight: FontWeight.w600, - ), - side: BorderSide.none, - backgroundColor: theme.colorScheme.secondaryContainer, + style: ButtonVariance.secondary, + child: Text(genre), ); }, ).toList(), ), - onTap: () => onSelected(option), + onPressed: () => onSelected(option), + style: ButtonVariance.ghost, ), displayStringForOption: (option) => option.name!, - selectedSeedBuilder: (artist) => Chip( - avatar: CircleAvatar( - backgroundImage: UniversalImage.imageProvider( + selectedSeedBuilder: (artist) => OutlineBadge( + leading: Avatar( + initials: artist.name!.substring(0, 1), + size: 30, + provider: UniversalImage.imageProvider( artist.images.asUrlString( placeholder: ImagePlaceholder.artist, ), ), ), - label: Text(artist.name!), - onDeleted: () { - artists.value = [ - ...artists.value..removeWhere((element) => element.id == artist.id) - ]; - }, + trailing: IconButton.ghost( + icon: const Icon(SpotubeIcons.close), + onPressed: () { + artists.value = [ + ...artists.value + ..removeWhere((element) => element.id == artist.id) + ]; + }, + ), + child: Text(artist.name!), ), ); @@ -136,14 +138,11 @@ class PlaylistGeneratorPage extends HookConsumerWidget { seeds: tracks, enabled: enabled, selectedItemDisplayType: SelectedItemDisplayType.list, - inputDecoration: InputDecoration( - labelText: context.l10n.tracks, - labelStyle: textTheme.titleMedium, - helperText: context.l10n.select_up_to_count_type( - leftSeedCount, - context.l10n.tracks, - ), - ), + label: Text(context.l10n.tracks), + placeholder: Text(context.l10n.select_up_to_count_type( + leftSeedCount, + context.l10n.tracks, + )), fetchSeeds: (textEditingValue) => spotify.search .get( textEditingValue.text, @@ -160,22 +159,23 @@ class PlaylistGeneratorPage extends HookConsumerWidget { ) .toList(), ), - autocompleteOptionBuilder: (option, onSelected) => ListTile( - leading: CircleAvatar( - backgroundImage: UniversalImage.imageProvider( + autocompleteOptionBuilder: (option, onSelected) => ButtonTile( + leading: Avatar( + initials: option.name!.substring(0, 1), + provider: UniversalImage.imageProvider( (option.album?.images).asUrlString( placeholder: ImagePlaceholder.artist, ), ), ), - horizontalTitleGap: 20, title: Text(option.name!), subtitle: Text( option.artists?.map((e) => e.name).join(", ") ?? option.album?.name ?? "", ), - onTap: () => onSelected(option), + onPressed: () => onSelected(option), + style: ButtonVariance.ghost, ), displayStringForOption: (option) => option.name!, selectedSeedBuilder: (option) => SimpleTrackTile( @@ -188,42 +188,65 @@ class PlaylistGeneratorPage extends HookConsumerWidget { ), ); - final genreSelector = MultiSelectField( - options: genresCollection.asData?.value ?? [], - selectedOptions: genres.value, - getValueForOption: (option) => option, - onSelected: (value) { + final genreSelector = MultiSelect( + value: genres.value, + searchFilter: (item, query) { + return item.toLowerCase().contains(query.toLowerCase()) ? 1 : 0; + }, + onChanged: (value) { + if (!enabled) return; genres.value = value; }, - dialogTitle: Text(context.l10n.select_genres), - label: Text(context.l10n.add_genres), - helperText: context.l10n.select_up_to_count_type( - leftSeedCount, - context.l10n.genre, + itemBuilder: (context, item) => Text(item), + searchPlaceholder: Text(context.l10n.select_genres), + orderSelectedFirst: false, + popoverAlignment: Alignment.bottomCenter, + popupConstraints: BoxConstraints( + maxHeight: MediaQuery.sizeOf(context).height * .8, ), - enabled: enabled, + placeholder: Text( + context.l10n.select_up_to_count_type( + leftSeedCount, + context.l10n.genre, + ), + ), + children: [ + for (final option in genresCollection.asData?.value ?? []) + SelectItemButton( + value: option, + child: Text(option), + ), + ], ); + final countrySelector = ValueListenableBuilder( valueListenable: market, builder: (context, value, _) { - return DropdownButtonFormField( - decoration: InputDecoration( - labelText: context.l10n.country, - labelStyle: textTheme.titleMedium, + return Select( + placeholder: Text(context.l10n.country), + value: market.value, + onChanged: (value) { + market.value = value!; + }, + searchFilter: (item, query) { + return item.name.toLowerCase().contains(query.toLowerCase()) + ? 1 + : 0; + }, + searchPlaceholder: Text(context.l10n.search), + popupConstraints: BoxConstraints( + maxHeight: MediaQuery.sizeOf(context).height * .8, ), - isExpanded: true, - items: spotifyMarkets + popoverAlignment: Alignment.bottomCenter, + itemBuilder: (context, value) => Text(value.name), + children: spotifyMarkets .map( - (country) => DropdownMenuItem( + (country) => SelectItemButton( value: country.$1, child: Text(country.$2), ), ) .toList(), - value: market.value, - onChanged: (value) { - market.value = value!; - }, ); }, ); @@ -231,395 +254,394 @@ class PlaylistGeneratorPage extends HookConsumerWidget { final controller = useScrollController(); return Scaffold( - appBar: TitleBar( - leading: const [BackButton()], - title: Text(context.l10n.generate_playlist), - ), - body: Scrollbar( + headers: [ + TitleBar( + leading: const [BackButton()], + title: Text(context.l10n.generate), + ) + ], + child: Scrollbar( controller: controller, child: Center( child: ConstrainedBox( constraints: BoxConstraints(maxWidth: Breakpoints.lg), - child: SliderTheme( - data: const SliderThemeData( - overlayShape: RoundSliderOverlayShape(), - ), - child: SafeArea( - child: LayoutBuilder(builder: (context, constrains) { - return ScrollConfiguration( - behavior: ScrollConfiguration.of(context) - .copyWith(scrollbars: false), - child: ListView( - controller: controller, - padding: const EdgeInsets.all(16), - children: [ - ValueListenableBuilder( - valueListenable: limit, - builder: (context, value, child) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - context.l10n.number_of_tracks_generate, - style: textTheme.titleMedium, - ), - Row( - children: [ - Container( - width: 40, - height: 40, - alignment: Alignment.center, - decoration: BoxDecoration( + child: SafeArea( + child: LayoutBuilder(builder: (context, constrains) { + return ScrollConfiguration( + behavior: ScrollConfiguration.of(context) + .copyWith(scrollbars: false), + child: ListView( + controller: controller, + padding: const EdgeInsets.all(16), + children: [ + ValueListenableBuilder( + valueListenable: limit, + builder: (context, value, child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + context.l10n.number_of_tracks_generate, + style: typography.semiBold, + ), + Row( + spacing: 5, + children: [ + Container( + width: 40, + height: 40, + alignment: Alignment.center, + decoration: BoxDecoration( + color: theme.colorScheme.primary + .withAlpha(25), + shape: BoxShape.circle, + ), + child: Text( + value.round().toString(), + style: typography.large.copyWith( color: theme.colorScheme.primary, - shape: BoxShape.circle, - ), - child: Text( - value.round().toString(), - style: textTheme.bodyLarge?.copyWith( - color: theme - .colorScheme.primaryContainer, - ), ), ), - Expanded( - child: Slider( - value: value.toDouble(), - min: 10, - max: 100, - divisions: 9, - label: value.round().toString(), - onChanged: (value) { - limit.value = value.round(); - }, - ), - ) - ], - ) - ], - ); - }, - ), - const SizedBox(height: 16), - if (constrains.mdAndUp) - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: countrySelector, - ), - const SizedBox(width: 16), - Expanded( - child: genreSelector, - ), + ), + Expanded( + child: Slider( + value: + SliderValue.single(value.toDouble()), + min: 10, + max: 100, + divisions: 9, + onChanged: (value) { + limit.value = value.value.round(); + }, + ), + ) + ], + ) ], - ) - else ...[ - countrySelector, - const SizedBox(height: 16), - genreSelector, - ], - const SizedBox(height: 16), - if (constrains.mdAndUp) - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: artistAutoComplete, - ), - const SizedBox(width: 16), - Expanded( - child: tracksAutocomplete, - ), - ], - ) - else ...[ - artistAutoComplete, - const SizedBox(height: 16), - tracksAutocomplete, - ], - const SizedBox(height: 16), - RecommendationAttributeDials( - title: Text(context.l10n.acousticness), - values: ( - target: target.value.acousticness?.toDouble() ?? 0, - min: min.value.acousticness?.toDouble() ?? 0, - max: max.value.acousticness?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - acousticness: value.target, - ); - min.value = min.value.copyWith( - acousticness: value.min, - ); - max.value = max.value.copyWith( - acousticness: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.danceability), - values: ( - target: target.value.danceability?.toDouble() ?? 0, - min: min.value.danceability?.toDouble() ?? 0, - max: max.value.danceability?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - danceability: value.target, - ); - min.value = min.value.copyWith( - danceability: value.min, - ); - max.value = max.value.copyWith( - danceability: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.energy), - values: ( - target: target.value.energy?.toDouble() ?? 0, - min: min.value.energy?.toDouble() ?? 0, - max: max.value.energy?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - energy: value.target, - ); - min.value = min.value.copyWith( - energy: value.min, - ); - max.value = max.value.copyWith( - energy: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.instrumentalness), - values: ( - target: - target.value.instrumentalness?.toDouble() ?? 0, - min: min.value.instrumentalness?.toDouble() ?? 0, - max: max.value.instrumentalness?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - instrumentalness: value.target, - ); - min.value = min.value.copyWith( - instrumentalness: value.min, - ); - max.value = max.value.copyWith( - instrumentalness: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.liveness), - values: ( - target: target.value.liveness?.toDouble() ?? 0, - min: min.value.liveness?.toDouble() ?? 0, - max: max.value.liveness?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - liveness: value.target, - ); - min.value = min.value.copyWith( - liveness: value.min, - ); - max.value = max.value.copyWith( - liveness: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.loudness), - values: ( - target: target.value.loudness?.toDouble() ?? 0, - min: min.value.loudness?.toDouble() ?? 0, - max: max.value.loudness?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - loudness: value.target, - ); - min.value = min.value.copyWith( - loudness: value.min, - ); - max.value = max.value.copyWith( - loudness: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.speechiness), - values: ( - target: target.value.speechiness?.toDouble() ?? 0, - min: min.value.speechiness?.toDouble() ?? 0, - max: max.value.speechiness?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - speechiness: value.target, - ); - min.value = min.value.copyWith( - speechiness: value.min, - ); - max.value = max.value.copyWith( - speechiness: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.valence), - values: ( - target: target.value.valence?.toDouble() ?? 0, - min: min.value.valence?.toDouble() ?? 0, - max: max.value.valence?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - valence: value.target, - ); - min.value = min.value.copyWith( - valence: value.min, - ); - max.value = max.value.copyWith( - valence: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.popularity), - base: 100, - values: ( - target: target.value.popularity?.toDouble() ?? 0, - min: min.value.popularity?.toDouble() ?? 0, - max: max.value.popularity?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - popularity: value.target, - ); - min.value = min.value.copyWith( - popularity: value.min, - ); - max.value = max.value.copyWith( - popularity: value.max, - ); - }, - ), - RecommendationAttributeDials( - title: Text(context.l10n.key), - base: 11, - values: ( - target: target.value.key?.toDouble() ?? 0, - min: min.value.key?.toDouble() ?? 0, - max: max.value.key?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - key: value.target, - ); - min.value = min.value.copyWith( - key: value.min, - ); - max.value = max.value.copyWith( - key: value.max, - ); - }, - ), - RecommendationAttributeFields( - title: Text(context.l10n.duration), - values: ( - max: (max.value.durationMs ?? 0) / 1000, - target: (target.value.durationMs ?? 0) / 1000, - min: (min.value.durationMs ?? 0) / 1000, - ), - onChanged: (value) { - target.value = target.value.copyWith( - durationMs: (value.target * 1000).toInt(), - ); - min.value = min.value.copyWith( - durationMs: (value.min * 1000).toInt(), - ); - max.value = max.value.copyWith( - durationMs: (value.max * 1000).toInt(), - ); - }, - presets: { - context.l10n.short: (min: 50, target: 90, max: 120), - context.l10n.medium: ( - min: 120, - target: 180, - max: 200 + ); + }, + ), + const SizedBox(height: 16), + if (constrains.mdAndUp) + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: countrySelector, ), - context.l10n.long: (min: 480, target: 560, max: 640) - }, + const SizedBox(width: 16), + Expanded( + child: genreSelector, + ), + ], + ) + else ...[ + countrySelector, + const SizedBox(height: 16), + genreSelector, + ], + const SizedBox(height: 16), + if (constrains.mdAndUp) + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: artistAutoComplete, + ), + const SizedBox(width: 16), + Expanded( + child: tracksAutocomplete, + ), + ], + ) + else ...[ + artistAutoComplete, + const SizedBox(height: 16), + tracksAutocomplete, + ], + const SizedBox(height: 16), + RecommendationAttributeDials( + title: Text(context.l10n.acousticness), + values: ( + target: target.value.acousticness?.toDouble() ?? 0, + min: min.value.acousticness?.toDouble() ?? 0, + max: max.value.acousticness?.toDouble() ?? 0, ), - RecommendationAttributeFields( - title: Text(context.l10n.tempo), - values: ( - max: max.value.tempo?.toDouble() ?? 0, - target: target.value.tempo?.toDouble() ?? 0, - min: min.value.tempo?.toDouble() ?? 0, + onChanged: (value) { + target.value = target.value.copyWith( + acousticness: value.target, + ); + min.value = min.value.copyWith( + acousticness: value.min, + ); + max.value = max.value.copyWith( + acousticness: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.danceability), + values: ( + target: target.value.danceability?.toDouble() ?? 0, + min: min.value.danceability?.toDouble() ?? 0, + max: max.value.danceability?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + danceability: value.target, + ); + min.value = min.value.copyWith( + danceability: value.min, + ); + max.value = max.value.copyWith( + danceability: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.energy), + values: ( + target: target.value.energy?.toDouble() ?? 0, + min: min.value.energy?.toDouble() ?? 0, + max: max.value.energy?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + energy: value.target, + ); + min.value = min.value.copyWith( + energy: value.min, + ); + max.value = max.value.copyWith( + energy: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.instrumentalness), + values: ( + target: + target.value.instrumentalness?.toDouble() ?? 0, + min: min.value.instrumentalness?.toDouble() ?? 0, + max: max.value.instrumentalness?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + instrumentalness: value.target, + ); + min.value = min.value.copyWith( + instrumentalness: value.min, + ); + max.value = max.value.copyWith( + instrumentalness: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.liveness), + values: ( + target: target.value.liveness?.toDouble() ?? 0, + min: min.value.liveness?.toDouble() ?? 0, + max: max.value.liveness?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + liveness: value.target, + ); + min.value = min.value.copyWith( + liveness: value.min, + ); + max.value = max.value.copyWith( + liveness: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.loudness), + values: ( + target: target.value.loudness?.toDouble() ?? 0, + min: min.value.loudness?.toDouble() ?? 0, + max: max.value.loudness?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + loudness: value.target, + ); + min.value = min.value.copyWith( + loudness: value.min, + ); + max.value = max.value.copyWith( + loudness: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.speechiness), + values: ( + target: target.value.speechiness?.toDouble() ?? 0, + min: min.value.speechiness?.toDouble() ?? 0, + max: max.value.speechiness?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + speechiness: value.target, + ); + min.value = min.value.copyWith( + speechiness: value.min, + ); + max.value = max.value.copyWith( + speechiness: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.valence), + values: ( + target: target.value.valence?.toDouble() ?? 0, + min: min.value.valence?.toDouble() ?? 0, + max: max.value.valence?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + valence: value.target, + ); + min.value = min.value.copyWith( + valence: value.min, + ); + max.value = max.value.copyWith( + valence: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.popularity), + base: 100, + values: ( + target: target.value.popularity?.toDouble() ?? 0, + min: min.value.popularity?.toDouble() ?? 0, + max: max.value.popularity?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + popularity: value.target, + ); + min.value = min.value.copyWith( + popularity: value.min, + ); + max.value = max.value.copyWith( + popularity: value.max, + ); + }, + ), + RecommendationAttributeDials( + title: Text(context.l10n.key), + base: 11, + values: ( + target: target.value.key?.toDouble() ?? 0, + min: min.value.key?.toDouble() ?? 0, + max: max.value.key?.toDouble() ?? 0, + ), + onChanged: (value) { + target.value = target.value.copyWith( + key: value.target, + ); + min.value = min.value.copyWith( + key: value.min, + ); + max.value = max.value.copyWith( + key: value.max, + ); + }, + ), + RecommendationAttributeFields( + title: Text(context.l10n.duration), + values: ( + max: (max.value.durationMs ?? 0) / 1000, + target: (target.value.durationMs ?? 0) / 1000, + min: (min.value.durationMs ?? 0) / 1000, + ), + onChanged: (value) { + target.value = target.value.copyWith( + durationMs: (value.target * 1000).toInt(), + ); + min.value = min.value.copyWith( + durationMs: (value.min * 1000).toInt(), + ); + max.value = max.value.copyWith( + durationMs: (value.max * 1000).toInt(), + ); + }, + presets: { + context.l10n.short: (min: 50, target: 90, max: 120), + context.l10n.medium: ( + min: 120, + target: 180, + max: 200 ), - onChanged: (value) { - target.value = target.value.copyWith( - tempo: value.target, - ); - min.value = min.value.copyWith( - tempo: value.min, - ); - max.value = max.value.copyWith( - tempo: value.max, - ); - }, + context.l10n.long: (min: 480, target: 560, max: 640) + }, + ), + RecommendationAttributeFields( + title: Text(context.l10n.tempo), + values: ( + max: max.value.tempo?.toDouble() ?? 0, + target: target.value.tempo?.toDouble() ?? 0, + min: min.value.tempo?.toDouble() ?? 0, ), - RecommendationAttributeFields( - title: Text(context.l10n.mode), - values: ( - max: max.value.mode?.toDouble() ?? 0, - target: target.value.mode?.toDouble() ?? 0, - min: min.value.mode?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - mode: value.target, - ); - min.value = min.value.copyWith( - mode: value.min, - ); - max.value = max.value.copyWith( - mode: value.max, - ); - }, + onChanged: (value) { + target.value = target.value.copyWith( + tempo: value.target, + ); + min.value = min.value.copyWith( + tempo: value.min, + ); + max.value = max.value.copyWith( + tempo: value.max, + ); + }, + ), + RecommendationAttributeFields( + title: Text(context.l10n.mode), + values: ( + max: max.value.mode?.toDouble() ?? 0, + target: target.value.mode?.toDouble() ?? 0, + min: min.value.mode?.toDouble() ?? 0, ), - RecommendationAttributeFields( - title: Text(context.l10n.time_signature), - values: ( - max: max.value.timeSignature?.toDouble() ?? 0, - target: target.value.timeSignature?.toDouble() ?? 0, - min: min.value.timeSignature?.toDouble() ?? 0, - ), - onChanged: (value) { - target.value = target.value.copyWith( - timeSignature: value.target, - ); - min.value = min.value.copyWith( - timeSignature: value.min, - ); - max.value = max.value.copyWith( - timeSignature: value.max, - ); - }, + onChanged: (value) { + target.value = target.value.copyWith( + mode: value.target, + ); + min.value = min.value.copyWith( + mode: value.min, + ); + max.value = max.value.copyWith( + mode: value.max, + ); + }, + ), + RecommendationAttributeFields( + title: Text(context.l10n.time_signature), + values: ( + max: max.value.timeSignature?.toDouble() ?? 0, + target: target.value.timeSignature?.toDouble() ?? 0, + min: min.value.timeSignature?.toDouble() ?? 0, ), - const SizedBox(height: 20), - FilledButton.icon( - icon: const Icon(SpotubeIcons.magic), - label: Text(context.l10n.generate_playlist), + onChanged: (value) { + target.value = target.value.copyWith( + timeSignature: value.target, + ); + min.value = min.value.copyWith( + timeSignature: value.min, + ); + max.value = max.value.copyWith( + timeSignature: value.max, + ); + }, + ), + const Gap(20), + Center( + child: Button.primary( + leading: const Icon(SpotubeIcons.magic), onPressed: artists.value.isEmpty && tracks.value.isEmpty && genres.value.isEmpty @@ -643,12 +665,13 @@ class PlaylistGeneratorPage extends HookConsumerWidget { extra: routeState, ); }, + child: Text(context.l10n.generate), ), - ], - ), - ); - }), - ), + ), + ], + ), + ); + }), ), ), ), diff --git a/lib/pages/library/playlist_generate/playlist_generate_result.dart b/lib/pages/library/playlist_generate/playlist_generate_result.dart index f44cbee7..87d6fdc9 100644 --- a/lib/pages/library/playlist_generate/playlist_generate_result.dart +++ b/lib/pages/library/playlist_generate/playlist_generate_result.dart @@ -1,9 +1,10 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/modules/library/playlist_generate/simple_track_tile.dart'; import 'package:spotube/modules/playlist/playlist_create_dialog.dart'; import 'package:spotube/components/dialogs/playlist_add_track_dialog.dart'; @@ -27,7 +28,7 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final router = GoRouter.of(context); - final scaffoldMessenger = ScaffoldMessenger.of(context); + final playlistNotifier = ref.watch(audioPlayerProvider.notifier); final generatedPlaylist = ref.watch(generatePlaylistProvider(state)); @@ -48,8 +49,10 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { (generatedPlaylist.asData?.value.length ?? 0); return Scaffold( - appBar: const TitleBar(leading: [BackButton()]), - body: generatedPlaylist.isLoading + headers: const [ + TitleBar(leading: [BackButton()]) + ], + child: generatedPlaylist.isLoading ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -74,9 +77,8 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { ), shrinkWrap: true, children: [ - FilledButton.tonalIcon( - icon: const Icon(SpotubeIcons.play), - label: Text(context.l10n.play), + Button.primary( + leading: const Icon(SpotubeIcons.play), onPressed: selectedTracks.value.isEmpty ? null : () async { @@ -90,10 +92,10 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { autoPlay: true, ); }, + child: Text(context.l10n.play), ), - FilledButton.tonalIcon( - icon: const Icon(SpotubeIcons.queueAdd), - label: Text(context.l10n.add_to_queue), + Button.primary( + leading: const Icon(SpotubeIcons.queueAdd), onPressed: selectedTracks.value.isEmpty ? null : () async { @@ -103,21 +105,25 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { ), ); if (context.mounted) { - scaffoldMessenger.showSnackBar( - SnackBar( - content: Text( - context.l10n.add_count_to_queue( - selectedTracks.value.length, + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n.add_count_to_queue( + selectedTracks.value.length, + ), ), - ), - ), + ); + }, ); } }, + child: Text(context.l10n.add_to_queue), ), - FilledButton.tonalIcon( - icon: const Icon(SpotubeIcons.addFilled), - label: Text(context.l10n.create_a_playlist), + Button.primary( + leading: const Icon(SpotubeIcons.addFilled), onPressed: selectedTracks.value.isEmpty ? null : () async { @@ -138,10 +144,10 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { ); } }, + child: Text(context.l10n.create_a_playlist), ), - FilledButton.tonalIcon( - icon: const Icon(SpotubeIcons.playlistAdd), - label: Text(context.l10n.add_to_playlist), + Button.primary( + leading: const Icon(SpotubeIcons.playlistAdd), onPressed: selectedTracks.value.isEmpty ? null : () async { @@ -161,17 +167,22 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { ); if (context.mounted && hasAdded == true) { - scaffoldMessenger.showSnackBar( - SnackBar( - content: Text( - context.l10n.add_count_to_playlist( - selectedTracks.value.length, + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n.add_count_to_playlist( + selectedTracks.value.length, + ), ), - ), - ), + ); + }, ); } }, + child: Text(context.l10n.add_to_playlist), ) ], ), @@ -185,7 +196,7 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { selectedTracks.value.length, ), ), - ElevatedButton.icon( + Button.secondary( onPressed: () { if (isAllTrackSelected) { selectedTracks.value = []; @@ -197,8 +208,8 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { []; } }, - icon: const Icon(SpotubeIcons.selectionCheck), - label: Text( + leading: const Icon(SpotubeIcons.selectionCheck), + child: Text( isAllTrackSelected ? context.l10n.deselect_all : context.l10n.select_all, @@ -207,32 +218,44 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { ], ), const SizedBox(height: 8), - Card( - margin: const EdgeInsets.all(0), - child: SafeArea( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - for (final track - in generatedPlaylist.asData?.value ?? []) - CheckboxListTile( - value: selectedTracks.value.contains(track.id), - onChanged: (value) { - if (value == true) { - selectedTracks.value.add(track.id!); - } else { - selectedTracks.value.remove(track.id); - } - selectedTracks.value = - selectedTracks.value.toList(); - }, - controlAffinity: ListTileControlAffinity.leading, - contentPadding: EdgeInsets.zero, - dense: true, - title: SimpleTrackTile(track: track), - ) - ], - ), + SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + for (final track + in generatedPlaylist.asData?.value ?? []) + Row( + spacing: 5, + children: [ + Checkbox( + state: selectedTracks.value.contains(track.id) + ? CheckboxState.checked + : CheckboxState.unchecked, + onChanged: (value) { + if (value == CheckboxState.checked) { + selectedTracks.value.add(track.id!); + } else { + selectedTracks.value.remove(track.id); + } + selectedTracks.value = + selectedTracks.value.toList(); + }, + ), + Expanded( + child: GestureDetector( + onTap: () { + selectedTracks.value.contains(track.id) + ? selectedTracks.value.remove(track.id) + : selectedTracks.value.add(track.id!); + selectedTracks.value = + selectedTracks.value.toList(); + }, + child: SimpleTrackTile(track: track), + ), + ), + ], + ) + ], ), ), ], diff --git a/untranslated_messages.json b/untranslated_messages.json index fae95f00..a31de6a2 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1,6 +1,8 @@ { "ar": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -10,7 +12,9 @@ ], "bn": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -20,7 +24,9 @@ ], "ca": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -30,7 +36,9 @@ ], "cs": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -40,7 +48,9 @@ ], "de": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -50,7 +60,9 @@ ], "es": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -60,7 +72,9 @@ ], "eu": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -70,7 +84,9 @@ ], "fa": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -80,7 +96,9 @@ ], "fi": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -90,7 +108,9 @@ ], "fr": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -100,7 +120,9 @@ ], "hi": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -110,7 +132,9 @@ ], "id": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -120,7 +144,9 @@ ], "it": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -130,7 +156,9 @@ ], "ja": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -140,7 +168,9 @@ ], "ka": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -150,7 +180,9 @@ ], "ko": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -160,7 +192,9 @@ ], "ne": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -170,7 +204,9 @@ ], "nl": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -180,7 +216,9 @@ ], "pl": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -190,7 +228,9 @@ ], "pt": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -200,7 +240,9 @@ ], "ru": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -210,7 +252,9 @@ ], "th": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -220,7 +264,9 @@ ], "tr": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -230,7 +276,9 @@ ], "uk": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -240,7 +288,9 @@ ], "vi": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", @@ -250,7 +300,9 @@ ], "zh": [ + "playlist", "no_loop", + "generate", "undo", "download_all", "add_all_to_playlist", From b7349851999995591cfad973d28807761f70019e Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 5 Jan 2025 16:32:14 +0600 Subject: [PATCH 34/81] refactor: track page --- .../adaptive/adaptive_pop_sheet_list.dart | 1 - lib/components/track_tile/track_options.dart | 112 +++++++++++------- lib/pages/track/track.dart | 79 ++++++------ 3 files changed, 112 insertions(+), 80 deletions(-) diff --git a/lib/components/adaptive/adaptive_pop_sheet_list.dart b/lib/components/adaptive/adaptive_pop_sheet_list.dart index d81ca977..95d3fae7 100644 --- a/lib/components/adaptive/adaptive_pop_sheet_list.dart +++ b/lib/components/adaptive/adaptive_pop_sheet_list.dart @@ -110,7 +110,6 @@ class AdaptivePopSheetList extends StatelessWidget { backgroundColor: context.theme.colorScheme.card, builder: (context) { return ListView.builder( - physics: const NeverScrollableScrollPhysics(), itemCount: childrenModified.length, shrinkWrap: true, itemBuilder: (context, index) { diff --git a/lib/components/track_tile/track_options.dart b/lib/components/track_tile/track_options.dart index ec2fd2f0..14514cde 100644 --- a/lib/components/track_tile/track_options.dart +++ b/lib/components/track_tile/track_options.dart @@ -1,10 +1,10 @@ import 'dart:io'; -import 'package:flutter/material.dart' hide Page; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotify/spotify.dart' hide Offset; @@ -69,16 +69,20 @@ class TrackOptions extends HookConsumerWidget { void actionShare(BuildContext context, Track track) { final data = "https://open.spotify.com/track/${track.id}"; Clipboard.setData(ClipboardData(text: data)).then((_) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - width: 300, - behavior: SnackBarBehavior.floating, - content: Text( - context.l10n.copied_to_clipboard(data), - textAlign: TextAlign.center, - ), - ), - ); + if (context.mounted) { + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n.copied_to_clipboard(data), + textAlign: TextAlign.center, + ), + ); + }, + ); + } }); } @@ -161,7 +165,6 @@ class TrackOptions extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final scaffoldMessenger = ScaffoldMessenger.of(context); final mediaQuery = MediaQuery.of(context); final router = GoRouter.of(context); final ThemeData(:colorScheme) = Theme.of(context); @@ -220,36 +223,57 @@ class TrackOptions extends HookConsumerWidget { case TrackOptionValue.addToQueue: await playback.addTrack(track); if (context.mounted) { - scaffoldMessenger.showSnackBar( - SnackBar( - content: Text( - context.l10n.added_track_to_queue(track.name!), - ), - ), + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n.added_track_to_queue(track.name!), + textAlign: TextAlign.center, + ), + ); + }, ); } break; case TrackOptionValue.playNext: playback.addTracksAtFirst([track]); - scaffoldMessenger.showSnackBar( - SnackBar( - content: Text( - context.l10n.track_will_play_next(track.name!), - ), - ), - ); + + if (context.mounted) { + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n.track_will_play_next(track.name!), + textAlign: TextAlign.center, + ), + ); + }, + ); + } break; case TrackOptionValue.removeFromQueue: playback.removeTrack(track.id!); - scaffoldMessenger.showSnackBar( - SnackBar( - content: Text( - context.l10n.removed_track_from_queue( - track.name!, - ), - ), - ), - ); + + if (context.mounted) { + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Text( + context.l10n.removed_track_from_queue( + track.name!, + ), + textAlign: TextAlign.center, + ), + ); + }, + ); + } break; case TrackOptionValue.favorite: favorites.toggleTrackLike(track); @@ -286,7 +310,10 @@ class TrackOptions extends HookConsumerWidget { case TrackOptionValue.details: showDialog( context: context, - builder: (context) => TrackDetailsDialog(track: track), + builder: (context) => ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 400), + child: TrackDetailsDialog(track: track), + ), ); break; case TrackOptionValue.download: @@ -299,8 +326,7 @@ class TrackOptions extends HookConsumerWidget { }, icon: icon ?? const Icon(SpotubeIcons.moreHorizontal), headings: [ - ListTile( - dense: true, + Basic( leading: AspectRatio( aspectRatio: 1, child: ClipRRect( @@ -316,8 +342,7 @@ class TrackOptions extends HookConsumerWidget { track.name!, maxLines: 1, overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.titleMedium, - ), + ).semiBold(), subtitle: Align( alignment: Alignment.centerLeft, child: ArtistLink( @@ -449,7 +474,7 @@ class TrackOptions extends HookConsumerWidget { leading: Assets.logos.songlinkTransparent.image( width: 22, height: 22, - color: colorScheme.onSurface.withOpacity(0.5), + color: colorScheme.foreground.withOpacity(0.5), ), child: Text(context.l10n.song_link), ), @@ -471,11 +496,6 @@ class TrackOptions extends HookConsumerWidget { adaptivePopSheetList.showDropdownMenu(context, offsetFromRect); }; - return ListTileTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: adaptivePopSheetList, - ); + return adaptivePopSheetList; } } diff --git a/lib/pages/track/track.dart b/lib/pages/track/track.dart index 30f2e998..54563bfe 100644 --- a/lib/pages/track/track.dart +++ b/lib/pages/track/track.dart @@ -1,8 +1,8 @@ import 'dart:ui'; -import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -32,7 +32,7 @@ class TrackPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme, :colorScheme) = Theme.of(context); + final ThemeData(:typography, :colorScheme) = Theme.of(context); final mediaQuery = MediaQuery.of(context); final playlist = ref.watch(audioPlayerProvider); @@ -53,12 +53,15 @@ class TrackPage extends HookConsumerWidget { } return Scaffold( - appBar: const TitleBar( - automaticallyImplyLeading: true, - backgroundColor: Colors.transparent, - ), - extendBodyBehindAppBar: true, - body: Stack( + headers: const [ + TitleBar( + automaticallyImplyLeading: true, + backgroundColor: Colors.transparent, + surfaceBlur: 0, + ) + ], + floatingHeader: true, + child: Stack( children: [ Positioned.fill( child: Container( @@ -71,7 +74,7 @@ class TrackPage extends HookConsumerWidget { ), fit: BoxFit.cover, colorFilter: ColorFilter.mode( - colorScheme.surface.withOpacity(0.5), + colorScheme.background.withOpacity(0.5), BlendMode.srcOver, ), alignment: Alignment.topCenter, @@ -89,7 +92,7 @@ class TrackPage extends HookConsumerWidget { decoration: BoxDecoration( gradient: LinearGradient( colors: [ - colorScheme.surface, + colorScheme.background, Colors.transparent, ], begin: Alignment.topCenter, @@ -125,8 +128,7 @@ class TrackPage extends HookConsumerWidget { children: [ Text( track.name!, - style: textTheme.titleLarge, - ), + ).large().semiBold(), const Gap(10), Row( mainAxisSize: MainAxisSize.min, @@ -170,9 +172,10 @@ class TrackPage extends HookConsumerWidget { if (!isActive && !playlist.tracks .containsBy(track, (t) => t.id)) - OutlinedButton.icon( - icon: const Icon(SpotubeIcons.queueAdd), - label: Text(context.l10n.queue), + Button.outline( + leading: + const Icon(SpotubeIcons.queueAdd), + child: Text(context.l10n.queue), onPressed: () { playlistNotifier.addTrack(track); }, @@ -181,27 +184,37 @@ class TrackPage extends HookConsumerWidget { if (!isActive && !playlist.tracks .containsBy(track, (t) => t.id)) - IconButton.outlined( - icon: - const Icon(SpotubeIcons.lightning), - tooltip: context.l10n.play_next, - onPressed: () { - playlistNotifier - .addTracksAtFirst([track]); - }, + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.play_next), + ), + child: IconButton.outline( + icon: const Icon( + SpotubeIcons.lightning), + onPressed: () { + playlistNotifier + .addTracksAtFirst([track]); + }, + ), ), const Gap(5), - IconButton.filled( - tooltip: isActive - ? context.l10n.pause_playback - : context.l10n.play, - icon: Icon( - isActive - ? SpotubeIcons.pause - : SpotubeIcons.play, - color: colorScheme.onPrimary, + Tooltip( + tooltip: TooltipContainer( + child: Text( + isActive + ? context.l10n.pause_playback + : context.l10n.play, + ), + ), + child: IconButton.primary( + shape: ButtonShape.circle, + icon: Icon( + isActive + ? SpotubeIcons.pause + : SpotubeIcons.play, + ), + onPressed: onPlay, ), - onPressed: onPlay, ), const Gap(5), if (mediaQuery.smAndDown) From dff8fe2e64fb334e1c77afdc24417145941c42fe Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 5 Jan 2025 16:50:04 +0600 Subject: [PATCH 35/81] chore: fix alternative source list item theme inconsistency --- lib/components/ui/button_tile.dart | 24 ++-- lib/modules/player/sibling_tracks_sheet.dart | 135 +++++++++---------- 2 files changed, 79 insertions(+), 80 deletions(-) diff --git a/lib/components/ui/button_tile.dart b/lib/components/ui/button_tile.dart index 099691d0..7318e8c4 100644 --- a/lib/components/ui/button_tile.dart +++ b/lib/components/ui/button_tile.dart @@ -9,6 +9,7 @@ class ButtonTile extends StatelessWidget { final void Function()? onPressed; final bool selected; final ButtonVariance style; + final EdgeInsets? padding; const ButtonTile({ super.key, @@ -19,6 +20,7 @@ class ButtonTile extends StatelessWidget { this.enabled = true, this.onPressed, this.selected = false, + this.padding, this.style = ButtonVariance.outline, }); @@ -30,17 +32,23 @@ class ButtonTile extends StatelessWidget { enabled: enabled, onPressed: onPressed, style: style.copyWith( + padding: padding != null ? (context, states, value) => padding! : null, decoration: (context, states, value) { final decoration = style.decoration(context, states) as BoxDecoration; - if (selected && style == ButtonVariance.outline) { - return decoration.copyWith( - border: Border.all( - color: colorScheme.primary, - width: 1.0, - ), - color: colorScheme.primary.withAlpha(25), - ); + if (selected) { + return switch (style) { + ButtonVariance.outline => decoration.copyWith( + border: Border.all( + color: colorScheme.primary, + width: 1.0, + ), + color: colorScheme.primary.withAlpha(25), + ), + ButtonVariance.ghost || _ => decoration.copyWith( + color: colorScheme.primary.withAlpha(25), + ), + }; } return decoration; diff --git a/lib/modules/player/sibling_tracks_sheet.dart b/lib/modules/player/sibling_tracks_sheet.dart index 9bd1ea22..14773156 100644 --- a/lib/modules/player/sibling_tracks_sheet.dart +++ b/lib/modules/player/sibling_tracks_sheet.dart @@ -1,14 +1,14 @@ import 'package:collection/collection.dart'; -import 'package:flutter/material.dart' show ListTile, Material, MaterialType; + import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; - import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/artist_simple.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/duration.dart'; @@ -18,7 +18,6 @@ import 'package:spotube/provider/audio_player/audio_player.dart'; import 'package:spotube/provider/audio_player/querying_track_info.dart'; import 'package:spotube/provider/server/active_sourced_track.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; - import 'package:spotube/services/sourced_track/models/source_info.dart'; import 'package:spotube/services/sourced_track/models/video_info.dart'; import 'package:spotube/services/sourced_track/sourced_track.dart'; @@ -161,40 +160,36 @@ class SiblingTracksSheet extends HookConsumerWidget { final itemBuilder = useCallback( (SourceInfo sourceInfo) { final icon = sourceInfoToIconMap[sourceInfo.runtimeType]; - return ListTile( - hoverColor: theme.colorScheme.primary.withOpacity(.1), - dense: true, - subtitleTextStyle: theme.typography.small.copyWith( - color: theme.colorScheme.mutedForeground, + return ButtonTile( + style: ButtonVariance.ghost, + padding: const EdgeInsets.symmetric(horizontal: 8), + title: Text( + sourceInfo.title, + maxLines: 2, + overflow: TextOverflow.ellipsis, ), - titleTextStyle: theme.typography.normal, - leadingAndTrailingTextStyle: theme.typography.normal, - title: Text(sourceInfo.title), - horizontalTitleGap: 0, - leading: Padding( - padding: const EdgeInsets.only(top: 8.0, right: 8.0), - child: UniversalImage( - path: sourceInfo.thumbnail, - height: 60, - width: 60, - ), - ), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5), + leading: UniversalImage( + path: sourceInfo.thumbnail, + height: 60, + width: 60, ), trailing: Text(sourceInfo.duration.toHumanReadableString()), subtitle: Row( children: [ if (icon != null) icon, - Text(" • ${sourceInfo.artist}"), + Flexible( + child: Text( + " • ${sourceInfo.artist}", + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), ], ), enabled: !isFetchingActiveTrack, selected: !isFetchingActiveTrack && sourceInfo.id == (activeTrack as SourcedTrack).sourceInfo.id, - selectedTileColor: theme.colorScheme.primary.withOpacity(.1), - selectedColor: theme.colorScheme.primary, - onTap: () { + onPressed: () { if (!isFetchingActiveTrack && sourceInfo.id != (activeTrack as SourcedTrack).sourceInfo.id) { activeTrackNotifier.swapSibling(sourceInfo); @@ -222,20 +217,17 @@ class SiblingTracksSheet extends HookConsumerWidget { child: !isSearching.value ? Text( context.l10n.alternative_track_sources, - style: theme.typography.bold, - ) - : Flexible( - child: ConstrainedBox( - constraints: BoxConstraints( - maxWidth: 320 * scale, - maxHeight: 38 * scale, - ), - child: TextField( - autofocus: true, - controller: searchController, - placeholder: Text(context.l10n.search), - style: theme.typography.bold, - ), + ).bold() + : ConstrainedBox( + constraints: BoxConstraints( + maxWidth: 320 * scale, + maxHeight: 38 * scale, + ), + child: TextField( + autofocus: true, + controller: searchController, + placeholder: Text(context.l10n.search), + style: theme.typography.bold, ), ), ), @@ -290,39 +282,38 @@ class SiblingTracksSheet extends HookConsumerWidget { FadeTransition(opacity: animation, child: child), child: InterScrollbar( controller: controller, - child: Material( - type: MaterialType.transparency, - child: switch (isSearching.value) { - false => ListView.builder( - padding: const EdgeInsets.all(8.0), - controller: controller, - itemCount: siblings.length, - itemBuilder: (context, index) => - itemBuilder(siblings[index]), - ), - true => FutureBuilder( - future: searchRequest, - builder: (context, snapshot) { - if (snapshot.hasError) { - return Center( - child: Text(snapshot.error.toString()), - ); - } else if (!snapshot.hasData) { - return const Center( - child: CircularProgressIndicator()); - } - - return ListView.builder( - padding: const EdgeInsets.all(8.0), - controller: controller, - itemCount: snapshot.data!.length, - itemBuilder: (context, index) => - itemBuilder(snapshot.data![index]), + child: switch (isSearching.value) { + false => ListView.separated( + padding: const EdgeInsets.all(8.0), + controller: controller, + itemCount: siblings.length, + separatorBuilder: (context, index) => const Gap(8), + itemBuilder: (context, index) => + itemBuilder(siblings[index]), + ), + true => FutureBuilder( + future: searchRequest, + builder: (context, snapshot) { + if (snapshot.hasError) { + return Center( + child: Text(snapshot.error.toString()), ); - }, - ), - }, - ), + } else if (!snapshot.hasData) { + return const Center( + child: CircularProgressIndicator()); + } + + return ListView.separated( + padding: const EdgeInsets.all(8.0), + controller: controller, + itemCount: snapshot.data!.length, + separatorBuilder: (context, index) => const Gap(8), + itemBuilder: (context, index) => + itemBuilder(snapshot.data![index]), + ); + }, + ), + }, ), ), ), From e6408ccc0d5153f634af991ea1ef3f138d30b49a Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 5 Jan 2025 17:11:58 +0600 Subject: [PATCH 36/81] refactor: genre home section --- .../fallbacks/anonymous_fallback.dart | 4 +- lib/components/fallbacks/not_found.dart | 8 +- lib/modules/home/sections/genres.dart | 88 +++++-------------- lib/pages/lastfm_login/lastfm_login.dart | 19 ++-- 4 files changed, 39 insertions(+), 80 deletions(-) diff --git a/lib/components/fallbacks/anonymous_fallback.dart b/lib/components/fallbacks/anonymous_fallback.dart index 62ed8ddd..cd7a218f 100644 --- a/lib/components/fallbacks/anonymous_fallback.dart +++ b/lib/components/fallbacks/anonymous_fallback.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/settings/settings.dart'; @@ -28,7 +28,7 @@ class AnonymousFallback extends ConsumerWidget { children: [ Text(context.l10n.not_logged_in), const SizedBox(height: 10), - FilledButton( + Button.primary( child: Text(context.l10n.login_with_spotify), onPressed: () => ServiceUtils.pushNamed(context, SettingsPage.name), ) diff --git a/lib/components/fallbacks/not_found.dart b/lib/components/fallbacks/not_found.dart index ce168f17..d35a4b50 100644 --- a/lib/components/fallbacks/not_found.dart +++ b/lib/components/fallbacks/not_found.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/extensions/context.dart'; @@ -8,7 +8,6 @@ class NotFound extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = Theme.of(context); final widgets = [ SizedBox( height: 150, @@ -19,11 +18,10 @@ class NotFound extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(context.l10n.nothing_found, style: theme.textTheme.titleLarge), + Text(context.l10n.nothing_found).large().semiBold(), Text( context.l10n.the_box_is_empty, - style: theme.textTheme.titleMedium, - ), + ).semiBold(), ], ), ]; diff --git a/lib/modules/home/sections/genres.dart b/lib/modules/home/sections/genres.dart index 574f3294..f0ed1fb3 100644 --- a/lib/modules/home/sections/genres.dart +++ b/lib/modules/home/sections/genres.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -8,7 +6,6 @@ import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/fake.dart'; -import 'package:spotube/collections/gradients.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; @@ -84,70 +81,33 @@ class HomeGenresSection extends HookConsumerWidget { final category = categories.elementAtOrNull(index) ?? FakeData.category; - return HookBuilder(builder: (context) { - final (:gradient, :textColor) = useMemoized( - () { - final gradient = - gradients[Random().nextInt(gradients.length)]; - final text = gradient.colors - .take(2) - .any((c) => c.computeLuminance() > 0.5) - ? Colors.gray[900] - : Colors.white; - return ( - gradient: LinearGradient( - colors: gradient.colors - .map((c) => c.withAlpha((0.8 * 255).ceil())) - .toList(), - ), - textColor: text + return Button( + style: ButtonVariance.secondary.copyWith( + padding: (context, states, value) { + return EdgeInsets.zero; + }, + ), + onPressed: () {}, + child: CardImage( + onPressed: () { + context.pushNamed( + GenrePlaylistsPage.name, + pathParameters: { + "categoryId": category.id!, + }, + extra: category, ); }, - [], - ); - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: () { - context.pushNamed( - GenrePlaylistsPage.name, - pathParameters: { - "categoryId": category.id!, - }, - extra: category, - ); - }, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - image: DecorationImage( - image: UniversalImage.imageProvider( - category.icons!.first.url!, - ), - fit: BoxFit.cover, - ), - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - color: context.theme.colorScheme.muted, - gradient: - categoriesQuery.isLoading ? null : gradient, - ), - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Align( - alignment: Alignment.centerLeft, - child: Text( - category.name!, - style: context.theme.typography.large, - ), - ), - ), - ), + direction: Axis.horizontal, + image: UniversalImage( + path: category.icons!.first.url!, + fit: BoxFit.cover, + height: 50, + width: 50, ), - ); - }); + title: Text(category.name!), + ), + ); }, ), ), diff --git a/lib/pages/lastfm_login/lastfm_login.dart b/lib/pages/lastfm_login/lastfm_login.dart index d5466544..89b8270a 100644 --- a/lib/pages/lastfm_login/lastfm_login.dart +++ b/lib/pages/lastfm_login/lastfm_login.dart @@ -36,14 +36,15 @@ class LastFMLoginPage extends HookConsumerWidget { ), ), ], - child: SingleChildScrollView( - child: Container( - constraints: const BoxConstraints(maxWidth: 400), - alignment: Alignment.center, - padding: const EdgeInsets.all(16), - child: Card( - child: Padding( - padding: const EdgeInsets.all(16.0).copyWith(top: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + constraints: const BoxConstraints(maxWidth: 400), + alignment: Alignment.center, + padding: const EdgeInsets.all(16), + child: Card( + padding: const EdgeInsets.all(16.0), child: Form( onSubmit: (context, values) async { try { @@ -136,7 +137,7 @@ class LastFMLoginPage extends HookConsumerWidget { ), ), ), - ), + ], ), ); } From 6dd9b753b01dee248362680999a06e962e23432e Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Mon, 6 Jan 2025 14:13:53 +0600 Subject: [PATCH 37/81] refactor: migrate stats to shadcn --- lib/components/links/anchor_button.dart | 2 +- lib/modules/player/player_controls.dart | 8 +- lib/modules/root/update_dialog.dart | 4 +- lib/modules/stats/common/album_item.dart | 9 +- lib/modules/stats/common/artist_item.dart | 14 +- lib/modules/stats/common/playlist_item.dart | 9 +- lib/modules/stats/common/track_item.dart | 9 +- lib/modules/stats/summary/summary.dart | 6 +- lib/modules/stats/summary/summary_card.dart | 26 ++-- lib/modules/stats/top/top.dart | 164 ++++++++++---------- lib/pages/stats/albums/albums.dart | 14 +- lib/pages/stats/artists/artists.dart | 14 +- lib/pages/stats/fees/fees.dart | 68 ++++---- lib/pages/stats/minutes/minutes.dart | 15 +- lib/pages/stats/playlists/playlists.dart | 14 +- lib/pages/stats/stats.dart | 9 +- lib/pages/stats/streams/streams.dart | 15 +- 17 files changed, 206 insertions(+), 194 deletions(-) diff --git a/lib/components/links/anchor_button.dart b/lib/components/links/anchor_button.dart index c6f0b889..a0b3fa73 100644 --- a/lib/components/links/anchor_button.dart +++ b/lib/components/links/anchor_button.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; class AnchorButton extends HookWidget { final String text; diff --git a/lib/modules/player/player_controls.dart b/lib/modules/player/player_controls.dart index acc3064e..964ff54f 100644 --- a/lib/modules/player/player_controls.dart +++ b/lib/modules/player/player_controls.dart @@ -148,7 +148,10 @@ class PlayerControls extends HookConsumerWidget { ), ), child: IconButton( - icon: const Icon(SpotubeIcons.shuffle), + icon: Icon( + SpotubeIcons.shuffle, + color: shuffled ? theme.colorScheme.primary : null, + ), variance: shuffled ? ButtonVariance.secondary : ButtonVariance.ghost, @@ -228,6 +231,9 @@ class PlayerControls extends HookConsumerWidget { loopMode == PlaylistMode.single ? SpotubeIcons.repeatOne : SpotubeIcons.repeat, + color: loopMode != PlaylistMode.none + ? theme.colorScheme.primary + : null, ), variance: loopMode == PlaylistMode.single || loopMode == PlaylistMode.loop diff --git a/lib/modules/root/update_dialog.dart b/lib/modules/root/update_dialog.dart index 27b857df..4aa2fd13 100644 --- a/lib/modules/root/update_dialog.dart +++ b/lib/modules/root/update_dialog.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/links/anchor_button.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:spotube/extensions/context.dart'; @@ -19,7 +19,7 @@ class RootAppUpdateDialog extends StatelessWidget { return AlertDialog( title: Text(context.l10n.spotube_has_an_update), actions: [ - FilledButton( + Button.primary( child: Text(context.l10n.download_now), onPressed: () => launchUrlString( nightlyBuildNum != null ? nightlyUrl : url, diff --git a/lib/modules/stats/common/album_item.dart b/lib/modules/stats/common/album_item.dart index eec68717..0920baae 100644 --- a/lib/modules/stats/common/album_item.dart +++ b/lib/modules/stats/common/album_item.dart @@ -1,5 +1,6 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/modules/album/album_card.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/links/artist_link.dart'; @@ -14,8 +15,8 @@ class StatsAlbumItem extends StatelessWidget { @override Widget build(BuildContext context) { - return ListTile( - horizontalTitleGap: 8, + return ButtonTile( + style: ButtonVariance.ghost, leading: ClipRRect( borderRadius: BorderRadius.circular(4), child: UniversalImage( @@ -47,7 +48,7 @@ class StatsAlbumItem extends StatelessWidget { ], ), trailing: info, - onTap: () { + onPressed: () { ServiceUtils.pushNamed( context, AlbumPage.name, diff --git a/lib/modules/stats/common/artist_item.dart b/lib/modules/stats/common/artist_item.dart index 7e7281da..26691ba4 100644 --- a/lib/modules/stats/common/artist_item.dart +++ b/lib/modules/stats/common/artist_item.dart @@ -1,6 +1,7 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/image/universal_image.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/pages/artist/artist.dart'; import 'package:spotube/utils/service_utils.dart'; @@ -16,18 +17,19 @@ class StatsArtistItem extends StatelessWidget { @override Widget build(BuildContext context) { - return ListTile( + return ButtonTile( + style: ButtonVariance.ghost, title: Text(artist.name!), - horizontalTitleGap: 8, - leading: CircleAvatar( - backgroundImage: UniversalImage.imageProvider( + leading: Avatar( + initials: artist.name!.substring(0, 1), + provider: UniversalImage.imageProvider( (artist.images).asUrlString( placeholder: ImagePlaceholder.artist, ), ), ), trailing: info, - onTap: () { + onPressed: () { ServiceUtils.pushNamed( context, ArtistPage.name, diff --git a/lib/modules/stats/common/playlist_item.dart b/lib/modules/stats/common/playlist_item.dart index 515c97b3..3859db6b 100644 --- a/lib/modules/stats/common/playlist_item.dart +++ b/lib/modules/stats/common/playlist_item.dart @@ -1,6 +1,7 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/image/universal_image.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/extensions/string.dart'; import 'package:spotube/pages/playlist/playlist.dart'; @@ -14,8 +15,8 @@ class StatsPlaylistItem extends StatelessWidget { @override Widget build(BuildContext context) { - return ListTile( - horizontalTitleGap: 8, + return ButtonTile( + style: ButtonVariance.ghost, leading: ClipRRect( borderRadius: BorderRadius.circular(4), child: UniversalImage( @@ -33,7 +34,7 @@ class StatsPlaylistItem extends StatelessWidget { overflow: TextOverflow.ellipsis, ), trailing: info, - onTap: () { + onPressed: () { ServiceUtils.pushNamed( context, PlaylistPage.name, diff --git a/lib/modules/stats/common/track_item.dart b/lib/modules/stats/common/track_item.dart index 44e81340..8f0f5b8d 100644 --- a/lib/modules/stats/common/track_item.dart +++ b/lib/modules/stats/common/track_item.dart @@ -1,7 +1,8 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/links/artist_link.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/pages/track/track.dart'; import 'package:spotube/utils/service_utils.dart'; @@ -17,8 +18,8 @@ class StatsTrackItem extends StatelessWidget { @override Widget build(BuildContext context) { - return ListTile( - horizontalTitleGap: 8, + return ButtonTile( + style: ButtonVariance.ghost, leading: ClipRRect( borderRadius: BorderRadius.circular(4), child: UniversalImage( @@ -42,7 +43,7 @@ class StatsTrackItem extends StatelessWidget { ), ), trailing: info, - onTap: () { + onPressed: () { ServiceUtils.pushNamed( context, TrackPage.name, diff --git a/lib/modules/stats/summary/summary.dart b/lib/modules/stats/summary/summary.dart index 46068fec..351b0264 100644 --- a/lib/modules/stats/summary/summary.dart +++ b/lib/modules/stats/summary/summary.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/collections/formatters.dart'; @@ -48,7 +48,7 @@ class StatsPageSummarySection extends HookConsumerWidget { title: summaryData.duration.inMinutes.toDouble(), unit: context.l10n.summary_minutes, description: context.l10n.summary_listened_to_music, - color: Colors.purple, + color: Colors.indigo, onTap: () { ServiceUtils.pushNamed(context, StatsMinutesPage.name); }, @@ -57,7 +57,7 @@ class StatsPageSummarySection extends HookConsumerWidget { title: summaryData.tracks.toDouble(), unit: context.l10n.summary_songs, description: context.l10n.summary_streamed_overall, - color: Colors.lightBlue, + color: Colors.blue, onTap: () { ServiceUtils.pushNamed(context, StatsStreamsPage.name); }, diff --git a/lib/modules/stats/summary/summary_card.dart b/lib/modules/stats/summary/summary_card.dart index 243c50e8..e78dd080 100644 --- a/lib/modules/stats/summary/summary_card.dart +++ b/lib/modules/stats/summary/summary_card.dart @@ -1,6 +1,7 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; +import 'package:flutter/foundation.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/formatters.dart'; class SummaryCard extends StatelessWidget { @@ -9,7 +10,7 @@ class SummaryCard extends StatelessWidget { final String description; final VoidCallback? onTap; - final MaterialColor color; + final ColorShades color; SummaryCard({ super.key, @@ -31,15 +32,18 @@ class SummaryCard extends StatelessWidget { @override Widget build(BuildContext context) { - final ThemeData(:textTheme, :brightness) = Theme.of(context); + final ThemeData(:typography, :brightness) = Theme.of(context); final descriptionNewLines = description.split("").where((s) => s == "\n"); return Card( - color: brightness == Brightness.dark ? color.shade100 : color.shade50, - child: InkWell( - borderRadius: BorderRadius.circular(16), - onTap: onTap, + fillColor: brightness == Brightness.dark ? color.shade100 : color.shade50, + filled: true, + borderColor: color, + padding: EdgeInsets.zero, + borderRadius: context.theme.borderRadiusLg, + child: Button.ghost( + onPressed: onTap, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 15), child: Column( @@ -52,13 +56,13 @@ class SummaryCard extends StatelessWidget { children: [ TextSpan( text: title, - style: textTheme.headlineLarge?.copyWith( + style: typography.h2.copyWith( color: color.shade900, ), ), TextSpan( text: " $unit", - style: textTheme.titleMedium?.copyWith( + style: typography.semiBold.copyWith( color: color.shade900, ), ), @@ -73,7 +77,7 @@ class SummaryCard extends StatelessWidget { ? descriptionNewLines.length + 1 : 1, minFontSize: 9, - style: textTheme.labelMedium!.copyWith( + style: typography.small.copyWith( color: color.shade900, ), ), diff --git a/lib/modules/stats/top/top.dart b/lib/modules/stats/top/top.dart index 5c2cfbf9..8e9134c7 100644 --- a/lib/modules/stats/top/top.dart +++ b/lib/modules/stats/top/top.dart @@ -1,6 +1,8 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/modules/stats/top/albums.dart'; import 'package:spotube/modules/stats/top/artists.dart'; import 'package:spotube/modules/stats/top/tracks.dart'; @@ -13,94 +15,90 @@ class StatsPageTopSection extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final tabController = useTabController(initialLength: 3); + final selectedIndex = useState(0); final historyDuration = ref.watch(playbackHistoryTopDurationProvider); final historyDurationNotifier = ref.watch(playbackHistoryTopDurationProvider.notifier); - return SliverMainAxisGroup( - slivers: [ - SliverAppBar( - floating: true, - flexibleSpace: TabBar( - controller: tabController, - tabs: [ - Tab( - child: Padding( - padding: const EdgeInsets.all(5), - child: Text(context.l10n.top_tracks), - ), - ), - Tab( - child: Padding( - padding: const EdgeInsets.all(5), - child: Text(context.l10n.top_artists), - ), - ), - Tab( - child: Padding( - padding: const EdgeInsets.all(5), - child: Text(context.l10n.top_albums), - ), - ), - ], + final translations = { + HistoryDuration.days7: context.l10n.this_week, + HistoryDuration.days30: context.l10n.this_month, + HistoryDuration.months6: context.l10n.last_6_months, + HistoryDuration.year: context.l10n.this_year, + HistoryDuration.years2: context.l10n.last_2_years, + HistoryDuration.allTime: context.l10n.all_time, + }; + + final dropdown = Select( + popupConstraints: const BoxConstraints(maxWidth: 150), + popupWidthConstraint: PopoverConstraint.flexible, + padding: const EdgeInsets.all(4), + borderRadius: BorderRadius.circular(4), + value: historyDuration, + onChanged: (value) { + if (value == null) return; + historyDurationNotifier.update((_) => value); + }, + itemBuilder: (context, item) => Text(translations[item]!), + children: [ + for (final item in HistoryDuration.values) + SelectItemButton( + value: item, + child: Text(translations[item]!), ), - ), - SliverToBoxAdapter( - child: Align( - alignment: Alignment.centerRight, - child: DropdownButton( - style: Theme.of(context).textTheme.bodySmall!, - isDense: true, - padding: const EdgeInsets.all(4), - borderRadius: BorderRadius.circular(4), - underline: const SizedBox(), - value: historyDuration, - onChanged: (value) { - if (value == null) return; - historyDurationNotifier.update((_) => value); - }, - icon: const Icon(Icons.arrow_drop_down), - items: [ - DropdownMenuItem( - value: HistoryDuration.days7, - child: Text(context.l10n.this_week), - ), - DropdownMenuItem( - value: HistoryDuration.days30, - child: Text(context.l10n.this_month), - ), - DropdownMenuItem( - value: HistoryDuration.months6, - child: Text(context.l10n.last_6_months), - ), - DropdownMenuItem( - value: HistoryDuration.year, - child: Text(context.l10n.this_year), - ), - DropdownMenuItem( - value: HistoryDuration.years2, - child: Text(context.l10n.last_2_years), - ), - DropdownMenuItem( - value: HistoryDuration.allTime, - child: Text(context.l10n.all_time), - ), - ], - ), - ), - ), - ListenableBuilder( - listenable: tabController, - builder: (context, _) { - return switch (tabController.index) { - 1 => const TopArtists(), - 2 => const TopAlbums(), - _ => const TopTracks(), - }; - }, - ), ], ); + + return SliverLayoutBuilder(builder: (context, constraints) { + return SliverMainAxisGroup( + slivers: [ + SliverAppBar( + floating: true, + elevation: 0, + backgroundColor: context.theme.colorScheme.background, + flexibleSpace: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + TabList( + index: selectedIndex.value, + children: [ + TabButton( + child: Text(context.l10n.top_tracks), + onPressed: () => selectedIndex.value = 0, + ), + TabButton( + child: Text(context.l10n.top_artists), + onPressed: () => selectedIndex.value = 1, + ), + TabButton( + child: Text(context.l10n.top_albums), + onPressed: () => selectedIndex.value = 2, + ), + ], + ), + if (constraints.mdAndUp) ...[ + const Spacer(), + dropdown, + ] + ], + ), + ), + ), + if (constraints.smAndDown) + SliverToBoxAdapter( + child: Align( + alignment: Alignment.centerRight, + child: dropdown, + ), + ), + switch (selectedIndex.value) { + 1 => const TopArtists(), + 2 => const TopAlbums(), + _ => const TopTracks(), + }, + ], + ); + }); } } diff --git a/lib/pages/stats/albums/albums.dart b/lib/pages/stats/albums/albums.dart index b424cd70..eee6694b 100644 --- a/lib/pages/stats/albums/albums.dart +++ b/lib/pages/stats/albums/albums.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/formatters.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -25,11 +25,13 @@ class StatsAlbumsPage extends HookConsumerWidget { final albumsData = topAlbums.asData?.value.items ?? []; return Scaffold( - appBar: TitleBar( - automaticallyImplyLeading: true, - title: Text(context.l10n.albums), - ), - body: Skeletonizer( + headers: [ + TitleBar( + automaticallyImplyLeading: true, + title: Text(context.l10n.albums), + ) + ], + child: Skeletonizer( enabled: topAlbums.isLoading && !topAlbums.isLoadingNextPage, child: InfiniteList( onFetchData: () async { diff --git a/lib/pages/stats/artists/artists.dart b/lib/pages/stats/artists/artists.dart index 468ddabb..3a719725 100644 --- a/lib/pages/stats/artists/artists.dart +++ b/lib/pages/stats/artists/artists.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/formatters.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -28,11 +28,13 @@ class StatsArtistsPage extends HookConsumerWidget { () => topTracks.asData?.value.artists ?? [], [topTracks.asData?.value]); return Scaffold( - appBar: TitleBar( - automaticallyImplyLeading: true, - title: Text(context.l10n.artists), - ), - body: Skeletonizer( + headers: [ + TitleBar( + automaticallyImplyLeading: true, + title: Text(context.l10n.artists), + ) + ], + child: Skeletonizer( enabled: topTracks.isLoading && !topTracks.isLoadingNextPage, child: InfiniteList( onFetchData: () async { diff --git a/lib/pages/stats/fees/fees.dart b/lib/pages/stats/fees/fees.dart index 1bbcb103..14f432d6 100644 --- a/lib/pages/stats/fees/fees.dart +++ b/lib/pages/stats/fees/fees.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:sliver_tools/sliver_tools.dart'; import 'package:spotube/collections/formatters.dart'; @@ -20,7 +20,6 @@ class StatsStreamFeesPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme, :hintColor) = Theme.of(context); final duration = useState(HistoryDuration.days30); final topTracks = ref.watch( @@ -40,12 +39,23 @@ class StatsStreamFeesPage extends HookConsumerWidget { [artistsData], ); + final translations = { + HistoryDuration.days7: context.l10n.this_week, + HistoryDuration.days30: context.l10n.this_month, + HistoryDuration.months6: context.l10n.last_6_months, + HistoryDuration.year: context.l10n.this_year, + HistoryDuration.years2: context.l10n.last_2_years, + HistoryDuration.allTime: context.l10n.all_time, + }; + return Scaffold( - appBar: TitleBar( - automaticallyImplyLeading: true, - title: Text(context.l10n.streaming_fees_hypothetical), - ), - body: CustomScrollView( + headers: [ + TitleBar( + automaticallyImplyLeading: true, + title: Text(context.l10n.streaming_fees_hypothetical), + ) + ], + child: CustomScrollView( slivers: [ SliverCrossAxisConstrained( maxCrossAxisExtent: 600, @@ -55,10 +65,7 @@ class StatsStreamFeesPage extends HookConsumerWidget { sliver: SliverToBoxAdapter( child: Text( context.l10n.spotify_hipotetical_calculation, - style: textTheme.bodySmall?.copyWith( - color: hintColor, - ), - ), + ).small().muted(), ), ), ), @@ -70,39 +77,22 @@ class StatsStreamFeesPage extends HookConsumerWidget { children: [ Text( context.l10n.total_money(usdFormatter.format(total)), - style: textTheme.titleLarge, - ), - DropdownButton( + ).semiBold().large(), + Select( value: duration.value, onChanged: (value) { if (value == null) return; duration.value = value; }, - items: [ - DropdownMenuItem( - value: HistoryDuration.days7, - child: Text(context.l10n.this_week), - ), - DropdownMenuItem( - value: HistoryDuration.days30, - child: Text(context.l10n.this_month), - ), - DropdownMenuItem( - value: HistoryDuration.months6, - child: Text(context.l10n.last_6_months), - ), - DropdownMenuItem( - value: HistoryDuration.year, - child: Text(context.l10n.this_year), - ), - DropdownMenuItem( - value: HistoryDuration.years2, - child: Text(context.l10n.last_2_years), - ), - DropdownMenuItem( - value: HistoryDuration.allTime, - child: Text(context.l10n.all_time), - ), + itemBuilder: (context, value) => Text(translations[value]!), + constraints: const BoxConstraints(maxWidth: 150), + popupWidthConstraint: PopoverConstraint.anchorMaxSize, + children: [ + for (final entry in translations.entries) + SelectItemButton( + value: entry.key, + child: Text(entry.value), + ), ], ), ], diff --git a/lib/pages/stats/minutes/minutes.dart b/lib/pages/stats/minutes/minutes.dart index f6cfafca..39438b47 100644 --- a/lib/pages/stats/minutes/minutes.dart +++ b/lib/pages/stats/minutes/minutes.dart @@ -1,6 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/formatters.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -28,11 +27,13 @@ class StatsMinutesPage extends HookConsumerWidget { final tracksData = topTracks.asData?.value.items ?? []; return Scaffold( - appBar: TitleBar( - title: Text(context.l10n.minutes_listened), - automaticallyImplyLeading: true, - ), - body: Skeletonizer( + headers: [ + TitleBar( + title: Text(context.l10n.minutes_listened), + automaticallyImplyLeading: true, + ) + ], + child: Skeletonizer( enabled: topTracks.isLoading && !topTracks.isLoadingNextPage, child: InfiniteList( separatorBuilder: (context, index) => const Gap(8), diff --git a/lib/pages/stats/playlists/playlists.dart b/lib/pages/stats/playlists/playlists.dart index 53885570..f5d7a285 100644 --- a/lib/pages/stats/playlists/playlists.dart +++ b/lib/pages/stats/playlists/playlists.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/formatters.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -26,11 +26,13 @@ class StatsPlaylistsPage extends HookConsumerWidget { final playlistsData = topPlaylists.asData?.value.items ?? []; return Scaffold( - appBar: TitleBar( - automaticallyImplyLeading: true, - title: Text(context.l10n.playlists), - ), - body: Skeletonizer( + headers: [ + TitleBar( + automaticallyImplyLeading: true, + title: Text(context.l10n.playlists), + ) + ], + child: Skeletonizer( enabled: topPlaylists.isLoading && !topPlaylists.isLoadingNextPage, child: InfiniteList( onFetchData: () async { diff --git a/lib/pages/stats/stats.dart b/lib/pages/stats/stats.dart index 9c35df63..a17e7562 100644 --- a/lib/pages/stats/stats.dart +++ b/lib/pages/stats/stats.dart @@ -1,6 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/modules/stats/summary/summary.dart'; import 'package:spotube/modules/stats/top/top.dart'; @@ -16,8 +15,10 @@ class StatsPage extends HookConsumerWidget { return SafeArea( bottom: false, child: Scaffold( - appBar: kIsMacOS || kIsMobile ? null : const TitleBar(), - body: CustomScrollView( + headers: [ + if (kIsWindows || kIsLinux) const TitleBar(), + ], + child: CustomScrollView( slivers: [ if (kIsMacOS) const SliverGap(20), const StatsPageSummarySection(), diff --git a/lib/pages/stats/streams/streams.dart b/lib/pages/stats/streams/streams.dart index b835b3a6..2c2e0c9b 100644 --- a/lib/pages/stats/streams/streams.dart +++ b/lib/pages/stats/streams/streams.dart @@ -1,6 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/formatters.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -28,11 +27,13 @@ class StatsStreamsPage extends HookConsumerWidget { final tracksData = topTracks.asData?.value.items ?? []; return Scaffold( - appBar: TitleBar( - title: Text(context.l10n.streamed_songs), - automaticallyImplyLeading: true, - ), - body: Skeletonizer( + headers: [ + TitleBar( + title: Text(context.l10n.streamed_songs), + automaticallyImplyLeading: true, + ) + ], + child: Skeletonizer( enabled: topTracks.isLoading && !topTracks.isLoadingNextPage, child: InfiniteList( separatorBuilder: (context, index) => const Gap(8), From bf94a490bbb4d88c028807522f636a349459160e Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Mon, 6 Jan 2025 20:45:37 +0600 Subject: [PATCH 38/81] refactor: genres section --- lib/l10n/app_en.arb | 3 +- lib/modules/home/sections/genres.dart | 217 ++++++++++++++++++++------ lib/utils/service_utils.dart | 14 +- untranslated_messages.json | 78 ++++++--- 4 files changed, 236 insertions(+), 76 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 45a8d78f..c95ec54f 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -408,5 +408,6 @@ "add_all_to_playlist": "Add all to playlist", "add_all_to_queue": "Add all to queue", "play_all_next": "Play all next", - "pause": "Pause" + "pause": "Pause", + "view_all": "View all" } \ No newline at end of file diff --git a/lib/modules/home/sections/genres.dart b/lib/modules/home/sections/genres.dart index f0ed1fb3..57006b59 100644 --- a/lib/modules/home/sections/genres.dart +++ b/lib/modules/home/sections/genres.dart @@ -4,14 +4,16 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; -import 'package:spotify/spotify.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; +import 'package:spotube/extensions/string.dart'; import 'package:spotube/pages/home/genres/genre_playlists.dart'; import 'package:spotube/pages/home/genres/genres.dart'; +import 'package:spotube/pages/playlist/playlist.dart'; import 'package:spotube/provider/spotify/spotify.dart'; class HomeGenresSection extends HookConsumerWidget { @@ -19,7 +21,8 @@ class HomeGenresSection extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final mediaQuery = MediaQuery.of(context); + final theme = context.theme; + final mediaQuery = MediaQuery.sizeOf(context); final categoriesQuery = ref.watch(categoriesProvider); final categories = useMemoized( @@ -28,7 +31,9 @@ class HomeGenresSection extends HookConsumerWidget { .where((c) => (c.icons?.length ?? 0) > 0) .take(mediaQuery.mdAndDown ? 6 : 10) .toList() ?? - [], + [ + FakeData.category, + ], [mediaQuery.mdAndDown, categoriesQuery.asData?.value], ); @@ -61,51 +66,175 @@ class HomeGenresSection extends HookConsumerWidget { ), ), const SliverGap(8), - SliverPadding( - padding: const EdgeInsets.symmetric(horizontal: 16), - sliver: Skeletonizer.sliver( - enabled: categoriesQuery.isLoading, - child: SliverGrid.builder( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: mediaQuery.mdAndDown ? 200 : 250, - mainAxisExtent: 50, - crossAxisSpacing: 16, - mainAxisSpacing: 16, + SliverToBoxAdapter( + child: SizedBox( + height: 280 * theme.scaling, + child: Carousel( + transition: const CarouselTransition.sliding(gap: 24), + sizeConstraint: CarouselSizeConstraint.fixed( + mediaQuery.mdAndUp + ? mediaQuery.width * .6 + : mediaQuery.width * .95, ), - itemCount: categoriesQuery.isLoading - ? mediaQuery.mdAndDown - ? 6 - : 10 - : categories.length, + itemCount: categories.length, + autoplaySpeed: const Duration(seconds: 2), + duration: const Duration(seconds: 5), + pauseOnHover: true, + direction: Axis.horizontal, itemBuilder: (context, index) { - final category = - categories.elementAtOrNull(index) ?? FakeData.category; + final category = categories[index]; + final playlists = + ref.watch(categoryPlaylistsProvider(category.id!)); + final playlistsData = playlists.asData?.value.items.take(8) ?? + List.generate(5, (index) => FakeData.playlistSimple); - return Button( - style: ButtonVariance.secondary.copyWith( - padding: (context, states, value) { - return EdgeInsets.zero; - }, - ), - onPressed: () {}, - child: CardImage( - onPressed: () { - context.pushNamed( - GenrePlaylistsPage.name, - pathParameters: { - "categoryId": category.id!, - }, - extra: category, - ); - }, - direction: Axis.horizontal, - image: UniversalImage( - path: category.icons!.first.url!, - fit: BoxFit.cover, - height: 50, - width: 50, + return Container( + margin: const EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + borderRadius: theme.borderRadiusXxl, + border: Border.all( + color: theme.colorScheme.border, + width: 1, ), - title: Text(category.name!), + image: DecorationImage( + image: UniversalImage.imageProvider( + category.icons!.first.url!, + ), + colorFilter: ColorFilter.mode( + theme.colorScheme.background.withAlpha(125), + BlendMode.darken, + ), + fit: BoxFit.cover, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 16, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + category.name!, + style: const TextStyle(color: Colors.white), + ).h3(), + Button.link( + onPressed: () { + context.pushNamed( + GenrePlaylistsPage.name, + pathParameters: {'categoryId': category.id!}, + extra: category, + ); + }, + child: Text( + context.l10n.view_all, + style: const TextStyle(color: Colors.white), + ).muted(), + ), + ], + ), + Expanded( + child: Skeleton.ignore( + child: Skeletonizer( + enabled: playlists.isLoading, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + spacing: 12, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + for (final playlist in playlistsData) + Container( + width: 115 * theme.scaling, + decoration: BoxDecoration( + color: theme.colorScheme.background + .withAlpha(75), + borderRadius: theme.borderRadiusMd, + ), + child: SurfaceBlur( + borderRadius: theme.borderRadiusMd, + surfaceBlur: theme.surfaceBlur, + child: Button( + style: + ButtonVariance.secondary.copyWith( + padding: (context, states, value) => + const EdgeInsets.all(8), + decoration: + (context, states, value) { + final decoration = ButtonVariance + .secondary + .decoration( + context, states) + as BoxDecoration; + + if (states.isNotEmpty) { + return decoration; + } + + return decoration.copyWith( + color: decoration.color + ?.withAlpha(180), + ); + }, + ), + onPressed: () { + context.pushNamed( + PlaylistPage.name, + pathParameters: { + "id": playlist.id!, + }, + extra: playlist, + ); + }, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + spacing: 5, + children: [ + ClipRRect( + borderRadius: + theme.borderRadiusSm, + child: UniversalImage( + path: (playlist.images)! + .asUrlString( + placeholder: + ImagePlaceholder + .collection, + index: 1, + ), + fit: BoxFit.cover, + height: 100 * theme.scaling, + width: 100 * theme.scaling, + ), + ), + Text( + playlist.name!, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ).semiBold().small(), + if (playlist.description != null) + Text( + playlist.description + ?.unescapeHtml() + .cleanHtml() ?? + "", + maxLines: 2, + overflow: + TextOverflow.ellipsis, + ).xSmall().muted(), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ), + ) + ], ), ); }, diff --git a/lib/utils/service_utils.dart b/lib/utils/service_utils.dart index bdc3877a..2abb98ef 100644 --- a/lib/utils/service_utils.dart +++ b/lib/utils/service_utils.dart @@ -4,6 +4,7 @@ import 'package:dio/dio.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:go_router/go_router.dart'; import 'package:html/dom.dart' hide Text; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide Element; import 'package:spotify/spotify.dart'; import 'package:spotube/modules/library/user_local_tracks.dart'; import 'package:spotube/modules/root/update_dialog.dart'; @@ -20,7 +21,6 @@ import 'package:html/parser.dart' as parser; import 'dart:async'; -import 'package:flutter/material.dart' hide Element; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:spotube/collections/env.dart'; @@ -304,7 +304,9 @@ abstract class ServiceUtils { .map((e) => e.matchedLocation); if (routerState.matchedLocation == location || - routerStack.contains(location)) return; + routerStack.contains(location)) { + return; + } router.push(location, extra: extra); } @@ -418,7 +420,7 @@ abstract class ServiceUtils { await showDialog( context: context, barrierDismissible: true, - barrierColor: Colors.black26, + barrierColor: Colors.black.withAlpha(66), builder: (context) { return RootAppUpdateDialog.nightly(nightlyBuildNum: buildNum); }, @@ -439,14 +441,16 @@ abstract class ServiceUtils { if (currentVersion == null || latestVersion == null || (latestVersion.isPreRelease && !currentVersion.isPreRelease) || - (!latestVersion.isPreRelease && currentVersion.isPreRelease)) return; + (!latestVersion.isPreRelease && currentVersion.isPreRelease)) { + return; + } if (latestVersion <= currentVersion || !context.mounted) return; showDialog( context: context, barrierDismissible: true, - barrierColor: Colors.black26, + barrierColor: Colors.black.withAlpha(66), builder: (context) { return RootAppUpdateDialog(version: latestVersion); }, diff --git a/untranslated_messages.json b/untranslated_messages.json index a31de6a2..ddaf9ab0 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -8,7 +8,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "bn": [ @@ -20,7 +21,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "ca": [ @@ -32,7 +34,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "cs": [ @@ -44,7 +47,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "de": [ @@ -56,7 +60,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "es": [ @@ -68,7 +73,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "eu": [ @@ -80,7 +86,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "fa": [ @@ -92,7 +99,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "fi": [ @@ -104,7 +112,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "fr": [ @@ -116,7 +125,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "hi": [ @@ -128,7 +138,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "id": [ @@ -140,7 +151,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "it": [ @@ -152,7 +164,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "ja": [ @@ -164,7 +177,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "ka": [ @@ -176,7 +190,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "ko": [ @@ -188,7 +203,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "ne": [ @@ -200,7 +216,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "nl": [ @@ -212,7 +229,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "pl": [ @@ -224,7 +242,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "pt": [ @@ -236,7 +255,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "ru": [ @@ -248,7 +268,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "th": [ @@ -260,7 +281,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "tr": [ @@ -272,7 +294,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "uk": [ @@ -284,7 +307,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "vi": [ @@ -296,7 +320,8 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ], "zh": [ @@ -308,6 +333,7 @@ "add_all_to_playlist", "add_all_to_queue", "play_all_next", - "pause" + "pause", + "view_all" ] } From 46852545a942160164bab13f5e2a6707da7eb7d6 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Mon, 6 Jan 2025 21:33:26 +0600 Subject: [PATCH 39/81] refactor: add genre carousel buttons and indicators --- lib/modules/home/sections/genres.dart | 440 +++++++++++------- .../local_folder/cache_export_dialog.dart | 19 +- 2 files changed, 274 insertions(+), 185 deletions(-) diff --git a/lib/modules/home/sections/genres.dart b/lib/modules/home/sections/genres.dart index 57006b59..add61a5a 100644 --- a/lib/modules/home/sections/genres.dart +++ b/lib/modules/home/sections/genres.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -36,209 +38,297 @@ class HomeGenresSection extends HookConsumerWidget { ], [mediaQuery.mdAndDown, categoriesQuery.asData?.value], ); + final controller = useMemoized(() => CarouselController(), []); + final interactedRef = useRef(false); - return SliverMainAxisGroup( - slivers: [ - SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - context.l10n.genres, - style: context.theme.typography.h4, + useEffect(() { + int times = 0; + Timer.periodic( + const Duration(seconds: 5), + (timer) { + if (times > 5 || interactedRef.value) { + timer.cancel(); + return; + } + controller.animateNext( + const Duration(seconds: 2), + ); + times++; + }, + ); + + return controller.dispose; + }, []); + + return SliverList.list( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + context.l10n.genres, + style: context.theme.typography.h4, + ), + Directionality( + textDirection: TextDirection.rtl, + child: Button.link( + onPressed: () { + context.pushNamed(GenrePage.name); + }, + leading: const Icon(SpotubeIcons.angleRight), + child: Text( + context.l10n.browse_all, + ).muted(), ), - Directionality( - textDirection: TextDirection.rtl, - child: Button.link( - onPressed: () { - context.pushNamed(GenrePage.name); - }, - leading: const Icon(SpotubeIcons.angleRight), - child: Text( - context.l10n.browse_all, - ).muted(), - ), - ), - ], - ), + ), + ], ), ), - const SliverGap(8), - SliverToBoxAdapter( - child: SizedBox( - height: 280 * theme.scaling, - child: Carousel( - transition: const CarouselTransition.sliding(gap: 24), - sizeConstraint: CarouselSizeConstraint.fixed( - mediaQuery.mdAndUp - ? mediaQuery.width * .6 - : mediaQuery.width * .95, - ), - itemCount: categories.length, - autoplaySpeed: const Duration(seconds: 2), - duration: const Duration(seconds: 5), - pauseOnHover: true, - direction: Axis.horizontal, - itemBuilder: (context, index) { - final category = categories[index]; - final playlists = - ref.watch(categoryPlaylistsProvider(category.id!)); - final playlistsData = playlists.asData?.value.items.take(8) ?? - List.generate(5, (index) => FakeData.playlistSimple); + const Gap(8), + Stack( + children: [ + SizedBox( + height: 280 * theme.scaling, + child: Carousel( + controller: controller, + transition: const CarouselTransition.sliding(gap: 24), + sizeConstraint: CarouselSizeConstraint.fixed( + mediaQuery.mdAndUp + ? mediaQuery.width * .6 + : mediaQuery.width * .95, + ), + itemCount: categories.length, + pauseOnHover: true, + direction: Axis.horizontal, + itemBuilder: (context, index) { + final category = categories[index]; + final playlists = + ref.watch(categoryPlaylistsProvider(category.id!)); + final playlistsData = playlists.asData?.value.items.take(8) ?? + List.generate(5, (index) => FakeData.playlistSimple); - return Container( - margin: const EdgeInsets.symmetric(horizontal: 8), - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - borderRadius: theme.borderRadiusXxl, - border: Border.all( - color: theme.colorScheme.border, - width: 1, - ), - image: DecorationImage( - image: UniversalImage.imageProvider( - category.icons!.first.url!, + return Container( + margin: const EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + borderRadius: theme.borderRadiusXxl, + border: Border.all( + color: theme.colorScheme.border, + width: 1, ), - colorFilter: ColorFilter.mode( - theme.colorScheme.background.withAlpha(125), - BlendMode.darken, + image: DecorationImage( + image: UniversalImage.imageProvider( + category.icons!.first.url!, + ), + colorFilter: ColorFilter.mode( + theme.colorScheme.background.withAlpha(125), + BlendMode.darken, + ), + fit: BoxFit.cover, ), - fit: BoxFit.cover, ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 16, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - category.name!, - style: const TextStyle(color: Colors.white), - ).h3(), - Button.link( - onPressed: () { - context.pushNamed( - GenrePlaylistsPage.name, - pathParameters: {'categoryId': category.id!}, - extra: category, - ); - }, - child: Text( - context.l10n.view_all, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 16, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + category.name!, style: const TextStyle(color: Colors.white), - ).muted(), - ), - ], - ), - Expanded( - child: Skeleton.ignore( - child: Skeletonizer( - enabled: playlists.isLoading, - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - spacing: 12, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - for (final playlist in playlistsData) - Container( - width: 115 * theme.scaling, - decoration: BoxDecoration( - color: theme.colorScheme.background - .withAlpha(75), - borderRadius: theme.borderRadiusMd, - ), - child: SurfaceBlur( - borderRadius: theme.borderRadiusMd, - surfaceBlur: theme.surfaceBlur, - child: Button( - style: - ButtonVariance.secondary.copyWith( - padding: (context, states, value) => - const EdgeInsets.all(8), - decoration: - (context, states, value) { - final decoration = ButtonVariance - .secondary - .decoration( - context, states) - as BoxDecoration; + ).h3(), + Button.link( + onPressed: () { + context.pushNamed( + GenrePlaylistsPage.name, + pathParameters: {'categoryId': category.id!}, + extra: category, + ); + }, + child: Text( + context.l10n.view_all, + style: const TextStyle(color: Colors.white), + ).muted(), + ), + ], + ), + Expanded( + child: Skeleton.ignore( + child: Skeletonizer( + enabled: playlists.isLoading, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + spacing: 12, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + for (final playlist in playlistsData) + Container( + width: 115 * theme.scaling, + decoration: BoxDecoration( + color: theme.colorScheme.background + .withAlpha(75), + borderRadius: theme.borderRadiusMd, + ), + child: SurfaceBlur( + borderRadius: theme.borderRadiusMd, + surfaceBlur: theme.surfaceBlur, + child: Button( + style: ButtonVariance.secondary + .copyWith( + padding: + (context, states, value) => + const EdgeInsets.all(8), + decoration: + (context, states, value) { + final decoration = + ButtonVariance.secondary + .decoration( + context, states) + as BoxDecoration; - if (states.isNotEmpty) { - return decoration; - } + if (states.isNotEmpty) { + return decoration; + } - return decoration.copyWith( - color: decoration.color - ?.withAlpha(180), + return decoration.copyWith( + color: decoration.color + ?.withAlpha(180), + ); + }, + ), + onPressed: () { + context.pushNamed( + PlaylistPage.name, + pathParameters: { + "id": playlist.id!, + }, + extra: playlist, ); }, - ), - onPressed: () { - context.pushNamed( - PlaylistPage.name, - pathParameters: { - "id": playlist.id!, - }, - extra: playlist, - ); - }, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - spacing: 5, - children: [ - ClipRRect( - borderRadius: - theme.borderRadiusSm, - child: UniversalImage( - path: (playlist.images)! - .asUrlString( - placeholder: - ImagePlaceholder - .collection, - index: 1, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + spacing: 5, + children: [ + ClipRRect( + borderRadius: + theme.borderRadiusSm, + child: UniversalImage( + path: (playlist.images)! + .asUrlString( + placeholder: + ImagePlaceholder + .collection, + index: 1, + ), + fit: BoxFit.cover, + height: 100 * theme.scaling, + width: 100 * theme.scaling, ), - fit: BoxFit.cover, - height: 100 * theme.scaling, - width: 100 * theme.scaling, ), - ), - Text( - playlist.name!, - maxLines: 2, - overflow: TextOverflow.ellipsis, - ).semiBold().small(), - if (playlist.description != null) Text( - playlist.description - ?.unescapeHtml() - .cleanHtml() ?? - "", + playlist.name!, maxLines: 2, overflow: TextOverflow.ellipsis, - ).xSmall().muted(), - ], + ).semiBold().small(), + if (playlist.description != + null) + Text( + playlist.description + ?.unescapeHtml() + .cleanHtml() ?? + "", + maxLines: 2, + overflow: + TextOverflow.ellipsis, + ).xSmall().muted(), + ], + ), ), ), ), - ), - ], + ], + ), ), ), ), - ), - ) + ) + ], + ), + ); + }, + ), + ), + Positioned( + left: 0, + child: Container( + height: 280 * theme.scaling, + width: (mediaQuery.mdAndUp ? 80 : 50) * theme.scaling, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + theme.colorScheme.background.withAlpha(255), + theme.colorScheme.background.withAlpha(0), ], ), - ); - }, + ), + alignment: Alignment.center, + child: IconButton.ghost( + size: + mediaQuery.mdAndUp ? ButtonSize.normal : ButtonSize.small, + icon: const Icon(SpotubeIcons.angleLeft), + onPressed: () { + controller.animatePrevious( + const Duration(seconds: 1), + ); + interactedRef.value = true; + }, + ), + ), ), + Positioned( + right: 0, + child: Container( + height: 280 * theme.scaling, + width: (mediaQuery.mdAndUp ? 80 : 50) * theme.scaling, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + theme.colorScheme.background.withAlpha(0), + theme.colorScheme.background.withAlpha(255), + ], + ), + ), + alignment: Alignment.center, + child: IconButton.ghost( + size: + mediaQuery.mdAndUp ? ButtonSize.normal : ButtonSize.small, + icon: const Icon(SpotubeIcons.angleRight), + onPressed: () { + controller.animateNext( + const Duration(seconds: 1), + ); + interactedRef.value = true; + }, + ), + ), + ), + ], + ), + const Gap(8), + Center( + child: CarouselDotIndicator( + itemCount: categories.length, + controller: controller, ), ), ], diff --git a/lib/modules/library/local_folder/cache_export_dialog.dart b/lib/modules/library/local_folder/cache_export_dialog.dart index 1d1421be..0f10defc 100644 --- a/lib/modules/library/local_folder/cache_export_dialog.dart +++ b/lib/modules/library/local_folder/cache_export_dialog.dart @@ -1,10 +1,9 @@ import 'dart:io'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:path/path.dart'; +import 'package:path/path.dart' as path; import 'package:spotube/extensions/context.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/services/sourced_track/enums.dart'; @@ -22,7 +21,7 @@ class LocalFolderCacheExportDialog extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme, :colorScheme) = Theme.of(context); + final ThemeData(:typography, :colorScheme) = Theme.of(context); final files = useState>([]); final filesExported = useState(0); @@ -31,7 +30,7 @@ class LocalFolderCacheExportDialog extends HookConsumerWidget { final stream = cacheDir.list().where( (event) => event is File && - codecs.contains(extension(event.path).replaceAll(".", "")), + codecs.contains(path.extension(event.path).replaceAll(".", "")), ); stream.listen( @@ -76,8 +75,8 @@ class LocalFolderCacheExportDialog extends HookConsumerWidget { ), TextSpan( text: "\n${exportDir.path}?", - style: textTheme.labelMedium!.copyWith( - color: colorScheme.secondary, + style: typography.small.copyWith( + color: colorScheme.mutedForeground, ), ), ], @@ -102,7 +101,7 @@ class LocalFolderCacheExportDialog extends HookConsumerWidget { ), ), actions: [ - TextButton( + Button.outline( onPressed: isExportInProgress ? null : () { @@ -110,14 +109,14 @@ class LocalFolderCacheExportDialog extends HookConsumerWidget { }, child: Text(context.l10n.cancel), ), - TextButton( + Button.primary( onPressed: isExportInProgress ? null : () async { for (final file in files.value) { try { final destinationFile = File( - join(exportDir.path, basename(file.path)), + path.join(exportDir.path, path.basename(file.path)), ); if (await destinationFile.exists()) { From 3ffcb48db9bcc377b78cab33342172464180ab7d Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Mon, 6 Jan 2025 21:44:06 +0600 Subject: [PATCH 40/81] chore: improve carousel performance --- lib/modules/home/sections/genres.dart | 174 +++++++++++++------------- 1 file changed, 84 insertions(+), 90 deletions(-) diff --git a/lib/modules/home/sections/genres.dart b/lib/modules/home/sections/genres.dart index add61a5a..9309e2e7 100644 --- a/lib/modules/home/sections/genres.dart +++ b/lib/modules/home/sections/genres.dart @@ -31,12 +31,12 @@ class HomeGenresSection extends HookConsumerWidget { () => categoriesQuery.asData?.value .where((c) => (c.icons?.length ?? 0) > 0) - .take(mediaQuery.mdAndDown ? 6 : 10) + .take(6) .toList() ?? [ FakeData.category, ], - [mediaQuery.mdAndDown, categoriesQuery.asData?.value], + [categoriesQuery.asData?.value], ); final controller = useMemoized(() => CarouselController(), []); final interactedRef = useRef(false); @@ -159,101 +159,95 @@ class HomeGenresSection extends HookConsumerWidget { child: Skeleton.ignore( child: Skeletonizer( enabled: playlists.isLoading, - child: SingleChildScrollView( + child: ListView.separated( scrollDirection: Axis.horizontal, - child: Row( - spacing: 12, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - for (final playlist in playlistsData) - Container( - width: 115 * theme.scaling, - decoration: BoxDecoration( - color: theme.colorScheme.background - .withAlpha(75), - borderRadius: theme.borderRadiusMd, + itemCount: playlistsData.length, + separatorBuilder: (context, index) => + const Gap(12), + itemBuilder: (context, index) { + final playlist = + playlistsData.elementAt(index); + + return Container( + width: 115 * theme.scaling, + decoration: BoxDecoration( + color: theme.colorScheme.background + .withAlpha(75), + borderRadius: theme.borderRadiusMd, + ), + child: SurfaceBlur( + borderRadius: theme.borderRadiusMd, + surfaceBlur: theme.surfaceBlur, + child: Button( + style: + ButtonVariance.secondary.copyWith( + padding: (context, states, value) => + const EdgeInsets.all(8), + decoration: (context, states, value) { + final decoration = ButtonVariance + .secondary + .decoration(context, states) + as BoxDecoration; + + if (states.isNotEmpty) { + return decoration; + } + + return decoration.copyWith( + color: decoration.color + ?.withAlpha(180), + ); + }, ), - child: SurfaceBlur( - borderRadius: theme.borderRadiusMd, - surfaceBlur: theme.surfaceBlur, - child: Button( - style: ButtonVariance.secondary - .copyWith( - padding: - (context, states, value) => - const EdgeInsets.all(8), - decoration: - (context, states, value) { - final decoration = - ButtonVariance.secondary - .decoration( - context, states) - as BoxDecoration; - - if (states.isNotEmpty) { - return decoration; - } - - return decoration.copyWith( - color: decoration.color - ?.withAlpha(180), - ); - }, - ), - onPressed: () { - context.pushNamed( - PlaylistPage.name, - pathParameters: { - "id": playlist.id!, - }, - extra: playlist, - ); + onPressed: () { + context.pushNamed( + PlaylistPage.name, + pathParameters: { + "id": playlist.id!, }, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - spacing: 5, - children: [ - ClipRRect( - borderRadius: - theme.borderRadiusSm, - child: UniversalImage( - path: (playlist.images)! - .asUrlString( - placeholder: - ImagePlaceholder - .collection, - index: 1, - ), - fit: BoxFit.cover, - height: 100 * theme.scaling, - width: 100 * theme.scaling, - ), + extra: playlist, + ); + }, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + spacing: 5, + children: [ + ClipRRect( + borderRadius: + theme.borderRadiusSm, + child: UniversalImage( + path: (playlist.images)! + .asUrlString( + placeholder: ImagePlaceholder + .collection, + index: 1, ), - Text( - playlist.name!, - maxLines: 2, - overflow: - TextOverflow.ellipsis, - ).semiBold().small(), - if (playlist.description != - null) - Text( - playlist.description - ?.unescapeHtml() - .cleanHtml() ?? - "", - maxLines: 2, - overflow: - TextOverflow.ellipsis, - ).xSmall().muted(), - ], + fit: BoxFit.cover, + height: 100 * theme.scaling, + width: 100 * theme.scaling, + ), ), - ), + Text( + playlist.name!, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ).semiBold().small(), + if (playlist.description != null) + Text( + playlist.description + ?.unescapeHtml() + .cleanHtml() ?? + "", + maxLines: 2, + overflow: TextOverflow.ellipsis, + ).xSmall().muted(), + ], ), ), - ], - ), + ), + ); + }, ), ), ), From e54a6460732c8360346187a5a250853b368123a4 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Wed, 8 Jan 2025 19:11:29 +0600 Subject: [PATCH 41/81] refactor: downloads page to shadcn --- .../local_folder/local_folder_item.dart | 20 +++---- lib/modules/library/user_downloads.dart | 11 +--- .../library/user_downloads/download_item.dart | 58 +++++++++---------- 3 files changed, 39 insertions(+), 50 deletions(-) diff --git a/lib/modules/library/local_folder/local_folder_item.dart b/lib/modules/library/local_folder/local_folder_item.dart index 84e43e96..20845ef7 100644 --- a/lib/modules/library/local_folder/local_folder_item.dart +++ b/lib/modules/library/local_folder/local_folder_item.dart @@ -77,17 +77,15 @@ class LocalFolderItem extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, children: [ if (tracks.isEmpty) - Card( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Icon( - SpotubeIcons.folder, - size: mediaQuery.smAndDown - ? 95 - : mediaQuery.mdAndDown - ? 100 - : 142, - ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Icon( + SpotubeIcons.folder, + size: mediaQuery.smAndDown + ? 95 + : mediaQuery.mdAndDown + ? 100 + : 142, ), ) else diff --git a/lib/modules/library/user_downloads.dart b/lib/modules/library/user_downloads.dart index 7fe9800c..5db30342 100644 --- a/lib/modules/library/user_downloads.dart +++ b/lib/modules/library/user_downloads.dart @@ -1,6 +1,6 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/modules/library/user_downloads/download_item.dart'; import 'package:spotube/extensions/context.dart'; @@ -31,15 +31,10 @@ class UserDownloads extends HookConsumerWidget { context.l10n .currently_downloading(downloadManager.$downloadCount), maxLines: 1, - style: Theme.of(context).textTheme.titleMedium, - ), + ).semiBold(), ), const SizedBox(width: 10), - FilledButton( - style: FilledButton.styleFrom( - backgroundColor: Colors.red[50], - foregroundColor: Colors.red[400], - ), + Button.destructive( onPressed: downloadManager.$downloadCount == 0 ? null : downloadManager.cancelAll, diff --git a/lib/modules/library/user_downloads/download_item.dart b/lib/modules/library/user_downloads/download_item.dart index c4bd7bce..4b104ed1 100644 --- a/lib/modules/library/user_downloads/download_item.dart +++ b/lib/modules/library/user_downloads/download_item.dart @@ -1,10 +1,11 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/links/artist_link.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/pages/track/track.dart'; @@ -46,7 +47,8 @@ class DownloadItem extends HookConsumerWidget { final isQueryingSourceInfo = taskStatus.value == null || track is! SourcedTrack; - return ListTile( + return ButtonTile( + style: ButtonVariance.ghost, leading: Padding( padding: const EdgeInsets.symmetric(horizontal: 5), child: ClipRRect( @@ -73,10 +75,7 @@ class DownloadItem extends HookConsumerWidget { ), ), trailing: isQueryingSourceInfo - ? Text( - context.l10n.querying_info, - style: Theme.of(context).textTheme.labelMedium, - ) + ? Text(context.l10n.querying_info).small() : switch (taskStatus.value!) { DownloadStatus.downloading => HookBuilder(builder: (context) { final taskProgress = useListenable(useMemoized( @@ -84,39 +83,36 @@ class DownloadItem extends HookConsumerWidget { .getProgressNotifier(track as SourcedTrack), [track], )); - return SizedBox( - width: 140, - child: Row( - children: [ - CircularProgressIndicator( - value: taskProgress?.value ?? 0, - ), - const SizedBox(width: 10), - IconButton( - icon: const Icon(SpotubeIcons.pause), - onPressed: () { - downloadManager.pause(track as SourcedTrack); - }), - const SizedBox(width: 10), - IconButton( - icon: const Icon(SpotubeIcons.close), - onPressed: () { - downloadManager.cancel(track as SourcedTrack); - }), - ], - ), + return Row( + children: [ + CircularProgressIndicator( + value: taskProgress?.value ?? 0, + ), + const SizedBox(width: 10), + IconButton.ghost( + icon: const Icon(SpotubeIcons.pause), + onPressed: () { + downloadManager.pause(track as SourcedTrack); + }), + const SizedBox(width: 10), + IconButton.ghost( + icon: const Icon(SpotubeIcons.close), + onPressed: () { + downloadManager.cancel(track as SourcedTrack); + }), + ], ); }), DownloadStatus.paused => Row( mainAxisSize: MainAxisSize.min, children: [ - IconButton( + IconButton.ghost( icon: const Icon(SpotubeIcons.play), onPressed: () { downloadManager.resume(track as SourcedTrack); }), const SizedBox(width: 10), - IconButton( + IconButton.ghost( icon: const Icon(SpotubeIcons.close), onPressed: () { downloadManager.cancel(track as SourcedTrack); @@ -132,7 +128,7 @@ class DownloadItem extends HookConsumerWidget { color: Colors.red[400], ), const SizedBox(width: 10), - IconButton( + IconButton.ghost( icon: const Icon(SpotubeIcons.refresh), onPressed: () { downloadManager.retry(track as SourcedTrack); @@ -143,7 +139,7 @@ class DownloadItem extends HookConsumerWidget { ), DownloadStatus.completed => Icon(SpotubeIcons.done, color: Colors.green[400]), - DownloadStatus.queued => IconButton( + DownloadStatus.queued => IconButton.ghost( icon: const Icon(SpotubeIcons.close), onPressed: () { downloadManager.removeFromQueue(track as SourcedTrack); From 88906098dd229338cf811963c5b539aabccfeadd Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Wed, 8 Jan 2025 22:16:46 +0600 Subject: [PATCH 42/81] refactor: use shadcn for TrackTile --- .../track_presentation.dart | 15 +- .../use_track_tile_play_callback.dart | 6 +- lib/components/track_tile/track_tile.dart | 399 +++++++++--------- lib/components/ui/button_tile.dart | 129 +++--- lib/extensions/button_variance.dart | 21 + lib/modules/home/sections/genres.dart | 7 +- 6 files changed, 309 insertions(+), 268 deletions(-) create mode 100644 lib/extensions/button_variance.dart diff --git a/lib/components/track_presentation/track_presentation.dart b/lib/components/track_presentation/track_presentation.dart index 4f1db832..47089bd6 100644 --- a/lib/components/track_presentation/track_presentation.dart +++ b/lib/components/track_presentation/track_presentation.dart @@ -1,4 +1,3 @@ -import 'package:flutter/material.dart' show ListTile; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; @@ -21,9 +20,6 @@ class TrackPresentation extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final headerTextStyle = context.theme.typography.small.copyWith( - color: context.theme.colorScheme.mutedForeground, - ); final scrollController = useScrollController(); final focusNode = useFocusNode(); final scale = context.theme.scaling; @@ -66,10 +62,11 @@ class TrackPresentation extends HookConsumerWidget { TrackPresentationModifiersSection( focusNode: focusNode, ), - ListTile( - titleTextStyle: headerTextStyle, - subtitleTextStyle: headerTextStyle, - leadingAndTrailingTextStyle: headerTextStyle, + Basic( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 16, + ), leading: constrains.mdAndUp ? const Text(" #") : null, title: Row( children: [ @@ -85,7 +82,7 @@ class TrackPresentation extends HookConsumerWidget { Text(context.l10n.duration), ], ), - ), + ).small().muted(), ], ); }, diff --git a/lib/components/track_presentation/use_track_tile_play_callback.dart b/lib/components/track_presentation/use_track_tile_play_callback.dart index 74608205..b519f781 100644 --- a/lib/components/track_presentation/use_track_tile_play_callback.dart +++ b/lib/components/track_presentation/use_track_tile_play_callback.dart @@ -32,7 +32,11 @@ Future Function(Track track, int index) useTrackTilePlayCallback( ref.read(presentationStateProvider(options.collection).notifier); if (state.selectedTracks.isNotEmpty) { - notifier.selectTrack(track); + if (state.selectedTracks.contains(track)) { + notifier.deselectTrack(track); + } else { + notifier.selectTrack(track); + } return; } diff --git a/lib/components/track_tile/track_tile.dart b/lib/components/track_tile/track_tile.dart index 560d2255..0ca14979 100644 --- a/lib/components/track_tile/track_tile.dart +++ b/lib/components/track_tile/track_tile.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart' show ListTile, Material, MaterialType; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; @@ -14,7 +14,9 @@ import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/links/artist_link.dart'; import 'package:spotube/components/links/link_text.dart'; import 'package:spotube/components/track_tile/track_options.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/artist_simple.dart'; +import 'package:spotube/extensions/button_variance.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/duration.dart'; import 'package:spotube/extensions/image.dart'; @@ -89,225 +91,232 @@ class TrackTile extends HookConsumerWidget { }, child: HoverBuilder( permanentState: isSelected || constrains.smAndDown ? true : null, - builder: (context, isHovering) => Material( - type: MaterialType.transparency, - child: ListTile( - selectedColor: theme.colorScheme.primary, - selectedTileColor: theme.colorScheme.primary.withOpacity(0.1), - selected: isSelected, - onTap: () async { - try { - isLoading.value = true; - await onTap?.call(); - } finally { - if (context.mounted) { - isLoading.value = false; - } + builder: (context, isHovering) => ButtonTile( + selected: isSelected, + onPressed: () async { + if (isBlackListed) return; + try { + isLoading.value = true; + await onTap?.call(); + } finally { + if (context.mounted) { + isLoading.value = false; } - }, - onLongPress: onLongPress, - enabled: !isBlackListed, - contentPadding: EdgeInsets.zero, - tileColor: isBlackListed ? theme.colorScheme.destructive : null, - horizontalTitleGap: 12, - leadingAndTrailingTextStyle: theme.typography.normal.copyWith( - color: theme.colorScheme.foreground, - ), - titleTextStyle: theme.typography.normal.copyWith( - color: theme.colorScheme.foreground, - ), - subtitleTextStyle: theme.typography.xSmall.copyWith( - color: theme.colorScheme.mutedForeground, - ), - leading: Row( - mainAxisSize: MainAxisSize.min, - children: [ - ...?leadingActions, - AnimatedCrossFade( - duration: const Duration(milliseconds: 300), - crossFadeState: index != null && onChanged == null - ? CrossFadeState.showSecond - : CrossFadeState.showFirst, - firstChild: Checkbox( - state: selected - ? CheckboxState.checked - : CheckboxState.unchecked, - onChanged: (state) => - onChanged?.call(state == CheckboxState.checked), - ), - secondChild: constrains.smAndDown - ? const SizedBox(width: 16) - : SizedBox( - width: 50, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 6), - child: Text( - '${(index ?? 0) + 1}', - maxLines: 1, - style: theme.typography.small, - textAlign: TextAlign.center, - ), + } + }, + onLongPress: onLongPress, + style: (isBlackListed + ? ButtonVariance.destructive + : ButtonVariance.ghost) + .copyWith( + padding: (context, states) => + const EdgeInsets.symmetric(vertical: 8, horizontal: 0), + ), + leading: Row( + mainAxisSize: MainAxisSize.min, + children: [ + ...?leadingActions, + AnimatedCrossFade( + duration: const Duration(milliseconds: 300), + crossFadeState: index != null && onChanged == null + ? CrossFadeState.showSecond + : CrossFadeState.showFirst, + firstChild: Checkbox( + state: selected + ? CheckboxState.checked + : CheckboxState.unchecked, + onChanged: (state) => + onChanged?.call(state == CheckboxState.checked), + ), + secondChild: constrains.smAndDown + ? const SizedBox(width: 16) + : SizedBox( + width: 50, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 6), + child: Text( + '${(index ?? 0) + 1}', + maxLines: 1, + style: theme.typography.small, + textAlign: TextAlign.center, ), ), - ), - Stack( - children: [ - Container( - height: 40, - width: 40, + ), + ), + Stack( + children: [ + Container( + height: 40, + width: 40, + decoration: BoxDecoration( + borderRadius: theme.borderRadiusMd, + image: DecorationImage( + fit: BoxFit.cover, + image: UniversalImage.imageProvider( + (track.album?.images).asUrlString( + placeholder: ImagePlaceholder.albumArt, + ), + ), + ), + ), + ), + Positioned.fill( + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), decoration: BoxDecoration( borderRadius: theme.borderRadiusMd, - image: DecorationImage( - fit: BoxFit.cover, - image: UniversalImage.imageProvider( - (track.album?.images).asUrlString( - placeholder: ImagePlaceholder.albumArt, + color: isHovering + ? Colors.black.withAlpha(102) + : Colors.transparent, + ), + ), + ), + Positioned.fill( + child: Center( + child: Skeleton.ignore( + child: Consumer( + builder: (context, ref, _) { + final isFetchingActiveTrack = + ref.watch(queryingTrackInfoProvider); + return AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + child: switch (( + isPlaying, + isFetchingActiveTrack, + isPlaying, + isHovering, + isLoading.value + )) { + (true, true, _, _, _) || + (_, _, _, _, true) => + const SizedBox( + width: 26, + height: 26, + child: + CircularProgressIndicator(size: 1.5), + ), + (_, _, true, _, _) => Icon( + SpotubeIcons.pause, + color: theme.colorScheme.primary, + ), + (_, _, _, true, _) => const Icon( + SpotubeIcons.play, + color: Colors.white, + ), + _ => const SizedBox.shrink(), + }, + ); + }, + ), + ), + ), + ), + ], + ), + ], + ), + title: Row( + children: [ + Expanded( + flex: 6, + child: switch (track) { + LocalTrack() => Text( + track.name!, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + _ => Row( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: Button( + style: ButtonVariance.link.copyWith( + padding: (context, states) => EdgeInsets.zero, ), - ), - ), - ), - ), - Positioned.fill( - child: AnimatedContainer( - duration: const Duration(milliseconds: 300), - decoration: BoxDecoration( - borderRadius: theme.borderRadiusMd, - color: isHovering - ? Colors.black.withOpacity(0.4) - : Colors.transparent, - ), - ), - ), - Positioned.fill( - child: Center( - child: Skeleton.ignore( - child: Consumer( - builder: (context, ref, _) { - final isFetchingActiveTrack = - ref.watch(queryingTrackInfoProvider); - return AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: switch (( - isPlaying, - isFetchingActiveTrack, - isPlaying, - isHovering, - isLoading.value - )) { - (true, true, _, _, _) || - (_, _, _, _, true) => - const SizedBox( - width: 26, - height: 26, - child: CircularProgressIndicator( - size: 1.5), - ), - (_, _, true, _, _) => Icon( - SpotubeIcons.pause, - color: theme.colorScheme.primary, - ), - (_, _, _, true, _) => const Icon( - SpotubeIcons.play, - color: Colors.white, - ), - _ => const SizedBox.shrink(), + onPressed: () { + context.pushNamed( + TrackPage.name, + pathParameters: { + "id": track.id!, }, ); }, + child: Text( + track.name!, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), ), ), - ), + ], ), - ], - ), - ], - ), - title: Row( - children: [ + }, + ), + if (constrains.mdAndUp) ...[ + const SizedBox(width: 8), Expanded( - flex: 6, + flex: 4, child: switch (track) { LocalTrack() => Text( - track.name!, + track.album!.name!, maxLines: 1, overflow: TextOverflow.ellipsis, ), - _ => LinkText( - track.name!, - "/track/${track.id}", - push: true, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - }, - ), - if (constrains.mdAndUp) ...[ - const SizedBox(width: 8), - Expanded( - flex: 4, - child: switch (track) { - LocalTrack() => Text( + _ => Align( + alignment: Alignment.centerLeft, + child: LinkText( track.album!.name!, - maxLines: 1, + "/album/${track.album?.id}", + extra: track.album, + push: true, overflow: TextOverflow.ellipsis, ), - _ => Align( - alignment: Alignment.centerLeft, - child: LinkText( - track.album!.name!, - "/album/${track.album?.id}", - extra: track.album, - push: true, - overflow: TextOverflow.ellipsis, - ), - ) - }, - ), - ], + ) + }, + ), ], - ), - subtitle: Align( - alignment: Alignment.centerLeft, - child: track is LocalTrack - ? Text( - track.artists?.asString() ?? '', - ) - : ClipRect( - child: ConstrainedBox( - constraints: const BoxConstraints(maxHeight: 40), - child: ArtistLink( - artists: track.artists ?? [], - onOverflowArtistClick: () => ServiceUtils.pushNamed( - context, - TrackPage.name, - pathParameters: { - "id": track.id!, - }, - ), + ], + ), + subtitle: Align( + alignment: Alignment.centerLeft, + child: track is LocalTrack + ? Text( + track.artists?.asString() ?? '', + ) + : ClipRect( + child: ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 40), + child: ArtistLink( + artists: track.artists ?? [], + onOverflowArtistClick: () => ServiceUtils.pushNamed( + context, + TrackPage.name, + pathParameters: { + "id": track.id!, + }, ), ), ), - ), - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox(width: 8), - Text( - Duration(milliseconds: track.durationMs ?? 0) - .toHumanReadableString(padZero: false), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - TrackOptions( - track: track, - playlistId: playlistId, - userPlaylist: userPlaylist, - showMenuCbRef: showOptionCbRef, - ), - if (kIsDesktop) const Gap(10), - ], - ), + ), + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(width: 8), + Text( + Duration(milliseconds: track.durationMs ?? 0) + .toHumanReadableString(padZero: false), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + TrackOptions( + track: track, + playlistId: playlistId, + userPlaylist: userPlaylist, + showMenuCbRef: showOptionCbRef, + ), + if (kIsDesktop) const Gap(10), + ], ), ), ), diff --git a/lib/components/ui/button_tile.dart b/lib/components/ui/button_tile.dart index 7318e8c4..8f5a7581 100644 --- a/lib/components/ui/button_tile.dart +++ b/lib/components/ui/button_tile.dart @@ -6,7 +6,8 @@ class ButtonTile extends StatelessWidget { final Widget? leading; final Widget? trailing; final bool enabled; - final void Function()? onPressed; + final VoidCallback? onPressed; + final VoidCallback? onLongPress; final bool selected; final ButtonVariance style; final EdgeInsets? padding; @@ -19,6 +20,7 @@ class ButtonTile extends StatelessWidget { this.trailing, this.enabled = true, this.onPressed, + this.onLongPress, this.selected = false, this.padding, this.style = ButtonVariance.outline, @@ -28,73 +30,78 @@ class ButtonTile extends StatelessWidget { Widget build(BuildContext context) { final ThemeData(:colorScheme, :typography) = Theme.of(context); - return Button( - enabled: enabled, - onPressed: onPressed, - style: style.copyWith( - padding: padding != null ? (context, states, value) => padding! : null, - decoration: (context, states, value) { - final decoration = style.decoration(context, states) as BoxDecoration; + return GestureDetector( + onLongPress: onLongPress, + child: Button( + enabled: enabled, + onPressed: onPressed, + style: style.copyWith( + padding: + padding != null ? (context, states, value) => padding! : null, + decoration: (context, states, value) { + final decoration = + style.decoration(context, states) as BoxDecoration; - if (selected) { - return switch (style) { - ButtonVariance.outline => decoration.copyWith( - border: Border.all( - color: colorScheme.primary, - width: 1.0, + if (selected) { + return switch (style) { + ButtonVariance.outline => decoration.copyWith( + border: Border.all( + color: colorScheme.primary, + width: 1.0, + ), + color: colorScheme.primary.withAlpha(25), ), - color: colorScheme.primary.withAlpha(25), - ), - ButtonVariance.ghost || _ => decoration.copyWith( - color: colorScheme.primary.withAlpha(25), - ), - }; - } + ButtonVariance.ghost || _ => decoration.copyWith( + color: colorScheme.primary.withAlpha(25), + ), + }; + } - return decoration; - }, - iconTheme: (context, states, value) { - final iconTheme = style.iconTheme(context, states); + return decoration; + }, + iconTheme: (context, states, value) { + final iconTheme = style.iconTheme(context, states); - if (selected && style == ButtonVariance.outline) { - return iconTheme.copyWith( - color: colorScheme.primary, - ); - } + if (selected && style == ButtonVariance.outline) { + return iconTheme.copyWith( + color: colorScheme.primary, + ); + } - return iconTheme; - }, - textStyle: (context, states, value) { - final textStyle = style.textStyle(context, states); + return iconTheme; + }, + textStyle: (context, states, value) { + final textStyle = style.textStyle(context, states); - if (selected && style == ButtonVariance.outline) { - return textStyle.copyWith( - color: colorScheme.primary, - ); - } + if (selected && style == ButtonVariance.outline) { + return textStyle.copyWith( + color: colorScheme.primary, + ); + } - return textStyle; - }, - ), - alignment: Alignment.centerLeft, - child: SizedBox( - width: double.infinity, - child: Basic( - padding: EdgeInsets.zero, - leadingAlignment: Alignment.center, - trailingAlignment: Alignment.center, - leading: leading, - title: title, - subtitle: - style == ButtonVariance.outline && selected && subtitle != null - ? DefaultTextStyle( - style: typography.xSmall.copyWith( - color: colorScheme.primary, - ), - child: subtitle!, - ) - : subtitle, - trailing: trailing, + return textStyle; + }, + ), + alignment: Alignment.centerLeft, + child: SizedBox( + width: double.infinity, + child: Basic( + padding: EdgeInsets.zero, + leadingAlignment: Alignment.center, + trailingAlignment: Alignment.center, + leading: leading, + title: title, + subtitle: + style == ButtonVariance.outline && selected && subtitle != null + ? DefaultTextStyle( + style: typography.xSmall.copyWith( + color: colorScheme.primary, + ), + child: subtitle!, + ) + : subtitle, + trailing: trailing, + ), ), ), ); diff --git a/lib/extensions/button_variance.dart b/lib/extensions/button_variance.dart new file mode 100644 index 00000000..cf66d528 --- /dev/null +++ b/lib/extensions/button_variance.dart @@ -0,0 +1,21 @@ +import 'package:shadcn_flutter/shadcn_flutter.dart'; + +extension CopyWithButtonVarianceExtension on ButtonVariance { + ButtonVariance copyWith({ + ButtonStateProperty? padding, + ButtonStateProperty? decoration, + ButtonStateProperty? mouseCursor, + ButtonStateProperty? iconTheme, + ButtonStateProperty? margin, + ButtonStateProperty? textStyle, + }) { + return ButtonVariance( + padding: padding ?? this.padding, + decoration: decoration ?? this.decoration, + mouseCursor: mouseCursor ?? this.mouseCursor, + iconTheme: iconTheme ?? this.iconTheme, + margin: margin ?? this.margin, + textStyle: textStyle ?? this.textStyle, + ); + } +} diff --git a/lib/modules/home/sections/genres.dart b/lib/modules/home/sections/genres.dart index 9309e2e7..b273b970 100644 --- a/lib/modules/home/sections/genres.dart +++ b/lib/modules/home/sections/genres.dart @@ -43,7 +43,7 @@ class HomeGenresSection extends HookConsumerWidget { useEffect(() { int times = 0; - Timer.periodic( + final timer = Timer.periodic( const Duration(seconds: 5), (timer) { if (times > 5 || interactedRef.value) { @@ -57,7 +57,10 @@ class HomeGenresSection extends HookConsumerWidget { }, ); - return controller.dispose; + return () { + timer.cancel(); + controller.dispose(); + }; }, []); return SliverList.list( From 2daea2b3efb9b273eb6843c2106fd08d142edc38 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 10 Jan 2025 19:51:21 +0600 Subject: [PATCH 43/81] chore: make genre carousel items better in light mode --- lib/modules/home/sections/genres.dart | 334 ------------------ .../home/sections/genres/genre_card.dart | 114 ++++++ .../genres/genre_card_playlist_card.dart | 88 +++++ lib/modules/home/sections/genres/genres.dart | 180 ++++++++++ .../player/player_overlay_collapsed.dart | 1 - lib/modules/root/spotube_navigation_bar.dart | 41 ++- lib/pages/home/home.dart | 2 +- 7 files changed, 406 insertions(+), 354 deletions(-) delete mode 100644 lib/modules/home/sections/genres.dart create mode 100644 lib/modules/home/sections/genres/genre_card.dart create mode 100644 lib/modules/home/sections/genres/genre_card_playlist_card.dart create mode 100644 lib/modules/home/sections/genres/genres.dart diff --git a/lib/modules/home/sections/genres.dart b/lib/modules/home/sections/genres.dart deleted file mode 100644 index b273b970..00000000 --- a/lib/modules/home/sections/genres.dart +++ /dev/null @@ -1,334 +0,0 @@ -import 'dart:async'; - -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:go_router/go_router.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; -import 'package:skeletonizer/skeletonizer.dart'; -import 'package:spotube/collections/fake.dart'; -import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/components/image/universal_image.dart'; -import 'package:spotube/extensions/constrains.dart'; -import 'package:spotube/extensions/context.dart'; -import 'package:spotube/extensions/image.dart'; -import 'package:spotube/extensions/string.dart'; -import 'package:spotube/pages/home/genres/genre_playlists.dart'; -import 'package:spotube/pages/home/genres/genres.dart'; -import 'package:spotube/pages/playlist/playlist.dart'; -import 'package:spotube/provider/spotify/spotify.dart'; - -class HomeGenresSection extends HookConsumerWidget { - const HomeGenresSection({super.key}); - - @override - Widget build(BuildContext context, ref) { - final theme = context.theme; - final mediaQuery = MediaQuery.sizeOf(context); - - final categoriesQuery = ref.watch(categoriesProvider); - final categories = useMemoized( - () => - categoriesQuery.asData?.value - .where((c) => (c.icons?.length ?? 0) > 0) - .take(6) - .toList() ?? - [ - FakeData.category, - ], - [categoriesQuery.asData?.value], - ); - final controller = useMemoized(() => CarouselController(), []); - final interactedRef = useRef(false); - - useEffect(() { - int times = 0; - final timer = Timer.periodic( - const Duration(seconds: 5), - (timer) { - if (times > 5 || interactedRef.value) { - timer.cancel(); - return; - } - controller.animateNext( - const Duration(seconds: 2), - ); - times++; - }, - ); - - return () { - timer.cancel(); - controller.dispose(); - }; - }, []); - - return SliverList.list( - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - context.l10n.genres, - style: context.theme.typography.h4, - ), - Directionality( - textDirection: TextDirection.rtl, - child: Button.link( - onPressed: () { - context.pushNamed(GenrePage.name); - }, - leading: const Icon(SpotubeIcons.angleRight), - child: Text( - context.l10n.browse_all, - ).muted(), - ), - ), - ], - ), - ), - const Gap(8), - Stack( - children: [ - SizedBox( - height: 280 * theme.scaling, - child: Carousel( - controller: controller, - transition: const CarouselTransition.sliding(gap: 24), - sizeConstraint: CarouselSizeConstraint.fixed( - mediaQuery.mdAndUp - ? mediaQuery.width * .6 - : mediaQuery.width * .95, - ), - itemCount: categories.length, - pauseOnHover: true, - direction: Axis.horizontal, - itemBuilder: (context, index) { - final category = categories[index]; - final playlists = - ref.watch(categoryPlaylistsProvider(category.id!)); - final playlistsData = playlists.asData?.value.items.take(8) ?? - List.generate(5, (index) => FakeData.playlistSimple); - - return Container( - margin: const EdgeInsets.symmetric(horizontal: 8), - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - borderRadius: theme.borderRadiusXxl, - border: Border.all( - color: theme.colorScheme.border, - width: 1, - ), - image: DecorationImage( - image: UniversalImage.imageProvider( - category.icons!.first.url!, - ), - colorFilter: ColorFilter.mode( - theme.colorScheme.background.withAlpha(125), - BlendMode.darken, - ), - fit: BoxFit.cover, - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 16, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - category.name!, - style: const TextStyle(color: Colors.white), - ).h3(), - Button.link( - onPressed: () { - context.pushNamed( - GenrePlaylistsPage.name, - pathParameters: {'categoryId': category.id!}, - extra: category, - ); - }, - child: Text( - context.l10n.view_all, - style: const TextStyle(color: Colors.white), - ).muted(), - ), - ], - ), - Expanded( - child: Skeleton.ignore( - child: Skeletonizer( - enabled: playlists.isLoading, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: playlistsData.length, - separatorBuilder: (context, index) => - const Gap(12), - itemBuilder: (context, index) { - final playlist = - playlistsData.elementAt(index); - - return Container( - width: 115 * theme.scaling, - decoration: BoxDecoration( - color: theme.colorScheme.background - .withAlpha(75), - borderRadius: theme.borderRadiusMd, - ), - child: SurfaceBlur( - borderRadius: theme.borderRadiusMd, - surfaceBlur: theme.surfaceBlur, - child: Button( - style: - ButtonVariance.secondary.copyWith( - padding: (context, states, value) => - const EdgeInsets.all(8), - decoration: (context, states, value) { - final decoration = ButtonVariance - .secondary - .decoration(context, states) - as BoxDecoration; - - if (states.isNotEmpty) { - return decoration; - } - - return decoration.copyWith( - color: decoration.color - ?.withAlpha(180), - ); - }, - ), - onPressed: () { - context.pushNamed( - PlaylistPage.name, - pathParameters: { - "id": playlist.id!, - }, - extra: playlist, - ); - }, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - spacing: 5, - children: [ - ClipRRect( - borderRadius: - theme.borderRadiusSm, - child: UniversalImage( - path: (playlist.images)! - .asUrlString( - placeholder: ImagePlaceholder - .collection, - index: 1, - ), - fit: BoxFit.cover, - height: 100 * theme.scaling, - width: 100 * theme.scaling, - ), - ), - Text( - playlist.name!, - maxLines: 2, - overflow: TextOverflow.ellipsis, - ).semiBold().small(), - if (playlist.description != null) - Text( - playlist.description - ?.unescapeHtml() - .cleanHtml() ?? - "", - maxLines: 2, - overflow: TextOverflow.ellipsis, - ).xSmall().muted(), - ], - ), - ), - ), - ); - }, - ), - ), - ), - ) - ], - ), - ); - }, - ), - ), - Positioned( - left: 0, - child: Container( - height: 280 * theme.scaling, - width: (mediaQuery.mdAndUp ? 80 : 50) * theme.scaling, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [ - theme.colorScheme.background.withAlpha(255), - theme.colorScheme.background.withAlpha(0), - ], - ), - ), - alignment: Alignment.center, - child: IconButton.ghost( - size: - mediaQuery.mdAndUp ? ButtonSize.normal : ButtonSize.small, - icon: const Icon(SpotubeIcons.angleLeft), - onPressed: () { - controller.animatePrevious( - const Duration(seconds: 1), - ); - interactedRef.value = true; - }, - ), - ), - ), - Positioned( - right: 0, - child: Container( - height: 280 * theme.scaling, - width: (mediaQuery.mdAndUp ? 80 : 50) * theme.scaling, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [ - theme.colorScheme.background.withAlpha(0), - theme.colorScheme.background.withAlpha(255), - ], - ), - ), - alignment: Alignment.center, - child: IconButton.ghost( - size: - mediaQuery.mdAndUp ? ButtonSize.normal : ButtonSize.small, - icon: const Icon(SpotubeIcons.angleRight), - onPressed: () { - controller.animateNext( - const Duration(seconds: 1), - ); - interactedRef.value = true; - }, - ), - ), - ), - ], - ), - const Gap(8), - Center( - child: CarouselDotIndicator( - itemCount: categories.length, - controller: controller, - ), - ), - ], - ); - } -} diff --git a/lib/modules/home/sections/genres/genre_card.dart b/lib/modules/home/sections/genres/genre_card.dart new file mode 100644 index 00000000..722e6644 --- /dev/null +++ b/lib/modules/home/sections/genres/genre_card.dart @@ -0,0 +1,114 @@ +import 'dart:math'; +import 'dart:ui'; + +import 'package:go_router/go_router.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:skeletonizer/skeletonizer.dart'; +import 'package:spotify/spotify.dart' hide Offset; +import 'package:spotube/collections/fake.dart'; +import 'package:spotube/collections/gradients.dart'; +import 'package:spotube/components/image/universal_image.dart'; +import 'package:spotube/extensions/context.dart'; +import 'package:spotube/modules/home/sections/genres/genre_card_playlist_card.dart'; +import 'package:spotube/pages/home/genres/genre_playlists.dart'; +import 'package:spotube/provider/spotify/spotify.dart'; + +final random = Random(); +final gradientState = StateProvider.family( + (ref, String id) => gradients[random.nextInt(gradients.length)], +); + +class GenreSectionCard extends HookConsumerWidget { + final Category category; + const GenreSectionCard({ + super.key, + required this.category, + }); + + @override + Widget build(BuildContext context, ref) { + final theme = Theme.of(context); + final playlists = category == FakeData.category + ? null + : ref.watch(categoryPlaylistsProvider(category.id!)); + final playlistsData = playlists?.asData?.value.items.take(8) ?? + List.generate(5, (index) => FakeData.playlistSimple); + + final randomGradient = ref.watch(gradientState(category.id!)); + + return Container( + margin: const EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + borderRadius: theme.borderRadiusXxl, + boxShadow: [ + BoxShadow( + color: theme.colorScheme.foreground, + offset: const Offset(0, 5), + blurRadius: 7, + spreadRadius: -5, + ), + ], + image: DecorationImage( + image: UniversalImage.imageProvider( + category.icons!.first.url!, + ), + fit: BoxFit.cover, + ), + ), + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + borderRadius: theme.borderRadiusXxl, + gradient: randomGradient + .withOpacity(theme.brightness == Brightness.dark ? 0.2 : 0.7), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 16, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + category.name!, + style: const TextStyle(color: Colors.white), + ).h3(), + Button.link( + onPressed: () { + context.pushNamed( + GenrePlaylistsPage.name, + pathParameters: {'categoryId': category.id!}, + extra: category, + ); + }, + child: Text( + context.l10n.view_all, + style: const TextStyle(color: Colors.white), + ).muted(), + ), + ], + ), + Expanded( + child: Skeleton.ignore( + child: Skeletonizer( + enabled: playlists?.isLoading ?? false, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: playlistsData.length, + separatorBuilder: (context, index) => const Gap(12), + itemBuilder: (context, index) { + final playlist = playlistsData.elementAt(index); + + return GenreSectionCardPlaylistCard(playlist: playlist); + }, + ), + ), + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/modules/home/sections/genres/genre_card_playlist_card.dart b/lib/modules/home/sections/genres/genre_card_playlist_card.dart new file mode 100644 index 00000000..bbc42c61 --- /dev/null +++ b/lib/modules/home/sections/genres/genre_card_playlist_card.dart @@ -0,0 +1,88 @@ +import 'package:go_router/go_router.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotify/spotify.dart'; +import 'package:spotube/components/image/universal_image.dart'; +import 'package:spotube/extensions/image.dart'; +import 'package:spotube/extensions/string.dart'; +import 'package:spotube/pages/playlist/playlist.dart'; + +class GenreSectionCardPlaylistCard extends HookConsumerWidget { + final PlaylistSimple playlist; + const GenreSectionCardPlaylistCard({ + super.key, + required this.playlist, + }); + + @override + Widget build(BuildContext context, ref) { + final theme = Theme.of(context); + + return Container( + width: 115 * theme.scaling, + decoration: BoxDecoration( + color: theme.colorScheme.background.withAlpha(75), + borderRadius: theme.borderRadiusMd, + ), + child: SurfaceBlur( + borderRadius: theme.borderRadiusMd, + surfaceBlur: theme.surfaceBlur, + child: Button( + style: ButtonVariance.secondary.copyWith( + padding: (context, states, value) => const EdgeInsets.all(8), + decoration: (context, states, value) { + final decoration = ButtonVariance.secondary + .decoration(context, states) as BoxDecoration; + + if (states.isNotEmpty) { + return decoration; + } + + return decoration.copyWith( + color: decoration.color?.withAlpha(180), + ); + }, + ), + onPressed: () { + context.pushNamed( + PlaylistPage.name, + pathParameters: { + "id": playlist.id!, + }, + extra: playlist, + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + ClipRRect( + borderRadius: theme.borderRadiusSm, + child: UniversalImage( + path: (playlist.images)!.asUrlString( + placeholder: ImagePlaceholder.collection, + index: 1, + ), + fit: BoxFit.cover, + height: 100 * theme.scaling, + width: 100 * theme.scaling, + ), + ), + Text( + playlist.name!, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ).semiBold().small(), + if (playlist.description != null) + Text( + playlist.description?.unescapeHtml().cleanHtml() ?? "", + maxLines: 2, + overflow: TextOverflow.ellipsis, + ).xSmall().muted(), + ], + ), + ), + ), + ); + } +} diff --git a/lib/modules/home/sections/genres/genres.dart b/lib/modules/home/sections/genres/genres.dart new file mode 100644 index 00000000..5e6fa330 --- /dev/null +++ b/lib/modules/home/sections/genres/genres.dart @@ -0,0 +1,180 @@ +import 'dart:async'; + +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:skeletonizer/skeletonizer.dart'; +import 'package:spotube/collections/fake.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/extensions/constrains.dart'; +import 'package:spotube/extensions/context.dart'; +import 'package:spotube/modules/home/sections/genres/genre_card.dart'; +import 'package:spotube/pages/home/genres/genres.dart'; +import 'package:spotube/provider/spotify/spotify.dart'; + +class HomeGenresSection extends HookConsumerWidget { + const HomeGenresSection({super.key}); + + @override + Widget build(BuildContext context, ref) { + final theme = context.theme; + final mediaQuery = MediaQuery.sizeOf(context); + + final categoriesQuery = ref.watch(categoriesProvider); + final categories = useMemoized( + () => + categoriesQuery.asData?.value + .where((c) => (c.icons?.length ?? 0) > 0) + .take(6) + .toList() ?? + [ + FakeData.category, + ], + [categoriesQuery.asData?.value], + ); + final controller = useMemoized(() => CarouselController(), []); + final interactedRef = useRef(false); + + useEffect(() { + int times = 0; + final timer = Timer.periodic( + const Duration(seconds: 5), + (timer) { + if (times > 5 || interactedRef.value) { + timer.cancel(); + return; + } + controller.animateNext( + const Duration(seconds: 2), + ); + times++; + }, + ); + + return () { + timer.cancel(); + }; + }, []); + + return SliverList.list( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + context.l10n.genres, + style: context.theme.typography.h4, + ), + Button.link( + onPressed: () { + context.pushNamed(GenrePage.name); + }, + trailing: const Icon(SpotubeIcons.angleRight), + child: Text( + context.l10n.browse_all, + ).muted(), + ), + ], + ), + ), + const Gap(8), + Stack( + children: [ + SizedBox( + height: 280 * theme.scaling, + child: Carousel( + controller: controller, + transition: const CarouselTransition.sliding(gap: 24), + sizeConstraint: CarouselSizeConstraint.fixed( + mediaQuery.mdAndUp + ? mediaQuery.width * .6 + : mediaQuery.width * .95, + ), + itemCount: categories.length, + pauseOnHover: true, + direction: Axis.horizontal, + itemBuilder: (context, index) { + final category = categories[index]; + + return Skeletonizer( + enabled: categoriesQuery.isLoading, + child: GenreSectionCard(category: category), + ); + }, + ), + ), + Positioned( + left: 0, + child: Container( + height: 280 * theme.scaling, + width: (mediaQuery.mdAndUp ? 80 : 50) * theme.scaling, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + theme.colorScheme.background.withAlpha(255), + theme.colorScheme.background.withAlpha(0), + ], + ), + ), + alignment: Alignment.center, + child: IconButton.ghost( + size: + mediaQuery.mdAndUp ? ButtonSize.normal : ButtonSize.small, + icon: const Icon(SpotubeIcons.angleLeft), + onPressed: () { + controller.animatePrevious( + const Duration(seconds: 1), + ); + interactedRef.value = true; + }, + ), + ), + ), + Positioned( + right: 0, + child: Container( + height: 280 * theme.scaling, + width: (mediaQuery.mdAndUp ? 80 : 50) * theme.scaling, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + theme.colorScheme.background.withAlpha(0), + theme.colorScheme.background.withAlpha(255), + ], + ), + ), + alignment: Alignment.center, + child: IconButton.ghost( + size: + mediaQuery.mdAndUp ? ButtonSize.normal : ButtonSize.small, + icon: const Icon(SpotubeIcons.angleRight), + onPressed: () { + controller.animateNext( + const Duration(seconds: 1), + ); + interactedRef.value = true; + }, + ), + ), + ), + ], + ), + const Gap(8), + Center( + child: CarouselDotIndicator( + itemCount: categories.length, + controller: controller, + ), + ), + ], + ); + } +} diff --git a/lib/modules/player/player_overlay_collapsed.dart b/lib/modules/player/player_overlay_collapsed.dart index 52847c40..d0961ade 100644 --- a/lib/modules/player/player_overlay_collapsed.dart +++ b/lib/modules/player/player_overlay_collapsed.dart @@ -40,7 +40,6 @@ class PlayerOverlayCollapsedSection extends HookConsumerWidget { ? Padding( padding: const EdgeInsets.all(5), child: SurfaceCard( - borderWidth: 0, surfaceBlur: theme.surfaceBlur, surfaceOpacity: theme.surfaceOpacity, padding: EdgeInsets.zero, diff --git a/lib/modules/root/spotube_navigation_bar.dart b/lib/modules/root/spotube_navigation_bar.dart index 8d3e71f4..c19b3a40 100644 --- a/lib/modules/root/spotube_navigation_bar.dart +++ b/lib/modules/root/spotube_navigation_bar.dart @@ -55,25 +55,30 @@ class SpotubeNavigationBar extends HookConsumerWidget { duration: const Duration(milliseconds: 100), height: panelHeight, child: SingleChildScrollView( - child: NavigationBar( - index: selectedIndex, - surfaceBlur: context.theme.surfaceBlur, - surfaceOpacity: context.theme.surfaceOpacity, - onSelected: (i) { - ServiceUtils.navigateNamed(context, navbarTileList[i].name); - }, + child: Column( children: [ - for (final tile in navbarTileList) - NavigationButton( - style: const ButtonStyle.muted(density: ButtonDensity.icon), - selectedStyle: - const ButtonStyle.fixed(density: ButtonDensity.icon), - child: Badge( - isLabelVisible: tile.id == "library" && downloadCount > 0, - label: Text(downloadCount.toString()), - child: Icon(tile.icon), - ), - ) + const Divider(), + NavigationBar( + index: selectedIndex, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: context.theme.surfaceOpacity, + onSelected: (i) { + ServiceUtils.navigateNamed(context, navbarTileList[i].name); + }, + children: [ + for (final tile in navbarTileList) + NavigationButton( + style: const ButtonStyle.muted(density: ButtonDensity.icon), + selectedStyle: + const ButtonStyle.fixed(density: ButtonDensity.icon), + child: Badge( + isLabelVisible: tile.id == "library" && downloadCount > 0, + label: Text(downloadCount.toString()), + child: Icon(tile.icon), + ), + ) + ], + ), ], ), ), diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart index 2dfbc0f3..ea0a651b 100644 --- a/lib/pages/home/home.dart +++ b/lib/pages/home/home.dart @@ -10,7 +10,7 @@ import 'package:spotube/modules/connect/connect_device.dart'; import 'package:spotube/modules/home/sections/featured.dart'; import 'package:spotube/modules/home/sections/feed.dart'; import 'package:spotube/modules/home/sections/friends.dart'; -import 'package:spotube/modules/home/sections/genres.dart'; +import 'package:spotube/modules/home/sections/genres/genres.dart'; import 'package:spotube/modules/home/sections/made_for_user.dart'; import 'package:spotube/modules/home/sections/new_releases.dart'; import 'package:spotube/modules/home/sections/recent.dart'; From 5a14f587a0cbecf5678c928c76d00f5d4a662a0d Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 10 Jan 2025 20:33:59 +0600 Subject: [PATCH 44/81] chore: titlebar buttons not working --- lib/components/titlebar/titlebar.dart | 2 + lib/components/titlebar/titlebar_buttons.dart | 17 +++++---- lib/components/titlebar/window_button.dart | 22 ++++------- lib/pages/home/home.dart | 2 +- lib/pages/library/library.dart | 37 +++++++++++-------- lib/pages/search/search.dart | 4 +- lib/pages/stats/stats.dart | 2 +- 7 files changed, 44 insertions(+), 42 deletions(-) diff --git a/lib/components/titlebar/titlebar.dart b/lib/components/titlebar/titlebar.dart index cba33ab4..215b63ed 100644 --- a/lib/components/titlebar/titlebar.dart +++ b/lib/components/titlebar/titlebar.dart @@ -7,6 +7,8 @@ import 'package:spotube/provider/user_preferences/user_preferences_provider.dart import 'package:spotube/utils/platform.dart'; import 'package:window_manager/window_manager.dart'; +final kTitlebarVisible = kIsWindows || kIsLinux; + class TitleBar extends HookConsumerWidget implements PreferredSizeWidget { final bool automaticallyImplyLeading; final List trailing; diff --git a/lib/components/titlebar/titlebar_buttons.dart b/lib/components/titlebar/titlebar_buttons.dart index 35cdf08e..42765d7b 100644 --- a/lib/components/titlebar/titlebar_buttons.dart +++ b/lib/components/titlebar/titlebar_buttons.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/components/titlebar/titlebar_icon_buttons.dart'; import 'package:spotube/components/titlebar/window_button.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; @@ -20,6 +22,7 @@ class WindowTitleBarButtons extends HookConsumerWidget { final preferences = ref.watch(userPreferencesProvider); final isMaximized = useState(null); const type = ThemeType.auto; + final scale = context.theme.scaling; Future onClose() async { await windowManager.close(); @@ -34,7 +37,7 @@ class WindowTitleBarButtons extends HookConsumerWidget { return null; }, []); - if (!kIsDesktop || kIsMacOS || preferences.systemTitleBar) { + if (!kTitlebarVisible || preferences.systemTitleBar) { return const SizedBox.shrink(); } @@ -43,8 +46,8 @@ class WindowTitleBarButtons extends HookConsumerWidget { final colors = WindowButtonColors( normal: Colors.transparent, iconNormal: foregroundColor ?? theme.colorScheme.onSurface, - mouseOver: theme.colorScheme.onSurface.withOpacity(0.1), - mouseDown: theme.colorScheme.onSurface.withOpacity(0.2), + mouseOver: theme.colorScheme.onSurface.withAlpha(25), + mouseDown: theme.colorScheme.onSurface.withAlpha(51), iconMouseOver: theme.colorScheme.onSurface, iconMouseDown: theme.colorScheme.onSurface, ); @@ -58,8 +61,8 @@ class WindowTitleBarButtons extends HookConsumerWidget { iconMouseDown: Colors.black, ); - return Padding( - padding: const EdgeInsets.only(bottom: 25), + return Transform( + transform: Matrix4.translationValues(18, -12, 0) * scale, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -92,8 +95,8 @@ class WindowTitleBarButtons extends HookConsumerWidget { ); } - return Padding( - padding: const EdgeInsets.only(bottom: 20, left: 10), + return Transform( + transform: Matrix4.translationValues(18, -12, 0) * scale, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/components/titlebar/window_button.dart b/lib/components/titlebar/window_button.dart index 3201d191..fef9d754 100644 --- a/lib/components/titlebar/window_button.dart +++ b/lib/components/titlebar/window_button.dart @@ -1,8 +1,6 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/titlebar/mouse_state.dart'; +import 'package:spotube/components/titlebar/titlebar.dart'; typedef WindowButtonIconBuilder = Widget Function( WindowButtonContext buttonContext); @@ -86,14 +84,7 @@ class WindowButton extends StatelessWidget { @override Widget build(BuildContext context) { - if (kIsWeb) { - return Container(); - } else { - // Don't show button on macOS - if (Platform.isMacOS) { - return Container(); - } - } + if (!kTitlebarVisible) return const SizedBox.shrink(); return MouseStateBuilder( builder: (context, mouseState) { @@ -103,11 +94,12 @@ class WindowButton extends StatelessWidget { backgroundColor: getBackgroundColor(mouseState), iconColor: getIconColor(mouseState)); - var icon = - (iconBuilder != null) ? iconBuilder!(buttonContext) : Container(); + var icon = (iconBuilder != null) + ? iconBuilder!(buttonContext) + : const SizedBox(); var fadeOutColor = - getBackgroundColor(MouseState()..isMouseOver = true).withOpacity(0); + getBackgroundColor(MouseState()..isMouseOver = true).withAlpha(0); var padding = this.padding ?? const EdgeInsets.all(10); var animationMs = mouseState.isMouseOver ? (animate ? 100 : 0) : (animate ? 200 : 0); diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart index ea0a651b..78371c4d 100644 --- a/lib/pages/home/home.dart +++ b/lib/pages/home/home.dart @@ -36,7 +36,7 @@ class HomePage extends HookConsumerWidget { bottom: false, child: Scaffold( headers: [ - if (kIsWindows || kIsLinux) const TitleBar(), + if (kTitlebarVisible) const TitleBar(), ], child: CustomScrollView( controller: controller, diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index e107f413..87b6a6cb 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart' show Badge; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/modules/library/user_local_tracks.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -11,7 +12,6 @@ import 'package:spotube/modules/library/user_downloads.dart'; import 'package:spotube/modules/library/user_playlists.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/download_manager_provider.dart'; -import 'package:spotube/utils/platform.dart'; class LibraryPage extends HookConsumerWidget { static const name = "library"; @@ -19,6 +19,7 @@ class LibraryPage extends HookConsumerWidget { const LibraryPage({super.key}); @override Widget build(BuildContext context, ref) { + final scale = context.theme.scaling; final downloadingCount = ref.watch(downloadManagerProvider).$downloadCount; final index = useState(0); @@ -38,20 +39,26 @@ class LibraryPage extends HookConsumerWidget { bottom: false, child: Scaffold( headers: [ - if (kIsWindows || kIsLinux) const TitleBar(), - SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: TabList( - index: index.value, - children: [ - for (final child in children) - TabButton( - child: child, - onPressed: () { - index.value = children.indexOf(child); - }, - ), - ], + TitleBar( + padding: const EdgeInsets.symmetric( + horizontal: 18, + vertical: 12, + ).copyWith(left: 0) * + scale, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: TabList( + index: index.value, + children: [ + for (final child in children) + TabButton( + child: child, + onPressed: () { + index.value = children.indexOf(child); + }, + ), + ], + ), ), ), const Gap(10), diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index 9e2bf20c..d0f59ce2 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -19,7 +19,6 @@ import 'package:spotube/pages/search/sections/tracks.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/services/kv_store/kv_store.dart'; -import 'package:spotube/utils/platform.dart'; class SearchPage extends HookConsumerWidget { static const name = "search"; @@ -70,8 +69,7 @@ class SearchPage extends HookConsumerWidget { bottom: false, child: Scaffold( headers: [ - if (kIsWindows || kIsLinux) - const TitleBar(automaticallyImplyLeading: true) + if (kTitlebarVisible) const TitleBar(automaticallyImplyLeading: true) ], child: auth.asData?.value == null ? const AnonymousFallback() diff --git a/lib/pages/stats/stats.dart b/lib/pages/stats/stats.dart index a17e7562..e543900c 100644 --- a/lib/pages/stats/stats.dart +++ b/lib/pages/stats/stats.dart @@ -16,7 +16,7 @@ class StatsPage extends HookConsumerWidget { bottom: false, child: Scaffold( headers: [ - if (kIsWindows || kIsLinux) const TitleBar(), + if (kTitlebarVisible) const TitleBar(), ], child: CustomScrollView( slivers: [ From b25ae332b86d0a86f0200ce3af821f619b71b4b6 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 10 Jan 2025 23:41:22 +0600 Subject: [PATCH 45/81] feat: flag to hide spotify generated images with patterns --- assets/patterns/black_white_visualized.jpg | Bin 0 -> 343650 bytes assets/patterns/brazil_carnival.jpg | Bin 0 -> 80205 bytes assets/patterns/cotton_balls.jpg | Bin 0 -> 509803 bytes assets/patterns/cute_worms.jpg | Bin 0 -> 34160 bytes assets/patterns/flash_cross_axis.jpg | Bin 0 -> 41323 bytes assets/patterns/memphis_shapes.jpg | Bin 0 -> 175703 bytes assets/patterns/oval_gloomy.jpg | Bin 0 -> 144698 bytes assets/patterns/oval_sunny.jpg | Bin 0 -> 162271 bytes assets/patterns/red_nimbuses.jpg | Bin 0 -> 184678 bytes assets/patterns/tree_bark.jpg | Bin 0 -> 51461 bytes assets/patterns/vibrant_pentagons.jpg | Bin 0 -> 171063 bytes assets/patterns/wiring_pattern.jpg | Bin 0 -> 70479 bytes assets/patterns/zigzags_gloomy.jpg | Bin 0 -> 52678 bytes assets/patterns/zigzags_sunny.jpg | Bin 0 -> 50600 bytes lib/collections/assets.gen.dart | 79 ++++++++++++++++++ lib/collections/env.dart | 5 ++ .../playbutton_view/playbutton_card.dart | 39 ++++++--- .../playbutton_view/playbutton_tile.dart | 42 ++++++---- .../track_presentation/presentation_top.dart | 34 ++++++-- lib/models/spotify/home_feed.dart | 2 +- .../genres/genre_card_playlist_card.dart | 66 ++++++++++++--- lib/modules/playlist/playlist_card.dart | 50 ++++++++++- lib/provider/spotify/playlist/playlist.dart | 36 ++++++++ lib/provider/spotify/spotify.dart | 2 + pubspec.yaml | 1 + 25 files changed, 307 insertions(+), 49 deletions(-) create mode 100644 assets/patterns/black_white_visualized.jpg create mode 100644 assets/patterns/brazil_carnival.jpg create mode 100644 assets/patterns/cotton_balls.jpg create mode 100644 assets/patterns/cute_worms.jpg create mode 100644 assets/patterns/flash_cross_axis.jpg create mode 100644 assets/patterns/memphis_shapes.jpg create mode 100644 assets/patterns/oval_gloomy.jpg create mode 100644 assets/patterns/oval_sunny.jpg create mode 100644 assets/patterns/red_nimbuses.jpg create mode 100644 assets/patterns/tree_bark.jpg create mode 100644 assets/patterns/vibrant_pentagons.jpg create mode 100644 assets/patterns/wiring_pattern.jpg create mode 100644 assets/patterns/zigzags_gloomy.jpg create mode 100644 assets/patterns/zigzags_sunny.jpg diff --git a/assets/patterns/black_white_visualized.jpg b/assets/patterns/black_white_visualized.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e56a2780440cfdfbaa91f0aa6b4c0022545b3b95 GIT binary patch literal 343650 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

dDjY$6O3N~ZsLJ& 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

lOoZ&k#C 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[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 literal 0 HcmV?d00001 diff --git a/assets/patterns/brazil_carnival.jpg b/assets/patterns/brazil_carnival.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a7cdb3a1108080409232987b93fb607a5724c729 GIT binary patch literal 80205 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 jQ|LDlSMcHI-SA;Zpke~3pNZ=m9->LrtDQPt; literal 0 HcmV?d00001 diff --git a/assets/patterns/cotton_balls.jpg b/assets/patterns/cotton_balls.jpg new file mode 100644 index 0000000000000000000000000000000000000000..db6f02a88997585ad0e51f40f3d9333f38d5c273 GIT binary patch literal 509803 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 {c0!=+Q}HD9D~h7FyADfQVZM@fJvDkSq;p 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

-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

8Zi=WXV2#WAr#7f;+77Bg$xCwjQo6xOV47 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 LP*J67r*r=WT5u>t literal 0 HcmV?d00001 diff --git a/assets/patterns/cute_worms.jpg b/assets/patterns/cute_worms.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0c9f4fbbba9004a4be79f0c1ff08bca3cfb85454 GIT binary patch literal 34160 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

4I|zXEn&}LdA~+tSwWiN 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 Bmnr}N literal 0 HcmV?d00001 diff --git a/assets/patterns/memphis_shapes.jpg b/assets/patterns/memphis_shapes.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2db8e775a0dcd706f86274faeed66991f56066af GIT binary patch literal 175703 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

P+;#Y~ia9LzQn6?@KJ*=T0x6B(hxoKP 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%0DbAu0>y4F@UCFwMQS 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 pUE?e&3!34W1Tg-5)l9A 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 aob!ZVIio6260Ex|Yj6)6e_{UF_WuBco4IoU literal 0 HcmV?d00001 diff --git a/assets/patterns/red_nimbuses.jpg b/assets/patterns/red_nimbuses.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6527999ceb457f7e5a1986ac285ba7a3f6ddd293 GIT binary patch literal 184678 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 Gi~kGB4i1q3 literal 0 HcmV?d00001 diff --git a/assets/patterns/tree_bark.jpg b/assets/patterns/tree_bark.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0dac37d7fdf28897de0ecfcda9fe73242baf0b68 GIT binary patch literal 51461 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

R8s1e}%=!G&f(kOZz4QiP! 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�bUFYe+UYZDHr`C2WhBVZS9&cy}hZLSWr5 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 literal 0 HcmV?d00001 diff --git a/assets/patterns/zigzags_gloomy.jpg b/assets/patterns/zigzags_gloomy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c6ccd2a3ea40d5f1bdc5a5592f3cd749b8d55522 GIT binary patch literal 52678 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 get values => [songlinkTransparent, songlink]; } +class $AssetsPatternsGen { + const $AssetsPatternsGen(); + + /// File path: assets/patterns/black_white_visualized.jpg + AssetGenImage get blackWhiteVisualized => + const AssetGenImage('assets/patterns/black_white_visualized.jpg'); + + /// File path: assets/patterns/brazil_carnival.jpg + AssetGenImage get brazilCarnival => + const AssetGenImage('assets/patterns/brazil_carnival.jpg'); + + /// File path: assets/patterns/cotton_balls.jpg + AssetGenImage get cottonBalls => + const AssetGenImage('assets/patterns/cotton_balls.jpg'); + + /// File path: assets/patterns/cute_worms.jpg + AssetGenImage get cuteWorms => + const AssetGenImage('assets/patterns/cute_worms.jpg'); + + /// File path: assets/patterns/flash_cross_axis.jpg + AssetGenImage get flashCrossAxis => + const AssetGenImage('assets/patterns/flash_cross_axis.jpg'); + + /// File path: assets/patterns/memphis_shapes.jpg + AssetGenImage get memphisShapes => + const AssetGenImage('assets/patterns/memphis_shapes.jpg'); + + /// File path: assets/patterns/oval_gloomy.jpg + AssetGenImage get ovalGloomy => + const AssetGenImage('assets/patterns/oval_gloomy.jpg'); + + /// File path: assets/patterns/oval_sunny.jpg + AssetGenImage get ovalSunny => + const AssetGenImage('assets/patterns/oval_sunny.jpg'); + + /// File path: assets/patterns/red_nimbuses.jpg + AssetGenImage get redNimbuses => + const AssetGenImage('assets/patterns/red_nimbuses.jpg'); + + /// File path: assets/patterns/tree_bark.jpg + AssetGenImage get treeBark => + const AssetGenImage('assets/patterns/tree_bark.jpg'); + + /// File path: assets/patterns/vibrant_pentagons.jpg + AssetGenImage get vibrantPentagons => + const AssetGenImage('assets/patterns/vibrant_pentagons.jpg'); + + /// File path: assets/patterns/wiring_pattern.jpg + AssetGenImage get wiringPattern => + const AssetGenImage('assets/patterns/wiring_pattern.jpg'); + + /// File path: assets/patterns/zigzags_gloomy.jpg + AssetGenImage get zigzagsGloomy => + const AssetGenImage('assets/patterns/zigzags_gloomy.jpg'); + + /// File path: assets/patterns/zigzags_sunny.jpg + AssetGenImage get zigzagsSunny => + const AssetGenImage('assets/patterns/zigzags_sunny.jpg'); + + /// List of all assets + List get values => [ + blackWhiteVisualized, + brazilCarnival, + cottonBalls, + cuteWorms, + flashCrossAxis, + memphisShapes, + ovalGloomy, + ovalSunny, + redNimbuses, + treeBark, + vibrantPentagons, + wiringPattern, + zigzagsGloomy, + zigzagsSunny + ]; +} + class $AssetsTutorialGen { const $AssetsTutorialGen(); @@ -67,6 +145,7 @@ class Assets { static const AssetGenImage likedTracks = AssetGenImage('assets/liked-tracks.jpg'); static const $AssetsLogosGen logos = $AssetsLogosGen(); + static const $AssetsPatternsGen patterns = $AssetsPatternsGen(); static const AssetGenImage placeholder = AssetGenImage('assets/placeholder.png'); static const AssetGenImage spotubeHeroBanner = diff --git a/lib/collections/env.dart b/lib/collections/env.dart index eb60851f..eb6c5639 100644 --- a/lib/collections/env.dart +++ b/lib/collections/env.dart @@ -38,6 +38,11 @@ abstract class Env { @EnviedField(varName: "RELEASE_CHANNEL", defaultValue: "nightly") static final String _releaseChannel = _Env._releaseChannel; + @EnviedField(varName: "DISABLE_SPOTIFY_IMAGES", defaultValue: "0") + static final int _disableSpotifyImages = _Env._disableSpotifyImages; + + static bool get disableSpotifyImages => _disableSpotifyImages == 1; + static ReleaseChannel get releaseChannel => _releaseChannel == "stable" ? ReleaseChannel.stable : ReleaseChannel.nightly; diff --git a/lib/components/playbutton_view/playbutton_card.dart b/lib/components/playbutton_view/playbutton_card.dart index 21016d57..05efef38 100644 --- a/lib/components/playbutton_view/playbutton_card.dart +++ b/lib/components/playbutton_view/playbutton_card.dart @@ -11,14 +11,14 @@ class PlaybuttonCard extends StatelessWidget { final void Function()? onAddToQueuePressed; final String? description; - final String imageUrl; + final String? imageUrl; + final Widget? image; final bool isPlaying; final bool isLoading; final String title; final bool isOwner; const PlaybuttonCard({ - required this.imageUrl, required this.isPlaying, required this.isLoading, required this.title, @@ -27,8 +27,13 @@ class PlaybuttonCard extends StatelessWidget { this.onAddToQueuePressed, this.onTap, this.isOwner = false, + this.imageUrl, + this.image, super.key, - }); + }) : assert( + imageUrl != null || image != null, + "imageUrl and image can't be null at the same time", + ); @override Widget build(BuildContext context) { @@ -40,17 +45,27 @@ class PlaybuttonCard extends StatelessWidget { child: CardImage( image: Stack( children: [ - Container( - width: 150 * scale, - height: 150 * scale, - decoration: BoxDecoration( - borderRadius: context.theme.borderRadiusMd, - image: DecorationImage( - image: UniversalImage.imageProvider(imageUrl), - fit: BoxFit.cover, + if (imageUrl != null) + Container( + width: 150 * scale, + height: 150 * scale, + decoration: BoxDecoration( + borderRadius: context.theme.borderRadiusMd, + image: DecorationImage( + image: UniversalImage.imageProvider(imageUrl!), + fit: BoxFit.cover, + ), + ), + ) + else + SizedBox( + width: 150 * scale, + height: 150 * scale, + child: ClipRRect( + borderRadius: context.theme.borderRadiusMd, + child: image!, ), ), - ), StatedWidget.builder( builder: (context, states) { return Positioned( diff --git a/lib/components/playbutton_view/playbutton_tile.dart b/lib/components/playbutton_view/playbutton_tile.dart index 3daaf75c..ec1ca95f 100644 --- a/lib/components/playbutton_view/playbutton_tile.dart +++ b/lib/components/playbutton_view/playbutton_tile.dart @@ -11,14 +11,14 @@ class PlaybuttonTile extends StatelessWidget { final void Function()? onAddToQueuePressed; final String? description; - final String imageUrl; + final String? imageUrl; + final Widget? image; final bool isPlaying; final bool isLoading; final String title; final bool isOwner; const PlaybuttonTile({ - required this.imageUrl, required this.isPlaying, required this.isLoading, required this.title, @@ -27,8 +27,13 @@ class PlaybuttonTile extends StatelessWidget { this.onAddToQueuePressed, this.onTap, this.isOwner = false, + this.imageUrl, + this.image, super.key, - }); + }) : assert( + imageUrl != null || image != null, + "imageUrl and image can't be null at the same time", + ); @override Widget build(BuildContext context) { @@ -36,17 +41,26 @@ class PlaybuttonTile extends StatelessWidget { final scale = context.theme.scaling; return Button( - leading: Container( - width: 50 * scale, - height: 50 * scale, - decoration: BoxDecoration( - borderRadius: context.theme.borderRadiusMd, - image: DecorationImage( - image: UniversalImage.imageProvider(imageUrl), - fit: BoxFit.cover, - ), - ), - ), + leading: imageUrl != null + ? Container( + width: 50 * scale, + height: 50 * scale, + decoration: BoxDecoration( + borderRadius: context.theme.borderRadiusMd, + image: DecorationImage( + image: UniversalImage.imageProvider(imageUrl!), + fit: BoxFit.cover, + ), + ), + ) + : SizedBox( + width: 50 * scale, + height: 50 * scale, + child: ClipRRect( + borderRadius: context.theme.borderRadiusMd, + child: image, + ), + ), style: ButtonVariance.ghost.copyWith( padding: (context, states, value) { return (ButtonVariance.ghost.padding(context, states) as EdgeInsets) diff --git a/lib/components/track_presentation/presentation_top.dart b/lib/components/track_presentation/presentation_top.dart index 59854aaf..8da2f51c 100644 --- a/lib/components/track_presentation/presentation_top.dart +++ b/lib/components/track_presentation/presentation_top.dart @@ -3,6 +3,8 @@ import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/env.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/heart_button/heart_button.dart'; import 'package:spotube/components/image/universal_image.dart'; @@ -12,6 +14,7 @@ import 'package:spotube/components/track_presentation/use_is_user_playlist.dart' import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/modules/playlist/playlist_create_dialog.dart'; +import 'package:spotube/provider/spotify/spotify.dart'; class TrackPresentationTopSection extends HookConsumerWidget { const TrackPresentationTopSection({super.key}); @@ -23,6 +26,26 @@ class TrackPresentationTopSection extends HookConsumerWidget { final scale = context.theme.scaling; final isUserPlaylist = useIsUserPlaylist(ref, options.collectionId); + final playlistImage = (options.collection is PlaylistSimple && + (options.collection as PlaylistSimple).owner?.displayName == + "Spotify" && + Env.disableSpotifyImages) + ? ref.watch(playlistImageProvider(options.collectionId)) + : null; + final decorationImage = playlistImage != null + ? DecorationImage( + image: AssetImage(playlistImage.src), + fit: BoxFit.cover, + colorFilter: ColorFilter.mode( + playlistImage.color, + playlistImage.colorBlendMode, + ), + ) + : DecorationImage( + image: UniversalImage.imageProvider(options.image), + fit: BoxFit.cover, + ); + final imageDimension = mediaQuery.mdAndUp ? 200 : 120; final (:isLoading, :isActive, :onPlay, :onShuffle) = @@ -153,10 +176,7 @@ class TrackPresentationTopSection extends HookConsumerWidget { children: [ DecoratedBox( decoration: BoxDecoration( - image: DecorationImage( - image: UniversalImage.imageProvider(options.image), - fit: BoxFit.cover, - ), + image: decorationImage, borderRadius: BorderRadius.circular(45), ), child: OutlinedContainer( @@ -179,11 +199,7 @@ class TrackPresentationTopSection extends HookConsumerWidget { width: imageDimension * scale, decoration: BoxDecoration( borderRadius: context.theme.borderRadiusXl, - image: DecorationImage( - image: - UniversalImage.imageProvider(options.image), - fit: BoxFit.cover, - ), + image: decorationImage, ), ), Flexible( diff --git a/lib/models/spotify/home_feed.dart b/lib/models/spotify/home_feed.dart index e5c2f666..ad764304 100644 --- a/lib/models/spotify/home_feed.dart +++ b/lib/models/spotify/home_feed.dart @@ -29,7 +29,7 @@ class SpotifySectionPlaylist with _$SpotifySectionPlaylist { ..description = description ..collaborative = false ..images = images.map((e) => e.asImage).toList() - ..owner = (User()..displayName = "Spotify") + ..owner = (User()..displayName = owner) ..uri = uri ..type = "playlist"; } diff --git a/lib/modules/home/sections/genres/genre_card_playlist_card.dart b/lib/modules/home/sections/genres/genre_card_playlist_card.dart index bbc42c61..0e2284b3 100644 --- a/lib/modules/home/sections/genres/genre_card_playlist_card.dart +++ b/lib/modules/home/sections/genres/genre_card_playlist_card.dart @@ -1,11 +1,14 @@ import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:spotify/spotify.dart'; +import 'package:spotify/spotify.dart' hide Image; +import 'package:spotube/collections/env.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/extensions/string.dart'; import 'package:spotube/pages/playlist/playlist.dart'; +import 'package:spotube/provider/spotify/spotify.dart'; +import 'package:stroke_text/stroke_text.dart'; class GenreSectionCardPlaylistCard extends HookConsumerWidget { final PlaylistSimple playlist; @@ -58,15 +61,58 @@ class GenreSectionCardPlaylistCard extends HookConsumerWidget { children: [ ClipRRect( borderRadius: theme.borderRadiusSm, - child: UniversalImage( - path: (playlist.images)!.asUrlString( - placeholder: ImagePlaceholder.collection, - index: 1, - ), - fit: BoxFit.cover, - height: 100 * theme.scaling, - width: 100 * theme.scaling, - ), + child: playlist.owner?.displayName == "Spotify" && + Env.disableSpotifyImages + ? Consumer( + builder: (context, ref, _) { + final (:src, :color, :colorBlendMode, :placement) = + ref.watch(playlistImageProvider(playlist.id!)); + return SizedBox( + height: 100 * theme.scaling, + width: 100 * theme.scaling, + child: Stack( + children: [ + Positioned.fill( + child: Image.asset( + src, + color: color, + colorBlendMode: colorBlendMode, + fit: BoxFit.cover, + ), + ), + Positioned.fill( + top: placement == Alignment.topLeft + ? 10 + : null, + left: 10, + bottom: placement == Alignment.bottomLeft + ? 10 + : null, + child: StrokeText( + text: playlist.name!, + strokeColor: Colors.white, + strokeWidth: 3, + textColor: Colors.black, + textStyle: const TextStyle( + fontSize: 16, + fontStyle: FontStyle.italic, + ), + ), + ), + ], + ), + ); + }, + ) + : UniversalImage( + path: (playlist.images)!.asUrlString( + placeholder: ImagePlaceholder.collection, + index: 1, + ), + fit: BoxFit.cover, + height: 100 * theme.scaling, + width: 100 * theme.scaling, + ), ), Text( playlist.name!, diff --git a/lib/modules/playlist/playlist_card.dart b/lib/modules/playlist/playlist_card.dart index 43f2ee4e..c24eb24b 100644 --- a/lib/modules/playlist/playlist_card.dart +++ b/lib/modules/playlist/playlist_card.dart @@ -1,8 +1,10 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:spotify/spotify.dart'; +import 'package:spotify/spotify.dart' hide Offset, Image; +import 'package:spotube/collections/env.dart'; import 'package:spotube/components/dialogs/select_device_dialog.dart'; +import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/playbutton_view/playbutton_card.dart'; import 'package:spotube/components/playbutton_view/playbutton_tile.dart'; import 'package:spotube/extensions/context.dart'; @@ -16,6 +18,7 @@ import 'package:spotube/provider/audio_player/audio_player.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/utils/service_utils.dart'; +import 'package:stroke_text/stroke_text.dart'; class PlaylistCard extends HookConsumerWidget { final PlaylistSimple playlist; @@ -168,11 +171,52 @@ class PlaylistCard extends HookConsumerWidget { final isOwner = playlist.owner?.id == me.asData?.value.id && me.asData?.value.id != null; + final image = + playlist.owner?.displayName == "Spotify" && Env.disableSpotifyImages + ? Consumer( + builder: (context, ref, child) { + final (:color, :colorBlendMode, :src, :placement) = + ref.watch(playlistImageProvider(playlist.id!)); + + return Stack( + children: [ + Positioned.fill( + child: Image.asset( + src, + color: color, + colorBlendMode: colorBlendMode, + fit: BoxFit.cover, + ), + ), + Positioned.fill( + top: placement == Alignment.topLeft ? 10 : null, + left: 10, + bottom: placement == Alignment.bottomLeft ? 10 : null, + child: StrokeText( + text: playlist.name!, + strokeColor: Colors.white, + strokeWidth: 3, + textColor: Colors.black, + textStyle: const TextStyle( + fontSize: 16, + fontStyle: FontStyle.italic, + ), + ), + ), + ], + ); + }, + ) + : UniversalImage( + path: imageUrl, + fit: BoxFit.cover, + ); + if (_isTile) { return PlaybuttonTile( title: playlist.name!, description: playlist.description, - imageUrl: imageUrl, + image: image, isPlaying: isPlaylistPlaying, isLoading: isLoading, isOwner: isOwner, @@ -185,7 +229,7 @@ class PlaylistCard extends HookConsumerWidget { return PlaybuttonCard( title: playlist.name!, description: playlist.description, - imageUrl: imageUrl, + image: image, isPlaying: isPlaylistPlaying, isLoading: isLoading, isOwner: isOwner, diff --git a/lib/provider/spotify/playlist/playlist.dart b/lib/provider/spotify/playlist/playlist.dart index 0eec3a87..6782fb35 100644 --- a/lib/provider/spotify/playlist/playlist.dart +++ b/lib/provider/spotify/playlist/playlist.dart @@ -104,3 +104,39 @@ final playlistProvider = AsyncNotifierProvider.family( () => PlaylistNotifier(), ); + +final _blendModes = BlendMode.values + .where((e) => switch (e) { + BlendMode.clear || + BlendMode.src || + BlendMode.srcATop || + BlendMode.srcIn || + BlendMode.srcOut || + BlendMode.srcOver || + BlendMode.dstOut || + BlendMode.xor => + false, + _ => true + }) + .toList(); + +typedef PlaylistImageInfo = ({ + Color color, + BlendMode colorBlendMode, + String src, + Alignment placement, +}); + +final playlistImageProvider = Provider.family( + (ref, playlistId) { + final random = Random(); + + return ( + color: Colors.primaries[random.nextInt(Colors.primaries.length)], + colorBlendMode: _blendModes[random.nextInt(_blendModes.length)], + src: Assets + .patterns.values[random.nextInt(Assets.patterns.values.length)].path, + placement: random.nextBool() ? Alignment.topLeft : Alignment.bottomLeft, + ); + }, +); diff --git a/lib/provider/spotify/spotify.dart b/lib/provider/spotify/spotify.dart index dbf3802b..344116cd 100644 --- a/lib/provider/spotify/spotify.dart +++ b/lib/provider/spotify/spotify.dart @@ -1,8 +1,10 @@ library spotify; import 'dart:async'; +import 'dart:math'; import 'package:drift/drift.dart'; +import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/database/database.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 35738548..7cd4cbbd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -172,6 +172,7 @@ flutter: - assets/tutorial/ - assets/logos/ - assets/backgrounds/ + - assets/patterns/ - LICENSE fonts: - family: GeistSans From a8694a7a8bf2bf55903cbb36fe7a3404d80ee35e Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 11 Jan 2025 20:08:04 +0600 Subject: [PATCH 46/81] refactor: blacklist and about page --- lib/modules/home/sections/genres/genres.dart | 1 + lib/pages/settings/about.dart | 108 ++++++++++--------- lib/pages/settings/blacklist.dart | 27 ++--- pubspec.lock | 4 +- pubspec.yaml | 2 +- 5 files changed, 79 insertions(+), 63 deletions(-) diff --git a/lib/modules/home/sections/genres/genres.dart b/lib/modules/home/sections/genres/genres.dart index 5e6fa330..520c1121 100644 --- a/lib/modules/home/sections/genres/genres.dart +++ b/lib/modules/home/sections/genres/genres.dart @@ -55,6 +55,7 @@ class HomeGenresSection extends HookConsumerWidget { return () { timer.cancel(); + controller.dispose(); }; }, []); diff --git a/lib/pages/settings/about.dart b/lib/pages/settings/about.dart index 491cdcf6..79c6692b 100644 --- a/lib/pages/settings/about.dart +++ b/lib/pages/settings/about.dart @@ -1,7 +1,8 @@ -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/env.dart'; +import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/links/hyper_link.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -26,14 +27,16 @@ class AboutSpotube extends HookConsumerWidget { final license = ref.watch(_licenseProvider); final theme = Theme.of(context); - const colon = Text(":"); + const colon = TableCell(child: Text(":")); return Scaffold( - appBar: TitleBar( - leading: const [BackButton()], - title: Text(context.l10n.about_spotube), - ), - body: SingleChildScrollView( + headers: [ + TitleBar( + leading: const [BackButton()], + title: Text(context.l10n.about_spotube), + ) + ], + child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Column( @@ -45,76 +48,85 @@ class AboutSpotube extends HookConsumerWidget { Center( child: Column( children: [ - Text( - context.l10n.spotube_description, - style: theme.textTheme.titleLarge, - ), + Text(context.l10n.spotube_description).semiBold().large(), const SizedBox(height: 20), Table( columnWidths: const { - 0: FixedColumnWidth(95), - 1: FixedColumnWidth(10), - 2: IntrinsicColumnWidth(), + 0: FixedTableSize(95), + 1: FixedTableSize(10), + 2: IntrinsicTableSize(), }, - children: [ + defaultRowHeight: const FixedTableSize(40), + rows: [ TableRow( - children: [ - Text(context.l10n.founder), + cells: [ + TableCell(child: Text(context.l10n.founder)), colon, - Hyperlink( - context.l10n.kingkor_roy_tirtho, - "https://github.com/KRTirtho", + TableCell( + child: Hyperlink( + context.l10n.kingkor_roy_tirtho, + "https://github.com/KRTirtho", + ), ) ], ), TableRow( - children: [ - Text(context.l10n.version), + cells: [ + TableCell(child: Text(context.l10n.version)), colon, - Text("v${packageInfo.version}") + TableCell(child: Text("v${packageInfo.version}")) ], ), TableRow( - children: [ - Text(context.l10n.channel), + cells: [ + TableCell(child: Text(context.l10n.channel)), colon, - Text(Env.releaseChannel.name) + TableCell(child: Text(Env.releaseChannel.name)) ], ), TableRow( - children: [ - Text(context.l10n.build_number), + cells: [ + TableCell(child: Text(context.l10n.build_number)), colon, - Text(packageInfo.buildNumber.replaceAll(".", " ")) + TableCell( + child: Text( + packageInfo.buildNumber.replaceAll(".", " ")), + ) ], ), TableRow( - children: [ - Text(context.l10n.repository), + cells: [ + TableCell(child: Text(context.l10n.repository)), colon, - const Hyperlink( - "github.com/KRTirtho/spotube", - "https://github.com/KRTirtho/spotube", + const TableCell( + child: Hyperlink( + "github.com/KRTirtho/spotube", + "https://github.com/KRTirtho/spotube", + ), ), ], ), TableRow( - children: [ - Text(context.l10n.license), + cells: [ + TableCell(child: Text(context.l10n.license)), colon, - const Hyperlink( - "BSD-4-Clause", - "https://raw.githubusercontent.com/KRTirtho/spotube/master/LICENSE", + const TableCell( + child: Hyperlink( + "BSD-4-Clause", + "https://raw.githubusercontent.com/KRTirtho/spotube/master/LICENSE", + ), ), ], ), TableRow( - children: [ - Text(context.l10n.bug_issues), + cells: [ + TableCell(child: Text(context.l10n.bug_issues)), colon, - const Hyperlink( - "github.com/KRTirtho/spotube/issues", - "https://github.com/KRTirtho/spotube/issues", + const TableCell( + child: Hyperlink( + "github.com/KRTirtho/spotube/issues", + "https://github.com/KRTirtho/spotube/issues", + ), ), ], ), @@ -141,12 +153,12 @@ class AboutSpotube extends HookConsumerWidget { Text( context.l10n.made_with, textAlign: TextAlign.center, - style: theme.textTheme.bodySmall, + style: theme.typography.small, ), Text( context.l10n.copyright(DateTime.now().year), textAlign: TextAlign.center, - style: theme.textTheme.bodySmall, + style: theme.typography.small, ), const SizedBox(height: 20), ConstrainedBox( @@ -156,7 +168,7 @@ class AboutSpotube extends HookConsumerWidget { data: (data) { return Text( data, - style: theme.textTheme.bodySmall, + style: theme.typography.small, ); }, loading: () { @@ -167,7 +179,7 @@ class AboutSpotube extends HookConsumerWidget { error: (e, s) { return Text( e.toString(), - style: theme.textTheme.bodySmall, + style: theme.typography.small, ); }, ), diff --git a/lib/pages/settings/blacklist.dart b/lib/pages/settings/blacklist.dart index 57a8b6fe..b525b1b5 100644 --- a/lib/pages/settings/blacklist.dart +++ b/lib/pages/settings/blacklist.dart @@ -1,12 +1,14 @@ -import 'package:flutter/material.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:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/blacklist_provider.dart'; @@ -44,21 +46,21 @@ class BlackListPage extends HookConsumerWidget { ); return Scaffold( - appBar: TitleBar( - title: Text(context.l10n.blacklist), - leading: const [BackButton()], - ), - body: Column( + headers: [ + TitleBar( + title: Text(context.l10n.blacklist), + leading: const [BackButton()], + ) + ], + child: 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), - ), + placeholder: Text(context.l10n.search), + leading: const Icon(SpotubeIcons.search), ), ), InterScrollbar( @@ -69,11 +71,12 @@ class BlackListPage extends HookConsumerWidget { itemCount: filteredBlacklist.length, itemBuilder: (context, index) { final item = filteredBlacklist.elementAt(index); - return ListTile( + return ButtonTile( + style: ButtonVariance.ghost, leading: Text("${index + 1}."), title: Text("${item.name} (${item.elementType.name})"), subtitle: Text(item.elementId), - trailing: IconButton( + trailing: IconButton.ghost( icon: Icon(SpotubeIcons.trash, color: Colors.red[400]), onPressed: () { ref diff --git a/pubspec.lock b/pubspec.lock index a43f4f2c..fbcdfd52 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1971,8 +1971,8 @@ packages: dependency: "direct main" description: path: "." - ref: fix-scaffold-footer-safearea - resolved-ref: "8ede34e1e3270ec3839192a7a6453e19cd00f9ab" + ref: d928e73cd734582046c63a3bed99cc42aeab6085 + resolved-ref: d928e73cd734582046c63a3bed99cc42aeab6085 url: "https://github.com/KRTirtho/shadcn_flutter.git" source: git version: "0.0.24" diff --git a/pubspec.yaml b/pubspec.yaml index 7cd4cbbd..7bbf15a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -105,7 +105,7 @@ dependencies: shadcn_flutter: git: url: https://github.com/KRTirtho/shadcn_flutter.git - ref: fix-scaffold-footer-safearea + ref: d928e73cd734582046c63a3bed99cc42aeab6085 shared_preferences: ^2.2.3 shelf: ^1.4.1 shelf_router: ^1.1.4 From b8ffb9b75f27076060104aedabe0ed15e11bdce0 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 12 Jan 2025 14:16:18 +0600 Subject: [PATCH 47/81] feat: show placeholder images where there is no item or on empty page --- lib/collections/assets.gen.dart | 13 ++ .../fallbacks/anonymous_fallback.dart | 12 +- .../playbutton_view/playbutton_view.dart | 100 +++++++--- .../track_presentation/presentation_list.dart | 27 +++ lib/l10n/app_en.arb | 7 +- lib/modules/getting_started/blur_card.dart | 7 +- lib/modules/home/sections/featured.dart | 17 ++ .../home/sections/genres/genre_card.dart | 29 +-- lib/modules/library/user_albums.dart | 52 +++-- lib/modules/library/user_artists.dart | 107 ++++++---- lib/modules/stats/top/albums.dart | 22 ++- lib/modules/stats/top/artists.dart | 22 ++- lib/modules/stats/top/tracks.dart | 22 ++- lib/pages/album/album.dart | 2 +- .../getting_started/getting_started.dart | 70 +++---- .../getting_started/sections/greeting.dart | 30 +-- .../getting_started/sections/playback.dart | 108 +++++------ .../getting_started/sections/region.dart | 162 +++++++++------- .../getting_started/sections/support.dart | 116 ++++++----- lib/pages/playlist/playlist.dart | 2 +- lib/pages/search/search.dart | 19 +- pubspec.lock | 30 +-- pubspec.yaml | 10 + untranslated_messages.json | 182 +++++++++++++++--- 24 files changed, 765 insertions(+), 403 deletions(-) diff --git a/lib/collections/assets.gen.dart b/lib/collections/assets.gen.dart index 004001f2..98b67c80 100644 --- a/lib/collections/assets.gen.dart +++ b/lib/collections/assets.gen.dart @@ -20,6 +20,17 @@ class $AssetsBackgroundsGen { List get values => [xmasEffect]; } +class $AssetsIllustrationsGen { + const $AssetsIllustrationsGen(); + + /// File path: assets/illustrations/fixing_bugs.png + AssetGenImage get fixingBugs => + const AssetGenImage('assets/illustrations/fixing_bugs.png'); + + /// List of all assets + List get values => [fixingBugs]; +} + class $AssetsLogosGen { const $AssetsLogosGen(); @@ -140,6 +151,8 @@ class Assets { AssetGenImage('assets/bengali-patterns-bg.jpg'); static const AssetGenImage branding = AssetGenImage('assets/branding.png'); static const AssetGenImage emptyBox = AssetGenImage('assets/empty_box.png'); + static const $AssetsIllustrationsGen illustrations = + $AssetsIllustrationsGen(); static const AssetGenImage invidious = AssetGenImage('assets/invidious.jpg'); static const AssetGenImage jiosaavn = AssetGenImage('assets/jiosaavn.png'); static const AssetGenImage likedTracks = diff --git a/lib/components/fallbacks/anonymous_fallback.dart b/lib/components/fallbacks/anonymous_fallback.dart index cd7a218f..373e0454 100644 --- a/lib/components/fallbacks/anonymous_fallback.dart +++ b/lib/components/fallbacks/anonymous_fallback.dart @@ -1,9 +1,12 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/settings/settings.dart'; import 'package:spotube/provider/authentication/authentication.dart'; +import 'package:spotube/utils/platform.dart'; import 'package:spotube/utils/service_utils.dart'; class AnonymousFallback extends ConsumerWidget { @@ -25,9 +28,16 @@ class AnonymousFallback extends ConsumerWidget { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, children: [ + Undraw( + illustration: kIsMobile + ? UndrawIllustration.accessDenied + : UndrawIllustration.secureLogin, + height: 200 * context.theme.scaling, + color: context.theme.colorScheme.primary, + ), Text(context.l10n.not_logged_in), - const SizedBox(height: 10), Button.primary( child: Text(context.l10n.login_with_spotify), onPressed: () => ServiceUtils.pushNamed(context, SettingsPage.name), diff --git a/lib/components/playbutton_view/playbutton_view.dart b/lib/components/playbutton_view/playbutton_view.dart index dd8dc371..46e67e25 100644 --- a/lib/components/playbutton_view/playbutton_view.dart +++ b/lib/components/playbutton_view/playbutton_view.dart @@ -1,4 +1,5 @@ import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; @@ -7,6 +8,7 @@ import 'package:spotube/components/playbutton_view/playbutton_card.dart'; import 'package:spotube/components/playbutton_view/playbutton_tile.dart'; import 'package:spotube/components/waypoint.dart'; import 'package:spotube/extensions/constrains.dart'; +import 'package:spotube/extensions/context.dart'; import 'package:very_good_infinite_list/very_good_infinite_list.dart'; const _dummyPlaybuttonCard = PlaybuttonCard( @@ -99,38 +101,59 @@ class PlaybuttonView extends StatelessWidget { const SliverGap(10), // Toggle between grid and list view switch ((isGrid.value, isLoading)) { - (true, _) => SliverGrid.builder( - itemCount: isLoading ? 6 : itemCount + 1, - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 150 * scale, - mainAxisExtent: 225 * scale, - crossAxisSpacing: 12 * scale, - mainAxisSpacing: 12 * scale, - ), - itemBuilder: (context, index) { - if (isLoading) { - return const Skeletonizer( - enabled: true, - child: _dummyPlaybuttonCard, - ); - } - - if (index == itemCount) { - if (!hasMore) return const SizedBox.shrink(); - return Waypoint( - controller: controller, - isGrid: true, - onTouchEdge: onRequestMore, - child: const Skeletonizer( - enabled: true, - child: _dummyPlaybuttonCard, + (true, _) => !isLoading && itemCount == 0 + ? SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 8), + sliver: SliverToBoxAdapter( + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: 10, + children: [ + Undraw( + height: 200 * context.theme.scaling, + illustration: UndrawIllustration.taken, + color: Theme.of(context).colorScheme.primary, + ), + Text( + context.l10n.nothing_found, + textAlign: TextAlign.center, + ).muted().small() + ], ), - ); - } + ), + ) + : SliverGrid.builder( + itemCount: isLoading ? 6 : itemCount + 1, + gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 150 * scale, + mainAxisExtent: 225 * scale, + crossAxisSpacing: 12 * scale, + mainAxisSpacing: 12 * scale, + ), + itemBuilder: (context, index) { + if (isLoading) { + return const Skeletonizer( + enabled: true, + child: _dummyPlaybuttonCard, + ); + } - return gridItemBuilder(context, index); - }, - ), + if (index == itemCount) { + if (!hasMore) return const SizedBox.shrink(); + return Waypoint( + controller: controller, + isGrid: true, + onTouchEdge: onRequestMore, + child: const Skeletonizer( + enabled: true, + child: _dummyPlaybuttonCard, + ), + ); + } + + return gridItemBuilder(context, index); + }, + ), (false, true) => Skeletonizer.sliver( enabled: true, child: SliverList( @@ -150,6 +173,23 @@ class PlaybuttonView extends StatelessWidget { onFetchData: onRequestMore, hasReachedMax: !hasMore, isLoading: isLoading, + emptyBuilder: (context) { + return Column( + mainAxisSize: MainAxisSize.min, + spacing: 10, + children: [ + Undraw( + height: 200 * context.theme.scaling, + illustration: UndrawIllustration.taken, + color: Theme.of(context).colorScheme.primary, + ), + Text( + context.l10n.nothing_found, + textAlign: TextAlign.center, + ).muted().small() + ], + ); + }, ), } ], diff --git a/lib/components/track_presentation/presentation_list.dart b/lib/components/track_presentation/presentation_list.dart index 55b4c46d..dda7dffa 100644 --- a/lib/components/track_presentation/presentation_list.dart +++ b/lib/components/track_presentation/presentation_list.dart @@ -1,6 +1,8 @@ import 'package:flutter/services.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/components/track_presentation/presentation_props.dart'; @@ -8,6 +10,7 @@ import 'package:spotube/components/track_presentation/presentation_state.dart'; import 'package:spotube/components/track_presentation/use_track_tile_play_callback.dart'; import 'package:spotube/components/track_tile/track_tile.dart'; import 'package:spotube/components/track_presentation/use_is_user_playlist.dart'; +import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/audio_player/audio_player.dart'; import 'package:very_good_infinite_list/very_good_infinite_list.dart'; @@ -25,6 +28,30 @@ class PresentationListSection extends HookConsumerWidget { final onTileTap = useTrackTilePlayCallback(ref); + if (state.presentationTracks.isEmpty && !options.pagination.isLoading) { + return SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Undraw( + illustration: UndrawIllustration.dreamer, + color: context.theme.colorScheme.primary, + height: 200 * context.theme.scaling, + ), + Text( + isUserPlaylist + ? context.l10n.no_tracks_added_yet + : context.l10n.no_tracks, + textAlign: TextAlign.center, + ).muted().small(), + ], + ), + ), + ); + } + return SliverInfiniteList( isLoading: options.pagination.isLoading, onFetchData: options.pagination.onFetchMore, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index c95ec54f..9a0f1814 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -409,5 +409,10 @@ "add_all_to_queue": "Add all to queue", "play_all_next": "Play all next", "pause": "Pause", - "view_all": "View all" + "view_all": "View all", + "no_tracks_added_yet": "Looks like you haven't added any tracks yet", + "no_tracks": "Looks like there are no tracks here", + "no_tracks_listened_yet": "Looks like you haven't listened to anything yet", + "not_following_artists": "You're not following any artists", + "no_favorite_albums_yet": "Looks like you haven't added any albums to your favorites yet" } \ No newline at end of file diff --git a/lib/modules/getting_started/blur_card.dart b/lib/modules/getting_started/blur_card.dart index db887013..6434c0a3 100644 --- a/lib/modules/getting_started/blur_card.dart +++ b/lib/modules/getting_started/blur_card.dart @@ -1,7 +1,5 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; class BlurCard extends HookConsumerWidget { final Widget child; @@ -18,8 +16,7 @@ class BlurCard extends HookConsumerWidget { clipBehavior: Clip.antiAlias, child: SizedBox( width: double.infinity, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), + child: SurfaceCard( child: Padding( padding: const EdgeInsets.all(16.0), child: child, diff --git a/lib/modules/home/sections/featured.dart b/lib/modules/home/sections/featured.dart index 9ccc8908..a339bd43 100644 --- a/lib/modules/home/sections/featured.dart +++ b/lib/modules/home/sections/featured.dart @@ -1,5 +1,7 @@ +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; @@ -15,6 +17,21 @@ class HomeFeaturedSection extends HookConsumerWidget { final featuredPlaylistsNotifier = ref.watch(featuredPlaylistsProvider.notifier); + if (featuredPlaylists.hasError) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Undraw( + illustration: UndrawIllustration.fixingBugs, + height: 200 * context.theme.scaling, + color: context.theme.colorScheme.primary, + ), + Text(context.l10n.something_went_wrong).small().muted(), + const Gap(8), + ], + ); + } + return Skeletonizer( enabled: featuredPlaylists.isLoading, child: HorizontalPlaybuttonCardView( diff --git a/lib/modules/home/sections/genres/genre_card.dart b/lib/modules/home/sections/genres/genre_card.dart index 722e6644..617d7392 100644 --- a/lib/modules/home/sections/genres/genre_card.dart +++ b/lib/modules/home/sections/genres/genre_card.dart @@ -89,23 +89,24 @@ class GenreSectionCard extends HookConsumerWidget { ), ], ), - Expanded( - child: Skeleton.ignore( - child: Skeletonizer( - enabled: playlists?.isLoading ?? false, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: playlistsData.length, - separatorBuilder: (context, index) => const Gap(12), - itemBuilder: (context, index) { - final playlist = playlistsData.elementAt(index); + if (playlists?.hasError != true) + Expanded( + child: Skeleton.ignore( + child: Skeletonizer( + enabled: playlists?.isLoading ?? false, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: playlistsData.length, + separatorBuilder: (context, index) => const Gap(12), + itemBuilder: (context, index) { + final playlist = playlistsData.elementAt(index); - return GenreSectionCardPlaylistCard(playlist: playlist); - }, + return GenreSectionCardPlaylistCard(playlist: playlist); + }, + ), ), ), - ), - ) + ) ], ), ), diff --git a/lib/modules/library/user_albums.dart b/lib/modules/library/user_albums.dart index a3f14fba..8d55cf80 100644 --- a/lib/modules/library/user_albums.dart +++ b/lib/modules/library/user_albums.dart @@ -1,9 +1,11 @@ +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' hide Image; 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:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/playbutton_view/playbutton_view.dart'; @@ -75,21 +77,45 @@ class UserAlbums extends HookConsumerWidget { ), ), const SliverGap(10), - SliverPadding( - padding: const EdgeInsets.symmetric(horizontal: 8), - sliver: PlaybuttonView( - controller: controller, - itemCount: albums.length, - hasMore: albumsQuery.asData?.value.hasMore == true, - isLoading: albumsQuery.isLoading, - onRequestMore: albumsQueryNotifier.fetchMore, - gridItemBuilder: (context, index) => AlbumCard( - albums[index], + if (albums.isEmpty && + !albumsQuery.isLoading && + searchText.value.isEmpty) + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 8), + sliver: SliverToBoxAdapter( + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: 10, + children: [ + Undraw( + height: 200 * context.theme.scaling, + illustration: UndrawIllustration.followMeDrone, + color: Theme.of(context).colorScheme.primary, + ), + Text( + context.l10n.not_following_artists, + textAlign: TextAlign.center, + ).muted().small() + ], + ), + ), + ) + else + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 8), + sliver: PlaybuttonView( + controller: controller, + itemCount: albums.length, + hasMore: albumsQuery.asData?.value.hasMore == true, + isLoading: albumsQuery.isLoading, + onRequestMore: albumsQueryNotifier.fetchMore, + gridItemBuilder: (context, index) => AlbumCard( + albums[index], + ), + listItemBuilder: (context, index) => + AlbumCard.tile(albums[index]), ), - listItemBuilder: (context, index) => - AlbumCard.tile(albums[index]), ), - ), const SliverSafeArea(sliver: SliverGap(10)), ], ), diff --git a/lib/modules/library/user_artists.dart b/lib/modules/library/user_artists.dart index 576298ce..fd23f426 100644 --- a/lib/modules/library/user_artists.dart +++ b/lib/modules/library/user_artists.dart @@ -1,9 +1,11 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:collection/collection.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/fake.dart'; @@ -79,45 +81,82 @@ class UserArtists extends HookConsumerWidget { ), ), const SliverGap(10), - SliverLayoutBuilder(builder: (context, constrains) { - return SliverGrid.builder( - itemCount: filteredArtists.isEmpty - ? 6 - : filteredArtists.length + 1, - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 200, - mainAxisExtent: constrains.smAndDown ? 225 : 250, - crossAxisSpacing: 8, - mainAxisSpacing: 8, - ), - itemBuilder: (context, index) { - if (filteredArtists.isNotEmpty && - index == filteredArtists.length) { - if (artistQuery.asData?.value.hasMore != true) { - return const SizedBox.shrink(); + if (filteredArtists.isNotEmpty) + SliverLayoutBuilder(builder: (context, constrains) { + return SliverGrid.builder( + itemCount: filteredArtists.length + 1, + gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 200, + mainAxisExtent: constrains.smAndDown ? 225 : 250, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + ), + itemBuilder: (context, index) { + if (filteredArtists.isNotEmpty && + index == filteredArtists.length) { + if (artistQuery.asData?.value.hasMore != true) { + return const SizedBox.shrink(); + } + + return Waypoint( + controller: controller, + isGrid: true, + onTouchEdge: artistQueryNotifier.fetchMore, + child: Skeletonizer( + enabled: true, + child: ArtistCard(FakeData.artist), + ), + ); } - return Waypoint( - controller: controller, - isGrid: true, - onTouchEdge: artistQueryNotifier.fetchMore, - child: Skeletonizer( - enabled: true, - child: ArtistCard(FakeData.artist), + return Skeletonizer( + enabled: artistQuery.isLoading, + child: ArtistCard( + filteredArtists.elementAtOrNull(index) ?? + FakeData.artist, ), ); - } - - return Skeletonizer( - enabled: artistQuery.isLoading, - child: ArtistCard( - filteredArtists.elementAtOrNull(index) ?? - FakeData.artist, + }, + ); + }) + else if (filteredArtists.isEmpty && + searchText.value.isEmpty && + !artistQuery.isLoading) + SliverToBoxAdapter( + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: 10, + children: [ + Undraw( + height: 200 * context.theme.scaling, + illustration: UndrawIllustration.followMeDrone, + color: Theme.of(context).colorScheme.primary, ), - ); - }, - ); - }), + Text( + context.l10n.not_following_artists, + textAlign: TextAlign.center, + ).muted().small() + ], + ), + ) + else + SliverToBoxAdapter( + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: 10, + children: [ + Undraw( + height: 200 * context.theme.scaling, + illustration: UndrawIllustration.taken, + color: Theme.of(context).colorScheme.primary, + ), + Text( + context.l10n.nothing_found, + textAlign: TextAlign.center, + ).muted().small() + ], + ), + ), const SliverSafeArea(sliver: SliverGap(10)), ], ), diff --git a/lib/modules/stats/top/albums.dart b/lib/modules/stats/top/albums.dart index e401340e..09bf755c 100644 --- a/lib/modules/stats/top/albums.dart +++ b/lib/modules/stats/top/albums.dart @@ -1,5 +1,7 @@ -import 'package:flutter/material.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/formatters.dart'; import 'package:spotube/modules/stats/common/album_item.dart'; @@ -31,6 +33,24 @@ class TopAlbums extends HookConsumerWidget { isLoading: topAlbums.isLoading && !topAlbums.isLoadingNextPage, hasReachedMax: topAlbums.asData?.value.hasMore ?? true, itemCount: albumsData.length, + emptyBuilder: (context) => Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Gap(50), + Undraw( + illustration: UndrawIllustration.happyMusic, + color: context.theme.colorScheme.primary, + height: 200 * context.theme.scaling, + ), + Text( + context.l10n.no_tracks_listened_yet, + textAlign: TextAlign.center, + ).muted().small(), + ], + ), + ), itemBuilder: (context, index) { final album = albumsData[index]; return StatsAlbumItem( diff --git a/lib/modules/stats/top/artists.dart b/lib/modules/stats/top/artists.dart index 3e4e098d..c53c34fd 100644 --- a/lib/modules/stats/top/artists.dart +++ b/lib/modules/stats/top/artists.dart @@ -1,6 +1,8 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/formatters.dart'; import 'package:spotube/modules/stats/common/artist_item.dart'; @@ -35,6 +37,24 @@ class TopArtists extends HookConsumerWidget { isLoading: topTracks.isLoading && !topTracks.isLoadingNextPage, hasReachedMax: topTracks.asData?.value.hasMore ?? true, itemCount: artistsData.length, + emptyBuilder: (context) => Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Gap(50), + Undraw( + illustration: UndrawIllustration.happyMusic, + color: context.theme.colorScheme.primary, + height: 200 * context.theme.scaling, + ), + Text( + context.l10n.no_tracks_listened_yet, + textAlign: TextAlign.center, + ).muted().small(), + ], + ), + ), itemBuilder: (context, index) { final artist = artistsData[index]; return StatsArtistItem( diff --git a/lib/modules/stats/top/tracks.dart b/lib/modules/stats/top/tracks.dart index 7fba220d..c4015431 100644 --- a/lib/modules/stats/top/tracks.dart +++ b/lib/modules/stats/top/tracks.dart @@ -1,5 +1,7 @@ -import 'package:flutter/material.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotube/collections/formatters.dart'; import 'package:spotube/modules/stats/common/track_item.dart'; @@ -33,6 +35,24 @@ class TopTracks extends HookConsumerWidget { isLoading: topTracks.isLoading && !topTracks.isLoadingNextPage, hasReachedMax: topTracks.asData?.value.hasMore ?? true, itemCount: tracksData.length, + emptyBuilder: (context) => Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Gap(50), + Undraw( + illustration: UndrawIllustration.happyMusic, + color: context.theme.colorScheme.primary, + height: 200 * context.theme.scaling, + ), + Text( + context.l10n.no_tracks_listened_yet, + textAlign: TextAlign.center, + ).muted().small(), + ], + ), + ), itemBuilder: (context, index) { final track = tracksData[index]; return StatsTrackItem( diff --git a/lib/pages/album/album.dart b/lib/pages/album/album.dart index 4a10268b..bc013574 100644 --- a/lib/pages/album/album.dart +++ b/lib/pages/album/album.dart @@ -35,7 +35,7 @@ class AlbumPage extends HookConsumerWidget { tracks: tracks.asData?.value.items ?? [], pagination: PaginationProps( hasNextPage: tracks.asData?.value.hasMore ?? false, - isLoading: tracks.isLoadingNextPage, + isLoading: tracks.isLoading || tracks.isLoadingNextPage, onFetchMore: () async { await tracksNotifier.fetchMore(); }, diff --git a/lib/pages/getting_started/getting_started.dart b/lib/pages/getting_started/getting_started.dart index 6a8141d0..2931a782 100644 --- a/lib/pages/getting_started/getting_started.dart +++ b/lib/pages/getting_started/getting_started.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/extensions/context.dart'; @@ -8,8 +8,6 @@ import 'package:spotube/pages/getting_started/sections/greeting.dart'; import 'package:spotube/pages/getting_started/sections/playback.dart'; import 'package:spotube/pages/getting_started/sections/region.dart'; import 'package:spotube/pages/getting_started/sections/support.dart'; -import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; -import 'package:spotube/themes/theme.dart'; class GettingStarting extends HookConsumerWidget { static const name = "getting_started"; @@ -18,12 +16,6 @@ class GettingStarting extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final preferences = ref.watch(userPreferencesProvider); - final themeData = theme( - preferences.accentColorScheme, - Brightness.dark, - preferences.amoledDarkTheme, - ); final pageController = usePageController(); final onNext = useCallback(() { @@ -40,11 +32,11 @@ class GettingStarting extends HookConsumerWidget { ); }, [pageController]); - return Theme( - data: themeData, - child: Scaffold( - appBar: TitleBar( + return Scaffold( + headers: [ + TitleBar( backgroundColor: Colors.transparent, + surfaceBlur: 0, trailing: [ ListenableBuilder( listenable: pageController, @@ -54,7 +46,7 @@ class GettingStarting extends HookConsumerWidget { child: pageController.hasClients && (pageController.page == 0 || pageController.page == 3) ? const SizedBox() - : TextButton( + : Button.secondary( onPressed: () { pageController.animateToPage( 3, @@ -62,43 +54,33 @@ class GettingStarting extends HookConsumerWidget { curve: Curves.easeInOut, ); }, - child: Text( - context.l10n.skip_this_nonsense, - style: TextStyle( - decoration: TextDecoration.underline, - decorationColor: themeData.colorScheme.primary, - ), - ), + child: Text(context.l10n.skip_this_nonsense), ), ); }, ), ], ), - extendBodyBehindAppBar: true, - body: DecoratedBox( - decoration: BoxDecoration( - image: DecorationImage( - image: Assets.bengaliPatternsBg.provider(), - fit: BoxFit.cover, - colorFilter: const ColorFilter.mode( - Colors.black38, - BlendMode.srcOver, - ), + ], + floatingHeader: true, + child: DecoratedBox( + decoration: BoxDecoration( + image: DecorationImage( + image: Assets.bengaliPatternsBg.provider(), + fit: BoxFit.cover, + ), + ), + child: PageView( + controller: pageController, + children: [ + GettingStartedPageGreetingSection(onNext: onNext), + GettingStartedPageLanguageRegionSection(onNext: onNext), + GettingStartedPagePlaybackSection( + onNext: onNext, + onPrevious: onPrevious, ), - ), - child: PageView( - controller: pageController, - children: [ - GettingStartedPageGreetingSection(onNext: onNext), - GettingStartedPageLanguageRegionSection(onNext: onNext), - GettingStartedPagePlaybackSection( - onNext: onNext, - onPrevious: onPrevious, - ), - const GettingStartedScreenSupportSection(), - ], - ), + const GettingStartedScreenSupportSection(), + ], ), ), ); diff --git a/lib/pages/getting_started/sections/greeting.dart b/lib/pages/getting_started/sections/greeting.dart index 6d649351..4b9c0a89 100644 --- a/lib/pages/getting_started/sections/greeting.dart +++ b/lib/pages/getting_started/sections/greeting.dart @@ -1,10 +1,9 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/modules/getting_started/blur_card.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/modules/getting_started/blur_card.dart'; import 'package:spotube/utils/platform.dart'; class GettingStartedPageGreetingSection extends HookConsumerWidget { @@ -13,8 +12,6 @@ class GettingStartedPageGreetingSection extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme) = Theme.of(context); - return Center( child: BlurCard( child: Column( @@ -22,30 +19,19 @@ class GettingStartedPageGreetingSection extends HookConsumerWidget { children: [ Assets.spotubeLogoPng.image(height: 200), const Gap(24), - Text( - "Spotube", - style: - textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), - ), + const Text("Spotube").semiBold().h4(), const Gap(4), Text( kIsMobile ? context.l10n.freedom_of_music_palm : context.l10n.freedom_of_music, textAlign: TextAlign.center, - style: textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w300, - fontStyle: FontStyle.italic, - ), - ), + ).light().large().italic(), const Gap(84), - Directionality( - textDirection: TextDirection.rtl, - child: FilledButton.icon( - onPressed: onNext, - icon: const Icon(SpotubeIcons.angleRight), - label: Text(context.l10n.get_started), - ), + Button.primary( + onPressed: onNext, + trailing: const Icon(SpotubeIcons.angleRight), + child: Text(context.l10n.get_started), ), ], ), diff --git a/lib/pages/getting_started/sections/playback.dart b/lib/pages/getting_started/sections/playback.dart index dbf0bda2..bf12d426 100644 --- a/lib/pages/getting_started/sections/playback.dart +++ b/lib/pages/getting_started/sections/playback.dart @@ -1,9 +1,9 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/modules/getting_started/blur_card.dart'; import 'package:spotube/extensions/context.dart'; @@ -14,14 +14,14 @@ final audioSourceToIconMap = { AudioSource.youtube: const Icon( SpotubeIcons.youtube, color: Colors.red, - size: 30, + size: 20, ), - AudioSource.piped: const Icon(SpotubeIcons.piped, size: 30), + AudioSource.piped: const Icon(SpotubeIcons.piped, size: 20), AudioSource.invidious: ClipRRect( - borderRadius: BorderRadius.circular(48), - child: Assets.invidious.image(width: 48, height: 48), + borderRadius: BorderRadius.circular(26), + child: Assets.invidious.image(width: 26, height: 26), ), - AudioSource.jiosaavn: Assets.jiosaavn.image(width: 48, height: 48), + AudioSource.jiosaavn: Assets.jiosaavn.image(width: 20, height: 20), }; class GettingStartedPagePlaybackSection extends HookConsumerWidget { @@ -36,8 +36,6 @@ class GettingStartedPagePlaybackSection extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme, :colorScheme, :dividerColor) = - Theme.of(context); final preferences = ref.watch(userPreferencesProvider); final preferencesNotifier = ref.read(userPreferencesProvider.notifier); @@ -62,76 +60,56 @@ class GettingStartedPagePlaybackSection extends HookConsumerWidget { children: [ const Icon(SpotubeIcons.album, size: 16), const Gap(8), - Text(context.l10n.playback, style: textTheme.titleMedium), + Text(context.l10n.playback).semiBold().large(), ], ), const Gap(16), - ListTile( - title: Text( - context.l10n.select_audio_source, - style: textTheme.titleMedium, - ), + Align( + alignment: Alignment.centerLeft, + child: Text(context.l10n.select_audio_source).semiBold().large(), ), const Gap(16), - ToggleButtons( - isSelected: [ - for (final source in AudioSource.values) - preferences.audioSource == source, - ], - onPressed: (index) { - preferencesNotifier.setAudioSource(AudioSource.values[index]); + Select( + value: preferences.audioSource, + onChanged: (value) { + if (value == null) return; + preferencesNotifier.setAudioSource(value); }, - borderRadius: BorderRadius.circular(8), + placeholder: Text(preferences.audioSource.name.capitalize()), + itemBuilder: (context, value) => Row( + mainAxisSize: MainAxisSize.min, + spacing: 6, + children: [ + audioSourceToIconMap[value]!, + Text(value.name.capitalize()), + ], + ), children: [ for (final source in AudioSource.values) - SizedBox.square( - dimension: 84, - child: Column( + SelectItemButton( + value: source, + child: Row( mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, + spacing: 6, children: [ audioSourceToIconMap[source]!, - const Gap(8), - Text( - source.name.capitalize(), - style: textTheme.bodySmall!.copyWith( - color: preferences.audioSource == source - ? colorScheme.primary - : null, - ), - ), + Text(source.name.capitalize()), ], ), ), ], ), - ListTile( - title: Align( - alignment: switch (preferences.audioSource) { - AudioSource.youtube => Alignment.centerLeft, - AudioSource.piped || - AudioSource.invidious => - Alignment.center, - AudioSource.jiosaavn => Alignment.centerRight, - }, - child: Text( - audioSourceToDescription[preferences.audioSource]!, - style: textTheme.bodySmall?.copyWith( - color: dividerColor, - ), - ), - ), - ), const Gap(16), - ListTile( + Text( + audioSourceToDescription[preferences.audioSource]!, + ).small().muted(), + const Gap(16), + ButtonTile( title: Text(context.l10n.endless_playback), subtitle: Text( context.l10n.endless_playback_description, - style: textTheme.bodySmall?.copyWith( - color: dividerColor, - ), - ), - onTap: () { + ).small().muted(), + onPressed: () { preferencesNotifier .setEndlessPlayback(!preferences.endlessPlayback); }, @@ -146,17 +124,17 @@ class GettingStartedPagePlaybackSection extends HookConsumerWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - FilledButton.icon( - icon: const Icon(SpotubeIcons.angleLeft), - label: Text(context.l10n.previous), + Button.secondary( + leading: const Icon(SpotubeIcons.angleLeft), onPressed: onPrevious, + child: Text(context.l10n.previous), ), Directionality( textDirection: TextDirection.rtl, - child: FilledButton.icon( - icon: const Icon(SpotubeIcons.angleRight), - label: Text(context.l10n.next), + child: Button.primary( + leading: const Icon(SpotubeIcons.angleRight), onPressed: onNext, + child: Text(context.l10n.next), ), ), ], diff --git a/lib/pages/getting_started/sections/region.dart b/lib/pages/getting_started/sections/region.dart index 9e31a273..19507fe9 100644 --- a/lib/pages/getting_started/sections/region.dart +++ b/lib/pages/getting_started/sections/region.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotify/spotify.dart'; import 'package:spotube/collections/language_codes.dart'; import 'package:spotube/collections/spotify_markets.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -16,7 +16,6 @@ class GettingStartedPageLanguageRegionSection extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme, :dividerColor) = Theme.of(context); final preferences = ref.watch(userPreferencesProvider); return SafeArea( @@ -32,92 +31,119 @@ class GettingStartedPageLanguageRegionSection extends HookConsumerWidget { size: 16, ), const SizedBox(width: 8), - Text( - context.l10n.language_region, - style: textTheme.titleMedium, - ), + Text(context.l10n.language_region).semiBold(), ], ), - const Gap(48), + const Gap(30), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - Text( - context.l10n.choose_your_region, - style: textTheme.titleSmall, - ), + Text(context.l10n.choose_your_region).semiBold(), Text( context.l10n.choose_your_region_description, - style: textTheme.bodySmall?.copyWith( - color: dividerColor, - ), - ), + ).small().muted(), const Gap(16), - DropdownMenu( - initialSelection: preferences.market, - onSelected: (value) { - if (value == null) return; - ref - .read(userPreferencesProvider.notifier) - .setRecommendationMarket(value); - }, - hintText: preferences.market.name, - label: Text(context.l10n.market_place_region), - inputDecorationTheme: - const InputDecorationTheme(isDense: true), - dropdownMenuEntries: [ - for (final market in spotifyMarkets) - DropdownMenuEntry( - value: market.$1, - label: market.$2, - ), - ], + Text(context.l10n.market_place_region).small(), + const Gap(8), + SizedBox( + width: double.infinity, + child: Select( + value: preferences.market, + onChanged: (value) { + if (value == null) return; + ref + .read(userPreferencesProvider.notifier) + .setRecommendationMarket(value); + }, + placeholder: Text(preferences.market.name), + itemBuilder: (context, value) => Text( + spotifyMarkets + .firstWhere((element) => element.$1 == value) + .$2, + ), + searchPlaceholder: Text(context.l10n.search), + searchFilter: (item, query) { + final market = spotifyMarkets + .firstWhere((element) => element.$1 == item) + .$2 + .toLowerCase(); + + return market.contains(query.toLowerCase()) ? 1 : 0; + }, + children: [ + for (final market in spotifyMarkets) + SelectItemButton( + value: market.$1, + child: Text(market.$2), + ), + ], + ), ), const Gap(36), Text( context.l10n.choose_your_language, - style: textTheme.titleSmall, - ), + ).semiBold(), const Gap(16), - DropdownMenu( - initialSelection: preferences.locale, - onSelected: (locale) { - if (locale == null) return; - ref - .read(userPreferencesProvider.notifier) - .setLocale(locale); - }, - hintText: context.l10n.system_default, - label: Text(context.l10n.language), - inputDecorationTheme: - const InputDecorationTheme(isDense: true), - dropdownMenuEntries: [ - DropdownMenuEntry( - value: const Locale("system", "system"), - label: context.l10n.system_default, - ), - for (final locale in L10n.all) - DropdownMenuEntry( - value: locale, - label: LanguageLocals.getDisplayLanguage( - locale.languageCode) - .toString(), + Text(context.l10n.language).small(), + const Gap(8), + SizedBox( + width: double.infinity, + child: Select( + value: preferences.locale, + onChanged: (locale) { + if (locale == null) return; + ref + .read(userPreferencesProvider.notifier) + .setLocale(locale); + }, + placeholder: Text(context.l10n.system_default), + itemBuilder: (context, value) => + value.languageCode == "system" + ? Text(context.l10n.system_default) + : Text( + LanguageLocals.getDisplayLanguage( + value.languageCode) + .toString(), + ), + searchPlaceholder: Text(context.l10n.search), + searchFilter: (locale, query) { + final language = LanguageLocals.getDisplayLanguage( + locale.languageCode) + .toString(); + + return language + .toLowerCase() + .contains(query.toLowerCase()) + ? 1 + : 0; + }, + children: [ + SelectItemButton( + value: const Locale("system", "system"), + child: Text(context.l10n.system_default), ), - ], + for (final locale in L10n.all) + SelectItemButton( + value: locale, + child: Text( + LanguageLocals.getDisplayLanguage( + locale.languageCode) + .toString(), + ), + ), + ], + ), ), ], ), const Gap(48), Align( alignment: Alignment.centerRight, - child: Directionality( - textDirection: TextDirection.rtl, - child: FilledButton.icon( - icon: const Icon(SpotubeIcons.angleRight), - label: Text(context.l10n.next), - onPressed: onNext, - ), + child: Button.primary( + trailing: const Icon(SpotubeIcons.angleRight), + onPressed: onNext, + child: Text(context.l10n.next), ), ), ], diff --git a/lib/pages/getting_started/sections/support.dart b/lib/pages/getting_started/sections/support.dart index f09a585d..640b0b38 100644 --- a/lib/pages/getting_started/sections/support.dart +++ b/lib/pages/getting_started/sections/support.dart @@ -1,7 +1,6 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/env.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/getting_started/blur_card.dart'; @@ -16,7 +15,6 @@ class GettingStartedScreenSupportSection extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme, :colorScheme) = Theme.of(context); final onLogin = useLoginCallback(ref); return Center( @@ -34,9 +32,8 @@ class GettingStartedScreenSupportSection extends HookConsumerWidget { const SizedBox(width: 8), Text( context.l10n.help_project_grow, - style: - textTheme.titleMedium?.copyWith(color: Colors.pink), - ), + style: const TextStyle(color: Colors.pink), + ).semiBold(), ], ), const Gap(16), @@ -46,38 +43,57 @@ class GettingStartedScreenSupportSection extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - FilledButton.icon( - icon: const Icon(SpotubeIcons.github), - label: Text(context.l10n.contribute_on_github), - style: FilledButton.styleFrom( - backgroundColor: Colors.black, - foregroundColor: Colors.white, - shape: RoundedRectangleBorder( + Button( + leading: const Icon(SpotubeIcons.github), + style: ButtonVariance.primary.copyWith( + decoration: (context, states, value) { + if (states.isNotEmpty) { + return ButtonVariance.primary + .decoration(context, states); + } + + return BoxDecoration( + color: Colors.black, borderRadius: BorderRadius.circular(8), - ), - ), + ); + }), onPressed: () async { await launchUrlString( "https://github.com/KRTirtho/spotube", mode: LaunchMode.externalApplication, ); }, + child: Text( + context.l10n.contribute_on_github, + style: const TextStyle(color: Colors.white), + ), ), if (!Env.hideDonations) ...[ const Gap(16), - FilledButton.icon( - icon: const Icon(SpotubeIcons.openCollective), - label: Text(context.l10n.donate_on_open_collective), - style: FilledButton.styleFrom( - backgroundColor: const Color(0xff4cb7f6), - foregroundColor: Colors.white, - ), + Button( + leading: const Icon(SpotubeIcons.openCollective), + style: ButtonVariance.primary.copyWith( + decoration: (context, states, value) { + if (states.isNotEmpty) { + return ButtonVariance.primary + .decoration(context, states); + } + + return BoxDecoration( + color: const Color(0xff4cb7f6), + borderRadius: BorderRadius.circular(8), + ); + }), onPressed: () async { await launchUrlString( "https://opencollective.com/spotube", mode: LaunchMode.externalApplication, ); }, + child: Text( + context.l10n.donate_on_open_collective, + style: const TextStyle(color: Colors.white), + ), ), ] ], @@ -91,42 +107,40 @@ class GettingStartedScreenSupportSection extends HookConsumerWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - DecoratedBox( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - gradient: LinearGradient( - colors: [ - colorScheme.primary, - colorScheme.secondary, - ], - ), - ), - child: TextButton.icon( - icon: const Icon(SpotubeIcons.anonymous), - label: Text(context.l10n.browse_anonymously), - style: TextButton.styleFrom( - foregroundColor: Colors.white, - ), - onPressed: () async { - await KVStoreService.setDoneGettingStarted(true); - if (context.mounted) { - context.goNamed(HomePage.name); - } - }, - ), + Button.secondary( + leading: const Icon(SpotubeIcons.anonymous), + onPressed: () async { + await KVStoreService.setDoneGettingStarted(true); + if (context.mounted) { + context.goNamed(HomePage.name); + } + }, + child: Text(context.l10n.browse_anonymously), ), const Gap(16), - FilledButton.icon( - icon: const Icon(SpotubeIcons.spotify), - label: Text(context.l10n.connect_with_spotify), - style: FilledButton.styleFrom( - backgroundColor: const Color(0xff1db954), - foregroundColor: Colors.white, + Button.primary( + leading: const Icon(SpotubeIcons.spotify), + style: ButtonVariance.primary.copyWith( + decoration: (context, states, value) { + if (states.isNotEmpty) { + return ButtonVariance.primary + .decoration(context, states); + } + + return BoxDecoration( + color: const Color(0xff1db954), + borderRadius: BorderRadius.circular(8), + ); + }, ), onPressed: () async { await KVStoreService.setDoneGettingStarted(true); await onLogin(); }, + child: Text( + context.l10n.connect_with_spotify, + style: const TextStyle(color: Colors.white), + ), ), ], ), diff --git a/lib/pages/playlist/playlist.dart b/lib/pages/playlist/playlist.dart index da28c83c..b610b1d4 100644 --- a/lib/pages/playlist/playlist.dart +++ b/lib/pages/playlist/playlist.dart @@ -53,7 +53,7 @@ class PlaylistPage extends HookConsumerWidget { ), pagination: PaginationProps( hasNextPage: tracks.asData?.value.hasMore ?? false, - isLoading: tracks.isLoadingNextPage, + isLoading: tracks.isLoading || tracks.isLoadingNextPage, onFetchMore: tracksNotifier.fetchMore, onRefresh: () async { ref.invalidate(playlistTracksProvider(playlist.id!)); diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index d0f59ce2..efd46ebb 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -1,4 +1,5 @@ import 'package:flutter/services.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; @@ -159,21 +160,13 @@ class SearchPage extends HookConsumerWidget { SizedBox( height: mediaQuery.height * 0.2, ), - Icon( - SpotubeIcons.web, - size: 120, - color: theme.colorScheme.foreground - .withOpacity(0.7), + Undraw( + illustration: UndrawIllustration.explore, + color: theme.colorScheme.primary, + height: 200 * theme.scaling, ), const SizedBox(height: 20), - Text( - context.l10n.search_to_get_results, - style: theme.typography.h3.copyWith( - fontWeight: FontWeight.w900, - color: theme.colorScheme.foreground - .withOpacity(0.5), - ), - ), + Text(context.l10n.search_to_get_results).large(), ], ), (false, true) => Container( diff --git a/pubspec.lock b/pubspec.lock index fbcdfd52..2666460c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -963,18 +963,26 @@ packages: source: hosted version: "1.1.1" flutter_svg: - dependency: transitive + dependency: "direct overridden" description: name: flutter_svg - sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" + sha256: c200fd79c918a40c5cd50ea0877fa13f81bdaf6f0a5d3dbcc2a13e3285d6aa1b url: "https://pub.dev" source: hosted - version: "1.1.6" + version: "2.0.17" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_undraw: + dependency: "direct main" + description: + name: flutter_undraw + sha256: "17fe2738231c502171f984c003f6e40979de1a2550ef2debdd29fec27ae006ea" + url: "https://pub.dev" + source: hosted + version: "0.2.0" flutter_web_plugins: dependency: transitive description: flutter @@ -1662,14 +1670,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" - path_drawing: - dependency: transitive - description: - name: path_drawing - sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977 - url: "https://pub.dev" - source: hosted - version: "1.0.1" path_parsing: dependency: transitive description: @@ -2525,6 +2525,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.5.1" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7" + url: "https://pub.dev" + source: hosted + version: "1.1.15" vector_graphics_codec: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7bbf15a1..657de0c0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,6 +63,7 @@ dependencies: flutter_riverpod: ^2.5.1 flutter_secure_storage: ^9.0.0 flutter_sharing_intent: ^1.1.0 + flutter_undraw: ^0.2.0 form_builder_validators: ^11.1.1 form_validator: ^2.1.1 freezed_annotation: ^2.4.1 @@ -163,6 +164,7 @@ dependency_overrides: path: packages/bonsoir_android web: ^1.1.0 meta: 1.16.0 + flutter_svg: ^2.0.17 flutter: generate: true @@ -174,6 +176,14 @@ flutter: - assets/backgrounds/ - assets/patterns/ - LICENSE + - packages/flutter_undraw/assets/undraw/access_denied.svg + - packages/flutter_undraw/assets/undraw/fixing_bugs.svg + - packages/flutter_undraw/assets/undraw/secure_login.svg + - packages/flutter_undraw/assets/undraw/explore.svg + - packages/flutter_undraw/assets/undraw/dreamer.svg + - packages/flutter_undraw/assets/undraw/happy_music.svg + - packages/flutter_undraw/assets/undraw/follow_me_drone.svg + - packages/flutter_undraw/assets/undraw/taken.svg fonts: - family: GeistSans fonts: diff --git a/untranslated_messages.json b/untranslated_messages.json index ddaf9ab0..b00b1fd4 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -9,7 +9,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "bn": [ @@ -22,7 +27,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "ca": [ @@ -35,7 +45,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "cs": [ @@ -48,7 +63,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "de": [ @@ -61,7 +81,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "es": [ @@ -74,7 +99,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "eu": [ @@ -87,7 +117,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "fa": [ @@ -100,7 +135,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "fi": [ @@ -113,7 +153,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "fr": [ @@ -126,7 +171,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "hi": [ @@ -139,7 +189,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "id": [ @@ -152,7 +207,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "it": [ @@ -165,7 +225,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "ja": [ @@ -178,7 +243,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "ka": [ @@ -191,7 +261,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "ko": [ @@ -204,7 +279,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "ne": [ @@ -217,7 +297,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "nl": [ @@ -230,7 +315,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "pl": [ @@ -243,7 +333,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "pt": [ @@ -256,7 +351,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "ru": [ @@ -269,7 +369,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "th": [ @@ -282,7 +387,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "tr": [ @@ -295,7 +405,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "uk": [ @@ -308,7 +423,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "vi": [ @@ -321,7 +441,12 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ], "zh": [ @@ -334,6 +459,11 @@ "add_all_to_queue", "play_all_next", "pause", - "view_all" + "view_all", + "no_tracks_added_yet", + "no_tracks", + "no_tracks_listened_yet", + "not_following_artists", + "no_favorite_albums_yet" ] } From 3649b67869bf14f7cbbf25385c2343e42fc4f92d Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 12 Jan 2025 14:22:54 +0600 Subject: [PATCH 48/81] refactor: use undraw for not_found component --- lib/components/fallbacks/not_found.dart | 39 ++++++++++++------------- lib/modules/player/player_queue.dart | 2 +- lib/pages/library/local_folder.dart | 18 ++++++++++-- pubspec.yaml | 1 + 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/lib/components/fallbacks/not_found.dart b/lib/components/fallbacks/not_found.dart index d35a4b50..9a994446 100644 --- a/lib/components/fallbacks/not_found.dart +++ b/lib/components/fallbacks/not_found.dart @@ -1,30 +1,27 @@ +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:spotube/collections/assets.gen.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/extensions/context.dart'; class NotFound extends StatelessWidget { - final bool vertical; - const NotFound({super.key, this.vertical = false}); + const NotFound({super.key}); @override Widget build(BuildContext context) { - final widgets = [ - SizedBox( - height: 150, - width: 150, - child: Assets.emptyBox.image(), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(context.l10n.nothing_found).large().semiBold(), - Text( - context.l10n.the_box_is_empty, - ).semiBold(), - ], - ), - ]; - return vertical ? Column(children: widgets) : Row(children: widgets); + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Undraw( + illustration: UndrawIllustration.empty, + height: 200 * context.theme.scaling, + color: context.theme.colorScheme.primary, + ), + const Gap(10), + Text( + context.l10n.nothing_found, + textAlign: TextAlign.center, + ).muted().small() + ], + ); } } diff --git a/lib/modules/player/player_queue.dart b/lib/modules/player/player_queue.dart index a91c883d..fb19f880 100644 --- a/lib/modules/player/player_queue.dart +++ b/lib/modules/player/player_queue.dart @@ -81,7 +81,7 @@ class PlayerQueue extends HookConsumerWidget { ); if (tracks.isEmpty) { - return const NotFound(vertical: true); + return const NotFound(); } return Stack( diff --git a/lib/pages/library/local_folder.dart b/lib/pages/library/local_folder.dart index 23326c68..84873b84 100644 --- a/lib/pages/library/local_folder.dart +++ b/lib/pages/library/local_folder.dart @@ -4,6 +4,7 @@ import 'dart:math'; import 'package:collection/collection.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; @@ -320,10 +321,21 @@ class LocalLibraryPage extends HookConsumerWidget { if (!trackSnapshot.isLoading && filteredTracks.isEmpty) { - return const Expanded( - child: Row( + return Expanded( + child: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [NotFound()], + children: [ + Undraw( + illustration: UndrawIllustration.empty, + height: 200 * scale, + color: context.theme.colorScheme.primary, + ), + const Gap(10), + Text( + context.l10n.nothing_found, + textAlign: TextAlign.center, + ).muted().small() + ], ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 657de0c0..3aaa3395 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -184,6 +184,7 @@ flutter: - packages/flutter_undraw/assets/undraw/happy_music.svg - packages/flutter_undraw/assets/undraw/follow_me_drone.svg - packages/flutter_undraw/assets/undraw/taken.svg + - packages/flutter_undraw/assets/undraw/empty.svg fonts: - family: GeistSans fonts: From 5930c342b5be95c58b2d3884f738b7990abcb46d Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 12 Jan 2025 21:32:33 +0600 Subject: [PATCH 49/81] chore: fix window resizing --- lib/collections/assets.gen.dart | 13 -- lib/components/titlebar/mouse_state.dart | 73 --------- lib/components/titlebar/titlebar.dart | 17 ++- lib/components/titlebar/titlebar_buttons.dart | 144 +++++++++--------- .../titlebar/titlebar_icon_buttons.dart | 95 ++++++------ lib/components/titlebar/window_button.dart | 125 --------------- lib/main.dart | 4 +- lib/pages/home/home.dart | 2 +- lib/pages/library/library.dart | 8 - lib/pages/lyrics/lyrics.dart | 2 + lib/pages/search/search.dart | 3 +- 11 files changed, 132 insertions(+), 354 deletions(-) delete mode 100644 lib/components/titlebar/mouse_state.dart delete mode 100644 lib/components/titlebar/window_button.dart diff --git a/lib/collections/assets.gen.dart b/lib/collections/assets.gen.dart index 98b67c80..004001f2 100644 --- a/lib/collections/assets.gen.dart +++ b/lib/collections/assets.gen.dart @@ -20,17 +20,6 @@ class $AssetsBackgroundsGen { List get values => [xmasEffect]; } -class $AssetsIllustrationsGen { - const $AssetsIllustrationsGen(); - - /// File path: assets/illustrations/fixing_bugs.png - AssetGenImage get fixingBugs => - const AssetGenImage('assets/illustrations/fixing_bugs.png'); - - /// List of all assets - List get values => [fixingBugs]; -} - class $AssetsLogosGen { const $AssetsLogosGen(); @@ -151,8 +140,6 @@ class Assets { AssetGenImage('assets/bengali-patterns-bg.jpg'); static const AssetGenImage branding = AssetGenImage('assets/branding.png'); static const AssetGenImage emptyBox = AssetGenImage('assets/empty_box.png'); - static const $AssetsIllustrationsGen illustrations = - $AssetsIllustrationsGen(); static const AssetGenImage invidious = AssetGenImage('assets/invidious.jpg'); static const AssetGenImage jiosaavn = AssetGenImage('assets/jiosaavn.png'); static const AssetGenImage likedTracks = diff --git a/lib/components/titlebar/mouse_state.dart b/lib/components/titlebar/mouse_state.dart deleted file mode 100644 index 9af2a8b0..00000000 --- a/lib/components/titlebar/mouse_state.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:flutter/material.dart'; - -typedef MouseStateBuilderCB = Widget Function( - BuildContext context, MouseState mouseState); - -class MouseState { - bool isMouseOver = false; - bool isMouseDown = false; - MouseState(); - @override - String toString() { - return "isMouseDown: $isMouseDown - isMouseOver: $isMouseOver"; - } -} - -T? _ambiguate(T? value) => value; - -class MouseStateBuilder extends StatefulWidget { - final MouseStateBuilderCB builder; - final VoidCallback? onPressed; - const MouseStateBuilder({super.key, required this.builder, this.onPressed}); - @override - // ignore: library_private_types_in_public_api - _MouseStateBuilderState createState() => _MouseStateBuilderState(); -} - -class _MouseStateBuilderState extends State { - late MouseState _mouseState; - _MouseStateBuilderState() { - _mouseState = MouseState(); - } - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (event) { - setState(() { - _mouseState.isMouseOver = true; - }); - }, - onExit: (event) { - setState(() { - _mouseState.isMouseOver = false; - }); - }, - child: GestureDetector( - onTapDown: (_) { - setState(() { - _mouseState.isMouseDown = true; - }); - }, - onTapCancel: () { - setState(() { - _mouseState.isMouseDown = false; - }); - }, - onTap: () { - setState(() { - _mouseState.isMouseDown = false; - _mouseState.isMouseOver = false; - }); - _ambiguate(WidgetsBinding.instance)!.addPostFrameCallback((_) { - if (widget.onPressed != null) { - widget.onPressed!(); - } - }); - }, - onTapUp: (_) {}, - child: widget.builder(context, _mouseState), - ), - ); - } -} diff --git a/lib/components/titlebar/titlebar.dart b/lib/components/titlebar/titlebar.dart index 215b63ed..5b86f6ad 100644 --- a/lib/components/titlebar/titlebar.dart +++ b/lib/components/titlebar/titlebar.dart @@ -1,6 +1,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/components/titlebar/titlebar_buttons.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; @@ -49,7 +50,7 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget { this.height, this.surfaceBlur, this.surfaceOpacity, - this.useSafeArea = true, + this.useSafeArea = false, }); void onDrag(WidgetRef ref) { @@ -66,7 +67,7 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget { final lastClicked = useRef(DateTime.now().millisecondsSinceEpoch); return SizedBox( - height: height ?? 56, + height: height ?? (48 * context.theme.scaling), child: LayoutBuilder( builder: (context, constraints) { final hasFullscreen = @@ -102,18 +103,22 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget { : leading, trailing: [ ...trailing, - WindowTitleBarButtons(foregroundColor: foregroundColor), + Align( + alignment: Alignment.topRight, + child: + WindowTitleBarButtons(foregroundColor: foregroundColor), + ), ], title: title, header: header, subtitle: subtitle, trailingExpanded: trailingExpanded, alignment: alignment, - padding: padding, + padding: padding ?? EdgeInsets.zero, backgroundColor: backgroundColor, leadingGap: leadingGap, trailingGap: trailingGap, - height: height, + height: height ?? (48 * context.theme.scaling), surfaceBlur: surfaceBlur, surfaceOpacity: surfaceOpacity, useSafeArea: useSafeArea, @@ -127,5 +132,5 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget { } @override - Size get preferredSize => Size.fromHeight(height ?? 56.0); + Size get preferredSize => Size.fromHeight(height ?? 48); } diff --git a/lib/components/titlebar/titlebar_buttons.dart b/lib/components/titlebar/titlebar_buttons.dart index 42765d7b..92c2c93d 100644 --- a/lib/components/titlebar/titlebar_buttons.dart +++ b/lib/components/titlebar/titlebar_buttons.dart @@ -2,9 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; +import 'package:spotube/components/hover_builder.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/components/titlebar/titlebar_icon_buttons.dart'; -import 'package:spotube/components/titlebar/window_button.dart'; + +import 'package:spotube/hooks/configurators/use_window_listener.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/utils/platform.dart'; import 'package:titlebar_buttons/titlebar_buttons.dart'; @@ -22,12 +24,20 @@ class WindowTitleBarButtons extends HookConsumerWidget { final preferences = ref.watch(userPreferencesProvider); final isMaximized = useState(null); const type = ThemeType.auto; - final scale = context.theme.scaling; Future onClose() async { await windowManager.close(); } + useWindowListener( + onWindowMaximize: () { + isMaximized.value = true; + }, + onWindowUnmaximize: () { + isMaximized.value = false; + }, + ); + useEffect(() { if (kIsDesktop) { windowManager.isMaximized().then((value) { @@ -42,86 +52,68 @@ class WindowTitleBarButtons extends HookConsumerWidget { } if (kIsWindows) { - final theme = Theme.of(context); - final colors = WindowButtonColors( - normal: Colors.transparent, - iconNormal: foregroundColor ?? theme.colorScheme.onSurface, - mouseOver: theme.colorScheme.onSurface.withAlpha(25), - mouseDown: theme.colorScheme.onSurface.withAlpha(51), - iconMouseOver: theme.colorScheme.onSurface, - iconMouseDown: theme.colorScheme.onSurface, - ); - - final closeColors = WindowButtonColors( - normal: Colors.transparent, - iconNormal: foregroundColor ?? theme.colorScheme.onSurface, - mouseOver: Colors.red, - mouseDown: Colors.red[800]!, - iconMouseOver: Colors.white, - iconMouseDown: Colors.black, - ); - - return Transform( - transform: Matrix4.translationValues(18, -12, 0) * scale, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - MinimizeWindowButton( - onPressed: windowManager.minimize, - colors: colors, + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ShadcnWindowButton( + icon: MinimizeIcon(color: context.theme.colorScheme.foreground), + onPressed: windowManager.minimize, + ), + if (isMaximized.value != true) + ShadcnWindowButton( + icon: MaximizeIcon(color: context.theme.colorScheme.foreground), + onPressed: () { + windowManager.maximize(); + isMaximized.value = true; + }, + ) + else + ShadcnWindowButton( + icon: RestoreIcon(color: context.theme.colorScheme.foreground), + onPressed: () { + windowManager.unmaximize(); + isMaximized.value = false; + }, ), - if (isMaximized.value != true) - MaximizeWindowButton( - colors: colors, - onPressed: () { - windowManager.maximize(); - isMaximized.value = true; - }, - ) - else - RestoreWindowButton( - colors: colors, - onPressed: () { - windowManager.unmaximize(); - isMaximized.value = false; - }, + HoverBuilder(builder: (context, isHovered) { + return ShadcnWindowButton( + icon: CloseIcon( + color: isHovered + ? Colors.white + : context.theme.colorScheme.foreground, ), - CloseWindowButton( - colors: closeColors, onPressed: onClose, - ), - ], - ), + hoverBackgroundColor: const Color(0xFFD32F2F), + ); + }), + ], ); } - return Transform( - transform: Matrix4.translationValues(18, -12, 0) * scale, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - DecoratedMinimizeButton( - type: type, - onPressed: windowManager.minimize, - ), - DecoratedMaximizeButton( - type: type, - onPressed: () async { - if (await windowManager.isMaximized()) { - await windowManager.unmaximize(); - isMaximized.value = false; - } else { - await windowManager.maximize(); - isMaximized.value = true; - } - }, - ), - DecoratedCloseButton( - type: type, - onPressed: onClose, - ), - ], - ), + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DecoratedMinimizeButton( + type: type, + onPressed: windowManager.minimize, + ), + DecoratedMaximizeButton( + type: type, + onPressed: () async { + if (await windowManager.isMaximized()) { + await windowManager.unmaximize(); + isMaximized.value = false; + } else { + await windowManager.maximize(); + isMaximized.value = true; + } + }, + ), + DecoratedCloseButton( + type: type, + onPressed: onClose, + ), + ], ); } } diff --git a/lib/components/titlebar/titlebar_icon_buttons.dart b/lib/components/titlebar/titlebar_icon_buttons.dart index 70170262..481a22ce 100644 --- a/lib/components/titlebar/titlebar_icon_buttons.dart +++ b/lib/components/titlebar/titlebar_icon_buttons.dart @@ -1,56 +1,50 @@ import 'dart:math'; -import 'package:flutter/material.dart'; -import 'package:spotube/components/titlebar/window_button.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/extensions/button_variance.dart'; -class MinimizeWindowButton extends WindowButton { - MinimizeWindowButton( - {super.key, super.colors, super.onPressed, bool? animate}) - : super( - animate: animate ?? false, - iconBuilder: (buttonContext) => - MinimizeIcon(color: buttonContext.iconColor), - ); +class ShadcnWindowButton extends StatelessWidget { + final Widget icon; + final VoidCallback onPressed; + final Color? hoverBackgroundColor; + + const ShadcnWindowButton({ + super.key, + required this.icon, + required this.onPressed, + this.hoverBackgroundColor, + }); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 45, + height: 32, + child: IconButton( + variance: ButtonVariance.ghost.copyWith( + decoration: (context, states) { + final decoration = ButtonVariance.ghost.decoration(context, states) + as BoxDecoration; + if (hoverBackgroundColor != null && + states.contains(WidgetState.hovered)) { + return decoration.copyWith( + borderRadius: BorderRadius.zero, + color: hoverBackgroundColor, + ); + } + + return decoration.copyWith( + borderRadius: BorderRadius.zero, + ); + }, + ), + icon: icon, + onPressed: onPressed, + ), + ); + } } -class MaximizeWindowButton extends WindowButton { - MaximizeWindowButton( - {super.key, super.colors, super.onPressed, bool? animate}) - : super( - animate: animate ?? false, - iconBuilder: (buttonContext) => - MaximizeIcon(color: buttonContext.iconColor), - ); -} - -class RestoreWindowButton extends WindowButton { - RestoreWindowButton({super.key, super.colors, super.onPressed, bool? animate}) - : super( - animate: animate ?? false, - iconBuilder: (buttonContext) => - RestoreIcon(color: buttonContext.iconColor), - ); -} - -final _defaultCloseButtonColors = WindowButtonColors( - mouseOver: const Color(0xFFD32F2F), - mouseDown: const Color(0xFFB71C1C), - iconNormal: const Color(0xFF805306), - iconMouseOver: const Color(0xFFFFFFFF)); - -class CloseWindowButton extends WindowButton { - CloseWindowButton( - {super.key, WindowButtonColors? colors, super.onPressed, bool? animate}) - : super( - colors: colors ?? _defaultCloseButtonColors, - animate: animate ?? false, - iconBuilder: (buttonContext) => - CloseIcon(color: buttonContext.iconColor), - ); -} - -// Switched to CustomPaint icons by https://github.com/esDotDev - /// Close class CloseIcon extends StatelessWidget { final Color color; @@ -149,8 +143,9 @@ class _AlignedPaint extends StatelessWidget { @override Widget build(BuildContext context) { return Align( - alignment: Alignment.center, - child: CustomPaint(size: const Size(10, 10), painter: painter)); + alignment: Alignment.center, + child: CustomPaint(size: const Size(10, 10), painter: painter), + ); } } diff --git a/lib/components/titlebar/window_button.dart b/lib/components/titlebar/window_button.dart deleted file mode 100644 index fef9d754..00000000 --- a/lib/components/titlebar/window_button.dart +++ /dev/null @@ -1,125 +0,0 @@ -import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:spotube/components/titlebar/mouse_state.dart'; -import 'package:spotube/components/titlebar/titlebar.dart'; - -typedef WindowButtonIconBuilder = Widget Function( - WindowButtonContext buttonContext); -typedef WindowButtonBuilder = Widget Function( - WindowButtonContext buttonContext, Widget icon); - -class WindowButtonContext { - BuildContext context; - MouseState mouseState; - Color? backgroundColor; - Color iconColor; - WindowButtonContext( - {required this.context, - required this.mouseState, - this.backgroundColor, - required this.iconColor}); -} - -class WindowButtonColors { - late Color normal; - late Color mouseOver; - late Color mouseDown; - late Color iconNormal; - late Color iconMouseOver; - late Color iconMouseDown; - WindowButtonColors( - {Color? normal, - Color? mouseOver, - Color? mouseDown, - Color? iconNormal, - Color? iconMouseOver, - Color? iconMouseDown}) { - this.normal = normal ?? _defaultButtonColors.normal; - this.mouseOver = mouseOver ?? _defaultButtonColors.mouseOver; - this.mouseDown = mouseDown ?? _defaultButtonColors.mouseDown; - this.iconNormal = iconNormal ?? _defaultButtonColors.iconNormal; - this.iconMouseOver = iconMouseOver ?? _defaultButtonColors.iconMouseOver; - this.iconMouseDown = iconMouseDown ?? _defaultButtonColors.iconMouseDown; - } -} - -final _defaultButtonColors = WindowButtonColors( - normal: Colors.transparent, - iconNormal: const Color(0xFF805306), - mouseOver: const Color(0xFF404040), - mouseDown: const Color(0xFF202020), - iconMouseOver: const Color(0xFFFFFFFF), - iconMouseDown: const Color(0xFFF0F0F0), -); - -class WindowButton extends StatelessWidget { - final WindowButtonBuilder? builder; - final WindowButtonIconBuilder? iconBuilder; - late final WindowButtonColors colors; - final bool animate; - final EdgeInsets? padding; - final VoidCallback? onPressed; - - WindowButton( - {super.key, - WindowButtonColors? colors, - this.builder, - @required this.iconBuilder, - this.padding, - this.onPressed, - this.animate = false}) { - this.colors = colors ?? _defaultButtonColors; - } - - Color getBackgroundColor(MouseState mouseState) { - if (mouseState.isMouseDown) return colors.mouseDown; - if (mouseState.isMouseOver) return colors.mouseOver; - return colors.normal; - } - - Color getIconColor(MouseState mouseState) { - if (mouseState.isMouseDown) return colors.iconMouseDown; - if (mouseState.isMouseOver) return colors.iconMouseOver; - return colors.iconNormal; - } - - @override - Widget build(BuildContext context) { - if (!kTitlebarVisible) return const SizedBox.shrink(); - - return MouseStateBuilder( - builder: (context, mouseState) { - WindowButtonContext buttonContext = WindowButtonContext( - mouseState: mouseState, - context: context, - backgroundColor: getBackgroundColor(mouseState), - iconColor: getIconColor(mouseState)); - - var icon = (iconBuilder != null) - ? iconBuilder!(buttonContext) - : const SizedBox(); - - var fadeOutColor = - getBackgroundColor(MouseState()..isMouseOver = true).withAlpha(0); - var padding = this.padding ?? const EdgeInsets.all(10); - var animationMs = - mouseState.isMouseOver ? (animate ? 100 : 0) : (animate ? 200 : 0); - Widget iconWithPadding = Padding(padding: padding, child: icon); - iconWithPadding = AnimatedContainer( - curve: Curves.easeOut, - duration: Duration(milliseconds: animationMs), - color: buttonContext.backgroundColor ?? fadeOutColor, - child: iconWithPadding); - var button = - (builder != null) ? builder!(buttonContext, icon) : iconWithPadding; - return SizedBox( - width: 45, - height: 32, - child: button, - ); - }, - onPressed: () { - if (onPressed != null) onPressed!(); - }, - ); - } -} diff --git a/lib/main.dart b/lib/main.dart index 5b20acd8..8025f7cc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -207,7 +207,9 @@ class Spotube extends HookConsumerWidget { child: child!, ); - if (kIsDesktop && !kIsMacOS) child = DragToResizeArea(child: child); + if (kIsLinux) { + child = DragToResizeArea(child: child); + } return child; }, diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart index 78371c4d..1638393b 100644 --- a/lib/pages/home/home.dart +++ b/lib/pages/home/home.dart @@ -36,7 +36,7 @@ class HomePage extends HookConsumerWidget { bottom: false, child: Scaffold( headers: [ - if (kTitlebarVisible) const TitleBar(), + if (kTitlebarVisible) const TitleBar(height: 30), ], child: CustomScrollView( controller: controller, diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index 87b6a6cb..ec896228 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -2,8 +2,6 @@ import 'package:flutter/material.dart' show Badge; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; - import 'package:spotube/modules/library/user_local_tracks.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/modules/library/user_albums.dart'; @@ -19,7 +17,6 @@ class LibraryPage extends HookConsumerWidget { const LibraryPage({super.key}); @override Widget build(BuildContext context, ref) { - final scale = context.theme.scaling; final downloadingCount = ref.watch(downloadManagerProvider).$downloadCount; final index = useState(0); @@ -40,11 +37,6 @@ class LibraryPage extends HookConsumerWidget { child: Scaffold( headers: [ TitleBar( - padding: const EdgeInsets.symmetric( - horizontal: 18, - vertical: 12, - ).copyWith(left: 0) * - scale, child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: TabList( diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index 679ef78e..f61dbbe3 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -151,6 +151,8 @@ class LyricsPage extends HookConsumerWidget { ? TitleBar( backgroundColor: Colors.transparent, title: tabbar, + height: 58 * context.theme.scaling, + surfaceBlur: 0, ) : tabbar ], diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index efd46ebb..701c3c5c 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -70,7 +70,8 @@ class SearchPage extends HookConsumerWidget { bottom: false, child: Scaffold( headers: [ - if (kTitlebarVisible) const TitleBar(automaticallyImplyLeading: true) + if (kTitlebarVisible) + const TitleBar(automaticallyImplyLeading: true, height: 30) ], child: auth.asData?.value == null ? const AnonymousFallback() From 696875e4b5ab5d8976aa538164dfff54f2eb83de Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 12 Jan 2025 23:21:20 +0600 Subject: [PATCH 50/81] chore: use youtube_explode from github --- lib/provider/audio_player/audio_player.dart | 8 ++++++-- pubspec.lock | 15 ++++++++------- pubspec.yaml | 7 +++++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/provider/audio_player/audio_player.dart b/lib/provider/audio_player/audio_player.dart index b4892a0c..170cbb12 100644 --- a/lib/provider/audio_player/audio_player.dart +++ b/lib/provider/audio_player/audio_player.dart @@ -301,7 +301,9 @@ class AudioPlayerNotifier extends Notifier { bool _compareTracks(Track a, Track b) { if ((a is LocalTrack && b is! LocalTrack) || - (a is! LocalTrack && b is LocalTrack)) return false; + (a is! LocalTrack && b is LocalTrack)) { + return false; + } return a is LocalTrack && b is LocalTrack ? (a).path == (b).path @@ -347,7 +349,9 @@ class AudioPlayerNotifier extends Notifier { newIndex < 0 || oldIndex < 0 || newIndex > state.tracks.length - 1 || - oldIndex > state.tracks.length - 1) return; + oldIndex > state.tracks.length - 1) { + return; + } await audioPlayer.moveTrack(oldIndex, newIndex); } diff --git a/pubspec.lock b/pubspec.lock index 2666460c..2fa1d8ab 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -979,10 +979,10 @@ packages: dependency: "direct main" description: name: flutter_undraw - sha256: "17fe2738231c502171f984c003f6e40979de1a2550ef2debdd29fec27ae006ea" + sha256: a38083350fac9e0d44ddde0e53a39f00730498ed4a110f967a38c6fb1a161755 url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.1" flutter_web_plugins: dependency: transitive description: flutter @@ -2696,11 +2696,12 @@ packages: youtube_explode_dart: dependency: "direct main" description: - name: youtube_explode_dart - sha256: "51ca5b2c03bf56060143d4f87df90ec3227592d7ae8a8003532533ae019d4291" - url: "https://pub.dev" - source: hosted - version: "2.3.6" + path: "." + ref: e519db65ad0b0a40b12f69285932f9db509da3cf + resolved-ref: e519db65ad0b0a40b12f69285932f9db509da3cf + url: "https://github.com/Hexer10/youtube_explode_dart.git" + source: git + version: "2.3.7" sdks: dart: ">=3.6.0 <4.0.0" flutter: ">=3.27.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3aaa3395..1594abb2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,7 +63,7 @@ dependencies: flutter_riverpod: ^2.5.1 flutter_secure_storage: ^9.0.0 flutter_sharing_intent: ^1.1.0 - flutter_undraw: ^0.2.0 + flutter_undraw: ^0.2.1 form_builder_validators: ^11.1.1 form_validator: ^2.1.1 freezed_annotation: ^2.4.1 @@ -134,7 +134,10 @@ dependencies: wikipedia_api: ^0.1.0 win32_registry: ^1.1.5 window_manager: ^0.4.3 - youtube_explode_dart: ^2.3.5 + youtube_explode_dart: + git: + url: https://github.com/Hexer10/youtube_explode_dart.git + ref: e519db65ad0b0a40b12f69285932f9db509da3cf dev_dependencies: build_runner: ^2.4.13 From 6c005592e35edff02c3dc7870ad8293eaced428d Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 16 Jan 2025 21:13:42 +0600 Subject: [PATCH 51/81] refactor: color scheme support based on shadcn colors --- lib/main.dart | 16 +- lib/modules/home/sections/feed.dart | 21 +- lib/modules/home/sections/genres/genres.dart | 1 - .../settings/color_scheme_picker_dialog.dart | 252 ++++++------------ lib/pages/settings/sections/appearance.dart | 5 +- 5 files changed, 108 insertions(+), 187 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 8025f7cc..af7da1b7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -26,6 +26,7 @@ import 'package:spotube/hooks/configurators/use_fix_window_stretching.dart'; import 'package:spotube/hooks/configurators/use_get_storage_perms.dart'; import 'package:spotube/hooks/configurators/use_has_touch.dart'; import 'package:spotube/models/database/database.dart'; +import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; import 'package:spotube/provider/audio_player/audio_player_streams.dart'; import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/glance/glance.dart'; @@ -43,7 +44,6 @@ import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/services/wm_tools/wm_tools.dart'; import 'package:spotube/utils/migrations/sandbox.dart'; import 'package:spotube/utils/platform.dart'; -import 'package:system_theme/system_theme.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart'; @@ -83,8 +83,6 @@ Future main(List rawArgs) async { await windowManager.setPreventClose(true); } - await SystemTheme.accentColor.load(); - if (!kIsWeb) { MetadataGod.initialize(); } @@ -133,8 +131,8 @@ class Spotube extends HookConsumerWidget { final themeMode = ref.watch(userPreferencesProvider.select((s) => s.themeMode)); final locale = ref.watch(userPreferencesProvider.select((s) => s.locale)); - // final accentMaterialColor = - // ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme)); + final accentMaterialColor = + ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme)); // final isAmoledTheme = // ref.watch(userPreferencesProvider.select((s) => s.amoledDarkTheme)); // final paletteColor = @@ -217,14 +215,18 @@ class Spotube extends HookConsumerWidget { theme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), - colorScheme: ColorSchemes.lightOrange(), + colorScheme: + colorSchemeMap[accentMaterialColor.name]?.call(ThemeMode.light) ?? + ColorSchemes.lightOrange(), surfaceOpacity: .8, surfaceBlur: 10, ), darkTheme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), - colorScheme: ColorSchemes.darkOrange(), + colorScheme: + colorSchemeMap[accentMaterialColor.name]?.call(ThemeMode.dark) ?? + ColorSchemes.darkOrange(), surfaceOpacity: .8, surfaceBlur: 10, ), diff --git a/lib/modules/home/sections/feed.dart b/lib/modules/home/sections/feed.dart index bce2ea5b..34a9ee4b 100644 --- a/lib/modules/home/sections/feed.dart +++ b/lib/modules/home/sections/feed.dart @@ -1,6 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/home/feed/feed_section.dart'; @@ -38,18 +37,14 @@ class HomePageFeedSection extends HookConsumerWidget { hasNextPage: false, isLoadingNextPage: false, onFetchMore: () {}, - titleTrailing: Directionality( - textDirection: TextDirection.rtl, - child: Button.link( - leading: const Icon(SpotubeIcons.angleRight), - child: Text(context.l10n.browse_more), - onPressed: () => ServiceUtils.pushNamed( - context, - HomeFeedSectionPage.name, - pathParameters: { - "feedId": section.uri, - }, - ), + titleTrailing: Button.text( + child: Text(context.l10n.browse_all), + onPressed: () => ServiceUtils.pushNamed( + context, + HomeFeedSectionPage.name, + pathParameters: { + "feedId": section.uri, + }, ), ), ); diff --git a/lib/modules/home/sections/genres/genres.dart b/lib/modules/home/sections/genres/genres.dart index 520c1121..5e96f78f 100644 --- a/lib/modules/home/sections/genres/genres.dart +++ b/lib/modules/home/sections/genres/genres.dart @@ -74,7 +74,6 @@ class HomeGenresSection extends HookConsumerWidget { onPressed: () { context.pushNamed(GenrePage.name); }, - trailing: const Icon(SpotubeIcons.angleRight), child: Text( context.l10n.browse_all, ).muted(), diff --git a/lib/modules/settings/color_scheme_picker_dialog.dart b/lib/modules/settings/color_scheme_picker_dialog.dart index f2933505..8092f825 100644 --- a/lib/modules/settings/color_scheme_picker_dialog.dart +++ b/lib/modules/settings/color_scheme_picker_dialog.dart @@ -1,10 +1,11 @@ -import 'package:flutter/material.dart'; +import 'package:collection/collection.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; -import 'package:system_theme/system_theme.dart'; class SpotubeColor extends Color { final String name; @@ -25,23 +26,33 @@ class SpotubeColor extends Color { } final Set colorsMap = { - SpotubeColor(SystemTheme.accentColor.accent.value, name: "System"), - SpotubeColor(Colors.red.value, name: "Red"), - SpotubeColor(Colors.pink.value, name: "Pink"), - SpotubeColor(Colors.purple.value, name: "Purple"), - SpotubeColor(Colors.deepPurple.value, name: "DeepPurple"), - SpotubeColor(Colors.indigo.value, name: "Indigo"), - SpotubeColor(Colors.blue.value, name: "Blue"), - SpotubeColor(Colors.lightBlue.value, name: "LightBlue"), - SpotubeColor(Colors.cyan.value, name: "Cyan"), - SpotubeColor(Colors.teal.value, name: "Teal"), - SpotubeColor(Colors.green.value, name: "Green"), - SpotubeColor(Colors.lightGreen.value, name: "LightGreen"), - SpotubeColor(Colors.yellow.value, name: "Yellow"), - SpotubeColor(Colors.amber.value, name: "Amber"), - SpotubeColor(Colors.orange.value, name: "Orange"), - SpotubeColor(Colors.deepOrange.value, name: "DeepOrange"), - SpotubeColor(Colors.brown.value, name: "Brown"), + SpotubeColor(Colors.slate.value, name: "slate"), + SpotubeColor(Colors.gray.value, name: "gray"), + SpotubeColor(Colors.zinc.value, name: "zinc"), + SpotubeColor(Colors.neutral.value, name: "neutral"), + SpotubeColor(Colors.stone.value, name: "stone"), + SpotubeColor(Colors.red.value, name: "red"), + SpotubeColor(Colors.orange.value, name: "orange"), + SpotubeColor(Colors.yellow.value, name: "yellow"), + SpotubeColor(Colors.green.value, name: "green"), + SpotubeColor(Colors.blue.value, name: "blue"), + SpotubeColor(Colors.violet.value, name: "violet"), + SpotubeColor(Colors.rose.value, name: "rose"), +}; + +final colorSchemeMap = { + "slate": ColorSchemes.slate, + "gray": ColorSchemes.gray, + "zinc": ColorSchemes.zinc, + "neutral": ColorSchemes.neutral, + "stone": ColorSchemes.stone, + "red": ColorSchemes.red, + "orange": ColorSchemes.orange, + "yellow": ColorSchemes.yellow, + "green": ColorSchemes.green, + "blue": ColorSchemes.blue, + "violet": ColorSchemes.violet, + "rose": ColorSchemes.rose, }; class ColorSchemePickerDialog extends HookConsumerWidget { @@ -51,180 +62,93 @@ class ColorSchemePickerDialog extends HookConsumerWidget { Widget build(BuildContext context, ref) { final preferences = ref.watch(userPreferencesProvider); final preferencesNotifier = ref.watch(userPreferencesProvider.notifier); - final scheme = preferences.accentColorScheme; - final active = useState(colorsMap.firstWhere( - (element) { - return scheme.name == element.name; - }, - ).name); - onOk() { - preferencesNotifier.setAccentColorScheme( - colorsMap.firstWhere( - (element) { - return element.name == active.value; - }, - ), - ); - Navigator.pop(context); - } + final scheme = preferences.accentColorScheme; + final active = useState( + colorsMap.firstWhereOrNull( + (element) { + return scheme.name == element.name; + }, + )?.name, + ); return AlertDialog( - title: Text(context.l10n.pick_color_scheme), + title: Text( + context.l10n.pick_color_scheme, + style: TextStyle(color: context.theme.colorScheme.foreground), + ).large(), actions: [ - OutlinedButton( + Button.outline( child: Text(context.l10n.cancel), onPressed: () { Navigator.pop(context); }, ), - FilledButton( - onPressed: onOk, + Button.primary( + onPressed: () { + Navigator.pop(context); + }, child: Text(context.l10n.save), ), ], content: SizedBox( height: 200, width: 400, - child: ListView.separated( - separatorBuilder: (context, index) { - return const SizedBox(height: 10); - }, - itemCount: colorsMap.length, - itemBuilder: (context, index) { - final color = colorsMap.elementAt(index); - return ColorTile( - color: color, - isActive: active.value == color.name, - onPressed: () { - active.value = color.name; - }, - tooltip: color.name, - ); - }, + child: Wrap( + spacing: 8, + runSpacing: 8, + children: colorsMap.map( + (color) { + return ColorChip( + name: color.name, + color: color, + isActive: color.name == active.value, + onPressed: () { + active.value = color.name; + preferencesNotifier.setAccentColorScheme( + colorsMap.firstWhere( + (element) { + return element.name == color.name; + }, + ), + ); + }, + ); + }, + ).toList(), ), ), ); } } -class ColorTile extends StatelessWidget { +class ColorChip extends StatelessWidget { + final String name; final Color color; final bool isActive; - final void Function()? onPressed; - final String? tooltip; - final bool isCompact; - const ColorTile({ - required this.color, - this.isActive = false, - this.onPressed, - this.tooltip = "", - this.isCompact = false, + final VoidCallback onPressed; + const ColorChip({ super.key, + required this.name, + required this.color, + required this.isActive, + required this.onPressed, }); - factory ColorTile.compact({ - required Color color, - bool isActive = false, - void Function()? onPressed, - String? tooltip = "", - Key? key, - }) { - return ColorTile( - color: color, - isActive: isActive, - onPressed: onPressed, - tooltip: tooltip, - isCompact: true, - key: key, - ); - } - @override Widget build(BuildContext context) { - final theme = Theme.of(context); - - final lead = Container( - height: 40, - width: 40, - decoration: BoxDecoration( - border: isActive - ? Border.fromBorderSide( - BorderSide( - color: Color.lerp( - theme.colorScheme.primary, - theme.colorScheme.onPrimary, - 0.5, - )!, - width: 4, - ), - ) - : null, - borderRadius: BorderRadius.circular(15), - color: color, - ), - ); - - if (isCompact) { - return GestureDetector( - onTap: onPressed, - child: lead, - ); - } - - final colorScheme = ColorScheme.fromSeed(seedColor: color); - - final palette = [ - colorScheme.primary, - colorScheme.inversePrimary, - colorScheme.primaryContainer, - colorScheme.secondary, - colorScheme.secondaryContainer, - colorScheme.surface, - colorScheme.surface, - colorScheme.surfaceContainerHighest, - colorScheme.onPrimary, - colorScheme.onSurface, - ]; - - return GestureDetector( - onTap: onPressed, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - lead, - const SizedBox(width: 10), - Text( - tooltip!, - style: theme.textTheme.bodyLarge?.copyWith( - color: theme.colorScheme.primary, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - const SizedBox(height: 10), - Wrap( - alignment: WrapAlignment.start, - spacing: 10, - runSpacing: 10, - children: [ - ...palette.map( - (e) => Container( - height: 20, - width: 20, - decoration: BoxDecoration( - color: e, - borderRadius: BorderRadius.circular(5), - ), - ), - ), - ], - ), - ], + return Chip( + leading: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(10), + ), ), + onPressed: onPressed, + style: isActive ? ButtonVariance.primary : ButtonVariance.outline, + child: Text(name), ); } } diff --git a/lib/pages/settings/sections/appearance.dart b/lib/pages/settings/sections/appearance.dart index aaa2ce8a..55a8f1ef 100644 --- a/lib/pages/settings/sections/appearance.dart +++ b/lib/pages/settings/sections/appearance.dart @@ -94,10 +94,11 @@ class SettingsAppearanceSection extends HookConsumerWidget { horizontal: 15, vertical: 5, ), - trailing: ColorTile.compact( + trailing: ColorChip( color: preferences.accentColorScheme, + name: preferences.accentColorScheme.name, onPressed: pickColorScheme(), - isActive: true, + isActive: false, ), onTap: pickColorScheme(), ), From e470f50e813b4f02c3036d8d800e28fc4970a944 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 19 Jan 2025 19:59:42 +0600 Subject: [PATCH 52/81] chore: remove xmas background from glance widget --- .../oss/krtirtho/spotube/glance/HomePlayerWidget.kt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/android/app/src/main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt b/android/app/src/main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt index 013723c0..a20af959 100644 --- a/android/app/src/main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt +++ b/android/app/src/main/kotlin/oss/krtirtho/spotube/glance/HomePlayerWidget.kt @@ -120,16 +120,6 @@ class HomePlayerWidget : GlanceAppWidget() { } , ) { - Image( - provider = FlutterAssetImageProvider( - context, - "assets/backgrounds/xmas-effect.png" - ), - contentDescription = "Background", - modifier = GlanceModifier - .fillMaxSize(), - contentScale = ContentScale.Crop - ) Box( modifier = GlanceModifier .background( From 74a328e52916ba587e03d4e63818bc26f2d98e2d Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 19 Jan 2025 21:00:49 +0600 Subject: [PATCH 53/81] refactor: logs page to shadcn --- lib/l10n/app_en.arb | 3 +- lib/pages/settings/logs.dart | 106 +++++++++++++++---------- lib/pages/settings/sections/about.dart | 32 +++++--- lib/provider/logs/logs_provider.dart | 5 ++ pubspec.yaml | 1 + untranslated_messages.json | 78 ++++++++++++------ 6 files changed, 144 insertions(+), 81 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 9a0f1814..ae7abb01 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -414,5 +414,6 @@ "no_tracks": "Looks like there are no tracks here", "no_tracks_listened_yet": "Looks like you haven't listened to anything yet", "not_following_artists": "You're not following any artists", - "no_favorite_albums_yet": "Looks like you haven't added any albums to your favorites yet" + "no_favorite_albums_yet": "Looks like you haven't added any albums to your favorites yet", + "no_logs_found": "No logs found" } \ No newline at end of file diff --git a/lib/pages/settings/logs.dart b/lib/pages/settings/logs.dart index 0f1260aa..f9439317 100644 --- a/lib/pages/settings/logs.dart +++ b/lib/pages/settings/logs.dart @@ -1,8 +1,11 @@ -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_undraw/flutter_undraw.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/extensions/context.dart'; @@ -21,54 +24,73 @@ class LogsPage extends HookConsumerWidget { final logsQuery = ref.watch(logsProvider); return Scaffold( - appBar: TitleBar( - title: Text(context.l10n.logs), - leading: const [BackButton()], - trailing: [ - IconButton( - icon: const Icon(SpotubeIcons.clipboard), - iconSize: 16, - onPressed: () async { - final logsSnapshot = await ref.read(logsProvider.future); + headers: [ + TitleBar( + title: Text(context.l10n.logs), + leading: const [BackButton()], + trailing: [ + IconButton.ghost( + icon: const Icon(SpotubeIcons.clipboard, size: 16), + onPressed: () async { + final logsSnapshot = await ref.read(logsProvider.future); - await Clipboard.setData(ClipboardData(text: logsSnapshot)); - if (context.mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(context.l10n.copied_to_clipboard("")), - ), - ); - } - }, - ), - IconButton( - icon: const Icon(SpotubeIcons.trash), - iconSize: 16, - onPressed: () async { - ref.invalidate(logsProvider); + await Clipboard.setData(ClipboardData(text: logsSnapshot)); + if (context.mounted) { + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Basic( + title: Text(context.l10n.copied_to_clipboard("")), + ), + ); + }, + ); + } + }, + ), + IconButton.ghost( + icon: const Icon( + SpotubeIcons.trash, + size: 16, + ), + onPressed: () async { + ref.invalidate(logsProvider); - final logsFile = await AppLogger.getLogsPath(); + final logsFile = await AppLogger.getLogsPath(); - await logsFile.writeAsString(""); - }, - ) - ], - ), - body: SafeArea( + await logsFile.writeAsString(""); + }, + ) + ], + ) + ], + child: SafeArea( child: switch (logsQuery) { - AsyncData(:final value) => Card( - child: InterScrollbar( + AsyncData(:final value) => InterScrollbar( + controller: controller, + child: SingleChildScrollView( + padding: const EdgeInsets.all(8.0), controller: controller, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: SingleChildScrollView( - controller: controller, - child: Text(value), - ), - ), + child: Card(child: SelectableText(value)), ), ), - AsyncError(:final error) => Center(child: Text(error.toString())), + AsyncError(:final error) => switch (error) { + StateError() => Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Undraw( + illustration: UndrawIllustration.noData, + height: 200 * context.theme.scaling, + width: 200 * context.theme.scaling, + color: context.theme.colorScheme.primary, + ), + Text(context.l10n.no_logs_found).muted().small(), + ], + ), + _ => Center(child: Text(error.toString())), + }, _ => const Center(child: CircularProgressIndicator()), }, ), diff --git a/lib/pages/settings/sections/about.dart b/lib/pages/settings/sections/about.dart index 5910fc1b..5ed26ee8 100644 --- a/lib/pages/settings/sections/about.dart +++ b/lib/pages/settings/sections/about.dart @@ -1,9 +1,8 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart' show FilledButton, ButtonStyle, ListTile; +import 'package:flutter/material.dart' show ListTile; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' hide ButtonStyle; -import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/env.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/settings/section_card_with_heading.dart'; @@ -44,16 +43,25 @@ class SettingsAboutSection extends HookConsumerWidget { ), ), ), - trailing: (context, update) => FilledButton( - style: ButtonStyle( - backgroundColor: WidgetStatePropertyAll(Colors.red[100]), - foregroundColor: const WidgetStatePropertyAll(Colors.pink), - padding: const WidgetStatePropertyAll(EdgeInsets.all(15)), - shape: WidgetStatePropertyAll( - RoundedRectangleBorder( - borderRadius: context.theme.borderRadiusLg, - ), - ), + trailing: (context, update) => Button( + style: ButtonVariance.primary.copyWith( + decoration: (context, states, value) { + final decoration = ButtonVariance.primary + .decoration(context, states) as BoxDecoration; + + if (states.contains(WidgetState.hovered)) { + return decoration.copyWith(color: Colors.pink[400]); + } else if (states.contains(WidgetState.focused)) { + return decoration.copyWith(color: Colors.pink[300]); + } else if (states.isNotEmpty) { + return decoration; + } + + return decoration.copyWith(color: Colors.pink); + }, + textStyle: (context, states, value) => ButtonVariance.primary + .textStyle(context, states) + .copyWith(color: Colors.white), ), onPressed: () { launchUrlString( diff --git a/lib/provider/logs/logs_provider.dart b/lib/provider/logs/logs_provider.dart index b0e95cae..571d96cc 100644 --- a/lib/provider/logs/logs_provider.dart +++ b/lib/provider/logs/logs_provider.dart @@ -6,6 +6,11 @@ import 'package:spotube/services/logger/logger.dart'; final logsProvider = StreamProvider.autoDispose((ref) async* { final file = await AppLogger.getLogsPath(); final stream = file.openRead().transform(utf8.decoder); + + if (await stream.isEmpty) { + throw StateError('No logs found'); + } + await for (final line in stream) { yield line; } diff --git a/pubspec.yaml b/pubspec.yaml index 1594abb2..3c20981b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -188,6 +188,7 @@ flutter: - packages/flutter_undraw/assets/undraw/follow_me_drone.svg - packages/flutter_undraw/assets/undraw/taken.svg - packages/flutter_undraw/assets/undraw/empty.svg + - packages/flutter_undraw/assets/undraw/no_data.svg fonts: - family: GeistSans fonts: diff --git a/untranslated_messages.json b/untranslated_messages.json index b00b1fd4..810c3125 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -14,7 +14,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "bn": [ @@ -32,7 +33,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "ca": [ @@ -50,7 +52,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "cs": [ @@ -68,7 +71,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "de": [ @@ -86,7 +90,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "es": [ @@ -104,7 +109,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "eu": [ @@ -122,7 +128,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "fa": [ @@ -140,7 +147,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "fi": [ @@ -158,7 +166,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "fr": [ @@ -176,7 +185,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "hi": [ @@ -194,7 +204,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "id": [ @@ -212,7 +223,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "it": [ @@ -230,7 +242,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "ja": [ @@ -248,7 +261,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "ka": [ @@ -266,7 +280,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "ko": [ @@ -284,7 +299,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "ne": [ @@ -302,7 +318,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "nl": [ @@ -320,7 +337,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "pl": [ @@ -338,7 +356,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "pt": [ @@ -356,7 +375,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "ru": [ @@ -374,7 +394,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "th": [ @@ -392,7 +413,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "tr": [ @@ -410,7 +432,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "uk": [ @@ -428,7 +451,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "vi": [ @@ -446,7 +470,8 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ], "zh": [ @@ -464,6 +489,7 @@ "no_tracks", "no_tracks_listened_yet", "not_following_artists", - "no_favorite_albums_yet" + "no_favorite_albums_yet", + "no_logs_found" ] } From 086107b2cd9ecf0c7e20d1086f813cf3ba855f43 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Mon, 20 Jan 2025 13:24:24 +0600 Subject: [PATCH 54/81] refactor: adaptive list tile to use shadcn --- .../adaptive/adaptive_list_tile.dart | 57 +++++++++---------- lib/pages/settings/sections/about.dart | 10 +--- 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/lib/components/adaptive/adaptive_list_tile.dart b/lib/components/adaptive/adaptive_list_tile.dart index 33df44c1..c6d00bd4 100644 --- a/lib/components/adaptive/adaptive_list_tile.dart +++ b/lib/components/adaptive/adaptive_list_tile.dart @@ -1,5 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/constrains.dart'; class AdaptiveListTile extends HookWidget { @@ -24,41 +25,39 @@ class AdaptiveListTile extends HookWidget { Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); - return ListTile( + return ButtonTile( title: title, subtitle: subtitle, trailing: breakOn ?? mediaQuery.smAndDown ? null : trailing?.call(context, null), leading: leading, - onTap: breakOn ?? mediaQuery.smAndDown - ? () { - onTap?.call(); - showDialog( - context: context, - barrierDismissible: true, - builder: (context) { - return StatefulBuilder(builder: (context, update) { - return AlertDialog( - title: title != null - ? Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (leading != null) ...[ - leading!, - const SizedBox(width: 5) - ], - Flexible(child: title!), - ], - ) - : Container(), - content: trailing?.call(context, update), - ); - }); - }, + enabled: breakOn ?? mediaQuery.smAndDown, + onPressed: () { + onTap?.call(); + showDialog( + context: context, + barrierDismissible: true, + builder: (context) { + return StatefulBuilder(builder: (context, update) { + return AlertDialog( + title: title != null + ? Row( + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (leading != null) leading!, + Flexible(child: title!), + ], + ) + : const SizedBox.shrink(), + content: Center(child: trailing?.call(context, update)), ); - } - : null, + }); + }, + ); + }, ); } } diff --git a/lib/pages/settings/sections/about.dart b/lib/pages/settings/sections/about.dart index 5ed26ee8..7f5d3977 100644 --- a/lib/pages/settings/sections/about.dart +++ b/lib/pages/settings/sections/about.dart @@ -69,14 +69,8 @@ class SettingsAboutSection extends HookConsumerWidget { mode: LaunchMode.externalApplication, ); }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(SpotubeIcons.heart), - const SizedBox(width: 5), - Text(context.l10n.please_sponsor), - ], - ), + leading: const Icon(SpotubeIcons.heart), + child: Text(context.l10n.please_sponsor), ), ), if (Env.enableUpdateChecker) From 4fead5f504273699f951f9f29a1713f1a6905a65 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Mon, 20 Jan 2025 22:04:12 +0600 Subject: [PATCH 55/81] feat: pause playback when no internet connection --- lib/modules/root/use_downloader_dialogs.dart | 46 ++++++ .../root/use_global_subscriptions.dart | 127 +++++++++++++++ lib/pages/root/root_app.dart | 144 +----------------- lib/provider/audio_player/audio_player.dart | 2 +- lib/services/connectivity_adapter.dart | 12 +- .../sourced_track/sources/youtube.dart | 13 +- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + macos/Podfile.lock | 7 + pubspec.lock | 24 +++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 12 files changed, 233 insertions(+), 149 deletions(-) create mode 100644 lib/modules/root/use_downloader_dialogs.dart create mode 100644 lib/modules/root/use_global_subscriptions.dart diff --git a/lib/modules/root/use_downloader_dialogs.dart b/lib/modules/root/use_downloader_dialogs.dart new file mode 100644 index 00000000..e2f91043 --- /dev/null +++ b/lib/modules/root/use_downloader_dialogs.dart @@ -0,0 +1,46 @@ +import 'dart:async'; + +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/components/dialogs/replace_downloaded_dialog.dart'; +import 'package:spotube/provider/download_manager_provider.dart'; + +void useDownloaderDialogs(WidgetRef ref) { + final context = useContext(); + final showingDialogCompleter = useRef(Completer()..complete()); + final downloader = ref.watch(downloadManagerProvider); + + useEffect(() { + downloader.onFileExists = (track) async { + if (!context.mounted) return false; + + if (!showingDialogCompleter.value.isCompleted) { + await showingDialogCompleter.value.future; + } + + final replaceAll = ref.read(replaceDownloadedFileState); + + if (replaceAll != null) return replaceAll; + + showingDialogCompleter.value = Completer(); + + if (context.mounted) { + final result = await showDialog( + context: context, + builder: (context) => ReplaceDownloadedDialog( + track: track, + ), + ) ?? + false; + + showingDialogCompleter.value.complete(); + return result; + } + + // it'll never reach here as root_app is always mounted + return false; + }; + return null; + }, [downloader]); +} diff --git a/lib/modules/root/use_global_subscriptions.dart b/lib/modules/root/use_global_subscriptions.dart new file mode 100644 index 00000000..e0e4dae7 --- /dev/null +++ b/lib/modules/root/use_global_subscriptions.dart @@ -0,0 +1,127 @@ +import 'dart:async'; + +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/extensions/context.dart'; +import 'package:spotube/provider/server/routes/connect.dart'; +import 'package:spotube/services/audio_player/audio_player.dart'; +import 'package:spotube/services/connectivity_adapter.dart'; +import 'package:spotube/utils/service_utils.dart'; + +void useGlobalSubscriptions(WidgetRef ref) { + final context = useContext(); + final theme = Theme.of(context); + final connectRoutes = ref.watch(serverConnectRoutesProvider); + + useEffect(() { + WidgetsBinding.instance.addPostFrameCallback((_) async { + ServiceUtils.checkForUpdates(context, ref); + }); + + StreamSubscription? audioPlayerSubscription; + bool pausedByStream = false; + + final subscriptions = [ + ConnectionCheckerService.instance.onConnectivityChanged + .listen((connected) async { + audioPlayerSubscription?.cancel(); + + /// Pausing or resuming based on connectivity to avoid MPV skipping + /// audio while retrying to connect + if (audioPlayer.currentIndex >= 0) { + if (connected && audioPlayer.isPaused && pausedByStream) { + await audioPlayer.resume(); + pausedByStream = false; + } else if (!connected && audioPlayer.isPlaying) { + if ((audioPlayer.bufferedPosition - const Duration(seconds: 1)) <= + audioPlayer.position) { + await audioPlayer.pause(); + pausedByStream = true; + } else { + audioPlayerSubscription = + audioPlayer.positionStream.listen((position) async { + if (ConnectionCheckerService.instance.isConnectedSync) return; + + final bufferedPosition = + audioPlayer.bufferedPosition - const Duration(seconds: 1); + final duration = + audioPlayer.duration - const Duration(seconds: 1); + + if (bufferedPosition <= position || position >= duration) { + audioPlayer.pause(); + pausedByStream = true; + } + }); + } + } + } + + // Show notification for connection related issues + if (!context.mounted) return; + + showToast( + context: context, + location: ToastLocation.bottomCenter, + builder: (context, overlay) { + if (connected) { + return SurfaceCard( + child: Basic( + leading: const Icon(SpotubeIcons.wifi), + title: Text(context.l10n.connection_restored), + ), + ); + } + + return SurfaceCard( + fillColor: theme.colorScheme.destructive, + filled: true, + child: Basic( + leading: Icon( + SpotubeIcons.noWifi, + color: theme.colorScheme.destructiveForeground, + ), + trailing: Text( + context.l10n.you_are_offline, + style: TextStyle( + color: theme.colorScheme.destructiveForeground, + ), + ), + ), + ); + }, + ); + }), + connectRoutes.connectClientStream.listen((clientOrigin) { + if (!context.mounted) return; + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + fillColor: Colors.yellow[600], + filled: true, + child: Basic( + leading: const Icon( + SpotubeIcons.error, + color: Colors.black, + ), + title: Text( + context.l10n.connect_client_alert(clientOrigin), + style: const TextStyle(color: Colors.black), + ), + ), + ); + }, + ); + }) + ]; + + return () { + for (final subscription in subscriptions) { + subscription.cancel(); + } + }; + }, []); +} diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index cdb56910..2a1bf088 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -1,26 +1,20 @@ -import 'dart:async'; - import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; -import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/framework/app_pop_scope.dart'; -import 'package:spotube/components/dialogs/replace_downloaded_dialog.dart'; import 'package:spotube/modules/root/bottom_player.dart'; import 'package:spotube/modules/root/sidebar.dart'; import 'package:spotube/modules/root/spotube_navigation_bar.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/hooks/configurators/use_endless_playback.dart'; +import 'package:spotube/modules/root/use_downloader_dialogs.dart'; +import 'package:spotube/modules/root/use_global_subscriptions.dart'; import 'package:spotube/pages/home/home.dart'; -import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/glance/glance.dart'; -import 'package:spotube/provider/server/routes/connect.dart'; -import 'package:spotube/services/connectivity_adapter.dart'; import 'package:spotube/utils/platform.dart'; -import 'package:spotube/utils/service_utils.dart'; class RootApp extends HookConsumerWidget { final Widget child; @@ -31,138 +25,14 @@ class RootApp extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final theme = Theme.of(context); - - final showingDialogCompleter = useRef(Completer()..complete()); - final downloader = ref.watch(downloadManagerProvider); - - final connectRoutes = ref.watch(serverConnectRoutesProvider); - - ref.listen(glanceProvider, (_, __) {}); - - useEffect(() { - WidgetsBinding.instance.addPostFrameCallback((_) async { - ServiceUtils.checkForUpdates(context, ref); - }); - - final subscriptions = [ - ConnectionCheckerService.instance.onConnectivityChanged - .listen((status) { - if (!context.mounted) return; - if (status) { - showToast( - context: context, - builder: (context, overlay) { - return SurfaceCard( - fillColor: theme.colorScheme.primary, - child: Row( - children: [ - Icon( - SpotubeIcons.wifi, - color: theme.colorScheme.primaryForeground, - ), - const SizedBox(width: 10), - Text(context.l10n.connection_restored), - ], - ), - ); - }, - ); - } else { - showToast( - context: context, - builder: (context, overlay) { - return SurfaceCard( - fillColor: theme.colorScheme.destructive, - child: Row( - children: [ - Icon( - SpotubeIcons.noWifi, - color: theme.colorScheme.destructiveForeground, - ), - const SizedBox(width: 10), - Text(context.l10n.you_are_offline), - ], - ), - ); - }, - ); - } - }), - connectRoutes.connectClientStream.listen((clientOrigin) { - if (!context.mounted) return; - showToast( - context: context, - builder: (context, overlay) { - return SurfaceCard( - fillColor: Colors.yellow[600], - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - SpotubeIcons.error, - color: Colors.black, - ), - const SizedBox(width: 10), - Text( - context.l10n.connect_client_alert(clientOrigin), - style: const TextStyle(color: Colors.black), - ), - ], - ), - ); - }, - ); - }) - ]; - - return () { - for (final subscription in subscriptions) { - subscription.cancel(); - } - }; - }, []); - - useEffect(() { - downloader.onFileExists = (track) async { - if (!context.mounted) return false; - - if (!showingDialogCompleter.value.isCompleted) { - await showingDialogCompleter.value.future; - } - - final replaceAll = ref.read(replaceDownloadedFileState); - - if (replaceAll != null) return replaceAll; - - showingDialogCompleter.value = Completer(); - - if (context.mounted) { - final result = await showDialog( - context: context, - builder: (context) => ReplaceDownloadedDialog( - track: track, - ), - ) ?? - false; - - showingDialogCompleter.value.complete(); - return result; - } - - // it'll never reach here as root_app is always mounted - return false; - }; - return null; - }, [downloader]); - - // checks for latest version of the application - - useEndlessPlayback(ref); - final backgroundColor = Theme.of(context).colorScheme.background; final brightness = Theme.of(context).brightness; + ref.listen(glanceProvider, (_, __) {}); + useGlobalSubscriptions(ref); + useDownloaderDialogs(ref); + useEndlessPlayback(ref); + useEffect(() { SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( diff --git a/lib/provider/audio_player/audio_player.dart b/lib/provider/audio_player/audio_player.dart index 170cbb12..aa93bd4f 100644 --- a/lib/provider/audio_player/audio_player.dart +++ b/lib/provider/audio_player/audio_player.dart @@ -45,7 +45,7 @@ class AudioPlayerNotifier extends Notifier { var playlist = await database.select(database.playlistTable).getSingleOrNull(); - var medias = await database.select(database.playlistMediaTable).get(); + final medias = await database.select(database.playlistMediaTable).get(); if (playlist == null) { await database.into(database.playlistTable).insert( diff --git a/lib/services/connectivity_adapter.dart b/lib/services/connectivity_adapter.dart index 86765671..478890df 100644 --- a/lib/services/connectivity_adapter.dart +++ b/lib/services/connectivity_adapter.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:io'; +import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:dio/dio.dart'; import 'package:flutter/widgets.dart'; import 'package:spotube/services/logger/logger.dart'; @@ -34,6 +35,10 @@ class ConnectionCheckerService with WidgetsBindingObserver { AppLogger.reportError(e, stack); } }); + + Connectivity().onConnectivityChanged.listen((event) async { + await isConnected; + }); } @override @@ -77,8 +82,9 @@ class ConnectionCheckerService with WidgetsBindingObserver { } return interfaces.any( - (interface) => - vpnNames.any((name) => interface.name.toLowerCase().contains(name)), + (interface) => vpnNames.any( + (name) => interface.name.toLowerCase().contains(name), + ), ); } @@ -109,10 +115,10 @@ class ConnectionCheckerService with WidgetsBindingObserver { Future get isConnected async { final connected = await _isConnected(); - isConnectedSync = connected; if (connected != isConnectedSync /*previous value*/) { _connectionStreamController.add(connected); } + isConnectedSync = connected; return connected; } diff --git a/lib/services/sourced_track/sources/youtube.dart b/lib/services/sourced_track/sources/youtube.dart index 0b5ee71b..1bafb705 100644 --- a/lib/services/sourced_track/sources/youtube.dart +++ b/lib/services/sourced_track/sources/youtube.dart @@ -82,14 +82,11 @@ class YoutubeSourcedTrack extends SourcedTrack { ); } final item = await youtubeClient.videos.get(cachedSource.sourceId); - final manifest = await youtubeClient.videos.streamsClient - .getManifest( - cachedSource.sourceId, - ) - .timeout( - const Duration(seconds: 5), - onTimeout: () => throw ClientException("Timeout"), - ); + final manifest = await youtubeClient.videos.streamsClient.getManifest( + cachedSource.sourceId, + requireWatchPage: false, + ytClients: [YoutubeApiClient.tv], + ); return YoutubeSourcedTrack( ref: ref, siblings: [], diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 608a854e..b92d7882 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import app_links import audio_service import audio_session import bonsoir_darwin +import connectivity_plus import desktop_webview_window import device_info_plus import file_selector_macos @@ -33,6 +34,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioServicePlugin.register(with: registry.registrar(forPlugin: "AudioServicePlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) SwiftBonsoirPlugin.register(with: registry.registrar(forPlugin: "SwiftBonsoirPlugin")) + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index bdf530f1..44da1f81 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -8,6 +8,9 @@ PODS: - bonsoir_darwin (0.0.1): - Flutter - FlutterMacOS + - connectivity_plus (0.0.1): + - Flutter + - FlutterMacOS - desktop_webview_window (0.0.1): - FlutterMacOS - device_info_plus (0.0.1): @@ -79,6 +82,7 @@ DEPENDENCIES: - audio_service (from `Flutter/ephemeral/.symlinks/plugins/audio_service/macos`) - audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`) - bonsoir_darwin (from `Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin`) + - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin`) - desktop_webview_window (from `Flutter/ephemeral/.symlinks/plugins/desktop_webview_window/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`) @@ -116,6 +120,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/audio_session/macos bonsoir_darwin: :path: Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin + connectivity_plus: + :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin desktop_webview_window: :path: Flutter/ephemeral/.symlinks/plugins/desktop_webview_window/macos device_info_plus: @@ -166,6 +172,7 @@ SPEC CHECKSUMS: audio_service: b88ff778e0e3915efd4cd1a5ad6f0beef0c950a9 audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72 bonsoir_darwin: e3b8526c42ca46a885142df84229131dfabea842 + connectivity_plus: 18382e7311ba19efcaee94442b23b32507b20695 desktop_webview_window: 89bb3d691f4c80314a10be312f4cd35db93a9d5a device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215 file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d diff --git a/pubspec.lock b/pubspec.lock index 2fa1d8ab..09bc1361 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -375,6 +375,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + connectivity_plus: + dependency: "direct main" + description: + name: connectivity_plus + sha256: "8a68739d3ee113e51ad35583fdf9ab82c55d09d693d3c39da1aebab87c938412" + url: "https://pub.dev" + source: hosted + version: "6.1.2" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" + url: "https://pub.dev" + source: hosted + version: "2.0.1" convert: dependency: transitive description: @@ -1542,6 +1558,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.6" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" node_preamble: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 3c20981b..b9e44021 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,6 +23,7 @@ dependencies: bonsoir: ^5.1.10 cached_network_image: ^3.3.1 collection: ^1.18.0 + connectivity_plus: ^6.1.2 desktop_webview_window: git: path: packages/desktop_webview_window diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 42fa2129..d1bee122 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("AppLinksPluginCApi")); BonsoirWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("BonsoirWindowsPluginCApi")); + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); DesktopWebviewWindowPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("DesktopWebviewWindowPlugin")); FileSelectorWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index cf14ec52..32c8a634 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -5,6 +5,7 @@ list(APPEND FLUTTER_PLUGIN_LIST app_links bonsoir_windows + connectivity_plus desktop_webview_window file_selector_windows flutter_inappwebview_windows From 2411f468777fa91aa5a868563cb75b6fe1cfd00f Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Tue, 21 Jan 2025 10:15:06 +0600 Subject: [PATCH 56/81] fix: youtube video unplayable issue and use more ytClients --- lib/services/connectivity_adapter.dart | 3 +- lib/services/logger/logger.dart | 34 +++++++++++++++++++ .../sourced_track/sources/youtube.dart | 24 +++++++++---- pubspec.lock | 2 +- pubspec.yaml | 1 + 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/lib/services/connectivity_adapter.dart b/lib/services/connectivity_adapter.dart index 478890df..f6b760c8 100644 --- a/lib/services/connectivity_adapter.dart +++ b/lib/services/connectivity_adapter.dart @@ -20,6 +20,7 @@ class ConnectionCheckerService with WidgetsBindingObserver { onConnectivityChanged.listen((connected) { try { if (!connected && timer == null) { + // check every 30 seconds if we are connected when we are not connected timer = Timer.periodic(const Duration(seconds: 30), (timer) async { if (WidgetsBinding.instance.lifecycleState == AppLifecycleState.paused) { @@ -111,7 +112,7 @@ class ConnectionCheckerService with WidgetsBindingObserver { await isVpnActive(); // when VPN is active that means we are connected } - bool isConnectedSync = false; + bool isConnectedSync = true; Future get isConnected async { final connected = await _isConnected(); diff --git a/lib/services/logger/logger.dart b/lib/services/logger/logger.dart index 1df7b5aa..46fc6de5 100644 --- a/lib/services/logger/logger.dart +++ b/lib/services/logger/logger.dart @@ -9,6 +9,20 @@ import 'package:logger/logger.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; import 'package:spotube/utils/platform.dart'; +import 'package:logging/logging.dart' as logging; + +final _loggingToLoggerLevel = { + logging.Level.ALL: Level.all, + logging.Level.FINEST: Level.trace, + logging.Level.FINER: Level.debug, + logging.Level.FINE: Level.info, + logging.Level.CONFIG: Level.info, + logging.Level.INFO: Level.info, + logging.Level.WARNING: Level.warning, + logging.Level.SEVERE: Level.error, + logging.Level.SHOUT: Level.fatal, + logging.Level.OFF: Level.off, +}; class AppLogger { static late final Logger log; @@ -20,6 +34,24 @@ class AppLogger { ); } + static void _initInternalPackageLoggers() { + if (!kDebugMode) return; + logging.hierarchicalLoggingEnabled = true; + logging.Logger('YoutubeExplode.StreamsClient') + ..level = logging.Level.ALL + ..onRecord.listen( + (record) { + log.log( + _loggingToLoggerLevel[record.level] ?? Level.info, + record.message, + error: record.error, + stackTrace: record.stackTrace, + time: record.time, + ); + }, + ); + } + static R? runZoned(R Function() body) { return runZonedGuarded( () { @@ -46,6 +78,8 @@ class AppLogger { ); } + _initInternalPackageLoggers(); + getLogsPath().then((value) => logFile = value); return body(); diff --git a/lib/services/sourced_track/sources/youtube.dart b/lib/services/sourced_track/sources/youtube.dart index 1bafb705..fa13a25d 100644 --- a/lib/services/sourced_track/sources/youtube.dart +++ b/lib/services/sourced_track/sources/youtube.dart @@ -85,7 +85,13 @@ class YoutubeSourcedTrack extends SourcedTrack { final manifest = await youtubeClient.videos.streamsClient.getManifest( cachedSource.sourceId, requireWatchPage: false, - ytClients: [YoutubeApiClient.tv], + ytClients: [ + YoutubeApiClient.mediaConnect, + YoutubeApiClient.ios, + YoutubeApiClient.android, + YoutubeApiClient.mweb, + YoutubeApiClient.tv, + ], ); return YoutubeSourcedTrack( ref: ref, @@ -138,11 +144,17 @@ class YoutubeSourcedTrack extends SourcedTrack { ) async { SourceMap? sourceMap; if (index == 0) { - final manifest = - await youtubeClient.videos.streamsClient.getManifest(item.id).timeout( - const Duration(seconds: 5), - onTimeout: () => throw ClientException("Timeout"), - ); + final manifest = await youtubeClient.videos.streamsClient.getManifest( + item.id, + requireWatchPage: false, + ytClients: [ + YoutubeApiClient.mediaConnect, + YoutubeApiClient.ios, + YoutubeApiClient.android, + YoutubeApiClient.mweb, + YoutubeApiClient.tv, + ], + ); sourceMap = toSourceMap(manifest); } diff --git a/pubspec.lock b/pubspec.lock index 09bc1361..1a35f9c9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1423,7 +1423,7 @@ packages: source: hosted version: "2.5.0" logging: - dependency: transitive + dependency: "direct main" description: name: logging sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 diff --git a/pubspec.yaml b/pubspec.yaml index b9e44021..ed0d7ce5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -86,6 +86,7 @@ dependencies: json_annotation: ^4.8.1 local_notifier: ^0.1.6 logger: ^2.0.2 + logging: ^1.3.0 lrc: ^1.0.2 media_kit: ^1.1.10+1 media_kit_libs_audio: ^1.0.4 From 6e357230ac87c621c7823168b3db09ba171a5350 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 23 Jan 2025 20:34:04 +0600 Subject: [PATCH 57/81] refactor: use expanded sidebar tiles for library --- .vscode/launch.json | 11 ++ lib/collections/intents.dart | 31 +++++- lib/collections/routes.dart | 105 ++++++++++++------ lib/collections/side_bar_tiles.dart | 40 +++++-- lib/collections/spotube_icons.dart | 2 + .../presentation_state.dart | 2 +- .../sort_tracks_dropdown.dart | 2 +- lib/main.dart | 24 +++- lib/modules/connect/connect_device.dart | 12 ++ lib/modules/root/sidebar.dart | 99 +++++++++++++---- .../getting_started/getting_started.dart | 55 ++++----- lib/pages/library/library.dart | 92 +++++++-------- lib/pages/library/local_folder.dart | 3 +- .../library/user_albums.dart | 5 +- .../library/user_artists.dart | 5 +- .../library/user_downloads.dart | 5 +- .../library/user_local_tracks.dart | 5 +- .../library/user_playlists.dart | 5 +- lib/pages/lyrics/lyrics.dart | 86 ++++++-------- lib/utils/service_utils.dart | 2 +- macos/Podfile.lock | 52 ++++----- 21 files changed, 403 insertions(+), 240 deletions(-) rename lib/{modules => pages}/library/user_albums.dart (97%) rename lib/{modules => pages}/library/user_artists.dart (98%) rename lib/{modules => pages}/library/user_downloads.dart (92%) rename lib/{modules => pages}/library/user_local_tracks.dart (96%) rename lib/{modules => pages}/library/user_playlists.dart (97%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 7a1e8b9b..deabf1d3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -30,6 +30,17 @@ "request": "launch", "program": "lib/main.dart", "flutterMode": "release" + }, + { + "name": "spotube (mobile) (release)", + "type": "dart", + "request": "launch", + "program": "lib/main.dart", + "flutterMode": "release", + "args": [ + "--flavor", + "dev" + ] } ], "compounds": [] diff --git a/lib/collections/intents.dart b/lib/collections/intents.dart index 4f446831..1ec62812 100644 --- a/lib/collections/intents.dart +++ b/lib/collections/intents.dart @@ -7,7 +7,11 @@ import 'package:go_router/go_router.dart'; import 'package:spotube/collections/routes.dart'; import 'package:spotube/modules/player/player_controls.dart'; import 'package:spotube/pages/home/home.dart'; -import 'package:spotube/pages/library/library.dart'; +import 'package:spotube/pages/library/user_albums.dart'; +import 'package:spotube/pages/library/user_artists.dart'; +import 'package:spotube/pages/library/user_downloads.dart'; +import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_playlists.dart'; import 'package:spotube/pages/lyrics/lyrics.dart'; import 'package:spotube/pages/search/search.dart'; import 'package:spotube/provider/audio_player/querying_track_info.dart'; @@ -52,8 +56,13 @@ class NavigationAction extends Action { enum HomeTabs { browse, search, - library, + lyrics, + userPlaylists, + userArtists, + userAlbums, + userLocalLibrary, + userDownloads, } class HomeTabIntent extends Intent { @@ -73,12 +82,24 @@ class HomeTabAction extends Action { case HomeTabs.search: router.goNamed(SearchPage.name); break; - case HomeTabs.library: - router.goNamed(LibraryPage.name); - break; case HomeTabs.lyrics: router.goNamed(LyricsPage.name); break; + case HomeTabs.userPlaylists: + router.goNamed(UserPlaylistsPage.name); + break; + case HomeTabs.userArtists: + router.goNamed(UserArtistsPage.name); + break; + case HomeTabs.userAlbums: + router.goNamed(UserAlbumsPage.name); + break; + case HomeTabs.userLocalLibrary: + router.goNamed(UserLocalLibraryPage.name); + break; + case HomeTabs.userDownloads: + router.goNamed(UserDownloadsPage.name); + break; } return null; } diff --git a/lib/collections/routes.dart b/lib/collections/routes.dart index a0380e29..25cf995c 100644 --- a/lib/collections/routes.dart +++ b/lib/collections/routes.dart @@ -16,6 +16,11 @@ import 'package:spotube/pages/lastfm_login/lastfm_login.dart'; import 'package:spotube/pages/library/local_folder.dart'; import 'package:spotube/pages/library/playlist_generate/playlist_generate.dart'; import 'package:spotube/pages/library/playlist_generate/playlist_generate_result.dart'; +import 'package:spotube/pages/library/user_albums.dart'; +import 'package:spotube/pages/library/user_artists.dart'; +import 'package:spotube/pages/library/user_downloads.dart'; +import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_playlists.dart'; import 'package:spotube/pages/lyrics/mini_lyrics.dart'; import 'package:spotube/pages/playlist/liked_playlist.dart'; import 'package:spotube/pages/playlist/playlist.dart'; @@ -99,45 +104,73 @@ final routerProvider = Provider((ref) { pageBuilder: (context, state) => const SpotubePage(child: SearchPage()), ), + ShellRoute( + pageBuilder: (context, state, child) => + SpotubePage(child: LibraryPage(child: child)), + routes: [ + GoRoute( + path: "/library/playlists", + name: UserPlaylistsPage.name, + pageBuilder: (context, state) => + const SpotubePage(child: UserPlaylistsPage()), + ), + GoRoute( + path: "/library/artists", + name: UserArtistsPage.name, + pageBuilder: (context, state) => + const SpotubePage(child: UserArtistsPage()), + ), + GoRoute( + path: "/library/album", + name: UserAlbumsPage.name, + pageBuilder: (context, state) => + const SpotubePage(child: UserAlbumsPage()), + ), + GoRoute( + path: "/library/local", + name: UserLocalLibraryPage.name, + pageBuilder: (context, state) => + const SpotubePage(child: UserLocalLibraryPage()), + ), + GoRoute( + path: "/library/downloads", + name: UserDownloadsPage.name, + pageBuilder: (context, state) => + const SpotubePage(child: UserDownloadsPage()), + ), + ], + ), GoRoute( - path: "/library", - name: LibraryPage.name, - pageBuilder: (context, state) => - const SpotubePage(child: LibraryPage()), - routes: [ - GoRoute( - path: "generate", - name: PlaylistGeneratorPage.name, - pageBuilder: (context, state) => - const SpotubePage(child: PlaylistGeneratorPage()), - routes: [ - GoRoute( - path: "result", - name: PlaylistGenerateResultPage.name, - pageBuilder: (context, state) => SpotubePage( - child: PlaylistGenerateResultPage( - state: state.extra as GeneratePlaylistProviderInput, - ), - ), - ) - ], + path: "/library/generate", + name: PlaylistGeneratorPage.name, + pageBuilder: (context, state) => + const SpotubePage(child: PlaylistGeneratorPage()), + routes: [ + GoRoute( + path: "result", + name: PlaylistGenerateResultPage.name, + pageBuilder: (context, state) => SpotubePage( + child: PlaylistGenerateResultPage( + state: state.extra as GeneratePlaylistProviderInput, + ), ), - GoRoute( - path: "local", - name: LocalLibraryPage.name, - pageBuilder: (context, state) { - assert(state.extra is String); - return SpotubePage( - child: LocalLibraryPage( - state.extra as String, - isDownloads: - state.uri.queryParameters["downloads"] != null, - isCache: state.uri.queryParameters["cache"] != null, - ), - ); - }, + ) + ], + ), + GoRoute( + path: "/library/local", + name: LocalLibraryPage.name, + pageBuilder: (context, state) { + assert(state.extra is String); + return SpotubePage( + child: LocalLibraryPage( + state.extra as String, + isDownloads: state.uri.queryParameters["downloads"] != null, + isCache: state.uri.queryParameters["cache"] != null, ), - ]), + ); + }, + ), GoRoute( path: "/lyrics", name: LyricsPage.name, diff --git a/lib/collections/side_bar_tiles.dart b/lib/collections/side_bar_tiles.dart index 4f23c049..26396e39 100644 --- a/lib/collections/side_bar_tiles.dart +++ b/lib/collections/side_bar_tiles.dart @@ -2,7 +2,10 @@ import 'package:flutter/material.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:spotube/pages/home/home.dart'; -import 'package:spotube/pages/library/library.dart'; +import 'package:spotube/pages/library/user_albums.dart'; +import 'package:spotube/pages/library/user_artists.dart'; +import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_playlists.dart'; import 'package:spotube/pages/lyrics/lyrics.dart'; import 'package:spotube/pages/search/search.dart'; import 'package:spotube/pages/stats/stats.dart'; @@ -34,12 +37,6 @@ List getSidebarTileList(AppLocalizations l10n) => [ icon: SpotubeIcons.search, title: l10n.search, ), - SideBarTiles( - id: "library", - name: LibraryPage.name, - icon: SpotubeIcons.library, - title: l10n.library, - ), SideBarTiles( id: "lyrics", name: LyricsPage.name, @@ -54,6 +51,33 @@ List getSidebarTileList(AppLocalizations l10n) => [ ), ]; +List getSidebarLibraryTileList(AppLocalizations l10n) => [ + SideBarTiles( + id: "playlists", + title: l10n.playlists, + name: UserPlaylistsPage.name, + icon: SpotubeIcons.playlist, + ), + SideBarTiles( + id: "artists", + title: l10n.artists, + name: UserArtistsPage.name, + icon: SpotubeIcons.artist, + ), + SideBarTiles( + id: "albums", + title: l10n.albums, + name: UserAlbumsPage.name, + icon: SpotubeIcons.album, + ), + SideBarTiles( + id: "local_library", + title: l10n.local_library, + name: UserLocalLibraryPage.name, + icon: SpotubeIcons.device, + ), + ]; + List getNavbarTileList(AppLocalizations l10n) => [ SideBarTiles( id: "browse", @@ -69,7 +93,7 @@ List getNavbarTileList(AppLocalizations l10n) => [ ), SideBarTiles( id: "library", - name: LibraryPage.name, + name: UserPlaylistsPage.name, icon: SpotubeIcons.library, title: l10n.library, ), diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index 9239875e..56192d18 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -37,6 +37,7 @@ abstract class SpotubeIcons { static const share = FeatherIcons.share2; static const playlistAdd = Icons.playlist_add_rounded; static const playlistRemove = Icons.playlist_remove_rounded; + static const playlist = Icons.playlist_play_rounded; static const trash = FeatherIcons.trash2; static const clock = FeatherIcons.clock; static const lyrics = Icons.lyrics_rounded; @@ -132,4 +133,5 @@ abstract class SpotubeIcons { static const radioUnchecked = Icons.radio_button_off_rounded; static const grid = FeatherIcons.grid; static const list = FeatherIcons.list; + static const device = FeatherIcons.smartphone; } diff --git a/lib/components/track_presentation/presentation_state.dart b/lib/components/track_presentation/presentation_state.dart index 11ca9809..91adbfcd 100644 --- a/lib/components/track_presentation/presentation_state.dart +++ b/lib/components/track_presentation/presentation_state.dart @@ -2,7 +2,7 @@ import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/modules/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/utils/service_utils.dart'; diff --git a/lib/components/track_presentation/sort_tracks_dropdown.dart b/lib/components/track_presentation/sort_tracks_dropdown.dart index 543bacb3..ecab615f 100644 --- a/lib/components/track_presentation/sort_tracks_dropdown.dart +++ b/lib/components/track_presentation/sort_tracks_dropdown.dart @@ -1,6 +1,6 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/modules/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks.dart'; import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; import 'package:spotube/extensions/context.dart'; diff --git a/lib/main.dart b/lib/main.dart index af7da1b7..bbf161c5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -264,12 +264,32 @@ class Spotube extends HookConsumerWidget { LogicalKeyboardKey.digit3, LogicalKeyboardKey.control, LogicalKeyboardKey.shift, - ): HomeTabIntent(ref, tab: HomeTabs.library), + ): HomeTabIntent(ref, tab: HomeTabs.lyrics), LogicalKeySet( LogicalKeyboardKey.digit4, LogicalKeyboardKey.control, LogicalKeyboardKey.shift, - ): HomeTabIntent(ref, tab: HomeTabs.lyrics), + ): HomeTabIntent(ref, tab: HomeTabs.userPlaylists), + LogicalKeySet( + LogicalKeyboardKey.digit5, + LogicalKeyboardKey.control, + LogicalKeyboardKey.shift, + ): HomeTabIntent(ref, tab: HomeTabs.userArtists), + LogicalKeySet( + LogicalKeyboardKey.digit6, + LogicalKeyboardKey.control, + LogicalKeyboardKey.shift, + ): HomeTabIntent(ref, tab: HomeTabs.userAlbums), + LogicalKeySet( + LogicalKeyboardKey.digit7, + LogicalKeyboardKey.control, + LogicalKeyboardKey.shift, + ): HomeTabIntent(ref, tab: HomeTabs.userLocalLibrary), + LogicalKeySet( + LogicalKeyboardKey.digit8, + LogicalKeyboardKey.control, + LogicalKeyboardKey.shift, + ): HomeTabIntent(ref, tab: HomeTabs.userDownloads), LogicalKeySet( LogicalKeyboardKey.keyW, LogicalKeyboardKey.control, diff --git a/lib/modules/connect/connect_device.dart b/lib/modules/connect/connect_device.dart index be9826a3..a285284c 100644 --- a/lib/modules/connect/connect_device.dart +++ b/lib/modules/connect/connect_device.dart @@ -1,6 +1,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/connect/connect.dart'; import 'package:spotube/provider/connect/clients.dart'; @@ -19,6 +20,17 @@ class ConnectDeviceButton extends HookConsumerWidget { connectClients.asData?.value.services.isNotEmpty == true; if (_sidebar) { + final mediaQuery = MediaQuery.sizeOf(context); + + if (mediaQuery.mdAndDown) { + return IconButton.ghost( + icon: const Icon(SpotubeIcons.speaker), + onPressed: () { + ServiceUtils.pushNamed(context, ConnectPage.name); + }, + ); + } + return SizedBox( width: double.infinity, child: Button.primary( diff --git a/lib/modules/root/sidebar.dart b/lib/modules/root/sidebar.dart index 9a92a1cb..1d5d9da0 100644 --- a/lib/modules/root/sidebar.dart +++ b/lib/modules/root/sidebar.dart @@ -3,7 +3,6 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; @@ -14,6 +13,7 @@ import 'package:spotube/models/database/database.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/modules/connect/connect_device.dart'; +import 'package:spotube/pages/library/user_downloads.dart'; import 'package:spotube/pages/profile/profile.dart'; import 'package:spotube/pages/settings/settings.dart'; import 'package:spotube/provider/authentication/authentication.dart'; @@ -47,8 +47,6 @@ class Sidebar extends HookConsumerWidget { final routerState = GoRouterState.of(context); final mediaQuery = MediaQuery.of(context); - final downloadCount = ref.watch(downloadManagerProvider).$downloadCount; - final layoutMode = ref.watch(userPreferencesProvider.select((s) => s.layoutMode)); @@ -57,7 +55,14 @@ class Sidebar extends HookConsumerWidget { [context.l10n], ); - final selectedIndex = sidebarTileList.indexWhere( + final sidebarLibraryTileList = useMemoized( + () => getSidebarLibraryTileList(context.l10n), + [context.l10n], + ); + + final tileList = [...sidebarTileList, ...sidebarLibraryTileList]; + + final selectedIndex = tileList.indexWhere( (e) => routerState.namedLocation(e.name) == routerState.matchedLocation, ); @@ -73,16 +78,8 @@ class Sidebar extends HookConsumerWidget { for (final tile in sidebarTileList) NavigationButton( label: mediaQuery.lgAndUp ? Text(tile.title) : null, - child: Badge( - backgroundColor: context.theme.colorScheme.primary, - isLabelVisible: tile.title == "Library" && downloadCount > 0, - label: Text( - downloadCount.toString(), - style: TextStyle( - color: context.theme.colorScheme.primaryForeground, - fontSize: 10, - ), - ), + child: Tooltip( + tooltip: TooltipContainer(child: Text(tile.title)), child: Icon(tile.icon), ), onChanged: (value) { @@ -91,6 +88,22 @@ class Sidebar extends HookConsumerWidget { } }, ), + const NavigationDivider(), + if (mediaQuery.lgAndUp) + NavigationLabel(child: Text(context.l10n.library)), + for (final tile in sidebarLibraryTileList) + NavigationButton( + label: mediaQuery.lgAndUp ? Text(tile.title) : null, + onChanged: (value) { + if (value) { + context.goNamed(tile.name); + } + }, + child: Tooltip( + tooltip: TooltipContainer(child: Text(tile.title)), + child: Icon(tile.icon), + ), + ), ]; return Row( @@ -103,7 +116,7 @@ class Sidebar extends HookConsumerWidget { ? NavigationSidebar( index: selectedIndex, onSelected: (index) { - final tile = sidebarTileList[index]; + final tile = tileList[index]; context.goNamed(tile.name); }, children: navigationButtons, @@ -112,7 +125,7 @@ class Sidebar extends HookConsumerWidget { alignment: NavigationRailAlignment.start, index: selectedIndex, onSelected: (index) { - final tile = sidebarTileList[index]; + final tile = tileList[index]; context.goNamed(tile.name); }, children: navigationButtons, @@ -138,8 +151,10 @@ class SidebarFooter extends HookConsumerWidget implements NavigationBarItem { Widget build(BuildContext context, ref) { final theme = Theme.of(context); final mediaQuery = MediaQuery.of(context); - final me = ref.watch(meProvider); - final data = me.asData?.value; + final routerState = GoRouterState.of(context); + final downloadCount = ref.watch(downloadManagerProvider).$downloadCount; + final userSnapshot = ref.watch(meProvider); + final data = userSnapshot.asData?.value; final avatarImg = (data?.images).asUrlString( index: (data?.images?.length ?? 1) - 1, @@ -149,10 +164,30 @@ class SidebarFooter extends HookConsumerWidget implements NavigationBarItem { final auth = ref.watch(authenticationProvider); if (mediaQuery.mdAndDown) { - return IconButton( - variance: ButtonVariance.ghost, - icon: const Icon(SpotubeIcons.settings), - onPressed: () => ServiceUtils.navigateNamed(context, SettingsPage.name), + return Column( + mainAxisSize: MainAxisSize.min, + spacing: 10, + children: [ + Badge( + isLabelVisible: downloadCount > 0, + label: Text(downloadCount.toString()), + child: IconButton( + variance: routerState.topRoute?.name == UserDownloadsPage.name + ? ButtonVariance.secondary + : ButtonVariance.ghost, + icon: const Icon(SpotubeIcons.download), + onPressed: () => + ServiceUtils.navigateNamed(context, UserDownloadsPage.name), + ), + ), + const ConnectDeviceButton.sidebar(), + IconButton( + variance: ButtonVariance.ghost, + icon: const Icon(SpotubeIcons.settings), + onPressed: () => + ServiceUtils.navigateNamed(context, SettingsPage.name), + ), + ], ); } @@ -161,9 +196,27 @@ class SidebarFooter extends HookConsumerWidget implements NavigationBarItem { width: 180, child: Column( mainAxisSize: MainAxisSize.min, + spacing: 10, children: [ + SizedBox( + width: double.infinity, + child: Button( + style: routerState.topRoute?.name == UserDownloadsPage.name + ? ButtonVariance.secondary + : ButtonVariance.outline, + onPressed: () { + ServiceUtils.navigateNamed(context, UserDownloadsPage.name); + }, + leading: const Icon(SpotubeIcons.download), + trailing: downloadCount > 0 + ? PrimaryBadge( + child: Text(downloadCount.toString()), + ) + : null, + child: Text(context.l10n.downloads), + ), + ), const ConnectDeviceButton.sidebar(), - const Gap(10), Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/pages/getting_started/getting_started.dart b/lib/pages/getting_started/getting_started.dart index 2931a782..f710bd8f 100644 --- a/lib/pages/getting_started/getting_started.dart +++ b/lib/pages/getting_started/getting_started.dart @@ -34,32 +34,35 @@ class GettingStarting extends HookConsumerWidget { return Scaffold( headers: [ - TitleBar( - backgroundColor: Colors.transparent, - surfaceBlur: 0, - trailing: [ - ListenableBuilder( - listenable: pageController, - builder: (context, _) { - return AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: pageController.hasClients && - (pageController.page == 0 || pageController.page == 3) - ? const SizedBox() - : Button.secondary( - onPressed: () { - pageController.animateToPage( - 3, - duration: const Duration(milliseconds: 300), - curve: Curves.easeInOut, - ); - }, - child: Text(context.l10n.skip_this_nonsense), - ), - ); - }, - ), - ], + SafeArea( + child: TitleBar( + backgroundColor: Colors.transparent, + surfaceBlur: 0, + trailing: [ + ListenableBuilder( + listenable: pageController, + builder: (context, _) { + return AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + child: pageController.hasClients && + (pageController.page == 0 || + pageController.page == 3) + ? const SizedBox() + : Button.secondary( + onPressed: () { + pageController.animateToPage( + 3, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + }, + child: Text(context.l10n.skip_this_nonsense), + ), + ); + }, + ), + ], + ), ), ], floatingHeader: true, diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index ec896228..7ae5a0e4 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -1,71 +1,63 @@ import 'package:flutter/material.dart' show Badge; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:spotube/modules/library/user_local_tracks.dart'; +import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; -import 'package:spotube/modules/library/user_albums.dart'; -import 'package:spotube/modules/library/user_artists.dart'; -import 'package:spotube/modules/library/user_downloads.dart'; -import 'package:spotube/modules/library/user_playlists.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/download_manager_provider.dart'; class LibraryPage extends HookConsumerWidget { - static const name = "library"; + final Widget child; + const LibraryPage({super.key, required this.child}); - const LibraryPage({super.key}); @override Widget build(BuildContext context, ref) { final downloadingCount = ref.watch(downloadManagerProvider).$downloadCount; - final index = useState(0); - - final children = [ - Text(context.l10n.playlists), - Text(context.l10n.local_tab), - Badge( - isLabelVisible: downloadingCount > 0, - label: Text(downloadingCount.toString()), - child: Text(context.l10n.downloads), - ), - Text(context.l10n.artists), - Text(context.l10n.albums), - ]; + final routerState = GoRouterState.of(context); + final sidebarLibraryTileList = useMemoized( + () => getSidebarLibraryTileList(context.l10n), + [context.l10n], + ); + final index = sidebarLibraryTileList.indexWhere( + (e) => routerState.namedLocation(e.name) == routerState.matchedLocation, + ); return SafeArea( bottom: false, - child: Scaffold( - headers: [ - TitleBar( - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: TabList( - index: index.value, - children: [ - for (final child in children) - TabButton( - child: child, - onPressed: () { - index.value = children.indexOf(child); - }, - ), - ], + child: LayoutBuilder(builder: (context, constraints) { + return Scaffold( + headers: [ + if (constraints.smAndDown) + TitleBar( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: TabList( + index: index, + children: [ + for (final tile in sidebarLibraryTileList) + TabButton( + child: Badge( + isLabelVisible: + tile.id == 'downloads' && downloadingCount > 0, + label: Text(downloadingCount.toString()), + child: Text(tile.title), + ), + onPressed: () { + context.goNamed(tile.name); + }, + ), + ], + ), + ), ), - ), - ), - const Gap(10), - ], - child: IndexedStack( - index: index.value, - children: const [ - UserPlaylists(), - UserLocalTracks(), - UserDownloads(), - UserArtists(), - UserAlbums(), + const Gap(10), ], - ), - ), + child: child, + ); + }), ); } } diff --git a/lib/pages/library/local_folder.dart b/lib/pages/library/local_folder.dart index 84873b84..b8cdd096 100644 --- a/lib/pages/library/local_folder.dart +++ b/lib/pages/library/local_folder.dart @@ -16,9 +16,8 @@ import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/string.dart'; import 'package:spotube/modules/library/local_folder/cache_export_dialog.dart'; -import 'package:spotube/modules/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks.dart'; import 'package:spotube/components/expandable_search/expandable_search.dart'; -import 'package:spotube/components/fallbacks/not_found.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/components/track_presentation/sort_tracks_dropdown.dart'; diff --git a/lib/modules/library/user_albums.dart b/lib/pages/library/user_albums.dart similarity index 97% rename from lib/modules/library/user_albums.dart rename to lib/pages/library/user_albums.dart index 8d55cf80..861d1705 100644 --- a/lib/modules/library/user_albums.dart +++ b/lib/pages/library/user_albums.dart @@ -16,8 +16,9 @@ import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/spotify/spotify.dart'; -class UserAlbums extends HookConsumerWidget { - const UserAlbums({super.key}); +class UserAlbumsPage extends HookConsumerWidget { + static const name = 'user_albums'; + const UserAlbumsPage({super.key}); @override Widget build(BuildContext context, ref) { diff --git a/lib/modules/library/user_artists.dart b/lib/pages/library/user_artists.dart similarity index 98% rename from lib/modules/library/user_artists.dart rename to lib/pages/library/user_artists.dart index fd23f426..aacf4102 100644 --- a/lib/modules/library/user_artists.dart +++ b/lib/pages/library/user_artists.dart @@ -19,8 +19,9 @@ import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/authentication/authentication.dart'; import 'package:spotube/provider/spotify/spotify.dart'; -class UserArtists extends HookConsumerWidget { - const UserArtists({super.key}); +class UserArtistsPage extends HookConsumerWidget { + static const name = 'user_artists'; + const UserArtistsPage({super.key}); @override Widget build(BuildContext context, ref) { diff --git a/lib/modules/library/user_downloads.dart b/lib/pages/library/user_downloads.dart similarity index 92% rename from lib/modules/library/user_downloads.dart rename to lib/pages/library/user_downloads.dart index 5db30342..871e21ab 100644 --- a/lib/modules/library/user_downloads.dart +++ b/lib/pages/library/user_downloads.dart @@ -6,8 +6,9 @@ import 'package:spotube/modules/library/user_downloads/download_item.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/download_manager_provider.dart'; -class UserDownloads extends HookConsumerWidget { - const UserDownloads({super.key}); +class UserDownloadsPage extends HookConsumerWidget { + static const name = 'user_downloads'; + const UserDownloadsPage({super.key}); @override Widget build(BuildContext context, ref) { diff --git a/lib/modules/library/user_local_tracks.dart b/lib/pages/library/user_local_tracks.dart similarity index 96% rename from lib/modules/library/user_local_tracks.dart rename to lib/pages/library/user_local_tracks.dart index 86b36dfb..66c011e5 100644 --- a/lib/modules/library/user_local_tracks.dart +++ b/lib/pages/library/user_local_tracks.dart @@ -24,8 +24,9 @@ enum SortBy { album, } -class UserLocalTracks extends HookConsumerWidget { - const UserLocalTracks({super.key}); +class UserLocalLibraryPage extends HookConsumerWidget { + static const name = 'user_local_library'; + const UserLocalLibraryPage({super.key}); @override Widget build(BuildContext context, ref) { diff --git a/lib/modules/library/user_playlists.dart b/lib/pages/library/user_playlists.dart similarity index 97% rename from lib/modules/library/user_playlists.dart rename to lib/pages/library/user_playlists.dart index 06f08ab6..a4711e1b 100644 --- a/lib/modules/library/user_playlists.dart +++ b/lib/pages/library/user_playlists.dart @@ -20,8 +20,9 @@ import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/utils/platform.dart'; import 'package:spotube/utils/service_utils.dart'; -class UserPlaylists extends HookConsumerWidget { - const UserPlaylists({super.key}); +class UserPlaylistsPage extends HookConsumerWidget { + static const name = 'user_playlists'; + const UserPlaylistsPage({super.key}); @override Widget build(BuildContext context, ref) { diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index f61dbbe3..85798eda 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -8,7 +8,6 @@ import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; -import 'package:spotube/hooks/utils/use_custom_status_bar_color.dart'; import 'package:spotube/hooks/utils/use_palette_color.dart'; import 'package:spotube/pages/lyrics/plain_lyrics.dart'; import 'package:spotube/pages/lyrics/synced_lyrics.dart'; @@ -33,15 +32,8 @@ class LyricsPage extends HookConsumerWidget { [playlist.activeTrack?.album?.images], ); final palette = usePaletteColor(albumArt, ref); - final route = ModalRoute.of(context); final selectedIndex = useState(0); - final resetStatusBar = useCustomStatusBarColor( - palette.color, - route?.isCurrent ?? false, - noSetBGColor: true, - ); - Widget tabbar = Padding( padding: const EdgeInsets.all(10), child: isModal @@ -93,51 +85,47 @@ class LyricsPage extends HookConsumerWidget { ); if (isModal) { - return PopScope( - canPop: true, - onPopInvokedWithResult: (_, __) => resetStatusBar(), - child: SafeArea( - bottom: false, - child: SurfaceCard( - surfaceBlur: context.theme.surfaceBlur, - surfaceOpacity: context.theme.surfaceOpacity, - padding: EdgeInsets.zero, - borderRadius: BorderRadius.zero, - borderWidth: 0, - child: Column( - children: [ - const SizedBox(height: 5), - Container( - height: 7, - width: 150, - decoration: BoxDecoration( - color: palette.titleTextColor, - borderRadius: BorderRadius.circular(10), - ), + return SafeArea( + bottom: false, + child: SurfaceCard( + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: context.theme.surfaceOpacity, + padding: EdgeInsets.zero, + borderRadius: BorderRadius.zero, + borderWidth: 0, + child: Column( + children: [ + const SizedBox(height: 20), + Container( + height: 7, + width: 150, + decoration: BoxDecoration( + color: palette.titleTextColor, + borderRadius: BorderRadius.circular(10), ), - Row( + ), + Row( + children: [ + Expanded( + child: tabbar, + ), + IconButton.ghost( + icon: const Icon(SpotubeIcons.minimize), + onPressed: () => Navigator.of(context).pop(), + ), + const SizedBox(width: 5), + ], + ), + Expanded( + child: IndexedStack( + index: selectedIndex.value, children: [ - Expanded( - child: tabbar, - ), - IconButton.ghost( - icon: const Icon(SpotubeIcons.minimize), - onPressed: () => Navigator.of(context).pop(), - ), - const SizedBox(width: 5), + SyncedLyrics(palette: palette, isModal: isModal), + PlainLyrics(palette: palette, isModal: isModal), ], ), - Expanded( - child: IndexedStack( - index: selectedIndex.value, - children: [ - SyncedLyrics(palette: palette, isModal: isModal), - PlainLyrics(palette: palette, isModal: isModal), - ], - ), - ), - ], - ), + ), + ], ), ), ); diff --git a/lib/utils/service_utils.dart b/lib/utils/service_utils.dart index 2abb98ef..bc57dd4a 100644 --- a/lib/utils/service_utils.dart +++ b/lib/utils/service_utils.dart @@ -6,7 +6,7 @@ import 'package:go_router/go_router.dart'; import 'package:html/dom.dart' hide Text; import 'package:shadcn_flutter/shadcn_flutter.dart' hide Element; import 'package:spotify/spotify.dart'; -import 'package:spotube/modules/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks.dart'; import 'package:spotube/modules/root/update_dialog.dart'; import 'package:spotube/models/lyrics.dart'; diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 44da1f81..95feb26d 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -168,35 +168,35 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos SPEC CHECKSUMS: - app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a - audio_service: b88ff778e0e3915efd4cd1a5ad6f0beef0c950a9 - audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72 - bonsoir_darwin: e3b8526c42ca46a885142df84229131dfabea842 - connectivity_plus: 18382e7311ba19efcaee94442b23b32507b20695 - desktop_webview_window: 89bb3d691f4c80314a10be312f4cd35db93a9d5a - device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215 - file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d - flutter_discord_rpc: 67a7c10ea24d9d3bf35d01af643f48fbcfa7c24f - flutter_inappwebview_macos: bdf207b8f4ebd58e86ae06cd96b147de99a67c9b - flutter_secure_storage_macos: 59459653abe1adb92abbc8ea747d79f8d19866c9 + app_links: 9028728e32c83a0831d9db8cf91c526d16cc5468 + audio_service: 0d9e4e25347bb3efb768f3b9f005911a81e587a7 + audio_session: 48ab6500f7a5e7c64363e206565a5dfe5a0c1441 + bonsoir_darwin: 29c7ccf356646118844721f36e1de4b61f6cbd0e + connectivity_plus: 2256d3e20624a7749ed21653aafe291a46446fee + desktop_webview_window: 2f0cdefecc06e21208a51589bd3d1580a87a703c + device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 + file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31 + flutter_discord_rpc: 90614fcca26f3cebfd33263557ea7875936d184b + flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d + flutter_secure_storage_macos: b2d62a774c23b060f0b99d0173b0b36abb4a8632 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - local_notifier: e9506bc66fc70311e8bc7291fb70f743c081e4ff - media_kit_libs_macos_audio: 3871782a4f3f84c77f04d7666c87800a781c24da - media_kit_native_event_loop: 7321675377cb9ae8596a29bddf3a3d2b5e8792c5 - metadata_god: 829f61208b44ac1173e7cd32ab740d8776be5435 - open_file_mac: 0e554648e2a87ce59e9438e3e5ca3e552e90d89a + local_notifier: ebf072651e35ae5e47280ad52e2707375cb2ae4e + media_kit_libs_macos_audio: 06f3cf88d6d89c7c3c87eae57689d1c6adb335b2 + media_kit_native_event_loop: a5833d1e4d5bedb6f691e9909fa57f15f436f2c8 + metadata_god: 8029e6ff4b1400ae4f13c38d2c478e8633f0e58b + open_file_mac: 01874b6d6a2c1485ac9b126d7105b99102dea2cf OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 - package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161 - shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d + package_info_plus: a8a591e70e87ce97ce5d21b2594f69cea9e0312f + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f + shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 sqlite3: 7559e33dae4c78538df563795af3a86fc887ee71 - sqlite3_flutter_libs: 1b4e98da20ebd4e9b1240269b78cdcf492dbe9f3 - system_theme: c7b9f6659a5caa26c9bc2284da096781e9a6fcbc - tray_manager: 9064e219c56d75c476e46b9a21182087930baf90 - url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 - window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 + sqlite3_flutter_libs: f0b59f6bb2a18597d0796558725007e5a7428397 + system_theme: ed74293ad07d3a05e3e2d0059ff342360346f1a0 + tray_manager: a104b5c81b578d83f3c3d0f40a997c8b10810166 + url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673 + window_manager: 1d01fa7ac65a6e6f83b965471b1a7fdd3f06166c PODFILE CHECKSUM: 0d3963a09fc94f580682bd88480486da345dc3f0 From 082f7110187778b0f9920a885b2c847414b3068e Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 23 Jan 2025 20:39:04 +0600 Subject: [PATCH 58/81] chore: use angle --- lib/modules/home/sections/genres/genres.dart | 40 ++++++-------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/lib/modules/home/sections/genres/genres.dart b/lib/modules/home/sections/genres/genres.dart index 5e96f78f..881003aa 100644 --- a/lib/modules/home/sections/genres/genres.dart +++ b/lib/modules/home/sections/genres/genres.dart @@ -111,21 +111,13 @@ class HomeGenresSection extends HookConsumerWidget { left: 0, child: Container( height: 280 * theme.scaling, - width: (mediaQuery.mdAndUp ? 80 : 50) * theme.scaling, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [ - theme.colorScheme.background.withAlpha(255), - theme.colorScheme.background.withAlpha(0), - ], - ), - ), + width: (mediaQuery.mdAndUp ? 60 : 40) * theme.scaling, alignment: Alignment.center, - child: IconButton.ghost( - size: - mediaQuery.mdAndUp ? ButtonSize.normal : ButtonSize.small, + child: IconButton.secondary( + shape: ButtonShape.circle, + size: mediaQuery.mdAndUp + ? const ButtonSize(1.3) + : ButtonSize.normal, icon: const Icon(SpotubeIcons.angleLeft), onPressed: () { controller.animatePrevious( @@ -140,21 +132,13 @@ class HomeGenresSection extends HookConsumerWidget { right: 0, child: Container( height: 280 * theme.scaling, - width: (mediaQuery.mdAndUp ? 80 : 50) * theme.scaling, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [ - theme.colorScheme.background.withAlpha(0), - theme.colorScheme.background.withAlpha(255), - ], - ), - ), + width: (mediaQuery.mdAndUp ? 60 : 40) * theme.scaling, alignment: Alignment.center, - child: IconButton.ghost( - size: - mediaQuery.mdAndUp ? ButtonSize.normal : ButtonSize.small, + child: IconButton.secondary( + shape: ButtonShape.circle, + size: mediaQuery.mdAndUp + ? const ButtonSize(1.3) + : ButtonSize.normal, icon: const Icon(SpotubeIcons.angleRight), onPressed: () { controller.animateNext( From 768bab8bbbf2f7667a80c16cb69a44dbc7ceacd2 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 23 Jan 2025 21:11:59 +0600 Subject: [PATCH 59/81] chore: settings popup menu constraints --- lib/components/adaptive/adaptive_select_tile.dart | 7 +++++++ lib/pages/settings/sections/playback.dart | 2 ++ 2 files changed, 9 insertions(+) diff --git a/lib/components/adaptive/adaptive_select_tile.dart b/lib/components/adaptive/adaptive_select_tile.dart index 40308711..2e2e7041 100644 --- a/lib/components/adaptive/adaptive_select_tile.dart +++ b/lib/components/adaptive/adaptive_select_tile.dart @@ -23,6 +23,9 @@ class AdaptiveSelectTile extends HookWidget { final bool? breakLayout; + final BoxConstraints? popupConstraints; + final PopoverConstraint? popupWidthConstraint; + const AdaptiveSelectTile({ required this.title, required this.value, @@ -34,6 +37,8 @@ class AdaptiveSelectTile extends HookWidget { this.breakLayout, this.showValueWhenUnfolded = true, super.key, + this.popupConstraints, + this.popupWidthConstraint, }); @override @@ -47,6 +52,8 @@ class AdaptiveSelectTile extends HookWidget { }, value: value, onChanged: onChanged, + popupConstraints: popupConstraints ?? const BoxConstraints(maxWidth: 200), + popupWidthConstraint: popupWidthConstraint ?? PopoverConstraint.flexible, children: options, ); diff --git a/lib/pages/settings/sections/playback.dart b/lib/pages/settings/sections/playback.dart index 6888e3a9..be3fc15b 100644 --- a/lib/pages/settings/sections/playback.dart +++ b/lib/pages/settings/sections/playback.dart @@ -281,6 +281,7 @@ class SettingsPlaybackSection extends HookConsumerWidget { ), if (preferences.audioSource != AudioSource.jiosaavn) ...[ AdaptiveSelectTile( + popupConstraints: const BoxConstraints(maxWidth: 300), secondary: const Icon(SpotubeIcons.stream), title: Text(context.l10n.streaming_music_codec), value: preferences.streamMusicCodec, @@ -300,6 +301,7 @@ class SettingsPlaybackSection extends HookConsumerWidget { }, ), AdaptiveSelectTile( + popupConstraints: const BoxConstraints(maxWidth: 300), secondary: const Icon(SpotubeIcons.file), title: Text(context.l10n.download_music_codec), value: preferences.downloadMusicCodec, From 0aee8b339919979e5df6c23d5808ab048728c1f8 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 23 Jan 2025 21:16:40 +0600 Subject: [PATCH 60/81] cd: use upload-artifact v4 --- .github/workflows/spotube-release-binary.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index eb251d2a..fb64d55a 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -125,7 +125,7 @@ jobs: CHANNEL: ${{inputs.channel}} DOTENV: ${{secrets.DOTENV_RELEASE}} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: if-no-files-found: error name: Spotube-Release-Binaries @@ -143,7 +143,7 @@ jobs: - build_platform steps: - uses: actions/checkout@v4 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: Spotube-Release-Binaries path: ./Spotube-Release-Binaries @@ -162,7 +162,7 @@ jobs: run: | echo "PUBSPEC_VERSION=$(grep -oP 'version:\s*\K[^+]+(?=\+)' pubspec.yaml)" >> $GITHUB_ENV - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: if-no-files-found: error name: Spotube-Release-Binaries From 343198a7e8ff19f45b537e005a010f7d06bf6c46 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 09:55:09 +0600 Subject: [PATCH 61/81] cd: use individual artifacts --- .github/workflows/spotube-release-binary.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index fb64d55a..1e07d938 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -128,7 +128,6 @@ jobs: - uses: actions/upload-artifact@v4 with: if-no-files-found: error - name: Spotube-Release-Binaries path: ${{matrix.files}} - name: Debug With SSH When fails @@ -145,7 +144,6 @@ jobs: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: - name: Spotube-Release-Binaries path: ./Spotube-Release-Binaries - name: Install dependencies From becba8956f97b50d0b9d01bdb0863ef87af97c51 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 10:15:24 +0600 Subject: [PATCH 62/81] cd: artifact name need to be specified --- .github/workflows/spotube-release-binary.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 1e07d938..a4afcab3 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -107,7 +107,7 @@ jobs: echo '${{ secrets.KEYSTORE }}' | base64 --decode > android/app/upload-keystore.jks echo '${{ secrets.KEY_PROPERTIES }}' > android/key.properties - - name: Unessary hosted tools + - name: Uncessary hosted tools if: ${{matrix.platform == 'linux_arm'}} uses: jlumbroso/free-disk-space@main with: @@ -128,6 +128,7 @@ jobs: - uses: actions/upload-artifact@v4 with: if-no-files-found: error + name: ${{matrix.platform}} path: ${{matrix.files}} - name: Debug With SSH When fails @@ -163,7 +164,7 @@ jobs: - uses: actions/upload-artifact@v4 with: if-no-files-found: error - name: Spotube-Release-Binaries + name: sums path: | RELEASE.md5sum RELEASE.sha256sum @@ -196,3 +197,10 @@ jobs: Nightly release includes newest features but may contain bugs It is preferred to use the stable version unless you know what you're doing + + - name: Debug With SSH When fails + if: ${{ failure() && inputs.debug && inputs.channel == 'nightly' }} + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + From 85ebaf69de09e8c96629faeca799e4d331f5f260 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 11:15:48 +0600 Subject: [PATCH 63/81] cd: use new hosted github runners --- .github/workflows/spotube-release-binary.yml | 32 ++++-------- cli/commands/build.dart | 8 ++- cli/commands/build/common.dart | 2 + cli/commands/build/linux.dart | 55 ++++++++++++-------- cli/commands/build/linux_arm.dart | 37 ------------- cli/commands/install-dependencies.dart | 15 +++--- 6 files changed, 58 insertions(+), 91 deletions(-) delete mode 100644 cli/commands/build/linux_arm.dart diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index a4afcab3..410cb835 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -33,31 +33,37 @@ jobs: include: - os: ubuntu-latest platform: linux + arch: x86 files: | dist/Spotube-linux-x86_64.deb dist/Spotube-linux-x86_64.rpm dist/spotube-linux-*-x86_64.tar.xz - - os: ubuntu-latest - platform: linux_arm + - os: ubuntu-22.04-arm + platform: linux + arch: arm64 files: | dist/Spotube-linux-aarch64.deb dist/spotube-linux-*-aarch64.tar.xz - os: ubuntu-latest platform: android + arch: all files: | build/Spotube-android-all-arch.apk build/Spotube-playstore-all-arch.aab - os: windows-latest platform: windows + arch: x86 files: | dist/Spotube-windows-x86_64.nupkg dist/Spotube-windows-x86_64-setup.exe - os: macos-latest platform: ios + arch: all files: | Spotube-iOS.ipa - os: macos-14 platform: macos + arch: all files: | build/Spotube-macos-universal.dmg build/Spotube-macos-universal.pkg @@ -78,14 +84,8 @@ jobs: java-version: '17' cache: 'gradle' check-latest: true - - name: Set up QEMU - if: ${{matrix.platform == 'linux_arm'}} - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - if: ${{matrix.platform == 'linux_arm'}} - uses: docker/setup-buildx-action@v3 + - name: Setup Rust toolchain - if: ${{matrix.platform != 'linux_arm'}} uses: dtolnay/rust-toolchain@stable with: toolchain: stable @@ -107,20 +107,8 @@ jobs: echo '${{ secrets.KEYSTORE }}' | base64 --decode > android/app/upload-keystore.jks echo '${{ secrets.KEY_PROPERTIES }}' > android/key.properties - - name: Uncessary hosted tools - if: ${{matrix.platform == 'linux_arm'}} - uses: jlumbroso/free-disk-space@main - with: - tool-cache: false - swap-storage: false - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - - name: Build ${{matrix.platform}} binaries - run: dart cli/cli.dart build ${{matrix.platform}} + run: dart cli/cli.dart build --arch=${{matrix.arch}} ${{matrix.platform}} env: CHANNEL: ${{inputs.channel}} DOTENV: ${{secrets.DOTENV_RELEASE}} diff --git a/cli/commands/build.dart b/cli/commands/build.dart index fdf35a95..e0c254ff 100644 --- a/cli/commands/build.dart +++ b/cli/commands/build.dart @@ -3,7 +3,6 @@ import 'package:args/command_runner.dart'; import 'build/android.dart'; import 'build/ios.dart'; import 'build/linux.dart'; -import 'build/linux_arm.dart'; import 'build/macos.dart'; import 'build/windows.dart'; @@ -18,8 +17,13 @@ class BuildCommand extends Command { addSubcommand(AndroidBuildCommand()); addSubcommand(IosBuildCommand()); addSubcommand(LinuxBuildCommand()); - addSubcommand(LinuxArmBuildCommand()); addSubcommand(MacosBuildCommand()); addSubcommand(WindowsBuildCommand()); + argParser.addOption( + "arch", + abbr: "a", + defaultsTo: "x86", + allowed: ["x86", "arm64", "all"], + ); } } diff --git a/cli/commands/build/common.dart b/cli/commands/build/common.dart index 4c7e3e51..f6f6ad50 100644 --- a/cli/commands/build/common.dart +++ b/cli/commands/build/common.dart @@ -63,4 +63,6 @@ mixin BuildCommandCommonSteps on Command { """, ); } + + String get architecture => argResults?.option("arch") as String; } diff --git a/cli/commands/build/linux.dart b/cli/commands/build/linux.dart index a218720c..f61ffbce 100644 --- a/cli/commands/build/linux.dart +++ b/cli/commands/build/linux.dart @@ -37,23 +37,32 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps { await bootstrap(); await shell.run( - """ - flutter_distributor package --platform=linux --targets=deb - flutter_distributor package --platform=linux --targets=rpm - """, + "flutter_distributor package --platform=linux --targets=deb", ); + if (architecture == "x86") { + await shell.run( + "flutter_distributor package --platform=linux --targets=rpm", + ); + } + final tempDir = join(Directory.systemTemp.path, "spotube-tar"); - final bundleDirPath = - join(cwd.path, "build", "linux", "x64", "release", "bundle"); + final bundleDirPath = join( + cwd.path, + "build", + "linux", + architecture == "x86" ? "x64" : architecture, + "release", + "bundle", + ); final tarFile = File(join( cwd.path, "dist", "spotube-linux-" "${CliEnv.channel == BuildChannel.nightly ? "nightly" : versionWithoutBuildNumber}" - "-x86_64.tar.xz", + "-${architecture == "x86" ? "x86_64" : "aarch64"}.tar.xz", )); await copyPath(bundleDirPath, tempDir); @@ -81,25 +90,27 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps { "spotube-${pubspec.version}-linux.deb", ), ); - - final ogRpm = File( - join( - cwd.path, - "dist", - pubspec.version.toString(), - "spotube-${pubspec.version}-linux.rpm", - ), - ); - await ogDeb.copy( join(cwd.path, "dist", "Spotube-linux-x86_64.deb"), ); - await ogRpm.copy( - join(cwd.path, "dist", "Spotube-linux-x86_64.rpm"), - ); - await ogDeb.delete(); - await ogRpm.delete(); + + if (architecture == "x86") { + final ogRpm = File( + join( + cwd.path, + "dist", + pubspec.version.toString(), + "spotube-${pubspec.version}-linux.rpm", + ), + ); + + await ogRpm.copy( + join(cwd.path, "dist", "Spotube-linux-x86_64.rpm"), + ); + + await ogRpm.delete(); + } stdout.writeln("✅ Linux building done"); } diff --git a/cli/commands/build/linux_arm.dart b/cli/commands/build/linux_arm.dart deleted file mode 100644 index a09f0980..00000000 --- a/cli/commands/build/linux_arm.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'dart:async'; - -import 'package:args/command_runner.dart'; -import 'package:path/path.dart'; - -import '../../core/env.dart'; -import 'common.dart'; - -class LinuxArmBuildCommand extends Command with BuildCommandCommonSteps { - @override - String get description => "Build Linux Arm"; - - @override - String get name => "linux_arm"; - - @override - FutureOr? run() async { - await bootstrap(); - - await shell.run( - "docker buildx build --platform=linux/arm64 " - "-f ${join(cwd.path, ".github", "Dockerfile")} ${cwd.path} " - "--build-arg FLUTTER_VERSION=${CliEnv.flutterVersion} " - "--build-arg BUILD_VERSION=${CliEnv.channel == BuildChannel.nightly ? "nightly" : versionWithoutBuildNumber} " - "-t krtirtho/spotube_linux_arm:latest " - "--load", - ); - - await shell.run( - """ - docker images ls - docker create --name spotube_linux_arm krtirtho/spotube_linux_arm:latest - docker cp spotube_linux_arm:/app/dist/ dist/ - """, - ); - } -} diff --git a/cli/commands/install-dependencies.dart b/cli/commands/install-dependencies.dart index dc519cc6..e26b8078 100644 --- a/cli/commands/install-dependencies.dart +++ b/cli/commands/install-dependencies.dart @@ -24,6 +24,13 @@ class InstallDependenciesCommand extends Command { ], mandatory: true, ); + + argParser.addOption( + "arch", + abbr: "a", + allowed: ["x86", "arm64", "all"], + defaultsTo: "x86", + ); } @override @@ -41,14 +48,6 @@ class InstallDependenciesCommand extends Command { """, ); break; - case "linux_arm": - await shell.run( - """ - sudo apt-get update -y - sudo apt-get install -y pkg-config make python3-pip python3-setuptools - """, - ); - break; case "macos": await shell.run( """ From 1937b1b8401a9473ea3d41caf86ba2287299d499 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 11:31:01 +0600 Subject: [PATCH 64/81] cd: use default caching key --- .github/workflows/spotube-release-binary.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 410cb835..9d2f2441 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -73,7 +73,6 @@ jobs: - uses: subosito/flutter-action@v2.12.0 with: cache: true - cache-key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.yaml') }} flutter-version: ${{ env.FLUTTER_VERSION }} channel: ${{ env.FLUTTER_CHANNEL }} - name: Setup Java From b7bb35d299c3e4e0c2c2e00b114cd5d5ed026d8d Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 11:32:41 +0600 Subject: [PATCH 65/81] cd: upgrade flutter action --- .github/workflows/spotube-release-binary.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 9d2f2441..b0096517 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -70,7 +70,7 @@ jobs: runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v4 - - uses: subosito/flutter-action@v2.12.0 + - uses: subosito/flutter-action@v2 with: cache: true flutter-version: ${{ env.FLUTTER_VERSION }} From 15773e1ce7105d608a289b64133b3e18055ddab7 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 11:44:22 +0600 Subject: [PATCH 66/81] cd: use alternative flutter action setup action --- .github/workflows/spotube-release-binary.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index b0096517..68fc6a60 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -70,10 +70,9 @@ jobs: runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v4 - - uses: subosito/flutter-action@v2 + - uses: flutter-actions/setup-flutter@v4 with: - cache: true - flutter-version: ${{ env.FLUTTER_VERSION }} + version: ${{ env.FLUTTER_VERSION }} channel: ${{ env.FLUTTER_CHANNEL }} - name: Setup Java if: ${{matrix.platform == 'android'}} From ed1f4ad6f522863c5635212b8f56ea41bc307de9 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 12:08:01 +0600 Subject: [PATCH 67/81] cd: use cache less Flutter SDK --- .github/workflows/spotube-release-binary.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 68fc6a60..4e8c9ac7 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -70,10 +70,12 @@ jobs: runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v4 - - uses: flutter-actions/setup-flutter@v4 + - uses: subosito/flutter-action@v2 with: - version: ${{ env.FLUTTER_VERSION }} + flutter-version: ${{ env.FLUTTER_VERSION }} channel: ${{ env.FLUTTER_CHANNEL }} + cache: false + - name: Setup Java if: ${{matrix.platform == 'android'}} uses: actions/setup-java@v4 From 219ae9dcb3d57e0324d48790f82f498636e2807f Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 12:15:30 +0600 Subject: [PATCH 68/81] cd: use git source for flutter action --- .github/workflows/spotube-release-binary.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 4e8c9ac7..30e9dd2c 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -70,11 +70,12 @@ jobs: runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v4 - - uses: subosito/flutter-action@v2 + - uses: subosito/flutter-action@v2.18.0 with: flutter-version: ${{ env.FLUTTER_VERSION }} channel: ${{ env.FLUTTER_CHANNEL }} cache: false + git-source: https://github.com/flutter/flutter.git - name: Setup Java if: ${{matrix.platform == 'android'}} From b2b38a919184325f56d4a9b4c539f657ab0b5c13 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 12:18:33 +0600 Subject: [PATCH 69/81] cd: use git source for flutter action --- .github/workflows/spotube-release-binary.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 30e9dd2c..f146ae9a 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -21,7 +21,7 @@ on: env: FLUTTER_VERSION: 3.28.0-0.1.pre - FLUTTER_CHANNEL: beta + FLUTTER_CHANNEL: master permissions: contents: write From ee95b3b26a37ed9255ee46b300f0fb40b03fcf09 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 12:32:01 +0600 Subject: [PATCH 70/81] chore: fix build cli argument access --- cli/commands/build/common.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/commands/build/common.dart b/cli/commands/build/common.dart index f6f6ad50..30906b3c 100644 --- a/cli/commands/build/common.dart +++ b/cli/commands/build/common.dart @@ -64,5 +64,5 @@ mixin BuildCommandCommonSteps on Command { ); } - String get architecture => argResults?.option("arch") as String; + String get architecture => parent?.argResults?.option("arch") as String; } From e05645c46e68e481a172f1b4b83b3e046aeb72ca Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 12:43:44 +0600 Subject: [PATCH 71/81] cd: enable caching for Flutter SDK in release workflow --- .github/workflows/spotube-release-binary.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index f146ae9a..7b9ffe72 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -74,7 +74,7 @@ jobs: with: flutter-version: ${{ env.FLUTTER_VERSION }} channel: ${{ env.FLUTTER_CHANNEL }} - cache: false + cache: true git-source: https://github.com/flutter/flutter.git - name: Setup Java @@ -117,7 +117,7 @@ jobs: - uses: actions/upload-artifact@v4 with: if-no-files-found: error - name: ${{matrix.platform}} + name: ${{matrix.platform}}-${{matrix.arch}} path: ${{matrix.files}} - name: Debug With SSH When fails From 697ba1ed7b9dad734a305b0fc7e0f412e9249f00 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 13:27:20 +0600 Subject: [PATCH 72/81] cd: sha and md5 sum error --- .github/workflows/spotube-release-binary.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 7b9ffe72..19011967 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -142,8 +142,9 @@ jobs: - name: Generate Checksums run: | tree . - md5sum Spotube-Release-Binaries/* >> RELEASE.md5sum - sha256sum Spotube-Release-Binaries/* >> RELEASE.sha256sum + find Spotube-Release-Binaries -type f -exec md5sum {} \; >> RELEASE.md5sum + find Spotube-Release-Binaries -type f -exec sha256sum {} \; >> RELEASE.sha256sum + sed -i 's|Spotube-Release-Binaries/.*/\([^/]*\)$|\1|' RELEASE.sha256sum RELEASE.md5sum sed -i 's|Spotube-Release-Binaries/||' RELEASE.sha256sum RELEASE.md5sum - name: Extract pubspec version From 8c0a47374da809a7c03fa34efa6badfdae7b0131 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 13:55:57 +0600 Subject: [PATCH 73/81] cd: artifact nested directory glob --- .github/workflows/spotube-release-binary.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index 19011967..e8651c07 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -169,7 +169,7 @@ jobs: omitNameDuringUpdate: true omitPrereleaseDuringUpdate: true allowUpdates: true - artifacts: Spotube-Release-Binaries/*,RELEASE.sha256sum,RELEASE.md5sum + artifacts: Spotube-Release-Binaries/**/*,RELEASE.sha256sum,RELEASE.md5sum - name: Upload Release Binaries (nightly) if: ${{ !inputs.dry_run && inputs.channel == 'nightly' }} @@ -181,7 +181,7 @@ jobs: omitNameDuringUpdate: true omitPrereleaseDuringUpdate: true allowUpdates: true - artifacts: Spotube-Release-Binaries/*,RELEASE.sha256sum,RELEASE.md5sum + artifacts: Spotube-Release-Binaries/**/*,RELEASE.sha256sum,RELEASE.md5sum body: | Build Number: ${{github.run_number}} From 75e189344e1d6b1e288c8178d1f7069cec21e834 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 24 Jan 2025 14:19:44 +0600 Subject: [PATCH 74/81] cd: update workflow and build command for Ubuntu 22.04 compatibility --- .github/workflows/spotube-release-binary.yml | 6 +++--- cli/commands/build/linux.dart | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index e8651c07..fa736f27 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -31,7 +31,7 @@ jobs: strategy: matrix: include: - - os: ubuntu-latest + - os: ubuntu-22.04 platform: linux arch: x86 files: | @@ -44,7 +44,7 @@ jobs: files: | dist/Spotube-linux-aarch64.deb dist/spotube-linux-*-aarch64.tar.xz - - os: ubuntu-latest + - os: ubuntu-22.04 platform: android arch: all files: | @@ -127,7 +127,7 @@ jobs: limit-access-to-actor: true upload: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: - build_platform steps: diff --git a/cli/commands/build/linux.dart b/cli/commands/build/linux.dart index f61ffbce..3fd8a0b9 100644 --- a/cli/commands/build/linux.dart +++ b/cli/commands/build/linux.dart @@ -47,7 +47,7 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps { } final tempDir = join(Directory.systemTemp.path, "spotube-tar"); - + final bundleArchName = architecture == "x86" ? "x86_64" : "aarch64"; final bundleDirPath = join( cwd.path, "build", @@ -62,7 +62,7 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps { "dist", "spotube-linux-" "${CliEnv.channel == BuildChannel.nightly ? "nightly" : versionWithoutBuildNumber}" - "-${architecture == "x86" ? "x86_64" : "aarch64"}.tar.xz", + "-$bundleArchName.tar.xz", )); await copyPath(bundleDirPath, tempDir); @@ -91,7 +91,11 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps { ), ); await ogDeb.copy( - join(cwd.path, "dist", "Spotube-linux-x86_64.deb"), + join( + cwd.path, + "dist", + "Spotube-linux-$bundleArchName.deb", + ), ); await ogDeb.delete(); @@ -106,7 +110,7 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps { ); await ogRpm.copy( - join(cwd.path, "dist", "Spotube-linux-x86_64.rpm"), + join(cwd.path, "dist", "Spotube-linux-$bundleArchName.rpm"), ); await ogRpm.delete(); From 4e8a50ec58ebd3aba51f043ab629de52b41cc2b4 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 26 Jan 2025 22:05:24 +0600 Subject: [PATCH 75/81] chore: fix logs not showing up and nightly crashing on track change on android --- .vscode/launch.json | 2 +- .../res/drawable/ic_launcher_monochrome.xml | 27 ++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 11 +- lib/pages/settings/logs.dart | 123 +++++++++--------- lib/provider/logs/logs_provider.dart | 8 +- .../audio_services/audio_services.dart | 11 +- pubspec.lock | 48 +++---- 7 files changed, 132 insertions(+), 98 deletions(-) create mode 100644 android/app/src/nightly/res/drawable/ic_launcher_monochrome.xml diff --git a/.vscode/launch.json b/.vscode/launch.json index deabf1d3..df4131e5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,7 +14,7 @@ "program": "lib/main.dart", "args": [ "--flavor", - "dev" + "nightly" ] }, { diff --git a/android/app/src/nightly/res/drawable/ic_launcher_monochrome.xml b/android/app/src/nightly/res/drawable/ic_launcher_monochrome.xml new file mode 100644 index 00000000..8aae0e6c --- /dev/null +++ b/android/app/src/nightly/res/drawable/ic_launcher_monochrome.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/android/app/src/nightly/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/nightly/res/mipmap-anydpi-v26/ic_launcher.xml index c79c58a3..83e651db 100644 --- a/android/app/src/nightly/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/android/app/src/nightly/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,9 +1,6 @@ - - - - - + + + + \ No newline at end of file diff --git a/lib/pages/settings/logs.dart b/lib/pages/settings/logs.dart index f9439317..3a4f7715 100644 --- a/lib/pages/settings/logs.dart +++ b/lib/pages/settings/logs.dart @@ -25,75 +25,76 @@ class LogsPage extends HookConsumerWidget { return Scaffold( headers: [ - TitleBar( - title: Text(context.l10n.logs), - leading: const [BackButton()], - trailing: [ - IconButton.ghost( - icon: const Icon(SpotubeIcons.clipboard, size: 16), - onPressed: () async { - final logsSnapshot = await ref.read(logsProvider.future); + SafeArea( + bottom: false, + child: TitleBar( + title: Text(context.l10n.logs), + leading: const [BackButton()], + trailing: [ + IconButton.ghost( + icon: const Icon(SpotubeIcons.clipboard, size: 16), + onPressed: () async { + final logsSnapshot = await ref.read(logsProvider.future); - await Clipboard.setData(ClipboardData(text: logsSnapshot)); - if (context.mounted) { - showToast( - context: context, - location: ToastLocation.topRight, - builder: (context, overlay) { - return SurfaceCard( - child: Basic( - title: Text(context.l10n.copied_to_clipboard("")), - ), - ); - }, - ); - } - }, - ), - IconButton.ghost( - icon: const Icon( - SpotubeIcons.trash, - size: 16, + await Clipboard.setData(ClipboardData(text: logsSnapshot)); + if (context.mounted) { + showToast( + context: context, + location: ToastLocation.topRight, + builder: (context, overlay) { + return SurfaceCard( + child: Basic( + title: Text(context.l10n.copied_to_clipboard("")), + ), + ); + }, + ); + } + }, ), - onPressed: () async { - ref.invalidate(logsProvider); + IconButton.ghost( + icon: const Icon( + SpotubeIcons.trash, + size: 16, + ), + onPressed: () async { + ref.invalidate(logsProvider); - final logsFile = await AppLogger.getLogsPath(); + final logsFile = await AppLogger.getLogsPath(); - await logsFile.writeAsString(""); - }, - ) - ], + await logsFile.writeAsString(""); + }, + ) + ], + ), ) ], - child: SafeArea( - child: switch (logsQuery) { - AsyncData(:final value) => InterScrollbar( + child: switch (logsQuery) { + AsyncData(:final value) => InterScrollbar( + controller: controller, + child: SingleChildScrollView( + padding: const EdgeInsets.all(8.0), controller: controller, - child: SingleChildScrollView( - padding: const EdgeInsets.all(8.0), - controller: controller, - child: Card(child: SelectableText(value)), - ), + child: Card(child: SelectableText(value)), ), - AsyncError(:final error) => switch (error) { - StateError() => Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Undraw( - illustration: UndrawIllustration.noData, - height: 200 * context.theme.scaling, - width: 200 * context.theme.scaling, - color: context.theme.colorScheme.primary, - ), - Text(context.l10n.no_logs_found).muted().small(), - ], - ), - _ => Center(child: Text(error.toString())), - }, - _ => const Center(child: CircularProgressIndicator()), - }, - ), + ), + AsyncError(:final error) => switch (error) { + StateError() => Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Undraw( + illustration: UndrawIllustration.noData, + height: 200 * context.theme.scaling, + width: 200 * context.theme.scaling, + color: context.theme.colorScheme.primary, + ), + Text(context.l10n.no_logs_found).muted().small(), + ], + ), + _ => Center(child: Text(error.toString())), + }, + _ => const Center(child: CircularProgressIndicator()), + }, ); } } diff --git a/lib/provider/logs/logs_provider.dart b/lib/provider/logs/logs_provider.dart index 571d96cc..d39059ac 100644 --- a/lib/provider/logs/logs_provider.dart +++ b/lib/provider/logs/logs_provider.dart @@ -5,12 +5,14 @@ import 'package:spotube/services/logger/logger.dart'; final logsProvider = StreamProvider.autoDispose((ref) async* { final file = await AppLogger.getLogsPath(); - final stream = file.openRead().transform(utf8.decoder); + // Check if file is empty or non-existent - if (await stream.isEmpty) { - throw StateError('No logs found'); + if (await file.length() == 0) { + throw StateError("Logs file is empty or non-existent"); } + final stream = file.openRead().transform(utf8.decoder); + await for (final line in stream) { yield line; } diff --git a/lib/services/audio_services/audio_services.dart b/lib/services/audio_services/audio_services.dart index 0b1843c4..6433707d 100644 --- a/lib/services/audio_services/audio_services.dart +++ b/lib/services/audio_services/audio_services.dart @@ -2,6 +2,7 @@ import 'package:audio_service/audio_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/env.dart'; import 'package:spotube/extensions/artist_simple.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/audio_player/audio_player.dart'; @@ -27,8 +28,14 @@ class AudioServices with WidgetsBindingObserver { ? await AudioService.init( builder: () => MobileAudioService(playback), config: AudioServiceConfig( - androidNotificationChannelId: - kIsLinux ? 'spotube' : 'com.krtirtho.Spotube', + androidNotificationChannelId: switch (( + kIsLinux, + Env.releaseChannel + )) { + (true, _) => "spotube", + (_, ReleaseChannel.stable) => "com.krtirtho.Spotube", + (_, ReleaseChannel.nightly) => "com.krtirtho.Spotube.nightly", + }, androidNotificationChannelName: 'Spotube', androidNotificationOngoing: false, androidStopForegroundOnPause: false, diff --git a/pubspec.lock b/pubspec.lock index 1a35f9c9..1e9d9265 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -98,10 +98,10 @@ packages: dependency: "direct main" description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.11.0" audio_service: dependency: "direct main" description: @@ -203,10 +203,10 @@ packages: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" build: dependency: transitive description: @@ -347,10 +347,10 @@ packages: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" code_builder: dependency: transitive description: @@ -614,10 +614,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.1" ffi: dependency: transitive description: @@ -630,10 +630,10 @@ packages: dependency: transitive description: name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.0" file_picker: dependency: "direct main" description: @@ -1370,18 +1370,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -1690,10 +1690,10 @@ packages: dependency: "direct main" description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -1826,10 +1826,10 @@ packages: dependency: transitive description: name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.1.5" plugin_platform_interface: dependency: transitive description: @@ -1866,10 +1866,10 @@ packages: dependency: transitive description: name: process - sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "5.0.3" + version: "5.0.2" process_run: dependency: "direct dev" description: @@ -2305,10 +2305,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.3.0" stroke_text: dependency: "direct main" description: @@ -2609,10 +2609,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "14.3.0" watcher: dependency: transitive description: From 4c3718467d2037caea3c85ccd273f3b3e4ef093b Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 26 Jan 2025 22:36:11 +0600 Subject: [PATCH 76/81] chore: local library not working --- .fvm/fvm_config.json | 2 +- .fvmrc | 2 +- .github/workflows/spotube-release-binary.yml | 2 +- .vscode/launch.json | 2 +- .vscode/settings.json | 2 +- lib/collections/intents.dart | 2 +- lib/collections/routes.dart | 45 ++++++++++--------- lib/collections/side_bar_tiles.dart | 2 +- .../presentation_state.dart | 2 +- .../sort_tracks_dropdown.dart | 2 +- .../local_folder/local_folder_item.dart | 4 +- lib/pages/library/library.dart | 12 ++++- .../{ => user_local_tracks}/local_folder.dart | 2 +- .../user_local_tracks.dart | 0 lib/utils/service_utils.dart | 2 +- 15 files changed, 48 insertions(+), 35 deletions(-) rename lib/pages/library/{ => user_local_tracks}/local_folder.dart (99%) rename lib/pages/library/{ => user_local_tracks}/user_local_tracks.dart (100%) diff --git a/.fvm/fvm_config.json b/.fvm/fvm_config.json index 7572d05e..c0b314bc 100644 --- a/.fvm/fvm_config.json +++ b/.fvm/fvm_config.json @@ -1,3 +1,3 @@ { - "flutterSdkVersion": "3.28.0-0.1.pre" + "flutterSdkVersion": "3.27.3" } \ No newline at end of file diff --git a/.fvmrc b/.fvmrc index 089fa312..74c2c15a 100644 --- a/.fvmrc +++ b/.fvmrc @@ -1,4 +1,4 @@ { - "flutter": "3.28.0-0.1.pre", + "flutter": "3.27.3", "flavors": {} } \ No newline at end of file diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml index fa736f27..5cfa5b6e 100644 --- a/.github/workflows/spotube-release-binary.yml +++ b/.github/workflows/spotube-release-binary.yml @@ -20,7 +20,7 @@ on: description: Dry run without uploading to release env: - FLUTTER_VERSION: 3.28.0-0.1.pre + FLUTTER_VERSION: 3.27.3 FLUTTER_CHANNEL: master permissions: diff --git a/.vscode/launch.json b/.vscode/launch.json index df4131e5..deabf1d3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,7 +14,7 @@ "program": "lib/main.dart", "args": [ "--flavor", - "nightly" + "dev" ] }, { diff --git a/.vscode/settings.json b/.vscode/settings.json index a5548411..ac8518d1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -28,5 +28,5 @@ "README.md": "LICENSE,CODE_OF_CONDUCT.md,CONTRIBUTING.md,SECURITY.md,CONTRIBUTION.md,CHANGELOG.md,PRIVACY_POLICY.md", "*.dart": "${capture}.g.dart,${capture}.freezed.dart" }, - "dart.flutterSdkPath": ".fvm/versions/3.28.0-0.1.pre" + "dart.flutterSdkPath": ".fvm/versions/3.27.3" } \ No newline at end of file diff --git a/lib/collections/intents.dart b/lib/collections/intents.dart index 1ec62812..d0a0c8b6 100644 --- a/lib/collections/intents.dart +++ b/lib/collections/intents.dart @@ -10,7 +10,7 @@ import 'package:spotube/pages/home/home.dart'; import 'package:spotube/pages/library/user_albums.dart'; import 'package:spotube/pages/library/user_artists.dart'; import 'package:spotube/pages/library/user_downloads.dart'; -import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks/user_local_tracks.dart'; import 'package:spotube/pages/library/user_playlists.dart'; import 'package:spotube/pages/lyrics/lyrics.dart'; import 'package:spotube/pages/search/search.dart'; diff --git a/lib/collections/routes.dart b/lib/collections/routes.dart index 25cf995c..4cd869cd 100644 --- a/lib/collections/routes.dart +++ b/lib/collections/routes.dart @@ -13,13 +13,13 @@ import 'package:spotube/pages/home/genres/genre_playlists.dart'; import 'package:spotube/pages/home/genres/genres.dart'; import 'package:spotube/pages/home/home.dart'; import 'package:spotube/pages/lastfm_login/lastfm_login.dart'; -import 'package:spotube/pages/library/local_folder.dart'; +import 'package:spotube/pages/library/user_local_tracks/local_folder.dart'; import 'package:spotube/pages/library/playlist_generate/playlist_generate.dart'; import 'package:spotube/pages/library/playlist_generate/playlist_generate_result.dart'; import 'package:spotube/pages/library/user_albums.dart'; import 'package:spotube/pages/library/user_artists.dart'; import 'package:spotube/pages/library/user_downloads.dart'; -import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks/user_local_tracks.dart'; import 'package:spotube/pages/library/user_playlists.dart'; import 'package:spotube/pages/lyrics/mini_lyrics.dart'; import 'package:spotube/pages/playlist/liked_playlist.dart'; @@ -127,11 +127,28 @@ final routerProvider = Provider((ref) { const SpotubePage(child: UserAlbumsPage()), ), GoRoute( - path: "/library/local", - name: UserLocalLibraryPage.name, - pageBuilder: (context, state) => - const SpotubePage(child: UserLocalLibraryPage()), - ), + path: "/library/local", + name: UserLocalLibraryPage.name, + pageBuilder: (context, state) => + const SpotubePage(child: UserLocalLibraryPage()), + routes: [ + GoRoute( + path: "folder", + name: LocalLibraryPage.name, + parentNavigatorKey: shellRouteNavigatorKey, + pageBuilder: (context, state) { + assert(state.extra is String); + return SpotubePage( + child: LocalLibraryPage( + state.extra as String, + isDownloads: + state.uri.queryParameters["downloads"] != null, + isCache: state.uri.queryParameters["cache"] != null, + ), + ); + }, + ), + ]), GoRoute( path: "/library/downloads", name: UserDownloadsPage.name, @@ -157,20 +174,6 @@ final routerProvider = Provider((ref) { ) ], ), - GoRoute( - path: "/library/local", - name: LocalLibraryPage.name, - pageBuilder: (context, state) { - assert(state.extra is String); - return SpotubePage( - child: LocalLibraryPage( - state.extra as String, - isDownloads: state.uri.queryParameters["downloads"] != null, - isCache: state.uri.queryParameters["cache"] != null, - ), - ); - }, - ), GoRoute( path: "/lyrics", name: LyricsPage.name, diff --git a/lib/collections/side_bar_tiles.dart b/lib/collections/side_bar_tiles.dart index 26396e39..f84bd158 100644 --- a/lib/collections/side_bar_tiles.dart +++ b/lib/collections/side_bar_tiles.dart @@ -4,7 +4,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:spotube/pages/home/home.dart'; import 'package:spotube/pages/library/user_albums.dart'; import 'package:spotube/pages/library/user_artists.dart'; -import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks/user_local_tracks.dart'; import 'package:spotube/pages/library/user_playlists.dart'; import 'package:spotube/pages/lyrics/lyrics.dart'; import 'package:spotube/pages/search/search.dart'; diff --git a/lib/components/track_presentation/presentation_state.dart b/lib/components/track_presentation/presentation_state.dart index 91adbfcd..2ae0b451 100644 --- a/lib/components/track_presentation/presentation_state.dart +++ b/lib/components/track_presentation/presentation_state.dart @@ -2,7 +2,7 @@ import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks/user_local_tracks.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/utils/service_utils.dart'; diff --git a/lib/components/track_presentation/sort_tracks_dropdown.dart b/lib/components/track_presentation/sort_tracks_dropdown.dart index ecab615f..54990503 100644 --- a/lib/components/track_presentation/sort_tracks_dropdown.dart +++ b/lib/components/track_presentation/sort_tracks_dropdown.dart @@ -1,6 +1,6 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks/user_local_tracks.dart'; import 'package:spotube/components/adaptive/adaptive_pop_sheet_list.dart'; import 'package:spotube/extensions/context.dart'; diff --git a/lib/modules/library/local_folder/local_folder_item.dart b/lib/modules/library/local_folder/local_folder_item.dart index 20845ef7..149657cc 100644 --- a/lib/modules/library/local_folder/local_folder_item.dart +++ b/lib/modules/library/local_folder/local_folder_item.dart @@ -12,7 +12,7 @@ import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; import 'package:spotube/extensions/string.dart'; -import 'package:spotube/pages/library/local_folder.dart'; +import 'package:spotube/pages/library/user_local_tracks/local_folder.dart'; import 'package:spotube/provider/local_tracks/local_tracks_provider.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; @@ -59,7 +59,7 @@ class LocalFolderItem extends HookConsumerWidget { return Button( onPressed: () { - context.goNamed( + context.pushNamed( LocalLibraryPage.name, queryParameters: { if (isDownloadFolder) "downloads": "true", diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index 7ae5a0e4..6677a3b6 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -4,9 +4,11 @@ import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; +import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/pages/library/user_downloads.dart'; import 'package:spotube/provider/download_manager_provider.dart'; class LibraryPage extends HookConsumerWidget { @@ -18,7 +20,15 @@ class LibraryPage extends HookConsumerWidget { final downloadingCount = ref.watch(downloadManagerProvider).$downloadCount; final routerState = GoRouterState.of(context); final sidebarLibraryTileList = useMemoized( - () => getSidebarLibraryTileList(context.l10n), + () => [ + ...getSidebarLibraryTileList(context.l10n), + SideBarTiles( + id: "downloads", + title: context.l10n.downloads, + name: UserDownloadsPage.name, + icon: SpotubeIcons.download, + ), + ], [context.l10n], ); final index = sidebarLibraryTileList.indexWhere( diff --git a/lib/pages/library/local_folder.dart b/lib/pages/library/user_local_tracks/local_folder.dart similarity index 99% rename from lib/pages/library/local_folder.dart rename to lib/pages/library/user_local_tracks/local_folder.dart index b8cdd096..5282894a 100644 --- a/lib/pages/library/local_folder.dart +++ b/lib/pages/library/user_local_tracks/local_folder.dart @@ -16,7 +16,7 @@ import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/string.dart'; import 'package:spotube/modules/library/local_folder/cache_export_dialog.dart'; -import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks/user_local_tracks.dart'; import 'package:spotube/components/expandable_search/expandable_search.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; diff --git a/lib/pages/library/user_local_tracks.dart b/lib/pages/library/user_local_tracks/user_local_tracks.dart similarity index 100% rename from lib/pages/library/user_local_tracks.dart rename to lib/pages/library/user_local_tracks/user_local_tracks.dart diff --git a/lib/utils/service_utils.dart b/lib/utils/service_utils.dart index bc57dd4a..c89866b4 100644 --- a/lib/utils/service_utils.dart +++ b/lib/utils/service_utils.dart @@ -6,7 +6,7 @@ import 'package:go_router/go_router.dart'; import 'package:html/dom.dart' hide Text; import 'package:shadcn_flutter/shadcn_flutter.dart' hide Element; import 'package:spotify/spotify.dart'; -import 'package:spotube/pages/library/user_local_tracks.dart'; +import 'package:spotube/pages/library/user_local_tracks/user_local_tracks.dart'; import 'package:spotube/modules/root/update_dialog.dart'; import 'package:spotube/models/lyrics.dart'; From 5c6cb770a8c94fe54c09a661aabd8e50b711ff7e Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Tue, 28 Jan 2025 21:07:02 +0600 Subject: [PATCH 77/81] chore: fix where loading images not working --- .../presentation_state.dart | 58 ++++++++++++------- lib/modules/home/sections/genres/genres.dart | 27 --------- lib/pages/library/user_artists.dart | 2 +- lib/pages/playlist/liked_playlist.dart | 2 +- 4 files changed, 39 insertions(+), 50 deletions(-) diff --git a/lib/components/track_presentation/presentation_state.dart b/lib/components/track_presentation/presentation_state.dart index 2ae0b451..d3428861 100644 --- a/lib/components/track_presentation/presentation_state.dart +++ b/lib/components/track_presentation/presentation_state.dart @@ -34,25 +34,38 @@ class PresentationStateNotifier extends AutoDisposeFamilyNotifier { @override PresentationState build(collection) { - final isPlaylist = arg is PlaylistSimple; - - if ((isPlaylist && (arg as PlaylistSimple).id != "user-liked-tracks") || - arg is AlbumSimple) { - ref.listen( - isPlaylist - ? playlistTracksProvider((arg as PlaylistSimple).id!) - : albumTracksProvider((arg as AlbumSimple)), - (previous, next) { - next.whenData((value) { - state = state.copyWith( - presentationTracks: ServiceUtils.sortTracks( - value.items, - state.sortBy, - ), - ); - }); - }, - ); + if (arg case PlaylistSimple() || AlbumSimple()) { + if (isSavedTrackPlaylist) { + ref.listen( + likedTracksProvider, + (previous, next) { + next.whenData((value) { + state = state.copyWith( + presentationTracks: ServiceUtils.sortTracks( + value, + state.sortBy, + ), + ); + }); + }, + ); + } else { + ref.listen( + arg is PlaylistSimple + ? playlistTracksProvider((arg as PlaylistSimple).id!) + : albumTracksProvider((arg as AlbumSimple)), + (previous, next) { + next.whenData((value) { + state = state.copyWith( + presentationTracks: ServiceUtils.sortTracks( + value.items, + state.sortBy, + ), + ); + }); + }, + ); + } } return PresentationState( @@ -62,6 +75,10 @@ class PresentationStateNotifier ); } + bool get isSavedTrackPlaylist => + arg is PlaylistSimple && + (arg as PlaylistSimple).id == "user-liked-tracks"; + List get tracks { assert( arg is PlaylistSimple || arg is AlbumSimple, @@ -69,8 +86,7 @@ class PresentationStateNotifier ); final isPlaylist = arg is PlaylistSimple; - final isSavedTrackPlaylist = - isPlaylist && (arg as PlaylistSimple).id == "user-liked-tracks"; + final tracks = switch ((isPlaylist, isSavedTrackPlaylist)) { (true, true) => ref.read(likedTracksProvider).asData?.value, (true, false) => ref diff --git a/lib/modules/home/sections/genres/genres.dart b/lib/modules/home/sections/genres/genres.dart index 881003aa..64a6be1c 100644 --- a/lib/modules/home/sections/genres/genres.dart +++ b/lib/modules/home/sections/genres/genres.dart @@ -1,5 +1,3 @@ -import 'dart:async'; - import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -35,29 +33,6 @@ class HomeGenresSection extends HookConsumerWidget { [categoriesQuery.asData?.value], ); final controller = useMemoized(() => CarouselController(), []); - final interactedRef = useRef(false); - - useEffect(() { - int times = 0; - final timer = Timer.periodic( - const Duration(seconds: 5), - (timer) { - if (times > 5 || interactedRef.value) { - timer.cancel(); - return; - } - controller.animateNext( - const Duration(seconds: 2), - ); - times++; - }, - ); - - return () { - timer.cancel(); - controller.dispose(); - }; - }, []); return SliverList.list( children: [ @@ -123,7 +98,6 @@ class HomeGenresSection extends HookConsumerWidget { controller.animatePrevious( const Duration(seconds: 1), ); - interactedRef.value = true; }, ), ), @@ -144,7 +118,6 @@ class HomeGenresSection extends HookConsumerWidget { controller.animateNext( const Duration(seconds: 1), ); - interactedRef.value = true; }, ), ), diff --git a/lib/pages/library/user_artists.dart b/lib/pages/library/user_artists.dart index aacf4102..6ce715ad 100644 --- a/lib/pages/library/user_artists.dart +++ b/lib/pages/library/user_artists.dart @@ -82,7 +82,7 @@ class UserArtistsPage extends HookConsumerWidget { ), ), const SliverGap(10), - if (filteredArtists.isNotEmpty) + if (filteredArtists.isNotEmpty || artistQuery.isLoading) SliverLayoutBuilder(builder: (context, constrains) { return SliverGrid.builder( itemCount: filteredArtists.length + 1, diff --git a/lib/pages/playlist/liked_playlist.dart b/lib/pages/playlist/liked_playlist.dart index 3b4455d5..95107a8c 100644 --- a/lib/pages/playlist/liked_playlist.dart +++ b/lib/pages/playlist/liked_playlist.dart @@ -26,7 +26,7 @@ class LikedPlaylistPage extends HookConsumerWidget { image: "assets/liked-tracks.jpg", pagination: PaginationProps( hasNextPage: false, - isLoading: false, + isLoading: likedTracks.isLoading, onFetchMore: () {}, onFetchAll: () async { return tracks.toList(); From 42158a99ff1f528eb9e2e7f1c8394afe6be92f46 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Tue, 28 Jan 2025 21:23:57 +0600 Subject: [PATCH 78/81] refactor: use shadcn for mini lyrics window --- lib/modules/player/sibling_tracks_sheet.dart | 7 +- lib/pages/lyrics/mini_lyrics.dart | 308 ++++++++++--------- 2 files changed, 164 insertions(+), 151 deletions(-) diff --git a/lib/modules/player/sibling_tracks_sheet.dart b/lib/modules/player/sibling_tracks_sheet.dart index 14773156..6f9763b6 100644 --- a/lib/modules/player/sibling_tracks_sheet.dart +++ b/lib/modules/player/sibling_tracks_sheet.dart @@ -10,6 +10,7 @@ import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/artist_simple.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/duration.dart'; import 'package:spotube/hooks/utils/use_debounce.dart'; @@ -193,7 +194,11 @@ class SiblingTracksSheet extends HookConsumerWidget { if (!isFetchingActiveTrack && sourceInfo.id != (activeTrack as SourcedTrack).sourceInfo.id) { activeTrackNotifier.swapSibling(sourceInfo); - closeDrawer(context); + if (MediaQuery.sizeOf(context).mdAndUp) { + closeOverlay(context); + } else { + closeDrawer(context); + } } }, ); diff --git a/lib/pages/lyrics/mini_lyrics.dart b/lib/pages/lyrics/mini_lyrics.dart index 8f6ec1fc..9fd54ad6 100644 --- a/lib/pages/lyrics/mini_lyrics.dart +++ b/lib/pages/lyrics/mini_lyrics.dart @@ -1,13 +1,12 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:palette_generator/palette_generator.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/player/player_controls.dart'; import 'package:spotube/modules/player/player_queue.dart'; -import 'package:spotube/modules/root/sidebar.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/hooks/utils/use_force_update.dart'; import 'package:spotube/pages/lyrics/plain_lyrics.dart'; @@ -30,6 +29,8 @@ class MiniLyricsPage extends HookConsumerWidget { final playlistQueue = ref.watch(audioPlayerProvider); + final index = useState(0); + final areaActive = useState(false); final hoverMode = useState(true); final showLyrics = useState(true); @@ -43,8 +44,6 @@ class MiniLyricsPage extends HookConsumerWidget { return null; }, []); - - return MouseRegion( onEnter: !hoverMode.value ? null @@ -56,12 +55,11 @@ class MiniLyricsPage extends HookConsumerWidget { : (event) { areaActive.value = false; }, - child: DefaultTabController( - length: 2, - child: Scaffold( - backgroundColor: theme.colorScheme.surface.withOpacity(0.4), - appBar: PreferredSize( - preferredSize: const Size.fromHeight(60), + child: Scaffold( + backgroundColor: theme.colorScheme.background.withOpacity(0.4), + headers: [ + Padding( + padding: const EdgeInsets.all(8.0), child: AnimatedCrossFade( duration: const Duration(milliseconds: 200), crossFadeState: areaActive.value @@ -70,91 +68,90 @@ class MiniLyricsPage extends HookConsumerWidget { secondChild: const SizedBox(), firstChild: DragToMoveArea( child: Row( + spacing: 2, children: [ const Gap(10), - if (!kIsMacOS) - SizedBox( - height: 30, - width: 30, - child: Sidebar.brandLogo(), - ), - const Spacer(), + if (kIsMacOS) const SizedBox(width: 65), if (showLyrics.value) - SizedBox( - height: 30, - child: TabBar( - tabs: [ - Tab(text: context.l10n.synced), - Tab(text: context.l10n.plain), - ], - isScrollable: true, - ), + Tabs( + index: index.value, + onChanged: (i) { + index.value = i; + }, + tabs: [ + Text(context.l10n.synced), + Text(context.l10n.plain), + ], ), const Spacer(), - IconButton( - tooltip: context.l10n.lyrics, - icon: showLyrics.value - ? const Icon(SpotubeIcons.lyrics) - : const Icon(SpotubeIcons.lyricsOff), - style: ButtonStyle( - foregroundColor: showLyrics.value - ? WidgetStateProperty.all(theme.colorScheme.primary) - : null, - ), - onPressed: () async { - showLyrics.value = !showLyrics.value; - areaActive.value = true; - hoverMode.value = false; + Tooltip( + tooltip: + TooltipContainer(child: Text(context.l10n.lyrics)), + child: IconButton( + variance: showLyrics.value + ? ButtonVariance.secondary + : ButtonVariance.ghost, + icon: showLyrics.value + ? const Icon(SpotubeIcons.lyrics) + : const Icon(SpotubeIcons.lyricsOff), + onPressed: () async { + showLyrics.value = !showLyrics.value; + areaActive.value = true; + hoverMode.value = false; - if (kIsDesktop) { - await windowManager.setSize( - showLyrics.value - ? const Size(400, 500) - : const Size(400, 150), - ); - } - }, - ), - IconButton( - tooltip: context.l10n.show_hide_ui_on_hover, - icon: hoverMode.value - ? const Icon(SpotubeIcons.hoverOn) - : const Icon(SpotubeIcons.hoverOff), - style: ButtonStyle( - foregroundColor: hoverMode.value - ? WidgetStateProperty.all(theme.colorScheme.primary) - : null, + if (kIsDesktop) { + await windowManager.setSize( + showLyrics.value + ? const Size(400, 500) + : const Size(400, 150), + ); + } + }, + ), + ), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.show_hide_ui_on_hover), + ), + child: IconButton( + variance: hoverMode.value + ? ButtonVariance.secondary + : ButtonVariance.ghost, + icon: hoverMode.value + ? const Icon(SpotubeIcons.hoverOn) + : const Icon(SpotubeIcons.hoverOff), + onPressed: () async { + areaActive.value = true; + hoverMode.value = !hoverMode.value; + }, ), - onPressed: () async { - areaActive.value = true; - hoverMode.value = !hoverMode.value; - }, ), if (kIsDesktop) FutureBuilder( future: windowManager.isAlwaysOnTop(), builder: (context, snapshot) { - return IconButton( - tooltip: context.l10n.always_on_top, - icon: Icon( - snapshot.data == true - ? SpotubeIcons.pinOn - : SpotubeIcons.pinOff, + return Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.always_on_top), ), - style: ButtonStyle( - foregroundColor: snapshot.data == true - ? WidgetStateProperty.all( - theme.colorScheme.primary) - : null, + child: IconButton( + variance: snapshot.data == true + ? ButtonVariance.secondary + : ButtonVariance.ghost, + icon: Icon( + snapshot.data == true + ? SpotubeIcons.pinOn + : SpotubeIcons.pinOff, + ), + onPressed: snapshot.data == null + ? null + : () async { + await windowManager.setAlwaysOnTop( + snapshot.data == true ? false : true, + ); + update(); + }, ), - onPressed: snapshot.data == null - ? null - : () async { - await windowManager.setAlwaysOnTop( - snapshot.data == true ? false : true, - ); - update(); - }, ); }, ), @@ -163,79 +160,90 @@ class MiniLyricsPage extends HookConsumerWidget { ), ), ), - body: Column( - children: [ - if (playlistQueue.activeTrack != null) - Text( - playlistQueue.activeTrack!.name!, - style: theme.textTheme.titleMedium, - ), - if (showLyrics.value) - Expanded( - child: TabBarView( - children: [ - SyncedLyrics( - palette: PaletteColor(theme.colorScheme.surface, 0), - isModal: true, - defaultTextZoom: 65, - ), - PlainLyrics( - palette: PaletteColor(theme.colorScheme.surface, 0), - isModal: true, - defaultTextZoom: 65, - ), - ], - ), - ) - else - const Gap(20), - AnimatedCrossFade( - crossFadeState: areaActive.value - ? CrossFadeState.showFirst - : CrossFadeState.showSecond, - duration: const Duration(milliseconds: 200), - secondChild: const SizedBox(), - firstChild: Row( + ], + child: Column( + children: [ + if (playlistQueue.activeTrack != null) + Text(playlistQueue.activeTrack!.name!).semiBold(), + if (showLyrics.value) + Expanded( + child: IndexedStack( + index: index.value, children: [ - IconButton( + SyncedLyrics( + palette: PaletteColor(theme.colorScheme.background, 0), + isModal: true, + defaultTextZoom: 65, + ), + PlainLyrics( + palette: PaletteColor(theme.colorScheme.background, 0), + isModal: true, + defaultTextZoom: 65, + ), + ], + ), + ) + else + const Gap(20), + AnimatedCrossFade( + crossFadeState: areaActive.value + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + duration: const Duration(milliseconds: 200), + secondChild: const SizedBox(), + firstChild: Row( + children: [ + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.queue), + ), + child: IconButton.ghost( icon: const Icon(SpotubeIcons.queue), - tooltip: context.l10n.queue, onPressed: playlistQueue.activeTrack != null ? () { - showModalBottomSheet( + openDrawer( context: context, - isDismissible: true, - enableDrag: true, - isScrollControlled: true, - backgroundColor: Colors.black12, - barrierColor: Colors.black12, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - constraints: BoxConstraints( - maxHeight: - MediaQuery.of(context).size.height * .7, - ), - builder: (context) { - return Consumer(builder: (context, ref, _) { - final playlist = - ref.watch(audioPlayerProvider); - - return PlayerQueue.fromAudioPlayerNotifier( - floating: true, - playlist: playlist, - notifier: ref - .read(audioPlayerProvider.notifier), + barrierDismissible: true, + draggable: true, + barrierColor: Colors.black.withAlpha(100), + borderRadius: BorderRadius.circular(10), + transformBackdrop: false, + position: OverlayPosition.bottom, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: 0.7, + expands: true, + builder: (context) => Consumer( + builder: (context, ref, _) { + final playlist = ref.watch( + audioPlayerProvider, ); - }); - }, + final playlistNotifier = + ref.read(audioPlayerProvider.notifier); + return ConstrainedBox( + constraints: BoxConstraints( + maxHeight: + MediaQuery.of(context).size.height * + 0.8, + ), + child: + PlayerQueue.fromAudioPlayerNotifier( + floating: false, + playlist: playlist, + notifier: playlistNotifier, + ), + ); + }, + ), ); } : null, ), - const Flexible(child: PlayerControls(compact: true)), - IconButton( - tooltip: context.l10n.exit_mini_player, + ), + const Flexible(child: PlayerControls(compact: true)), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.exit_mini_player)), + child: IconButton.ghost( icon: const Icon(SpotubeIcons.maximize), onPressed: () async { if (!kIsDesktop) return; @@ -262,11 +270,11 @@ class MiniLyricsPage extends HookConsumerWidget { } }, ), - ], - ), - ) - ], - ), + ), + ], + ), + ) + ], ), ), ); From ada0ca14727fad4dd98a8fb0b1e1f5a6cd7987ac Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Tue, 28 Jan 2025 21:42:16 +0600 Subject: [PATCH 79/81] chore: remove obsolete appearance customization --- lib/main.dart | 17 ---- lib/pages/settings/sections/appearance.dart | 32 +++---- .../audio_player/audio_player_streams.dart | 28 ------ lib/provider/palette_provider.dart | 4 - .../user_preferences_provider.dart | 12 ++- lib/themes/theme.dart | 86 ------------------- 6 files changed, 21 insertions(+), 158 deletions(-) delete mode 100644 lib/provider/palette_provider.dart delete mode 100644 lib/themes/theme.dart diff --git a/lib/main.dart b/lib/main.dart index bbf161c5..e0b6e370 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -133,10 +133,6 @@ class Spotube extends HookConsumerWidget { final locale = ref.watch(userPreferencesProvider.select((s) => s.locale)); final accentMaterialColor = ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme)); - // final isAmoledTheme = - // ref.watch(userPreferencesProvider.select((s) => s.amoledDarkTheme)); - // final paletteColor = - // ref.watch(paletteProvider.select((s) => s?.dominantColor?.color)); final router = ref.watch(routerProvider); final hasTouchSupport = useHasTouch(); @@ -166,19 +162,6 @@ class Spotube extends HookConsumerWidget { }; }, []); - // final lightTheme = useMemoized( - // () => theme(paletteColor ?? accentMaterialColor, Brightness.light, false), - // [paletteColor, accentMaterialColor], - // ); - // final darkTheme = useMemoized( - // () => theme( - // paletteColor ?? accentMaterialColor, - // Brightness.dark, - // isAmoledTheme, - // ), - // [paletteColor, accentMaterialColor, isAmoledTheme], - // ); - return ShadcnApp.router( supportedLocales: L10n.all, locale: locale.languageCode == "system" ? null : locale, diff --git a/lib/pages/settings/sections/appearance.dart b/lib/pages/settings/sections/appearance.dart index 55a8f1ef..88f39a25 100644 --- a/lib/pages/settings/sections/appearance.dart +++ b/lib/pages/settings/sections/appearance.dart @@ -79,14 +79,14 @@ class SettingsAppearanceSection extends HookConsumerWidget { } }, ), - ListTile( - leading: const Icon(SpotubeIcons.amoled), - title: Text(context.l10n.use_amoled_mode), - subtitle: Text(context.l10n.pitch_dark_theme), - trailing: Switch( - value: preferences.amoledDarkTheme, - onChanged: preferencesNotifier.setAmoledDarkTheme, - )), + // ListTile( + // leading: const Icon(SpotubeIcons.amoled), + // title: Text(context.l10n.use_amoled_mode), + // subtitle: Text(context.l10n.pitch_dark_theme), + // trailing: Switch( + // value: preferences.amoledDarkTheme, + // onChanged: preferencesNotifier.setAmoledDarkTheme, + // )), ListTile( leading: const Icon(SpotubeIcons.palette), title: Text(context.l10n.accent_color), @@ -102,14 +102,14 @@ class SettingsAppearanceSection extends HookConsumerWidget { ), onTap: pickColorScheme(), ), - ListTile( - leading: const Icon(SpotubeIcons.colorSync), - title: Text(context.l10n.sync_album_color), - subtitle: Text(context.l10n.sync_album_color_description), - trailing: Switch( - value: preferences.albumColorSync, - onChanged: preferencesNotifier.setAlbumColorSync, - )), + // ListTile( + // leading: const Icon(SpotubeIcons.colorSync), + // title: Text(context.l10n.sync_album_color), + // subtitle: Text(context.l10n.sync_album_color_description), + // trailing: Switch( + // value: preferences.albumColorSync, + // onChanged: preferencesNotifier.setAlbumColorSync, + // )), ]; if (isGettingStarted) { diff --git a/lib/provider/audio_player/audio_player_streams.dart b/lib/provider/audio_player/audio_player_streams.dart index e52b6109..880f643f 100644 --- a/lib/provider/audio_player/audio_player_streams.dart +++ b/lib/provider/audio_player/audio_player_streams.dart @@ -1,15 +1,11 @@ import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:palette_generator/palette_generator.dart'; -import 'package:spotube/components/image/universal_image.dart'; -import 'package:spotube/extensions/image.dart'; import 'package:spotube/models/local_track.dart'; import 'package:spotube/provider/audio_player/audio_player.dart'; import 'package:spotube/provider/audio_player/state.dart'; import 'package:spotube/provider/discord_provider.dart'; import 'package:spotube/provider/history/history.dart'; -import 'package:spotube/provider/palette_provider.dart'; import 'package:spotube/provider/skip_segments/skip_segments.dart'; import 'package:spotube/provider/scrobbler/scrobbler.dart'; import 'package:spotube/provider/server/sourced_track.dart'; @@ -48,36 +44,12 @@ class AudioPlayerStreamListeners { PlaybackHistoryActions get history => ref.read(playbackHistoryActionsProvider); - Future updatePalette() async { - final palette = ref.read(paletteProvider); - if (!preferences.albumColorSync) { - if (palette != null) ref.read(paletteProvider.notifier).state = null; - return; - } - return Future.microtask(() async { - final activeTrack = ref.read(audioPlayerProvider).activeTrack; - if (activeTrack == null) return; - - final palette = await PaletteGenerator.fromImageProvider( - UniversalImage.imageProvider( - (activeTrack.album?.images).asUrlString( - placeholder: ImagePlaceholder.albumArt, - ), - height: 50, - width: 50, - ), - ); - ref.read(paletteProvider.notifier).state = palette; - }); - } - StreamSubscription subscribeToPlaylist() { return audioPlayer.playlistStream.listen((mpvPlaylist) { try { if (audioPlayerState.activeTrack == null) return; notificationService.addTrack(audioPlayerState.activeTrack!); discord.updatePresence(audioPlayerState.activeTrack!); - updatePalette(); } catch (e, stack) { AppLogger.reportError(e, stack); } diff --git a/lib/provider/palette_provider.dart b/lib/provider/palette_provider.dart deleted file mode 100644 index 8f0e9e29..00000000 --- a/lib/provider/palette_provider.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:palette_generator/palette_generator.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; - -final paletteProvider = StateProvider((ref) => null); diff --git a/lib/provider/user_preferences/user_preferences_provider.dart b/lib/provider/user_preferences/user_preferences_provider.dart index 0f9efce1..eeb712e1 100644 --- a/lib/provider/user_preferences/user_preferences_provider.dart +++ b/lib/provider/user_preferences/user_preferences_provider.dart @@ -7,9 +7,7 @@ import 'package:shadcn_flutter/shadcn_flutter.dart' hide join; import 'package:spotify/spotify.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; -import 'package:spotube/provider/audio_player/audio_player_streams.dart'; import 'package:spotube/provider/database/database.dart'; -import 'package:spotube/provider/palette_provider.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/services/sourced_track/enums.dart'; @@ -144,11 +142,11 @@ class UserPreferencesNotifier extends Notifier { void setAlbumColorSync(bool sync) { setData(PreferencesTableCompanion(albumColorSync: Value(sync))); - if (!sync) { - ref.read(paletteProvider.notifier).state = null; - } else { - ref.read(audioPlayerStreamListenersProvider).updatePalette(); - } + // if (!sync) { + // ref.read(paletteProvider.notifier).state = null; + // } else { + // ref.read(audioPlayerStreamListenersProvider).updatePalette(); + // } } void setCheckUpdate(bool check) { diff --git a/lib/themes/theme.dart b/lib/themes/theme.dart deleted file mode 100644 index 485e5af7..00000000 --- a/lib/themes/theme.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:flutter/material.dart'; - -ThemeData theme(Color seed, Brightness brightness, bool isAmoled) { - final scheme = ColorScheme.fromSeed( - seedColor: seed, - shadow: Colors.black12, - surface: isAmoled ? Colors.black : null, - brightness: brightness, - ); - return ThemeData( - useMaterial3: true, - colorScheme: scheme, - listTileTheme: ListTileThemeData( - horizontalTitleGap: 5, - iconColor: scheme.onSurface, - ), - appBarTheme: const AppBarTheme( - surfaceTintColor: Colors.transparent, - scrolledUnderElevation: 0, - shadowColor: Colors.transparent, - elevation: 0, - ), - inputDecorationTheme: InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(15), - ), - ), - iconTheme: IconThemeData(size: 16, color: scheme.onSurface), - navigationBarTheme: const NavigationBarThemeData( - labelBehavior: NavigationDestinationLabelBehavior.alwaysHide, - height: 50, - iconTheme: WidgetStatePropertyAll( - IconThemeData(size: 18), - ), - ), - tabBarTheme: TabBarTheme( - indicatorSize: TabBarIndicatorSize.tab, - labelStyle: const TextStyle(fontWeight: FontWeight.w600), - labelColor: scheme.primary, - dividerColor: Colors.transparent, - indicator: BoxDecoration( - color: scheme.secondaryContainer, - borderRadius: BorderRadius.circular(15), - ), - ), - popupMenuTheme: PopupMenuThemeData( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - color: scheme.surface, - elevation: 4, - labelTextStyle: WidgetStatePropertyAll( - TextStyle(color: scheme.onSurface), - ), - ), - snackBarTheme: SnackBarThemeData( - behavior: SnackBarBehavior.floating, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - backgroundColor: scheme.onSurface, - contentTextStyle: TextStyle(color: scheme.surface), - ), - sliderTheme: SliderThemeData(overlayShape: SliderComponentShape.noOverlay), - searchBarTheme: SearchBarThemeData( - textStyle: const WidgetStatePropertyAll(TextStyle(fontSize: 15)), - constraints: const BoxConstraints(maxWidth: double.infinity), - padding: const WidgetStatePropertyAll(EdgeInsets.all(8)), - backgroundColor: WidgetStatePropertyAll( - Color.lerp( - scheme.surfaceContainerHighest, - scheme.surface, - brightness == Brightness.light ? .9 : .7, - ), - ), - elevation: const WidgetStatePropertyAll(0), - shape: WidgetStatePropertyAll( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - ), - scrollbarTheme: const ScrollbarThemeData( - thickness: WidgetStatePropertyAll(14), - ), - checkboxTheme: CheckboxThemeData( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), - ), - ); -} From e0760e62504de1ab28495ee7fe9cfbd630a2dd37 Mon Sep 17 00:00:00 2001 From: KRTirtho Date: Thu, 30 Jan 2025 20:36:52 +0600 Subject: [PATCH 80/81] chore: fix linux resizing blocking scrollbar --- .env.example | 1 + lib/main.dart | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 888cbe6b..35c5d563 100644 --- a/.env.example +++ b/.env.example @@ -14,3 +14,4 @@ LASTFM_API_SECRET=$LASTFM_API_SECRET RELEASE_CHANNEL=$RELEASE_CHANNEL HIDE_DONATIONS=$HIDE_DONATIONS +DISABLE_SPOTIFY_IMAGES=$DISABLE_SPOTIFY_IMAGES diff --git a/lib/main.dart b/lib/main.dart index e0b6e370..3994fd50 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -189,7 +189,10 @@ class Spotube extends HookConsumerWidget { ); if (kIsLinux) { - child = DragToResizeArea(child: child); + child = DragToResizeArea( + resizeEdgeSize: 2.5, + child: child, + ); } return child; From 6cf4ca91793b95f0ec3393f3e7c4a7d0e2197f57 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 30 Jan 2025 21:44:07 +0600 Subject: [PATCH 81/81] chore: use shadcn in all places that's using material --- lib/collections/env.dart | 4 +-- lib/collections/gradients.dart | 2 +- lib/collections/side_bar_tiles.dart | 2 +- lib/collections/spotube_icons.dart | 2 +- lib/components/animated_gradient.dart | 2 +- lib/components/framework/app_pop_scope.dart | 2 +- .../inter_scrollbar/inter_scrollbar.dart | 2 +- lib/components/links/artist_link.dart | 2 +- lib/components/links/hyper_link.dart | 2 +- lib/components/links/link_text.dart | 2 +- lib/components/shimmers/shimmer_lyrics.dart | 2 +- lib/components/spotube_page_route.dart | 2 +- lib/components/titlebar/titlebar_buttons.dart | 2 +- lib/extensions/color.dart | 2 +- lib/extensions/context.dart | 2 +- lib/extensions/theme.dart | 34 ------------------- .../use_fix_window_stretching.dart | 2 +- lib/hooks/configurators/use_has_touch.dart | 2 +- .../use_auto_scroll_controller.dart | 2 +- lib/hooks/controllers/use_package_info.dart | 2 +- lib/hooks/utils/use_breakpoint_value.dart | 2 +- lib/hooks/utils/use_brightness_value.dart | 3 +- .../utils/use_custom_status_bar_color.dart | 4 +-- lib/hooks/utils/use_palette_color.dart | 5 +-- lib/l10n/l10n.dart | 2 +- lib/models/database/database.steps.dart | 2 +- lib/modules/player/player_track_details.dart | 6 ++-- lib/pages/artist/section/footer.dart | 14 ++++---- lib/pages/artist/section/related_artists.dart | 2 +- .../mobile_login/hooks/login_callback.dart | 5 +-- lib/pages/mobile_login/mobile_login.dart | 19 ++++++----- .../no_webview_runtime_dialog.dart | 15 +++++--- lib/provider/spotify/spotify.dart | 2 +- .../audio_services/audio_services.dart | 2 +- lib/services/logger/logger.dart | 2 +- lib/services/wm_tools/wm_tools.dart | 2 +- 36 files changed, 70 insertions(+), 91 deletions(-) delete mode 100644 lib/extensions/theme.dart diff --git a/lib/collections/env.dart b/lib/collections/env.dart index eb6c5639..feb2a2db 100644 --- a/lib/collections/env.dart +++ b/lib/collections/env.dart @@ -39,9 +39,9 @@ abstract class Env { static final String _releaseChannel = _Env._releaseChannel; @EnviedField(varName: "DISABLE_SPOTIFY_IMAGES", defaultValue: "0") - static final int _disableSpotifyImages = _Env._disableSpotifyImages; + static final String _disableSpotifyImages = _Env._disableSpotifyImages; - static bool get disableSpotifyImages => _disableSpotifyImages == 1; + static bool get disableSpotifyImages => _disableSpotifyImages == "1"; static ReleaseChannel get releaseChannel => _releaseChannel == "stable" ? ReleaseChannel.stable diff --git a/lib/collections/gradients.dart b/lib/collections/gradients.dart index e861dde7..a7936ee2 100644 --- a/lib/collections/gradients.dart +++ b/lib/collections/gradients.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; const gradients = [ LinearGradient(colors: [ diff --git a/lib/collections/side_bar_tiles.dart b/lib/collections/side_bar_tiles.dart index f84bd158..f12517bb 100644 --- a/lib/collections/side_bar_tiles.dart +++ b/lib/collections/side_bar_tiles.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:spotube/pages/home/home.dart'; diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index 56192d18..b5fbe5e8 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -1,5 +1,5 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:simple_icons/simple_icons.dart'; diff --git a/lib/components/animated_gradient.dart b/lib/components/animated_gradient.dart index aaba2ff9..a9d4ef2b 100644 --- a/lib/components/animated_gradient.dart +++ b/lib/components/animated_gradient.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; class AnimateGradient extends HookWidget { diff --git a/lib/components/framework/app_pop_scope.dart b/lib/components/framework/app_pop_scope.dart index b8e35767..fe923958 100644 --- a/lib/components/framework/app_pop_scope.dart +++ b/lib/components/framework/app_pop_scope.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; /// A temporary workaround for [WillPopScope] and [PopScope] not working in GoRouter /// https://github.com/flutter/flutter/issues/140869#issuecomment-2247181468 diff --git a/lib/components/inter_scrollbar/inter_scrollbar.dart b/lib/components/inter_scrollbar/inter_scrollbar.dart index 8a86b643..415ba6da 100644 --- a/lib/components/inter_scrollbar/inter_scrollbar.dart +++ b/lib/components/inter_scrollbar/inter_scrollbar.dart @@ -1,5 +1,5 @@ import 'package:draggable_scrollbar/draggable_scrollbar.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:spotube/utils/platform.dart'; diff --git a/lib/components/links/artist_link.dart b/lib/components/links/artist_link.dart index 9f06f1b3..c6ea5c14 100644 --- a/lib/components/links/artist_link.dart +++ b/lib/components/links/artist_link.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/links/anchor_button.dart'; import 'package:spotube/extensions/context.dart'; diff --git a/lib/components/links/hyper_link.dart b/lib/components/links/hyper_link.dart index 32d715e0..647edaca 100644 --- a/lib/components/links/hyper_link.dart +++ b/lib/components/links/hyper_link.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/links/anchor_button.dart'; import 'package:url_launcher/url_launcher_string.dart'; diff --git a/lib/components/links/link_text.dart b/lib/components/links/link_text.dart index 0cab71d0..a54c8b9f 100644 --- a/lib/components/links/link_text.dart +++ b/lib/components/links/link_text.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/links/anchor_button.dart'; import 'package:spotube/utils/service_utils.dart'; diff --git a/lib/components/shimmers/shimmer_lyrics.dart b/lib/components/shimmers/shimmer_lyrics.dart index 03816202..f8d29722 100644 --- a/lib/components/shimmers/shimmer_lyrics.dart +++ b/lib/components/shimmers/shimmer_lyrics.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:gap/gap.dart'; diff --git a/lib/components/spotube_page_route.dart b/lib/components/spotube_page_route.dart index 22e4d2f1..6d152dd5 100644 --- a/lib/components/spotube_page_route.dart +++ b/lib/components/spotube_page_route.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:go_router/go_router.dart'; class SpotubePage extends MaterialPage { diff --git a/lib/components/titlebar/titlebar_buttons.dart b/lib/components/titlebar/titlebar_buttons.dart index 92c2c93d..30d88508 100644 --- a/lib/components/titlebar/titlebar_buttons.dart +++ b/lib/components/titlebar/titlebar_buttons.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; diff --git a/lib/extensions/color.dart b/lib/extensions/color.dart index 68cd8ef7..bc7d65a2 100644 --- a/lib/extensions/color.dart +++ b/lib/extensions/color.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; extension ColorAlterer on Color { Color darken(double amount) { diff --git a/lib/extensions/context.dart b/lib/extensions/context.dart index 9ca1e237..f6c5915c 100644 --- a/lib/extensions/context.dart +++ b/lib/extensions/context.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; extension AppLocale on BuildContext { diff --git a/lib/extensions/theme.dart b/lib/extensions/theme.dart deleted file mode 100644 index 22a1ce84..00000000 --- a/lib/extensions/theme.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; - -class ShimmerColorTheme extends ThemeExtension { - final Color? shimmerColor; - final Color? shimmerBackgroundColor; - - ShimmerColorTheme({ - this.shimmerBackgroundColor, - this.shimmerColor, - }); - - @override - ThemeExtension copyWith( - {Color? shimmerColor, Color? shimmerBackgroundColor}) { - return ShimmerColorTheme( - shimmerBackgroundColor: - shimmerBackgroundColor ?? this.shimmerBackgroundColor, - shimmerColor: shimmerColor ?? this.shimmerColor, - ); - } - - @override - ThemeExtension lerp( - ThemeExtension? other, double t) { - if (other is! ShimmerColorTheme) { - return this; - } - return ShimmerColorTheme( - shimmerBackgroundColor: - Color.lerp(shimmerBackgroundColor, other.shimmerBackgroundColor, t), - shimmerColor: Color.lerp(shimmerColor, other.shimmerColor, t), - ); - } -} diff --git a/lib/hooks/configurators/use_fix_window_stretching.dart b/lib/hooks/configurators/use_fix_window_stretching.dart index a6603d59..b94098ab 100644 --- a/lib/hooks/configurators/use_fix_window_stretching.dart +++ b/lib/hooks/configurators/use_fix_window_stretching.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:spotube/utils/platform.dart'; import 'package:window_manager/window_manager.dart'; diff --git a/lib/hooks/configurators/use_has_touch.dart b/lib/hooks/configurators/use_has_touch.dart index 75353f27..5ce309b8 100644 --- a/lib/hooks/configurators/use_has_touch.dart +++ b/lib/hooks/configurators/use_has_touch.dart @@ -1,5 +1,5 @@ import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:spotube/utils/platform.dart'; diff --git a/lib/hooks/controllers/use_auto_scroll_controller.dart b/lib/hooks/controllers/use_auto_scroll_controller.dart index 0c7119e4..befc4351 100644 --- a/lib/hooks/controllers/use_auto_scroll_controller.dart +++ b/lib/hooks/controllers/use_auto_scroll_controller.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; diff --git a/lib/hooks/controllers/use_package_info.dart b/lib/hooks/controllers/use_package_info.dart index b3c05665..07b53af6 100644 --- a/lib/hooks/controllers/use_package_info.dart +++ b/lib/hooks/controllers/use_package_info.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:package_info_plus/package_info_plus.dart'; diff --git a/lib/hooks/utils/use_breakpoint_value.dart b/lib/hooks/utils/use_breakpoint_value.dart index b2592124..74b2f860 100644 --- a/lib/hooks/utils/use_breakpoint_value.dart +++ b/lib/hooks/utils/use_breakpoint_value.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:spotube/extensions/constrains.dart'; diff --git a/lib/hooks/utils/use_brightness_value.dart b/lib/hooks/utils/use_brightness_value.dart index d3823b2f..64e3f27c 100644 --- a/lib/hooks/utils/use_brightness_value.dart +++ b/lib/hooks/utils/use_brightness_value.dart @@ -1,4 +1,5 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; T useBrightnessValue( diff --git a/lib/hooks/utils/use_custom_status_bar_color.dart b/lib/hooks/utils/use_custom_status_bar_color.dart index 8afc6a59..f34ae7a8 100644 --- a/lib/hooks/utils/use_custom_status_bar_color.dart +++ b/lib/hooks/utils/use_custom_status_bar_color.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -9,7 +9,7 @@ VoidCallback useCustomStatusBarColor( bool? automaticSystemUiAdjustment, }) { final context = useContext(); - final backgroundColor = Theme.of(context).scaffoldBackgroundColor; + final backgroundColor = Theme.of(context).colorScheme.background; // ignore: invalid_use_of_visible_for_testing_member final previousState = SystemChrome.latestStyle; diff --git a/lib/hooks/utils/use_palette_color.dart b/lib/hooks/utils/use_palette_color.dart index 64994d2b..c70bcf72 100644 --- a/lib/hooks/utils/use_palette_color.dart +++ b/lib/hooks/utils/use_palette_color.dart @@ -1,4 +1,5 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:palette_generator/palette_generator.dart'; @@ -6,7 +7,7 @@ import 'package:spotube/components/image/universal_image.dart'; final _paletteColorState = StateProvider( (ref) { - return PaletteColor(Colors.grey[300]!, 0); + return PaletteColor(Colors.gray[300], 0); }, ); diff --git a/lib/l10n/l10n.dart b/lib/l10n/l10n.dart index ebdc4b61..2dba8370 100644 --- a/lib/l10n/l10n.dart +++ b/lib/l10n/l10n.dart @@ -16,7 +16,7 @@ library l10n; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; class L10n { static final all = [ diff --git a/lib/models/database/database.steps.dart b/lib/models/database/database.steps.dart index 11a564c6..25bf6ad9 100644 --- a/lib/models/database/database.steps.dart +++ b/lib/models/database/database.steps.dart @@ -2,7 +2,7 @@ import 'package:drift/internal/versioned_schema.dart' as i0; import 'package:drift/drift.dart' as i1; import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/services/sourced_track/enums.dart'; diff --git a/lib/modules/player/player_track_details.dart b/lib/modules/player/player_track_details.dart index 8d3b99fa..5c13f3e8 100644 --- a/lib/modules/player/player_track_details.dart +++ b/lib/modules/player/player_track_details.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; @@ -53,14 +53,14 @@ class PlayerTrackDetails extends HookConsumerWidget { "/track/${playback.activeTrack?.id}", push: true, overflow: TextOverflow.ellipsis, - style: theme.textTheme.bodyMedium!.copyWith( + style: theme.typography.normal.copyWith( color: color, ), ), Text( playback.activeTrack?.artists?.asString() ?? "", overflow: TextOverflow.ellipsis, - style: theme.textTheme.bodySmall!.copyWith(color: color), + style: theme.typography.small.copyWith(color: color), ) ], ), diff --git a/lib/pages/artist/section/footer.dart b/lib/pages/artist/section/footer.dart index 61d9d100..0fe2ab68 100644 --- a/lib/pages/artist/section/footer.dart +++ b/lib/pages/artist/section/footer.dart @@ -1,5 +1,5 @@ import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -16,7 +16,7 @@ class ArtistPageFooter extends ConsumerWidget { @override Widget build(BuildContext context, ref) { - final ThemeData(:textTheme) = Theme.of(context); + final ThemeData(:typography) = Theme.of(context); final mediaQuery = MediaQuery.of(context); final artistImage = artist.images.asUrlString( @@ -50,7 +50,7 @@ class ArtistPageFooter extends ConsumerWidget { alignment: Alignment.center, child: RichText( text: TextSpan( - style: textTheme.bodyLarge?.copyWith( + style: typography.semiBold.copyWith( color: Colors.white, ), children: [ @@ -64,7 +64,7 @@ class ArtistPageFooter extends ConsumerWidget { ), TextSpan( text: " Wikipedia", - style: textTheme.titleLarge?.copyWith( + style: typography.large.copyWith( color: Colors.white, ), ), @@ -74,10 +74,10 @@ class ArtistPageFooter extends ConsumerWidget { ), TextSpan( text: '\n...read more at wikipedia', - style: textTheme.bodyLarge?.copyWith( - color: Colors.lightBlue[300], + style: typography.semiBold.copyWith( + color: Colors.sky[300], decoration: TextDecoration.underline, - decorationColor: Colors.lightBlue[300], + decorationColor: Colors.sky[300], ), recognizer: TapGestureRecognizer() ..onTap = () async { diff --git a/lib/pages/artist/section/related_artists.dart b/lib/pages/artist/section/related_artists.dart index 066f73fd..2db9ca94 100644 --- a/lib/pages/artist/section/related_artists.dart +++ b/lib/pages/artist/section/related_artists.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/modules/artist/artist_card.dart'; import 'package:spotube/provider/spotify/spotify.dart'; diff --git a/lib/pages/mobile_login/hooks/login_callback.dart b/lib/pages/mobile_login/hooks/login_callback.dart index 07c0210a..9979f4a5 100644 --- a/lib/pages/mobile_login/hooks/login_callback.dart +++ b/lib/pages/mobile_login/hooks/login_callback.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:desktop_webview_window/desktop_webview_window.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide join; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; @@ -28,7 +28,8 @@ Future Function() useLoginCallback(WidgetRef ref) { final exp = RegExp(r"https:\/\/accounts.spotify.com\/.+\/status"); final applicationSupportDir = await getApplicationSupportDirectory(); final userDataFolder = Directory( - join(applicationSupportDir.path, "webview_window_Webview2")); + join(applicationSupportDir.path, "webview_window_Webview2"), + ); if (!await userDataFolder.exists()) { await userDataFolder.create(); diff --git a/lib/pages/mobile_login/mobile_login.dart b/lib/pages/mobile_login/mobile_login.dart index fa818dc8..e2191586 100644 --- a/lib/pages/mobile_login/mobile_login.dart +++ b/lib/pages/mobile_login/mobile_login.dart @@ -1,7 +1,8 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotube/components/button/back_button.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/provider/authentication/authentication.dart'; @@ -17,19 +18,21 @@ class WebViewLogin extends HookConsumerWidget { if (kIsDesktop) { const Scaffold( - body: Center( + child: Center( child: Text('This feature is not available on desktop'), ), ); } return Scaffold( - appBar: const TitleBar( - leading: [BackButton(color: Colors.white)], - backgroundColor: Colors.transparent, - ), - extendBodyBehindAppBar: true, - body: InAppWebView( + headers: const [ + TitleBar( + leading: [BackButton(color: Colors.white)], + backgroundColor: Colors.transparent, + ), + ], + floatingHeader: true, + child: InAppWebView( initialSettings: InAppWebViewSettings( userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 safari/537.36", diff --git a/lib/pages/mobile_login/no_webview_runtime_dialog.dart b/lib/pages/mobile_login/no_webview_runtime_dialog.dart index a6cc5ffb..b0919e5c 100644 --- a/lib/pages/mobile_login/no_webview_runtime_dialog.dart +++ b/lib/pages/mobile_login/no_webview_runtime_dialog.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/extensions/context.dart'; import 'package:url_launcher/url_launcher_string.dart'; @@ -19,7 +19,7 @@ class NoWebviewRuntimeDialog extends StatelessWidget { }, child: Text(context.l10n.cancel), ), - FilledButton( + Button.primary( onPressed: () async { final url = switch (platform) { TargetPlatform.windows => @@ -30,8 +30,15 @@ class NoWebviewRuntimeDialog extends StatelessWidget { _ => "", }; if (url.isEmpty) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Unsupported platform')), + showToast( + context: context, + builder: (context, overlay) { + return const SurfaceCard( + child: Basic( + title: Text('Unsupported platform'), + ), + ); + }, ); } diff --git a/lib/provider/spotify/spotify.dart b/lib/provider/spotify/spotify.dart index 344116cd..d43e34cd 100644 --- a/lib/provider/spotify/spotify.dart +++ b/lib/provider/spotify/spotify.dart @@ -11,7 +11,7 @@ import 'package:spotube/provider/database/database.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:collection/collection.dart'; import 'package:dio/dio.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:intl/intl.dart'; import 'package:lrc/lrc.dart'; import 'package:package_info_plus/package_info_plus.dart'; diff --git a/lib/services/audio_services/audio_services.dart b/lib/services/audio_services/audio_services.dart index 6433707d..060a7f41 100644 --- a/lib/services/audio_services/audio_services.dart +++ b/lib/services/audio_services/audio_services.dart @@ -1,5 +1,5 @@ import 'package:audio_service/audio_service.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/env.dart'; diff --git a/lib/services/logger/logger.dart b/lib/services/logger/logger.dart index 46fc6de5..d1595930 100644 --- a/lib/services/logger/logger.dart +++ b/lib/services/logger/logger.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'dart:isolate'; import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart' hide join; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:logger/logger.dart'; import 'package:path/path.dart'; diff --git a/lib/services/wm_tools/wm_tools.dart b/lib/services/wm_tools/wm_tools.dart index 920e09b5..f60b4ac9 100644 --- a/lib/services/wm_tools/wm_tools.dart +++ b/lib/services/wm_tools/wm_tools.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/services/kv_store/kv_store.dart'; import 'package:spotube/utils/platform.dart'; import 'package:window_manager/window_manager.dart';