refactor: clean up
parent
7473b959dc
commit
17361d189c
|
|
@ -1,53 +1,28 @@
|
|||
import 'package:immich_mobile/infrastructure/repositories/action_button_order.repository.dart';
|
||||
import 'package:immich_mobile/utils/action_button.utils.dart';
|
||||
|
||||
/// Service for managing quick action configurations.
|
||||
/// Provides business logic for building quick action types based on context.
|
||||
class QuickActionService {
|
||||
final ActionButtonOrderRepository _repository;
|
||||
|
||||
const QuickActionService(this._repository);
|
||||
|
||||
// Constants
|
||||
static const int defaultQuickActionLimit = 4;
|
||||
|
||||
static const List<ActionButtonType> defaultQuickActionSeed = [
|
||||
ActionButtonType.share,
|
||||
ActionButtonType.upload,
|
||||
ActionButtonType.edit,
|
||||
ActionButtonType.add,
|
||||
ActionButtonType.archive,
|
||||
ActionButtonType.delete,
|
||||
ActionButtonType.removeFromAlbum,
|
||||
ActionButtonType.likeActivity,
|
||||
];
|
||||
|
||||
static final Set<ActionButtonType> _quickActionSet = Set<ActionButtonType>.unmodifiable(defaultQuickActionSeed);
|
||||
|
||||
static final List<ActionButtonType> defaultQuickActionOrder = List<ActionButtonType>.unmodifiable(
|
||||
defaultQuickActionSeed,
|
||||
static final Set<ActionButtonType> _quickActionSet = Set<ActionButtonType>.unmodifiable(
|
||||
ActionButtonBuilder.defaultQuickActionOrder,
|
||||
);
|
||||
|
||||
/// Get the list of available quick action options
|
||||
// static List<ActionButtonType> get quickActionOptions => defaultQuickActionOrder;
|
||||
|
||||
/// Get the current quick action order
|
||||
List<ActionButtonType> get() {
|
||||
return _repository.get();
|
||||
}
|
||||
|
||||
/// Set the quick action order
|
||||
Future<void> set(List<ActionButtonType> order) async {
|
||||
final normalized = _normalizeQuickActionOrder(order);
|
||||
await _repository.set(normalized);
|
||||
}
|
||||
|
||||
/// Watch for changes to quick action order
|
||||
Stream<List<ActionButtonType>> watch() {
|
||||
return _repository.watch();
|
||||
}
|
||||
|
||||
/// Normalize quick action order by filtering valid types and ensuring all defaults are included
|
||||
List<ActionButtonType> _normalizeQuickActionOrder(List<ActionButtonType> order) {
|
||||
final ordered = <ActionButtonType>{};
|
||||
|
||||
|
|
@ -57,19 +32,20 @@ class QuickActionService {
|
|||
}
|
||||
}
|
||||
|
||||
ordered.addAll(defaultQuickActionSeed);
|
||||
ordered.addAll(ActionButtonBuilder.defaultQuickActionOrder);
|
||||
|
||||
return ordered.toList(growable: false);
|
||||
}
|
||||
|
||||
/// Build a list of quick action types based on context and custom order
|
||||
List<ActionButtonType> buildQuickActionTypes(
|
||||
ActionButtonContext context, {
|
||||
List<ActionButtonType>? quickActionOrder,
|
||||
int limit = defaultQuickActionLimit,
|
||||
int limit = ActionButtonBuilder.defaultQuickActionLimit,
|
||||
}) {
|
||||
final normalized = _normalizeQuickActionOrder(
|
||||
quickActionOrder == null || quickActionOrder.isEmpty ? defaultQuickActionOrder : quickActionOrder,
|
||||
quickActionOrder == null || quickActionOrder.isEmpty
|
||||
? ActionButtonBuilder.defaultQuickActionOrder
|
||||
: quickActionOrder,
|
||||
);
|
||||
|
||||
final seen = <ActionButtonType>{};
|
||||
|
|
|
|||
|
|
@ -1,60 +1,42 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||
import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/utils/action_button.utils.dart';
|
||||
|
||||
/// Repository for managing quick action button order persistence.
|
||||
/// Handles serialization, deserialization, and storage operations.
|
||||
class ActionButtonOrderRepository {
|
||||
const ActionButtonOrderRepository();
|
||||
|
||||
/// Default order for quick actions
|
||||
static const List<ActionButtonType> defaultOrder = [
|
||||
ActionButtonType.share,
|
||||
ActionButtonType.upload,
|
||||
ActionButtonType.edit,
|
||||
ActionButtonType.add,
|
||||
ActionButtonType.archive,
|
||||
ActionButtonType.delete,
|
||||
ActionButtonType.removeFromAlbum,
|
||||
ActionButtonType.likeActivity,
|
||||
];
|
||||
static const storeKey = StoreKey.viewerQuickActionOrder;
|
||||
|
||||
/// Get the current quick action order from storage
|
||||
List<ActionButtonType> get() {
|
||||
final json = Store.tryGet(StoreKey.viewerQuickActionOrder);
|
||||
final json = Store.tryGet(storeKey);
|
||||
if (json == null || json.isEmpty) {
|
||||
return defaultOrder;
|
||||
return ActionButtonBuilder.defaultQuickActionOrder;
|
||||
}
|
||||
|
||||
final deserialized = _deserialize(json);
|
||||
return deserialized.isEmpty ? defaultOrder : deserialized;
|
||||
return deserialized.isEmpty ? ActionButtonBuilder.defaultQuickActionOrder : deserialized;
|
||||
}
|
||||
|
||||
/// Save quick action order to storage
|
||||
Future<void> set(List<ActionButtonType> order) async {
|
||||
final json = _serialize(order);
|
||||
await Store.put(StoreKey.viewerQuickActionOrder, json);
|
||||
await Store.put(storeKey, json);
|
||||
}
|
||||
|
||||
/// Watch for changes to quick action order
|
||||
Stream<List<ActionButtonType>> watch() {
|
||||
return Store.watch(StoreKey.viewerQuickActionOrder).map((json) {
|
||||
return Store.watch(storeKey).map((json) {
|
||||
if (json == null || json.isEmpty) {
|
||||
return defaultOrder;
|
||||
return ActionButtonBuilder.defaultQuickActionOrder;
|
||||
}
|
||||
final deserialized = _deserialize(json);
|
||||
return deserialized.isEmpty ? defaultOrder : deserialized;
|
||||
return deserialized.isEmpty ? ActionButtonBuilder.defaultQuickActionOrder : deserialized;
|
||||
});
|
||||
}
|
||||
|
||||
/// Serialize a list of ActionButtonType to JSON string
|
||||
String _serialize(List<ActionButtonType> order) {
|
||||
return jsonEncode(order.map((type) => type.name).toList());
|
||||
}
|
||||
|
||||
/// Deserialize a JSON string to a list of ActionButtonType
|
||||
List<ActionButtonType> _deserialize(String json) {
|
||||
try {
|
||||
final list = jsonDecode(json) as List<dynamic>;
|
||||
|
|
|
|||
|
|
@ -77,10 +77,10 @@ class ViewerBottomBar extends ConsumerWidget {
|
|||
});
|
||||
}
|
||||
|
||||
final actions = ActionButtonBuilder.buildQuickActions(
|
||||
buttonContext,
|
||||
quickActionTypes: quickActionTypes,
|
||||
).map((widget) => GestureDetector(onLongPress: openConfigurator, child: widget)).toList(growable: false);
|
||||
final actions = quickActionTypes
|
||||
.map((type) => type.buildButton(buttonContext))
|
||||
.map((widget) => GestureDetector(onLongPress: openConfigurator, child: widget))
|
||||
.toList(growable: false);
|
||||
|
||||
return IgnorePointer(
|
||||
ignoring: opacity < 255,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_reorderable_grid_view/widgets/reorderable_builder.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/services/quick_action.service.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/viewer_quick_action_order.provider.dart';
|
||||
import 'package:immich_mobile/utils/action_button.utils.dart';
|
||||
import 'package:immich_mobile/utils/action_button_visuals.dart';
|
||||
|
|
@ -42,7 +41,7 @@ class _QuickActionConfiguratorState extends ConsumerState<QuickActionConfigurato
|
|||
|
||||
void _resetToDefault() {
|
||||
setState(() {
|
||||
_order = List<ActionButtonType>.from(QuickActionService.defaultQuickActionOrder);
|
||||
_order = List<ActionButtonType>.from(ActionButtonBuilder.defaultQuickActionOrder);
|
||||
_hasLocalChanges = true;
|
||||
});
|
||||
}
|
||||
|
|
@ -90,7 +89,7 @@ class _QuickActionConfiguratorState extends ConsumerState<QuickActionConfigurato
|
|||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'quick_actions_settings_description'.tr(
|
||||
namedArgs: {'count': QuickActionService.defaultQuickActionLimit.toString()},
|
||||
namedArgs: {'count': ActionButtonBuilder.defaultQuickActionLimit.toString()},
|
||||
),
|
||||
style: theme.textTheme.bodyMedium,
|
||||
textAlign: TextAlign.center,
|
||||
|
|
|
|||
|
|
@ -54,8 +54,7 @@ enum AppSettingsEnum<T> {
|
|||
readonlyModeEnabled<bool>(StoreKey.readonlyModeEnabled, "readonlyModeEnabled", false),
|
||||
albumGridView<bool>(StoreKey.albumGridView, "albumGridView", false),
|
||||
backupRequireCharging<bool>(StoreKey.backupRequireCharging, null, false),
|
||||
backupTriggerDelay<int>(StoreKey.backupTriggerDelay, null, 30),
|
||||
viewerQuickActionOrder<String>(StoreKey.viewerQuickActionOrder, null, '');
|
||||
backupTriggerDelay<int>(StoreKey.backupTriggerDelay, null, 30);
|
||||
|
||||
const AppSettingsEnum(this.storeKey, this.hiveKey, this.defaultValue);
|
||||
|
||||
|
|
@ -74,8 +73,4 @@ class AppSettingsService {
|
|||
Future<void> setSetting<T>(AppSettingsEnum<T> setting, T value) {
|
||||
return Store.put(setting.storeKey, value);
|
||||
}
|
||||
|
||||
Stream<T> watchSetting<T>(AppSettingsEnum<T> setting) {
|
||||
return Store.watch(setting.storeKey).map((value) => value ?? setting.defaultValue);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,22 +169,22 @@ enum ActionButtonType {
|
|||
}
|
||||
}
|
||||
|
||||
/// Builder class for creating action button widgets.
|
||||
/// This class provides simple factory methods for building action button widgets
|
||||
/// from ActionButtonContext. Business logic for quick actions is handled by QuickActionService.
|
||||
class ActionButtonBuilder {
|
||||
static const List<ActionButtonType> _actionTypes = ActionButtonType.values;
|
||||
|
||||
/// Build a list of quick action widgets based on context and custom order.
|
||||
/// Uses QuickActionService for business logic.
|
||||
static List<Widget> buildQuickActions(
|
||||
ActionButtonContext context, {
|
||||
required List<ActionButtonType> quickActionTypes,
|
||||
}) {
|
||||
return quickActionTypes.map((type) => type.buildButton(context)).toList();
|
||||
}
|
||||
static const int defaultQuickActionLimit = 4;
|
||||
|
||||
static const List<ActionButtonType> defaultQuickActionOrder = [
|
||||
ActionButtonType.share,
|
||||
ActionButtonType.upload,
|
||||
ActionButtonType.edit,
|
||||
ActionButtonType.add,
|
||||
ActionButtonType.archive,
|
||||
ActionButtonType.delete,
|
||||
ActionButtonType.removeFromAlbum,
|
||||
ActionButtonType.likeActivity,
|
||||
];
|
||||
|
||||
/// Build all available action button widgets for the given context.
|
||||
static List<Widget> build(ActionButtonContext context) {
|
||||
return _actionTypes.where((type) => type.shouldShow(context)).map((type) => type.buildButton(context)).toList();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ void main() {
|
|||
|
||||
final types = service.buildQuickActionTypes(context, quickActionOrder: customOrder);
|
||||
|
||||
expect(types.length, lessThanOrEqualTo(QuickActionService.defaultQuickActionLimit));
|
||||
expect(types.length, lessThanOrEqualTo(ActionButtonBuilder.defaultQuickActionLimit));
|
||||
expect(types.first, ActionButtonType.archive);
|
||||
expect(types[1], ActionButtonType.share);
|
||||
});
|
||||
|
|
@ -140,7 +140,7 @@ void main() {
|
|||
|
||||
final types = service.buildQuickActionTypes(
|
||||
context,
|
||||
quickActionOrder: QuickActionService.defaultQuickActionOrder,
|
||||
quickActionOrder: ActionButtonBuilder.defaultQuickActionOrder,
|
||||
limit: 2,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1042,9 +1042,9 @@ void main() {
|
|||
],
|
||||
);
|
||||
|
||||
final quickActions = ActionButtonBuilder.buildQuickActions(context, quickActionTypes: quickActionTypes);
|
||||
final quickActions = quickActionTypes.map((type) => type.buildButton(context)).toList();
|
||||
|
||||
expect(quickActions.length, QuickActionService.defaultQuickActionLimit);
|
||||
expect(quickActions.length, ActionButtonBuilder.defaultQuickActionLimit);
|
||||
expect(quickActions.first, isA<ArchiveActionButton>());
|
||||
expect(quickActions[1], isA<ShareActionButton>());
|
||||
expect(quickActions[2], isA<EditImageActionButton>());
|
||||
|
|
|
|||
Loading…
Reference in New Issue