mirror of
https://github.com/immich-app/immich.git
synced 2026-03-22 17:49:56 +03:00
chore(mobile): simplify asset page scroll (#26635)
In order to scroll smoothly without interfering with the gesture detector on the photo view, we have an offstate scroll view which we defer all drags to, and then forward scroll offsets to the real scroll controller. This works well, but it can be simpler. Instead, we can create a custom scroll controller on a scroll view with never scrollable physics, and then forward drag events to that, bypassing the need for a proxy scroll controller. Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
@@ -50,8 +50,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
bool _showingDetails = false;
|
||||
bool _isZoomed = false;
|
||||
|
||||
final _scrollController = ScrollController();
|
||||
late final _proxyScrollController = ProxyScrollController(scrollController: _scrollController);
|
||||
final _scrollController = SnapScrollController();
|
||||
double _snapOffset = 0.0;
|
||||
|
||||
DragStartDetails? _dragStart;
|
||||
@@ -63,17 +62,17 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
super.initState();
|
||||
_eventSubscription = EventStream.shared.listen(_onEvent);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted || !_proxyScrollController.hasClients) return;
|
||||
_proxyScrollController.snapPosition.snapOffset = _snapOffset;
|
||||
if (!mounted || !_scrollController.hasClients) return;
|
||||
_scrollController.snapPosition.snapOffset = _snapOffset;
|
||||
if (_showingDetails && _snapOffset > 0) {
|
||||
_proxyScrollController.jumpTo(_snapOffset);
|
||||
_scrollController.jumpTo(_snapOffset);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_proxyScrollController.dispose();
|
||||
_scrollController.dispose();
|
||||
_scaleBoundarySub?.cancel();
|
||||
_eventSubscription?.cancel();
|
||||
super.dispose();
|
||||
@@ -88,21 +87,20 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
}
|
||||
|
||||
void _showDetails() {
|
||||
if (!_proxyScrollController.hasClients || _snapOffset <= 0) return;
|
||||
if (!_scrollController.hasClients || _snapOffset <= 0) return;
|
||||
_viewer.setShowingDetails(true);
|
||||
_proxyScrollController.animateTo(_snapOffset, duration: Durations.medium2, curve: Curves.easeOutCubic);
|
||||
_scrollController.animateTo(_snapOffset, duration: Durations.medium2, curve: Curves.easeOutCubic);
|
||||
}
|
||||
|
||||
bool _willClose(double scrollVelocity) {
|
||||
if (!_proxyScrollController.hasClients || _snapOffset <= 0) return false;
|
||||
|
||||
final position = _proxyScrollController.position;
|
||||
return _proxyScrollController.position.pixels < _snapOffset &&
|
||||
SnapScrollPhysics.target(position, scrollVelocity, _snapOffset) < SnapScrollPhysics.minSnapDistance;
|
||||
}
|
||||
bool _willClose(double scrollVelocity) =>
|
||||
_scrollController.hasClients &&
|
||||
_snapOffset > 0 &&
|
||||
_scrollController.position.pixels < _snapOffset &&
|
||||
SnapScrollPhysics.target(_scrollController.position, scrollVelocity, _snapOffset) <
|
||||
SnapScrollPhysics.minSnapDistance;
|
||||
|
||||
void _syncShowingDetails() {
|
||||
final offset = _proxyScrollController.offset;
|
||||
final offset = _scrollController.offset;
|
||||
if (offset > SnapScrollPhysics.minSnapDistance) {
|
||||
_viewer.setShowingDetails(true);
|
||||
} else if (offset < SnapScrollPhysics.minSnapDistance - kTouchSlop) {
|
||||
@@ -124,8 +122,8 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
}
|
||||
|
||||
void _startProxyDrag() {
|
||||
if (_proxyScrollController.hasClients && _dragStart != null) {
|
||||
_drag = _proxyScrollController.position.drag(_dragStart!, () => _drag = null);
|
||||
if (_scrollController.hasClients && _dragStart != null) {
|
||||
_drag = _scrollController.position.drag(_dragStart!, () => _drag = null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,22 +388,15 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
|
||||
_snapOffset = detailsOffset - snapTarget;
|
||||
|
||||
if (_proxyScrollController.hasClients) {
|
||||
_proxyScrollController.snapPosition.snapOffset = _snapOffset;
|
||||
if (_scrollController.hasClients) {
|
||||
_scrollController.snapPosition.snapOffset = _snapOffset;
|
||||
}
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
Offstage(
|
||||
child: SingleChildScrollView(
|
||||
controller: _proxyScrollController,
|
||||
physics: const SnapScrollPhysics(),
|
||||
child: const SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
SingleChildScrollView(
|
||||
controller: _scrollController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
physics: const SnapScrollPhysics(),
|
||||
child: Stack(
|
||||
children: [
|
||||
SizedBox(
|
||||
|
||||
Reference in New Issue
Block a user