diff --git a/lib/api/library_provider.dart b/lib/api/library_provider.dart index 62c79d8..0903015 100644 --- a/lib/api/library_provider.dart +++ b/lib/api/library_provider.dart @@ -26,7 +26,7 @@ Future library(Ref ref, String id) async { _logger.warning('No library found in the list of libraries'); return null; } - _logger.fine('Fetched library: $library'); + _logger.fine('Fetched library: ${library}'); return library.library; } diff --git a/lib/api/library_provider.g.dart b/lib/api/library_provider.g.dart index a8bc88a..8f22251 100644 --- a/lib/api/library_provider.g.dart +++ b/lib/api/library_provider.g.dart @@ -6,7 +6,7 @@ part of 'library_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$libraryHash() => r'f8a34100acb58f02fa958c71a629577bf815710e'; +String _$libraryHash() => r'b62d976f8ab83b2f5823a0fb7dac52fde8fcbffc'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/features/item_viewer/view/library_item_page.dart b/lib/features/item_viewer/view/library_item_page.dart index e7b9310..53db17e 100644 --- a/lib/features/item_viewer/view/library_item_page.dart +++ b/lib/features/item_viewer/view/library_item_page.dart @@ -3,7 +3,6 @@ import 'dart:math'; import 'package:animated_theme_switcher/animated_theme_switcher.dart'; import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:vaani/api/library_item_provider.dart'; import 'package:vaani/features/item_viewer/view/library_item_sliver_app_bar.dart'; @@ -24,89 +23,19 @@ class LibraryItemPage extends HookConsumerWidget { final String itemId; final Object? extra; - static const double _showFabThreshold = 300.0; @override Widget build(BuildContext context, WidgetRef ref) { final additionalItemData = extra is LibraryItemExtras ? extra as LibraryItemExtras : null; - final scrollController = useScrollController(); - final showFab = useState(false); - - // Effect to listen to scroll changes and update FAB visibility - useEffect( - () { - void listener() { - if (!scrollController.hasClients) { - return; // Ensure controller is attached - } - final shouldShow = scrollController.offset > _showFabThreshold; - // Update state only if it changes and widget is still mounted - if (showFab.value != shouldShow && context.mounted) { - showFab.value = shouldShow; - } - } - - scrollController.addListener(listener); - // Initial check in case the view starts scrolled (less likely but safe) - WidgetsBinding.instance.addPostFrameCallback((_) { - if (scrollController.hasClients && context.mounted) { - listener(); - } - }); - - // Cleanup: remove the listener when the widget is disposed - return () => scrollController.removeListener(listener); - }, - [scrollController], - ); // Re-run effect if scrollController changes - - // --- FAB Scroll-to-Top Logic --- - void scrollToTop() { - if (scrollController.hasClients) { - scrollController.animateTo( - 0.0, // Target offset (top) - duration: 300.ms, - curve: Curves.easeInOut, - ); - } - } return ThemeProvider( initTheme: Theme.of(context), duration: 200.ms, child: ThemeSwitchingArea( child: Scaffold( - floatingActionButton: AnimatedSwitcher( - duration: 250.ms, - // A common transition for FABs (fade + scale) - transitionBuilder: (Widget child, Animation animation) { - return ScaleTransition( - scale: animation, - child: FadeTransition( - opacity: animation, - child: child, - ), - ); - }, - child: showFab.value - ? FloatingActionButton( - // Key is important for AnimatedSwitcher to differentiate - key: const ValueKey('fab-scroll-top'), - onPressed: scrollToTop, - tooltip: 'Scroll to top', - child: const Icon(Icons.arrow_upward), - ) - : const SizedBox.shrink( - key: ValueKey('fab-empty'), - ), - ), body: CustomScrollView( - controller: scrollController, slivers: [ - LibraryItemSliverAppBar( - id: itemId, - scrollController: scrollController, - ), + const LibraryItemSliverAppBar(), SliverPadding( padding: const EdgeInsets.all(8), sliver: LibraryItemHeroSection( diff --git a/lib/features/item_viewer/view/library_item_sliver_app_bar.dart b/lib/features/item_viewer/view/library_item_sliver_app_bar.dart index fd6b621..ef133ee 100644 --- a/lib/features/item_viewer/view/library_item_sliver_app_bar.dart +++ b/lib/features/item_viewer/view/library_item_sliver_app_bar.dart @@ -1,80 +1,22 @@ import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:vaani/api/library_item_provider.dart' show libraryItemProvider; -class LibraryItemSliverAppBar extends HookConsumerWidget { +class LibraryItemSliverAppBar extends StatelessWidget { const LibraryItemSliverAppBar({ super.key, - required this.id, - required this.scrollController, }); - final String id; - final ScrollController scrollController; - - static const double _showTitleThreshold = kToolbarHeight * 0.5; - @override - Widget build(BuildContext context, WidgetRef ref) { - final item = ref.watch(libraryItemProvider(id)).valueOrNull; - - final showTitle = useState(false); - - useEffect( - () { - void listener() { - final shouldShow = scrollController.hasClients && - scrollController.offset > _showTitleThreshold; - if (showTitle.value != shouldShow) { - showTitle.value = shouldShow; - } - } - - scrollController.addListener(listener); - // Trigger listener once initially in case the view starts scrolled - // (though unlikely for this specific use case, it's good practice) - WidgetsBinding.instance.addPostFrameCallback((_) { - if (scrollController.hasClients) { - listener(); - } - }); - return () => scrollController.removeListener(listener); - }, - [scrollController], - ); - + Widget build(BuildContext context) { return SliverAppBar( elevation: 0, - floating: false, - pinned: true, + floating: true, primary: true, + snap: true, actions: [ - // IconButton( - // icon: const Icon(Icons.cast), - // onPressed: () { - // // Handle search action - // }, - // ), + // cast button + IconButton(onPressed: () {}, icon: const Icon(Icons.cast)), + IconButton(onPressed: () {}, icon: const Icon(Icons.more_vert)), ], - title: AnimatedSwitcher( - duration: const Duration(milliseconds: 150), - child: showTitle.value - ? Text( - // Use a Key to help AnimatedSwitcher differentiate widgets - key: const ValueKey('title-text'), - item?.media.metadata.title ?? '', - overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.bodyMedium, - ) - : const SizedBox( - // Also give it a key for differentiation - key: ValueKey('empty-title'), - width: 0, // Ensure it takes no space if possible - height: 0, - ), - ), - centerTitle: false, ); } } diff --git a/lib/features/you/view/widgets/library_switch_chip.dart b/lib/features/you/view/widgets/library_switch_chip.dart index a673332..1463b8f 100644 --- a/lib/features/you/view/widgets/library_switch_chip.dart +++ b/lib/features/you/view/widgets/library_switch_chip.dart @@ -204,8 +204,7 @@ class _LibrarySelectionContent extends ConsumerWidget { trailing: isSelected ? const Icon(Icons.check) : null, onTap: () { appLogger.info( - 'Selected library: ${library.name} (ID: ${library.id})', - ); + 'Selected library: ${library.name} (ID: ${library.id})'); // Get current settings state final currentSettings = ref.read(apiSettingsProvider); // Update the active library ID