mirror of
https://github.com/Eugeny/tabby.git
synced 2025-07-20 02:18:01 +00:00
more platform changes
This commit is contained in:
3
.github/workflows/linux.yml
vendored
3
.github/workflows/linux.yml
vendored
@@ -28,6 +28,9 @@ jobs:
|
|||||||
cd app
|
cd app
|
||||||
../node_modules/.bin/patch-package
|
../node_modules/.bin/patch-package
|
||||||
cd ..
|
cd ..
|
||||||
|
cd terminus-terminal
|
||||||
|
../node_modules/.bin/patch-package
|
||||||
|
cd ..
|
||||||
|
|
||||||
- name: Build native deps
|
- name: Build native deps
|
||||||
run: scripts/build-native.js
|
run: scripts/build-native.js
|
||||||
|
3
.github/workflows/macos.yml
vendored
3
.github/workflows/macos.yml
vendored
@@ -32,6 +32,9 @@ jobs:
|
|||||||
cd app
|
cd app
|
||||||
../node_modules/.bin/patch-package
|
../node_modules/.bin/patch-package
|
||||||
cd ..
|
cd ..
|
||||||
|
cd terminus-terminal
|
||||||
|
../node_modules/.bin/patch-package
|
||||||
|
cd ..
|
||||||
|
|
||||||
- name: Build native deps
|
- name: Build native deps
|
||||||
run: scripts/build-native.js
|
run: scripts/build-native.js
|
||||||
|
5
.github/workflows/windows.yml
vendored
5
.github/workflows/windows.yml
vendored
@@ -21,6 +21,11 @@ jobs:
|
|||||||
npm i -g yarn@1.19.1
|
npm i -g yarn@1.19.1
|
||||||
yarn
|
yarn
|
||||||
node scripts/build-native.js
|
node scripts/build-native.js
|
||||||
|
|
||||||
|
cd terminus-terminal
|
||||||
|
../node_modules/.bin/patch-package
|
||||||
|
cd ..
|
||||||
|
|
||||||
yarn run build
|
yarn run build
|
||||||
node scripts/prepackage-plugins.js
|
node scripts/prepackage-plugins.js
|
||||||
|
|
||||||
|
@@ -309,20 +309,6 @@ export class Window {
|
|||||||
this.window.focus()
|
this.window.focus()
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('window-maximize', event => {
|
|
||||||
if (!this.window || event.sender !== this.window.webContents) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.window.maximize()
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('window-unmaximize', event => {
|
|
||||||
if (!this.window || event.sender !== this.window.webContents) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.window.unmaximize()
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('window-toggle-maximize', event => {
|
ipcMain.on('window-toggle-maximize', event => {
|
||||||
if (!this.window || event.sender !== this.window.webContents) {
|
if (!this.window || event.sender !== this.window.webContents) {
|
||||||
return
|
return
|
||||||
|
12
terminus-core/src/api/hostWindow.ts
Normal file
12
terminus-core/src/api/hostWindow.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Observable } from 'rxjs'
|
||||||
|
|
||||||
|
export abstract class HostWindowService {
|
||||||
|
abstract readonly closeRequest$: Observable<void>
|
||||||
|
abstract readonly isFullscreen: boolean
|
||||||
|
abstract reload (): void
|
||||||
|
abstract setTitle (title?: string): void
|
||||||
|
abstract toggleFullscreen (): void
|
||||||
|
abstract minimize (): void
|
||||||
|
abstract toggleMaximize (): void
|
||||||
|
abstract close (): void
|
||||||
|
}
|
@@ -10,9 +10,10 @@ export { Theme } from './theme'
|
|||||||
export { TabContextMenuItemProvider } from './tabContextMenuProvider'
|
export { TabContextMenuItemProvider } from './tabContextMenuProvider'
|
||||||
export { SelectorOption } from './selector'
|
export { SelectorOption } from './selector'
|
||||||
export { CLIHandler, CLIEvent } from './cli'
|
export { CLIHandler, CLIEvent } from './cli'
|
||||||
export { PlatformService, ClipboardContent } from './platform'
|
export { PlatformService, ClipboardContent, MessageBoxResult, MessageBoxOptions } from './platform'
|
||||||
export { MenuItemOptions } from './menu'
|
export { MenuItemOptions } from './menu'
|
||||||
export { BootstrapData, BOOTSTRAP_DATA } from './mainProcess'
|
export { BootstrapData, BOOTSTRAP_DATA } from './mainProcess'
|
||||||
|
export { HostWindowService } from './hostWindow'
|
||||||
|
|
||||||
export { AppService } from '../services/app.service'
|
export { AppService } from '../services/app.service'
|
||||||
export { ConfigService } from '../services/config.service'
|
export { ConfigService } from '../services/config.service'
|
||||||
|
@@ -6,9 +6,22 @@ export interface ClipboardContent {
|
|||||||
html?: string
|
html?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MessageBoxOptions {
|
||||||
|
type: 'warning'|'error'
|
||||||
|
message: string
|
||||||
|
detail?: string
|
||||||
|
buttons: string[]
|
||||||
|
defaultId?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MessageBoxResult {
|
||||||
|
response: number
|
||||||
|
}
|
||||||
|
|
||||||
export abstract class PlatformService {
|
export abstract class PlatformService {
|
||||||
supportsWindowControls = false
|
supportsWindowControls = false
|
||||||
|
|
||||||
|
abstract readClipboard (): string
|
||||||
abstract setClipboard (content: ClipboardContent): void
|
abstract setClipboard (content: ClipboardContent): void
|
||||||
abstract loadConfig (): Promise<string>
|
abstract loadConfig (): Promise<string>
|
||||||
abstract saveConfig (content: string): Promise<void>
|
abstract saveConfig (content: string): Promise<void>
|
||||||
@@ -66,4 +79,5 @@ export abstract class PlatformService {
|
|||||||
abstract openExternal (url: string): void
|
abstract openExternal (url: string): void
|
||||||
abstract listFonts (): Promise<string[]>
|
abstract listFonts (): Promise<string[]>
|
||||||
abstract popupContextMenu (menu: MenuItemOptions[], event?: MouseEvent): void
|
abstract popupContextMenu (menu: MenuItemOptions[], event?: MouseEvent): void
|
||||||
|
abstract showMessageBox (options: MessageBoxOptions): Promise<MessageBoxResult>
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,16 @@
|
|||||||
title-bar(
|
title-bar(
|
||||||
*ngIf='!hostApp.isFullScreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
|
*ngIf='ready && !hostWindow.isFullScreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
|
||||||
[class.inset]='hostApp.platform == Platform.macOS && !hostApp.isFullScreen'
|
[class.inset]='hostApp.platform == Platform.macOS && !hostWindow.isFullScreen'
|
||||||
)
|
)
|
||||||
|
|
||||||
.content(
|
.content(
|
||||||
|
*ngIf='ready',
|
||||||
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left"',
|
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left"',
|
||||||
[class.tabs-on-side]='hasVerticalTabs()',
|
[class.tabs-on-side]='hasVerticalTabs()',
|
||||||
)
|
)
|
||||||
.tab-bar
|
.tab-bar
|
||||||
.inset.background(*ngIf='hostApp.platform == Platform.macOS \
|
.inset.background(*ngIf='hostApp.platform == Platform.macOS \
|
||||||
&& !hostApp.isFullScreen \
|
&& !hostWindow.isFullScreen \
|
||||||
&& config.store.appearance.frame == "thin" \
|
&& config.store.appearance.frame == "thin" \
|
||||||
&& (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")')
|
&& (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")')
|
||||||
.tabs(
|
.tabs(
|
||||||
|
@@ -12,7 +12,7 @@ import { UpdaterService } from '../services/updater.service'
|
|||||||
|
|
||||||
import { BaseTabComponent } from './baseTab.component'
|
import { BaseTabComponent } from './baseTab.component'
|
||||||
import { SafeModeModalComponent } from './safeModeModal.component'
|
import { SafeModeModalComponent } from './safeModeModal.component'
|
||||||
import { AppService, PlatformService, ToolbarButton, ToolbarButtonProvider } from '../api'
|
import { AppService, HostWindowService, PlatformService, ToolbarButton, ToolbarButtonProvider } from '../api'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
@@ -66,6 +66,7 @@ export class AppRootComponent {
|
|||||||
private constructor (
|
private constructor (
|
||||||
private hotkeys: HotkeysService,
|
private hotkeys: HotkeysService,
|
||||||
private updater: UpdaterService,
|
private updater: UpdaterService,
|
||||||
|
public hostWindow: HostWindowService,
|
||||||
public hostApp: HostAppService,
|
public hostApp: HostAppService,
|
||||||
public config: ConfigService,
|
public config: ConfigService,
|
||||||
public app: AppService,
|
public app: AppService,
|
||||||
@@ -78,9 +79,6 @@ export class AppRootComponent {
|
|||||||
this.logger = log.create('main')
|
this.logger = log.create('main')
|
||||||
this.logger.info('v', platform.getAppVersion())
|
this.logger.info('v', platform.getAppVersion())
|
||||||
|
|
||||||
this.leftToolbarButtons = this.getToolbarButtons(false)
|
|
||||||
this.rightToolbarButtons = this.getToolbarButtons(true)
|
|
||||||
|
|
||||||
this.updateIcon = require('../icons/gift.svg')
|
this.updateIcon = require('../icons/gift.svg')
|
||||||
|
|
||||||
this.hotkeys.matchedHotkey.subscribe((hotkey: string) => {
|
this.hotkeys.matchedHotkey.subscribe((hotkey: string) => {
|
||||||
@@ -114,7 +112,7 @@ export class AppRootComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hotkey === 'toggle-fullscreen') {
|
if (hotkey === 'toggle-fullscreen') {
|
||||||
this.hostApp.toggleFullscreen()
|
hostWindow.toggleFullscreen()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -126,14 +124,6 @@ export class AppRootComponent {
|
|||||||
ngbModal.open(SafeModeModalComponent)
|
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.app.tabOpened$.subscribe(tab => {
|
||||||
this.unsortedTabs.push(tab)
|
this.unsortedTabs.push(tab)
|
||||||
this.noTabs = false
|
this.noTabs = false
|
||||||
@@ -143,12 +133,26 @@ export class AppRootComponent {
|
|||||||
this.unsortedTabs = this.unsortedTabs.filter(x => x !== tab)
|
this.unsortedTabs = this.unsortedTabs.filter(x => x !== tab)
|
||||||
this.noTabs = app.tabs.length === 0
|
this.noTabs = app.tabs.length === 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
config.ready$.toPromise().then(() => {
|
||||||
|
this.leftToolbarButtons = this.getToolbarButtons(false)
|
||||||
|
this.rightToolbarButtons = this.getToolbarButtons(true)
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
if (this.config.store.enableAutomaticUpdates) {
|
||||||
|
this.updater.check().then(available => {
|
||||||
|
this.updatesAvailable = available
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 3600 * 12 * 1000)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit () {
|
async ngOnInit () {
|
||||||
this.ready = true
|
this.config.ready$.toPromise().then(() => {
|
||||||
|
this.ready = true
|
||||||
this.app.emitReady()
|
this.app.emitReady()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('dragover')
|
@HostListener('dragover')
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core'
|
||||||
import { BaseTabComponent } from './baseTab.component'
|
import { BaseTabComponent } from './baseTab.component'
|
||||||
import { ConfigService } from '../services/config.service'
|
import { ConfigService } from '../services/config.service'
|
||||||
import { HostAppService } from '../services/hostApp.service'
|
import { HostWindowService } from '../api/hostWindow'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
@@ -16,7 +16,7 @@ export class WelcomeTabComponent extends BaseTabComponent {
|
|||||||
enableGlobalHotkey = true
|
enableGlobalHotkey = true
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private hostApp: HostAppService,
|
private hostWindow: HostWindowService,
|
||||||
public config: ConfigService,
|
public config: ConfigService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
@@ -38,6 +38,6 @@ export class WelcomeTabComponent extends BaseTabComponent {
|
|||||||
this.config.store.hotkeys['toggle-window'] = []
|
this.config.store.hotkeys['toggle-window'] = []
|
||||||
}
|
}
|
||||||
this.config.save()
|
this.config.save()
|
||||||
this.hostApp.getWindow().reload()
|
this.hostWindow.reload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { NgModule, ModuleWithProviders, APP_INITIALIZER } from '@angular/core'
|
import { NgModule, ModuleWithProviders } from '@angular/core'
|
||||||
import { BrowserModule } from '@angular/platform-browser'
|
import { BrowserModule } from '@angular/platform-browser'
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
||||||
import { FormsModule } from '@angular/forms'
|
import { FormsModule } from '@angular/forms'
|
||||||
@@ -38,10 +38,6 @@ import { LastCLIHandler } from './cli'
|
|||||||
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
||||||
import 'ng2-dnd/bundles/style.css'
|
import 'ng2-dnd/bundles/style.css'
|
||||||
|
|
||||||
function initialize (config: ConfigService) {
|
|
||||||
return () => config.ready$.toPromise()
|
|
||||||
}
|
|
||||||
|
|
||||||
const PROVIDERS = [
|
const PROVIDERS = [
|
||||||
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
|
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
|
||||||
{ provide: Theme, useClass: StandardTheme, multi: true },
|
{ provide: Theme, useClass: StandardTheme, multi: true },
|
||||||
@@ -54,7 +50,6 @@ const PROVIDERS = [
|
|||||||
{ provide: TabRecoveryProvider, useClass: SplitTabRecoveryProvider, multi: true },
|
{ provide: TabRecoveryProvider, useClass: SplitTabRecoveryProvider, multi: true },
|
||||||
{ provide: CLIHandler, useClass: LastCLIHandler, multi: true },
|
{ provide: CLIHandler, useClass: LastCLIHandler, multi: true },
|
||||||
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
|
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
|
||||||
{ provide: APP_INITIALIZER, useFactory: initialize, deps: [ConfigService], multi: true },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
|
@@ -10,6 +10,7 @@ import { SelectorModalComponent } from '../components/selectorModal.component'
|
|||||||
import { SelectorOption } from '../api/selector'
|
import { SelectorOption } from '../api/selector'
|
||||||
import { RecoveryToken } from '../api/tabRecovery'
|
import { RecoveryToken } from '../api/tabRecovery'
|
||||||
import { BootstrapData, BOOTSTRAP_DATA } from '../api/mainProcess'
|
import { BootstrapData, BOOTSTRAP_DATA } from '../api/mainProcess'
|
||||||
|
import { HostWindowService } from '../api/hostWindow'
|
||||||
|
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './config.service'
|
||||||
import { HostAppService } from './hostApp.service'
|
import { HostAppService } from './hostApp.service'
|
||||||
@@ -73,6 +74,7 @@ export class AppService {
|
|||||||
private constructor (
|
private constructor (
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
|
private hostWindow: HostWindowService,
|
||||||
private tabRecovery: TabRecoveryService,
|
private tabRecovery: TabRecoveryService,
|
||||||
private tabsService: TabsService,
|
private tabsService: TabsService,
|
||||||
private ngbModal: NgbModal,
|
private ngbModal: NgbModal,
|
||||||
@@ -127,7 +129,7 @@ export class AppService {
|
|||||||
|
|
||||||
tab.titleChange$.subscribe(title => {
|
tab.titleChange$.subscribe(title => {
|
||||||
if (tab === this._activeTab) {
|
if (tab === this._activeTab) {
|
||||||
this.hostApp.setTitle(title)
|
this.hostWindow.setTitle(title)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -205,7 +207,7 @@ export class AppService {
|
|||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
this._activeTab?.emitFocused()
|
this._activeTab?.emitFocused()
|
||||||
})
|
})
|
||||||
this.hostApp.setTitle(this._activeTab?.title)
|
this.hostWindow.setTitle(this._activeTab?.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
getParentTab (tab: BaseTabComponent): SplitTabComponent|null {
|
getParentTab (tab: BaseTabComponent): SplitTabComponent|null {
|
||||||
@@ -332,7 +334,7 @@ export class AppService {
|
|||||||
this.tabRecovery.enabled = false
|
this.tabRecovery.enabled = false
|
||||||
await this.tabRecovery.saveTabs(this.tabs)
|
await this.tabRecovery.saveTabs(this.tabs)
|
||||||
if (await this.closeAllTabs()) {
|
if (await this.closeAllTabs()) {
|
||||||
this.hostApp.closeWindow()
|
this.hostWindow.close()
|
||||||
} else {
|
} else {
|
||||||
this.tabRecovery.enabled = true
|
this.tabRecovery.enabled = true
|
||||||
}
|
}
|
||||||
|
@@ -89,9 +89,9 @@ export class ConfigService {
|
|||||||
restartRequested: boolean
|
restartRequested: boolean
|
||||||
|
|
||||||
/** Fires once when the config is loaded */
|
/** Fires once when the config is loaded */
|
||||||
get ready$ (): Observable<void> { return this.ready }
|
get ready$ (): Observable<boolean> { return this.ready }
|
||||||
|
|
||||||
private ready = new AsyncSubject<void>()
|
private ready = new AsyncSubject<boolean>()
|
||||||
private changed = new Subject<void>()
|
private changed = new Subject<void>()
|
||||||
private _store: any
|
private _store: any
|
||||||
private defaults: any
|
private defaults: any
|
||||||
@@ -213,7 +213,7 @@ export class ConfigService {
|
|||||||
|
|
||||||
private async init () {
|
private async init () {
|
||||||
await this.load()
|
await this.load()
|
||||||
this.ready.next()
|
this.ready.next(true)
|
||||||
this.ready.complete()
|
this.ready.complete()
|
||||||
|
|
||||||
this.hostApp.configChangeBroadcast$.subscribe(() => {
|
this.hostApp.configChangeBroadcast$.subscribe(() => {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { App, IpcRenderer, Shell, Dialog, Clipboard, GlobalShortcut, Screen, Remote, AutoUpdater, TouchBar, BrowserWindow, Menu, MenuItem, NativeImage, MessageBoxOptions } from 'electron'
|
import { App, IpcRenderer, Shell, Dialog, Clipboard, GlobalShortcut, Screen, Remote, AutoUpdater, TouchBar, BrowserWindow, Menu, MenuItem, NativeImage } from 'electron'
|
||||||
import * as remote from '@electron/remote'
|
import * as remote from '@electron/remote'
|
||||||
|
|
||||||
export interface MessageBoxResponse {
|
export interface MessageBoxResponse {
|
||||||
@@ -44,11 +44,4 @@ export class ElectronService {
|
|||||||
this.Menu = remote.Menu
|
this.Menu = remote.Menu
|
||||||
this.MenuItem = remote.MenuItem
|
this.MenuItem = remote.MenuItem
|
||||||
}
|
}
|
||||||
|
|
||||||
async showMessageBox (
|
|
||||||
browserWindow: BrowserWindow,
|
|
||||||
options: MessageBoxOptions
|
|
||||||
): Promise<MessageBoxResponse> {
|
|
||||||
return this.dialog.showMessageBox(browserWindow, options)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,6 @@ export class HostAppService {
|
|||||||
* Fired once the window is visible
|
* Fired once the window is visible
|
||||||
*/
|
*/
|
||||||
shown = new EventEmitter<any>()
|
shown = new EventEmitter<any>()
|
||||||
isFullScreen = false
|
|
||||||
isPortable = !!process.env.PORTABLE_EXECUTABLE_FILE
|
isPortable = !!process.env.PORTABLE_EXECUTABLE_FILE
|
||||||
|
|
||||||
private preferencesMenu = new Subject<void>()
|
private preferencesMenu = new Subject<void>()
|
||||||
@@ -92,14 +91,6 @@ export class HostAppService {
|
|||||||
this.logger.error('Unhandled exception:', err)
|
this.logger.error('Unhandled exception:', err)
|
||||||
})
|
})
|
||||||
|
|
||||||
electron.ipcRenderer.on('host:window-enter-full-screen', () => this.zone.run(() => {
|
|
||||||
this.isFullScreen = true
|
|
||||||
}))
|
|
||||||
|
|
||||||
electron.ipcRenderer.on('host:window-leave-full-screen', () => this.zone.run(() => {
|
|
||||||
this.isFullScreen = false
|
|
||||||
}))
|
|
||||||
|
|
||||||
electron.ipcRenderer.on('host:window-shown', () => {
|
electron.ipcRenderer.on('host:window-shown', () => {
|
||||||
this.zone.run(() => this.shown.emit())
|
this.zone.run(() => this.shown.emit())
|
||||||
})
|
})
|
||||||
@@ -163,11 +154,6 @@ export class HostAppService {
|
|||||||
this.electron.ipcRenderer.send('app:new-window')
|
this.electron.ipcRenderer.send('app:new-window')
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleFullscreen (): void {
|
|
||||||
const window = this.getWindow()
|
|
||||||
window.setFullScreen(!this.isFullScreen)
|
|
||||||
}
|
|
||||||
|
|
||||||
openDevTools (): void {
|
openDevTools (): void {
|
||||||
this.getWindow().webContents.openDevTools({ mode: 'undocked' })
|
this.getWindow().webContents.openDevTools({ mode: 'undocked' })
|
||||||
}
|
}
|
||||||
@@ -176,22 +162,6 @@ export class HostAppService {
|
|||||||
this.electron.ipcRenderer.send('window-focus')
|
this.electron.ipcRenderer.send('window-focus')
|
||||||
}
|
}
|
||||||
|
|
||||||
minimize (): void {
|
|
||||||
this.electron.ipcRenderer.send('window-minimize')
|
|
||||||
}
|
|
||||||
|
|
||||||
maximize (): void {
|
|
||||||
this.electron.ipcRenderer.send('window-maximize')
|
|
||||||
}
|
|
||||||
|
|
||||||
unmaximize (): void {
|
|
||||||
this.electron.ipcRenderer.send('window-unmaximize')
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleMaximize (): void {
|
|
||||||
this.electron.ipcRenderer.send('window-toggle-maximize')
|
|
||||||
}
|
|
||||||
|
|
||||||
setBounds (bounds: Bounds): void {
|
setBounds (bounds: Bounds): void {
|
||||||
this.electron.ipcRenderer.send('window-set-bounds', bounds)
|
this.electron.ipcRenderer.send('window-set-bounds', bounds)
|
||||||
}
|
}
|
||||||
@@ -200,10 +170,6 @@ export class HostAppService {
|
|||||||
this.electron.ipcRenderer.send('window-set-always-on-top', flag)
|
this.electron.ipcRenderer.send('window-set-always-on-top', flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTitle (title?: string): void {
|
|
||||||
this.electron.ipcRenderer.send('window-set-title', title ?? 'Terminus')
|
|
||||||
}
|
|
||||||
|
|
||||||
setTouchBar (touchBar: TouchBar): void {
|
setTouchBar (touchBar: TouchBar): void {
|
||||||
this.getWindow().setTouchBar(touchBar)
|
this.getWindow().setTouchBar(touchBar)
|
||||||
}
|
}
|
||||||
@@ -223,10 +189,6 @@ export class HostAppService {
|
|||||||
this.electron.ipcRenderer.send('window-bring-to-front')
|
this.electron.ipcRenderer.send('window-bring-to-front')
|
||||||
}
|
}
|
||||||
|
|
||||||
closeWindow (): void {
|
|
||||||
this.electron.ipcRenderer.send('window-close')
|
|
||||||
}
|
|
||||||
|
|
||||||
registerGlobalHotkey (specs: string[]): void {
|
registerGlobalHotkey (specs: string[]): void {
|
||||||
this.electron.ipcRenderer.send('app:register-global-hotkey', specs)
|
this.electron.ipcRenderer.send('app:register-global-hotkey', specs)
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,20 @@
|
|||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, ElectronService, WIN_BUILD_FLUENT_BG_SUPPORTED, isWindowsBuild } from 'terminus-core'
|
import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, ElectronService, WIN_BUILD_FLUENT_BG_SUPPORTED, isWindowsBuild, HostWindowService } from 'terminus-core'
|
||||||
import { TerminalColorSchemeProvider } from 'terminus-terminal'
|
import { TerminalColorSchemeProvider } from 'terminus-terminal'
|
||||||
|
|
||||||
import { HyperColorSchemes } from './colorSchemes'
|
import { HyperColorSchemes } from './colorSchemes'
|
||||||
import { ElectronPlatformService } from './services/platform'
|
import { ElectronPlatformService } from './services/platform.service'
|
||||||
import { ElectronLogService } from './services/log.service'
|
import { ElectronLogService } from './services/log.service'
|
||||||
import { ElectronUpdaterService } from './services/updater.service'
|
import { ElectronUpdaterService } from './services/updater.service'
|
||||||
import { TouchbarService } from './services/touchbar.service'
|
import { TouchbarService } from './services/touchbar.service'
|
||||||
import { ElectronDockingService } from './services/docking.service'
|
import { ElectronDockingService } from './services/docking.service'
|
||||||
|
import { ElectronHostWindow } from './services/hostWindow.service'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: TerminalColorSchemeProvider, useClass: HyperColorSchemes, multi: true },
|
{ provide: TerminalColorSchemeProvider, useClass: HyperColorSchemes, multi: true },
|
||||||
{ provide: PlatformService, useClass: ElectronPlatformService },
|
{ provide: PlatformService, useClass: ElectronPlatformService },
|
||||||
|
{ provide: HostWindowService, useClass: ElectronHostWindow },
|
||||||
{ provide: LogService, useClass: ElectronLogService },
|
{ provide: LogService, useClass: ElectronLogService },
|
||||||
{ provide: UpdaterService, useClass: ElectronUpdaterService },
|
{ provide: UpdaterService, useClass: ElectronUpdaterService },
|
||||||
{ provide: DockingService, useClass: ElectronDockingService },
|
{ provide: DockingService, useClass: ElectronDockingService },
|
||||||
|
51
terminus-electron/src/services/hostWindow.service.ts
Normal file
51
terminus-electron/src/services/hostWindow.service.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
|
import { Observable, Subject } from 'rxjs'
|
||||||
|
import { ElectronService, HostAppService, HostWindowService } from 'terminus-core'
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class ElectronHostWindow extends HostWindowService {
|
||||||
|
get closeRequest$ (): Observable<void> { return this.closeRequest }
|
||||||
|
get isFullscreen (): boolean { return this._isFullScreen}
|
||||||
|
|
||||||
|
private closeRequest = new Subject<void>()
|
||||||
|
private _isFullScreen = false
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
private electron: ElectronService,
|
||||||
|
private hostApp: HostAppService,
|
||||||
|
zone: NgZone,
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
electron.ipcRenderer.on('host:window-enter-full-screen', () => zone.run(() => {
|
||||||
|
this._isFullScreen = true
|
||||||
|
}))
|
||||||
|
|
||||||
|
electron.ipcRenderer.on('host:window-leave-full-screen', () => zone.run(() => {
|
||||||
|
this._isFullScreen = false
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
reload (): void {
|
||||||
|
this.hostApp.getWindow().reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitle (title?: string): void {
|
||||||
|
this.electron.ipcRenderer.send('window-set-title', title ?? 'Terminus')
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFullscreen (): void {
|
||||||
|
this.hostApp.getWindow().setFullScreen(!this._isFullScreen)
|
||||||
|
}
|
||||||
|
|
||||||
|
minimize (): void {
|
||||||
|
this.electron.ipcRenderer.send('window-minimize')
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleMaximize (): void {
|
||||||
|
this.electron.ipcRenderer.send('window-toggle-maximize')
|
||||||
|
}
|
||||||
|
|
||||||
|
close (): void {
|
||||||
|
this.electron.ipcRenderer.send('window-close')
|
||||||
|
}
|
||||||
|
}
|
@@ -4,7 +4,7 @@ import * as os from 'os'
|
|||||||
import promiseIpc from 'electron-promise-ipc'
|
import promiseIpc from 'electron-promise-ipc'
|
||||||
import { execFile } from 'mz/child_process'
|
import { execFile } from 'mz/child_process'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { PlatformService, ClipboardContent, HostAppService, Platform, ElectronService, MenuItemOptions } from 'terminus-core'
|
import { PlatformService, ClipboardContent, HostAppService, Platform, ElectronService, MenuItemOptions, MessageBoxOptions, MessageBoxResult } from 'terminus-core'
|
||||||
const fontManager = require('fontmanager-redux') // eslint-disable-line
|
const fontManager = require('fontmanager-redux') // eslint-disable-line
|
||||||
|
|
||||||
/* eslint-disable block-scoped-var */
|
/* eslint-disable block-scoped-var */
|
||||||
@@ -30,6 +30,10 @@ export class ElectronPlatformService extends PlatformService {
|
|||||||
this.configPath = path.join(electron.app.getPath('userData'), 'config.yaml')
|
this.configPath = path.join(electron.app.getPath('userData'), 'config.yaml')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readClipboard (): string {
|
||||||
|
return this.electron.clipboard.readText()
|
||||||
|
}
|
||||||
|
|
||||||
setClipboard (content: ClipboardContent): void {
|
setClipboard (content: ClipboardContent): void {
|
||||||
require('@electron/remote').clipboard.write(content)
|
require('@electron/remote').clipboard.write(content)
|
||||||
}
|
}
|
||||||
@@ -86,7 +90,7 @@ export class ElectronPlatformService extends PlatformService {
|
|||||||
|
|
||||||
async loadConfig (): Promise<string> {
|
async loadConfig (): Promise<string> {
|
||||||
if (await fs.exists(this.configPath)) {
|
if (await fs.exists(this.configPath)) {
|
||||||
return fs.readFileSync(this.configPath, 'utf8')
|
return fs.readFile(this.configPath, 'utf8')
|
||||||
} else {
|
} else {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@@ -141,6 +145,12 @@ export class ElectronPlatformService extends PlatformService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
popupContextMenu (menu: MenuItemOptions[], _event?: MouseEvent): void {
|
popupContextMenu (menu: MenuItemOptions[], _event?: MouseEvent): void {
|
||||||
this.electron.Menu.buildFromTemplate(menu).popup({})
|
this.electron.Menu.buildFromTemplate(menu.map(item => ({
|
||||||
|
...item,
|
||||||
|
}))).popup({})
|
||||||
|
}
|
||||||
|
|
||||||
|
async showMessageBox (options: MessageBoxOptions): Promise<MessageBoxResult> {
|
||||||
|
return this.electron.dialog.showMessageBox(this.hostApp.getWindow(), options)
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -2,8 +2,7 @@ import * as path from 'path'
|
|||||||
import * as fs from 'mz/fs'
|
import * as fs from 'mz/fs'
|
||||||
import { exec } from 'mz/child_process'
|
import { exec } from 'mz/child_process'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { ElectronService } from '../../../terminus-core/src/services/electron.service'
|
import { ElectronService, HostAppService, Platform } from 'terminus-core'
|
||||||
import { HostAppService, Platform } from '../../../terminus-core/src/services/hostApp.service'
|
|
||||||
|
|
||||||
/* eslint-disable block-scoped-var */
|
/* eslint-disable block-scoped-var */
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import { Logger, LogService, ElectronService, ConfigService, HostAppService, UpdaterService } from 'terminus-core'
|
import { Logger, LogService, ElectronService, ConfigService, UpdaterService, PlatformService } from 'terminus-core'
|
||||||
|
|
||||||
const UPDATES_URL = 'https://api.github.com/repos/eugeny/terminus/releases/latest'
|
const UPDATES_URL = 'https://api.github.com/repos/eugeny/terminus/releases/latest'
|
||||||
|
|
||||||
@@ -15,8 +15,8 @@ export class ElectronUpdaterService extends UpdaterService {
|
|||||||
constructor (
|
constructor (
|
||||||
log: LogService,
|
log: LogService,
|
||||||
config: ConfigService,
|
config: ConfigService,
|
||||||
|
private platform: PlatformService,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
private hostApp: HostAppService,
|
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
this.logger = log.create('updater')
|
this.logger = log.create('updater')
|
||||||
@@ -42,18 +42,21 @@ export class ElectronUpdaterService extends UpdaterService {
|
|||||||
electron.autoUpdater.once('update-downloaded', () => resolve(true))
|
electron.autoUpdater.once('update-downloaded', () => resolve(true))
|
||||||
})
|
})
|
||||||
|
|
||||||
if (config.store.enableAutomaticUpdates && this.electronUpdaterAvailable && !process.env.TERMINUS_DEV) {
|
|
||||||
this.logger.debug('Checking for updates')
|
config.ready$.toPromise().then(() => {
|
||||||
try {
|
if (config.store.enableAutomaticUpdates && this.electronUpdaterAvailable && !process.env.TERMINUS_DEV) {
|
||||||
electron.autoUpdater.setFeedURL({
|
this.logger.debug('Checking for updates')
|
||||||
url: `https://update.electronjs.org/eugeny/terminus/${process.platform}-${process.arch}/${electron.app.getVersion()}`,
|
try {
|
||||||
})
|
electron.autoUpdater.setFeedURL({
|
||||||
electron.autoUpdater.checkForUpdates()
|
url: `https://update.electronjs.org/eugeny/terminus/${process.platform}-${process.arch}/${electron.app.getVersion()}`,
|
||||||
} catch (e) {
|
})
|
||||||
this.electronUpdaterAvailable = false
|
electron.autoUpdater.checkForUpdates()
|
||||||
this.logger.info('Electron updater unavailable, falling back', e)
|
} catch (e) {
|
||||||
|
this.electronUpdaterAvailable = false
|
||||||
|
this.logger.info('Electron updater unavailable, falling back', e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async check (): Promise<boolean> {
|
async check (): Promise<boolean> {
|
||||||
@@ -117,8 +120,7 @@ export class ElectronUpdaterService extends UpdaterService {
|
|||||||
if (!this.electronUpdaterAvailable) {
|
if (!this.electronUpdaterAvailable) {
|
||||||
this.electron.shell.openExternal(this.updateURL)
|
this.electron.shell.openExternal(this.updateURL)
|
||||||
} else {
|
} else {
|
||||||
if ((await this.electron.showMessageBox(
|
if ((await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Installing the update will close all tabs and restart Terminus.',
|
message: 'Installing the update will close all tabs and restart Terminus.',
|
||||||
|
@@ -90,8 +90,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
|
|||||||
if (!children?.length) {
|
if (!children?.length) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return (await this.electron.showMessageBox(
|
return (await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: `"${children[0].command}" is still running. Close?`,
|
message: `"${children[0].command}" is still running. Close?`,
|
||||||
|
@@ -4,7 +4,7 @@ import { TerminalService } from './services/terminal.service'
|
|||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TerminalHotkeyProvider extends HotkeyProvider {
|
export class LocalTerminalHotkeyProvider extends HotkeyProvider {
|
||||||
hotkeys: HotkeyDescription[] = [
|
hotkeys: HotkeyDescription[] = [
|
||||||
{
|
{
|
||||||
id: 'new-tab',
|
id: 'new-tab',
|
||||||
|
@@ -21,7 +21,7 @@ import { RecoveryProvider } from './recoveryProvider'
|
|||||||
import { ShellProvider } from './api'
|
import { ShellProvider } from './api'
|
||||||
import { ShellSettingsTabProvider } from './settings'
|
import { ShellSettingsTabProvider } from './settings'
|
||||||
import { TerminalConfigProvider } from './config'
|
import { TerminalConfigProvider } from './config'
|
||||||
import { TerminalHotkeyProvider } from './hotkeys'
|
import { LocalTerminalHotkeyProvider } from './hotkeys'
|
||||||
import { NewTabContextMenu, SaveAsProfileContextMenu } from './tabContextMenu'
|
import { NewTabContextMenu, SaveAsProfileContextMenu } from './tabContextMenu'
|
||||||
|
|
||||||
import { CmderShellProvider } from './shells/cmder'
|
import { CmderShellProvider } from './shells/cmder'
|
||||||
@@ -55,7 +55,7 @@ import { AutoOpenTabCLIHandler, OpenPathCLIHandler, TerminalCLIHandler } from '.
|
|||||||
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
|
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
|
||||||
{ provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true },
|
{ provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true },
|
||||||
{ provide: ConfigProvider, useClass: TerminalConfigProvider, multi: true },
|
{ provide: ConfigProvider, useClass: TerminalConfigProvider, multi: true },
|
||||||
{ provide: HotkeyProvider, useClass: TerminalHotkeyProvider, multi: true },
|
{ provide: HotkeyProvider, useClass: LocalTerminalHotkeyProvider, multi: true },
|
||||||
|
|
||||||
{ provide: ShellProvider, useClass: WindowsDefaultShellProvider, multi: true },
|
{ provide: ShellProvider, useClass: WindowsDefaultShellProvider, multi: true },
|
||||||
{ provide: ShellProvider, useClass: MacOSDefaultShellProvider, multi: true },
|
{ provide: ShellProvider, useClass: MacOSDefaultShellProvider, multi: true },
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'
|
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'
|
||||||
import { ElectronService, HostAppService } from 'terminus-core'
|
import { PlatformService } from 'terminus-core'
|
||||||
import { SerialConnection, LoginScript, SerialPortInfo, BAUD_RATES } from '../api'
|
import { SerialConnection, LoginScript, SerialPortInfo, BAUD_RATES } from '../api'
|
||||||
import { SerialService } from '../services/serial.service'
|
import { SerialService } from '../services/serial.service'
|
||||||
|
|
||||||
@@ -32,8 +32,7 @@ export class EditConnectionModalComponent {
|
|||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private modalInstance: NgbActiveModal,
|
private modalInstance: NgbActiveModal,
|
||||||
private electron: ElectronService,
|
private platform: PlatformService,
|
||||||
private hostApp: HostAppService,
|
|
||||||
private serial: SerialService,
|
private serial: SerialService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@@ -100,8 +99,7 @@ export class EditConnectionModalComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteScript (script: LoginScript) {
|
async deleteScript (script: LoginScript) {
|
||||||
if (this.connection.scripts && (await this.electron.showMessageBox(
|
if (this.connection.scripts && (await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Delete this script?',
|
message: 'Delete this script?',
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { ConfigService, ElectronService, HostAppService } from 'terminus-core'
|
import { ConfigService, PlatformService } from 'terminus-core'
|
||||||
import { SerialConnection } from '../api'
|
import { SerialConnection } from '../api'
|
||||||
import { EditConnectionModalComponent } from './editConnectionModal.component'
|
import { EditConnectionModalComponent } from './editConnectionModal.component'
|
||||||
|
|
||||||
@@ -14,8 +14,7 @@ export class SerialSettingsTabComponent {
|
|||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
public config: ConfigService,
|
public config: ConfigService,
|
||||||
private electron: ElectronService,
|
private platform: PlatformService,
|
||||||
private hostApp: HostAppService,
|
|
||||||
private ngbModal: NgbModal,
|
private ngbModal: NgbModal,
|
||||||
) {
|
) {
|
||||||
this.connections = this.config.store.serial.connections
|
this.connections = this.config.store.serial.connections
|
||||||
@@ -62,8 +61,7 @@ export class SerialSettingsTabComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteConnection (connection: SerialConnection) {
|
async deleteConnection (connection: SerialConnection) {
|
||||||
if ((await this.electron.showMessageBox(
|
if ((await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: `Delete "${connection.name}"?`,
|
message: `Delete "${connection.name}"?`,
|
||||||
|
@@ -4,7 +4,7 @@ import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|||||||
import { Observable } from 'rxjs'
|
import { Observable } from 'rxjs'
|
||||||
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'
|
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'
|
||||||
|
|
||||||
import { ElectronService, HostAppService, ConfigService } from 'terminus-core'
|
import { ElectronService, HostAppService, ConfigService, PlatformService } from 'terminus-core'
|
||||||
import { PasswordStorageService } from '../services/passwordStorage.service'
|
import { PasswordStorageService } from '../services/passwordStorage.service'
|
||||||
import { SSHConnection, LoginScript, ForwardedPortConfig, SSHAlgorithmType, ALGORITHM_BLACKLIST } from '../api'
|
import { SSHConnection, LoginScript, ForwardedPortConfig, SSHAlgorithmType, ALGORITHM_BLACKLIST } from '../api'
|
||||||
import { PromptModalComponent } from './promptModal.component'
|
import { PromptModalComponent } from './promptModal.component'
|
||||||
@@ -29,6 +29,7 @@ export class EditConnectionModalComponent {
|
|||||||
public config: ConfigService,
|
public config: ConfigService,
|
||||||
private modalInstance: NgbActiveModal,
|
private modalInstance: NgbActiveModal,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
|
private platform: PlatformService,
|
||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
private passwordStorage: PasswordStorageService,
|
private passwordStorage: PasswordStorageService,
|
||||||
private ngbModal: NgbModal,
|
private ngbModal: NgbModal,
|
||||||
@@ -153,8 +154,7 @@ export class EditConnectionModalComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteScript (script: LoginScript) {
|
async deleteScript (script: LoginScript) {
|
||||||
if (this.connection.scripts && (await this.electron.showMessageBox(
|
if (this.connection.scripts && (await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Delete this script?',
|
message: 'Delete this script?',
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import deepClone from 'clone-deep'
|
import deepClone from 'clone-deep'
|
||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { ConfigService, ElectronService, HostAppService, Platform } from 'terminus-core'
|
import { ConfigService, HostAppService, Platform, PlatformService } from 'terminus-core'
|
||||||
import { PasswordStorageService } from '../services/passwordStorage.service'
|
import { PasswordStorageService } from '../services/passwordStorage.service'
|
||||||
import { SSHConnection } from '../api'
|
import { SSHConnection } from '../api'
|
||||||
import { EditConnectionModalComponent } from './editConnectionModal.component'
|
import { EditConnectionModalComponent } from './editConnectionModal.component'
|
||||||
@@ -28,7 +28,7 @@ export class SSHSettingsTabComponent {
|
|||||||
constructor (
|
constructor (
|
||||||
public config: ConfigService,
|
public config: ConfigService,
|
||||||
public hostApp: HostAppService,
|
public hostApp: HostAppService,
|
||||||
private electron: ElectronService,
|
private platform: PlatformService,
|
||||||
private ngbModal: NgbModal,
|
private ngbModal: NgbModal,
|
||||||
private passwordStorage: PasswordStorageService,
|
private passwordStorage: PasswordStorageService,
|
||||||
) {
|
) {
|
||||||
@@ -81,8 +81,7 @@ export class SSHSettingsTabComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteConnection (connection: SSHConnection) {
|
async deleteConnection (connection: SSHConnection) {
|
||||||
if ((await this.electron.showMessageBox(
|
if ((await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: `Delete "${connection.name}"?`,
|
message: `Delete "${connection.name}"?`,
|
||||||
@@ -115,8 +114,7 @@ export class SSHSettingsTabComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteGroup (group: SSHConnectionGroup) {
|
async deleteGroup (group: SSHConnectionGroup) {
|
||||||
if ((await this.electron.showMessageBox(
|
if ((await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: `Delete "${group.name}"?`,
|
message: `Delete "${group.name}"?`,
|
||||||
|
@@ -210,8 +210,7 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
|
|||||||
if (!(this.connection?.warnOnClose ?? this.config.store.ssh.warnOnClose)) {
|
if (!(this.connection?.warnOnClose ?? this.config.store.ssh.warnOnClose)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return (await this.electron.showMessageBox(
|
return (await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: `Disconnect from ${this.connection?.host}?`,
|
message: `Disconnect from ${this.connection?.host}?`,
|
||||||
|
@@ -3,7 +3,7 @@ import { first } from 'rxjs/operators'
|
|||||||
import colors from 'ansi-colors'
|
import colors from 'ansi-colors'
|
||||||
import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core'
|
import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core'
|
||||||
import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations'
|
import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations'
|
||||||
import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, NotificationsService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent, SubscriptionContainer, MenuItemOptions, PlatformService } from 'terminus-core'
|
import { AppService, ConfigService, BaseTabComponent, HostAppService, HotkeysService, NotificationsService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent, SubscriptionContainer, MenuItemOptions, PlatformService } from 'terminus-core'
|
||||||
|
|
||||||
import { BaseSession } from '../session'
|
import { BaseSession } from '../session'
|
||||||
import { TerminalFrontendService } from '../services/terminalFrontend.service'
|
import { TerminalFrontendService } from '../services/terminalFrontend.service'
|
||||||
@@ -82,7 +82,6 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
protected app: AppService
|
protected app: AppService
|
||||||
protected hostApp: HostAppService
|
protected hostApp: HostAppService
|
||||||
protected hotkeys: HotkeysService
|
protected hotkeys: HotkeysService
|
||||||
protected electron: ElectronService
|
|
||||||
protected platform: PlatformService
|
protected platform: PlatformService
|
||||||
protected terminalContainersService: TerminalFrontendService
|
protected terminalContainersService: TerminalFrontendService
|
||||||
protected notifications: NotificationsService
|
protected notifications: NotificationsService
|
||||||
@@ -135,7 +134,6 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
this.app = injector.get(AppService)
|
this.app = injector.get(AppService)
|
||||||
this.hostApp = injector.get(HostAppService)
|
this.hostApp = injector.get(HostAppService)
|
||||||
this.hotkeys = injector.get(HotkeysService)
|
this.hotkeys = injector.get(HotkeysService)
|
||||||
this.electron = injector.get(ElectronService)
|
|
||||||
this.platform = injector.get(PlatformService)
|
this.platform = injector.get(PlatformService)
|
||||||
this.terminalContainersService = injector.get(TerminalFrontendService)
|
this.terminalContainersService = injector.get(TerminalFrontendService)
|
||||||
this.notifications = injector.get(NotificationsService)
|
this.notifications = injector.get(NotificationsService)
|
||||||
@@ -359,7 +357,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
}
|
}
|
||||||
|
|
||||||
async paste (): Promise<void> {
|
async paste (): Promise<void> {
|
||||||
let data = this.electron.clipboard.readText()
|
let data = this.platform.readClipboard()
|
||||||
if (this.config.store.terminal.bracketedPaste) {
|
if (this.config.store.terminal.bracketedPaste) {
|
||||||
data = `\x1b[200~${data}\x1b[201~`
|
data = `\x1b[200~${data}\x1b[201~`
|
||||||
}
|
}
|
||||||
@@ -374,15 +372,13 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
|
|
||||||
if (data.includes('\r') && this.config.store.terminal.warnOnMultilinePaste) {
|
if (data.includes('\r') && this.config.store.terminal.warnOnMultilinePaste) {
|
||||||
const buttons = ['Paste', 'Cancel']
|
const buttons = ['Paste', 'Cancel']
|
||||||
const result = (await this.electron.showMessageBox(
|
const result = (await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
detail: data,
|
detail: data,
|
||||||
message: `Paste multiple lines?`,
|
message: `Paste multiple lines?`,
|
||||||
buttons,
|
buttons,
|
||||||
defaultId: 0,
|
defaultId: 0,
|
||||||
cancelId: 1,
|
|
||||||
}
|
}
|
||||||
)).response
|
)).response
|
||||||
if (result === 1) {
|
if (result === 1) {
|
||||||
@@ -463,7 +459,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
cwd = await this.session.getWorkingDirectory()
|
cwd = await this.session.getWorkingDirectory()
|
||||||
}
|
}
|
||||||
if (cwd) {
|
if (cwd) {
|
||||||
this.electron.clipboard.writeText(cwd)
|
this.platform.setClipboard({ text: cwd })
|
||||||
this.notifications.notice('Copied')
|
this.notifications.notice('Copied')
|
||||||
} else {
|
} else {
|
||||||
this.notifications.error('Shell does not support current path detection')
|
this.notifications.error('Shell does not support current path detection')
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import deepEqual from 'deep-equal'
|
import deepEqual from 'deep-equal'
|
||||||
|
|
||||||
import { Component, Inject, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'
|
import { Component, Inject, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'
|
||||||
import { ConfigService, HostAppService, ElectronService } from 'terminus-core'
|
import { ConfigService, PlatformService } from 'terminus-core'
|
||||||
import { TerminalColorSchemeProvider } from '../api/colorSchemeProvider'
|
import { TerminalColorSchemeProvider } from '../api/colorSchemeProvider'
|
||||||
import { TerminalColorScheme } from '../api/interfaces'
|
import { TerminalColorScheme } from '../api/interfaces'
|
||||||
|
|
||||||
@@ -26,8 +26,7 @@ export class ColorSchemeSettingsTabComponent {
|
|||||||
constructor (
|
constructor (
|
||||||
@Inject(TerminalColorSchemeProvider) private colorSchemeProviders: TerminalColorSchemeProvider[],
|
@Inject(TerminalColorSchemeProvider) private colorSchemeProviders: TerminalColorSchemeProvider[],
|
||||||
private changeDetector: ChangeDetectorRef,
|
private changeDetector: ChangeDetectorRef,
|
||||||
private hostApp: HostAppService,
|
private platform: PlatformService,
|
||||||
private electron: ElectronService,
|
|
||||||
public config: ConfigService,
|
public config: ConfigService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@@ -76,8 +75,7 @@ export class ColorSchemeSettingsTabComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteScheme (scheme: TerminalColorScheme) {
|
async deleteScheme (scheme: TerminalColorScheme) {
|
||||||
if ((await this.electron.showMessageBox(
|
if ((await this.platform.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: `Delete "${scheme.name}"?`,
|
message: `Delete "${scheme.name}"?`,
|
||||||
|
@@ -2,13 +2,14 @@ import * as fs from 'fs'
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { TerminalDecorator } from '../api/decorator'
|
import { TerminalDecorator } from '../api/decorator'
|
||||||
import { BaseTerminalTabComponent } from '../api/baseTerminalTab.component'
|
import { BaseTerminalTabComponent } from '../api/baseTerminalTab.component'
|
||||||
import { ElectronService, HostAppService } from 'terminus-core'
|
import { ElectronService, HostAppService, PlatformService } from 'terminus-core'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DebugDecorator extends TerminalDecorator {
|
export class DebugDecorator extends TerminalDecorator {
|
||||||
constructor (
|
constructor (
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
|
private platform: PlatformService,
|
||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
@@ -93,7 +94,7 @@ export class DebugDecorator extends TerminalDecorator {
|
|||||||
|
|
||||||
private async doCopyState (terminal: BaseTerminalTabComponent) {
|
private async doCopyState (terminal: BaseTerminalTabComponent) {
|
||||||
const data = '```' + JSON.stringify(terminal.frontend!.saveState()) + '```'
|
const data = '```' + JSON.stringify(terminal.frontend!.saveState()) + '```'
|
||||||
this.electron.clipboard.writeText(data)
|
this.platform.setClipboard({ text: data })
|
||||||
}
|
}
|
||||||
|
|
||||||
private async doLoadState (terminal: BaseTerminalTabComponent) {
|
private async doLoadState (terminal: BaseTerminalTabComponent) {
|
||||||
@@ -104,7 +105,7 @@ export class DebugDecorator extends TerminalDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async doPasteState (terminal: BaseTerminalTabComponent) {
|
private async doPasteState (terminal: BaseTerminalTabComponent) {
|
||||||
let data = this.electron.clipboard.readText()
|
let data = this.platform.readClipboard()
|
||||||
if (data) {
|
if (data) {
|
||||||
if (data.startsWith('`')) {
|
if (data.startsWith('`')) {
|
||||||
data = data.substring(3, data.length - 3)
|
data = data.substring(3, data.length - 3)
|
||||||
@@ -119,7 +120,7 @@ export class DebugDecorator extends TerminalDecorator {
|
|||||||
|
|
||||||
private async doCopyOutput (buffer: string) {
|
private async doCopyOutput (buffer: string) {
|
||||||
const data = '```' + JSON.stringify(buffer) + '```'
|
const data = '```' + JSON.stringify(buffer) + '```'
|
||||||
this.electron.clipboard.writeText(data)
|
this.platform.setClipboard({ text: data })
|
||||||
}
|
}
|
||||||
|
|
||||||
private async doLoadOutput (terminal: BaseTerminalTabComponent) {
|
private async doLoadOutput (terminal: BaseTerminalTabComponent) {
|
||||||
@@ -130,7 +131,7 @@ export class DebugDecorator extends TerminalDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async doPasteOutput (terminal: BaseTerminalTabComponent) {
|
private async doPasteOutput (terminal: BaseTerminalTabComponent) {
|
||||||
let data = this.electron.clipboard.readText()
|
let data = this.platform.readClipboard()
|
||||||
if (data) {
|
if (data) {
|
||||||
if (data.startsWith('`')) {
|
if (data.startsWith('`')) {
|
||||||
data = data.substring(3, data.length - 3)
|
data = data.substring(3, data.length - 3)
|
||||||
|
13
terminus-web/src/components/messageBoxModal.component.pug
Normal file
13
terminus-web/src/components/messageBoxModal.component.pug
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.modal-body
|
||||||
|
div {{options.message}}
|
||||||
|
small {{options.detail}}
|
||||||
|
|
||||||
|
.modal-footer
|
||||||
|
.ml-auto
|
||||||
|
button.btn(
|
||||||
|
*ngFor='let button of options.buttons; index as i',
|
||||||
|
[autofocus]='i === options.defaultId',
|
||||||
|
[class.btn-primary]='i === options.defaultId',
|
||||||
|
[class.btn-secondary]='i !== options.defaultId',
|
||||||
|
(click)='onButton(i)',
|
||||||
|
) {{button}}
|
34
terminus-web/src/components/messageBoxModal.component.ts
Normal file
34
terminus-web/src/components/messageBoxModal.component.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { Component, Input, ElementRef, } from '@angular/core'
|
||||||
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { BaseComponent, HotkeysService, MessageBoxOptions } from 'terminus-core'
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
|
@Component({
|
||||||
|
template: require('./messageBoxModal.component.pug'),
|
||||||
|
})
|
||||||
|
export class MessageBoxModalComponent extends BaseComponent {
|
||||||
|
@Input() options: MessageBoxOptions
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
hotkeys: HotkeysService,
|
||||||
|
private element: ElementRef,
|
||||||
|
private modalInstance: NgbActiveModal,
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
this.subscribeUntilDestroyed(hotkeys.key, (event: KeyboardEvent) => {
|
||||||
|
if (event.type === 'keydown') {
|
||||||
|
if (event.key === 'Enter' && this.options.defaultId !== undefined) {
|
||||||
|
this.modalInstance.close(this.options.defaultId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit (): void {
|
||||||
|
this.element.nativeElement.querySelector('button[autofocus]').focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
onButton (index: number): void {
|
||||||
|
this.modalInstance.close(index)
|
||||||
|
}
|
||||||
|
}
|
@@ -1,17 +1,30 @@
|
|||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { LogService, PlatformService, UpdaterService } from 'terminus-core'
|
import { CommonModule } from '@angular/common'
|
||||||
|
import { HostWindowService, LogService, PlatformService, UpdaterService } from 'terminus-core'
|
||||||
|
|
||||||
import { WebPlatformService } from './platform'
|
import { WebPlatformService } from './platform'
|
||||||
import { ConsoleLogService } from './services/log.service'
|
import { ConsoleLogService } from './services/log.service'
|
||||||
import { NullUpdaterService } from './services/updater.service'
|
import { NullUpdaterService } from './services/updater.service'
|
||||||
|
import { WebHostWindow } from './services/hostWindow.service'
|
||||||
|
import { MessageBoxModalComponent } from './components/messageBoxModal.component'
|
||||||
|
|
||||||
import './styles.scss'
|
import './styles.scss'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: PlatformService, useClass: WebPlatformService },
|
{ provide: PlatformService, useClass: WebPlatformService },
|
||||||
{ provide: LogService, useClass: ConsoleLogService },
|
{ provide: LogService, useClass: ConsoleLogService },
|
||||||
{ provide: UpdaterService, useClass: NullUpdaterService },
|
{ provide: UpdaterService, useClass: NullUpdaterService },
|
||||||
|
{ provide: HostWindowService, useClass: WebHostWindow },
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
MessageBoxModalComponent,
|
||||||
|
],
|
||||||
|
entryComponents: [
|
||||||
|
MessageBoxModalComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export default class WebModule { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
export default class WebModule { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
import '@vaadin/vaadin-context-menu/vaadin-context-menu.js'
|
import '@vaadin/vaadin-context-menu/vaadin-context-menu.js'
|
||||||
import copyToClipboard from 'copy-text-to-clipboard'
|
import copyToClipboard from 'copy-text-to-clipboard'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { PlatformService, ClipboardContent, MenuItemOptions } from 'terminus-core'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { PlatformService, ClipboardContent, MenuItemOptions, MessageBoxOptions, MessageBoxResult } from 'terminus-core'
|
||||||
|
|
||||||
// eslint-disable-next-line no-duplicate-imports
|
// eslint-disable-next-line no-duplicate-imports
|
||||||
import type { ContextMenuElement, ContextMenuItem } from '@vaadin/vaadin-context-menu/vaadin-context-menu.js'
|
import type { ContextMenuElement, ContextMenuItem } from '@vaadin/vaadin-context-menu/vaadin-context-menu.js'
|
||||||
|
|
||||||
|
import { MessageBoxModalComponent } from './components/messageBoxModal.component'
|
||||||
import './styles.scss'
|
import './styles.scss'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -13,14 +15,19 @@ export class WebPlatformService extends PlatformService {
|
|||||||
private menu: ContextMenuElement
|
private menu: ContextMenuElement
|
||||||
private contextMenuHandlers = new Map<ContextMenuItem, () => void>()
|
private contextMenuHandlers = new Map<ContextMenuItem, () => void>()
|
||||||
|
|
||||||
constructor () {
|
constructor (
|
||||||
|
private ngbModal: NgbModal,
|
||||||
|
) {
|
||||||
super()
|
super()
|
||||||
this.menu = window.document.createElement('vaadin-context-menu')
|
this.menu = window.document.createElement('vaadin-context-menu')
|
||||||
this.menu.addEventListener('item-selected', e => {
|
this.menu.addEventListener('item-selected', e => {
|
||||||
this.contextMenuHandlers.get(e.detail.value)?.()
|
this.contextMenuHandlers.get(e.detail.value)?.()
|
||||||
})
|
})
|
||||||
document.body.appendChild(this.menu)
|
document.body.appendChild(this.menu)
|
||||||
console.log(require('./styles.scss'))
|
}
|
||||||
|
|
||||||
|
readClipboard (): string {
|
||||||
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
setClipboard (content: ClipboardContent): void {
|
setClipboard (content: ClipboardContent): void {
|
||||||
@@ -73,4 +80,19 @@ export class WebPlatformService extends PlatformService {
|
|||||||
}
|
}
|
||||||
return cmi
|
return cmi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async showMessageBox (options: MessageBoxOptions): Promise<MessageBoxResult> {
|
||||||
|
console.log(options)
|
||||||
|
const modal = this.ngbModal.open(MessageBoxModalComponent, {
|
||||||
|
backdrop: 'static',
|
||||||
|
})
|
||||||
|
const instance: MessageBoxModalComponent = modal.componentInstance
|
||||||
|
instance.options = options
|
||||||
|
try {
|
||||||
|
const response = await modal.result
|
||||||
|
return { response }
|
||||||
|
} catch {
|
||||||
|
return { response: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
39
terminus-web/src/services/hostWindow.service.ts
Normal file
39
terminus-web/src/services/hostWindow.service.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { Observable, Subject } from 'rxjs'
|
||||||
|
import { HostWindowService } from 'terminus-core'
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class WebHostWindow extends HostWindowService {
|
||||||
|
get closeRequest$ (): Observable<void> { return this.closeRequest }
|
||||||
|
get isFullscreen (): boolean { return !!document.fullscreenElement }
|
||||||
|
|
||||||
|
private closeRequest = new Subject<void>()
|
||||||
|
|
||||||
|
reload (): void {
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitle (title?: string): void {
|
||||||
|
document.title = title ?? 'Terminus'
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFullscreen (): void {
|
||||||
|
if (this.isFullscreen) {
|
||||||
|
document.exitFullscreen()
|
||||||
|
} else {
|
||||||
|
document.body.requestFullscreen({ navigationUI: 'hide' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
minimize (): void {
|
||||||
|
throw new Error('Unavailable')
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleMaximize (): void {
|
||||||
|
throw new Error('Unavailable')
|
||||||
|
}
|
||||||
|
|
||||||
|
close (): void {
|
||||||
|
window.close()
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user