mirror of
https://github.com/immich-app/immich.git
synced 2025-12-06 09:13:13 +03:00
Compare commits
1 Commits
fix/async-
...
fix/timeli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19c9f932ea |
@@ -10,6 +10,7 @@ import 'package:immich_mobile/domain/services/setting.service.dart';
|
||||
import 'package:immich_mobile/domain/utils/event_stream.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
||||
import 'package:immich_mobile/utils/async_mutex.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
typedef TimelineAssetSource = Future<List<BaseAsset>> Function(
|
||||
int index,
|
||||
@@ -77,6 +78,7 @@ class TimelineService {
|
||||
int _bufferOffset = 0;
|
||||
List<BaseAsset> _buffer = [];
|
||||
StreamSubscription? _bucketSubscription;
|
||||
final _log = Logger('TimelineService');
|
||||
|
||||
int _totalAssets = 0;
|
||||
int get totalAssets => _totalAssets;
|
||||
@@ -128,10 +130,10 @@ class TimelineService {
|
||||
|
||||
Stream<List<Bucket>> Function() get watchBuckets => _bucketSource;
|
||||
|
||||
Future<List<BaseAsset>> loadAssets(int index, int count) =>
|
||||
Future<List<BaseAsset>?> loadAssets(int index, int count) =>
|
||||
_mutex.run(() => _loadAssets(index, count));
|
||||
|
||||
Future<List<BaseAsset>> _loadAssets(int index, int count) async {
|
||||
Future<List<BaseAsset>?> _loadAssets(int index, int count) async {
|
||||
if (hasRange(index, count)) {
|
||||
return getAssets(index, count);
|
||||
}
|
||||
@@ -169,9 +171,10 @@ class TimelineService {
|
||||
index + count <= _bufferOffset + _buffer.length &&
|
||||
index + count <= _totalAssets;
|
||||
|
||||
List<BaseAsset> getAssets(int index, int count) {
|
||||
List<BaseAsset>? getAssets(int index, int count) {
|
||||
if (!hasRange(index, count)) {
|
||||
throw RangeError('TimelineService::getAssets Index out of range');
|
||||
_log.warning('TimelineService::getAssets Index out of range');
|
||||
return null;
|
||||
}
|
||||
int start = index - _bufferOffset;
|
||||
return _buffer.slice(start, start + count);
|
||||
|
||||
@@ -107,19 +107,22 @@ class _FixedSegmentRow extends ConsumerWidget {
|
||||
}
|
||||
|
||||
if (timelineService.hasRange(assetIndex, assetCount)) {
|
||||
return _buildAssetRow(
|
||||
context,
|
||||
timelineService.getAssets(assetIndex, assetCount),
|
||||
);
|
||||
final assets = timelineService.getAssets(assetIndex, assetCount);
|
||||
if (assets == null) {
|
||||
return _buildPlaceholder(context);
|
||||
}
|
||||
|
||||
return _buildAssetRow(context, assets);
|
||||
}
|
||||
|
||||
return FutureBuilder<List<BaseAsset>>(
|
||||
return FutureBuilder<List<BaseAsset>?>(
|
||||
future: timelineService.loadAssets(assetIndex, assetCount),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
if (snapshot.connectionState != ConnectionState.done ||
|
||||
snapshot.data == null) {
|
||||
return _buildPlaceholder(context);
|
||||
}
|
||||
return _buildAssetRow(context, snapshot.requireData);
|
||||
return _buildAssetRow(context, snapshot.data!);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -112,8 +112,9 @@ class _BulkSelectIconButton extends ConsumerWidget {
|
||||
List<BaseAsset> bucketAssets;
|
||||
try {
|
||||
bucketAssets = ref
|
||||
.watch(timelineServiceProvider)
|
||||
.getAssets(assetOffset, bucket.assetCount);
|
||||
.watch(timelineServiceProvider)
|
||||
.getAssets(assetOffset, bucket.assetCount) ??
|
||||
[];
|
||||
} catch (e) {
|
||||
bucketAssets = <BaseAsset>[];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/domain/services/timeline.service.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||
@@ -130,7 +129,7 @@ class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
final assets = await _timelineService.loadAssets(offset, bucketCount);
|
||||
final selectedAssets = state.selectedAssets.toSet();
|
||||
|
||||
selectedAssets.addAll(assets);
|
||||
selectedAssets.addAll(assets ?? []);
|
||||
|
||||
state = state.copyWith(
|
||||
selectedAssets: selectedAssets,
|
||||
@@ -141,14 +140,14 @@ class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
final assets = await _timelineService.loadAssets(offset, bucketCount);
|
||||
final selectedAssets = state.selectedAssets.toSet();
|
||||
|
||||
selectedAssets.removeAll(assets);
|
||||
selectedAssets.removeAll(assets ?? []);
|
||||
|
||||
state = state.copyWith(selectedAssets: selectedAssets);
|
||||
}
|
||||
|
||||
void toggleBucketSelection(int offset, int bucketCount) async {
|
||||
final assets = await _timelineService.loadAssets(offset, bucketCount);
|
||||
toggleBucketSelectionByAssets(assets);
|
||||
toggleBucketSelectionByAssets(assets ?? []);
|
||||
}
|
||||
|
||||
void toggleBucketSelectionByAssets(List<BaseAsset> bucketAssets) {
|
||||
|
||||
Reference in New Issue
Block a user