feat(app): Show add-on menu if start app with --addons arg (#359)
* refactor(store): Move app reducer from electron to shared module * feat(app): Show add-on menu if start app with --addons arg close: #351
This commit is contained in:
committed by
László Monda
parent
25257132a6
commit
a4d41f36d5
@@ -107,6 +107,7 @@ import { reducer } from './store';
|
||||
import { AutoUpdateSettings } from './shared/components/auto-update-settings/auto-update-settings';
|
||||
import { angularNotifierConfig } from './shared/models/angular-notifier-config';
|
||||
import { UhkHeader } from './shared/components/uhk-header/uhk-header';
|
||||
import { AppRendererService } from './services/app-renderer.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -210,8 +211,8 @@ import { UhkHeader } from './shared/components/uhk-header/uhk-header';
|
||||
AppUpdateRendererService,
|
||||
UhkHidApiService,
|
||||
UhkLibUsbApiService,
|
||||
uhkDeviceProvider()
|
||||
|
||||
uhkDeviceProvider(),
|
||||
AppRendererService
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
||||
1
electron/src/custom_types/command-line-args.d.ts
vendored
Normal file
1
electron/src/custom_types/command-line-args.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module 'command-line-args';
|
||||
@@ -1,4 +1,5 @@
|
||||
/// <reference path="./custom_types/electron-is-dev.d.ts"/>
|
||||
/// <reference path="./custom_types/command-line-args.d.ts"/>
|
||||
|
||||
import { app, BrowserWindow, ipcMain } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
@@ -8,9 +9,17 @@ import { ProgressInfo } from 'electron-builder-http/out/ProgressCallbackTransfor
|
||||
import { VersionInfo } from 'electron-builder-http/out/publishOptions';
|
||||
import * as settings from 'electron-settings';
|
||||
import * as isDev from 'electron-is-dev';
|
||||
import * as commandLineArgs from 'command-line-args';
|
||||
|
||||
import { IpcEvents } from './shared/util';
|
||||
import { ElectronDataStorageRepositoryService } from './services/electron-datastorage-repository.service';
|
||||
import { CommandLineArgs } from './shared/models/command-line-args';
|
||||
|
||||
const optionDefinitions = [
|
||||
{ name: 'addons', type: Boolean, defaultOption: false }
|
||||
];
|
||||
|
||||
const options: CommandLineArgs = commandLineArgs(optionDefinitions);
|
||||
|
||||
// import './dev-extension';
|
||||
require('electron-debug')({ showDevTools: false, enabled: true });
|
||||
@@ -143,6 +152,8 @@ ipcMain.on(IpcEvents.app.appStarted, () => {
|
||||
|
||||
ipcMain.on(IpcEvents.autoUpdater.checkForUpdate, () => checkForUpdate());
|
||||
|
||||
ipcMain.on(IpcEvents.app.getCommandLineArgs, (event: any) => event.sender.send(IpcEvents.app.getCommandLineArgsReply, options));
|
||||
|
||||
function isFirstRun() {
|
||||
if (!settings.has('firstRunVersion')) {
|
||||
return true;
|
||||
|
||||
30
electron/src/services/app-renderer.service.ts
Normal file
30
electron/src/services/app-renderer.service.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Action, Store } from '@ngrx/store';
|
||||
import { ipcRenderer } from 'electron';
|
||||
|
||||
import { IpcEvents } from '../shared/util';
|
||||
import { AppState } from '../store';
|
||||
import { CommandLineArgs } from '../shared/models/command-line-args';
|
||||
import { ProcessCommandLineArgsAction } from '../../../shared/src/store/actions/app.action';
|
||||
|
||||
@Injectable()
|
||||
export class AppRendererService {
|
||||
constructor(private store: Store<AppState>,
|
||||
private zone: NgZone) {
|
||||
this.registerEvents();
|
||||
}
|
||||
|
||||
getCommandLineArgs() {
|
||||
ipcRenderer.send(IpcEvents.app.getCommandLineArgs);
|
||||
}
|
||||
|
||||
private registerEvents() {
|
||||
ipcRenderer.on(IpcEvents.app.getCommandLineArgsReply, (event: string, arg: CommandLineArgs) => {
|
||||
this.dispachStoreAction(new ProcessCommandLineArgsAction(arg));
|
||||
});
|
||||
}
|
||||
|
||||
private dispachStoreAction(action: Action) {
|
||||
this.zone.run(() => this.store.dispatch(action));
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import 'rxjs/add/operator/do';
|
||||
|
||||
import * as app from '../../shared/store/actions/app.action';
|
||||
import { AppUpdateRendererService } from '../../services/app-update-renderer.service';
|
||||
import { AppRendererService } from '../../services/app-renderer.service';
|
||||
|
||||
@Injectable()
|
||||
export class ApplicationEffect {
|
||||
@@ -13,12 +14,13 @@ export class ApplicationEffect {
|
||||
appStart$: Observable<Action> = this.actions$
|
||||
.ofType(app.ActionTypes.APP_BOOTSRAPPED)
|
||||
.startWith(new app.AppStartedAction())
|
||||
.delay(3000) // wait 3 sec to mainRenderer subscribe all events
|
||||
.do(() => {
|
||||
this.appUpdateRendererService.sendAppStarted();
|
||||
this.appRendererService.getCommandLineArgs();
|
||||
});
|
||||
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private appUpdateRendererService: AppUpdateRendererService) { }
|
||||
private appUpdateRendererService: AppUpdateRendererService,
|
||||
private appRendererService: AppRendererService) { }
|
||||
}
|
||||
|
||||
@@ -3,26 +3,19 @@ import { createSelector } from 'reselect';
|
||||
import { compose } from '@ngrx/core/compose';
|
||||
import { storeFreeze } from 'ngrx-store-freeze';
|
||||
import { ActionReducer, combineReducers } from '@ngrx/store';
|
||||
import { routerReducer } from '@ngrx/router-store';
|
||||
import * as isDev from 'electron-is-dev';
|
||||
|
||||
import { AppState as CommonState } from '../shared/store';
|
||||
import * as fromApp from './reducers/app.reducer';
|
||||
import * as fromAppUpdate from './reducers/app-update.reducer';
|
||||
import { autoUpdateReducer, presetReducer, userConfigurationReducer } from '../shared/store/reducers';
|
||||
import { reducer as CommonReducer } from '../shared/store/reducers';
|
||||
|
||||
export interface AppState extends CommonState {
|
||||
app: fromApp.State;
|
||||
appUpdate: fromAppUpdate.State;
|
||||
}
|
||||
|
||||
const reducers = {
|
||||
userConfiguration: userConfigurationReducer,
|
||||
presetKeymaps: presetReducer,
|
||||
router: routerReducer,
|
||||
app: fromApp.reducer,
|
||||
appUpdate: fromAppUpdate.reducer,
|
||||
autoUpdateSettings: autoUpdateReducer
|
||||
...CommonReducer,
|
||||
appUpdate: fromAppUpdate.reducer
|
||||
};
|
||||
|
||||
const developmentReducer: ActionReducer<AppState> = compose(storeFreeze, combineReducers)(reducers);
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Actions, ActionTypes } from '../../shared/store/actions/app.action';
|
||||
|
||||
export interface State {
|
||||
started: boolean;
|
||||
}
|
||||
|
||||
const initialState: State = {
|
||||
started: false
|
||||
};
|
||||
|
||||
export function reducer(state = initialState, action: Actions) {
|
||||
switch (action.type) {
|
||||
case ActionTypes.APP_STARTED: {
|
||||
const newState = Object.assign({}, state);
|
||||
newState.started = true;
|
||||
return newState;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
4012
package-lock.json
generated
4012
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,7 @@
|
||||
"bootstrap": "^3.3.7",
|
||||
"browser-stdout": "^1.3.0",
|
||||
"buffer": "^5.0.6",
|
||||
"command-line-args": "^4.0.6",
|
||||
"core-js": "2.4.1",
|
||||
"dragula": "^3.7.2",
|
||||
"electron-is-dev": "0.1.2",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sidebar__level-1--item">
|
||||
<li class="sidebar__level-1--item" *ngIf="showAddonMenu$ | async">
|
||||
<div class="sidebar__level-1">
|
||||
<i class="fa fa-puzzle-piece"></i> Add-on modules
|
||||
<i class="fa fa-chevron-up pull-right" (click)="toggleHide($event, 'addon')"></i>
|
||||
|
||||
@@ -12,7 +12,7 @@ import { runInElectron } from '../../util/index';
|
||||
import { Keymap } from '../../config-serializer/config-items/keymap';
|
||||
import { Macro } from '../../config-serializer/config-items/macro';
|
||||
|
||||
import { AppState } from '../../store';
|
||||
import { AppState, showAddonMenu } from '../../store';
|
||||
import { MacroActions } from '../../store/actions';
|
||||
import { getKeymaps, getMacros } from '../../store/reducers/user-configuration';
|
||||
|
||||
@@ -33,6 +33,7 @@ import { getKeymaps, getMacros } from '../../store/reducers/user-configuration';
|
||||
styleUrls: ['./side-menu.component.scss']
|
||||
})
|
||||
export class SideMenuComponent {
|
||||
showAddonMenu$: Observable<boolean>;
|
||||
runInElectron = runInElectron();
|
||||
|
||||
private keymaps$: Observable<Keymap[]>;
|
||||
@@ -57,6 +58,8 @@ export class SideMenuComponent {
|
||||
.do((macros: Macro[]) => {
|
||||
macros.sort((first: Macro, second: Macro) => first.name.localeCompare(second.name));
|
||||
});
|
||||
|
||||
this.showAddonMenu$ = this.store.select(showAddonMenu);
|
||||
}
|
||||
|
||||
toggleHide(event: Event, type: string) {
|
||||
|
||||
3
shared/src/models/command-line-args.ts
Normal file
3
shared/src/models/command-line-args.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface CommandLineArgs {
|
||||
addons: boolean;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { Action } from '@ngrx/store';
|
||||
|
||||
import { type } from '../../util';
|
||||
import { Notification } from '../../models/notification';
|
||||
import { CommandLineArgs } from '../../models/command-line-args';
|
||||
|
||||
const PREFIX = '[app] ';
|
||||
|
||||
@@ -9,7 +10,9 @@ const PREFIX = '[app] ';
|
||||
export const ActionTypes = {
|
||||
APP_BOOTSRAPPED: type(PREFIX + 'bootstrapped'),
|
||||
APP_STARTED: type(PREFIX + 'started'),
|
||||
APP_SHOW_NOTIFICATION: type(PREFIX + 'show notification')
|
||||
APP_SHOW_NOTIFICATION: type(PREFIX + 'show notification'),
|
||||
APP_TOGGLE_ADDON_MENU: type(PREFIX + 'toggle add-on menu'),
|
||||
APP_PROCESS_COMMAND_LINE_ARGS: type(PREFIX + 'process command line args')
|
||||
};
|
||||
|
||||
export class AppBootsrappedAction implements Action {
|
||||
@@ -26,7 +29,21 @@ export class ShowNotificationAction implements Action {
|
||||
constructor(public payload: Notification) { }
|
||||
}
|
||||
|
||||
export class ToggleAddonMenuAction implements Action {
|
||||
type = ActionTypes.APP_TOGGLE_ADDON_MENU;
|
||||
|
||||
constructor(public payload: boolean) { }
|
||||
}
|
||||
|
||||
export class ProcessCommandLineArgsAction implements Action {
|
||||
type = ActionTypes.APP_PROCESS_COMMAND_LINE_ARGS;
|
||||
|
||||
constructor(public payload: CommandLineArgs) { }
|
||||
}
|
||||
|
||||
export type Actions
|
||||
= AppStartedAction
|
||||
| AppBootsrappedAction
|
||||
| ShowNotificationAction;
|
||||
| ShowNotificationAction
|
||||
| ToggleAddonMenuAction
|
||||
| ProcessCommandLineArgsAction;
|
||||
|
||||
@@ -7,8 +7,9 @@ import { NotifierService } from 'angular-notifier';
|
||||
import 'rxjs/add/operator/do';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
import { ActionTypes } from '../actions/app.action';
|
||||
import { ActionTypes, ToggleAddonMenuAction } from '../actions/app.action';
|
||||
import { Notification, NotificationType } from '../../models/notification';
|
||||
import { CommandLineArgs } from '../../models/command-line-args';
|
||||
|
||||
@Injectable()
|
||||
export class ApplicationEffects {
|
||||
@@ -22,6 +23,12 @@ export class ApplicationEffects {
|
||||
this.notifierService.notify(type, notification.message);
|
||||
});
|
||||
|
||||
@Effect()
|
||||
processCommandLineArgs: Observable<Action> = this.actions$
|
||||
.ofType(ActionTypes.APP_PROCESS_COMMAND_LINE_ARGS)
|
||||
.map(toPayload)
|
||||
.map((args: CommandLineArgs) => new ToggleAddonMenuAction(args.addons || false));
|
||||
|
||||
// TODO: Change typescript -> 2.4 and use string enum.
|
||||
// Corrently ngrx store is not compatible witn typescript 2.4
|
||||
private static mapNotificationType(type: NotificationType): string {
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
import { createSelector } from 'reselect';
|
||||
import { RouterState } from '@ngrx/router-store';
|
||||
|
||||
import { Keymap } from '../config-serializer/config-items/keymap';
|
||||
import { UserConfiguration } from '../config-serializer/config-items/user-configuration';
|
||||
import * as autoUpdate from './reducers/auto-update-settings';
|
||||
import * as fromApp from './reducers/app.reducer';
|
||||
|
||||
// State interface for the application
|
||||
export interface AppState {
|
||||
userConfiguration: UserConfiguration;
|
||||
presetKeymaps: Keymap[];
|
||||
autoUpdateSettings: autoUpdate.State;
|
||||
app: fromApp.State;
|
||||
router: RouterState;
|
||||
}
|
||||
|
||||
export const getUserConfiguration = (state: AppState) => state.userConfiguration;
|
||||
|
||||
export const appState = (state: AppState) => state.app;
|
||||
export const showAddonMenu = createSelector(appState, fromApp.showAddonMenu);
|
||||
|
||||
export const appUpdateState = (state: AppState) => state.autoUpdateSettings;
|
||||
|
||||
export const getAutoUpdateSettings = createSelector(appUpdateState, autoUpdate.getUpdateSettings);
|
||||
|
||||
30
shared/src/store/reducers/app.reducer.ts
Normal file
30
shared/src/store/reducers/app.reducer.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { ActionTypes } from '../actions/app.action';
|
||||
|
||||
export interface State {
|
||||
started: boolean;
|
||||
showAddonMenu: boolean;
|
||||
}
|
||||
|
||||
const initialState: State = {
|
||||
started: false,
|
||||
showAddonMenu: false
|
||||
};
|
||||
|
||||
export function reducer(state = initialState, action: Action) {
|
||||
switch (action.type) {
|
||||
case ActionTypes.APP_STARTED: {
|
||||
return Object.assign({ ...state }, { started: true });
|
||||
}
|
||||
|
||||
case ActionTypes.APP_TOGGLE_ADDON_MENU: {
|
||||
return Object.assign({ ...state }, { showAddonMenu: action.payload });
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export const showAddonMenu = (state: State) => state.showAddonMenu;
|
||||
@@ -3,13 +3,15 @@ import { routerReducer } from '@ngrx/router-store';
|
||||
import userConfigurationReducer from './user-configuration';
|
||||
import presetReducer from './preset';
|
||||
import { reducer as autoUpdateReducer } from './auto-update-settings';
|
||||
import { reducer as appReducer } from './app.reducer';
|
||||
|
||||
export { userConfigurationReducer, presetReducer, autoUpdateReducer };
|
||||
export { userConfigurationReducer, presetReducer, autoUpdateReducer, appReducer };
|
||||
|
||||
// All reducers that are used in application
|
||||
export const reducer = {
|
||||
userConfiguration: userConfigurationReducer,
|
||||
presetKeymaps: presetReducer,
|
||||
router: routerReducer,
|
||||
autoUpdateSettings: autoUpdateReducer
|
||||
autoUpdateSettings: autoUpdateReducer,
|
||||
app: appReducer
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class App {
|
||||
public static readonly appStarted = 'app-started';
|
||||
public static readonly getCommandLineArgs = 'app-get-command-line-args';
|
||||
public static readonly getCommandLineArgsReply = 'app-get-command-line-args-reply';
|
||||
}
|
||||
|
||||
class AutoUpdate {
|
||||
|
||||
Reference in New Issue
Block a user