mirror of
https://github.com/immich-app/immich.git
synced 2025-10-18 12:30:37 -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> {
|
class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
||||||
final _scrollController = ScrollController();
|
late final ScrollController _scrollController;
|
||||||
StreamSubscription? _eventSubscription;
|
StreamSubscription? _eventSubscription;
|
||||||
|
|
||||||
// Drag selection state
|
// Drag selection state
|
||||||
@ -119,10 +119,12 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
|||||||
int _perRow = 4;
|
int _perRow = 4;
|
||||||
double _scaleFactor = 3.0;
|
double _scaleFactor = 3.0;
|
||||||
double _baseScaleFactor = 3.0;
|
double _baseScaleFactor = 3.0;
|
||||||
|
int? _scaleRestoreAssetIndex;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_scrollController = ScrollController(onAttach: _restoreScalePosition);
|
||||||
_eventSubscription = EventStream.shared.listen(_onEvent);
|
_eventSubscription = EventStream.shared.listen(_onEvent);
|
||||||
|
|
||||||
final currentTilesPerRow = ref.read(settingsProvider).get(Setting.tilesPerRow);
|
final currentTilesPerRow = ref.read(settingsProvider).get(Setting.tilesPerRow);
|
||||||
@ -154,6 +156,28 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
|||||||
EventStream.shared.emit(MultiSelectToggleEvent(isEnabled));
|
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
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_scrollController.dispose();
|
_scrollController.dispose();
|
||||||
@ -345,9 +369,28 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
|||||||
final newPerRow = 7 - newScaleFactor.toInt();
|
final newPerRow = 7 - newScaleFactor.toInt();
|
||||||
|
|
||||||
if (newPerRow != _perRow) {
|
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(() {
|
setState(() {
|
||||||
_scaleFactor = newScaleFactor;
|
_scaleFactor = newScaleFactor;
|
||||||
_perRow = newPerRow;
|
_perRow = newPerRow;
|
||||||
|
_scaleRestoreAssetIndex = targetAssetIndex;
|
||||||
});
|
});
|
||||||
|
|
||||||
ref.read(settingsProvider.notifier).set(Setting.tilesPerRow, _perRow);
|
ref.read(settingsProvider.notifier).set(Setting.tilesPerRow, _perRow);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user