mirror of
https://github.com/immich-app/immich.git
synced 2024-12-25 10:43:13 +02:00
feat(mobile): Scroll to top when tapping photos while already on photo page (#1784)
* adds scroll to top when tapping photos while already on photo page * unused import
This commit is contained in:
parent
bf6f94f69f
commit
6e9749d6c4
@ -0,0 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final scrollToTopNotifierProvider = ScrollNotifier();
|
||||
|
||||
class ScrollNotifier with ChangeNotifier {
|
||||
void scrollToTop() {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import 'dart:collection';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart';
|
||||
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
@ -234,6 +235,30 @@ class ImmichAssetGridState extends State<ImmichAssetGrid> {
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
scrollToTopNotifierProvider.addListener(_scrollToTop);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollToTopNotifierProvider.removeListener(_scrollToTop);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _scrollToTop() {
|
||||
// for some reason, this is necessary as well in order
|
||||
// to correctly reposition the drag thumb scroll bar
|
||||
_itemScrollController.jumpTo(
|
||||
index: 0,
|
||||
);
|
||||
_itemScrollController.scrollTo(
|
||||
index: 0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
|
@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart';
|
||||
import 'package:immich_mobile/modules/home/providers/multiselect.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
|
||||
@ -16,6 +17,11 @@ class TabControllerPage extends ConsumerWidget {
|
||||
labelType: NavigationRailLabelType.all,
|
||||
selectedIndex: tabsRouter.activeIndex,
|
||||
onDestinationSelected: (index) {
|
||||
// Selected Photos while it is active
|
||||
if (tabsRouter.activeIndex == 0 && index == 0) {
|
||||
// Scroll to top
|
||||
scrollToTopNotifierProvider.scrollToTop();
|
||||
}
|
||||
HapticFeedback.selectionClick();
|
||||
tabsRouter.setActiveIndex(index);
|
||||
},
|
||||
@ -60,51 +66,14 @@ class TabControllerPage extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
bottomNavigationBar(TabsRouter tabsRouter) {
|
||||
return BottomNavigationBar(
|
||||
selectedLabelStyle: const TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
unselectedLabelStyle: const TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
currentIndex: tabsRouter.activeIndex,
|
||||
onTap: (index) {
|
||||
HapticFeedback.selectionClick();
|
||||
tabsRouter.setActiveIndex(index);
|
||||
},
|
||||
items: [
|
||||
BottomNavigationBarItem(
|
||||
label: 'tab_controller_nav_photos'.tr(),
|
||||
icon: const Icon(Icons.photo_outlined),
|
||||
activeIcon: const Icon(Icons.photo),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
label: 'tab_controller_nav_search'.tr(),
|
||||
icon: const Icon(Icons.search_rounded),
|
||||
activeIcon: const Icon(Icons.search),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
label: 'tab_controller_nav_sharing'.tr(),
|
||||
icon: const Icon(Icons.group_outlined),
|
||||
activeIcon: const Icon(Icons.group),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
label: 'tab_controller_nav_library'.tr(),
|
||||
icon: const Icon(Icons.photo_album_outlined),
|
||||
activeIcon: const Icon(Icons.photo_album_rounded),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
experimentalNavigationBar(TabsRouter tabsRouter) {
|
||||
return NavigationBar(
|
||||
selectedIndex: tabsRouter.activeIndex,
|
||||
onDestinationSelected: (index) {
|
||||
if (tabsRouter.activeIndex == 0 && index == 0) {
|
||||
// Scroll to top
|
||||
scrollToTopNotifierProvider.scrollToTop();
|
||||
}
|
||||
HapticFeedback.selectionClick();
|
||||
tabsRouter.setActiveIndex(index);
|
||||
},
|
||||
@ -179,7 +148,7 @@ class TabControllerPage extends ConsumerWidget {
|
||||
final Widget body;
|
||||
if (constraints.maxWidth < medium) {
|
||||
// Normal phone width
|
||||
bottom = experimentalNavigationBar(tabsRouter);
|
||||
bottom = bottomNavigationBar(tabsRouter);
|
||||
body = FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
|
Loading…
Reference in New Issue
Block a user