mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
refactor: implement suggestions
This commit is contained in:
@@ -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),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user