You've already forked immich
mirror of
https://github.com/immich-app/immich.git
synced 2025-08-07 23:03:36 +02:00
feat: selection mode timeline (#19734)
* feat: new page * force multi-selection state * fix: provider scoping * Return selected assets * lint * lint * simplify provider scope and drop drilling * selection styling
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
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';
|
||||
@ -12,8 +13,14 @@ final multiSelectProvider =
|
||||
|
||||
class MultiSelectState {
|
||||
final Set<BaseAsset> selectedAssets;
|
||||
final Set<BaseAsset> lockedSelectionAssets;
|
||||
final bool forceEnable;
|
||||
|
||||
const MultiSelectState({required this.selectedAssets});
|
||||
const MultiSelectState({
|
||||
required this.selectedAssets,
|
||||
required this.lockedSelectionAssets,
|
||||
this.forceEnable = false,
|
||||
});
|
||||
|
||||
bool get isEnabled => selectedAssets.isNotEmpty;
|
||||
bool get hasRemote => selectedAssets.any(
|
||||
@ -25,33 +32,54 @@ class MultiSelectState {
|
||||
(asset) => asset.storage == AssetState.local,
|
||||
);
|
||||
|
||||
MultiSelectState copyWith({Set<BaseAsset>? selectedAssets}) {
|
||||
MultiSelectState copyWith({
|
||||
Set<BaseAsset>? selectedAssets,
|
||||
Set<BaseAsset>? lockedSelectionAssets,
|
||||
bool? forceEnable,
|
||||
}) {
|
||||
return MultiSelectState(
|
||||
selectedAssets: selectedAssets ?? this.selectedAssets,
|
||||
lockedSelectionAssets:
|
||||
lockedSelectionAssets ?? this.lockedSelectionAssets,
|
||||
forceEnable: forceEnable ?? this.forceEnable,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'MultiSelectState(selectedAssets: $selectedAssets)';
|
||||
String toString() =>
|
||||
'MultiSelectState(selectedAssets: $selectedAssets, lockedSelectionAssets: $lockedSelectionAssets, forceEnable: $forceEnable)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant MultiSelectState other) {
|
||||
if (identical(this, other)) return true;
|
||||
final listEquals = const DeepCollectionEquality().equals;
|
||||
final setEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return listEquals(other.selectedAssets, selectedAssets);
|
||||
return setEquals(other.selectedAssets, selectedAssets) &&
|
||||
setEquals(other.lockedSelectionAssets, lockedSelectionAssets) &&
|
||||
other.forceEnable == forceEnable;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => selectedAssets.hashCode;
|
||||
int get hashCode =>
|
||||
selectedAssets.hashCode ^
|
||||
lockedSelectionAssets.hashCode ^
|
||||
forceEnable.hashCode;
|
||||
}
|
||||
|
||||
class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
MultiSelectNotifier([this._defaultState]);
|
||||
final MultiSelectState? _defaultState;
|
||||
|
||||
TimelineService get _timelineService => ref.read(timelineServiceProvider);
|
||||
|
||||
@override
|
||||
MultiSelectState build() {
|
||||
return const MultiSelectState(selectedAssets: {});
|
||||
return _defaultState ??
|
||||
const MultiSelectState(
|
||||
selectedAssets: {},
|
||||
lockedSelectionAssets: {},
|
||||
forceEnable: false,
|
||||
);
|
||||
}
|
||||
|
||||
void selectAsset(BaseAsset asset) {
|
||||
@ -83,7 +111,11 @@ class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
state = const MultiSelectState(selectedAssets: {});
|
||||
state = const MultiSelectState(
|
||||
selectedAssets: {},
|
||||
lockedSelectionAssets: {},
|
||||
forceEnable: false,
|
||||
);
|
||||
}
|
||||
|
||||
/// Bucket bulk operations
|
||||
@ -131,6 +163,12 @@ class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
|
||||
state = state.copyWith(selectedAssets: selectedAssets);
|
||||
}
|
||||
|
||||
void setLockedSelectionAssets(Set<BaseAsset> assets) {
|
||||
state = state.copyWith(
|
||||
lockedSelectionAssets: assets,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final bucketSelectionProvider = Provider.family<bool, List<BaseAsset>>(
|
||||
|
Reference in New Issue
Block a user