Files
tabby/terminus-core/src/components/appRoot.component.ts
T

199 lines
6.5 KiB
TypeScript

/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Component, Inject, Input, HostListener, HostBinding } from '@angular/core'
import { trigger, style, animate, transition, state } from '@angular/animations'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { HostAppService, Platform } from '../services/hostApp.service'
import { HotkeysService } from '../services/hotkeys.service'
import { Logger, LogService } from '../services/log.service'
import { ConfigService } from '../services/config.service'
import { ThemesService } from '../services/themes.service'
import { UpdaterService } from '../services/updater.service'
import { BaseTabComponent } from './baseTab.component'
import { SafeModeModalComponent } from './safeModeModal.component'
import { AppService, PlatformService, ToolbarButton, ToolbarButtonProvider } from '../api'
/** @hidden */
@Component({
selector: 'app-root',
template: require('./appRoot.component.pug'),
styles: [require('./appRoot.component.scss')],
animations: [
trigger('animateTab', [
state('in', style({
'flex-basis': '200px',
width: '200px',
})),
transition(':enter', [
style({
'flex-basis': '1px',
width: '1px',
}),
animate('250ms ease-in-out', style({
'flex-basis': '200px',
width: '200px',
})),
]),
transition(':leave', [
style({
'flex-basis': '200px',
width: '200px',
}),
animate('250ms ease-in-out', style({
'flex-basis': '1px',
width: '1px',
})),
]),
]),
],
})
export class AppRootComponent {
Platform = Platform
@Input() ready = false
@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'
@HostBinding('class.no-tabs') noTabs = true
tabsDragging = false
unsortedTabs: BaseTabComponent[] = []
updateIcon: string
updatesAvailable = false
private logger: Logger
private constructor (
private hotkeys: HotkeysService,
private updater: UpdaterService,
public hostApp: HostAppService,
public config: ConfigService,
public app: AppService,
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
platform: PlatformService,
log: LogService,
ngbModal: NgbModal,
_themes: ThemesService,
) {
this.logger = log.create('main')
this.logger.info('v', platform.getAppVersion())
this.leftToolbarButtons = this.getToolbarButtons(false)
this.rightToolbarButtons = this.getToolbarButtons(true)
this.updateIcon = require('../icons/gift.svg')
this.hotkeys.matchedHotkey.subscribe((hotkey: string) => {
if (hotkey.startsWith('tab-')) {
const index = parseInt(hotkey.split('-')[1])
if (index <= this.app.tabs.length) {
this.app.selectTab(this.app.tabs[index - 1])
}
}
if (this.app.activeTab) {
if (hotkey === 'close-tab') {
this.app.closeTab(this.app.activeTab, true)
}
if (hotkey === 'toggle-last-tab') {
this.app.toggleLastTab()
}
if (hotkey === 'next-tab') {
this.app.nextTab()
}
if (hotkey === 'previous-tab') {
this.app.previousTab()
}
if (hotkey === 'move-tab-left') {
this.app.moveSelectedTabLeft()
}
if (hotkey === 'move-tab-right') {
this.app.moveSelectedTabRight()
}
if (hotkey === 'reopen-tab') {
this.app.reopenLastTab()
}
}
if (hotkey === 'toggle-fullscreen') {
this.hostApp.toggleFullscreen()
}
})
this.hostApp.windowCloseRequest$.subscribe(async () => {
this.app.closeWindow()
})
if (window['safeModeReason']) {
ngbModal.open(SafeModeModalComponent)
}
setInterval(() => {
if (this.config.store.enableAutomaticUpdates) {
this.updater.check().then(available => {
this.updatesAvailable = available
})
}
}, 3600 * 12 * 1000)
this.app.tabOpened$.subscribe(tab => {
this.unsortedTabs.push(tab)
this.noTabs = false
})
this.app.tabClosed$.subscribe(tab => {
this.unsortedTabs = this.unsortedTabs.filter(x => x !== tab)
this.noTabs = app.tabs.length === 0
})
}
async ngOnInit () {
this.ready = true
this.app.emitReady()
}
@HostListener('dragover')
onDragOver () {
return false
}
@HostListener('drop')
onDrop () {
return false
}
hasVerticalTabs () {
return this.config.store.appearance.tabsLocation === 'left' || this.config.store.appearance.tabsLocation === 'right'
}
onTabDragStart () {
this.tabsDragging = true
}
onTabDragEnd () {
setTimeout(() => {
this.tabsDragging = false
this.app.emitTabsChanged()
})
}
async generateButtonSubmenu (button: ToolbarButton) {
if (button.submenu) {
button.submenuItems = await button.submenu()
}
}
hasIcons (submenuItems: ToolbarButton[]): boolean {
return submenuItems.some(x => !!x.icon)
}
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) > 0 === aboveZero)
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight ?? 0) - (b.weight ?? 0))
}
}