diff --git a/assets/fonts/AbsIcons.ttf b/assets/fonts/AbsIcons.ttf deleted file mode 100644 index 6f970dc..0000000 Binary files a/assets/fonts/AbsIcons.ttf and /dev/null differ diff --git a/docs/images_and_logos.md b/docs/images_and_logos.md deleted file mode 100644 index 55dd562..0000000 --- a/docs/images_and_logos.md +++ /dev/null @@ -1,8 +0,0 @@ -this is how i converted my png to svg - -`convert -background White vaani_logo.png vaani_logo.pbm` - - -`potrace -b svg -i vaani_logo.pbm -o vaani_logo.svg` - -`-i` flag was needed so that it took white as the svgs and black as background \ No newline at end of file diff --git a/images/vaani_logo.svg b/images/vaani_logo.svg deleted file mode 100644 index 6c79c5a..0000000 --- a/images/vaani_logo.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Created by potrace 1.16, written by Peter Selinger 2001-2019 - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib/api/api_provider.dart b/lib/api/api_provider.dart index a991727..0b11499 100644 --- a/lib/api/api_provider.dart +++ b/lib/api/api_provider.dart @@ -49,7 +49,8 @@ AudiobookshelfApi audiobookshelfApi(Ref ref, Uri? baseUrl) { /// if the user is not authenticated throw an error @Riverpod(keepAlive: true) AudiobookshelfApi authenticatedApi(Ref ref) { - final user = ref.watch(apiSettingsProvider.select((s) => s.activeUser)); + final apiSettings = ref.watch(apiSettingsProvider); + final user = apiSettings.activeUser; if (user == null) { _logger.severe('No active user can not provide authenticated api'); throw StateError('No active user'); diff --git a/lib/api/api_provider.g.dart b/lib/api/api_provider.g.dart index 619a729..23c630c 100644 --- a/lib/api/api_provider.g.dart +++ b/lib/api/api_provider.g.dart @@ -170,7 +170,7 @@ class _AudiobookshelfApiProviderElement Uri? get baseUrl => (origin as AudiobookshelfApiProvider).baseUrl; } -String _$authenticatedApiHash() => r'284be2c39823c20fb70035a136c430862c28fa27'; +String _$authenticatedApiHash() => r'5cf3329fe3074e3a09e266b4bae78b53e9c01220'; /// get the api instance for the authenticated user /// diff --git a/lib/api/library_provider.dart b/lib/api/library_provider.dart deleted file mode 100644 index 0903015..0000000 --- a/lib/api/library_provider.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart' show Ref; -import 'package:logging/logging.dart' show Logger; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import 'package:shelfsdk/audiobookshelf_api.dart' show Library; -import 'package:vaani/api/api_provider.dart' show authenticatedApiProvider; -import 'package:vaani/settings/api_settings_provider.dart' - show apiSettingsProvider; -part 'library_provider.g.dart'; - -final _logger = Logger('LibraryProvider'); - -@riverpod -Future library(Ref ref, String id) async { - final api = ref.watch(authenticatedApiProvider); - final library = await api.libraries.get(libraryId: id); - if (library == null) { - _logger.warning('No library found through id: $id'); - // try to get the library from the list of libraries - final libraries = await ref.watch(librariesProvider.future); - for (final lib in libraries) { - if (lib.id == id) { - return lib; - } - } - _logger.warning('No library found in the list of libraries'); - return null; - } - _logger.fine('Fetched library: ${library}'); - return library.library; -} - -@riverpod -Future currentLibrary(Ref ref) async { - final libraryId = - ref.watch(apiSettingsProvider.select((s) => s.activeLibraryId)); - if (libraryId == null) { - _logger.warning('No active library id found'); - return null; - } - return await ref.watch(libraryProvider(libraryId).future); -} - -@riverpod -class Libraries extends _$Libraries { - @override - FutureOr> build() async { - final api = ref.watch(authenticatedApiProvider); - final libraries = await api.libraries.getAll(); - if (libraries == null) { - _logger.warning('Failed to fetch libraries'); - return []; - } - _logger.fine('Fetched ${libraries.length} libraries'); - ref.keepAlive(); - return libraries; - } -} diff --git a/lib/api/library_provider.g.dart b/lib/api/library_provider.g.dart deleted file mode 100644 index 8f22251..0000000 --- a/lib/api/library_provider.g.dart +++ /dev/null @@ -1,192 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'library_provider.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$libraryHash() => r'b62d976f8ab83b2f5823a0fb7dac52fde8fcbffc'; - -/// Copied from Dart SDK -class _SystemHash { - _SystemHash._(); - - static int combine(int hash, int value) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + value); - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - static int finish(int hash) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - // ignore: parameter_assignments - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } -} - -/// See also [library]. -@ProviderFor(library) -const libraryProvider = LibraryFamily(); - -/// See also [library]. -class LibraryFamily extends Family> { - /// See also [library]. - const LibraryFamily(); - - /// See also [library]. - LibraryProvider call( - String id, - ) { - return LibraryProvider( - id, - ); - } - - @override - LibraryProvider getProviderOverride( - covariant LibraryProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'libraryProvider'; -} - -/// See also [library]. -class LibraryProvider extends AutoDisposeFutureProvider { - /// See also [library]. - LibraryProvider( - String id, - ) : this._internal( - (ref) => library( - ref as LibraryRef, - id, - ), - from: libraryProvider, - name: r'libraryProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$libraryHash, - dependencies: LibraryFamily._dependencies, - allTransitiveDependencies: LibraryFamily._allTransitiveDependencies, - id: id, - ); - - LibraryProvider._internal( - super._createNotifier, { - required super.name, - required super.dependencies, - required super.allTransitiveDependencies, - required super.debugGetCreateSourceHash, - required super.from, - required this.id, - }) : super.internal(); - - final String id; - - @override - Override overrideWith( - FutureOr Function(LibraryRef provider) create, - ) { - return ProviderOverride( - origin: this, - override: LibraryProvider._internal( - (ref) => create(ref as LibraryRef), - from: from, - name: null, - dependencies: null, - allTransitiveDependencies: null, - debugGetCreateSourceHash: null, - id: id, - ), - ); - } - - @override - AutoDisposeFutureProviderElement createElement() { - return _LibraryProviderElement(this); - } - - @override - bool operator ==(Object other) { - return other is LibraryProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -@Deprecated('Will be removed in 3.0. Use Ref instead') -// ignore: unused_element -mixin LibraryRef on AutoDisposeFutureProviderRef { - /// The parameter `id` of this provider. - String get id; -} - -class _LibraryProviderElement extends AutoDisposeFutureProviderElement - with LibraryRef { - _LibraryProviderElement(super.provider); - - @override - String get id => (origin as LibraryProvider).id; -} - -String _$currentLibraryHash() => r'658498a531e04a01e2b3915a3319101285601118'; - -/// See also [currentLibrary]. -@ProviderFor(currentLibrary) -final currentLibraryProvider = AutoDisposeFutureProvider.internal( - currentLibrary, - name: r'currentLibraryProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$currentLibraryHash, - dependencies: null, - allTransitiveDependencies: null, -); - -@Deprecated('Will be removed in 3.0. Use Ref instead') -// ignore: unused_element -typedef CurrentLibraryRef = AutoDisposeFutureProviderRef; -String _$librariesHash() => r'95ebd4d1ac0cc2acf7617dc22895eff0ca30600f'; - -/// See also [Libraries]. -@ProviderFor(Libraries) -final librariesProvider = - AutoDisposeAsyncNotifierProvider>.internal( - Libraries.new, - name: r'librariesProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$librariesHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$Libraries = AutoDisposeAsyncNotifier>; -// ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/downloads/view/downloads_page.dart b/lib/features/downloads/view/downloads_page.dart index 7c5dbfb..e8c0e9c 100644 --- a/lib/features/downloads/view/downloads_page.dart +++ b/lib/features/downloads/view/downloads_page.dart @@ -13,6 +13,7 @@ class DownloadsPage extends HookConsumerWidget { return Scaffold( appBar: AppBar( title: const Text('Downloads'), + backgroundColor: Colors.transparent, ), body: Center( // history of downloads diff --git a/lib/features/explore/view/explore_page.dart b/lib/features/explore/view/explore_page.dart index 1682254..23bb0f6 100644 --- a/lib/features/explore/view/explore_page.dart +++ b/lib/features/explore/view/explore_page.dart @@ -30,6 +30,7 @@ class ExplorePage extends HookConsumerWidget { return Scaffold( appBar: AppBar( title: const Text('Explore'), + backgroundColor: Colors.transparent, ), body: const MySearchBar(), ); 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 ef133ee..99068e2 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 @@ -8,6 +8,7 @@ class LibraryItemSliverAppBar extends StatelessWidget { @override Widget build(BuildContext context) { return SliverAppBar( + backgroundColor: Colors.transparent, elevation: 0, floating: true, primary: true, diff --git a/lib/features/library_browser/view/library_browser_page.dart b/lib/features/library_browser/view/library_browser_page.dart index 4327b17..d12de57 100644 --- a/lib/features/library_browser/view/library_browser_page.dart +++ b/lib/features/library_browser/view/library_browser_page.dart @@ -1,83 +1,47 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:vaani/api/library_provider.dart' show currentLibraryProvider; -import 'package:vaani/features/you/view/widgets/library_switch_chip.dart' - show showLibrarySwitcher; -import 'package:vaani/router/router.dart' show Routes; -import 'package:vaani/shared/icons/abs_icons.dart' show AbsIcons; -import 'package:vaani/shared/widgets/not_implemented.dart' - show showNotImplementedToast; +import 'package:vaani/router/router.dart'; class LibraryBrowserPage extends HookConsumerWidget { const LibraryBrowserPage({super.key}); + @override Widget build(BuildContext context, WidgetRef ref) { - final currentLibrary = ref.watch(currentLibraryProvider).valueOrNull; - - // Determine the icon to use, with a fallback - final IconData libraryIconData = - AbsIcons.getIconByName(currentLibrary?.icon) ?? Icons.library_books; - - // Determine the title text - final String appBarTitle = '${currentLibrary?.name ?? 'Your'} Library'; - return Scaffold( - // Use CustomScrollView to enable slivers - body: CustomScrollView( - slivers: [ - SliverAppBar( - pinned: true, - // floating: true, // Optional: uncomment if you want floating behavior - // snap: - // true, // Optional: uncomment if you want snapping behavior (usually with floating: true) - leading: IconButton( - icon: Icon(libraryIconData), - tooltip: 'Switch Library', // Helpful tooltip for users - onPressed: () { - showLibrarySwitcher(context, ref); - }, - ), - title: Text(appBarTitle), + appBar: AppBar( + title: const Text('Library'), + backgroundColor: Colors.transparent, + ), + // a list redirecting to authors, genres, and series pages + body: ListView( + children: [ + ListTile( + title: const Text('Authors'), + leading: const Icon(Icons.person), + trailing: const Icon(Icons.chevron_right), + onTap: () {}, ), - SliverList( - delegate: SliverChildListDelegate( - [ - ListTile( - title: const Text('Authors'), - leading: const Icon(Icons.person), - trailing: const Icon(Icons.chevron_right), - onTap: () { - showNotImplementedToast(context); - }, - ), - ListTile( - title: const Text('Genres'), - leading: const Icon(Icons.category), - trailing: const Icon(Icons.chevron_right), - onTap: () { - showNotImplementedToast(context); - }, - ), - ListTile( - title: const Text('Series'), - leading: const Icon(Icons.list), - trailing: const Icon(Icons.chevron_right), - onTap: () { - showNotImplementedToast(context); - }, - ), - // Downloads - ListTile( - title: const Text('Downloads'), - leading: const Icon(Icons.download), - trailing: const Icon(Icons.chevron_right), - onTap: () { - GoRouter.of(context).pushNamed(Routes.downloads.name); - }, - ), - ], - ), + ListTile( + title: const Text('Genres'), + leading: const Icon(Icons.category), + trailing: const Icon(Icons.chevron_right), + onTap: () {}, + ), + ListTile( + title: const Text('Series'), + leading: const Icon(Icons.list), + trailing: const Icon(Icons.chevron_right), + onTap: () {}, + ), + // Downloads + ListTile( + title: const Text('Downloads'), + leading: const Icon(Icons.download), + trailing: const Icon(Icons.chevron_right), + onTap: () { + GoRouter.of(context).pushNamed(Routes.downloads.name); + }, ), ], ), diff --git a/lib/features/logging/view/logs_page.dart b/lib/features/logging/view/logs_page.dart index 74d1ad3..ad2c764 100644 --- a/lib/features/logging/view/logs_page.dart +++ b/lib/features/logging/view/logs_page.dart @@ -1,10 +1,15 @@ +import 'dart:io'; + +import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:logging/logging.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:share_plus/share_plus.dart'; import 'package:vaani/features/logging/providers/logs_provider.dart'; import 'package:vaani/main.dart'; +import 'package:vaani/settings/metadata/metadata_provider.dart'; class LogsPage extends HookConsumerWidget { const LogsPage({super.key}); diff --git a/lib/features/you/view/widgets/library_switch_chip.dart b/lib/features/you/view/widgets/library_switch_chip.dart deleted file mode 100644 index 1463b8f..0000000 --- a/lib/features/you/view/widgets/library_switch_chip.dart +++ /dev/null @@ -1,224 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:shelfsdk/audiobookshelf_api.dart' show Library; -import 'package:vaani/api/library_provider.dart'; -import 'package:vaani/settings/api_settings_provider.dart' - show apiSettingsProvider; -import 'package:vaani/shared/icons/abs_icons.dart'; -import 'dart:io' show Platform; - -import 'package:flutter/foundation.dart'; -import 'package:vaani/main.dart' show appLogger; - -class LibrarySwitchChip extends HookConsumerWidget { - const LibrarySwitchChip({ - super.key, - required this.libraries, - }); - final List libraries; - - @override - Widget build(BuildContext context, WidgetRef ref) { - final apiSettings = ref.watch(apiSettingsProvider); - - return ActionChip( - avatar: Icon( - AbsIcons.getIconByName( - apiSettings.activeLibraryId != null - ? libraries - .firstWhere( - (lib) => lib.id == apiSettings.activeLibraryId, - ) - .icon - : libraries.first.icon, - ), - ), // Replace with your icon - label: const Text('Change Library'), - // Enable only if libraries are loaded and not empty - onPressed: libraries.isNotEmpty - ? () => showLibrarySwitcher( - context, - ref, - ) - : null, // Disable if no libraries - ); - } -} - -// --- Helper Function to Show the Switcher --- -void showLibrarySwitcher( - BuildContext context, - WidgetRef ref, -) { - final content = _LibrarySelectionContent(); - - // --- Platform-Specific UI --- - bool isDesktop = false; - if (!kIsWeb) { - // dart:io Platform is not available on web - isDesktop = Platform.isLinux || Platform.isMacOS || Platform.isWindows; - } else { - // Basic web detection (might need refinement based on screen size) - // Consider using MediaQuery for a size-based check instead for web/tablet - final size = MediaQuery.of(context).size; - isDesktop = size.width > 600; // Example threshold for "desktop-like" layout - } - - if (isDesktop) { - // --- Desktop: Use AlertDialog --- - showDialog( - context: context, - builder: (dialogContext) => AlertDialog( - title: const Text('Select Library'), - content: SizedBox( - // Constrain size for dialogs - width: 300, // Adjust as needed - // Make content scrollable if list is long - child: Scrollbar(child: content), - ), - actions: [ - TextButton( - onPressed: () { - // Invalidate the provider to trigger a refetch - ref.invalidate(librariesProvider); - Navigator.pop(dialogContext); - }, - child: const Text('Refresh'), - ), - TextButton( - onPressed: () => Navigator.pop(dialogContext), - child: const Text('Cancel'), - ), - ], - ), - ); - } else { - // --- Mobile/Tablet: Use BottomSheet --- - showModalBottomSheet( - context: context, - // Make it scrollable and control height - isScrollControlled: true, - constraints: BoxConstraints( - maxHeight: - MediaQuery.of(context).size.height * 0.6, // Max 60% of screen - ), - builder: (sheetContext) => Padding( - // Add padding within the bottom sheet - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, // Take minimum necessary height - children: [ - const Text( - 'Select Library', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - const SizedBox(height: 10), - const Divider(), - Flexible( - // Allow the list to take remaining space and scroll - child: Scrollbar(child: content), - ), - const SizedBox(height: 10), - ElevatedButton.icon( - icon: const Icon(Icons.refresh), - label: const Text('Refresh'), - onPressed: () { - // Invalidate the provider to trigger a refetch - ref.invalidate(librariesProvider); - }, - ), - ], - ), - ), - ); - } -} - -// --- Widget for the Selection List Content (Reusable) --- -class _LibrarySelectionContent extends ConsumerWidget { - @override - Widget build(BuildContext context, WidgetRef ref) { - final librariesAsyncValue = ref.watch(librariesProvider); - final currentLibraryId = ref.watch( - apiSettingsProvider.select((settings) => settings.activeLibraryId), - ); - final errorColor = Theme.of(context).colorScheme.error; - return librariesAsyncValue.when( - // --- Loading State --- - loading: () => const Center(child: CircularProgressIndicator()), - - // --- Error State --- - error: (error, stackTrace) => Center( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(Icons.error_outline, color: errorColor), - const SizedBox(height: 10), - Text( - 'Error loading libraries: $error', - textAlign: TextAlign.center, - style: TextStyle(color: errorColor), - ), - const SizedBox(height: 16), - ElevatedButton.icon( - icon: const Icon(Icons.refresh), - label: const Text('Retry'), - onPressed: () { - // Invalidate the provider to trigger a refetch - ref.invalidate(librariesProvider); - }, - ), - ], - ), - ), - ), - - // --- Data State --- - data: (libraries) { - // Handle case where data loaded successfully but is empty - if (libraries.isEmpty) { - return const Center( - child: Padding( - padding: EdgeInsets.all(16.0), - child: Text('No libraries available.'), - ), - ); - } - - // Build the list if libraries are available - return Scrollbar( - // Add scrollbar for potentially long lists - child: ListView.builder( - shrinkWrap: true, // Important for Dialog/BottomSheet sizing - itemCount: libraries.length, - itemBuilder: (context, index) { - final library = libraries[index]; - final bool isSelected = library.id == currentLibraryId; - - return ListTile( - title: Text(library.name), - leading: Icon(AbsIcons.getIconByName(library.icon)), - selected: isSelected, - trailing: isSelected ? const Icon(Icons.check) : null, - onTap: () { - appLogger.info( - 'Selected library: ${library.name} (ID: ${library.id})'); - // Get current settings state - final currentSettings = ref.read(apiSettingsProvider); - // Update the active library ID - ref.read(apiSettingsProvider.notifier).updateState( - currentSettings.copyWith(activeLibraryId: library.id), - ); - // Close the dialog/bottom sheet - Navigator.pop(context); - }, - ); - }, - ), - ); - }, - ); - } -} diff --git a/lib/features/you/view/you_page.dart b/lib/features/you/view/you_page.dart index 53b33b8..c15e80f 100644 --- a/lib/features/you/view/you_page.dart +++ b/lib/features/you/view/you_page.dart @@ -2,14 +2,11 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:vaani/api/api_provider.dart'; -import 'package:vaani/api/library_provider.dart' show librariesProvider; import 'package:vaani/features/player/view/mini_player_bottom_padding.dart'; -import 'package:vaani/features/you/view/widgets/library_switch_chip.dart'; import 'package:vaani/router/router.dart'; import 'package:vaani/settings/constants.dart'; import 'package:vaani/shared/utils.dart'; import 'package:vaani/shared/widgets/not_implemented.dart'; -import 'package:vaani/shared/widgets/vaani_logo.dart'; class YouPage extends HookConsumerWidget { const YouPage({ @@ -19,10 +16,10 @@ class YouPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final api = ref.watch(authenticatedApiProvider); - final librariesAsyncValue = ref.watch(librariesProvider); return Scaffold( appBar: AppBar( // title: const Text('You'), + backgroundColor: Colors.transparent, actions: [ IconButton( tooltip: 'Logs', @@ -66,35 +63,7 @@ class YouPage extends HookConsumerWidget { context.pushNamed(Routes.userManagement.name); }, ), - librariesAsyncValue.when( - data: (libraries) => - LibrarySwitchChip(libraries: libraries), - loading: () => const ActionChip( - avatar: SizedBox( - width: 18, - height: 18, - child: CircularProgressIndicator(strokeWidth: 2), - ), - label: Text('Loading Libs...'), - onPressed: null, // Disable while loading - ), - error: (error, stack) => ActionChip( - avatar: Icon( - Icons.error_outline, - color: Theme.of(context).colorScheme.error, - ), - label: const Text('Error Loading Libs'), - onPressed: () { - // Maybe show error details or allow retry - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: - Text('Failed to load libraries: $error'), - ), - ); - }, - ), - ), // ActionChip( + // ActionChip( // avatar: const Icon(Icons.logout), // label: const Text('Logout'), // onPressed: () { @@ -216,3 +185,29 @@ class UserBar extends HookConsumerWidget { ); } } + +class VaaniLogo extends StatelessWidget { + const VaaniLogo({ + super.key, + this.size, + this.duration = const Duration(milliseconds: 750), + this.curve = Curves.fastOutSlowIn, + }); + + final double? size; + final Duration duration; + final Curve curve; + + @override + Widget build(BuildContext context) { + final IconThemeData iconTheme = IconTheme.of(context); + final double? iconSize = size ?? iconTheme.size; + return AnimatedContainer( + width: iconSize, + height: iconSize, + duration: duration, + curve: curve, + child: Image.asset('assets/images/vaani_logo_foreground.png'), + ); + } +} diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index f9b0310..682a8a4 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -19,6 +19,7 @@ class HomePage extends HookConsumerWidget { final scrollController = useScrollController(); return Scaffold( appBar: AppBar( + backgroundColor: Colors.transparent, title: GestureDetector( child: Text( 'Vaani', diff --git a/lib/router/scaffold_with_nav_bar.dart b/lib/router/scaffold_with_nav_bar.dart index 27c3355..0a89162 100644 --- a/lib/router/scaffold_with_nav_bar.dart +++ b/lib/router/scaffold_with_nav_bar.dart @@ -2,15 +2,12 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:miniplayer/miniplayer.dart'; -import 'package:vaani/api/library_provider.dart' show currentLibraryProvider; import 'package:vaani/features/explore/providers/search_controller.dart'; import 'package:vaani/features/player/providers/player_form.dart'; import 'package:vaani/features/player/view/audiobook_player.dart'; import 'package:vaani/features/player/view/player_when_expanded.dart'; -import 'package:vaani/features/you/view/widgets/library_switch_chip.dart'; import 'package:vaani/main.dart'; import 'package:vaani/router/router.dart'; -import 'package:vaani/shared/icons/abs_icons.dart' show AbsIcons; // stack to track changes in navigationShell.currentIndex // home is always at index 0 and at the start and should be the last before popping @@ -114,39 +111,17 @@ class ScaffoldWithNavBar extends HookConsumerWidget { // world scenario, the items would most likely be generated from the // branches of the shell route, which can be fetched using // `navigationShell.route.branches`. - destinations: _navigationItems.map((item) { - final isDestinationLibrary = item.name == 'Library'; - var currentLibrary = - ref.watch(currentLibraryProvider).valueOrNull; - final libraryIcon = AbsIcons.getIconByName( - currentLibrary?.icon, - ); - final destinationWidget = NavigationDestination( - icon: Icon( - isDestinationLibrary ? libraryIcon ?? item.icon : item.icon, - ), - selectedIcon: Icon( - isDestinationLibrary - ? libraryIcon ?? item.activeIcon - : item.activeIcon, - ), - label: isDestinationLibrary - ? currentLibrary?.name ?? item.name - : item.name, - tooltip: item.tooltip, - ); - if (isDestinationLibrary) { - return GestureDetector( - onSecondaryTap: () => showLibrarySwitcher(context, ref), - onDoubleTap: () => showLibrarySwitcher(context, ref), - child: - destinationWidget, // Wrap the actual NavigationDestination - ); - } else { - // Return the unwrapped destination for other items - return destinationWidget; - } - }).toList(), + destinations: _navigationItems + .map( + (item) => NavigationDestination( + icon: Icon(item.icon), + selectedIcon: item.activeIcon != null + ? Icon(item.activeIcon) + : Icon(item.icon), + label: item.name, + ), + ) + .toList(), selectedIndex: navigationShell.currentIndex, onDestinationSelected: (int index) => _onTap(context, index, ref), ), @@ -216,19 +191,16 @@ const _navigationItems = [ name: 'Library', icon: Icons.book_outlined, activeIcon: Icons.book, - tooltip: 'Browse your library', ), _NavigationItem( name: 'Explore', icon: Icons.search_outlined, activeIcon: Icons.search, - tooltip: 'Search and Explore', ), _NavigationItem( name: 'You', icon: Icons.account_circle_outlined, activeIcon: Icons.account_circle, - tooltip: 'Your Profile and Settings', ), ]; @@ -236,12 +208,10 @@ class _NavigationItem { const _NavigationItem({ required this.name, required this.icon, - required this.activeIcon, - this.tooltip, + this.activeIcon, }); final String name; final IconData icon; - final IconData activeIcon; - final String? tooltip; + final IconData? activeIcon; } diff --git a/lib/shared/icons/abs_icons.dart b/lib/shared/icons/abs_icons.dart deleted file mode 100644 index eca3e1a..0000000 --- a/lib/shared/icons/abs_icons.dart +++ /dev/null @@ -1,103 +0,0 @@ -/// Flutter icons AbsIcons -/// Copyright (C) 2025 by original authors @ fluttericon.com, fontello.com -/// This font was generated by FlutterIcon.com, which is derived from Fontello. -/// -/// To use this font, place it in your fonts/ directory and include the -/// following in your pubspec.yaml -/// -/// flutter: -/// fonts: -/// - family: AbsIcons -/// fonts: -/// - asset: fonts/AbsIcons.ttf -/// -/// -/// -library; -// ignore_for_file: constant_identifier_names - -import 'package:flutter/widgets.dart' show IconData; - -class AbsIcons { - AbsIcons._(); - - static const _kFontFam = 'AbsIcons'; - static const String? _kFontPkg = null; - - static const IconData audiobookshelf = - IconData(0xe900, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData microphone_2 = - IconData(0xe901, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData microphone_1 = - IconData(0xe902, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData radio = - IconData(0xe903, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData podcast = - IconData(0xe904, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData books_1 = - IconData(0xe905, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData database_2 = - IconData(0xe906, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData headphones = - IconData(0xe910, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData music = - IconData(0xe911, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData video = - IconData(0xe914, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData microphone_3 = - IconData(0xe91e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData book = - IconData(0xe91f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData books_2 = - IconData(0xe920, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData file_picture = - IconData(0xe927, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData database_1 = - IconData(0xe964, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData rocket = - IconData(0xe9a5, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData power = - IconData(0xe9b5, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData star = - IconData(0xe9d9, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData heart = - IconData(0xe9da, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData rss = - IconData(0xea9b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - - static final Map _iconMap = { - 'audiobookshelf': audiobookshelf, - 'microphone_2': microphone_2, - 'microphone_1': microphone_1, - 'radio': radio, - 'podcast': podcast, - 'books_1': books_1, - 'database_2': database_2, - 'headphones': headphones, - 'music': music, - 'video': video, - 'microphone_3': microphone_3, - 'book': book, - 'books_2': books_2, - 'file_picture': file_picture, - 'database_1': database_1, - 'rocket': rocket, - 'power': power, - 'star': star, - 'heart': heart, - 'rss': rss, - }; - - /// Returns the IconData corresponding to the [iconName] string. - /// - /// If the [iconName] is not found in the map, returns null. - /// Considers null or empty strings as invalid. - static IconData? getIconByName(String? iconName) { - if (iconName == null || iconName.isEmpty) { - return null; - } - return _iconMap[iconName.toLowerCase()]; - } - - static Map get iconMap => _iconMap; -} diff --git a/lib/shared/widgets/vaani_logo.dart b/lib/shared/widgets/vaani_logo.dart deleted file mode 100644 index a5b4e11..0000000 --- a/lib/shared/widgets/vaani_logo.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -class VaaniLogo extends StatelessWidget { - const VaaniLogo({ - super.key, - this.size, - this.duration = const Duration(milliseconds: 750), - this.curve = Curves.fastOutSlowIn, - }); - - final double? size; - final Duration duration; - final Curve curve; - - @override - Widget build(BuildContext context) { - final IconThemeData iconTheme = IconTheme.of(context); - final double? iconSize = size ?? iconTheme.size; - return AnimatedContainer( - width: iconSize, - height: iconSize, - duration: duration, - curve: curve, - child: Image.asset('assets/images/vaani_logo_foreground.png'), - ); - } -} diff --git a/pubspec.yaml b/pubspec.yaml index 2aafa66..e1f9c4d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -122,7 +122,6 @@ flutter: - assets/animations/ - assets/sounds/ - assets/images/ - - assets/fonts/ # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see @@ -148,7 +147,3 @@ flutter: # # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages - fonts: - - family: AbsIcons - fonts: - - asset: assets/fonts/AbsIcons.ttf diff --git a/shelfsdk b/shelfsdk index e1848a4..5cc545c 160000 --- a/shelfsdk +++ b/shelfsdk @@ -1 +1 @@ -Subproject commit e1848a42c27257146015a33e9427f197f522fe03 +Subproject commit 5cc545ca87c05615473ab9c363cfa29e341d1e2a