@typescript-eslint linter

This commit is contained in:
Eugene Pankov
2019-06-14 23:47:48 +02:00
parent a5ecdeb5ea
commit c008a3478e
96 changed files with 1334 additions and 810 deletions

View File

@@ -1,4 +1,4 @@
export interface IHotkeyDescription {
export interface HotkeyDescription {
id: string
name: string
}
@@ -8,7 +8,7 @@ export interface IHotkeyDescription {
* must also provide the `hotkeys.foo` config options with the default values
*/
export abstract class HotkeyProvider {
hotkeys: IHotkeyDescription[] = []
hotkeys: HotkeyDescription[] = []
abstract provide (): Promise<IHotkeyDescription[]>
abstract provide (): Promise<HotkeyDescription[]>
}

View File

@@ -1,9 +1,9 @@
export { BaseTabComponent, BaseTabProcess } from '../components/baseTab.component'
export { SplitTabComponent, SplitContainer } from '../components/splitTab.component'
export { TabRecoveryProvider, RecoveredTab } from './tabRecovery'
export { ToolbarButtonProvider, IToolbarButton } from './toolbarButtonProvider'
export { ToolbarButtonProvider, ToolbarButton } from './toolbarButtonProvider'
export { ConfigProvider } from './configProvider'
export { HotkeyProvider, IHotkeyDescription } from './hotkeyProvider'
export { HotkeyProvider, HotkeyDescription } from './hotkeyProvider'
export { Theme } from './theme'
export { TabContextMenuItemProvider } from './tabContextMenuProvider'

View File

@@ -3,7 +3,7 @@ import { SafeHtml } from '@angular/platform-browser'
/**
* See [[ToolbarButtonProvider]]
*/
export interface IToolbarButton {
export interface ToolbarButton {
/**
* Raw SVG icon code
*/
@@ -25,15 +25,15 @@ export interface IToolbarButton {
click?: () => void
submenu?: () => Promise<IToolbarButton[]>
submenu?: () => Promise<ToolbarButton[]>
/** @hidden */
submenuItems?: IToolbarButton[]
submenuItems?: ToolbarButton[]
}
/**
* Extend to add buttons to the toolbar
*/
export abstract class ToolbarButtonProvider {
abstract provide (): IToolbarButton[]
abstract provide (): ToolbarButton[]
}

View File

@@ -15,7 +15,7 @@ import { TouchbarService } from '../services/touchbar.service'
import { BaseTabComponent } from './baseTab.component'
import { SafeModeModalComponent } from './safeModeModal.component'
import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
import { AppService, ToolbarButton, ToolbarButtonProvider } from '../api'
/** @hidden */
@Component({
@@ -26,36 +26,36 @@ import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
trigger('animateTab', [
state('in', style({
'flex-basis': '200px',
'width': '200px',
width: '200px',
})),
transition(':enter', [
style({
'flex-basis': '1px',
'width': '1px',
width: '1px',
}),
animate('250ms ease-in-out', style({
'flex-basis': '200px',
'width': '200px',
}))
width: '200px',
})),
]),
transition(':leave', [
style({
'flex-basis': '200px',
'width': '200px',
width: '200px',
}),
animate('250ms ease-in-out', style({
'flex-basis': '1px',
'width': '1px',
}))
])
])
]
width: '1px',
})),
]),
]),
],
})
export class AppRootComponent {
Platform = Platform
@Input() ready = false
@Input() leftToolbarButtons: IToolbarButton[]
@Input() rightToolbarButtons: IToolbarButton[]
@Input() leftToolbarButtons: ToolbarButton[]
@Input() rightToolbarButtons: ToolbarButton[]
@HostBinding('class.platform-win32') platformClassWindows = process.platform === 'win32'
@HostBinding('class.platform-darwin') platformClassMacOS = process.platform === 'darwin'
@HostBinding('class.platform-linux') platformClassLinux = process.platform === 'linux'
@@ -89,7 +89,7 @@ export class AppRootComponent {
this.updateIcon = domSanitizer.bypassSecurityTrustHtml(require('../icons/gift.svg')),
this.hotkeys.matchedHotkey.subscribe((hotkey) => {
this.hotkeys.matchedHotkey.subscribe((hotkey: string) => {
if (hotkey.startsWith('tab-')) {
const index = parseInt(hotkey.split('-')[1])
if (index <= this.app.tabs.length) {
@@ -233,20 +233,20 @@ export class AppRootComponent {
})
}
async generateButtonSubmenu (button: IToolbarButton) {
async generateButtonSubmenu (button: ToolbarButton) {
if (button.submenu) {
button.submenuItems = await button.submenu()
}
}
private getToolbarButtons (aboveZero: boolean): IToolbarButton[] {
let buttons: IToolbarButton[] = []
private getToolbarButtons (aboveZero: boolean): ToolbarButton[] {
let buttons: ToolbarButton[] = []
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
buttons = buttons.concat(provider.provide())
})
return buttons
.filter((button) => (button.weight > 0) === aboveZero)
.sort((a: IToolbarButton, b: IToolbarButton) => (a.weight || 0) - (b.weight || 0))
.filter(button => button.weight > 0 === aboveZero)
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight || 0) - (b.weight || 0))
}
private updateVibrancy () {

View File

@@ -8,7 +8,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
styles: [require('./checkbox.component.scss')],
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: CheckboxComponent, multi: true },
]
],
})
export class CheckboxComponent implements ControlValueAccessor {
@HostBinding('class.active') @Input() model: boolean

View File

@@ -6,8 +6,8 @@ import { TabsService } from '../services/tabs.service'
import { HotkeysService } from '../services/hotkeys.service'
import { TabRecoveryService } from '../services/tabRecovery.service'
export declare type SplitOrientation = 'v' | 'h'
export declare type SplitDirection = 'r' | 't' | 'b' | 'l'
export type SplitOrientation = 'v' | 'h' // eslint-disable-line @typescript-eslint/no-type-alias
export type SplitDirection = 'r' | 't' | 'b' | 'l' // eslint-disable-line @typescript-eslint/no-type-alias
/**
* Describes a horizontal or vertical split row or column
@@ -198,33 +198,33 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
return
}
switch (hotkey) {
case 'split-right':
this.splitTab(this.focusedTab, 'r')
break
case 'split-bottom':
this.splitTab(this.focusedTab, 'b')
break
case 'split-top':
this.splitTab(this.focusedTab, 't')
break
case 'split-left':
this.splitTab(this.focusedTab, 'l')
break
case 'pane-nav-left':
this.navigate('l')
break
case 'pane-nav-right':
this.navigate('r')
break
case 'pane-nav-up':
this.navigate('t')
break
case 'pane-nav-down':
this.navigate('b')
break
case 'close-pane':
this.removeTab(this.focusedTab)
break
case 'split-right':
this.splitTab(this.focusedTab, 'r')
break
case 'split-bottom':
this.splitTab(this.focusedTab, 'b')
break
case 'split-top':
this.splitTab(this.focusedTab, 't')
break
case 'split-left':
this.splitTab(this.focusedTab, 'l')
break
case 'pane-nav-left':
this.navigate('l')
break
case 'pane-nav-right':
this.navigate('r')
break
case 'pane-nav-up':
this.navigate('t')
break
case 'pane-nav-down':
this.navigate('b')
break
case 'close-pane':
this.removeTab(this.focusedTab)
break
}
})
}
@@ -291,11 +291,11 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
let insertIndex = target.children.indexOf(relative)
if (
(target.orientation === 'v' && ['l', 'r'].includes(side)) ||
(target.orientation === 'h' && ['t', 'b'].includes(side))
target.orientation === 'v' && ['l', 'r'].includes(side) ||
target.orientation === 'h' && ['t', 'b'].includes(side)
) {
const newContainer = new SplitContainer()
newContainer.orientation = (target.orientation === 'v') ? 'h' : 'v'
newContainer.orientation = target.orientation === 'v' ? 'h' : 'v'
newContainer.children = [relative]
newContainer.ratios = [1]
target.children[insertIndex] = newContainer
@@ -306,7 +306,7 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
if (insertIndex === -1) {
insertIndex = 0
} else {
insertIndex += (side === 'l' || side === 't') ? 0 : 1
insertIndex += side === 'l' || side === 't' ? 0 : 1
}
for (let i = 0; i < target.children.length; i++) {
@@ -419,7 +419,7 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
}
private attachTabView (tab: BaseTabComponent) {
const ref = this.viewContainer.insert(tab.hostView) as EmbeddedViewRef<any>
const ref = this.viewContainer.insert(tab.hostView) as EmbeddedViewRef<any> // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
this.viewRefs.set(tab, ref)
ref.rootNodes[0].addEventListener('click', () => this.focus(tab))
@@ -448,7 +448,7 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
}
private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
const size = (root.orientation === 'v') ? h : w
const size = root.orientation === 'v' ? h : w
const sizes = root.ratios.map(x => x * size)
root.x = x
@@ -458,10 +458,10 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
let offset = 0
root.children.forEach((child, i) => {
const childX = (root.orientation === 'v') ? x : (x + offset)
const childY = (root.orientation === 'v') ? (y + offset) : y
const childW = (root.orientation === 'v') ? w : sizes[i]
const childH = (root.orientation === 'v') ? sizes[i] : h
const childX = root.orientation === 'v' ? x : x + offset
const childY = root.orientation === 'v' ? y + offset : y
const childW = root.orientation === 'v' ? w : sizes[i]
const childH = root.orientation === 'v' ? sizes[i] : h
if (child instanceof SplitContainer) {
this.layoutInternal(child, childX, childY, childW, childH)
} else {
@@ -472,7 +472,7 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
element.style.width = `${childW}%`
element.style.height = `${childH}%`
element.style.opacity = (child === this.focusedTab) ? 1 : 0.75
element.style.opacity = child === this.focusedTab ? 1 : 0.75
}
offset += sizes[i]

View File

@@ -23,13 +23,13 @@ export class SplitTabSpannerComponent {
constructor (private element: ElementRef) { }
ngAfterViewInit () {
this.element.nativeElement.addEventListener('mousedown', e => {
this.element.nativeElement.addEventListener('mousedown', (e: MouseEvent) => {
this.isActive = true
const start = this.isVertical ? e.pageY : e.pageX
let current = start
const oldPosition = this.isVertical ? this.element.nativeElement.offsetTop : this.element.nativeElement.offsetLeft
const oldPosition: number = this.isVertical ? this.element.nativeElement.offsetTop : this.element.nativeElement.offsetLeft
const dragHandler = e => {
const dragHandler = (e: MouseEvent) => {
current = this.isVertical ? e.pageY : e.pageX
const newPosition = oldPosition + (current - start)
if (this.isVertical) {

View File

@@ -1,7 +1,7 @@
import { Component, Inject } from '@angular/core'
import { ConfigService } from '../services/config.service'
import { HomeBaseService } from '../services/homeBase.service'
import { IToolbarButton, ToolbarButtonProvider } from '../api'
import { ToolbarButton, ToolbarButtonProvider } from '../api'
/** @hidden */
@Component({
@@ -19,11 +19,11 @@ export class StartPageComponent {
) {
}
getButtons (): IToolbarButton[] {
getButtons (): ToolbarButton[] {
return this.config.enabledServices(this.toolbarButtonProviders)
.map(provider => provider.provide())
.reduce((a, b) => a.concat(b))
.filter(x => !!x.click)
.sort((a: IToolbarButton, b: IToolbarButton) => (a.weight || 0) - (b.weight || 0))
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight || 0) - (b.weight || 0))
}
}

View File

@@ -85,7 +85,6 @@ export class TabHeaderComponent {
contextMenu.popup({
x: $event.pageX,
y: $event.pageY,
async: true,
})
}
}

View File

@@ -6,4 +6,4 @@ import { Component } from '@angular/core'
template: require('./titleBar.component.pug'),
styles: [require('./titleBar.component.scss')],
})
export class TitleBarComponent { }
export class TitleBarComponent { } // eslint-disable-line @typescript-eslint/no-extraneous-class

View File

@@ -17,7 +17,7 @@ import { CheckboxComponent } from './checkbox.component'
styles: [require('./toggle.component.scss')],
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: ToggleComponent, multi: true },
]
],
})
export class ToggleComponent extends CheckboxComponent {
}

View File

@@ -2,7 +2,7 @@ import { Directive, AfterViewInit, ElementRef } from '@angular/core'
/** @hidden */
@Directive({
selector: '[autofocus]'
selector: '[autofocus]',
})
export class AutofocusDirective implements AfterViewInit {
constructor (private el: ElementRef) { }

View File

@@ -1,10 +1,10 @@
import { Injectable } from '@angular/core'
import { IHotkeyDescription, HotkeyProvider } from './api/hotkeyProvider'
import { HotkeyDescription, HotkeyProvider } from './api/hotkeyProvider'
/** @hidden */
@Injectable()
export class AppHotkeyProvider extends HotkeyProvider {
hotkeys: IHotkeyDescription[] = [
hotkeys: HotkeyDescription[] = [
{
id: 'new-window',
name: 'New window',
@@ -115,7 +115,7 @@ export class AppHotkeyProvider extends HotkeyProvider {
},
]
async provide (): Promise<IHotkeyDescription[]> {
async provide (): Promise<HotkeyDescription[]> {
return this.hotkeys
}
}

View File

@@ -39,6 +39,12 @@ import { TaskCompletionContextMenu, CommonOptionsContextMenu, CloseContextMenu }
import 'perfect-scrollbar/css/perfect-scrollbar.css'
import 'ng2-dnd/bundles/style.css'
// PerfectScrollbar fix
import { fromEvent } from 'rxjs/internal/observable/fromEvent'
import { merge } from 'rxjs/internal/observable/merge'
require('rxjs').fromEvent = fromEvent
require('rxjs').merge = merge
const PROVIDERS = [
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
{ provide: Theme, useClass: StandardTheme, multi: true },
@@ -49,7 +55,7 @@ const PROVIDERS = [
{ provide: TabContextMenuItemProvider, useClass: CloseContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: TaskCompletionContextMenu, multi: true },
{ provide: TabRecoveryProvider, useClass: SplitTabRecoveryProvider, multi: true },
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } }
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
]
/** @hidden */
@@ -88,9 +94,9 @@ const PROVIDERS = [
CheckboxComponent,
ToggleComponent,
AutofocusDirective,
]
],
})
export default class AppModule {
export default class AppModule { // eslint-disable-line @typescript-eslint/no-extraneous-class
constructor (app: AppService, config: ConfigService) {
app.ready$.subscribe(() => {
if (config.store.enableWelcomeTab) {
@@ -107,11 +113,9 @@ export default class AppModule {
}
}
// PerfectScrollbar fix
import { fromEvent } from 'rxjs/internal/observable/fromEvent'
import { merge } from 'rxjs/internal/observable/merge'
require('rxjs').fromEvent = fromEvent
require('rxjs').merge = merge
export { AppRootComponent as bootstrap }
export * from './api'
// Deprecations
export { ToolbarButton as IToolbarButton } from './api'
export { HotkeyDescription as IHotkeyDescription } from './api'

View File

@@ -21,7 +21,7 @@ class CompletionObserver {
}
async tick () {
if (!(await this.tab.getCurrentProcess())) {
if (!await this.tab.getCurrentProcess()) {
this.done.next(null)
this.stop()
}
@@ -81,7 +81,7 @@ export class AppService {
})
}
private addTabRaw (tab: BaseTabComponent) {
addTabRaw (tab: BaseTabComponent) {
this.tabs.push(tab)
this.selectTab(tab)
this.tabsChanged.next()

View File

@@ -14,7 +14,7 @@ function isStructuralMember (v) {
Object.keys(v).length > 0 && !v.__nonStructural
}
function isNonStructuralObjectMember (v) {
function isNonStructuralObjectMember (v): boolean {
return v instanceof Object && !(v instanceof Array) && v.__nonStructural
}
@@ -46,13 +46,13 @@ export class ConfigProxy {
get: () => this.getValue(key),
set: (value) => {
this.setValue(key, value)
}
},
}
)
}
}
this.getValue = (key: string) => {
this.getValue = (key: string) => { // eslint-disable-line @typescript-eslint/unbound-method
if (real[key] !== undefined) {
return real[key]
} else {
@@ -66,13 +66,13 @@ export class ConfigProxy {
}
}
this.setValue = (key: string, value: any) => {
this.setValue = (key: string, value: any) => { // eslint-disable-line @typescript-eslint/unbound-method
real[key] = value
}
}
getValue (key: string): any { } // tslint:disable-line
setValue (key: string, value: any) { } // tslint:disable-line
getValue (_key: string): any { }
setValue (_key: string, _value: any) { }
}
@Injectable({ providedIn: 'root' })
@@ -160,10 +160,6 @@ export class ConfigService {
this.emitChange()
}
private emitChange (): void {
this.changed.next()
}
requestRestart (): void {
this.restartRequested = true
}
@@ -179,7 +175,7 @@ export class ConfigService {
this.servicesCache = {}
const ngModule = window['rootModule'].ngInjectorDef
for (const imp of ngModule.imports) {
const module = (imp['ngModule'] || imp)
const module = imp['ngModule'] || imp
if (module.ngInjectorDef && module.ngInjectorDef.providers) {
this.servicesCache[module['pluginName']] = module.ngInjectorDef.providers.map(provider => {
return provider['useClass'] || provider
@@ -196,4 +192,8 @@ export class ConfigService {
return true
})
}
private emitChange (): void {
this.changed.next()
}
}

View File

@@ -3,11 +3,6 @@ import { ConfigService } from '../services/config.service'
import { ElectronService } from '../services/electron.service'
import { HostAppService, Bounds } from '../services/hostApp.service'
export interface IScreen {
id: string
name: string
}
@Injectable({ providedIn: 'root' })
export class DockingService {
/** @hidden */
@@ -29,7 +24,7 @@ export class DockingService {
}
let display = this.electron.screen.getAllDisplays()
.filter((x) => x.id === this.config.store.appearance.dockScreen)[0]
.filter(x => x.id === this.config.store.appearance.dockScreen)[0]
if (!display) {
display = this.getCurrentScreen()
}
@@ -71,10 +66,10 @@ export class DockingService {
return this.electron.screen.getAllDisplays().map((display, index) => {
return {
id: display.id,
name: {
0: 'Primary display',
1: 'Secondary display',
}[index] || `Display ${index + 1}`
name: [
'Primary display',
'Secondary display',
][index] || `Display ${index + 1}`,
}
})
}

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'
import { TouchBar, BrowserWindow, Menu, MenuItem } from 'electron'
import { TouchBar, BrowserWindow, Menu, MenuItem, NativeImage } from 'electron'
export interface MessageBoxResponse {
response: number
@@ -8,16 +8,16 @@ export interface MessageBoxResponse {
@Injectable({ providedIn: 'root' })
export class ElectronService {
app: any
ipcRenderer: any
shell: any
dialog: any
clipboard: any
globalShortcut: any
nativeImage: any
screen: any
remote: any
autoUpdater: any
app: Electron.App
ipcRenderer: Electron.IpcRenderer
shell: Electron.Shell
dialog: Electron.Dialog
clipboard: Electron.Clipboard
globalShortcut: Electron.GlobalShortcut
nativeImage: typeof NativeImage
screen: Electron.Screen
remote: Electron.Remote
autoUpdater: Electron.AutoUpdater
TouchBar: typeof TouchBar
BrowserWindow: typeof BrowserWindow
Menu: typeof Menu
@@ -52,7 +52,7 @@ export class ElectronService {
}
}
showMessageBox (
async showMessageBox (
browserWindow: Electron.BrowserWindow,
options: Electron.MessageBoxOptions
): Promise<MessageBoxResponse> {

View File

@@ -2,8 +2,8 @@ import * as os from 'os'
import { Injectable } from '@angular/core'
import { ElectronService } from './electron.service'
import { ConfigService } from './config.service'
import mixpanel = require('mixpanel')
import uuidv4 = require('uuid/v4')
import * as mixpanel from 'mixpanel'
import * as uuidv4 from 'uuid/v4'
@Injectable({ providedIn: 'root' })
export class HomeBaseService {
@@ -53,7 +53,7 @@ export class HomeBaseService {
getAnalyticsProperties () {
return {
distinct_id: window.localStorage.analyticsUserID,
distinct_id: window.localStorage.analyticsUserID, // eslint-disable-line @typescript-eslint/camelcase
platform: process.platform,
os: os.release(),
version: this.appVersion,

View File

@@ -1,5 +1,5 @@
import * as path from 'path'
import shellEscape = require('shell-escape')
import * as shellEscape from 'shell-escape'
import { Observable, Subject } from 'rxjs'
import { Injectable, NgZone, EventEmitter } from '@angular/core'
import { ElectronService } from './electron.service'
@@ -97,7 +97,7 @@ export class HostAppService {
this.platform = {
win32: Platform.Windows,
darwin: Platform.macOS,
linux: Platform.Linux
linux: Platform.Linux,
}[process.platform]
this.windowId = parseInt(location.search.substring(1))

View File

@@ -1,5 +1,5 @@
import { Injectable, Inject, NgZone, EventEmitter } from '@angular/core'
import { IHotkeyDescription, HotkeyProvider } from '../api/hotkeyProvider'
import { HotkeyDescription, HotkeyProvider } from '../api/hotkeyProvider'
import { stringifyKeySequence } from './hotkeys.util'
import { ConfigService } from '../services/config.service'
import { ElectronService } from '../services/electron.service'
@@ -24,7 +24,7 @@ export class HotkeysService {
globalHotkey = new EventEmitter()
private currentKeystrokes: EventBufferEntry[] = []
private disabledLevel = 0
private hotkeyDescriptions: IHotkeyDescription[] = []
private hotkeyDescriptions: HotkeyDescription[] = []
/** @hidden */
constructor (
@@ -94,56 +94,7 @@ export class HotkeysService {
return stringifyKeySequence(this.currentKeystrokes.map(x => x.event))
}
private registerGlobalHotkey () {
this.electron.globalShortcut.unregisterAll()
let value = this.config.store.hotkeys['toggle-window'] || []
if (typeof value === 'string') {
value = [value]
}
value.forEach((item: string | string[]) => {
item = (typeof item === 'string') ? [item] : item
try {
let electronKeySpec = item[0]
electronKeySpec = electronKeySpec.replace('⌘', 'Command')
electronKeySpec = electronKeySpec.replace('⌥', 'Alt')
electronKeySpec = electronKeySpec.replace(/-/g, '+')
this.electron.globalShortcut.register(electronKeySpec, () => {
this.globalHotkey.emit()
})
} catch (err) {
console.error('Could not register the global hotkey:', err)
}
})
}
private getHotkeysConfig () {
return this.getHotkeysConfigRecursive(this.config.store.hotkeys)
}
private getHotkeysConfigRecursive (branch: any) {
const keys = {}
for (const key in branch) {
let value = branch[key]
if (value instanceof Object && !(value instanceof Array)) {
const subkeys = this.getHotkeysConfigRecursive(value)
for (const subkey in subkeys) {
keys[key + '.' + subkey] = subkeys[subkey]
}
} else {
if (typeof value === 'string') {
value = [value]
}
if (value) {
value = value.map((item: string | string[]) => (typeof item === 'string') ? [item] : item)
keys[key] = value
}
}
}
return keys
}
private getCurrentFullyMatchedHotkey (): string {
getCurrentFullyMatchedHotkey (): string {
const currentStrokes = this.getCurrentKeystrokes()
const config = this.getHotkeysConfig()
for (const id in config) {
@@ -178,7 +129,7 @@ export class HotkeysService {
result.push({
matchedLength: matchLength,
id,
strokes: sequence
strokes: sequence,
})
break
}
@@ -188,7 +139,7 @@ export class HotkeysService {
return result
}
getHotkeyDescription (id: string): IHotkeyDescription {
getHotkeyDescription (id: string): HotkeyDescription {
return this.hotkeyDescriptions.filter((x) => x.id === id)[0]
}
@@ -204,7 +155,7 @@ export class HotkeysService {
return this.disabledLevel === 0
}
async getHotkeyDescriptions (): Promise<IHotkeyDescription[]> {
async getHotkeyDescriptions (): Promise<HotkeyDescription[]> {
return (
await Promise.all(
this.config.enabledServices(this.hotkeyProviders)
@@ -212,4 +163,53 @@ export class HotkeysService {
)
).reduce((a, b) => a.concat(b))
}
private registerGlobalHotkey () {
this.electron.globalShortcut.unregisterAll()
let value = this.config.store.hotkeys['toggle-window'] || []
if (typeof value === 'string') {
value = [value]
}
value.forEach((item: string | string[]) => {
item = typeof item === 'string' ? [item] : item
try {
let electronKeySpec = item[0]
electronKeySpec = electronKeySpec.replace('⌘', 'Command')
electronKeySpec = electronKeySpec.replace('⌥', 'Alt')
electronKeySpec = electronKeySpec.replace(/-/g, '+')
this.electron.globalShortcut.register(electronKeySpec, () => {
this.globalHotkey.emit()
})
} catch (err) {
console.error('Could not register the global hotkey:', err)
}
})
}
private getHotkeysConfig () {
return this.getHotkeysConfigRecursive(this.config.store.hotkeys)
}
private getHotkeysConfigRecursive (branch: any) {
const keys = {}
for (const key in branch) {
let value = branch[key]
if (value instanceof Object && !(value instanceof Array)) {
const subkeys = this.getHotkeysConfigRecursive(value)
for (const subkey in subkeys) {
keys[key + '.' + subkey] = subkeys[subkey]
}
} else {
if (typeof value === 'string') {
value = [value]
}
if (value) {
value = value.map((item: string | string[]) => typeof item === 'string' ? [item] : item)
keys[key] = value
}
}
}
return keys
}
}

View File

@@ -20,9 +20,9 @@ const initializeWinston = (electron: ElectronService) => {
handleExceptions: false,
maxsize: 5242880,
maxFiles: 5,
})
}),
],
exitOnError: false
exitOnError: false,
})
}
@@ -32,18 +32,32 @@ export class Logger {
private name: string,
) {}
debug (...args: any[]) {
this.doLog('debug', ...args)
}
info (...args: any[]) {
this.doLog('info', ...args)
}
warn (...args: any[]) {
this.doLog('warn', ...args)
}
error (...args: any[]) {
this.doLog('error', ...args)
}
log (...args: any[]) {
this.doLog('log', ...args)
}
private doLog (level: string, ...args: any[]) {
console[level](`%c[${this.name}]`, 'color: #aaa', ...args)
if (this.winstonLogger) {
this.winstonLogger[level](...args)
}
}
debug (...args: any[]) { this.doLog('debug', ...args) }
info (...args: any[]) { this.doLog('info', ...args) }
warn (...args: any[]) { this.doLog('warn', ...args) }
error (...args: any[]) { this.doLog('error', ...args) }
log (...args: any[]) { this.doLog('log', ...args) }
}
@Injectable({ providedIn: 'root' })

View File

@@ -5,9 +5,11 @@ import { Injectable } from '@angular/core'
import { ElectronService } from './electron.service'
import { HostAppService, Platform } from './hostApp.service'
/* eslint-disable block-scoped-var */
try {
var wnr = require('windows-native-registry') // tslint:disable-line
} catch (_) { } // tslint:disable-line
var wnr = require('windows-native-registry') // eslint-disable-line @typescript-eslint/no-var-requires
} catch (_) { }
@Injectable({ providedIn: 'root' })
export class ShellIntegrationService {
@@ -17,11 +19,11 @@ export class ShellIntegrationService {
private registryKeys = [
{
path: 'Software\\Classes\\Directory\\Background\\shell\\Open Terminus here',
command: 'open "%V"'
command: 'open "%V"',
},
{
path: 'Software\\Classes\\*\\shell\\Paste path into Terminus',
command: 'paste "%V"'
command: 'paste "%V"',
},
]
constructor (
@@ -40,15 +42,6 @@ export class ShellIntegrationService {
this.updatePaths()
}
private async updatePaths (): Promise<void> {
// Update paths in case of an update
if (this.hostApp.platform === Platform.Windows) {
if (await this.isInstalled()) {
await this.install()
}
}
}
async isInstalled (): Promise<boolean> {
if (this.hostApp.platform === Platform.macOS) {
return fs.exists(path.join(this.automatorWorkflowsDestination, this.automatorWorkflows[0]))
@@ -59,7 +52,7 @@ export class ShellIntegrationService {
}
async install () {
const exe = process.env.PORTABLE_EXECUTABLE_FILE || this.electron.app.getPath('exe')
const exe: string = process.env.PORTABLE_EXECUTABLE_FILE || this.electron.app.getPath('exe')
if (this.hostApp.platform === Platform.macOS) {
for (const wf of this.automatorWorkflows) {
await exec(`cp -r "${this.automatorWorkflowsLocation}/${wf}" "${this.automatorWorkflowsDestination}"`)
@@ -85,4 +78,13 @@ export class ShellIntegrationService {
}
}
}
private async updatePaths (): Promise<void> {
// Update paths in case of an update
if (this.hostApp.platform === Platform.Windows) {
if (await this.isInstalled()) {
await this.install()
}
}
}
}

View File

@@ -54,5 +54,4 @@ export class TabRecoveryService {
}
return []
}
}

View File

@@ -2,7 +2,8 @@ import { Injectable, ComponentFactoryResolver, Injector } from '@angular/core'
import { BaseTabComponent } from '../components/baseTab.component'
import { TabRecoveryService } from './tabRecovery.service'
export declare type TabComponentType = new (...args: any[]) => BaseTabComponent
// eslint-disable-next-line @typescript-eslint/no-type-alias
export type TabComponentType = new (...args: any[]) => BaseTabComponent
@Injectable({ providedIn: 'root' })
export class TabsService {

View File

@@ -4,7 +4,7 @@ import { AppService } from './app.service'
import { ConfigService } from './config.service'
import { ElectronService } from './electron.service'
import { HostAppService, Platform } from './hostApp.service'
import { IToolbarButton, ToolbarButtonProvider } from '../api'
import { ToolbarButton, ToolbarButtonProvider } from '../api'
/** @hidden */
@Injectable({ providedIn: 'root' })
@@ -61,7 +61,7 @@ export class TouchbarService {
return
}
let buttons: IToolbarButton[] = []
let buttons: ToolbarButton[] = []
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
buttons = buttons.concat(provider.provide())
})
@@ -76,7 +76,7 @@ export class TouchbarService {
selectedIndex: this.app.tabs.indexOf(this.app.activeTab),
change: (selectedIndex) => this.zone.run(() => {
this.app.selectTab(this.app.tabs[selectedIndex])
})
}),
})
this.buttonsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
@@ -84,7 +84,7 @@ export class TouchbarService {
mode: 'buttons',
change: (selectedIndex) => this.zone.run(() => {
buttons[selectedIndex].click()
})
}),
})
const touchBar = new this.electron.TouchBar({
@@ -93,12 +93,12 @@ export class TouchbarService {
new this.electron.TouchBar.TouchBarSpacer({ size: 'flexible' }),
new this.electron.TouchBar.TouchBarSpacer({ size: 'small' }),
this.buttonsSegmentedControl,
]
],
})
this.hostApp.setTouchBar(touchBar)
}
private getButton (button: IToolbarButton): Electron.SegmentedControlSegment {
private getButton (button: ToolbarButton): Electron.SegmentedControlSegment {
return {
label: button.touchBarNSImage ? null : this.shortenTitle(button.touchBarTitle || button.title),
icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : null,

View File

@@ -22,7 +22,7 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
label: 'Close',
click: () => this.zone.run(() => {
this.app.closeTab(tab, true)
})
}),
},
{
label: 'Close other tabs',
@@ -30,7 +30,7 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
for (const t of this.app.tabs.filter(x => x !== tab)) {
this.app.closeTab(t, true)
}
})
}),
},
{
label: 'Close tabs to the right',
@@ -38,7 +38,7 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
for (const t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) {
this.app.closeTab(t, true)
}
})
}),
},
{
label: 'Close tabs to the left',
@@ -46,7 +46,7 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
for (const t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) {
this.app.closeTab(t, true)
}
})
}),
},
]
}
@@ -78,11 +78,11 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
return [
{
label: 'Rename',
click: () => this.zone.run(() => tabHeader.showRenameTabModal())
click: () => this.zone.run(() => tabHeader.showRenameTabModal()),
},
{
label: 'Duplicate',
click: () => this.zone.run(() => this.app.duplicateTab(tab))
click: () => this.zone.run(() => this.app.duplicateTab(tab)),
},
{
label: 'Color',
@@ -95,7 +95,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
tab.color = color.value
}),
})) as Electron.MenuItemConstructorOptions[],
}
},
]
}
}
@@ -138,7 +138,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
} else {
this.app.stopObservingTabCompletion(tab)
}
})
}),
},
]
}