refactor: implement suggestions

This commit is contained in:
Yaros
2026-05-08 15:59:41 +02:00
parent 7956756d38
commit 12c4ee83d6
6 changed files with 96 additions and 59 deletions
@@ -27,19 +27,20 @@ class DriftMapRepository extends DriftDatabaseRepository {
condition = condition & _db.remoteAssetEntity.isFavorite.equals(true);
}
final from = options.timeRange.from;
final to = options.timeRange.to;
final timeRange = options.timeRange;
final hasCustomRange = timeRange.from.isSome || timeRange.to.isSome;
if (from != null || to != null) {
if (from != null) {
if (hasCustomRange) {
timeRange.from.ifSome((from) {
condition = condition & _db.remoteAssetEntity.createdAt.isBiggerOrEqualValue(from);
}
if (to != null) {
});
timeRange.to.ifSome((to) {
condition = condition & _db.remoteAssetEntity.createdAt.isSmallerOrEqualValue(to);
}
});
} else if (options.relativeDays > 0) {
final fromDate = DateTime.now().subtract(Duration(days: options.relativeDays));
condition = condition & _db.remoteAssetEntity.createdAt.isBiggerOrEqualValue(fromDate);
final cutoffDate = DateTime.now().toUtc().subtract(Duration(days: options.relativeDays));
condition = condition & _db.remoteAssetEntity.createdAt.isBiggerOrEqualValue(cutoffDate);
}
return condition;
@@ -552,20 +552,21 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
query.where(_db.remoteAssetEntity.isFavorite.equals(true));
}
final from = options.timeRange.from;
final to = options.timeRange.to;
final timeRange = options.timeRange;
if (from != null || to != null) {
// Use custom from/to filters
if (from != null) {
final hasCustomRange = timeRange.from.isSome || timeRange.to.isSome;
if (hasCustomRange) {
timeRange.from.ifSome((from) {
query.where(_db.remoteAssetEntity.createdAt.isBiggerOrEqualValue(from));
}
if (to != null) {
});
timeRange.to.ifSome((to) {
query.where(_db.remoteAssetEntity.createdAt.isSmallerOrEqualValue(to));
}
});
} else if (options.relativeDays > 0) {
// Use relative days
final cutoffDate = DateTime.now().toUtc().subtract(Duration(days: options.relativeDays));
query.where(_db.remoteAssetEntity.createdAt.isBiggerOrEqualValue(cutoffDate));
}
@@ -606,20 +607,21 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
query.where(_db.remoteAssetEntity.isFavorite.equals(true));
}
final from = options.timeRange.from;
final to = options.timeRange.to;
final timeRange = options.timeRange;
if (from != null || to != null) {
// Use custom from/to filters
if (from != null) {
final hasCustomRange = timeRange.from.isSome || timeRange.to.isSome;
if (hasCustomRange) {
timeRange.from.ifSome((from) {
query.where(_db.remoteAssetEntity.createdAt.isBiggerOrEqualValue(from));
}
if (to != null) {
});
timeRange.to.ifSome((to) {
query.where(_db.remoteAssetEntity.createdAt.isSmallerOrEqualValue(to));
}
});
} else if (options.relativeDays > 0) {
// Use relative days
final cutoffDate = DateTime.now().toUtc().subtract(Duration(days: options.relativeDays));
query.where(_db.remoteAssetEntity.createdAt.isBiggerOrEqualValue(cutoffDate));
}
@@ -7,15 +7,16 @@ import 'package:immich_mobile/providers/app_settings.provider.dart';
import 'package:immich_mobile/providers/infrastructure/map.provider.dart';
import 'package:immich_mobile/providers/map/map_state.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/utils/option.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
class TimeRange {
final DateTime? from;
final DateTime? to;
final Option<DateTime> from;
final Option<DateTime> to;
const TimeRange({this.from, this.to});
const TimeRange({this.from = const None(), this.to = const None()});
TimeRange copyWith({DateTime? from, DateTime? to}) {
TimeRange copyWith({Option<DateTime>? from, Option<DateTime>? to}) {
return TimeRange(from: from ?? this.from, to: to ?? this.to);
}
@@ -75,6 +76,7 @@ class MapState {
onlyFavorites: onlyFavorites,
includeArchived: includeArchived,
withPartners: withPartners,
relativeDays: relativeDays,
timeRange: timeRange,
);
}
@@ -123,31 +125,40 @@ class MapStateNotifier extends Notifier<MapState> {
}
void setTimeRange(TimeRange range) {
ref
.read(appSettingsServiceProvider)
.setSetting(AppSettingsEnum.mapCustomFrom, range.from == null ? "" : range.from!.toIso8601String());
ref
.read(appSettingsServiceProvider)
.setSetting(AppSettingsEnum.mapCustomTo, range.to == null ? "" : range.to!.toIso8601String());
final from = range.from.unwrapOrNull;
final to = range.to.unwrapOrNull;
ref.read(appSettingsServiceProvider).setSetting(AppSettingsEnum.mapCustomFrom, from?.toIso8601String() ?? "");
ref.read(appSettingsServiceProvider).setSetting(AppSettingsEnum.mapCustomTo, to?.toIso8601String() ?? "");
state = state.copyWith(timeRange: range);
EventStream.shared.emit(const MapMarkerReloadEvent());
}
Option<DateTime> parseDateOption(String s) {
try {
if (s.trim().isEmpty) return const Option.none();
return Option.some(DateTime.parse(s));
} catch (_) {
return const Option.none();
}
}
@override
MapState build() {
final appSettingsService = ref.read(appSettingsServiceProvider);
final customFrom = appSettingsService.getSetting(AppSettingsEnum.mapCustomFrom);
final customTo = appSettingsService.getSetting(AppSettingsEnum.mapCustomTo);
final customFrom = appSettingsService.getSetting(AppSettingsEnum.mapCustomFrom).toOption().flatMap(parseDateOption);
final customTo = appSettingsService.getSetting(AppSettingsEnum.mapCustomTo).toOption().flatMap(parseDateOption);
return MapState(
themeMode: ThemeMode.values[appSettingsService.getSetting(AppSettingsEnum.mapThemeMode)],
onlyFavorites: appSettingsService.getSetting(AppSettingsEnum.mapShowFavoriteOnly),
includeArchived: appSettingsService.getSetting(AppSettingsEnum.mapIncludeArchived),
withPartners: appSettingsService.getSetting(AppSettingsEnum.mapwithPartners),
bounds: LatLngBounds(northeast: const LatLng(0, 0), southwest: const LatLng(0, 0)),
timeRange: TimeRange(
from: customFrom.isNotEmpty ? DateTime.parse(customFrom) : null,
to: customTo.isNotEmpty ? DateTime.parse(customTo) : null,
),
relativeDays: appSettingsService.getSetting(AppSettingsEnum.mapRelativeDate),
timeRange: TimeRange(from: customFrom, to: customTo),
);
}
}
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/presentation/widgets/map/map.state.dart';
import 'package:immich_mobile/widgets/map/map_settings/map_custom_time_range.dart';
import 'package:immich_mobile/widgets/map/map_settings/map_settings_list_tile.dart';
@@ -22,7 +23,7 @@ class _DriftMapSettingsSheetState extends ConsumerState<DriftMapSettingsSheet> {
super.initState();
final mapState = ref.read(mapStateProvider);
final timeRange = mapState.timeRange;
useCustomRange = timeRange.from != null || timeRange.to != null;
useCustomRange = timeRange.from.isSome || timeRange.to.isSome;
}
@override
@@ -78,7 +79,7 @@ class _DriftMapSettingsSheetState extends ConsumerState<DriftMapSettingsSheet> {
ref.read(mapStateProvider.notifier).setRelativeTime(0);
ref.read(mapStateProvider.notifier).setTimeRange(const TimeRange());
}),
child: Text("remove_custom_date_range".t(context: context)),
child: Text(context.t.remove_custom_date_range),
),
),
] else ...[
@@ -94,7 +95,7 @@ class _DriftMapSettingsSheetState extends ConsumerState<DriftMapSettingsSheet> {
ref.read(mapStateProvider.notifier).setRelativeTime(0);
ref.read(mapStateProvider.notifier).setTimeRange(const TimeRange());
}),
child: Text("use_custom_date_range".t(context: context)),
child: Text(context.t.use_custom_date_range),
),
),
],
+15
View File
@@ -24,6 +24,21 @@ sealed class Option<T> {
None() => onNone(),
};
Option<U> flatMap<U>(Option<U> Function(T value) f) => switch (this) {
Some(:final value) => f(value),
None() => const Option.none(),
};
void ifSome(void Function(T value) action) {
switch (this) {
case Some(:final value):
action(value);
break;
case None():
break;
}
}
@override
String toString() => switch (this) {
Some(:final value) => 'Some($value)',
@@ -1,6 +1,8 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/presentation/widgets/map/map.state.dart';
import 'package:immich_mobile/utils/option.dart';
import 'package:intl/intl.dart';
class MapTimeRange extends StatelessWidget {
@@ -15,44 +17,49 @@ class MapTimeRange extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: Text("date_after".t(context: context)),
title: Text(context.t.date_after),
subtitle: Text(
timeRange.from != null
? DateFormat.yMMMd().add_jm().format(timeRange.from!)
: "not_set".t(context: context),
timeRange.from.fold((from) => DateFormat.yMMMd().add_jm().format(from), () => context.t.not_set),
),
trailing: timeRange.from != null
trailing: timeRange.from.isSome
? IconButton(icon: const Icon(Icons.close), onPressed: () => onChanged(timeRange.clearFrom()))
: null,
onTap: () async {
final initial = timeRange.from.unwrapOrNull ?? DateTime.now();
final picked = await showDatePicker(
context: context,
initialDate: timeRange.from ?? DateTime.now(),
initialDate: initial,
firstDate: DateTime(1970),
lastDate: DateTime.now(),
);
if (picked != null) {
onChanged(timeRange.copyWith(from: picked));
onChanged(timeRange.copyWith(from: Option.some(picked)));
}
},
),
ListTile(
title: Text("date_before".t(context: context)),
title: Text(context.t.date_before),
subtitle: Text(
timeRange.to != null ? DateFormat.yMMMd().add_jm().format(timeRange.to!) : "not_set".t(context: context),
timeRange.to.fold<String>((to) => DateFormat.yMMMd().add_jm().format(to), () => context.t.not_set),
),
trailing: timeRange.to != null
trailing: timeRange.to.isSome
? IconButton(icon: const Icon(Icons.close), onPressed: () => onChanged(timeRange.clearTo()))
: null,
onTap: () async {
final initial = timeRange.to.unwrapOrNull ?? DateTime.now();
final picked = await showDatePicker(
context: context,
initialDate: timeRange.to ?? DateTime.now(),
initialDate: initial,
firstDate: DateTime(1970),
lastDate: DateTime.now(),
);
if (picked != null) {
onChanged(timeRange.copyWith(to: picked));
onChanged(timeRange.copyWith(to: Option.some(picked)));
}
},
),