mirror of
https://github.com/Eugeny/tabby.git
synced 2025-10-03 21:44:54 +00:00
@typescript-eslint linter
This commit is contained in:
@@ -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[]>
|
||||
}
|
||||
|
@@ -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'
|
||||
|
||||
|
@@ -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[]
|
||||
}
|
||||
|
@@ -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 () {
|
||||
|
@@ -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
|
||||
|
@@ -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]
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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))
|
||||
}
|
||||
}
|
||||
|
@@ -85,7 +85,6 @@ export class TabHeaderComponent {
|
||||
contextMenu.popup({
|
||||
x: $event.pageX,
|
||||
y: $event.pageY,
|
||||
async: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
}
|
||||
|
@@ -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) { }
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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'
|
||||
|
@@ -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()
|
||||
|
@@ -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()
|
||||
}
|
||||
}
|
||||
|
@@ -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}`,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -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> {
|
||||
|
@@ -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,
|
||||
|
@@ -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))
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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' })
|
||||
|
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -54,5 +54,4 @@ export class TabRecoveryService {
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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,
|
||||
|
@@ -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)
|
||||
}
|
||||
})
|
||||
}),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user