minor
This commit is contained in:
parent
4fdaf23a0e
commit
7797c03170
15 changed files with 236 additions and 251 deletions
|
@ -1,7 +1,4 @@
|
|||
import 'package:aves/model/settings/enums/accessibility_animations.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class Durations {
|
||||
// Flutter animations (with margin)
|
||||
|
@ -72,26 +69,6 @@ class Durations {
|
|||
static const mapIdleDebounceDelay = Duration(milliseconds: 100);
|
||||
}
|
||||
|
||||
class DurationsProvider extends StatelessWidget {
|
||||
final Widget child;
|
||||
|
||||
const DurationsProvider({
|
||||
super.key,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ProxyProvider<Settings, DurationsData>(
|
||||
update: (context, settings, __) {
|
||||
final enabled = settings.accessibilityAnimations.animate;
|
||||
return enabled ? DurationsData() : DurationsData.noAnimation();
|
||||
},
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class DurationsData {
|
||||
// common animations
|
||||
|
|
|
@ -33,6 +33,7 @@ import 'package:aves/widgets/common/basic/scaffold.dart';
|
|||
import 'package:aves/widgets/common/behaviour/route_tracker.dart';
|
||||
import 'package:aves/widgets/common/behaviour/routes.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/common/providers/durations_provider.dart';
|
||||
import 'package:aves/widgets/common/providers/highlight_info_provider.dart';
|
||||
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||
import 'package:aves/widgets/home_page.dart';
|
||||
|
@ -190,95 +191,87 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
Widget build(BuildContext context) {
|
||||
// place the settings provider above `MaterialApp`
|
||||
// so it can be used during navigation transitions
|
||||
return Provider<AppFlavor>.value(
|
||||
value: widget.flavor,
|
||||
child: ChangeNotifierProvider<Settings>.value(
|
||||
value: settings,
|
||||
child: ListenableProvider<ValueNotifier<AppMode>>.value(
|
||||
value: _appModeNotifier,
|
||||
child: Provider<CollectionSource>.value(
|
||||
value: _mediaStoreSource,
|
||||
child: Provider<TvRailController>.value(
|
||||
value: _tvRailController,
|
||||
child: DurationsProvider(
|
||||
child: HighlightInfoProvider(
|
||||
child: OverlaySupport(
|
||||
child: FutureBuilder<void>(
|
||||
future: _appSetup,
|
||||
builder: (context, snapshot) {
|
||||
final initialized = !snapshot.hasError && snapshot.connectionState == ConnectionState.done;
|
||||
if (initialized) {
|
||||
AvesApp.showSystemUI();
|
||||
}
|
||||
final home = initialized
|
||||
? _getFirstPage()
|
||||
: AvesScaffold(
|
||||
body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(),
|
||||
);
|
||||
return Selector<Settings, Tuple3<Locale?, AvesThemeBrightness, bool>>(
|
||||
selector: (context, s) => Tuple3(
|
||||
s.locale,
|
||||
s.initialized ? s.themeBrightness : SettingsDefaults.themeBrightness,
|
||||
s.initialized ? s.enableDynamicColor : SettingsDefaults.enableDynamicColor,
|
||||
),
|
||||
builder: (context, s, child) {
|
||||
final settingsLocale = s.item1;
|
||||
final themeBrightness = s.item2;
|
||||
final enableDynamicColor = s.item3;
|
||||
|
||||
Constants.updateStylesForLocale(settings.appliedLocale);
|
||||
|
||||
return FutureBuilder<CorePalette?>(
|
||||
future: _dynamicColorPaletteLoader,
|
||||
builder: (context, snapshot) {
|
||||
const defaultAccent = Themes.defaultAccent;
|
||||
Color lightAccent = defaultAccent, darkAccent = defaultAccent;
|
||||
if (enableDynamicColor) {
|
||||
// `DynamicColorBuilder` from package `dynamic_color` provides light/dark
|
||||
// palettes with a primary color from tones too dark/light (40/80),
|
||||
// so we derive the color with adjusted tones (60/70)
|
||||
final tonalPalette = snapshot.data?.primary;
|
||||
lightAccent = Color(tonalPalette?.get(60) ?? defaultAccent.value);
|
||||
darkAccent = Color(tonalPalette?.get(70) ?? defaultAccent.value);
|
||||
}
|
||||
final lightTheme = Themes.lightTheme(lightAccent, initialized);
|
||||
final darkTheme = themeBrightness == AvesThemeBrightness.black ? Themes.blackTheme(darkAccent, initialized) : Themes.darkTheme(darkAccent, initialized);
|
||||
return Shortcuts(
|
||||
shortcuts: {
|
||||
// handle Android TV remote `select` button
|
||||
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
|
||||
},
|
||||
child: MaterialApp(
|
||||
navigatorKey: AvesApp.navigatorKey,
|
||||
home: home,
|
||||
navigatorObservers: _navigatorObservers,
|
||||
builder: (context, child) => _decorateAppChild(
|
||||
context: context,
|
||||
initialized: initialized,
|
||||
child: child,
|
||||
),
|
||||
onGenerateTitle: (context) => context.l10n.appName,
|
||||
theme: lightTheme,
|
||||
darkTheme: darkTheme,
|
||||
themeMode: themeBrightness.appThemeMode,
|
||||
locale: settingsLocale,
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AvesApp.supportedLocales,
|
||||
// TODO TLAD remove custom scroll behavior when this is fixed: https://github.com/flutter/flutter/issues/82906
|
||||
scrollBehavior: StretchMaterialScrollBehavior(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
Provider<AppFlavor>.value(value: widget.flavor),
|
||||
ChangeNotifierProvider<Settings>.value(value: settings),
|
||||
ListenableProvider<ValueNotifier<AppMode>>.value(value: _appModeNotifier),
|
||||
Provider<CollectionSource>.value(value: _mediaStoreSource),
|
||||
Provider<TvRailController>.value(value: _tvRailController),
|
||||
DurationsProvider(),
|
||||
HighlightInfoProvider(),
|
||||
],
|
||||
child: OverlaySupport(
|
||||
child: FutureBuilder<void>(
|
||||
future: _appSetup,
|
||||
builder: (context, snapshot) {
|
||||
final initialized = !snapshot.hasError && snapshot.connectionState == ConnectionState.done;
|
||||
if (initialized) {
|
||||
AvesApp.showSystemUI();
|
||||
}
|
||||
final home = initialized
|
||||
? _getFirstPage()
|
||||
: AvesScaffold(
|
||||
body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(),
|
||||
);
|
||||
return Selector<Settings, Tuple3<Locale?, AvesThemeBrightness, bool>>(
|
||||
selector: (context, s) => Tuple3(
|
||||
s.locale,
|
||||
s.initialized ? s.themeBrightness : SettingsDefaults.themeBrightness,
|
||||
s.initialized ? s.enableDynamicColor : SettingsDefaults.enableDynamicColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
builder: (context, s, child) {
|
||||
final settingsLocale = s.item1;
|
||||
final themeBrightness = s.item2;
|
||||
final enableDynamicColor = s.item3;
|
||||
|
||||
Constants.updateStylesForLocale(settings.appliedLocale);
|
||||
|
||||
return FutureBuilder<CorePalette?>(
|
||||
future: _dynamicColorPaletteLoader,
|
||||
builder: (context, snapshot) {
|
||||
const defaultAccent = Themes.defaultAccent;
|
||||
Color lightAccent = defaultAccent, darkAccent = defaultAccent;
|
||||
if (enableDynamicColor) {
|
||||
// `DynamicColorBuilder` from package `dynamic_color` provides light/dark
|
||||
// palettes with a primary color from tones too dark/light (40/80),
|
||||
// so we derive the color with adjusted tones (60/70)
|
||||
final tonalPalette = snapshot.data?.primary;
|
||||
lightAccent = Color(tonalPalette?.get(60) ?? defaultAccent.value);
|
||||
darkAccent = Color(tonalPalette?.get(70) ?? defaultAccent.value);
|
||||
}
|
||||
final lightTheme = Themes.lightTheme(lightAccent, initialized);
|
||||
final darkTheme = themeBrightness == AvesThemeBrightness.black ? Themes.blackTheme(darkAccent, initialized) : Themes.darkTheme(darkAccent, initialized);
|
||||
return Shortcuts(
|
||||
shortcuts: {
|
||||
// handle Android TV remote `select` button
|
||||
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
|
||||
},
|
||||
child: MaterialApp(
|
||||
navigatorKey: AvesApp.navigatorKey,
|
||||
home: home,
|
||||
navigatorObservers: _navigatorObservers,
|
||||
builder: (context, child) => _decorateAppChild(
|
||||
context: context,
|
||||
initialized: initialized,
|
||||
child: child,
|
||||
),
|
||||
onGenerateTitle: (context) => context.l10n.appName,
|
||||
theme: lightTheme,
|
||||
darkTheme: darkTheme,
|
||||
themeMode: themeBrightness.appThemeMode,
|
||||
locale: settingsLocale,
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AvesApp.supportedLocales,
|
||||
// TODO TLAD remove custom scroll behavior when this is fixed: https://github.com/flutter/flutter/issues/82906
|
||||
scrollBehavior: StretchMaterialScrollBehavior(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -19,7 +19,7 @@ import 'package:aves/widgets/collection/draggable_thumb_label.dart';
|
|||
import 'package:aves/widgets/collection/grid/list_details_theme.dart';
|
||||
import 'package:aves/widgets/collection/grid/section_layout.dart';
|
||||
import 'package:aves/widgets/collection/grid/tile.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/scrollbar.dart';
|
||||
import 'package:aves/widgets/common/basic/insets.dart';
|
||||
import 'package:aves/widgets/common/behaviour/sloppy_scroll_physics.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
|
|
|
@ -14,7 +14,7 @@ import 'package:aves/model/source/collection_source.dart';
|
|||
import 'package:aves/services/intent_service.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/widgets/collection/collection_grid.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/notifications.dart';
|
||||
import 'package:aves/widgets/common/basic/insets.dart';
|
||||
import 'package:aves/widgets/common/basic/scaffold.dart';
|
||||
import 'package:aves/widgets/common/behaviour/pop/double_back.dart';
|
||||
|
@ -52,7 +52,7 @@ class CollectionPage extends StatefulWidget {
|
|||
class _CollectionPageState extends State<CollectionPage> {
|
||||
final List<StreamSubscription> _subscriptions = [];
|
||||
late CollectionLens _collection;
|
||||
final StreamController<DraggableScrollBarEvent> _draggableScrollBarEventStreamController = StreamController.broadcast();
|
||||
final StreamController<DraggableScrollbarEvent> _draggableScrollBarEventStreamController = StreamController.broadcast();
|
||||
final DoubleBackPopHandler _doubleBackPopHandler = DoubleBackPopHandler();
|
||||
|
||||
@override
|
||||
|
@ -146,7 +146,7 @@ class _CollectionPageState extends State<CollectionPage> {
|
|||
final canNavigate = context.select<ValueNotifier<AppMode>, bool>((v) => v.value.canNavigate);
|
||||
final showBottomNavigationBar = canNavigate && enableBottomNavigationBar;
|
||||
|
||||
return NotificationListener<DraggableScrollBarNotification>(
|
||||
return NotificationListener<DraggableScrollbarNotification>(
|
||||
onNotification: (notification) {
|
||||
_draggableScrollBarEventStreamController.add(notification.event);
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import 'package:flutter/rendering.dart';
|
||||
|
||||
class ArrowClipper extends CustomClipper<Path> {
|
||||
@override
|
||||
Path getClip(Size size) {
|
||||
final path = Path();
|
||||
path.lineTo(0.0, size.height);
|
||||
path.lineTo(size.width, size.height);
|
||||
path.lineTo(size.width, 0.0);
|
||||
path.lineTo(0.0, 0.0);
|
||||
path.close();
|
||||
|
||||
const arrowWidth = 8.0;
|
||||
final startPointX = (size.width - arrowWidth) / 2;
|
||||
var startPointY = size.height / 2 - arrowWidth / 2;
|
||||
path.moveTo(startPointX, startPointY);
|
||||
path.lineTo(startPointX + arrowWidth / 2, startPointY - arrowWidth / 2);
|
||||
path.lineTo(startPointX + arrowWidth, startPointY);
|
||||
path.lineTo(startPointX + arrowWidth, startPointY + 1.0);
|
||||
path.lineTo(startPointX + arrowWidth / 2, startPointY - arrowWidth / 2 + 1.0);
|
||||
path.lineTo(startPointX, startPointY + 1.0);
|
||||
path.close();
|
||||
|
||||
startPointY = size.height / 2 + arrowWidth / 2;
|
||||
path.moveTo(startPointX + arrowWidth, startPointY);
|
||||
path.lineTo(startPointX + arrowWidth / 2, startPointY + arrowWidth / 2);
|
||||
path.lineTo(startPointX, startPointY);
|
||||
path.lineTo(startPointX, startPointY - 1.0);
|
||||
path.lineTo(startPointX + arrowWidth / 2, startPointY + arrowWidth / 2 - 1.0);
|
||||
path.lineTo(startPointX + arrowWidth, startPointY - 1.0);
|
||||
path.close();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:flutter/widgets.dart';
|
||||
|
||||
@immutable
|
||||
class DraggableScrollbarNotification extends Notification {
|
||||
final DraggableScrollbarEvent event;
|
||||
|
||||
const DraggableScrollbarNotification(this.event);
|
||||
}
|
||||
|
||||
enum DraggableScrollbarEvent { dragStart, dragEnd }
|
|
@ -0,0 +1,30 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class ScrollLabel extends StatelessWidget {
|
||||
final Animation<double> animation;
|
||||
final Color backgroundColor;
|
||||
final Widget child;
|
||||
|
||||
const ScrollLabel({
|
||||
super.key,
|
||||
required this.child,
|
||||
required this.animation,
|
||||
required this.backgroundColor,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: Container(
|
||||
margin: const EdgeInsetsDirectional.only(end: 12.0),
|
||||
child: Material(
|
||||
elevation: 4.0,
|
||||
color: backgroundColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/notifications.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/scroll_label.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/transition.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/*
|
||||
adapted from package `draggable_scrollbar` v0.0.4:
|
||||
|
@ -109,35 +111,6 @@ class DraggableScrollbar extends StatefulWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class ScrollLabel extends StatelessWidget {
|
||||
final Animation<double> animation;
|
||||
final Color backgroundColor;
|
||||
final Widget child;
|
||||
|
||||
const ScrollLabel({
|
||||
super.key,
|
||||
required this.child,
|
||||
required this.animation,
|
||||
required this.backgroundColor,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: Container(
|
||||
margin: const EdgeInsetsDirectional.only(end: 12.0),
|
||||
child: Material(
|
||||
elevation: 4.0,
|
||||
color: backgroundColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DraggableScrollbarState extends State<DraggableScrollbar> with TickerProviderStateMixin {
|
||||
final ValueNotifier<double> _thumbOffsetNotifier = ValueNotifier(0), _viewOffsetNotifier = ValueNotifier(0);
|
||||
bool _isDragInProcess = false;
|
||||
|
@ -304,7 +277,7 @@ class _DraggableScrollbarState extends State<DraggableScrollbar> with TickerProv
|
|||
}
|
||||
|
||||
void _onVerticalDragStart() {
|
||||
const DraggableScrollBarNotification(DraggableScrollBarEvent.dragStart).dispatch(context);
|
||||
const DraggableScrollbarNotification(DraggableScrollbarEvent.dragStart).dispatch(context);
|
||||
_labelAnimationController.forward();
|
||||
_fadeoutTimer?.cancel();
|
||||
_showThumb();
|
||||
|
@ -326,7 +299,7 @@ class _DraggableScrollbarState extends State<DraggableScrollbar> with TickerProv
|
|||
}
|
||||
|
||||
void _onVerticalDragEnd() {
|
||||
const DraggableScrollBarNotification(DraggableScrollBarEvent.dragEnd).dispatch(context);
|
||||
const DraggableScrollbarNotification(DraggableScrollbarEvent.dragEnd).dispatch(context);
|
||||
_scheduleFadeout();
|
||||
setState(() => _isDragInProcess = false);
|
||||
}
|
||||
|
@ -373,79 +346,3 @@ class _DraggableScrollbarState extends State<DraggableScrollbar> with TickerProv
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
///This cut 2 lines in arrow shape
|
||||
class ArrowClipper extends CustomClipper<Path> {
|
||||
@override
|
||||
Path getClip(Size size) {
|
||||
final path = Path();
|
||||
path.lineTo(0.0, size.height);
|
||||
path.lineTo(size.width, size.height);
|
||||
path.lineTo(size.width, 0.0);
|
||||
path.lineTo(0.0, 0.0);
|
||||
path.close();
|
||||
|
||||
const arrowWidth = 8.0;
|
||||
final startPointX = (size.width - arrowWidth) / 2;
|
||||
var startPointY = size.height / 2 - arrowWidth / 2;
|
||||
path.moveTo(startPointX, startPointY);
|
||||
path.lineTo(startPointX + arrowWidth / 2, startPointY - arrowWidth / 2);
|
||||
path.lineTo(startPointX + arrowWidth, startPointY);
|
||||
path.lineTo(startPointX + arrowWidth, startPointY + 1.0);
|
||||
path.lineTo(startPointX + arrowWidth / 2, startPointY - arrowWidth / 2 + 1.0);
|
||||
path.lineTo(startPointX, startPointY + 1.0);
|
||||
path.close();
|
||||
|
||||
startPointY = size.height / 2 + arrowWidth / 2;
|
||||
path.moveTo(startPointX + arrowWidth, startPointY);
|
||||
path.lineTo(startPointX + arrowWidth / 2, startPointY + arrowWidth / 2);
|
||||
path.lineTo(startPointX, startPointY);
|
||||
path.lineTo(startPointX, startPointY - 1.0);
|
||||
path.lineTo(startPointX + arrowWidth / 2, startPointY + arrowWidth / 2 - 1.0);
|
||||
path.lineTo(startPointX + arrowWidth, startPointY - 1.0);
|
||||
path.close();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
|
||||
}
|
||||
|
||||
class SlideFadeTransition extends StatelessWidget {
|
||||
final Animation<double> animation;
|
||||
final Widget child;
|
||||
|
||||
const SlideFadeTransition({
|
||||
super.key,
|
||||
required this.animation,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedBuilder(
|
||||
animation: animation,
|
||||
builder: (context, child) => animation.value == 0.0 ? Container() : child!,
|
||||
child: SlideTransition(
|
||||
position: Tween(
|
||||
begin: Offset((context.isRtl ? -1 : 1) * .3, 0),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class DraggableScrollBarNotification extends Notification {
|
||||
final DraggableScrollBarEvent event;
|
||||
|
||||
const DraggableScrollBarNotification(this.event);
|
||||
}
|
||||
|
||||
enum DraggableScrollBarEvent { dragStart, dragEnd }
|
31
lib/widgets/common/basic/draggable_scrollbar/transition.dart
Normal file
31
lib/widgets/common/basic/draggable_scrollbar/transition.dart
Normal file
|
@ -0,0 +1,31 @@
|
|||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class SlideFadeTransition extends StatelessWidget {
|
||||
final Animation<double> animation;
|
||||
final Widget child;
|
||||
|
||||
const SlideFadeTransition({
|
||||
super.key,
|
||||
required this.animation,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedBuilder(
|
||||
animation: animation,
|
||||
builder: (context, child) => animation.value == 0.0 ? Container() : child!,
|
||||
child: SlideTransition(
|
||||
position: Tween(
|
||||
begin: Offset((context.isRtl ? -1 : 1) * .3, 0),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:aves/widgets/common/basic/draggable_scrollbar.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/arrow_clipper.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/scrollbar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const double avesScrollThumbHeight = 48;
|
||||
|
|
16
lib/widgets/common/providers/durations_provider.dart
Normal file
16
lib/widgets/common/providers/durations_provider.dart
Normal file
|
@ -0,0 +1,16 @@
|
|||
import 'package:aves/model/settings/enums/accessibility_animations.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class DurationsProvider extends ProxyProvider<Settings, DurationsData> {
|
||||
DurationsProvider({
|
||||
super.key,
|
||||
super.child,
|
||||
}) : super(
|
||||
update: (context, settings, __) {
|
||||
final enabled = settings.accessibilityAnimations.animate;
|
||||
return enabled ? DurationsData() : DurationsData.noAnimation();
|
||||
},
|
||||
);
|
||||
}
|
|
@ -1,20 +1,11 @@
|
|||
import 'package:aves/model/highlight.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class HighlightInfoProvider extends StatelessWidget {
|
||||
final Widget child;
|
||||
|
||||
const HighlightInfoProvider({
|
||||
class HighlightInfoProvider extends ChangeNotifierProvider<HighlightInfo> {
|
||||
HighlightInfoProvider({
|
||||
super.key,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider<HighlightInfo>(
|
||||
create: (context) => HighlightInfo(),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
super.child,
|
||||
}) : super(
|
||||
create: (context) => HighlightInfo(),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ import 'package:aves/model/source/enums/enums.dart';
|
|||
import 'package:aves/model/vaults/vaults.dart';
|
||||
import 'package:aves/theme/colors.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/scrollbar.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/notifications.dart';
|
||||
import 'package:aves/widgets/common/basic/insets.dart';
|
||||
import 'package:aves/widgets/common/basic/scaffold.dart';
|
||||
import 'package:aves/widgets/common/behaviour/pop/double_back.dart';
|
||||
|
@ -61,7 +62,7 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
|
|||
final QueryTest<T> applyQuery;
|
||||
final Widget Function() emptyBuilder;
|
||||
final HeroType heroType;
|
||||
final StreamController<DraggableScrollBarEvent> _draggableScrollBarEventStreamController = StreamController.broadcast();
|
||||
final StreamController<DraggableScrollbarEvent> _draggableScrollBarEventStreamController = StreamController.broadcast();
|
||||
|
||||
FilterGridPage({
|
||||
super.key,
|
||||
|
@ -145,7 +146,7 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
|
|||
final canNavigate = context.select<ValueNotifier<AppMode>, bool>((v) => v.value.canNavigate);
|
||||
final showBottomNavigationBar = canNavigate && enableBottomNavigationBar;
|
||||
|
||||
return NotificationListener<DraggableScrollBarNotification>(
|
||||
return NotificationListener<DraggableScrollbarNotification>(
|
||||
onNotification: (notification) {
|
||||
_draggableScrollBarEventStreamController.add(notification.event);
|
||||
return false;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/notifications.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FloatingNavBar extends StatefulWidget {
|
||||
final ScrollController? scrollController;
|
||||
final Stream<DraggableScrollBarEvent> events;
|
||||
final Stream<DraggableScrollbarEvent> events;
|
||||
final double childHeight;
|
||||
final Widget child;
|
||||
|
||||
|
@ -109,12 +109,12 @@ class _FloatingNavBarState extends State<FloatingNavBar> with SingleTickerProvid
|
|||
}
|
||||
}
|
||||
|
||||
void _onDraggableScrollBarEvent(DraggableScrollBarEvent event) {
|
||||
void _onDraggableScrollBarEvent(DraggableScrollbarEvent event) {
|
||||
switch (event) {
|
||||
case DraggableScrollBarEvent.dragStart:
|
||||
case DraggableScrollbarEvent.dragStart:
|
||||
_isDragging = true;
|
||||
break;
|
||||
case DraggableScrollBarEvent.dragEnd:
|
||||
case DraggableScrollbarEvent.dragEnd:
|
||||
_isDragging = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:aves/model/settings/settings.dart';
|
|||
import 'package:aves/model/source/collection_lens.dart';
|
||||
import 'package:aves/model/source/collection_source.dart';
|
||||
import 'package:aves/widgets/collection/collection_page.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar.dart';
|
||||
import 'package:aves/widgets/common/basic/draggable_scrollbar/notifications.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/common/extensions/media_query.dart';
|
||||
import 'package:aves/widgets/common/identity/aves_app_bar.dart';
|
||||
|
@ -17,7 +17,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
|
||||
class AppBottomNavBar extends StatefulWidget {
|
||||
final Stream<DraggableScrollBarEvent> events;
|
||||
final Stream<DraggableScrollbarEvent> events;
|
||||
|
||||
// collection loaded in the `CollectionPage`, if any
|
||||
final CollectionLens? currentCollection;
|
||||
|
|
Loading…
Reference in a new issue