feat: improve finish day for electron variant
This commit is contained in:
parent
765ee1da28
commit
e85cfe2937
|
@ -2,11 +2,9 @@ import * as windowStateKeeper from 'electron-window-state';
|
|||
import {
|
||||
App,
|
||||
BrowserWindow,
|
||||
dialog,
|
||||
ipcMain,
|
||||
Menu,
|
||||
MenuItemConstructorOptions,
|
||||
MessageBoxReturnValue,
|
||||
shell,
|
||||
} from 'electron';
|
||||
import { errorHandlerWithFrontendInform } from './error-handler-with-frontend-inform';
|
||||
|
@ -237,25 +235,7 @@ const appCloseHandler = (app: App): void => {
|
|||
log('Actions to wait for ', ids);
|
||||
mainWin.webContents.send(IPC.NOTIFY_ON_CLOSE, ids);
|
||||
} else {
|
||||
if (appCfg && appCfg.misc.isConfirmBeforeExit && !(app as any).isQuiting) {
|
||||
dialog
|
||||
.showMessageBox(mainWin, {
|
||||
type: 'question',
|
||||
buttons: ['Yes', 'No'],
|
||||
title: 'Confirm',
|
||||
message: 'Are you sure you want to quit?',
|
||||
})
|
||||
.then((choice: MessageBoxReturnValue) => {
|
||||
if (choice.response === 1) {
|
||||
return;
|
||||
} else if (choice.response === 0) {
|
||||
_quitApp();
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_quitApp();
|
||||
}
|
||||
_quitApp();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import { SyncModule } from './imex/sync/sync.module';
|
|||
import { SearchBarModule } from './features/search-bar/search-bar.module';
|
||||
import { IdleModule } from './features/idle/idle.module';
|
||||
import { TrackingReminderModule } from './features/tracking-reminder/tracking-reminder.module';
|
||||
import { FinishDayBeforeCloseModule } from './features/finish-day-before-close/finish-day-before-close.module';
|
||||
|
||||
// NOTE: export required for aot to work
|
||||
export const createTranslateLoader = (http: HttpClient): TranslateHttpLoader =>
|
||||
|
@ -76,6 +77,7 @@ export const createTranslateLoader = (http: HttpClient): TranslateHttpLoader =>
|
|||
SyncModule,
|
||||
MaterialCssVarsModule.forRoot(),
|
||||
SearchBarModule,
|
||||
FinishDayBeforeCloseModule,
|
||||
|
||||
// External
|
||||
BrowserModule,
|
||||
|
|
|
@ -16,6 +16,7 @@ export const DEFAULT_GLOBAL_CONFIG: GlobalConfigState = {
|
|||
misc: {
|
||||
isDarkMode: IS_USE_DARK_THEME_AS_DEFAULT,
|
||||
isConfirmBeforeExit: false,
|
||||
isConfirmBeforeExitWithoutFinishDay: true,
|
||||
isNotifyWhenTimeEstimateExceeded: true,
|
||||
isAutMarkParentAsDone: false,
|
||||
isAutoStartNextTask: true,
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
/* eslint-disable max-len */
|
||||
import { ConfigFormSection, MiscConfig } from '../global-config.model';
|
||||
import {
|
||||
ConfigFormSection,
|
||||
LimitedFormlyFieldConfig,
|
||||
MiscConfig,
|
||||
} from '../global-config.model';
|
||||
import { T } from '../../../t.const';
|
||||
import { IS_ELECTRON } from '../../../app.constants';
|
||||
|
||||
export const MISC_SETTINGS_FORM_CFG: ConfigFormSection<MiscConfig> = {
|
||||
title: T.GCF.MISC.TITLE,
|
||||
|
@ -14,13 +19,25 @@ export const MISC_SETTINGS_FORM_CFG: ConfigFormSection<MiscConfig> = {
|
|||
// label: T.GCF.MISC.IS_DARK_MODE,
|
||||
// },
|
||||
// },
|
||||
{
|
||||
key: 'isConfirmBeforeExit',
|
||||
type: 'checkbox',
|
||||
templateOptions: {
|
||||
label: T.GCF.MISC.IS_CONFIRM_BEFORE_EXIT,
|
||||
},
|
||||
},
|
||||
...((IS_ELECTRON
|
||||
? [
|
||||
{
|
||||
key: 'isConfirmBeforeExitWithoutFinishDay',
|
||||
type: 'checkbox',
|
||||
templateOptions: {
|
||||
label: T.GCF.MISC.IS_CONFIRM_BEFORE_EXIT_WITHOUT_FINISH_DAY,
|
||||
},
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
key: 'isConfirmBeforeExit',
|
||||
type: 'checkbox',
|
||||
templateOptions: {
|
||||
label: T.GCF.MISC.IS_CONFIRM_BEFORE_EXIT,
|
||||
},
|
||||
},
|
||||
]) as LimitedFormlyFieldConfig<MiscConfig>[]),
|
||||
{
|
||||
key: 'isNotifyWhenTimeEstimateExceeded',
|
||||
type: 'checkbox',
|
||||
|
|
|
@ -9,6 +9,7 @@ export type MiscConfig = Readonly<{
|
|||
isAutMarkParentAsDone: boolean;
|
||||
isAutoStartNextTask: boolean;
|
||||
isConfirmBeforeExit: boolean;
|
||||
isConfirmBeforeExitWithoutFinishDay: boolean;
|
||||
isNotifyWhenTimeEstimateExceeded: boolean;
|
||||
isTurnOffMarkdown: boolean;
|
||||
isAutoAddWorkedOnToToday: boolean;
|
||||
|
|
|
@ -9,7 +9,7 @@ import { MODEL_VERSION_KEY } from '../../app.constants';
|
|||
import { isMigrateModel } from '../../util/model-version';
|
||||
import { SyncProvider } from '../../imex/sync/sync-provider.model';
|
||||
|
||||
const MODEL_VERSION = 2.2005;
|
||||
const MODEL_VERSION = 2.2006;
|
||||
|
||||
export const migrateGlobalConfigState = (
|
||||
globalConfigState: GlobalConfigState,
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// import { TestBed } from '@angular/core/testing';
|
||||
// import { provideMockActions } from '@ngrx/effects/testing';
|
||||
// import { Observable } from 'rxjs';
|
||||
//
|
||||
// import { FinishDayBeforeCloseEffects } from './finish-day-before-close.effects';
|
||||
//
|
||||
// describe('FinishDayBeforeCloseEffects', () => {
|
||||
// let actions$: Observable<any>;
|
||||
// let effects: FinishDayBeforeCloseEffects;
|
||||
//
|
||||
// beforeEach(() => {
|
||||
// TestBed.configureTestingModule({
|
||||
// providers: [
|
||||
// FinishDayBeforeCloseEffects,
|
||||
// provideMockActions(() => actions$)
|
||||
// ]
|
||||
// });
|
||||
//
|
||||
// effects = TestBed.inject(FinishDayBeforeCloseEffects);
|
||||
// });
|
||||
//
|
||||
// it('should be created', () => {
|
||||
// expect(effects).toBeTruthy();
|
||||
// });
|
||||
// });
|
|
@ -0,0 +1,97 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Actions, createEffect } from '@ngrx/effects';
|
||||
import { ExecBeforeCloseService } from '../../core/electron/exec-before-close.service';
|
||||
import { GlobalConfigService } from '../config/global-config.service';
|
||||
import {
|
||||
concatMap,
|
||||
distinctUntilChanged,
|
||||
first,
|
||||
map,
|
||||
switchMap,
|
||||
tap,
|
||||
} from 'rxjs/operators';
|
||||
import { DataInitService } from '../../core/data-init/data-init.service';
|
||||
import { IS_ELECTRON } from '../../app.constants';
|
||||
import { EMPTY, Observable } from 'rxjs';
|
||||
import { WorkContextService } from '../work-context/work-context.service';
|
||||
import { TaskService } from '../tasks/task.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { TODAY_TAG } from '../tag/tag.const';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { T } from '../../t.const';
|
||||
|
||||
const EXEC_BEFORE_CLOSE_ID = 'FINISH_DAY_BEFORE_CLOSE_EFFECT';
|
||||
|
||||
@Injectable()
|
||||
export class FinishDayBeforeCloseEffects {
|
||||
isEnabled$: Observable<boolean> = this._dataInitService.isAllDataLoadedInitially$.pipe(
|
||||
concatMap(() => this._globalConfigService.misc$),
|
||||
map((misc) => misc.isConfirmBeforeExitWithoutFinishDay),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
|
||||
scheduleUnscheduleFinishDayBeforeClose$ =
|
||||
IS_ELECTRON &&
|
||||
createEffect(
|
||||
() =>
|
||||
this.isEnabled$.pipe(
|
||||
tap((isEnabled) =>
|
||||
isEnabled
|
||||
? this._execBeforeCloseService.schedule(EXEC_BEFORE_CLOSE_ID)
|
||||
: this._execBeforeCloseService.unschedule(EXEC_BEFORE_CLOSE_ID),
|
||||
),
|
||||
),
|
||||
{ dispatch: false },
|
||||
);
|
||||
|
||||
warnToFinishDayBeforeClose$ =
|
||||
IS_ELECTRON &&
|
||||
createEffect(
|
||||
() =>
|
||||
this.isEnabled$.pipe(
|
||||
switchMap((isEnabled) =>
|
||||
isEnabled ? this._execBeforeCloseService.onBeforeClose$ : EMPTY,
|
||||
),
|
||||
switchMap(() =>
|
||||
this._workContextService.mainWorkContext$.pipe(
|
||||
switchMap((workContext) =>
|
||||
this._taskService.getByIdsLive$(workContext.taskIds).pipe(first()),
|
||||
),
|
||||
),
|
||||
),
|
||||
tap((todayMainTasks) => {
|
||||
const doneTasks = todayMainTasks.filter((t) => t.isDone);
|
||||
if (doneTasks.length) {
|
||||
if (
|
||||
confirm(
|
||||
this._translateService.instant(
|
||||
T.F.FINISH_DAY_BEFORE_EXIT.C.FINISH_DAY_BEFORE_EXIT,
|
||||
{
|
||||
nr: doneTasks.length,
|
||||
},
|
||||
),
|
||||
)
|
||||
) {
|
||||
this._execBeforeCloseService.setDone(EXEC_BEFORE_CLOSE_ID);
|
||||
} else {
|
||||
this._router.navigate([`tag/${TODAY_TAG.id}/daily-summary`]);
|
||||
}
|
||||
} else {
|
||||
this._execBeforeCloseService.setDone(EXEC_BEFORE_CLOSE_ID);
|
||||
}
|
||||
}),
|
||||
),
|
||||
{ dispatch: false },
|
||||
);
|
||||
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private _execBeforeCloseService: ExecBeforeCloseService,
|
||||
private _globalConfigService: GlobalConfigService,
|
||||
private _dataInitService: DataInitService,
|
||||
private _taskService: TaskService,
|
||||
private _workContextService: WorkContextService,
|
||||
private _router: Router,
|
||||
private _translateService: TranslateService,
|
||||
) {}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import { FinishDayBeforeCloseEffects } from './finish-day-before-close.effects';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [CommonModule, EffectsModule.forFeature([FinishDayBeforeCloseEffects])],
|
||||
})
|
||||
export class FinishDayBeforeCloseModule {}
|
|
@ -124,6 +124,11 @@ const T = {
|
|||
SYNC_ERROR: 'F.DROPBOX.S.SYNC_ERROR',
|
||||
},
|
||||
},
|
||||
FINISH_DAY_BEFORE_EXIT: {
|
||||
C: {
|
||||
FINISH_DAY_BEFORE_EXIT: 'F.FINISH_DAY_BEFORE_EXIT.C.FINISH_DAY_BEFORE_EXIT',
|
||||
},
|
||||
},
|
||||
GITHUB: {
|
||||
DIALOG_INITIAL: {
|
||||
TITLE: 'F.GITHUB.DIALOG_INITIAL.TITLE',
|
||||
|
@ -1113,6 +1118,8 @@ const T = {
|
|||
IS_AUTO_MARK_PARENT_AS_DONE: 'GCF.MISC.IS_AUTO_MARK_PARENT_AS_DONE',
|
||||
IS_AUTO_START_NEXT_TASK: 'GCF.MISC.IS_AUTO_START_NEXT_TASK',
|
||||
IS_CONFIRM_BEFORE_EXIT: 'GCF.MISC.IS_CONFIRM_BEFORE_EXIT',
|
||||
IS_CONFIRM_BEFORE_EXIT_WITHOUT_FINISH_DAY:
|
||||
'GCF.MISC.IS_CONFIRM_BEFORE_EXIT_WITHOUT_FINISH_DAY',
|
||||
IS_DARK_MODE: 'GCF.MISC.IS_DARK_MODE',
|
||||
IS_HIDE_NAV: 'GCF.MISC.IS_HIDE_NAV',
|
||||
IS_MINIMIZE_TO_TRAY: 'GCF.MISC.IS_MINIMIZE_TO_TRAY',
|
||||
|
@ -1267,7 +1274,6 @@ const T = {
|
|||
PP: {
|
||||
ARCHIVED_PROJECTS: 'PP.ARCHIVED_PROJECTS',
|
||||
ARCHIVE_PROJECT: 'PP.ARCHIVE_PROJECT',
|
||||
CREATE_NEW: 'PP.CREATE_NEW',
|
||||
DELETE_PROJECT: 'PP.DELETE_PROJECT',
|
||||
D_CONFIRM_ARCHIVE: {
|
||||
MSG: 'PP.D_CONFIRM_ARCHIVE.MSG',
|
||||
|
|
|
@ -124,6 +124,11 @@
|
|||
"SYNC_ERROR": "Dropbox: Error while syncing"
|
||||
}
|
||||
},
|
||||
"FINISH_DAY_BEFORE_EXIT": {
|
||||
"C": {
|
||||
"FINISH_DAY_BEFORE_EXIT": "There are {{nr}} done tasks in your today list not yet moved to the archive. Do you really want to quit without finishing your day?"
|
||||
}
|
||||
},
|
||||
"GITHUB": {
|
||||
"DIALOG_INITIAL": {
|
||||
"TITLE": "Setup GitHub for Project"
|
||||
|
@ -1099,6 +1104,7 @@
|
|||
"IS_AUTO_MARK_PARENT_AS_DONE": "Mark parent task as done, when all sub tasks are done",
|
||||
"IS_AUTO_START_NEXT_TASK": "Start tracking next task when marking current as done",
|
||||
"IS_CONFIRM_BEFORE_EXIT": "Confirm before exiting the app",
|
||||
"IS_CONFIRM_BEFORE_EXIT_WITHOUT_FINISH_DAY": "Confirm before exiting the app without finishing day first",
|
||||
"IS_DARK_MODE": "Dark Mode",
|
||||
"IS_HIDE_NAV": "Hide navigation until main header is hovered (desktop only)",
|
||||
"IS_MINIMIZE_TO_TRAY": "Minimize to tray (desktop only)",
|
||||
|
|
Loading…
Reference in New Issue
Block a user