collection: fixed scroll thumb top padding according to app bar height
This commit is contained in:
parent
459fc24856
commit
b3fde095e9
9 changed files with 128 additions and 125 deletions
|
@ -19,6 +19,9 @@ class Constants {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ref _PopupMenuRoute._kMenuDuration
|
||||||
|
static const popupMenuTransitionDuration = Duration(milliseconds: 300);
|
||||||
|
|
||||||
// TODO TLAD smarter sizing, but shouldn't only depend on `extent` so that it doesn't reload during gridview scaling
|
// TODO TLAD smarter sizing, but shouldn't only depend on `extent` so that it doesn't reload during gridview scaling
|
||||||
static const double thumbnailCacheExtent = 50;
|
static const double thumbnailCacheExtent = 50;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:aves/model/collection_lens.dart';
|
import 'package:aves/model/collection_lens.dart';
|
||||||
import 'package:aves/model/filters/query.dart';
|
import 'package:aves/model/filters/query.dart';
|
||||||
import 'package:aves/model/settings.dart';
|
import 'package:aves/model/settings.dart';
|
||||||
|
import 'package:aves/utils/constants.dart';
|
||||||
import 'package:aves/widgets/album/collection_page.dart';
|
import 'package:aves/widgets/album/collection_page.dart';
|
||||||
import 'package:aves/widgets/album/filter_bar.dart';
|
import 'package:aves/widgets/album/filter_bar.dart';
|
||||||
import 'package:aves/widgets/album/search/search_delegate.dart';
|
import 'package:aves/widgets/album/search/search_delegate.dart';
|
||||||
|
@ -12,13 +13,17 @@ import 'package:outline_material_icons/outline_material_icons.dart';
|
||||||
import 'package:pedantic/pedantic.dart';
|
import 'package:pedantic/pedantic.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class CollectionAppBar extends StatefulWidget implements PreferredSizeWidget {
|
class CollectionAppBar extends StatefulWidget {
|
||||||
final ValueNotifier<PageState> stateNotifier;
|
final ValueNotifier<PageState> stateNotifier;
|
||||||
|
final ValueNotifier<double> appBarHeightNotifier;
|
||||||
|
final CollectionLens collection;
|
||||||
|
|
||||||
@override
|
const CollectionAppBar({
|
||||||
final Size preferredSize = Size.fromHeight(kToolbarHeight + FilterBar.preferredHeight);
|
Key key,
|
||||||
|
@required this.stateNotifier,
|
||||||
CollectionAppBar({this.stateNotifier});
|
@required this.appBarHeightNotifier,
|
||||||
|
@required this.collection,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_CollectionAppBarState createState() => _CollectionAppBarState();
|
_CollectionAppBarState createState() => _CollectionAppBarState();
|
||||||
|
@ -31,6 +36,10 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
|
|
||||||
ValueNotifier<PageState> get stateNotifier => widget.stateNotifier;
|
ValueNotifier<PageState> get stateNotifier => widget.stateNotifier;
|
||||||
|
|
||||||
|
CollectionLens get collection => widget.collection;
|
||||||
|
|
||||||
|
bool get hasFilters => collection.filters.isNotEmpty;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -39,6 +48,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
vsync: this,
|
vsync: this,
|
||||||
);
|
);
|
||||||
_registerWidget(widget);
|
_registerWidget(widget);
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) => _updateHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -56,11 +66,13 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
}
|
}
|
||||||
|
|
||||||
void _registerWidget(CollectionAppBar widget) {
|
void _registerWidget(CollectionAppBar widget) {
|
||||||
stateNotifier.addListener(_onStateChange);
|
widget.stateNotifier.addListener(_onStateChange);
|
||||||
|
widget.collection.filterChangeNotifier.addListener(_updateHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _unregisterWidget(CollectionAppBar widget) {
|
void _unregisterWidget(CollectionAppBar widget) {
|
||||||
stateNotifier.removeListener(_onStateChange);
|
widget.stateNotifier.removeListener(_onStateChange);
|
||||||
|
widget.collection.filterChangeNotifier.removeListener(_updateHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -69,16 +81,14 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
valueListenable: stateNotifier,
|
valueListenable: stateNotifier,
|
||||||
builder: (context, state, child) {
|
builder: (context, state, child) {
|
||||||
debugPrint('$runtimeType builder state=$state');
|
debugPrint('$runtimeType builder state=$state');
|
||||||
return Consumer<CollectionLens>(
|
return AnimatedBuilder(
|
||||||
builder: (context, collection, child) => AnimatedBuilder(
|
animation: collection.filterChangeNotifier,
|
||||||
animation: collection.filterChangeNotifier,
|
builder: (context, child) => SliverAppBar(
|
||||||
builder: (context, child) => SliverAppBar(
|
leading: _buildAppBarLeading(),
|
||||||
leading: _buildAppBarLeading(),
|
title: _buildAppBarTitle(),
|
||||||
title: _buildAppBarTitle(),
|
actions: _buildActions(),
|
||||||
actions: _buildActions(),
|
bottom: hasFilters ? FilterBar() : null,
|
||||||
bottom: collection.filters.isNotEmpty ? FilterBar() : null,
|
floating: true,
|
||||||
floating: true,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -127,17 +137,15 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
switch (stateNotifier.value) {
|
switch (stateNotifier.value) {
|
||||||
case PageState.browse:
|
case PageState.browse:
|
||||||
return Consumer<CollectionLens>(
|
return IconButton(
|
||||||
builder: (context, collection, child) => IconButton(
|
icon: Icon(OMIcons.search),
|
||||||
icon: Icon(OMIcons.search),
|
onPressed: () async {
|
||||||
onPressed: () async {
|
final filter = await showSearch(
|
||||||
final filter = await showSearch(
|
context: context,
|
||||||
context: context,
|
delegate: ImageSearchDelegate(collection),
|
||||||
delegate: ImageSearchDelegate(collection),
|
);
|
||||||
);
|
collection.addFilter(filter);
|
||||||
collection.addFilter(filter);
|
},
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
case PageState.search:
|
case PageState.search:
|
||||||
return IconButton(
|
return IconButton(
|
||||||
|
@ -149,55 +157,53 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) => Consumer<CollectionLens>(
|
builder: (context) => PopupMenuButton<CollectionAction>(
|
||||||
builder: (context, collection, child) => PopupMenuButton<CollectionAction>(
|
itemBuilder: (context) => [
|
||||||
itemBuilder: (context) => [
|
PopupMenuItem(
|
||||||
|
value: CollectionAction.sortByDate,
|
||||||
|
child: MenuRow(text: 'Sort by date', checked: collection.sortFactor == SortFactor.date),
|
||||||
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
value: CollectionAction.sortBySize,
|
||||||
|
child: MenuRow(text: 'Sort by size', checked: collection.sortFactor == SortFactor.size),
|
||||||
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
value: CollectionAction.sortByName,
|
||||||
|
child: MenuRow(text: 'Sort by name', checked: collection.sortFactor == SortFactor.name),
|
||||||
|
),
|
||||||
|
const PopupMenuDivider(),
|
||||||
|
if (collection.sortFactor == SortFactor.date) ...[
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: CollectionAction.sortByDate,
|
value: CollectionAction.groupByAlbum,
|
||||||
child: MenuRow(text: 'Sort by date', checked: collection.sortFactor == SortFactor.date),
|
child: MenuRow(text: 'Group by album', checked: collection.groupFactor == GroupFactor.album),
|
||||||
),
|
),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: CollectionAction.sortBySize,
|
value: CollectionAction.groupByMonth,
|
||||||
child: MenuRow(text: 'Sort by size', checked: collection.sortFactor == SortFactor.size),
|
child: MenuRow(text: 'Group by month', checked: collection.groupFactor == GroupFactor.month),
|
||||||
),
|
),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: CollectionAction.sortByName,
|
value: CollectionAction.groupByDay,
|
||||||
child: MenuRow(text: 'Sort by name', checked: collection.sortFactor == SortFactor.name),
|
child: MenuRow(text: 'Group by day', checked: collection.groupFactor == GroupFactor.day),
|
||||||
),
|
),
|
||||||
const PopupMenuDivider(),
|
const PopupMenuDivider(),
|
||||||
if (collection.sortFactor == SortFactor.date) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: CollectionAction.groupByAlbum,
|
|
||||||
child: MenuRow(text: 'Group by album', checked: collection.groupFactor == GroupFactor.album),
|
|
||||||
),
|
|
||||||
PopupMenuItem(
|
|
||||||
value: CollectionAction.groupByMonth,
|
|
||||||
child: MenuRow(text: 'Group by month', checked: collection.groupFactor == GroupFactor.month),
|
|
||||||
),
|
|
||||||
PopupMenuItem(
|
|
||||||
value: CollectionAction.groupByDay,
|
|
||||||
child: MenuRow(text: 'Group by day', checked: collection.groupFactor == GroupFactor.day),
|
|
||||||
),
|
|
||||||
const PopupMenuDivider(),
|
|
||||||
],
|
|
||||||
PopupMenuItem(
|
|
||||||
value: CollectionAction.stats,
|
|
||||||
child: MenuRow(text: 'Stats', icon: OMIcons.pieChart),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
onSelected: (action) => _onActionSelected(collection, action),
|
PopupMenuItem(
|
||||||
),
|
value: CollectionAction.stats,
|
||||||
|
child: MenuRow(text: 'Stats', icon: OMIcons.pieChart),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onSelected: _onActionSelected,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onActionSelected(CollectionLens collection, CollectionAction action) async {
|
void _onActionSelected(CollectionAction action) async {
|
||||||
// wait for the popup menu to hide before proceeding with the action
|
// wait for the popup menu to hide before proceeding with the action
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(Constants.popupMenuTransitionDuration);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case CollectionAction.stats:
|
case CollectionAction.stats:
|
||||||
unawaited(_goToStats(collection));
|
unawaited(_goToStats());
|
||||||
break;
|
break;
|
||||||
case CollectionAction.groupByAlbum:
|
case CollectionAction.groupByAlbum:
|
||||||
settings.collectionGroupFactor = GroupFactor.album;
|
settings.collectionGroupFactor = GroupFactor.album;
|
||||||
|
@ -226,7 +232,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _goToStats(CollectionLens collection) {
|
Future<void> _goToStats() {
|
||||||
return Navigator.push(
|
return Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
|
@ -245,6 +251,10 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
_searchFieldController.clear();
|
_searchFieldController.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _updateHeight() {
|
||||||
|
widget.appBarHeightNotifier.value = kToolbarHeight + (hasFilters ? FilterBar.preferredHeight : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SearchField extends StatelessWidget {
|
class SearchField extends StatelessWidget {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import 'package:aves/model/collection_lens.dart';
|
import 'package:aves/model/collection_lens.dart';
|
||||||
import 'package:aves/widgets/album/collection_app_bar.dart';
|
|
||||||
import 'package:aves/widgets/album/collection_drawer.dart';
|
import 'package:aves/widgets/album/collection_drawer.dart';
|
||||||
import 'package:aves/widgets/album/empty.dart';
|
|
||||||
import 'package:aves/widgets/album/thumbnail_collection.dart';
|
import 'package:aves/widgets/album/thumbnail_collection.dart';
|
||||||
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -11,7 +9,9 @@ import 'package:provider/provider.dart';
|
||||||
class CollectionPage extends StatelessWidget {
|
class CollectionPage extends StatelessWidget {
|
||||||
final CollectionLens collection;
|
final CollectionLens collection;
|
||||||
|
|
||||||
const CollectionPage(this.collection);
|
final ValueNotifier<PageState> _stateNotifier = ValueNotifier(PageState.browse);
|
||||||
|
|
||||||
|
CollectionPage(this.collection);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -20,7 +20,18 @@ class CollectionPage extends StatelessWidget {
|
||||||
child: ChangeNotifierProvider<CollectionLens>.value(
|
child: ChangeNotifierProvider<CollectionLens>.value(
|
||||||
value: collection,
|
value: collection,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
body: CollectionPageBody(),
|
body: WillPopScope(
|
||||||
|
onWillPop: () {
|
||||||
|
if (_stateNotifier.value == PageState.search) {
|
||||||
|
_stateNotifier.value = PageState.browse;
|
||||||
|
return SynchronousFuture(false);
|
||||||
|
}
|
||||||
|
return SynchronousFuture(true);
|
||||||
|
},
|
||||||
|
child: ThumbnailCollection(
|
||||||
|
stateNotifier: _stateNotifier,
|
||||||
|
),
|
||||||
|
),
|
||||||
drawer: CollectionDrawer(
|
drawer: CollectionDrawer(
|
||||||
source: collection.source,
|
source: collection.source,
|
||||||
),
|
),
|
||||||
|
@ -31,27 +42,4 @@ class CollectionPage extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CollectionPageBody extends StatelessWidget {
|
|
||||||
final ValueNotifier<PageState> _stateNotifier = ValueNotifier(PageState.browse);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return WillPopScope(
|
|
||||||
onWillPop: () {
|
|
||||||
if (_stateNotifier.value == PageState.search) {
|
|
||||||
_stateNotifier.value = PageState.browse;
|
|
||||||
return SynchronousFuture(false);
|
|
||||||
}
|
|
||||||
return SynchronousFuture(true);
|
|
||||||
},
|
|
||||||
child: ThumbnailCollection(
|
|
||||||
appBar: CollectionAppBar(
|
|
||||||
stateNotifier: _stateNotifier,
|
|
||||||
),
|
|
||||||
emptyBuilder: (context) => EmptyContent(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum PageState { browse, search }
|
enum PageState { browse, search }
|
||||||
|
|
|
@ -167,7 +167,7 @@ class _ScaleOverlayState extends State<ScaleOverlay> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
child: ValueListenableBuilder(
|
child: ValueListenableBuilder<double>(
|
||||||
valueListenable: widget.scaledCountNotifier,
|
valueListenable: widget.scaledCountNotifier,
|
||||||
builder: (context, columnCount, child) {
|
builder: (context, columnCount, child) {
|
||||||
final extent = gridWidth / columnCount;
|
final extent = gridWidth / columnCount;
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
import 'package:aves/model/collection_lens.dart';
|
import 'package:aves/model/collection_lens.dart';
|
||||||
|
import 'package:aves/widgets/album/collection_app_bar.dart';
|
||||||
|
import 'package:aves/widgets/album/collection_page.dart';
|
||||||
import 'package:aves/widgets/album/collection_scaling.dart';
|
import 'package:aves/widgets/album/collection_scaling.dart';
|
||||||
import 'package:aves/widgets/album/collection_section.dart';
|
import 'package:aves/widgets/album/collection_section.dart';
|
||||||
|
import 'package:aves/widgets/album/empty.dart';
|
||||||
import 'package:aves/widgets/common/scroll_thumb.dart';
|
import 'package:aves/widgets/common/scroll_thumb.dart';
|
||||||
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
|
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ThumbnailCollection extends StatelessWidget {
|
class ThumbnailCollection extends StatelessWidget {
|
||||||
final Widget appBar;
|
final ValueNotifier<PageState> stateNotifier;
|
||||||
final WidgetBuilder emptyBuilder;
|
|
||||||
|
|
||||||
|
final ValueNotifier<double> _appBarHeightNotifier = ValueNotifier(0);
|
||||||
final ValueNotifier<int> _columnCountNotifier = ValueNotifier(4);
|
final ValueNotifier<int> _columnCountNotifier = ValueNotifier(4);
|
||||||
final GlobalKey _scrollableKey = GlobalKey();
|
final GlobalKey _scrollableKey = GlobalKey();
|
||||||
|
|
||||||
ThumbnailCollection({
|
ThumbnailCollection({
|
||||||
Key key,
|
Key key,
|
||||||
this.appBar,
|
@required this.stateNotifier,
|
||||||
this.emptyBuilder,
|
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -27,16 +29,6 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
final sectionKeys = sections.keys.toList();
|
final sectionKeys = sections.keys.toList();
|
||||||
final showHeaders = collection.showHeaders;
|
final showHeaders = collection.showHeaders;
|
||||||
|
|
||||||
double topPadding = 0;
|
|
||||||
if (appBar != null) {
|
|
||||||
final topWidget = appBar;
|
|
||||||
if (topWidget is PreferredSizeWidget) {
|
|
||||||
topPadding = topWidget.preferredSize.height;
|
|
||||||
} else if (topWidget is SliverAppBar) {
|
|
||||||
topPadding = kToolbarHeight + (topWidget.bottom?.preferredSize?.height ?? 0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Selector<MediaQueryData, double>(
|
child: Selector<MediaQueryData, double>(
|
||||||
selector: (c, mq) => mq.viewInsets.bottom,
|
selector: (c, mq) => mq.viewInsets.bottom,
|
||||||
|
@ -44,7 +36,7 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
return GridScaleGestureDetector(
|
return GridScaleGestureDetector(
|
||||||
scrollableKey: _scrollableKey,
|
scrollableKey: _scrollableKey,
|
||||||
columnCountNotifier: _columnCountNotifier,
|
columnCountNotifier: _columnCountNotifier,
|
||||||
child: ValueListenableBuilder(
|
child: ValueListenableBuilder<int>(
|
||||||
valueListenable: _columnCountNotifier,
|
valueListenable: _columnCountNotifier,
|
||||||
builder: (context, columnCount, child) {
|
builder: (context, columnCount, child) {
|
||||||
debugPrint('$runtimeType builder columnCount=$columnCount entries=${collection.entryCount}');
|
debugPrint('$runtimeType builder columnCount=$columnCount entries=${collection.entryCount}');
|
||||||
|
@ -55,10 +47,14 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
// when there is no content and we use `SliverFillRemaining`
|
// when there is no content and we use `SliverFillRemaining`
|
||||||
physics: collection.isEmpty ? const NeverScrollableScrollPhysics() : null,
|
physics: collection.isEmpty ? const NeverScrollableScrollPhysics() : null,
|
||||||
slivers: [
|
slivers: [
|
||||||
if (appBar != null) appBar,
|
CollectionAppBar(
|
||||||
if (collection.isEmpty && emptyBuilder != null)
|
stateNotifier: stateNotifier,
|
||||||
|
appBarHeightNotifier: _appBarHeightNotifier,
|
||||||
|
collection: collection,
|
||||||
|
),
|
||||||
|
if (collection.isEmpty)
|
||||||
SliverFillRemaining(
|
SliverFillRemaining(
|
||||||
child: emptyBuilder(context),
|
child: EmptyContent(),
|
||||||
hasScrollBody: false,
|
hasScrollBody: false,
|
||||||
),
|
),
|
||||||
...sectionKeys.map((sectionKey) => SectionSliver(
|
...sectionKeys.map((sectionKey) => SectionSliver(
|
||||||
|
@ -78,16 +74,22 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
return DraggableScrollbar(
|
return ValueListenableBuilder<double>(
|
||||||
heightScrollThumb: avesScrollThumbHeight,
|
valueListenable: _appBarHeightNotifier,
|
||||||
backgroundColor: Colors.white,
|
builder: (context, appBarHeight, child) {
|
||||||
scrollThumbBuilder: avesScrollThumbBuilder(),
|
return DraggableScrollbar(
|
||||||
controller: PrimaryScrollController.of(context),
|
heightScrollThumb: avesScrollThumbHeight,
|
||||||
padding: EdgeInsets.only(
|
backgroundColor: Colors.white,
|
||||||
// padding to get scroll thumb below app bar, above nav bar
|
scrollThumbBuilder: avesScrollThumbBuilder(),
|
||||||
top: topPadding,
|
controller: PrimaryScrollController.of(context),
|
||||||
bottom: mqViewInsetsBottom,
|
padding: EdgeInsets.only(
|
||||||
),
|
// padding to keep scroll thumb between app bar above and nav bar below
|
||||||
|
top: appBarHeight,
|
||||||
|
bottom: mqViewInsetsBottom,
|
||||||
|
),
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
},
|
||||||
child: scrollView,
|
child: scrollView,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -395,7 +395,7 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
return ValueListenableBuilder(
|
return ValueListenableBuilder<Color>(
|
||||||
valueListenable: _backgroundColorNotifier,
|
valueListenable: _backgroundColorNotifier,
|
||||||
builder: (context, backgroundColor, child) => Container(
|
builder: (context, backgroundColor, child) => Container(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
|
|
|
@ -45,7 +45,7 @@ class BasicSection extends StatelessWidget {
|
||||||
'URI': entry.uri ?? '?',
|
'URI': entry.uri ?? '?',
|
||||||
if (entry.path != null) 'Path': entry.path,
|
if (entry.path != null) 'Path': entry.path,
|
||||||
}),
|
}),
|
||||||
ValueListenableBuilder(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: entry.isFavouriteNotifier,
|
valueListenable: entry.isFavouriteNotifier,
|
||||||
builder: (context, isFavourite, child) {
|
builder: (context, isFavourite, child) {
|
||||||
final album = entry.directory;
|
final album = entry.directory;
|
||||||
|
|
|
@ -57,14 +57,14 @@ class _LocationSectionState extends State<LocationSection> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _registerWidget(LocationSection widget) {
|
void _registerWidget(LocationSection widget) {
|
||||||
entry.metadataChangeNotifier.addListener(_handleChange);
|
widget.entry.metadataChangeNotifier.addListener(_handleChange);
|
||||||
entry.addressChangeNotifier.addListener(_handleChange);
|
widget.entry.addressChangeNotifier.addListener(_handleChange);
|
||||||
widget.visibleNotifier.addListener(_handleChange);
|
widget.visibleNotifier.addListener(_handleChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _unregisterWidget(LocationSection widget) {
|
void _unregisterWidget(LocationSection widget) {
|
||||||
entry.metadataChangeNotifier.removeListener(_handleChange);
|
widget.entry.metadataChangeNotifier.removeListener(_handleChange);
|
||||||
entry.addressChangeNotifier.removeListener(_handleChange);
|
widget.entry.addressChangeNotifier.removeListener(_handleChange);
|
||||||
widget.visibleNotifier.removeListener(_handleChange);
|
widget.visibleNotifier.removeListener(_handleChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ class FullscreenTopOverlay extends StatelessWidget {
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
OverlayButton(
|
OverlayButton(
|
||||||
scale: scale,
|
scale: scale,
|
||||||
child: ValueListenableBuilder(
|
child: ValueListenableBuilder<bool>(
|
||||||
valueListenable: entry.isFavouriteNotifier,
|
valueListenable: entry.isFavouriteNotifier,
|
||||||
builder: (context, isFavourite, child) => Stack(
|
builder: (context, isFavourite, child) => Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|
Loading…
Reference in a new issue