Allow using custom time range in map

This commit is contained in:
Ming Ming 2024-08-24 23:07:25 +08:00
parent d4d0160642
commit 655ce1a3fe
8 changed files with 66 additions and 7 deletions

View file

@ -204,6 +204,12 @@ class PrefController {
value: value, value: value,
); );
Future<bool> setMapDefaultCustomRange(Duration value) => _set<Duration>(
controller: _mapDefaultCustomRangeController,
setter: (pref, value) => pref.setMapDefaultCustomRange(value),
value: value,
);
Future<bool> _set<T>({ Future<bool> _set<T>({
required BehaviorSubject<T> controller, required BehaviorSubject<T> controller,
required Future<bool> Function(Pref pref, T value) setter, required Future<bool> Function(Pref pref, T value) setter,
@ -328,6 +334,9 @@ class PrefController {
@npSubjectAccessor @npSubjectAccessor
late final _mapDefaultRangeTypeController = BehaviorSubject.seeded( late final _mapDefaultRangeTypeController = BehaviorSubject.seeded(
pref.getMapDefaultRangeType() ?? PrefMapDefaultRangeType.thisMonth); pref.getMapDefaultRangeType() ?? PrefMapDefaultRangeType.thisMonth);
@npSubjectAccessor
late final _mapDefaultCustomRangeController = BehaviorSubject.seeded(
pref.getMapDefaultCustomRange() ?? const Duration(days: 30));
} }
extension PrefControllerExtension on PrefController { extension PrefControllerExtension on PrefController {

View file

@ -197,6 +197,15 @@ extension $PrefControllerNpSubjectAccessor on PrefController {
mapDefaultRangeType.distinct().skip(1); mapDefaultRangeType.distinct().skip(1);
PrefMapDefaultRangeType get mapDefaultRangeTypeValue => PrefMapDefaultRangeType get mapDefaultRangeTypeValue =>
_mapDefaultRangeTypeController.value; _mapDefaultRangeTypeController.value;
// _mapDefaultCustomRangeController
ValueStream<Duration> get mapDefaultCustomRange =>
_mapDefaultCustomRangeController.stream;
Stream<Duration> get mapDefaultCustomRangeNew =>
mapDefaultCustomRange.skip(1);
Stream<Duration> get mapDefaultCustomRangeChange =>
mapDefaultCustomRange.distinct().skip(1);
Duration get mapDefaultCustomRangeValue =>
_mapDefaultCustomRangeController.value;
} }
extension $SecurePrefControllerNpSubjectAccessor on SecurePrefController { extension $SecurePrefControllerNpSubjectAccessor on SecurePrefController {

View file

@ -4,6 +4,7 @@ enum PrefMapDefaultRangeType {
thisMonth(0), thisMonth(0),
prevMonth(1), prevMonth(1),
thisYear(2), thisYear(2),
custom(3),
; ;
const PrefMapDefaultRangeType(this.value); const PrefMapDefaultRangeType(this.value);

View file

@ -125,6 +125,12 @@ extension on Pref {
?.let(PrefMapDefaultRangeType.fromValue); ?.let(PrefMapDefaultRangeType.fromValue);
Future<bool> setMapDefaultRangeType(PrefMapDefaultRangeType value) => Future<bool> setMapDefaultRangeType(PrefMapDefaultRangeType value) =>
provider.setInt(PrefKey.mapDefaultRangeType, value.value); provider.setInt(PrefKey.mapDefaultRangeType, value.value);
Duration? getMapDefaultCustomRange() => provider
.getInt(PrefKey.mapDefaultCustomRange)
?.let((v) => Duration(days: v));
Future<bool> setMapDefaultCustomRange(Duration value) =>
provider.setInt(PrefKey.mapDefaultCustomRange, value.inDays);
} }
MapCoord? _tryMapCoordFromJson(dynamic json) { MapCoord? _tryMapCoordFromJson(dynamic json) {

View file

@ -116,6 +116,7 @@ enum PrefKey implements PrefKeyInterface {
mapBrowserPrevPosition, mapBrowserPrevPosition,
isNewHttpEngine, isNewHttpEngine,
mapDefaultRangeType, mapDefaultRangeType,
mapDefaultCustomRange,
; ;
@override @override
@ -208,6 +209,8 @@ enum PrefKey implements PrefKeyInterface {
return "isNewHttpEngine"; return "isNewHttpEngine";
case PrefKey.mapDefaultRangeType: case PrefKey.mapDefaultRangeType:
return "mapDefaultRangeType"; return "mapDefaultRangeType";
case PrefKey.mapDefaultCustomRange:
return "mapDefaultCustomRange";
} }
} }
} }

View file

@ -54,10 +54,24 @@ class _Bloc extends Bloc<_Event, _State>
static _State _getInitialState(PrefController prefController) { static _State _getInitialState(PrefController prefController) {
final dateRangeType = final dateRangeType =
_DateRangeType.fromPref(prefController.mapDefaultRangeTypeValue); _DateRangeType.fromPref(prefController.mapDefaultRangeTypeValue);
return _State.init( if (dateRangeType == _DateRangeType.custom) {
dateRangeType: dateRangeType, final today = clock.now().toDate();
localDateRange: _calcDateRange(clock.now().toDate(), dateRangeType), return _State.init(
); dateRangeType: dateRangeType,
localDateRange: DateRange(
from: today.add(
day: -prefController.mapDefaultCustomRangeValue.inDays,
),
to: today,
toBound: TimeRangeBound.inclusive,
),
);
} else {
return _State.init(
dateRangeType: dateRangeType,
localDateRange: _calcDateRange(clock.now().toDate(), dateRangeType),
);
}
} }
Future<void> _onLoadData(_LoadData ev, Emitter<_State> emit) async { Future<void> _onLoadData(_LoadData ev, Emitter<_State> emit) async {
@ -118,6 +132,10 @@ class _Bloc extends Bloc<_Event, _State>
dateRangeType: _DateRangeType.custom, dateRangeType: _DateRangeType.custom,
localDateRange: ev.value, localDateRange: ev.value,
)); ));
if (prefController.mapDefaultRangeTypeValue ==
PrefMapDefaultRangeType.custom) {
_updatePrefDefaultCustomRange(ev.value);
}
} }
void _onSetPrefDateRangeType(_SetPrefDateRangeType ev, Emitter<_State> emit) { void _onSetPrefDateRangeType(_SetPrefDateRangeType ev, Emitter<_State> emit) {
@ -128,6 +146,9 @@ class _Bloc extends Bloc<_Event, _State>
void _onSetAsDefaultRange(_SetAsDefaultRange ev, Emitter<_State> emit) { void _onSetAsDefaultRange(_SetAsDefaultRange ev, Emitter<_State> emit) {
_log.info(ev); _log.info(ev);
prefController.setMapDefaultRangeType(state.dateRangeType.toPref()); prefController.setMapDefaultRangeType(state.dateRangeType.toPref());
if (state.dateRangeType == _DateRangeType.custom) {
_updatePrefDefaultCustomRange(state.localDateRange);
}
} }
void _onSetError(_SetError ev, Emitter<_State> emit) { void _onSetError(_SetError ev, Emitter<_State> emit) {
@ -173,6 +194,12 @@ class _Bloc extends Bloc<_Event, _State>
} }
} }
void _updatePrefDefaultCustomRange(DateRange value) {
final today = clock.now().toDate();
final diff = today.difference(value.from!);
prefController.setMapDefaultCustomRange(diff);
}
final DiContainer _c; final DiContainer _c;
final Account account; final Account account;
final PrefController prefController; final PrefController prefController;

View file

@ -259,6 +259,8 @@ enum _DateRangeType {
return prevMonth; return prevMonth;
case PrefMapDefaultRangeType.thisYear: case PrefMapDefaultRangeType.thisYear:
return thisYear; return thisYear;
case PrefMapDefaultRangeType.custom:
return custom;
} }
} }
@ -284,7 +286,7 @@ enum _DateRangeType {
case thisYear: case thisYear:
return PrefMapDefaultRangeType.thisYear; return PrefMapDefaultRangeType.thisYear;
case custom: case custom:
throw ArgumentError("Value not supported"); return PrefMapDefaultRangeType.custom;
} }
} }
} }

View file

@ -401,10 +401,12 @@ class _SetAsDefaultSwitch extends StatelessWidget {
return _BlocBuilder( return _BlocBuilder(
buildWhen: (previous, current) => buildWhen: (previous, current) =>
previous.dateRangeType != current.dateRangeType || previous.dateRangeType != current.dateRangeType ||
previous.prefDateRangeType != current.prefDateRangeType, previous.prefDateRangeType != current.prefDateRangeType ||
previous.localDateRange != current.localDateRange,
builder: (context, state) { builder: (context, state) {
final isChecked = state.dateRangeType == state.prefDateRangeType; final isChecked = state.dateRangeType == state.prefDateRangeType;
final isEnabled = state.dateRangeType != _DateRangeType.custom; final isEnabled = state.dateRangeType != _DateRangeType.custom ||
state.localDateRange.to == clock.now().toDate();
return InkWell( return InkWell(
customBorder: customBorder:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(64)), RoundedRectangleBorder(borderRadius: BorderRadius.circular(64)),