Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3978011d2e | ||
|
|
cd1952a7df | ||
|
|
4251477451 | ||
|
|
873f1de1ef | ||
|
|
150f993e5f | ||
|
|
06e76e5e0f | ||
|
|
a208a264c7 | ||
|
|
114014fa13 | ||
|
|
94cfd9d2e9 | ||
|
|
0aa9c73b4b | ||
|
|
5234f85dbe | ||
|
|
bd8a2f704f | ||
|
|
439886d69f | ||
|
|
b2a37795e3 |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -6,6 +6,26 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1
|
|||||||
|
|
||||||
Every Agent version includes the most recent firmware version. See the [firmware changelog](https://github.com/UltimateHackingKeyboard/firmware/blob/master/CHANGELOG.md).
|
Every Agent version includes the most recent firmware version. See the [firmware changelog](https://github.com/UltimateHackingKeyboard/firmware/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
## [1.2.5] - 2018-06-26
|
||||||
|
|
||||||
|
Firmware: 8.2.5 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.3.1 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
||||||
|
|
||||||
|
- When remapping a switch keymap action on all keymaps, don't set it on its own keymap.
|
||||||
|
- Make the key action popver always contain the action of the current key, even after cancelled.
|
||||||
|
- Include the firmware version to be updated to the firmware update log.
|
||||||
|
- Update the Agent icon of the side menu and the about page.
|
||||||
|
- When remapping a key, only flash the affected key instead of all keys.
|
||||||
|
- Fade in/out the keyboard separator line only when splitting the keyboard.
|
||||||
|
- Only show the unsupported OS message of the firmware page on relevant Windows versions.
|
||||||
|
- Close and reopen USB device when an error occurs.
|
||||||
|
- Temporarily remove the export keymap feature because it's useless until import is implemented.
|
||||||
|
|
||||||
|
## [1.2.4] - 2018-06-21
|
||||||
|
|
||||||
|
Firmware: 8.2.5 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.3.1 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
||||||
|
|
||||||
|
- Replace Linux x86-64 blhost with a statically linked version which should make firmware updates work on every Linux distro.
|
||||||
|
|
||||||
## [1.2.3] - 2018-06-19
|
## [1.2.3] - 2018-06-19
|
||||||
|
|
||||||
Firmware: 8.2.5 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.3.1 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
Firmware: 8.2.5 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.3.1 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
||||||
@@ -16,7 +36,7 @@ Firmware: 8.2.5 [[release](https://github.com/UltimateHackingKeyboard/firmware/r
|
|||||||
- Improve the looks and content of the tooltips of the key action popover.
|
- Improve the looks and content of the tooltips of the key action popover.
|
||||||
- Make the left keyboard half less likely to timeout during firmware update.
|
- Make the left keyboard half less likely to timeout during firmware update.
|
||||||
- Terminate the firmware update process if blhost segfaults.
|
- Terminate the firmware update process if blhost segfaults.
|
||||||
- Replace the Linux x64 version of the blhost binary which should not make it segfault anymore.
|
- Replace the Linux x86-64 version of the blhost binary which should not make it segfault anymore.
|
||||||
- Make the firmware update log shorter by listing one device per line and not repeating the list of available USB devices.
|
- Make the firmware update log shorter by listing one device per line and not repeating the list of available USB devices.
|
||||||
- Make the firmware update help text shorter.
|
- Make the firmware update help text shorter.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"author": "Ultimate Gadget Laboratories",
|
"author": "Ultimate Gadget Laboratories",
|
||||||
"main": "electron/dist/electron-main.js",
|
"main": "electron/dist/electron-main.js",
|
||||||
"version": "1.2.3",
|
"version": "1.2.5",
|
||||||
"firmwareVersion": "8.2.5",
|
"firmwareVersion": "8.2.5",
|
||||||
"deviceProtocolVersion": "4.3.1",
|
"deviceProtocolVersion": "4.3.1",
|
||||||
"userConfigVersion": "4.0.1",
|
"userConfigVersion": "4.0.1",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ function createWindow() {
|
|||||||
uhkHidDeviceService = new UhkHidDevice(logger, options);
|
uhkHidDeviceService = new UhkHidDevice(logger, options);
|
||||||
uhkBlhost = new UhkBlhost(logger, packagesDir);
|
uhkBlhost = new UhkBlhost(logger, packagesDir);
|
||||||
uhkOperations = new UhkOperations(logger, uhkBlhost, uhkHidDeviceService, packagesDir);
|
uhkOperations = new UhkOperations(logger, uhkBlhost, uhkHidDeviceService, packagesDir);
|
||||||
deviceService = new DeviceService(logger, win, uhkHidDeviceService, uhkOperations);
|
deviceService = new DeviceService(logger, win, uhkHidDeviceService, uhkOperations, packagesDir);
|
||||||
appUpdateService = new AppUpdateService(logger, win, app);
|
appUpdateService = new AppUpdateService(logger, win, app);
|
||||||
appService = new AppService(logger, win, deviceService, options, uhkHidDeviceService);
|
appService = new AppService(logger, win, deviceService, options, uhkHidDeviceService);
|
||||||
sudoService = new SudoService(logger, options);
|
sudoService = new SudoService(logger, options);
|
||||||
|
|||||||
@@ -3,5 +3,6 @@ import { SynchrounousResult } from 'tmp';
|
|||||||
export interface TmpFirmware {
|
export interface TmpFirmware {
|
||||||
rightFirmwarePath: string;
|
rightFirmwarePath: string;
|
||||||
leftFirmwarePath: string;
|
leftFirmwarePath: string;
|
||||||
|
packageJsonPath: string;
|
||||||
tmpDirectory: SynchrounousResult;
|
tmpDirectory: SynchrounousResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ipcMain, shell } from 'electron';
|
import { ipcMain, shell } from 'electron';
|
||||||
import { UhkHidDevice } from 'uhk-usb';
|
import { UhkHidDevice } from 'uhk-usb';
|
||||||
|
import * as os from 'os';
|
||||||
|
|
||||||
import { AppStartInfo, IpcEvents, LogService } from 'uhk-common';
|
import { AppStartInfo, IpcEvents, LogService } from 'uhk-common';
|
||||||
import { MainServiceBase } from './main-service-base';
|
import { MainServiceBase } from './main-service-base';
|
||||||
@@ -30,7 +31,9 @@ export class AppService extends MainServiceBase {
|
|||||||
},
|
},
|
||||||
deviceConnected: deviceConnectionState.connected,
|
deviceConnected: deviceConnectionState.connected,
|
||||||
hasPermission: deviceConnectionState.hasPermission,
|
hasPermission: deviceConnectionState.hasPermission,
|
||||||
bootloaderActive: deviceConnectionState.bootloaderActive
|
bootloaderActive: deviceConnectionState.bootloaderActive,
|
||||||
|
platform: process.platform as string,
|
||||||
|
osVersion: os.release()
|
||||||
};
|
};
|
||||||
this.logService.info('[AppService] getAppStartInfo response:', response);
|
this.logService.info('[AppService] getAppStartInfo response:', response);
|
||||||
return event.sender.send(IpcEvents.app.getAppStartInfoReply, response);
|
return event.sender.send(IpcEvents.app.getAppStartInfoReply, response);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { deviceConnectionStateComparer, snooze, UhkHidDevice, UhkOperations } fr
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
import { emptyDir } from 'fs-extra';
|
import { emptyDir } from 'fs-extra';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
import 'rxjs/add/observable/interval';
|
import 'rxjs/add/observable/interval';
|
||||||
import 'rxjs/add/operator/startWith';
|
import 'rxjs/add/operator/startWith';
|
||||||
@@ -22,10 +23,14 @@ import 'rxjs/add/operator/map';
|
|||||||
import 'rxjs/add/operator/do';
|
import 'rxjs/add/operator/do';
|
||||||
import 'rxjs/add/operator/distinctUntilChanged';
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
|
||||||
import { saveTmpFirmware } from '../util/save-extract-firmware';
|
|
||||||
import { TmpFirmware } from '../models/tmp-firmware';
|
import { TmpFirmware } from '../models/tmp-firmware';
|
||||||
import { QueueManager } from './queue-manager';
|
import { QueueManager } from './queue-manager';
|
||||||
import { backupUserConfiguration, getBackupUserConfigurationContent } from '../util/backup-user-confoguration';
|
import {
|
||||||
|
backupUserConfiguration,
|
||||||
|
getBackupUserConfigurationContent,
|
||||||
|
getPackageJsonFromPathAsync,
|
||||||
|
saveTmpFirmware
|
||||||
|
} from '../util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IpcMain pair of the UHK Communication
|
* IpcMain pair of the UHK Communication
|
||||||
@@ -40,7 +45,8 @@ export class DeviceService {
|
|||||||
constructor(private logService: LogService,
|
constructor(private logService: LogService,
|
||||||
private win: Electron.BrowserWindow,
|
private win: Electron.BrowserWindow,
|
||||||
private device: UhkHidDevice,
|
private device: UhkHidDevice,
|
||||||
private operations: UhkOperations) {
|
private operations: UhkOperations,
|
||||||
|
private rootDir: string) {
|
||||||
this.pollUhkDevice();
|
this.pollUhkDevice();
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.device.saveUserConfiguration, (...args: any[]) => {
|
ipcMain.on(IpcEvents.device.saveUserConfiguration, (...args: any[]) => {
|
||||||
@@ -146,15 +152,27 @@ export class DeviceService {
|
|||||||
let firmwarePathData: TmpFirmware;
|
let firmwarePathData: TmpFirmware;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const hardwareModules = await this.getHardwareModules(false);
|
||||||
|
this.logService.debug('Device right firmware version:', hardwareModules.rightModuleInfo.firmwareVersion);
|
||||||
|
this.logService.debug('Device left firmware version:', hardwareModules.leftModuleInfo.firmwareVersion);
|
||||||
|
|
||||||
this.device.resetDeviceCache();
|
this.device.resetDeviceCache();
|
||||||
this.stopPollTimer();
|
this.stopPollTimer();
|
||||||
|
|
||||||
if (args && args.length > 0) {
|
if (args && args.length > 0) {
|
||||||
firmwarePathData = await saveTmpFirmware(args[0]);
|
firmwarePathData = await saveTmpFirmware(args[0]);
|
||||||
|
|
||||||
|
const packageJson = await getPackageJsonFromPathAsync(firmwarePathData.packageJsonPath);
|
||||||
|
this.logService.debug('New firmware version:', packageJson.firmwareVersion);
|
||||||
|
|
||||||
await this.operations.updateRightFirmware(firmwarePathData.rightFirmwarePath);
|
await this.operations.updateRightFirmware(firmwarePathData.rightFirmwarePath);
|
||||||
await this.operations.updateLeftModule(firmwarePathData.leftFirmwarePath);
|
await this.operations.updateLeftModule(firmwarePathData.leftFirmwarePath);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
const packageJsonPath = path.join(this.rootDir, 'packages/firmware/package.json');
|
||||||
|
const packageJson = await getPackageJsonFromPathAsync(packageJsonPath);
|
||||||
|
this.logService.debug('New firmware version:', packageJson.firmwareVersion);
|
||||||
|
|
||||||
await this.operations.updateRightFirmware();
|
await this.operations.updateRightFirmware();
|
||||||
await this.operations.updateLeftModule();
|
await this.operations.updateLeftModule();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
export const getPackageJsonFromPathAsync = async (filePath: string): Promise<any> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(filePath, {encoding: 'utf-8'}, (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(JSON.parse(data));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
3
packages/uhk-agent/src/util/index.ts
Normal file
3
packages/uhk-agent/src/util/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * from './backup-user-confoguration';
|
||||||
|
export * from './get-package-json-from-path-async';
|
||||||
|
export * from './save-extract-firmware';
|
||||||
@@ -16,8 +16,8 @@ export async function saveTmpFirmware(data: string): Promise<TmpFirmware> {
|
|||||||
return {
|
return {
|
||||||
tmpDirectory,
|
tmpDirectory,
|
||||||
rightFirmwarePath: path.join(tmpDirectory.name, 'devices/uhk60-right/firmware.hex'),
|
rightFirmwarePath: path.join(tmpDirectory.name, 'devices/uhk60-right/firmware.hex'),
|
||||||
leftFirmwarePath: path.join(tmpDirectory.name, 'modules/uhk60-left.bin')
|
leftFirmwarePath: path.join(tmpDirectory.name, 'modules/uhk60-left.bin'),
|
||||||
|
packageJsonPath: path.join(tmpDirectory.name, 'package.json')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,6 @@ export interface AppStartInfo {
|
|||||||
deviceConnected: boolean;
|
deviceConnected: boolean;
|
||||||
hasPermission: boolean;
|
hasPermission: boolean;
|
||||||
bootloaderActive: boolean;
|
bootloaderActive: boolean;
|
||||||
|
platform: string;
|
||||||
|
osVersion: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ export class UhkHidDevice {
|
|||||||
device.read((err: any, receivedData: Array<number>) => {
|
device.read((err: any, receivedData: Array<number>) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.logService.error('[UhkHidDevice] Transfer error: ', err);
|
this.logService.error('[UhkHidDevice] Transfer error: ', err);
|
||||||
|
this.close();
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
const logString = bufferToString(receivedData);
|
const logString = bufferToString(receivedData);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
Firmware {{ hardwareModules.rightModuleInfo.firmwareVersion }} is running on the right keyboard half.
|
Firmware {{ hardwareModules.rightModuleInfo.firmwareVersion }} is running on the right keyboard half.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>Please note that firmware update doesn't work on Windows 7, Windows Vista, and Windows XP. Use Windows 10, Windows 8, Linux, or OSX instead.</p>
|
<p *ngIf="showUnsupportedOsToFirmwareUpgrade$ | async">Firmware update doesn't work on Windows 7, Windows Vista, and Windows XP. Use Windows 10, Windows 8, Linux, or OSX instead.</p>
|
||||||
|
|
||||||
<p>If the update process fails, disconnect every USB device from your computer including USB hubs, KVM switches, and every USB device. Then connect only your UHK and retry.</p>
|
<p>If the update process fails, disconnect every USB device from your computer including USB hubs, KVM switches, and every USB device. Then connect only your UHK and retry.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ import { Component, OnDestroy } from '@angular/core';
|
|||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
import { HardwareModules, VersionInformation } from 'uhk-common';
|
import { Constants, HardwareModules, VersionInformation } from 'uhk-common';
|
||||||
import { Constants } from 'uhk-common';
|
|
||||||
import { OpenUrlInNewWindowAction } from '../../../store/actions/app';
|
|
||||||
|
|
||||||
|
import { OpenUrlInNewWindowAction } from '../../../store/actions/app';
|
||||||
import {
|
import {
|
||||||
AppState,
|
AppState,
|
||||||
flashFirmwareButtonDisbabled,
|
flashFirmwareButtonDisbabled,
|
||||||
getAgentVersionInfo,
|
getAgentVersionInfo,
|
||||||
getHardwareModules,
|
getHardwareModules,
|
||||||
|
showUnsupportedOsToFirmwareUpgrade,
|
||||||
xtermLog
|
xtermLog
|
||||||
} from '../../../store';
|
} from '../../../store';
|
||||||
import { UpdateFirmwareAction, UpdateFirmwareWithAction } from '../../../store/actions/device';
|
import { UpdateFirmwareAction, UpdateFirmwareWithAction } from '../../../store/actions/device';
|
||||||
@@ -31,6 +31,7 @@ export class DeviceFirmwareComponent implements OnDestroy {
|
|||||||
getAgentVersionInfo$: Observable<VersionInformation>;
|
getAgentVersionInfo$: Observable<VersionInformation>;
|
||||||
hardwareModulesSubscription: Subscription;
|
hardwareModulesSubscription: Subscription;
|
||||||
hardwareModules: HardwareModules;
|
hardwareModules: HardwareModules;
|
||||||
|
showUnsupportedOsToFirmwareUpgrade$: Observable<boolean>;
|
||||||
|
|
||||||
constructor(private store: Store<AppState>) {
|
constructor(private store: Store<AppState>) {
|
||||||
this.flashFirmwareButtonDisbabled$ = store.select(flashFirmwareButtonDisbabled);
|
this.flashFirmwareButtonDisbabled$ = store.select(flashFirmwareButtonDisbabled);
|
||||||
@@ -39,6 +40,7 @@ export class DeviceFirmwareComponent implements OnDestroy {
|
|||||||
this.hardwareModulesSubscription = store.select(getHardwareModules).subscribe(data => {
|
this.hardwareModulesSubscription = store.select(getHardwareModules).subscribe(data => {
|
||||||
this.hardwareModules = data;
|
this.hardwareModules = data;
|
||||||
});
|
});
|
||||||
|
this.showUnsupportedOsToFirmwareUpgrade$ = store.select(showUnsupportedOsToFirmwareUpgrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
|
|||||||
@@ -37,12 +37,12 @@
|
|||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
(click)="duplicateKeymap()"
|
(click)="duplicateKeymap()"
|
||||||
></i>
|
></i>
|
||||||
<i class="fa fa-download keymap__download pull-right"
|
<!--i class="fa fa-download keymap__download pull-right"
|
||||||
title="Download keymap"
|
title="Download keymap"
|
||||||
[html]="true"
|
[html]="true"
|
||||||
data-toggle="tooltip"
|
data-toggle="tooltip"
|
||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
(click)="onDownloadIconClick()"></i>
|
(click)="onDownloadIconClick()"></i-->
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</uhk-header>
|
</uhk-header>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
(keyHover)="onKeyHover($event.index, $event.event, $event.over, i)"
|
(keyHover)="onKeyHover($event.index, $event.event, $event.over, i)"
|
||||||
(capture)="onCapture(i, $event.index, $event.captured)" />
|
(capture)="onCapture(i, $event.index, $event.captured)" />
|
||||||
|
|
||||||
<svg:path [ngClass]="{'separator-visible': !halvesSplit, 'separator-hide': halvesSplit}"
|
<svg:path [@fadeSeparator]="separatorAnimation"
|
||||||
[attr.d]="separator.d"
|
[attr.d]="separator.d"
|
||||||
[attr.style]="separatorStyle" />
|
[attr.style]="separatorStyle" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -8,33 +8,3 @@ editable-text {
|
|||||||
padding-right: 2em;
|
padding-right: 2em;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.separator-visible {
|
|
||||||
animation: visible-fade-in 1.5s;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes visible-fade-in {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.separator-hide {
|
|
||||||
animation: visible-fade-out 1.5s;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes visible-fade-out {
|
|
||||||
0% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,6 +22,16 @@ import { SvgSeparator } from '../separator';
|
|||||||
transform: 'translate(3%, 15%) rotate(-4deg) scale(0.92, 0.92)'
|
transform: 'translate(3%, 15%) rotate(-4deg) scale(0.92, 0.92)'
|
||||||
})),
|
})),
|
||||||
transition('* <=> *', animate(500))
|
transition('* <=> *', animate(500))
|
||||||
|
]),
|
||||||
|
trigger('fadeSeparator', [
|
||||||
|
state('visible', style({
|
||||||
|
opacity: 1
|
||||||
|
})),
|
||||||
|
state('invisible', style({
|
||||||
|
opacity: 0
|
||||||
|
})),
|
||||||
|
transition('visible => invisible', animate(500)),
|
||||||
|
transition('invisible => visible', animate(1500))
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@@ -45,6 +55,7 @@ export class SvgKeyboardComponent implements OnInit {
|
|||||||
moduleAnimationStates: string[];
|
moduleAnimationStates: string[];
|
||||||
separator: SvgSeparator;
|
separator: SvgSeparator;
|
||||||
separatorStyle: SafeStyle;
|
separatorStyle: SafeStyle;
|
||||||
|
separatorAnimation = 'visible';
|
||||||
|
|
||||||
constructor(private svgModuleProvider: SvgModuleProviderService,
|
constructor(private svgModuleProvider: SvgModuleProviderService,
|
||||||
private sanitizer: DomSanitizer) {
|
private sanitizer: DomSanitizer) {
|
||||||
@@ -96,8 +107,10 @@ export class SvgKeyboardComponent implements OnInit {
|
|||||||
private updateModuleAnimationStates() {
|
private updateModuleAnimationStates() {
|
||||||
if (this.halvesSplit) {
|
if (this.halvesSplit) {
|
||||||
this.moduleAnimationStates = ['rotateRight', 'rotateLeft'];
|
this.moduleAnimationStates = ['rotateRight', 'rotateLeft'];
|
||||||
|
this.separatorAnimation = 'invisible';
|
||||||
} else {
|
} else {
|
||||||
this.moduleAnimationStates = [];
|
this.moduleAnimationStates = [];
|
||||||
|
this.separatorAnimation = 'visible';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
|
|||||||
hidePopover(): void {
|
hidePopover(): void {
|
||||||
this.popoverShown = false;
|
this.popoverShown = false;
|
||||||
this.selectedKey = undefined;
|
this.selectedKey = undefined;
|
||||||
|
this.popoverInitKeyAction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectLayer(index: number): void {
|
selectLayer(index: number): void {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Action } from '@ngrx/store';
|
import { Action } from '@ngrx/store';
|
||||||
|
|
||||||
import { AppStartInfo, CommandLineArgs, HardwareConfiguration, Notification, type } from 'uhk-common';
|
import { AppStartInfo, HardwareConfiguration, Notification, type } from 'uhk-common';
|
||||||
import { ElectronLogEntry } from '../../models/xterm-log';
|
import { ElectronLogEntry } from '../../models/xterm-log';
|
||||||
|
|
||||||
const PREFIX = '[app] ';
|
const PREFIX = '[app] ';
|
||||||
@@ -10,7 +10,7 @@ export const ActionTypes = {
|
|||||||
APP_BOOTSRAPPED: type(PREFIX + 'bootstrapped'),
|
APP_BOOTSRAPPED: type(PREFIX + 'bootstrapped'),
|
||||||
APP_STARTED: type(PREFIX + 'started'),
|
APP_STARTED: type(PREFIX + 'started'),
|
||||||
APP_SHOW_NOTIFICATION: type(PREFIX + 'show notification'),
|
APP_SHOW_NOTIFICATION: type(PREFIX + 'show notification'),
|
||||||
APPLY_COMMAND_LINE_ARGS: type(PREFIX + 'apply command line args'),
|
APPLY_APP_START_INFO: type(PREFIX + 'apply command line args'),
|
||||||
APP_PROCESS_START_INFO: type(PREFIX + 'process start info'),
|
APP_PROCESS_START_INFO: type(PREFIX + 'process start info'),
|
||||||
UNDO_LAST: type(PREFIX + 'undo last action'),
|
UNDO_LAST: type(PREFIX + 'undo last action'),
|
||||||
UNDO_LAST_SUCCESS: type(PREFIX + 'undo last action success'),
|
UNDO_LAST_SUCCESS: type(PREFIX + 'undo last action success'),
|
||||||
@@ -38,10 +38,10 @@ export class ShowNotificationAction implements Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ApplyCommandLineArgsAction implements Action {
|
export class ApplyAppStartInfoAction implements Action {
|
||||||
type = ActionTypes.APPLY_COMMAND_LINE_ARGS;
|
type = ActionTypes.APPLY_APP_START_INFO;
|
||||||
|
|
||||||
constructor(public payload: CommandLineArgs) {
|
constructor(public payload: AppStartInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ export type Actions
|
|||||||
= AppStartedAction
|
= AppStartedAction
|
||||||
| AppBootsrappedAction
|
| AppBootsrappedAction
|
||||||
| ShowNotificationAction
|
| ShowNotificationAction
|
||||||
| ApplyCommandLineArgsAction
|
| ApplyAppStartInfoAction
|
||||||
| ProcessAppStartInfoAction
|
| ProcessAppStartInfoAction
|
||||||
| UndoLastAction
|
| UndoLastAction
|
||||||
| UndoLastSuccessAction
|
| UndoLastSuccessAction
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import 'rxjs/add/operator/catch';
|
|||||||
import { AppStartInfo, LogService, Notification, NotificationType } from 'uhk-common';
|
import { AppStartInfo, LogService, Notification, NotificationType } from 'uhk-common';
|
||||||
import {
|
import {
|
||||||
ActionTypes,
|
ActionTypes,
|
||||||
ApplyCommandLineArgsAction,
|
ApplyAppStartInfoAction,
|
||||||
AppStartedAction,
|
AppStartedAction,
|
||||||
DismissUndoNotificationAction,
|
DismissUndoNotificationAction,
|
||||||
OpenUrlInNewWindowAction,
|
OpenUrlInNewWindowAction,
|
||||||
@@ -65,7 +65,7 @@ export class ApplicationEffects {
|
|||||||
.mergeMap((appInfo: AppStartInfo) => {
|
.mergeMap((appInfo: AppStartInfo) => {
|
||||||
this.logService.debug('[AppEffect][processStartInfo] payload:', appInfo);
|
this.logService.debug('[AppEffect][processStartInfo] payload:', appInfo);
|
||||||
return [
|
return [
|
||||||
new ApplyCommandLineArgsAction(appInfo.commandLineArgs),
|
new ApplyAppStartInfoAction(appInfo),
|
||||||
new ConnectionStateChangedAction({
|
new ConnectionStateChangedAction({
|
||||||
connected: appInfo.deviceConnected,
|
connected: appInfo.deviceConnected,
|
||||||
hasPermission: appInfo.hasPermission,
|
hasPermission: appInfo.hasPermission,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export const getKeyboardLayout = createSelector(appState, fromApp.getKeyboardLay
|
|||||||
export const deviceConfigurationLoaded = createSelector(appState, fromApp.deviceConfigurationLoaded);
|
export const deviceConfigurationLoaded = createSelector(appState, fromApp.deviceConfigurationLoaded);
|
||||||
export const getAgentVersionInfo = createSelector(appState, fromApp.getAgentVersionInfo);
|
export const getAgentVersionInfo = createSelector(appState, fromApp.getAgentVersionInfo);
|
||||||
export const getPrivilegePageState = createSelector(appState, fromApp.getPrivilagePageState);
|
export const getPrivilegePageState = createSelector(appState, fromApp.getPrivilagePageState);
|
||||||
|
export const runningOnNotSupportedWindows = createSelector(appState, fromApp.runningOnNotSupportedWindows);
|
||||||
|
|
||||||
export const appUpdateState = (state: AppState) => state.appUpdate;
|
export const appUpdateState = (state: AppState) => state.appUpdate;
|
||||||
export const getShowAppUpdateAvailable = createSelector(appUpdateState, fromAppUpdate.getShowAppUpdateAvailable);
|
export const getShowAppUpdateAvailable = createSelector(appUpdateState, fromAppUpdate.getShowAppUpdateAvailable);
|
||||||
@@ -81,6 +82,7 @@ export const getHardwareModules = createSelector(deviceState, fromDevice.getHard
|
|||||||
export const getBackupUserConfigurationState = createSelector(deviceState, fromDevice.getBackupUserConfigurationState);
|
export const getBackupUserConfigurationState = createSelector(deviceState, fromDevice.getBackupUserConfigurationState);
|
||||||
export const getRestoreUserConfiguration = createSelector(deviceState, fromDevice.getHasBackupUserConfiguration);
|
export const getRestoreUserConfiguration = createSelector(deviceState, fromDevice.getHasBackupUserConfiguration);
|
||||||
export const bootloaderActive = createSelector(deviceState, fromDevice.bootloaderActive);
|
export const bootloaderActive = createSelector(deviceState, fromDevice.bootloaderActive);
|
||||||
|
export const firmwareUpgradeFailed = createSelector(deviceState, fromDevice.firmwareUpgradeFailed);
|
||||||
|
|
||||||
export const getSideMenuPageState = createSelector(
|
export const getSideMenuPageState = createSelector(
|
||||||
showAddonMenu,
|
showAddonMenu,
|
||||||
@@ -106,3 +108,9 @@ export const getSideMenuPageState = createSelector(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const getRouterState = (state: AppState) => state.router;
|
export const getRouterState = (state: AppState) => state.router;
|
||||||
|
|
||||||
|
export const showUnsupportedOsToFirmwareUpgrade = createSelector(
|
||||||
|
runningOnNotSupportedWindows,
|
||||||
|
firmwareUpgradeFailed,
|
||||||
|
(isUnsupportedOs,
|
||||||
|
hasFirmwareUpgradeFailed) => isUnsupportedOs && hasFirmwareUpgradeFailed);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ROUTER_NAVIGATION } from '@ngrx/router-store';
|
import { ROUTER_NAVIGATION } from '@ngrx/router-store';
|
||||||
import { Action } from '@ngrx/store';
|
import { Action } from '@ngrx/store';
|
||||||
import {
|
import {
|
||||||
|
AppStartInfo,
|
||||||
CommandLineArgs,
|
CommandLineArgs,
|
||||||
HardwareConfiguration,
|
HardwareConfiguration,
|
||||||
Notification,
|
Notification,
|
||||||
@@ -29,6 +30,8 @@ export interface State {
|
|||||||
agentVersionInfo?: VersionInformation;
|
agentVersionInfo?: VersionInformation;
|
||||||
privilegeWhatWillThisDoClicked: boolean;
|
privilegeWhatWillThisDoClicked: boolean;
|
||||||
permissionError?: any;
|
permissionError?: any;
|
||||||
|
platform?: string;
|
||||||
|
osVersion?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialState: State = {
|
export const initialState: State = {
|
||||||
@@ -50,10 +53,14 @@ export function reducer(state = initialState, action: Action & { payload: any })
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case ActionTypes.APPLY_COMMAND_LINE_ARGS: {
|
case ActionTypes.APPLY_APP_START_INFO: {
|
||||||
|
const payload = action.payload as AppStartInfo;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
commandLineArgs: action.payload
|
commandLineArgs: payload.commandLineArgs,
|
||||||
|
platform: payload.platform,
|
||||||
|
osVersion: payload.osVersion
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,3 +179,15 @@ export const getPrivilagePageState = (state: State): PrivilagePageSate => {
|
|||||||
showWhatWillThisDoContent: state.privilegeWhatWillThisDoClicked || permissionSetupFailed
|
showWhatWillThisDoContent: state.privilegeWhatWillThisDoClicked || permissionSetupFailed
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const runningOnNotSupportedWindows = (state: State): boolean => {
|
||||||
|
if (!state.osVersion || state.platform !== 'win32') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = state.osVersion.split('.');
|
||||||
|
const osMajor = +version[0];
|
||||||
|
const osMinor = +version[1];
|
||||||
|
|
||||||
|
return osMajor < 6 || (osMajor === 6 && osMinor < 2);
|
||||||
|
};
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export interface State {
|
|||||||
savingToKeyboard: boolean;
|
savingToKeyboard: boolean;
|
||||||
updatingFirmware: boolean;
|
updatingFirmware: boolean;
|
||||||
firmwareUpdateFinished: boolean;
|
firmwareUpdateFinished: boolean;
|
||||||
|
firmwareUpdateFailed?: boolean;
|
||||||
modules: HardwareModules;
|
modules: HardwareModules;
|
||||||
log: Array<XtermLog>;
|
log: Array<XtermLog>;
|
||||||
restoringUserConfiguration: boolean;
|
restoringUserConfiguration: boolean;
|
||||||
@@ -136,6 +137,7 @@ export function reducer(state = initialState, action: Action): State {
|
|||||||
...state,
|
...state,
|
||||||
updatingFirmware: false,
|
updatingFirmware: false,
|
||||||
firmwareUpdateFinished: true,
|
firmwareUpdateFinished: true,
|
||||||
|
firmwareUpdateFailed: false,
|
||||||
modules: (action as UpdateFirmwareSuccessAction).payload
|
modules: (action as UpdateFirmwareSuccessAction).payload
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -150,6 +152,7 @@ export function reducer(state = initialState, action: Action): State {
|
|||||||
...state,
|
...state,
|
||||||
updatingFirmware: false,
|
updatingFirmware: false,
|
||||||
firmwareUpdateFinished: true,
|
firmwareUpdateFinished: true,
|
||||||
|
firmwareUpdateFailed: true,
|
||||||
modules: data.modules,
|
modules: data.modules,
|
||||||
log: [...state.log, logEntry]
|
log: [...state.log, logEntry]
|
||||||
};
|
};
|
||||||
@@ -228,3 +231,4 @@ export const getBackupUserConfigurationState = (state: State): RestoreConfigurat
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
export const bootloaderActive = (state: State) => state.bootloaderActive;
|
export const bootloaderActive = (state: State) => state.bootloaderActive;
|
||||||
|
export const firmwareUpgradeFailed = (state: State) => state.firmwareUpdateFailed;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
Module,
|
Module,
|
||||||
NoneAction,
|
NoneAction,
|
||||||
PlayMacroAction,
|
PlayMacroAction,
|
||||||
|
SwitchKeymapAction,
|
||||||
SwitchLayerAction,
|
SwitchLayerAction,
|
||||||
UserConfiguration
|
UserConfiguration
|
||||||
} from 'uhk-common';
|
} from 'uhk-common';
|
||||||
@@ -143,14 +144,17 @@ export function reducer(state = initialState, action: Action & { payload?: any }
|
|||||||
const newKeyAction = keyActionRemap.action;
|
const newKeyAction = keyActionRemap.action;
|
||||||
const newKeymap: Keymap = action.payload.keymap;
|
const newKeymap: Keymap = action.payload.keymap;
|
||||||
const isSwitchLayerAction = newKeyAction instanceof SwitchLayerAction;
|
const isSwitchLayerAction = newKeyAction instanceof SwitchLayerAction;
|
||||||
|
const isSwitchKeymapAction = newKeyAction instanceof SwitchKeymapAction;
|
||||||
|
|
||||||
changedUserConfiguration.keymaps = state.keymaps.map(keymap => {
|
changedUserConfiguration.keymaps = state.keymaps.map(keymap => {
|
||||||
if (keyActionRemap.remapOnAllKeymap || keymap.abbreviation === newKeymap.abbreviation) {
|
// SwitchKeymapAction not allow to refer to itself
|
||||||
keymap = new Keymap(keymap);
|
if (isSwitchKeymapAction && keymap.abbreviation === newKeyAction.keymapAbbreviation) {
|
||||||
|
return keymap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyActionRemap.remapOnAllKeymap || keymap.abbreviation === newKeymap.abbreviation) {
|
||||||
keymap.layers = keymap.layers.map((layer, index) => {
|
keymap.layers = keymap.layers.map((layer, index) => {
|
||||||
if (keyActionRemap.remapOnAllLayer || index === layerIndex || isSwitchLayerAction) {
|
if (keyActionRemap.remapOnAllLayer || index === layerIndex || isSwitchLayerAction) {
|
||||||
layer = new Layer(layer);
|
|
||||||
const clonedAction = KeyActionHelper.createKeyAction(newKeyAction);
|
const clonedAction = KeyActionHelper.createKeyAction(newKeyAction);
|
||||||
|
|
||||||
// If the key action is a SwitchLayerAction then set the same SwitchLayerAction
|
// If the key action is a SwitchLayerAction then set the same SwitchLayerAction
|
||||||
|
|||||||
41
packages/uhk-web/src/assets/images/agent-logo-with-text.svg
Normal file
41
packages/uhk-web/src/assets/images/agent-logo-with-text.svg
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
version="1.1"
|
||||||
|
id="svg2"
|
||||||
|
viewBox="-5 -5 49.822906 12.159602"
|
||||||
|
height="18.239403"
|
||||||
|
width="74.73436">
|
||||||
|
<path
|
||||||
|
id="path4"
|
||||||
|
style="fill:#000000"
|
||||||
|
d="M -3,-5 C -4.108,-5 -5,-4.108 -5,-3 L -5,3 C -5,4.108 -4.108,5 -3,5 L 3,5 C 4.108,5 5,4.108 5,3 L 5,-3 C 5,-4.108 4.108,-5 3,-5 L -3,-5 Z M -4.0833333,-2.5 C -4.0364583,-2.5078125 -4,-2.5 -4,-2.5 L -0.99999998,-2.5 C -0.74999998,-2.5 -0.49999998,-2.25 -0.49999998,-2.25 -0.49999998,-2.25 -0.24999998,-2 2.4999999e-8,-2 0.25000003,-2 0.50000003,-2.25 0.50000003,-2.25 0.50000003,-2.25 0.75000003,-2.5 1,-2.5 L 4,-2.5 C 4.5,-2.5 4.5,-2 4.5,-2 L 4.5,-0.99999998 C 4.5,0.50000003 3.5,0.50000003 3.5,0.50000003 L 1,0.50000003 C 0.75000003,0.50000003 0.50000003,-0.24999998 0.50000003,-0.24999998 0.50000003,-0.24999998 0.25000003,-0.99999998 2.4999999e-8,-0.99999998 -0.24999998,-0.99999998 -0.49999998,-0.24999998 -0.49999998,-0.24999998 -0.49999998,-0.24999998 -0.74999998,0.50000003 -0.99999998,0.50000003 L -3.5,0.50000003 C -3.5,0.50000003 -4.5,0.50000003 -4.5,-0.99999998 L -4.5,-2 C -4.5,-2.375 -4.2239583,-2.4765625 -4.0833333,-2.5 Z" />
|
||||||
|
<g
|
||||||
|
id="text3338"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:13.33333302px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1">
|
||||||
|
<path
|
||||||
|
id="path3343"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.83333302px;font-family:Zekton;-inkscape-font-specification:'Zekton Bold'"
|
||||||
|
d="M 13.8736,1.4179352 16.1811,1.4179352 14.740267,-2.297898 11.8911,4.9929351 10.3636,4.9929351 14.155267,-4.5403979 15.3361,-4.5403979 19.149433,4.9929351 17.6111,4.9929351 16.744433,2.8262685 13.310267,2.8262685 13.8736,1.4179352 Z" />
|
||||||
|
<path
|
||||||
|
id="path3345"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.83333302px;font-family:Zekton;-inkscape-font-specification:'Zekton Bold'"
|
||||||
|
d="M 24.13886,5.7512684 Q 24.78886,5.7512684 24.78886,5.1012684 L 24.78886,0.22626858 Q 24.78886,-0.4237314 24.13886,-0.4237314 L 21.972193,-0.4237314 Q 21.322193,-0.4237314 21.322193,0.22626858 L 21.322193,2.9346018 Q 21.322193,3.5846018 21.972193,3.5846018 L 24.355527,3.5846018 24.355527,4.9929351 21.972193,4.9929351 Q 19.91386,4.9929351 19.91386,2.9346018 L 19.91386,0.22626858 Q 19.91386,-1.8320647 21.972193,-1.8320647 L 24.13886,-1.8320647 Q 26.197193,-1.8320647 26.197193,0.22626858 L 26.197193,5.1012684 Q 26.197193,7.1596017 24.13886,7.1596017 L 21.53886,7.1596017 21.53886,5.7512684 24.13886,5.7512684 Z" />
|
||||||
|
<path
|
||||||
|
id="path3347"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.83333302px;font-family:Zekton;-inkscape-font-specification:'Zekton Bold'"
|
||||||
|
d="M 33.018808,3.5846018 33.018808,4.9929351 29.335475,4.9929351 Q 27.277141,4.9929351 27.277141,2.9346018 L 27.277141,0.22626858 Q 27.277141,-1.8320647 29.335475,-1.8320647 L 31.502141,-1.8320647 Q 33.560474,-1.8320647 33.560474,0.22626858 L 33.560474,0.24793524 Q 33.560474,2.2846019 31.502141,2.2846019 L 29.118808,2.2846019 29.118808,0.87626856 31.502141,0.87626856 Q 32.152141,0.87626856 32.152141,0.24793524 L 32.152141,0.22626858 Q 32.152141,-0.4237314 31.502141,-0.4237314 L 29.335475,-0.4237314 Q 28.685475,-0.4237314 28.685475,0.22626858 L 28.685475,2.9346018 Q 28.685475,3.5846018 29.335475,3.5846018 L 33.018808,3.5846018 Z" />
|
||||||
|
<path
|
||||||
|
id="path3349"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.83333302px;font-family:Zekton;-inkscape-font-specification:'Zekton Bold'"
|
||||||
|
d="M 40.817961,4.9929351 39.409627,4.9929351 39.409627,0.22626858 Q 39.409627,-0.4237314 38.759627,-0.4237314 L 35.942961,-0.4237314 35.942961,4.9929351 34.534628,4.9929351 34.534628,-1.8320647 38.759627,-1.8320647 Q 40.817961,-1.8320647 40.817961,0.22626858 L 40.817961,4.9929351 Z" />
|
||||||
|
<path
|
||||||
|
id="path3351"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.83333302px;font-family:Zekton;-inkscape-font-specification:'Zekton Bold'"
|
||||||
|
d="M 41.789576,-1.8320647 42.331242,-1.8320647 42.331242,-4.5403979 43.663742,-4.5403979 43.663742,-1.8320647 44.822909,-1.8320647 44.822909,-0.4237314 43.663742,-0.4237314 43.663742,4.9929351 42.331242,4.9929351 42.331242,-0.4237314 41.789576,-0.4237314 41.789576,-1.8320647 Z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -8,6 +8,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.uhk-icon-agent-icon {
|
.uhk-icon-agent-icon {
|
||||||
@extend %svg-common;
|
background: url('assets/images/agent-icon.png') no-repeat;
|
||||||
background-position: 100% 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
BIN
packages/usb/blhost/linux/x86_64/blhost-old
Executable file
BIN
packages/usb/blhost/linux/x86_64/blhost-old
Executable file
Binary file not shown.
Reference in New Issue
Block a user