feat(user-config): Upload user configuration from json/bin file (#545)
* feat(user-config): Upload user configuration from json/bin file * fix error message * remove file extension filter * apply user config after loaded from file * add file filter * remove file filter
This commit is contained in:
committed by
László Monda
parent
b3f2e3451e
commit
f0139c55ee
@@ -14,9 +14,11 @@
|
||||
<span role="button" class="btn-link" (click)="saveConfigurationInBINFormat()">binary</span> format.
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn btn-default"
|
||||
>Upload device configuration
|
||||
</button>
|
||||
<label class="btn btn-default btn-file">
|
||||
Upload device configuration
|
||||
<input type="file"
|
||||
(change)="changeFile($event)">
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn btn-danger"
|
||||
|
||||
@@ -3,7 +3,11 @@ import { Store } from '@ngrx/store';
|
||||
|
||||
import { AppState } from '../../../store';
|
||||
import { ResetUserConfigurationAction } from '../../../store/actions/device';
|
||||
import { SaveUserConfigInBinaryFileAction, SaveUserConfigInJsonFileAction } from '../../../store/actions/user-config';
|
||||
import {
|
||||
LoadUserConfigurationFromFileAction,
|
||||
SaveUserConfigInBinaryFileAction,
|
||||
SaveUserConfigInJsonFileAction
|
||||
} from '../../../store/actions/user-config';
|
||||
|
||||
@Component({
|
||||
selector: 'device-settings',
|
||||
@@ -29,4 +33,17 @@ export class DeviceConfigurationComponent {
|
||||
saveConfigurationInBINFormat() {
|
||||
this.store.dispatch(new SaveUserConfigInBinaryFileAction());
|
||||
}
|
||||
|
||||
changeFile(event): void {
|
||||
const files = event.srcElement.files;
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onloadend = function () {
|
||||
const arrayBuffer = new Uint8Array(fileReader.result);
|
||||
this.store.dispatch(new LoadUserConfigurationFromFileAction({
|
||||
filename: event.srcElement.value,
|
||||
data: Array.from(arrayBuffer)
|
||||
}));
|
||||
}.bind(this);
|
||||
fileReader.readAsArrayBuffer(files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
4
packages/uhk-web/src/app/models/upload-file-data.ts
Normal file
4
packages/uhk-web/src/app/models/upload-file-data.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface UploadFileData {
|
||||
filename: string;
|
||||
data: Array<number>;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { type, UserConfiguration, ConfigurationReply } from 'uhk-common';
|
||||
import { UserConfigurationValue } from '../../models/user-configuration-value';
|
||||
import { UploadFileData } from '../../models/upload-file-data';
|
||||
|
||||
const PREFIX = '[user-config] ';
|
||||
|
||||
@@ -15,7 +16,9 @@ export const ActionTypes = {
|
||||
SAVE_USER_CONFIG_IN_BIN_FILE: type(PREFIX + 'Save User Config in binary file'),
|
||||
LOAD_RESET_USER_CONFIGURATION: type(PREFIX + 'Load reset user configuration'),
|
||||
RENAME_USER_CONFIGURATION: type(PREFIX + 'Rename user configuration'),
|
||||
SET_USER_CONFIGURATION_VALUE: type(PREFIX + 'Set user configuration value')
|
||||
SET_USER_CONFIGURATION_VALUE: type(PREFIX + 'Set user configuration value'),
|
||||
LOAD_USER_CONFIGURATION_FROM_FILE: type(PREFIX + 'Load user configuration from file'),
|
||||
APPLY_USER_CONFIGURATION_FROM_FILE: type(PREFIX + 'Apply user configuration from file')
|
||||
};
|
||||
|
||||
export class LoadUserConfigAction implements Action {
|
||||
@@ -76,6 +79,20 @@ export class SetUserConfigurationValueAction implements Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class LoadUserConfigurationFromFileAction implements Action {
|
||||
type = ActionTypes.LOAD_USER_CONFIGURATION_FROM_FILE;
|
||||
|
||||
constructor(public payload: UploadFileData) {
|
||||
}
|
||||
}
|
||||
|
||||
export class ApplyUserConfigurationFromFileAction implements Action {
|
||||
type = ActionTypes.APPLY_USER_CONFIGURATION_FROM_FILE;
|
||||
|
||||
constructor(public payload: UserConfiguration) {
|
||||
}
|
||||
}
|
||||
|
||||
export type Actions
|
||||
= LoadUserConfigAction
|
||||
| LoadUserConfigSuccessAction
|
||||
@@ -87,4 +104,6 @@ export type Actions
|
||||
| LoadResetUserConfigurationAction
|
||||
| RenameUserConfigurationAction
|
||||
| SetUserConfigurationValueAction
|
||||
| LoadUserConfigurationFromFileAction
|
||||
| ApplyUserConfigurationFromFileAction
|
||||
;
|
||||
|
||||
@@ -162,7 +162,7 @@ export class DeviceEffects {
|
||||
});
|
||||
|
||||
@Effect() saveResetUserConfigurationToDevice$ = this.actions$
|
||||
.ofType(UserConfigActions.LOAD_RESET_USER_CONFIGURATION)
|
||||
.ofType(UserConfigActions.LOAD_RESET_USER_CONFIGURATION, UserConfigActions.APPLY_USER_CONFIGURATION_FROM_FILE)
|
||||
.switchMap(() => Observable.of(new SaveConfigurationAction()));
|
||||
|
||||
@Effect({dispatch: false}) updateFirmware$ = this.actions$
|
||||
|
||||
@@ -15,12 +15,21 @@ import 'rxjs/add/observable/of';
|
||||
import 'rxjs/add/observable/empty';
|
||||
|
||||
import {
|
||||
ConfigurationReply, HardwareConfiguration, LogService, NotificationType, UhkBuffer,
|
||||
ConfigurationReply,
|
||||
HardwareConfiguration,
|
||||
LogService,
|
||||
NotificationType,
|
||||
UhkBuffer,
|
||||
UserConfiguration
|
||||
} from 'uhk-common';
|
||||
|
||||
import {
|
||||
ActionTypes, LoadConfigFromDeviceReplyAction, LoadUserConfigSuccessAction, RenameUserConfigurationAction,
|
||||
ActionTypes,
|
||||
ApplyUserConfigurationFromFileAction,
|
||||
LoadConfigFromDeviceReplyAction,
|
||||
LoadUserConfigSuccessAction,
|
||||
LoadUserConfigurationFromFileAction,
|
||||
RenameUserConfigurationAction,
|
||||
SaveUserConfigSuccessAction
|
||||
} from '../actions/user-config';
|
||||
|
||||
@@ -29,12 +38,15 @@ import { DefaultUserConfigurationService } from '../../services/default-user-con
|
||||
import { AppState, autoWriteUserConfiguration, getPrevUserConfiguration, getUserConfiguration } from '../index';
|
||||
import { KeymapAction, KeymapActions, MacroAction, MacroActions } from '../actions';
|
||||
import {
|
||||
DismissUndoNotificationAction, LoadHardwareConfigurationSuccessAction, ShowNotificationAction,
|
||||
DismissUndoNotificationAction,
|
||||
LoadHardwareConfigurationSuccessAction,
|
||||
ShowNotificationAction,
|
||||
UndoLastAction
|
||||
} from '../actions/app';
|
||||
import { SaveConfigurationAction, ShowSaveToKeyboardButtonAction } from '../actions/device';
|
||||
import { DeviceRendererService } from '../../services/device-renderer.service';
|
||||
import { UndoUserConfigData } from '../../models/undo-user-config-data';
|
||||
import { UploadFileData } from '../../models/upload-file-data';
|
||||
|
||||
@Injectable()
|
||||
export class UserConfigEffects {
|
||||
@@ -198,6 +210,38 @@ export class UserConfigEffects {
|
||||
}
|
||||
});
|
||||
|
||||
@Effect() loadUserConfigurationFromFile$ = this.actions$
|
||||
.ofType<LoadUserConfigurationFromFileAction>(ActionTypes.LOAD_USER_CONFIGURATION_FROM_FILE)
|
||||
.map(action => action.payload)
|
||||
.map((info: UploadFileData) => {
|
||||
try {
|
||||
const userConfig = new UserConfiguration();
|
||||
|
||||
if (info.filename.endsWith('.bin')) {
|
||||
userConfig.fromBinary(UhkBuffer.fromArray(info.data));
|
||||
}
|
||||
else {
|
||||
const buffer = new Buffer(info.data);
|
||||
const json = buffer.toString();
|
||||
userConfig.fromJsonObject(JSON.parse(json));
|
||||
}
|
||||
|
||||
if (userConfig.userConfigMajorVersion) {
|
||||
return new ApplyUserConfigurationFromFileAction(userConfig);
|
||||
}
|
||||
|
||||
return new ShowNotificationAction({
|
||||
type: NotificationType.Error,
|
||||
message: 'Invalid configuration specified.'
|
||||
});
|
||||
} catch (err) {
|
||||
return new ShowNotificationAction({
|
||||
type: NotificationType.Error,
|
||||
message: 'Invalid configuration specified.'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
constructor(private actions$: Actions,
|
||||
private dataStorageRepository: DataStorageRepositoryService,
|
||||
private store: Store<AppState>,
|
||||
|
||||
@@ -16,6 +16,7 @@ export function reducer(state = initialState, action: Action & { payload?: any }
|
||||
const changedUserConfiguration: UserConfiguration = Object.assign(new UserConfiguration(), state);
|
||||
|
||||
switch (action.type) {
|
||||
case ActionTypes.APPLY_USER_CONFIGURATION_FROM_FILE:
|
||||
case ActionTypes.LOAD_RESET_USER_CONFIGURATION:
|
||||
case ActionTypes.LOAD_USER_CONFIG_SUCCESS: {
|
||||
return Object.assign(changedUserConfiguration, action.payload);
|
||||
|
||||
@@ -94,3 +94,24 @@ a.disabled {
|
||||
.noUi-value {
|
||||
top: 2rem;
|
||||
}
|
||||
|
||||
.btn-file {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
input[type=file] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
font-size: 100px;
|
||||
text-align: right;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
outline: none;
|
||||
background: white;
|
||||
cursor: inherit;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user