mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2026-02-16 06:19:35 +00:00
123
This commit is contained in:
parent
edd5a01482
commit
eef72c6aa6
13 changed files with 1341 additions and 1012 deletions
|
|
@ -1,6 +1,5 @@
|
|||
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';
|
||||
|
|
@ -8,9 +7,11 @@ 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';
|
||||
import 'package:vaani/features/player/view/mini_player_bottom_padding.dart';
|
||||
import 'package:vaani/features/settings/app_settings_provider.dart';
|
||||
import 'package:vaani/generated/l10n.dart';
|
||||
import 'package:vaani/router/models/library_item_extras.dart';
|
||||
import 'package:vaani/shared/widgets/expandable_description.dart';
|
||||
import 'package:vaani/theme/providers/system_theme_provider.dart';
|
||||
|
||||
import 'library_item_actions.dart';
|
||||
import 'library_item_hero_section.dart';
|
||||
|
|
@ -32,6 +33,23 @@ class LibraryItemPage extends HookConsumerWidget {
|
|||
extra is LibraryItemExtras ? extra as LibraryItemExtras : null;
|
||||
final scrollController = useScrollController();
|
||||
final showFab = useState(false);
|
||||
final themeSettings =
|
||||
ref.watch(appSettingsProvider.select((v) => v.themeSettings));
|
||||
|
||||
var currentTheme = Theme.of(context);
|
||||
if (themeSettings.useMaterialThemeOnItemPage) {
|
||||
final theme = ref.watch(
|
||||
CurrentThemeProvider(
|
||||
highContrast: MediaQuery.of(context).highContrast,
|
||||
id: itemId,
|
||||
),
|
||||
);
|
||||
if (currentTheme.brightness == Brightness.dark) {
|
||||
currentTheme = theme.$2;
|
||||
} else {
|
||||
currentTheme = theme.$1;
|
||||
}
|
||||
}
|
||||
|
||||
// Effect to listen to scroll changes and update FAB visibility
|
||||
useEffect(
|
||||
|
|
@ -72,65 +90,62 @@ class LibraryItemPage extends HookConsumerWidget {
|
|||
}
|
||||
}
|
||||
|
||||
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<double> animation) {
|
||||
return ScaleTransition(
|
||||
scale: animation,
|
||||
child: FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
return Theme(
|
||||
data: currentTheme,
|
||||
child: Scaffold(
|
||||
floatingActionButton: AnimatedSwitcher(
|
||||
duration: 250.ms,
|
||||
// A common transition for FABs (fade + scale)
|
||||
transitionBuilder: (Widget child, Animation<double> 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'),
|
||||
),
|
||||
);
|
||||
},
|
||||
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,
|
||||
),
|
||||
body: CustomScrollView(
|
||||
controller: scrollController,
|
||||
slivers: [
|
||||
LibraryItemSliverAppBar(
|
||||
id: itemId,
|
||||
scrollController: scrollController,
|
||||
),
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
sliver: LibraryItemHeroSection(
|
||||
itemId: itemId,
|
||||
extraMap: additionalItemData,
|
||||
),
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
sliver: LibraryItemHeroSection(
|
||||
itemId: itemId,
|
||||
extraMap: additionalItemData,
|
||||
),
|
||||
),
|
||||
// a horizontal display with dividers of metadata
|
||||
SliverToBoxAdapter(
|
||||
child: LibraryItemMetadata(id: itemId),
|
||||
),
|
||||
// a row of actions like play, download, share, etc
|
||||
SliverToBoxAdapter(
|
||||
child: LibraryItemActions(id: itemId),
|
||||
),
|
||||
// a expandable section for book description
|
||||
SliverToBoxAdapter(
|
||||
child: LibraryItemDescription(id: itemId),
|
||||
),
|
||||
// a padding at the bottom to make sure the last item is not hidden by mini player
|
||||
const SliverToBoxAdapter(child: MiniPlayerBottomPadding()),
|
||||
],
|
||||
),
|
||||
),
|
||||
// a horizontal display with dividers of metadata
|
||||
SliverToBoxAdapter(
|
||||
child: LibraryItemMetadata(id: itemId),
|
||||
),
|
||||
// a row of actions like play, download, share, etc
|
||||
SliverToBoxAdapter(
|
||||
child: LibraryItemActions(id: itemId),
|
||||
),
|
||||
// a expandable section for book description
|
||||
SliverToBoxAdapter(
|
||||
child: LibraryItemDescription(id: itemId),
|
||||
),
|
||||
// a padding at the bottom to make sure the last item is not hidden by mini player
|
||||
const SliverToBoxAdapter(child: MiniPlayerBottomPadding()),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'dart:math';
|
|||
|
||||
import 'package:audio_video_progress_bar/audio_video_progress_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:shelfsdk/audiobookshelf_api.dart';
|
||||
import 'package:vaani/constants/sizes.dart';
|
||||
|
|
@ -29,6 +30,7 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
// final textTheme = Theme.of(context).textTheme;
|
||||
final book = ref.watch(currentBookProvider);
|
||||
if (book == null) {
|
||||
return SizedBox.shrink();
|
||||
|
|
@ -116,7 +118,16 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
|
|||
timeLabelLocation: TimeLabelLocation.sides,
|
||||
),
|
||||
),
|
||||
Container(child: _buildBottom()),
|
||||
MouseRegion(
|
||||
cursor: SystemMouseCursors.click, // 桌面端显示手型光标
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
context.pop();
|
||||
},
|
||||
child: _buildBottom(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
@ -125,11 +136,15 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
|
|||
|
||||
Widget _buildBottom() {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Spacer(),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Row(),
|
||||
),
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const AudiobookPlayerSeekChapterButton(isForward: false),
|
||||
const AudiobookPlayerSeekButton(isForward: false),
|
||||
|
|
@ -141,6 +156,7 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_settings_ui/flutter_settings_ui.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:vaani/generated/l10n.dart';
|
||||
import 'package:vaani/features/settings/app_settings_provider.dart';
|
||||
import 'package:vaani/features/settings/view/buttons.dart';
|
||||
import 'package:vaani/features/settings/view/simple_settings_page.dart';
|
||||
import 'package:vaani/generated/l10n.dart';
|
||||
import 'package:vaani/globals.dart';
|
||||
import 'package:vaani/shared/extensions/duration_format.dart';
|
||||
|
||||
class DownloadSettingsPage extends HookConsumerWidget {
|
||||
const DownloadSettingsPage({
|
||||
|
|
@ -22,7 +21,7 @@ class DownloadSettingsPage extends HookConsumerWidget {
|
|||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final appSettings = ref.watch(appSettingsProvider);
|
||||
final downloadSettings = appSettings.downloadSettings;
|
||||
final primaryColor = Theme.of(context).colorScheme.primary;
|
||||
// final primaryColor = Theme.of(context).colorScheme.primary;
|
||||
|
||||
return SimpleSettingsPage(
|
||||
title: Text(S.of(context).playerSettings),
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
if (newSpeedOptions != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
appSettings.copyWith.playerSettings(
|
||||
speedOptions: newSpeedOptions..sort(),
|
||||
speedOptions: [...newSpeedOptions]..sort(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_settings_ui/flutter_settings_ui.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:vaani/features/player/view/mini_player_bottom_padding.dart';
|
||||
|
||||
class SimpleSettingsPage extends HookConsumerWidget {
|
||||
const SimpleSettingsPage({
|
||||
|
|
@ -15,30 +14,43 @@ class SimpleSettingsPage extends HookConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
// appBar: AppBar(
|
||||
// title: title,
|
||||
// ),
|
||||
appBar: AppBar(
|
||||
title: title,
|
||||
),
|
||||
// body: body,
|
||||
// an app bar which is bigger than the default app bar but on scroll shrinks to the default app bar with the title being animated
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
expandedHeight: 200.0,
|
||||
floating: false,
|
||||
pinned: true,
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
title: title,
|
||||
// background: Theme.of(context).primaryColor,
|
||||
),
|
||||
),
|
||||
// SliverAppBar(
|
||||
// expandedHeight: 100.0,
|
||||
// floating: false,
|
||||
// pinned: true,
|
||||
// flexibleSpace: FlexibleSpaceBar(
|
||||
// title: title,
|
||||
// // background: Theme.of(context).primaryColor,
|
||||
// ),
|
||||
// ),
|
||||
if (sections != null)
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||
// borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||
child: SettingsList(
|
||||
lightTheme: SettingsThemeData(
|
||||
settingsListBackground: colorScheme.surface,
|
||||
settingsSectionBackground: colorScheme.surfaceContainer,
|
||||
// inactiveTitleColor:
|
||||
// trailingTextColor: colorScheme.primary,
|
||||
// settingsTileTextColor:
|
||||
),
|
||||
darkTheme: SettingsThemeData(
|
||||
settingsListBackground: colorScheme.surface,
|
||||
settingsSectionBackground: colorScheme.surfaceContainer,
|
||||
),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
sections: sections!,
|
||||
|
|
@ -48,7 +60,7 @@ class SimpleSettingsPage extends HookConsumerWidget {
|
|||
),
|
||||
),
|
||||
// some padding at the bottom
|
||||
const SliverPadding(padding: EdgeInsets.only(bottom: 20)),
|
||||
// const SliverPadding(padding: EdgeInsets.only(bottom: 20)),
|
||||
// SliverToBoxAdapter(child: MiniPlayerBottomPadding()),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue