feat(focusMode): better integrate idle case

This commit is contained in:
Johannes Millan 2025-02-28 15:37:18 +01:00
parent ddd822b385
commit 5bfb6bcf64
12 changed files with 247 additions and 143 deletions

View file

@ -8,7 +8,9 @@
></task-title>
<div class="progress-wrapper">
@if (isCountTimeDown) {
<progress-circle [progress]="sessionProgress$ | async"></progress-circle>
<progress-circle
[progress]="focusModeService.sessionProgress$ | async"
></progress-circle>
} @else {
<progress-circle [autoRotationDuration]="60000"></progress-circle>
}
@ -19,7 +21,7 @@
>
<!-- {{focusModeTimeToGo / 60000}}min-->
@if (isCountTimeDown) {
{{ timeToGo$ | async | msToMinuteClockString }}
{{ focusModeService.timeToGo$ | async | msToMinuteClockString }}
} @else {
{{ timeElapsed$ | async | msToMinuteClockString }}
}

View file

@ -18,9 +18,7 @@ import { IssueService } from '../../issue/issue.service';
import { Store } from '@ngrx/store';
import {
selectFocusModeMode,
selectFocusSessionProgress,
selectFocusSessionTimeElapsed,
selectFocusSessionTimeToGo,
} from '../store/focus-mode.selectors';
import { focusSessionDone, setFocusSessionActivePage } from '../store/focus-mode.actions';
import { updateTask } from '../../tasks/store/task.actions';
@ -42,6 +40,7 @@ import { IssueIconPipe } from '../../issue/issue-icon/issue-icon.pipe';
import { SimpleCounterButtonComponent } from '../../simple-counter/simple-counter-button/simple-counter-button.component';
import { TaskAttachmentListComponent } from '../../tasks/task-attachment/task-attachment-list/task-attachment-list.component';
import { slideInOutFromBottomAni } from '../../../ui/animations/slide-in-out-from-bottom.ani';
import { FocusModeService } from '../focus-mode.service';
@Component({
selector: 'focus-mode-main',
@ -74,13 +73,12 @@ export class FocusModeMainComponent implements OnDestroy {
private readonly _issueService = inject(IssueService);
private readonly _store = inject(Store);
timeToGo$ = this._store.select(selectFocusSessionTimeToGo);
focusModeService = inject(FocusModeService);
timeElapsed$ = this._store.select(selectFocusSessionTimeElapsed);
mode$ = this._store.select(selectFocusModeMode);
isCountTimeDown$ = this.mode$.pipe(map((mode) => mode !== FocusModeMode.Flowtime));
sessionProgress$ = this._store.select(selectFocusSessionProgress);
@HostBinding('class.isShowNotes') isShowNotes: boolean = false;
task: TaskCopy | null = null;
@ -165,7 +163,7 @@ export class FocusModeMainComponent implements OnDestroy {
}
finishCurrentTask(): void {
this._store.dispatch(focusSessionDone());
this._store.dispatch(focusSessionDone({}));
this._store.dispatch(
updateTask({
task: {

View file

@ -9,9 +9,7 @@ import { Store } from '@ngrx/store';
import {
selectFocusModeMode,
selectFocusSessionActivePage,
selectFocusSessionProgress,
selectFocusSessionTimeElapsed,
selectFocusSessionTimeToGo,
selectIsFocusSessionRunning,
} from '../store/focus-mode.selectors';
import {
@ -40,6 +38,7 @@ import { BannerService } from '../../../core/banner/banner.service';
import { BannerId } from '../../../core/banner/banner.model';
import { toSignal } from '@angular/core/rxjs-interop';
import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle';
import { FocusModeService } from '../focus-mode.service';
@Component({
selector: 'focus-mode-overlay',
@ -68,6 +67,8 @@ import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-
export class FocusModeOverlayComponent implements OnDestroy {
readonly taskService = inject(TaskService);
readonly bannerService = inject(BannerService);
readonly focusModeService = inject(FocusModeService);
private readonly _globalConfigService = inject(GlobalConfigService);
private readonly _store = inject(Store);
@ -151,10 +152,8 @@ export class FocusModeOverlayComponent implements OnDestroy {
msg: 'Focus Session is running',
timer$: isCountTimeUp
? this._store.select(selectFocusSessionTimeElapsed)
: this._store.select(selectFocusSessionTimeToGo),
progress$: isCountTimeUp
? undefined
: this._store.select(selectFocusSessionProgress),
: this.focusModeService.timeToGo$,
progress$: isCountTimeUp ? undefined : this.focusModeService.sessionProgress$,
action2: {
label: 'To Focus Overlay',
fn: () => {

View file

@ -0,0 +1,103 @@
import { inject, Injectable } from '@angular/core';
import { combineLatest, EMPTY, interval, merge, Observable, of } from 'rxjs';
import {
selectFocusSessionDuration,
selectIsFocusSessionRunning,
} from './store/focus-mode.selectors';
import {
map,
mapTo,
pairwise,
scan,
shareReplay,
startWith,
switchMap,
tap,
} from 'rxjs/operators';
import { Actions, ofType } from '@ngrx/effects';
import { cancelFocusSession, unPauseFocusSession } from './store/focus-mode.actions';
import { Store } from '@ngrx/store';
const TICK_DURATION = 500;
@Injectable({
providedIn: 'root',
})
export class FocusModeService {
private _store = inject(Store);
private _actions$ = inject(Actions);
private _isRunning$ = this._store.select(selectIsFocusSessionRunning);
private _plannedSessionDuration$ = this._store.select(selectFocusSessionDuration);
private _timer$: Observable<number> = interval(TICK_DURATION).pipe(
switchMap(() => of(Date.now())),
pairwise(),
map(([a, b]) => b - a),
);
private _tick$: Observable<number> = this._isRunning$.pipe(
switchMap((isRunning) => (isRunning ? this._timer$ : EMPTY)),
map((tick) => tick * -1),
);
currentSessionTime$: Observable<number> = merge(
// first val is negative otherwise
// TODO maybe comment in again
// startWith(567),
this._tick$,
this._actions$.pipe(ofType(cancelFocusSession), mapTo(0)),
this._actions$.pipe(
ofType(unPauseFocusSession),
map(({ idleTimeToAdd = 0 }) => idleTimeToAdd * -1),
),
// TODO remove if not needed
// this._store.select(selectFocusModeMode).pipe(
// switchMap((mode) =>
// mode === FocusModeMode.Countdown
// ? // needed in case plannedSessionDuration did not change
// this._actions$.pipe(
// ofType(startFocusSession, cancelFocusSession),
// switchMap(() => this._plannedSessionDuration$.pipe(first())),
// )
// : EMPTY,
// ),
// ),
).pipe(
scan((acc, value) => {
const accValMinZero = acc < 0 ? 0 : acc;
console.log('VALUPD currentSessionTime', value, value < 0, accValMinZero);
return value < 0 ? accValMinZero - value : value;
}),
shareReplay(1),
// tap((v) => console.log('___currentSessionTimeShared', v)),
);
timeToGo$: Observable<number> = combineLatest([
this.currentSessionTime$.pipe(startWith(0)),
this._plannedSessionDuration$,
]).pipe(
tap((v) => console.log('timeToGo$ params', v)),
map(
([currentSessionTime, plannedSessionDuration]) =>
plannedSessionDuration - currentSessionTime,
),
);
// timeToGo$: Observable<number> = this.currentSessionTime$.pipe(
// withLatestFrom(this._plannedSessionDuration$),
// tap((v) => console.log('timeToGo$ params', v)),
//
// map(
// ([currentSessionTime, plannedSessionDuration]) =>
// plannedSessionDuration - currentSessionTime,
// ),
// );
sessionProgress$ = combineLatest([this.timeToGo$, this._plannedSessionDuration$]).pipe(
// tap((v) => console.log('sessionProgress$ params', v)),
map(
([timeToGo, plannedSessionDuration]) =>
((plannedSessionDuration - timeToGo) * 100) / plannedSessionDuration,
),
);
}

View file

@ -15,18 +15,22 @@ export const setFocusSessionDuration = createAction(
props<{ focusSessionDuration: number }>(),
);
export const setFocusSessionTimeToGo = createAction(
'[FocusMode] Set focus session time to go',
props<{ focusSessionTimeToGo: number }>(),
);
export const setFocusSessionTimeElapsed = createAction(
'[FocusMode] Set focus session elapsed time',
props<{ focusSessionTimeElapsed: number }>(),
);
export const startFocusSession = createAction('[FocusMode] Start focus session');
export const cancelFocusSession = createAction('[FocusMode] Cancel Focus Session');
export const pauseFocusSession = createAction('[FocusMode] Pause Focus Session');
export const unPauseFocusSession = createAction(
'[FocusMode] UnPause Focus Session',
props<{ idleTimeToAdd?: number }>(),
);
export const focusSessionDone = createAction('[FocusMode] Focus session done');
export const focusSessionDone = createAction(
'[FocusMode] Focus session done',
props<{ isResetPlannedSessionDuration?: boolean }>(),
);
export const showFocusOverlay = createAction('[FocusMode] Show Focus Overlay');
export const hideFocusOverlay = createAction('[FocusMode] Hide Focus Overlay');

View file

@ -3,12 +3,11 @@ import { Actions, createEffect, ofType } from '@ngrx/effects';
import {
cancelFocusSession,
focusSessionDone,
pauseFocusSession,
setFocusModeMode,
setFocusSessionActivePage,
setFocusSessionTimeElapsed,
setFocusSessionTimeToGo,
showFocusOverlay,
startFocusSession,
} from './focus-mode.actions';
import { GlobalConfigService } from '../../config/global-config.service';
import {
@ -18,20 +17,16 @@ import {
first,
map,
mapTo,
pairwise,
scan,
startWith,
switchMap,
switchMapTo,
tap,
withLatestFrom,
} from 'rxjs/operators';
import { EMPTY, interval, merge, Observable, of } from 'rxjs';
import { EMPTY, Observable, of } from 'rxjs';
import { TaskService } from '../../tasks/task.service';
import {
selectFocusModeMode,
selectFocusSessionDuration,
selectFocusSessionProgress,
selectIsFocusSessionRunning,
} from './focus-mode.selectors';
import { Store } from '@ngrx/store';
@ -42,14 +37,16 @@ import { IdleService } from '../../idle/idle.service';
import { FocusModeMode, FocusModePage } from '../focus-mode.const';
import { selectFocusModeConfig } from '../../config/store/global-config.reducer';
import { LS } from '../../../core/persistence/storage-keys.const';
import { openIdleDialog } from '../../idle/store/idle.actions';
import { FocusModeService } from '../focus-mode.service';
const TICK_DURATION = 500;
const SESSION_DONE_SOUND = 'positive.ogg';
// const DEFAULT_TICK_SOUND = 'tick.mp3';
@Injectable()
export class FocusModeEffects {
private _focusModeService = inject(FocusModeService);
private _store = inject(Store);
private _actions$ = inject(Actions);
private _idleService = inject(IdleService);
@ -57,49 +54,8 @@ export class FocusModeEffects {
private _taskService = inject(TaskService);
private _isRunning$ = this._store.select(selectIsFocusSessionRunning);
private _sessionDuration$ = this._store.select(selectFocusSessionDuration);
private _sessionProgress$ = this._store.select(selectFocusSessionProgress);
private _timer$: Observable<number> = interval(TICK_DURATION).pipe(
switchMap(() => of(Date.now())),
pairwise(),
map(([a, b]) => b - a),
);
private _tick$: Observable<number> = this._isRunning$.pipe(
switchMap((isRunning) => (isRunning ? this._timer$ : EMPTY)),
map((tick) => tick * -1),
);
private _currentSessionTime$: Observable<number> = this._store
.select(selectFocusModeMode)
.pipe(
switchMap((mode) =>
mode === FocusModeMode.Countdown
? merge(
this._sessionDuration$,
this._tick$,
this._actions$.pipe(
ofType(startFocusSession, cancelFocusSession),
switchMap(() => this._sessionDuration$.pipe(first())),
),
).pipe(
scan((acc, value) => {
return value < 0 ? acc + value : value;
}),
)
: merge(
this._tick$,
this._actions$.pipe(ofType(cancelFocusSession), mapTo(0)),
).pipe(
// first val is negative otherwise
startWith(500),
scan((acc, value) => {
return value < 0 ? acc - value : value;
}),
),
),
);
// TODO also rename store value maybe
private _plannedSessionDuration$ = this._store.select(selectFocusSessionDuration);
autoStartFocusMode$ = createEffect(() => {
return this._store.select(selectFocusModeConfig).pipe(
@ -115,24 +71,36 @@ export class FocusModeEffects {
),
);
});
setElapsedTime$ = createEffect(() => {
return this._currentSessionTime$.pipe(
withLatestFrom(this._store.select(selectFocusModeMode)),
map(([focusSessionTimeToGo, mode]) => {
return this._focusModeService.currentSessionTime$.pipe(
tap((v) => console.log('currentSessionTime', v)),
withLatestFrom(
this._store.select(selectFocusModeMode),
this._focusModeService.timeToGo$,
),
map(([currentSessionTime, mode, timeToGo]) => {
if (mode === FocusModeMode.Flowtime) {
return setFocusSessionTimeElapsed({
focusSessionTimeElapsed: focusSessionTimeToGo,
focusSessionTimeElapsed: currentSessionTime,
});
}
return focusSessionTimeToGo >= 0
? setFocusSessionTimeToGo({ focusSessionTimeToGo })
: focusSessionDone();
return timeToGo >= 0
? // ? setFocusSessionTimeToGo({ currentSessionTime })
setFocusSessionTimeElapsed({
focusSessionTimeElapsed: currentSessionTime,
})
: focusSessionDone({ isResetPlannedSessionDuration: true });
}),
);
});
stopTrackingOnOnCancel$ = createEffect(() => {
return this._actions$.pipe(ofType(cancelFocusSession), mapTo(unsetCurrentTask()));
});
pauseOnIdle$ = createEffect(() => {
return this._actions$.pipe(ofType(openIdleDialog), mapTo(pauseFocusSession()));
});
playSessionDoneSoundIfEnabled$: Observable<unknown> = createEffect(
() =>
@ -149,6 +117,7 @@ export class FocusModeEffects {
{ dispatch: false },
);
// TODO check if needed
handleIdleCurrentTaskDeSelection$: Observable<unknown> = createEffect(() =>
this._isRunning$.pipe(
switchMap((isRunning) => (isRunning ? this._idleService.isIdle$ : EMPTY)),
@ -169,7 +138,7 @@ export class FocusModeEffects {
IS_ELECTRON &&
createEffect(
() =>
this._sessionProgress$.pipe(
this._focusModeService.sessionProgress$.pipe(
withLatestFrom(this._isRunning$),
tap(([progress, isRunning]: [number, boolean]) => {
const progressBarMode: 'normal' | 'pause' = isRunning ? 'normal' : 'pause';

View file

@ -3,30 +3,30 @@ import {
cancelFocusSession,
focusSessionDone,
hideFocusOverlay,
pauseFocusSession,
setFocusModeMode,
setFocusSessionActivePage,
setFocusSessionDuration,
setFocusSessionTimeElapsed,
setFocusSessionTimeToGo,
showFocusOverlay,
startFocusSession,
unPauseFocusSession,
} from './focus-mode.actions';
import { FocusModeMode, FocusModePage } from '../focus-mode.const';
import { LS } from '../../../core/persistence/storage-keys.const';
const DEFAULT_FOCUS_SESSION_DURATION = 25 * 60 * 1000;
const USE_REMAINING_SESSION_TIME_THRESHOLD = 60 * 1000;
// const USE_REMAINING_SESSION_TIME_THRESHOLD = 60 * 1000;
export const FOCUS_MODE_FEATURE_KEY = 'focusMode';
export interface State {
isFocusOverlayShown: boolean;
isFocusSessionRunning: boolean;
focusSessionDuration: number;
focusSessionTimeToGo: number;
focusSessionTimeElapsed: number;
focusSessionActivePage: FocusModePage;
mode: FocusModeMode;
lastFocusSessionDuration: number;
}
const focusModeModeFromLS = localStorage.getItem(LS.FOCUS_MODE_MODE);
@ -35,8 +35,6 @@ export const initialState: State = {
isFocusOverlayShown: false,
isFocusSessionRunning: false,
focusSessionDuration: DEFAULT_FOCUS_SESSION_DURATION,
lastFocusSessionDuration: 0,
focusSessionTimeToGo: 0,
focusSessionTimeElapsed: 0,
focusSessionActivePage: FocusModePage.TaskSelection,
mode: Object.values(FocusModeMode).includes(focusModeModeFromLS as any)
@ -60,16 +58,6 @@ export const focusModeReducer = createReducer<State>(
focusSessionDuration,
})),
on(setFocusSessionTimeToGo, (state, { focusSessionTimeToGo }) => ({
...state,
focusSessionTimeToGo,
})),
on(setFocusSessionTimeToGo, (state, { focusSessionTimeToGo }) => ({
...state,
focusSessionTimeToGo,
})),
on(setFocusSessionTimeElapsed, (state, { focusSessionTimeElapsed }) => ({
...state,
focusSessionTimeElapsed,
@ -78,7 +66,6 @@ export const focusModeReducer = createReducer<State>(
on(startFocusSession, (state) => ({
...state,
isFocusSessionRunning: true,
focusSessionTimeToGo: 0,
focusSessionActivePage: FocusModePage.Main,
// NOTE: not resetting since, we might want to continue
// focusSessionTimeElapsed: 0,
@ -87,16 +74,31 @@ export const focusModeReducer = createReducer<State>(
? state.focusSessionDuration
: DEFAULT_FOCUS_SESSION_DURATION,
})),
on(focusSessionDone, (state) => ({
on(focusSessionDone, (state, { isResetPlannedSessionDuration }) => {
return {
...state,
isFocusSessionRunning: false,
isFocusOverlayShown: true,
...(isResetPlannedSessionDuration
? {
focusSessionDuration: DEFAULT_FOCUS_SESSION_DURATION,
}
: {}),
focusSessionActivePage: FocusModePage.SessionDone,
};
}),
on(pauseFocusSession, (state) => ({
...state,
isFocusSessionRunning: false,
isFocusOverlayShown: true,
lastFocusSessionDuration: state.focusSessionDuration,
focusSessionDuration:
state.focusSessionTimeToGo >= USE_REMAINING_SESSION_TIME_THRESHOLD
? state.focusSessionTimeToGo
: DEFAULT_FOCUS_SESSION_DURATION,
focusSessionActivePage: FocusModePage.SessionDone,
})),
on(unPauseFocusSession, (state, { idleTimeToAdd = 0 }) => ({
...state,
isFocusSessionRunning: true,
// NOTE: this is adjusted in the effect via session time
// focusSessionDuration: state.focusSessionDuration,
})),
on(showFocusOverlay, (state) => ({

View file

@ -15,20 +15,11 @@ export const selectFocusSessionDuration = createSelector(
selectFocusModeState,
(state) => state.focusSessionDuration,
);
export const selectLastFocusSessionDuration = createSelector(
selectFocusModeState,
(state) => state.lastFocusSessionDuration,
);
export const selectIsFocusOverlayShown = createSelector(
selectFocusModeState,
(state) => state.isFocusOverlayShown,
);
export const selectFocusSessionTimeToGo = createSelector(
selectFocusModeState,
(state) => state.focusSessionTimeToGo,
);
export const selectFocusSessionTimeElapsed = createSelector(
selectFocusModeState,
(state) => state.focusSessionTimeElapsed,
@ -38,10 +29,3 @@ export const selectFocusSessionActivePage = createSelector(
selectFocusModeState,
(state) => state.focusSessionActivePage,
);
export const selectFocusSessionProgress = createSelector(
selectFocusModeState,
(state) =>
((state.focusSessionDuration - state.focusSessionTimeToGo) * 100) /
state.focusSessionDuration,
);

View file

@ -144,6 +144,7 @@ export class DialogIdleComponent implements OnInit, OnDestroy {
this._matDialogRef.close({
isResetBreakTimer: this.isResetBreakTimer,
trackItems: res.trackItems,
wasFocusSessionRunning: this.data.wasFocusSessionRunning,
});
}
});
@ -165,12 +166,14 @@ export class DialogIdleComponent implements OnInit, OnDestroy {
isResetBreakTimer: this.isResetBreakTimer,
trackItems: [],
simpleCounterToggleBtnsWhenNoTrackItems: this.simpleCounterToggleBtns,
wasFocusSessionRunning: this.data.wasFocusSessionRunning,
});
}
trackAsBreak(): void {
this._matDialogRef.close({
isResetBreakTimer: this.isResetBreakTimer,
wasFocusSessionRunning: this.data.wasFocusSessionRunning,
trackItems: [
{
type: 'BREAK',
@ -184,6 +187,7 @@ export class DialogIdleComponent implements OnInit, OnDestroy {
track(): void {
this._matDialogRef.close({
isResetBreakTimer: this.isResetBreakTimer,
wasFocusSessionRunning: this.data.wasFocusSessionRunning,
trackItems: [
{
type: 'TASK',

View file

@ -13,11 +13,13 @@ export interface DialogIdleReturnData {
trackItems: IdleTrackItem[];
simpleCounterToggleBtnsWhenNoTrackItems?: SimpleCounterIdleBtn[];
isResetBreakTimer: boolean;
wasFocusSessionRunning: boolean;
}
export interface DialogIdlePassedData {
enabledSimpleStopWatchCounters: SimpleCounter[];
lastCurrentTaskId: string | null;
wasFocusSessionRunning: boolean;
}
export interface DialogIdleSplitPassedData {

View file

@ -13,6 +13,7 @@ export const openIdleDialog = createAction(
props<{
lastCurrentTaskId: string | null;
enabledSimpleStopWatchCounters: SimpleCounter[];
wasFocusSessionRunning: boolean;
}>(),
);
@ -26,6 +27,7 @@ export const idleDialogResult = createAction(
props<{
idleTime: number;
isResetBreakTimer: boolean;
wasFocusSessionRunning: boolean;
trackItems: IdleTrackItem[];
simpleCounterToggleBtnsWhenNoTrackItems?: SimpleCounterIdleBtn[];
}>(),

View file

@ -45,6 +45,12 @@ import { DialogConfirmComponent } from '../../../ui/dialog-confirm/dialog-confir
import { T } from '../../../t.const';
import { DateService } from 'src/app/core/date/date.service';
import { ipcIdleTime$ } from '../../../core/ipc-events';
import { selectIsFocusSessionRunning } from '../../focus-mode/store/focus-mode.selectors';
import {
focusSessionDone,
showFocusOverlay,
unPauseFocusSession,
} from '../../focus-mode/store/focus-mode.actions';
const DEFAULT_MIN_IDLE_TIME = 60000;
const IDLE_POLL_INTERVAL = 1000;
@ -68,6 +74,7 @@ export class IdleEffects {
// NOTE: needs to live forever since we can't unsubscribe from ipcEvent$
// TODO check if this works as expected
private _electronIdleTime$: Observable<number> = IS_ELECTRON ? ipcIdleTime$ : EMPTY;
private _isFocusSessionRunning$ = this._store.select(selectIsFocusSessionRunning);
private _triggerIdleApis$ = IS_ELECTRON
? this._electronIdleTime$
@ -118,8 +125,9 @@ export class IdleEffects {
withLatestFrom(
this._store.select(selectIdleTime),
this._simpleCounterService.enabledSimpleStopWatchCounters$,
this._isFocusSessionRunning$,
),
map(([, idleTime, enabledSimpleStopWatchCounters]) => {
map(([, idleTime, enabledSimpleStopWatchCounters, isFocusSessionRunning]) => {
// ALL IDLE SIDE EFFECTS
// ---------------------
if (IS_ELECTRON) {
@ -152,7 +160,11 @@ export class IdleEffects {
// this._openDialog(enabledSimpleStopWatchCounters, lastCurrentTaskId);
// finally open dialog
return openIdleDialog({ enabledSimpleStopWatchCounters, lastCurrentTaskId });
return openIdleDialog({
enabledSimpleStopWatchCounters,
lastCurrentTaskId,
wasFocusSessionRunning: isFocusSessionRunning,
});
}),
),
);
@ -163,22 +175,24 @@ export class IdleEffects {
filter(() => !this._isDialogOpen),
tap(() => (this._isDialogOpen = true)),
// use exhaustMap to prevent opening up multiple dialogs
exhaustMap(({ enabledSimpleStopWatchCounters, lastCurrentTaskId }) =>
this._matDialog
.open<
DialogIdleComponent,
DialogIdlePassedData,
DialogIdleReturnData | undefined
>(DialogIdleComponent, {
restoreFocus: true,
disableClose: true,
closeOnNavigation: false,
data: {
lastCurrentTaskId,
enabledSimpleStopWatchCounters,
},
})
.afterClosed(),
exhaustMap(
({ enabledSimpleStopWatchCounters, lastCurrentTaskId, wasFocusSessionRunning }) =>
this._matDialog
.open<
DialogIdleComponent,
DialogIdlePassedData,
DialogIdleReturnData | undefined
>(DialogIdleComponent, {
restoreFocus: true,
disableClose: true,
closeOnNavigation: false,
data: {
lastCurrentTaskId,
enabledSimpleStopWatchCounters,
wasFocusSessionRunning,
},
})
.afterClosed(),
),
tap((dialogRes) => {
if (!dialogRes) {
@ -191,6 +205,7 @@ export class IdleEffects {
idleDialogResult({
...dialogRes,
idleTime,
// TODO
}),
),
tap(() => (this._isDialogOpen = false)),
@ -205,6 +220,7 @@ export class IdleEffects {
trackItems,
simpleCounterToggleBtnsWhenNoTrackItems,
idleTime,
wasFocusSessionRunning,
isResetBreakTimer,
}) => {
this._cancelIdlePoll();
@ -215,6 +231,15 @@ export class IdleEffects {
}
if (trackItems.length === 0 && simpleCounterToggleBtnsWhenNoTrackItems) {
if (wasFocusSessionRunning) {
this._store.dispatch(
focusSessionDone({
isResetPlannedSessionDuration: true,
}),
);
this._store.dispatch(showFocusOverlay());
}
const activatedItemNr = simpleCounterToggleBtnsWhenNoTrackItems.filter(
(btn) => btn.isTrackTo,
).length;
@ -247,7 +272,6 @@ export class IdleEffects {
return;
}
// TODO remove TASK_AND_BREAK case completely
const itemsWithMappedIdleTime = trackItems.map((trackItem) => ({
...trackItem,
time: trackItem.time === 'IDLE_TIME' ? idleTime : trackItem.time,
@ -268,6 +292,17 @@ export class IdleEffects {
item.time,
);
});
if (wasFocusSessionRunning) {
this._store.dispatch(
focusSessionDone({
isResetPlannedSessionDuration: true,
}),
);
this._store.dispatch(showFocusOverlay());
}
} else if (wasFocusSessionRunning) {
this._store.dispatch(unPauseFocusSession({ idleTimeToAdd: idleTime }));
this._store.dispatch(showFocusOverlay());
}
const taskItems = itemsWithMappedIdleTime.filter(
@ -298,11 +333,11 @@ export class IdleEffects {
),
);
// constructor() {
// window.setTimeout(() => {
// this._store.dispatch(triggerIdle({ idleTime: 60 * 1000 }));
// }, 2700);
// }
constructor() {
window.setTimeout(() => {
this._store.dispatch(triggerIdle({ idleTime: 60 * 1000 }));
}, 8700);
}
private _initIdlePoll(initialIdleTime: number): void {
const idleStart = Date.now();