diff --git a/src/app/features/metric/metric.service.ts b/src/app/features/metric/metric.service.ts index c35a38d60a..b16e3b925a 100644 --- a/src/app/features/metric/metric.service.ts +++ b/src/app/features/metric/metric.service.ts @@ -6,6 +6,7 @@ import { deleteMetric, updateMetric, upsertMetric, + logFocusSession, } from './store/metric.actions'; import { combineLatest, Observable, of } from 'rxjs'; import { LineChartData, Metric, MetricState } from './metric.model'; @@ -19,7 +20,7 @@ import { selectSimpleCounterClickCounterLineChartData, selectSimpleCounterStopWatchLineChartData, } from './store/metric.selectors'; -import { map, switchMap, take } from 'rxjs/operators'; +import { map, switchMap } from 'rxjs/operators'; import { DEFAULT_METRIC_FOR_DAY } from './metric.const'; import { selectCheckedImprovementIdsForDay, @@ -27,6 +28,8 @@ import { } from './improvement/store/improvement.reducer'; import { DateService } from 'src/app/core/date/date.service'; +const MIN_FOCUS_SESSION_DURATION = 1000; + @Injectable({ providedIn: 'root', }) @@ -116,37 +119,16 @@ export class MetricService { } logFocusSession(duration: number, day: string = this._dateService.todayStr()): void { - if (!duration || duration <= 0) { + if (!duration || duration < MIN_FOCUS_SESSION_DURATION) { return; } - this._store$ - .pipe(select(selectMetricById, { id: day }), take(1)) - .subscribe((metric) => { - if (metric) { - const focusSessions = metric.focusSessions ?? []; - this._store$.dispatch( - updateMetric({ - metric: { - id: day, - changes: { - focusSessions: [...focusSessions, duration], - }, - }, - }), - ); - } else { - this._store$.dispatch( - upsertMetric({ - metric: { - id: day, - ...DEFAULT_METRIC_FOR_DAY, - focusSessions: [duration], - }, - }), - ); - } - }); + this._store$.dispatch( + logFocusSession({ + day, + duration, + }), + ); } // STATISTICS diff --git a/src/app/features/metric/store/metric.actions.ts b/src/app/features/metric/store/metric.actions.ts index 2823919a53..ea4830e523 100644 --- a/src/app/features/metric/store/metric.actions.ts +++ b/src/app/features/metric/store/metric.actions.ts @@ -7,6 +7,7 @@ enum MetricActionTypes { 'UpdateMetric' = '[Metric] Update Metric', 'UpsertMetric' = '[Metric] Upsert Metric', 'DeleteMetric' = '[Metric] Delete Metric', + 'LogFocusSession' = '[Metric] Log Focus Session', } export const addMetric = createAction( @@ -28,3 +29,8 @@ export const deleteMetric = createAction( MetricActionTypes.DeleteMetric, props<{ id: string }>(), ); + +export const logFocusSession = createAction( + MetricActionTypes.LogFocusSession, + props<{ day: string; duration: number }>(), +); diff --git a/src/app/features/metric/store/metric.reducer.ts b/src/app/features/metric/store/metric.reducer.ts index 73cd00fd28..b86cd00f81 100644 --- a/src/app/features/metric/store/metric.reducer.ts +++ b/src/app/features/metric/store/metric.reducer.ts @@ -1,8 +1,15 @@ import { createEntityAdapter, EntityAdapter } from '@ngrx/entity'; -import { addMetric, deleteMetric, updateMetric, upsertMetric } from './metric.actions'; +import { + addMetric, + deleteMetric, + updateMetric, + upsertMetric, + logFocusSession, +} from './metric.actions'; import { Metric, MetricState } from '../metric.model'; import { loadAllData } from '../../../root-store/meta/load-all-data.action'; import { createReducer, on } from '@ngrx/store'; +import { DEFAULT_METRIC_FOR_DAY } from '../metric.const'; export const METRIC_FEATURE_NAME = 'metric'; export const metricAdapter: EntityAdapter = createEntityAdapter(); @@ -25,4 +32,31 @@ export const metricReducer = createReducer( on(upsertMetric, (state, { metric }) => metricAdapter.upsertOne(metric, state)), on(deleteMetric, (state, { id }) => metricAdapter.removeOne(id, state)), + + on(logFocusSession, (state, { day, duration }) => { + if (duration <= 0) { + return state; + } + + const existing = state.entities[day]; + if (existing) { + const focusSessions = existing.focusSessions ?? []; + return metricAdapter.updateOne( + { + id: day, + changes: { + focusSessions: [...focusSessions, duration], + }, + }, + state, + ); + } + + const newMetric: Metric = { + id: day, + ...DEFAULT_METRIC_FOR_DAY, + focusSessions: [duration], + }; + return metricAdapter.upsertOne(newMetric, state); + }), );