mirror of
https://github.com/immich-app/immich.git
synced 2025-06-23 15:34:03 -04:00
add collection page
This commit is contained in:
parent
d6729c50c9
commit
a1df3878a9
118
mobile/lib/pages/collections/collections.page.dart
Normal file
118
mobile/lib/pages/collections/collections.page.dart
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/widgets/common/immich_app_bar.dart';
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class CollectionsPage extends StatelessWidget {
|
||||||
|
const CollectionsPage({super.key});
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: const ImmichAppBar(
|
||||||
|
action: CreateNewButton(),
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
ActionButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icons.favorite_outline_rounded,
|
||||||
|
label: 'Favorite',
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
ActionButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icons.delete_outline_rounded,
|
||||||
|
label: 'Trash',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
ActionButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icons.link_outlined,
|
||||||
|
label: 'Shared links',
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
ActionButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icons.archive_outlined,
|
||||||
|
label: 'Archive',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActionButton extends StatelessWidget {
|
||||||
|
final VoidCallback onPressed;
|
||||||
|
final IconData icon;
|
||||||
|
final String label;
|
||||||
|
|
||||||
|
const ActionButton({
|
||||||
|
super.key,
|
||||||
|
required this.onPressed,
|
||||||
|
required this.icon,
|
||||||
|
required this.label,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Expanded(
|
||||||
|
child: FilledButton.icon(
|
||||||
|
onPressed: onPressed,
|
||||||
|
label: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
style: TextStyle(
|
||||||
|
color: context.colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: FilledButton.styleFrom(
|
||||||
|
elevation: 0,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
|
||||||
|
backgroundColor: context.colorScheme.surfaceContainer,
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
icon: Icon(
|
||||||
|
icon,
|
||||||
|
color: context.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreateNewButton extends StatelessWidget {
|
||||||
|
const CreateNewButton({super.key});
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {},
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(25)),
|
||||||
|
child: Icon(
|
||||||
|
Icons.add,
|
||||||
|
size: 32,
|
||||||
|
semanticLabel: 'profile_drawer_trash'.tr(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -94,6 +94,12 @@ class TabControllerPage extends HookConsumerWidget {
|
|||||||
selectedIcon: const Icon(Icons.photo_album),
|
selectedIcon: const Icon(Icons.photo_album),
|
||||||
label: const Text('tab_controller_nav_library').tr(),
|
label: const Text('tab_controller_nav_library').tr(),
|
||||||
),
|
),
|
||||||
|
NavigationRailDestination(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
icon: const Icon(Icons.photo_album_outlined),
|
||||||
|
selectedIcon: const Icon(Icons.photo_album),
|
||||||
|
label: const Text('Collections').tr(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -156,6 +162,18 @@ class TabControllerPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
NavigationDestination(
|
||||||
|
label: 'Collections'.tr(),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.photo_album_outlined,
|
||||||
|
),
|
||||||
|
selectedIcon: buildIcon(
|
||||||
|
Icon(
|
||||||
|
Icons.photo_album_rounded,
|
||||||
|
color: context.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -167,6 +185,7 @@ class TabControllerPage extends HookConsumerWidget {
|
|||||||
SearchRoute(),
|
SearchRoute(),
|
||||||
SharingRoute(),
|
SharingRoute(),
|
||||||
LibraryRoute(),
|
LibraryRoute(),
|
||||||
|
CollectionsRoute(),
|
||||||
],
|
],
|
||||||
duration: const Duration(milliseconds: 600),
|
duration: const Duration(milliseconds: 600),
|
||||||
transitionBuilder: (context, child, animation) => FadeTransition(
|
transitionBuilder: (context, child, animation) => FadeTransition(
|
||||||
|
@ -63,6 +63,8 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
|||||||
_ref.read(sharedAlbumProvider.notifier).getAllSharedAlbums();
|
_ref.read(sharedAlbumProvider.notifier).getAllSharedAlbums();
|
||||||
case TabEnum.library:
|
case TabEnum.library:
|
||||||
_ref.read(albumProvider.notifier).getAllAlbums();
|
_ref.read(albumProvider.notifier).getAllAlbums();
|
||||||
|
case TabEnum.collections:
|
||||||
|
// nothing to do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
enum TabEnum {
|
enum TabEnum { home, search, sharing, library, collections }
|
||||||
home,
|
|
||||||
search,
|
|
||||||
sharing,
|
|
||||||
library,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides the currently active tab
|
/// Provides the currently active tab
|
||||||
final tabProvider = StateProvider<TabEnum>(
|
final tabProvider = StateProvider<TabEnum>(
|
||||||
|
@ -13,6 +13,7 @@ import 'package:immich_mobile/pages/backup/backup_album_selection.page.dart';
|
|||||||
import 'package:immich_mobile/pages/backup/backup_controller.page.dart';
|
import 'package:immich_mobile/pages/backup/backup_controller.page.dart';
|
||||||
import 'package:immich_mobile/pages/backup/backup_options.page.dart';
|
import 'package:immich_mobile/pages/backup/backup_options.page.dart';
|
||||||
import 'package:immich_mobile/pages/backup/failed_backup_status.page.dart';
|
import 'package:immich_mobile/pages/backup/failed_backup_status.page.dart';
|
||||||
|
import 'package:immich_mobile/pages/collections/collections.page.dart';
|
||||||
import 'package:immich_mobile/pages/common/activities.page.dart';
|
import 'package:immich_mobile/pages/common/activities.page.dart';
|
||||||
import 'package:immich_mobile/pages/common/album_additional_shared_user_selection.page.dart';
|
import 'package:immich_mobile/pages/common/album_additional_shared_user_selection.page.dart';
|
||||||
import 'package:immich_mobile/pages/common/album_asset_selection.page.dart';
|
import 'package:immich_mobile/pages/common/album_asset_selection.page.dart';
|
||||||
@ -114,6 +115,10 @@ class AppRouter extends RootStackRouter {
|
|||||||
page: LibraryRoute.page,
|
page: LibraryRoute.page,
|
||||||
guards: [_authGuard, _duplicateGuard],
|
guards: [_authGuard, _duplicateGuard],
|
||||||
),
|
),
|
||||||
|
AutoRoute(
|
||||||
|
page: CollectionsRoute.page,
|
||||||
|
guards: [_authGuard, _duplicateGuard],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
transitionsBuilder: TransitionsBuilders.fadeIn,
|
transitionsBuilder: TransitionsBuilders.fadeIn,
|
||||||
),
|
),
|
||||||
|
@ -555,6 +555,25 @@ class ChangePasswordRoute extends PageRouteInfo<void> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [CollectionsPage]
|
||||||
|
class CollectionsRoute extends PageRouteInfo<void> {
|
||||||
|
const CollectionsRoute({List<PageRouteInfo>? children})
|
||||||
|
: super(
|
||||||
|
CollectionsRoute.name,
|
||||||
|
initialChildren: children,
|
||||||
|
);
|
||||||
|
|
||||||
|
static const String name = 'CollectionsRoute';
|
||||||
|
|
||||||
|
static PageInfo page = PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
return const CollectionsPage();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [CreateAlbumPage]
|
/// [CreateAlbumPage]
|
||||||
class CreateAlbumRoute extends PageRouteInfo<CreateAlbumRouteArgs> {
|
class CreateAlbumRoute extends PageRouteInfo<CreateAlbumRouteArgs> {
|
||||||
|
@ -185,7 +185,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
|
|||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
if (action != null)
|
if (action != null)
|
||||||
Padding(padding: const EdgeInsets.only(right: 20), child: action!),
|
Padding(padding: const EdgeInsets.only(right: 16), child: action!),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 20),
|
padding: const EdgeInsets.only(right: 20),
|
||||||
child: buildBackupIndicator(),
|
child: buildBackupIndicator(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user