mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:06:56 -04:00
better anchor menu
This commit is contained in:
parent
424de03204
commit
31f2b94396
@ -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(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,9 +73,7 @@ class CollectionsPage extends ConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
PeopleCollectionCard(),
|
PeopleCollectionCard(),
|
||||||
AlbumsCollectionCard(),
|
AlbumsCollectionCard(),
|
||||||
AlbumsCollectionCard(
|
AlbumsCollectionCard(isLocal: true),
|
||||||
isLocal: true,
|
|
||||||
),
|
|
||||||
PlacesCollectionCard(),
|
PlacesCollectionCard(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user