mirror of
https://github.com/immich-app/immich.git
synced 2025-09-29 15:31:13 -04:00
fix: retain scroll position on scale update (#22237)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
parent
6609e70fa8
commit
a582d3a03e
@ -107,7 +107,7 @@ class _SliverTimeline extends ConsumerStatefulWidget {
|
||||
}
|
||||
|
||||
class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
||||
final _scrollController = ScrollController();
|
||||
late final ScrollController _scrollController;
|
||||
StreamSubscription? _eventSubscription;
|
||||
|
||||
// Drag selection state
|
||||
@ -119,10 +119,12 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
||||
int _perRow = 4;
|
||||
double _scaleFactor = 3.0;
|
||||
double _baseScaleFactor = 3.0;
|
||||
int? _scaleRestoreAssetIndex;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_scrollController = ScrollController(onAttach: _restoreScalePosition);
|
||||
_eventSubscription = EventStream.shared.listen(_onEvent);
|
||||
|
||||
final currentTilesPerRow = ref.read(settingsProvider).get(Setting.tilesPerRow);
|
||||
@ -154,6 +156,28 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
||||
EventStream.shared.emit(MultiSelectToggleEvent(isEnabled));
|
||||
}
|
||||
|
||||
void _restoreScalePosition(_) {
|
||||
if (_scaleRestoreAssetIndex == null) return;
|
||||
|
||||
final asyncSegments = ref.read(timelineSegmentProvider);
|
||||
asyncSegments.whenData((segments) {
|
||||
final targetSegment = segments.lastWhereOrNull((segment) => segment.firstAssetIndex <= _scaleRestoreAssetIndex!);
|
||||
if (targetSegment != null) {
|
||||
final assetIndexInSegment = _scaleRestoreAssetIndex! - targetSegment.firstAssetIndex;
|
||||
final newColumnCount = ref.read(timelineArgsProvider).columnCount;
|
||||
final rowIndexInSegment = (assetIndexInSegment / newColumnCount).floor();
|
||||
final targetRowIndex = targetSegment.firstIndex + 1 + rowIndexInSegment;
|
||||
final targetOffset = targetSegment.indexToLayoutOffset(targetRowIndex);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
_scrollController.jumpTo(targetOffset.clamp(0.0, _scrollController.position.maxScrollExtent));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
_scaleRestoreAssetIndex = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
@ -345,9 +369,28 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
||||
final newPerRow = 7 - newScaleFactor.toInt();
|
||||
|
||||
if (newPerRow != _perRow) {
|
||||
final currentOffset = _scrollController.offset.clamp(
|
||||
0.0,
|
||||
_scrollController.position.maxScrollExtent,
|
||||
);
|
||||
final segment = segments.findByOffset(currentOffset) ?? segments.lastOrNull;
|
||||
int? targetAssetIndex;
|
||||
if (segment != null) {
|
||||
final rowIndex = segment.getMinChildIndexForScrollOffset(currentOffset);
|
||||
if (rowIndex > segment.firstIndex) {
|
||||
final rowIndexInSegment = rowIndex - (segment.firstIndex + 1);
|
||||
final assetsPerRow = ref.read(timelineArgsProvider).columnCount;
|
||||
final assetIndexInSegment = rowIndexInSegment * assetsPerRow;
|
||||
targetAssetIndex = segment.firstAssetIndex + assetIndexInSegment;
|
||||
} else {
|
||||
targetAssetIndex = segment.firstAssetIndex;
|
||||
}
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_scaleFactor = newScaleFactor;
|
||||
_perRow = newPerRow;
|
||||
_scaleRestoreAssetIndex = targetAssetIndex;
|
||||
});
|
||||
|
||||
ref.read(settingsProvider.notifier).set(Setting.tilesPerRow, _perRow);
|
||||
|
Loading…
x
Reference in New Issue
Block a user