feat(07-01): create TaskSortOption enum, SortPreferenceNotifier, and localization strings
- TaskSortOption enum with alphabetical, interval, effort values - SortPreferenceNotifier persists sort preference to SharedPreferences - Follows ThemeNotifier pattern: sync default (alphabetical), async load - Generated sort_preference_notifier.g.dart via build_runner - Added sortAlphabetical/sortInterval/sortEffort/sortLabel to app_de.arb - Regenerated app_localizations.dart and app_localizations_de.dart
This commit is contained in:
9
lib/features/tasks/domain/task_sort_option.dart
Normal file
9
lib/features/tasks/domain/task_sort_option.dart
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/// Sort options for task lists.
|
||||||
|
///
|
||||||
|
/// Stored as a string in SharedPreferences (not as intEnum in the database),
|
||||||
|
/// so reordering these values is safe.
|
||||||
|
enum TaskSortOption {
|
||||||
|
alphabetical, // A–Z by task name
|
||||||
|
interval, // by frequency interval (most frequent first)
|
||||||
|
effort, // by effort level (low → medium → high)
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
import 'package:household_keeper/features/tasks/domain/task_sort_option.dart';
|
||||||
|
|
||||||
|
part 'sort_preference_notifier.g.dart';
|
||||||
|
|
||||||
|
const _sortOptionKey = 'task_sort_option';
|
||||||
|
|
||||||
|
/// Notifier that manages the active task sort preference.
|
||||||
|
///
|
||||||
|
/// Defaults to [TaskSortOption.alphabetical] synchronously (matching the
|
||||||
|
/// existing A-Z sort in CalendarDayList), then loads the persisted value
|
||||||
|
/// asynchronously on first build.
|
||||||
|
///
|
||||||
|
/// Follows the same pattern as [ThemeNotifier] in
|
||||||
|
/// `lib/core/theme/theme_provider.dart`.
|
||||||
|
@Riverpod(keepAlive: true)
|
||||||
|
class SortPreferenceNotifier extends _$SortPreferenceNotifier {
|
||||||
|
@override
|
||||||
|
TaskSortOption build() {
|
||||||
|
_loadPersisted();
|
||||||
|
return TaskSortOption.alphabetical;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadPersisted() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final persisted = prefs.getString(_sortOptionKey);
|
||||||
|
if (persisted != null) {
|
||||||
|
state = _fromString(persisted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the active sort preference and persist it.
|
||||||
|
Future<void> setSortOption(TaskSortOption option) async {
|
||||||
|
state = option;
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setString(_sortOptionKey, _toString(option));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSortOption _fromString(String value) {
|
||||||
|
switch (value) {
|
||||||
|
case 'alphabetical':
|
||||||
|
return TaskSortOption.alphabetical;
|
||||||
|
case 'interval':
|
||||||
|
return TaskSortOption.interval;
|
||||||
|
case 'effort':
|
||||||
|
return TaskSortOption.effort;
|
||||||
|
default:
|
||||||
|
return TaskSortOption.alphabetical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static String _toString(TaskSortOption option) {
|
||||||
|
return option.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'sort_preference_notifier.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// RiverpodGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint, type=warning
|
||||||
|
/// Notifier that manages the active task sort preference.
|
||||||
|
///
|
||||||
|
/// Defaults to [TaskSortOption.alphabetical] synchronously (matching the
|
||||||
|
/// existing A-Z sort in CalendarDayList), then loads the persisted value
|
||||||
|
/// asynchronously on first build.
|
||||||
|
///
|
||||||
|
/// Follows the same pattern as [ThemeNotifier] in
|
||||||
|
/// `lib/core/theme/theme_provider.dart`.
|
||||||
|
|
||||||
|
@ProviderFor(SortPreferenceNotifier)
|
||||||
|
final sortPreferenceProvider = SortPreferenceNotifierProvider._();
|
||||||
|
|
||||||
|
/// Notifier that manages the active task sort preference.
|
||||||
|
///
|
||||||
|
/// Defaults to [TaskSortOption.alphabetical] synchronously (matching the
|
||||||
|
/// existing A-Z sort in CalendarDayList), then loads the persisted value
|
||||||
|
/// asynchronously on first build.
|
||||||
|
///
|
||||||
|
/// Follows the same pattern as [ThemeNotifier] in
|
||||||
|
/// `lib/core/theme/theme_provider.dart`.
|
||||||
|
final class SortPreferenceNotifierProvider
|
||||||
|
extends $NotifierProvider<SortPreferenceNotifier, TaskSortOption> {
|
||||||
|
/// Notifier that manages the active task sort preference.
|
||||||
|
///
|
||||||
|
/// Defaults to [TaskSortOption.alphabetical] synchronously (matching the
|
||||||
|
/// existing A-Z sort in CalendarDayList), then loads the persisted value
|
||||||
|
/// asynchronously on first build.
|
||||||
|
///
|
||||||
|
/// Follows the same pattern as [ThemeNotifier] in
|
||||||
|
/// `lib/core/theme/theme_provider.dart`.
|
||||||
|
SortPreferenceNotifierProvider._()
|
||||||
|
: super(
|
||||||
|
from: null,
|
||||||
|
argument: null,
|
||||||
|
retry: null,
|
||||||
|
name: r'sortPreferenceProvider',
|
||||||
|
isAutoDispose: false,
|
||||||
|
dependencies: null,
|
||||||
|
$allTransitiveDependencies: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String debugGetCreateSourceHash() => _$sortPreferenceNotifierHash();
|
||||||
|
|
||||||
|
@$internal
|
||||||
|
@override
|
||||||
|
SortPreferenceNotifier create() => SortPreferenceNotifier();
|
||||||
|
|
||||||
|
/// {@macro riverpod.override_with_value}
|
||||||
|
Override overrideWithValue(TaskSortOption value) {
|
||||||
|
return $ProviderOverride(
|
||||||
|
origin: this,
|
||||||
|
providerOverride: $SyncValueProvider<TaskSortOption>(value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _$sortPreferenceNotifierHash() =>
|
||||||
|
r'5d7f2c5d06b82b4114262ee05cf890ebe717fe2a';
|
||||||
|
|
||||||
|
/// Notifier that manages the active task sort preference.
|
||||||
|
///
|
||||||
|
/// Defaults to [TaskSortOption.alphabetical] synchronously (matching the
|
||||||
|
/// existing A-Z sort in CalendarDayList), then loads the persisted value
|
||||||
|
/// asynchronously on first build.
|
||||||
|
///
|
||||||
|
/// Follows the same pattern as [ThemeNotifier] in
|
||||||
|
/// `lib/core/theme/theme_provider.dart`.
|
||||||
|
|
||||||
|
abstract class _$SortPreferenceNotifier extends $Notifier<TaskSortOption> {
|
||||||
|
TaskSortOption build();
|
||||||
|
@$mustCallSuper
|
||||||
|
@override
|
||||||
|
void runBuild() {
|
||||||
|
final ref = this.ref as $Ref<TaskSortOption, TaskSortOption>;
|
||||||
|
final element =
|
||||||
|
ref.element
|
||||||
|
as $ClassProviderElement<
|
||||||
|
AnyNotifier<TaskSortOption, TaskSortOption>,
|
||||||
|
TaskSortOption,
|
||||||
|
Object?,
|
||||||
|
Object?
|
||||||
|
>;
|
||||||
|
element.handleCreate(ref, build);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -115,5 +115,9 @@
|
|||||||
"placeholders": {
|
"placeholders": {
|
||||||
"count": { "type": "int" }
|
"count": { "type": "int" }
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"sortAlphabetical": "A\u2013Z",
|
||||||
|
"sortInterval": "Intervall",
|
||||||
|
"sortEffort": "Aufwand",
|
||||||
|
"sortLabel": "Sortierung"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -537,6 +537,30 @@ abstract class AppLocalizations {
|
|||||||
/// In de, this message translates to:
|
/// In de, this message translates to:
|
||||||
/// **'{count} Mal erledigt'**
|
/// **'{count} Mal erledigt'**
|
||||||
String taskHistoryCount(int count);
|
String taskHistoryCount(int count);
|
||||||
|
|
||||||
|
/// No description provided for @sortAlphabetical.
|
||||||
|
///
|
||||||
|
/// In de, this message translates to:
|
||||||
|
/// **'A–Z'**
|
||||||
|
String get sortAlphabetical;
|
||||||
|
|
||||||
|
/// No description provided for @sortInterval.
|
||||||
|
///
|
||||||
|
/// In de, this message translates to:
|
||||||
|
/// **'Intervall'**
|
||||||
|
String get sortInterval;
|
||||||
|
|
||||||
|
/// No description provided for @sortEffort.
|
||||||
|
///
|
||||||
|
/// In de, this message translates to:
|
||||||
|
/// **'Aufwand'**
|
||||||
|
String get sortEffort;
|
||||||
|
|
||||||
|
/// No description provided for @sortLabel.
|
||||||
|
///
|
||||||
|
/// In de, this message translates to:
|
||||||
|
/// **'Sortierung'**
|
||||||
|
String get sortLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate
|
class _AppLocalizationsDelegate
|
||||||
|
|||||||
@@ -250,4 +250,16 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String taskHistoryCount(int count) {
|
String taskHistoryCount(int count) {
|
||||||
return '$count Mal erledigt';
|
return '$count Mal erledigt';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sortAlphabetical => 'A–Z';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sortInterval => 'Intervall';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sortEffort => 'Aufwand';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sortLabel => 'Sortierung';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user