moved menu zone handling into terminus-electron

This commit is contained in:
Eugene Pankov 2021-06-17 20:38:20 +02:00
parent cdf97f3b31
commit 96ce42461d
No known key found for this signature in database
GPG Key ID: 5896FCBBDD1CF4F4
5 changed files with 60 additions and 58 deletions

View File

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable, NgZone } from '@angular/core' import { Injectable } from '@angular/core'
import { Subscription } from 'rxjs' import { Subscription } from 'rxjs'
import { AppService } from './services/app.service' import { AppService } from './services/app.service'
import { BaseTabComponent } from './components/baseTab.component' import { BaseTabComponent } from './components/baseTab.component'
@ -15,7 +15,6 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
constructor ( constructor (
private app: AppService, private app: AppService,
private zone: NgZone,
) { ) {
super() super()
} }
@ -24,13 +23,13 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
let items: MenuItemOptions[] = [ let items: MenuItemOptions[] = [
{ {
label: 'Close', label: 'Close',
click: () => this.zone.run(() => { click: () => {
if (this.app.tabs.includes(tab)) { if (this.app.tabs.includes(tab)) {
this.app.closeTab(tab, true) this.app.closeTab(tab, true)
} else { } else {
tab.destroy() tab.destroy()
} }
}), },
}, },
] ]
if (tabHeader) { if (tabHeader) {
@ -38,27 +37,27 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
...items, ...items,
{ {
label: 'Close other tabs', label: 'Close other tabs',
click: () => this.zone.run(() => { click: () => {
for (const t of this.app.tabs.filter(x => x !== tab)) { for (const t of this.app.tabs.filter(x => x !== tab)) {
this.app.closeTab(t, true) this.app.closeTab(t, true)
} }
}), },
}, },
{ {
label: 'Close tabs to the right', label: 'Close tabs to the right',
click: () => this.zone.run(() => { click: () => {
for (const t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) { for (const t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) {
this.app.closeTab(t, true) this.app.closeTab(t, true)
} }
}), },
}, },
{ {
label: 'Close tabs to the left', label: 'Close tabs to the left',
click: () => this.zone.run(() => { click: () => {
for (const t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) { for (const t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) {
this.app.closeTab(t, true) this.app.closeTab(t, true)
} }
}), },
}, },
] ]
} else { } else {
@ -73,9 +72,9 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
l: 'Left', l: 'Left',
t: 'Up', t: 'Up',
}[dir], }[dir],
click: () => this.zone.run(() => { click: () => {
(tab.parent as SplitTabComponent).splitTab(tab, dir) (tab.parent as SplitTabComponent).splitTab(tab, dir)
}), },
})) as MenuItemOptions[], })) as MenuItemOptions[],
}) })
} }
@ -100,7 +99,6 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
weight = -1 weight = -1
constructor ( constructor (
private zone: NgZone,
private app: AppService, private app: AppService,
) { ) {
super() super()
@ -113,11 +111,11 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
...items, ...items,
{ {
label: 'Rename', label: 'Rename',
click: () => this.zone.run(() => tabHeader.showRenameTabModal()), click: () => tabHeader.showRenameTabModal(),
}, },
{ {
label: 'Duplicate', label: 'Duplicate',
click: () => this.zone.run(() => this.app.duplicateTab(tab)), click: () => this.app.duplicateTab(tab),
}, },
{ {
label: 'Color', label: 'Color',
@ -126,9 +124,9 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
label: color.name, label: color.name,
type: 'radio', type: 'radio',
checked: tab.color === color.value, checked: tab.color === color.value,
click: () => this.zone.run(() => { click: () => {
tab.color = color.value tab.color = color.value
}), },
})) as MenuItemOptions[], })) as MenuItemOptions[],
}, },
] ]
@ -142,7 +140,6 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
export class TaskCompletionContextMenu extends TabContextMenuItemProvider { export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
constructor ( constructor (
private app: AppService, private app: AppService,
private zone: NgZone,
) { ) {
super() super()
} }
@ -162,7 +159,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
label: 'Notify when done', label: 'Notify when done',
type: 'checkbox', type: 'checkbox',
checked: extTab.__completionNotificationEnabled, checked: extTab.__completionNotificationEnabled,
click: () => this.zone.run(() => { click: () => {
extTab.__completionNotificationEnabled = !extTab.__completionNotificationEnabled extTab.__completionNotificationEnabled = !extTab.__completionNotificationEnabled
if (extTab.__completionNotificationEnabled) { if (extTab.__completionNotificationEnabled) {
@ -177,14 +174,14 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
} else { } else {
this.app.stopObservingTabCompletion(tab) this.app.stopObservingTabCompletion(tab)
} }
}), },
}) })
} }
items.push({ items.push({
label: 'Notify on activity', label: 'Notify on activity',
type: 'checkbox', type: 'checkbox',
checked: !!extTab.__outputNotificationSubscription, checked: !!extTab.__outputNotificationSubscription,
click: () => this.zone.run(() => { click: () => {
if (extTab.__outputNotificationSubscription) { if (extTab.__outputNotificationSubscription) {
extTab.__outputNotificationSubscription.unsubscribe() extTab.__outputNotificationSubscription.unsubscribe()
extTab.__outputNotificationSubscription = null extTab.__outputNotificationSubscription = null
@ -201,7 +198,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
} }
}) })
} }
}), },
}) })
return items return items
} }

View File

@ -147,9 +147,19 @@ export class ElectronPlatformService extends PlatformService {
} }
popupContextMenu (menu: MenuItemOptions[], _event?: MouseEvent): void { popupContextMenu (menu: MenuItemOptions[], _event?: MouseEvent): void {
this.electron.Menu.buildFromTemplate(menu.map(item => ({ this.electron.Menu.buildFromTemplate(menu.map(item => this.rewrapMenuItemOptions(item))).popup({})
...item, }
}))).popup({})
rewrapMenuItemOptions (menu: MenuItemOptions): MenuItemOptions {
return {
...menu,
click: () => {
this.zone.run(() => {
menu.click?.()
})
},
submenu: menu.submenu ? menu.submenu.map(x => this.rewrapMenuItemOptions(x)) : undefined,
}
} }
async showMessageBox (options: MessageBoxOptions): Promise<MessageBoxResult> { async showMessageBox (options: MessageBoxOptions): Promise<MessageBoxResult> {

View File

@ -1,4 +1,4 @@
import { Injectable, NgZone } from '@angular/core' import { Injectable } from '@angular/core'
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, SplitTabComponent, NotificationsService, MenuItemOptions } from 'terminus-core' import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, SplitTabComponent, NotificationsService, MenuItemOptions } from 'terminus-core'
import { TerminalTabComponent } from './components/terminalTab.component' import { TerminalTabComponent } from './components/terminalTab.component'
import { UACService } from './services/uac.service' import { UACService } from './services/uac.service'
@ -9,7 +9,6 @@ import { TerminalService } from './services/terminal.service'
export class SaveAsProfileContextMenu extends TabContextMenuItemProvider { export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
constructor ( constructor (
private config: ConfigService, private config: ConfigService,
private zone: NgZone,
private notifications: NotificationsService, private notifications: NotificationsService,
) { ) {
super() super()
@ -22,7 +21,7 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
const items: MenuItemOptions[] = [ const items: MenuItemOptions[] = [
{ {
label: 'Save as profile', label: 'Save as profile',
click: () => this.zone.run(async () => { click: async () => {
const profile = { const profile = {
sessionOptions: { sessionOptions: {
...tab.sessionOptions, ...tab.sessionOptions,
@ -36,7 +35,7 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
] ]
this.config.save() this.config.save()
this.notifications.info('Saved') this.notifications.info('Saved')
}), },
}, },
] ]
@ -51,7 +50,6 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
constructor ( constructor (
public config: ConfigService, public config: ConfigService,
private zone: NgZone,
private terminalService: TerminalService, private terminalService: TerminalService,
private uac: UACService, private uac: UACService,
) { ) {
@ -64,21 +62,21 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
const items: MenuItemOptions[] = [ const items: MenuItemOptions[] = [
{ {
label: 'New terminal', label: 'New terminal',
click: () => this.zone.run(() => { click: () => {
this.terminalService.openTabWithOptions((tab as any).sessionOptions) this.terminalService.openTabWithOptions((tab as any).sessionOptions)
}), },
}, },
{ {
label: 'New with profile', label: 'New with profile',
submenu: profiles.map(profile => ({ submenu: profiles.map(profile => ({
label: profile.name, label: profile.name,
click: () => this.zone.run(async () => { click: async () => {
let workingDirectory = this.config.store.terminal.workingDirectory let workingDirectory = this.config.store.terminal.workingDirectory
if (this.config.store.terminal.alwaysUseWorkingDirectory !== true && tab instanceof TerminalTabComponent) { if (this.config.store.terminal.alwaysUseWorkingDirectory !== true && tab instanceof TerminalTabComponent) {
workingDirectory = await tab.session?.getWorkingDirectory() workingDirectory = await tab.session?.getWorkingDirectory()
} }
await this.terminalService.openTab(profile, workingDirectory) await this.terminalService.openTab(profile, workingDirectory)
}), },
})), })),
}, },
] ]
@ -88,12 +86,12 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
label: 'New admin tab', label: 'New admin tab',
submenu: profiles.map(profile => ({ submenu: profiles.map(profile => ({
label: profile.name, label: profile.name,
click: () => this.zone.run(async () => { click: () => {
this.terminalService.openTabWithOptions({ this.terminalService.openTabWithOptions({
...profile.sessionOptions, ...profile.sessionOptions,
runAsAdministrator: true, runAsAdministrator: true,
}) })
}), },
})), })),
}) })
} }
@ -101,28 +99,28 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
if (tab instanceof TerminalTabComponent && tabHeader && this.uac.isAvailable) { if (tab instanceof TerminalTabComponent && tabHeader && this.uac.isAvailable) {
items.push({ items.push({
label: 'Duplicate as administrator', label: 'Duplicate as administrator',
click: () => this.zone.run(async () => { click: () => {
this.terminalService.openTabWithOptions({ this.terminalService.openTabWithOptions({
...tab.sessionOptions, ...tab.sessionOptions,
runAsAdministrator: true, runAsAdministrator: true,
}) })
}), },
}) })
} }
if (tab instanceof TerminalTabComponent && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) { if (tab instanceof TerminalTabComponent && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
items.push({ items.push({
label: 'Focus all panes', label: 'Focus all panes',
click: () => this.zone.run(() => { click: () => {
tab.focusAllPanes() tab.focusAllPanes()
}), },
}) })
} }
if (tab instanceof TerminalTabComponent && tab.session?.supportsWorkingDirectory()) { if (tab instanceof TerminalTabComponent && tab.session?.supportsWorkingDirectory()) {
items.push({ items.push({
label: 'Copy current path', label: 'Copy current path',
click: () => this.zone.run(() => tab.copyCurrentPath()), click: () => tab.copyCurrentPath(),
}) })
} }

View File

@ -20,16 +20,18 @@ export class WinSCPContextMenu extends TabContextMenuItemProvider {
if (!(tab instanceof SSHTabComponent) || !tab.connection) { if (!(tab instanceof SSHTabComponent) || !tab.connection) {
return [] return []
} }
if (this.hostApp.platform !== Platform.Windows || !this.ssh.getWinSCPPath()) { const items = [{
return [] label: 'Open SFTP panel',
} click: () => tab.openSFTP(),
return [ }]
{ if (this.hostApp.platform === Platform.Windows && this.ssh.getWinSCPPath()) {
items.push({
label: 'Launch WinSCP', label: 'Launch WinSCP',
click: (): void => { click: (): void => {
this.ssh.launchWinSCP(tab.session!) this.ssh.launchWinSCP(tab.session!)
}, },
}, })
] }
return items
} }
} }

View File

@ -1,4 +1,4 @@
import { Injectable, NgZone, Optional, Inject } from '@angular/core' import { Injectable, Optional, Inject } from '@angular/core'
import { BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, NotificationsService, MenuItemOptions } from 'terminus-core' import { BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, NotificationsService, MenuItemOptions } from 'terminus-core'
import { BaseTerminalTabComponent } from './api/baseTerminalTab.component' import { BaseTerminalTabComponent } from './api/baseTerminalTab.component'
import { TerminalContextMenuItemProvider } from './api/contextMenuProvider' import { TerminalContextMenuItemProvider } from './api/contextMenuProvider'
@ -9,7 +9,6 @@ export class CopyPasteContextMenu extends TabContextMenuItemProvider {
weight = -10 weight = -10
constructor ( constructor (
private zone: NgZone,
private notifications: NotificationsService, private notifications: NotificationsService,
) { ) {
super() super()
@ -24,19 +23,15 @@ export class CopyPasteContextMenu extends TabContextMenuItemProvider {
{ {
label: 'Copy', label: 'Copy',
click: (): void => { click: (): void => {
this.zone.run(() => { setTimeout(() => {
setTimeout(() => { tab.frontend?.copySelection()
tab.frontend?.copySelection() this.notifications.notice('Copied')
this.notifications.notice('Copied')
})
}) })
}, },
}, },
{ {
label: 'Paste', label: 'Paste',
click: (): void => { click: () => tab.paste(),
this.zone.run(() => tab.paste())
},
}, },
] ]
} }