better anchor menu

This commit is contained in:
Alex 2024-09-06 22:05:52 -05:00
parent 424de03204
commit 31f2b94396
No known key found for this signature in database
GPG Key ID: 53CD082B3A5E1082
3 changed files with 120 additions and 56 deletions

View File

@ -1,3 +1,5 @@
import 'dart:math';
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -39,6 +41,8 @@ class AlbumsCollectionPage extends HookConsumerWidget {
title: const Text("Albums"), title: const Text("Albums"),
), ),
body: ListView( body: ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(18.0),
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -53,6 +57,40 @@ class AlbumsCollectionPage extends HookConsumerWidget {
), ),
], ],
), ),
if (isGrid.value)
GridView.builder(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: .7,
),
itemBuilder: (context, index) {
return AlbumThumbnailCard(
album: sorted[index],
onTap: () => context.pushRoute(
AlbumViewerRoute(albumId: sorted[index].id),
),
);
},
itemCount: sorted.length,
)
else
ListView.builder(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: sorted.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(sorted[index].name),
onTap: () => context.pushRoute(
AlbumViewerRoute(albumId: sorted[index].id),
),
);
},
),
], ],
), ),
); );
@ -67,63 +105,90 @@ class SortButton extends ConsumerWidget {
final albumSortOption = ref.watch(albumSortByOptionsProvider); final albumSortOption = ref.watch(albumSortByOptionsProvider);
final albumSortIsReverse = ref.watch(albumSortOrderProvider); final albumSortIsReverse = ref.watch(albumSortOrderProvider);
return PopupMenuButton( return MenuAnchor(
position: PopupMenuPosition.over, menuChildren: AlbumSortMode.values
itemBuilder: (BuildContext context) { .map(
return AlbumSortMode.values (mode) => MenuItemButton(
.map<PopupMenuEntry<AlbumSortMode>>((option) { leadingIcon: albumSortOption == mode
final selected = albumSortOption == option; ? albumSortIsReverse
return PopupMenuItem( ? Icon(
value: option, Icons.keyboard_arrow_down,
child: Row( color: albumSortOption == mode
children: [ ? context.colorScheme.onPrimary
Padding( : context.colorScheme.onSurface,
padding: const EdgeInsets.only(right: 12.0), )
: Icon(
Icons.keyboard_arrow_up_rounded,
color: albumSortOption == mode
? context.colorScheme.onPrimary
: context.colorScheme.onSurface,
)
: const Icon(Icons.abc, color: Colors.transparent),
onPressed: () {
final selected = albumSortOption == mode;
// Switch direction
if (selected) {
ref
.read(albumSortOrderProvider.notifier)
.changeSortDirection(!albumSortIsReverse);
} else {
ref
.read(albumSortByOptionsProvider.notifier)
.changeSortMode(mode);
}
},
style: ButtonStyle(
padding: WidgetStateProperty.all(const EdgeInsets.all(8)),
backgroundColor: WidgetStateProperty.all(
albumSortOption == mode
? context.colorScheme.primary
: Colors.transparent,
),
),
child: Text(
mode.label.tr(),
style: context.textTheme.bodyMedium?.copyWith(
color: albumSortOption == mode
? context.colorScheme.onPrimary
: context.colorScheme.onSurface,
),
),
),
)
.toList(),
builder: (context, controller, child) {
return GestureDetector(
onTap: () {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 5),
child: Transform.rotate(
angle: 90 * pi / 180,
child: Icon( child: Icon(
Icons.check, Icons.compare_arrows_rounded,
color: selected ? context.primaryColor : Colors.transparent, size: 18,
color: context.colorScheme.onSurface.withAlpha(200),
), ),
), ),
Text( ),
option.label.tr(), Text(
style: TextStyle( albumSortOption.label.tr(),
color: selected ? context.primaryColor : null, style: context.textTheme.bodyLarge?.copyWith(
fontSize: 14.0, fontWeight: FontWeight.w500,
), color: context.colorScheme.onSurface.withAlpha(200),
), ),
], ),
), ],
);
}).toList();
},
onSelected: (AlbumSortMode value) {
final selected = albumSortOption == value;
// Switch direction
if (selected) {
ref
.read(albumSortOrderProvider.notifier)
.changeSortDirection(!albumSortIsReverse);
} else {
ref.read(albumSortByOptionsProvider.notifier).changeSortMode(value);
}
},
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 5),
child: Icon(
albumSortIsReverse
? Icons.arrow_downward_rounded
: Icons.arrow_upward_rounded,
size: 18,
),
), ),
Text( );
albumSortOption.label.tr(), },
style: context.textTheme.labelLarge?.copyWith(),
),
],
),
); );
} }
} }

View File

@ -73,9 +73,7 @@ class CollectionsPage extends ConsumerWidget {
children: [ children: [
PeopleCollectionCard(), PeopleCollectionCard(),
AlbumsCollectionCard(), AlbumsCollectionCard(),
AlbumsCollectionCard( AlbumsCollectionCard(isLocal: true),
isLocal: true,
),
PlacesCollectionCard(), PlacesCollectionCard(),
], ],
), ),

View File

@ -169,9 +169,10 @@ class AppRouter extends RootStackRouter {
guards: [_authGuard, _duplicateGuard], guards: [_authGuard, _duplicateGuard],
transitionsBuilder: TransitionsBuilders.slideBottom, transitionsBuilder: TransitionsBuilders.slideBottom,
), ),
AutoRoute( CustomRoute(
page: AlbumViewerRoute.page, page: AlbumViewerRoute.page,
guards: [_authGuard, _duplicateGuard], guards: [_authGuard, _duplicateGuard],
transitionsBuilder: TransitionsBuilders.slideBottom,
), ),
CustomRoute( CustomRoute(
page: AlbumAdditionalSharedUserSelectionRoute.page, page: AlbumAdditionalSharedUserSelectionRoute.page,