Eugene Pankov 7 anni fa
parent
commit
23e93f0969

+ 20 - 7
terminus-core/src/components/baseTab.component.ts

@@ -1,17 +1,21 @@
-import { Subject } from 'rxjs'
+import { Observable, Subject } from 'rxjs'
 import { ViewRef } from '@angular/core'
 
 export abstract class BaseTabComponent {
     private static lastTabID = 0
     id: number
     title: string
-    titleChange$ = new Subject<string>()
     customTitle: string
     hasActivity = false
-    focused$ = new Subject<void>()
-    blurred$ = new Subject<void>()
     hasFocus = false
     hostView: ViewRef
+    protected titleChange = new Subject<string>()
+    protected focused = new Subject<void>()
+    protected blurred = new Subject<void>()
+
+    get focused$ (): Observable<void> { return this.focused }
+    get blurred$ (): Observable<void> { return this.blurred }
+    get titleChange$ (): Observable<string> { return this.titleChange }
 
     constructor () {
         this.id = BaseTabComponent.lastTabID++
@@ -26,7 +30,7 @@ export abstract class BaseTabComponent {
     setTitle (title: string) {
         this.title = title
         if (!this.customTitle) {
-            this.titleChange$.next(title)
+            this.titleChange.next(title)
         }
     }
 
@@ -42,8 +46,17 @@ export abstract class BaseTabComponent {
         return true
     }
 
+    emitFocused () {
+        this.focused.next()
+    }
+
+    emitBlurred () {
+        this.blurred.next()
+    }
+
     destroy (): void {
-        this.focused$.complete()
-        this.blurred$.complete()
+        this.focused.complete()
+        this.blurred.complete()
+        this.titleChange.complete()
     }
 }

+ 23 - 16
terminus-core/src/services/app.service.ts

@@ -1,4 +1,4 @@
-import { Subject, AsyncSubject } from 'rxjs'
+import { Observable, Subject, AsyncSubject } from 'rxjs'
 import { Injectable, ComponentFactoryResolver, Injector, Optional } from '@angular/core'
 import { DefaultTabProvider } from '../api/defaultTabProvider'
 import { BaseTabComponent } from '../components/baseTab.component'
@@ -11,13 +11,20 @@ export declare type TabComponentType = new (...args: any[]) => BaseTabComponent
 export class AppService {
     tabs: BaseTabComponent[] = []
     activeTab: BaseTabComponent
-    activeTabChange$ = new Subject<BaseTabComponent>()
     lastTabIndex = 0
     logger: Logger
-    tabsChanged$ = new Subject<void>()
-    tabOpened$ = new Subject<BaseTabComponent>()
-    tabClosed$ = new Subject<BaseTabComponent>()
-    ready$ = new AsyncSubject<void>()
+
+    private activeTabChange = new Subject<BaseTabComponent>()
+    private tabsChanged = new Subject<void>()
+    private tabOpened = new Subject<BaseTabComponent>()
+    private tabClosed = new Subject<BaseTabComponent>()
+    private ready = new AsyncSubject<void>()
+
+    get activeTabChange$ (): Observable<BaseTabComponent> { return this.activeTabChange }
+    get tabOpened$ (): Observable<BaseTabComponent> { return this.tabOpened }
+    get tabsChanged$ (): Observable<void> { return this.tabsChanged }
+    get tabClosed$ (): Observable<BaseTabComponent> { return this.tabClosed }
+    get ready$ (): Observable<void> { return this.ready }
 
     constructor (
         private componentFactoryResolver: ComponentFactoryResolver,
@@ -37,8 +44,8 @@ export class AppService {
 
         this.tabs.push(componentRef.instance)
         this.selectTab(componentRef.instance)
-        this.tabsChanged$.next()
-        this.tabOpened$.next(componentRef.instance)
+        this.tabsChanged.next()
+        this.tabOpened.next(componentRef.instance)
 
         return componentRef.instance
     }
@@ -60,12 +67,12 @@ export class AppService {
         }
         if (this.activeTab) {
             this.activeTab.hasActivity = false
-            this.activeTab.blurred$.next()
+            this.activeTab.emitBlurred()
         }
         this.activeTab = tab
-        this.activeTabChange$.next(tab)
+        this.activeTabChange.next(tab)
         if (this.activeTab) {
-            this.activeTab.focused$.next()
+            this.activeTab.emitFocused()
         }
     }
 
@@ -99,7 +106,7 @@ export class AppService {
     }
 
     emitTabsChanged () {
-        this.tabsChanged$.next()
+        this.tabsChanged.next()
     }
 
     async closeTab (tab: BaseTabComponent, checkCanClose?: boolean): Promise<void> {
@@ -115,12 +122,12 @@ export class AppService {
         if (tab === this.activeTab) {
             this.selectTab(this.tabs[newIndex])
         }
-        this.tabsChanged$.next()
-        this.tabClosed$.next(tab)
+        this.tabsChanged.next()
+        this.tabClosed.next(tab)
     }
 
     emitReady () {
-        this.ready$.next(null)
-        this.ready$.complete()
+        this.ready.next(null)
+        this.ready.complete()
     }
 }

+ 5 - 3
terminus-core/src/services/config.service.ts

@@ -1,4 +1,4 @@
-import { Subject } from 'rxjs'
+import { Observable, Subject } from 'rxjs'
 import * as yaml from 'js-yaml'
 import * as path from 'path'
 import * as fs from 'fs'
@@ -52,13 +52,15 @@ export class ConfigProxy {
 @Injectable()
 export class ConfigService {
     store: any
-    changed$ = new Subject<void>()
     restartRequested: boolean
+    private changed = new Subject<void>()
     private _store: any
     private path: string
     private defaults: any
     private servicesCache: { [id: string]: Function[] } = null
 
+    get changed$ (): Observable<void> { return this.changed }
+
     constructor (
         electron: ElectronService,
         hostApp: HostAppService,
@@ -93,7 +95,7 @@ export class ConfigService {
     }
 
     emitChange (): void {
-        this.changed$.next()
+        this.changed.next()
     }
 
     requestRestart (): void {

+ 19 - 11
terminus-core/src/services/hostApp.service.ts

@@ -14,17 +14,25 @@ export interface Bounds {
     height: number
 }
 
+export interface SecondInstanceArgs {
+    argv: string[],
+    cwd: string
+}
+
 @Injectable()
 export class HostAppService {
     platform: Platform
     nodePlatform: string
-    preferencesMenu$ = new Subject<void>()
     ready = new EventEmitter<any>()
     shown = new EventEmitter<any>()
-    secondInstance$ = new Subject<{ argv: string[], cwd: string }>()
     isFullScreen = false
+    private preferencesMenu = new Subject<void>()
+    private secondInstance = new Subject<SecondInstanceArgs>()
     private logger: Logger
 
+    get preferencesMenu$ (): Observable<void> { return this.preferencesMenu }
+    get secondInstance$ (): Observable<SecondInstanceArgs> { return this.secondInstance }
+
     constructor (
         private zone: NgZone,
         private electron: ElectronService,
@@ -38,7 +46,7 @@ export class HostAppService {
             linux: Platform.Linux
         }[this.nodePlatform]
 
-        electron.ipcRenderer.on('host:preferences-menu', () => this.zone.run(() => this.preferencesMenu$.next()))
+        electron.ipcRenderer.on('host:preferences-menu', () => this.zone.run(() => this.preferencesMenu.next()))
 
         electron.ipcRenderer.on('uncaughtException', ($event, err) => {
             this.logger.error('Unhandled exception:', err)
@@ -57,7 +65,7 @@ export class HostAppService {
         })
 
         electron.ipcRenderer.on('host:second-instance', ($event, argv: string[], cwd: string) => {
-            this.zone.run(() => this.secondInstance$.next({ argv, cwd }))
+            this.zone.run(() => this.secondInstance.next({ argv, cwd }))
         })
 
         this.ready.subscribe(() => {
@@ -119,13 +127,13 @@ export class HostAppService {
     }
 
     setVibrancy (enable: boolean) {
-      document.body.classList.toggle('vibrant', enable)
-      if (this.platform === Platform.macOS) {
-        this.hostApp.getWindow().setVibrancy(enable ? 'dark' : null)
-      }
-      if (this.platform === Platform.Windows) {
-        this.electron.ipcRenderer.send('window-set-vibrancy', enable)
-      }
+        document.body.classList.toggle('vibrant', enable)
+        if (this.platform === Platform.macOS) {
+            this.getWindow().setVibrancy(enable ? 'dark' : null)
+        }
+        if (this.platform === Platform.Windows) {
+            this.electron.ipcRenderer.send('window-set-vibrancy', enable)
+        }
     }
 
     quit () {

+ 1 - 2
terminus-core/src/services/touchbar.service.ts

@@ -1,6 +1,6 @@
 import { Injectable, Inject, NgZone } from '@angular/core'
 import { TouchBarSegmentedControl, SegmentedControlSegment } from 'electron'
-import { Subject, Subscription } from 'rxjs'
+import { Subscription } from 'rxjs'
 import { AppService } from './app.service'
 import { ConfigService } from './config.service'
 import { ElectronService } from './electron.service'
@@ -9,7 +9,6 @@ import { IToolbarButton, ToolbarButtonProvider } from '../api'
 
 @Injectable()
 export class TouchbarService {
-    tabSelected$ = new Subject<number>()
     private titleSubscriptions = new Map<BaseTabComponent, Subscription>()
     private tabsSegmentedControl: TouchBarSegmentedControl
     private tabSegments: SegmentedControlSegment[] = []

+ 2 - 2
terminus-terminal/src/api.ts

@@ -11,8 +11,8 @@ export abstract class TerminalDecorator {
 }
 
 export interface ResizeEvent {
-    width: number
-    height: number
+    columns: number
+    rows: number
 }
 
 export interface SessionOptions {

+ 10 - 7
terminus-terminal/src/components/terminalTab.component.ts

@@ -1,4 +1,4 @@
-import { Subject, Subscription } from 'rxjs'
+import { Observable, Subject, Subscription } from 'rxjs'
 import { first } from 'rxjs/operators'
 import { ToastrService } from 'ngx-toastr'
 import { Component, NgZone, Inject, Optional, ViewChild, HostBinding, Input } from '@angular/core'
@@ -33,14 +33,18 @@ export class TerminalTabComponent extends BaseTabComponent {
     termContainer: TermContainer
     sessionCloseSubscription: Subscription
     hotkeysSubscription: Subscription
-    size: ResizeEvent
-    output$ = new Subject<string>()
     htermVisible = false
     shell: IShell
+    private output = new Subject<string>()
     private bellPlayer: HTMLAudioElement
     private contextMenu: any
     private termContainerSubscriptions: Subscription[] = []
 
+    get input$ (): Observable<string> { return this.termContainer.input$ }
+    get output$ (): Observable<string> { return this.output }
+    get resize$ (): Observable<ResizeEvent> { return this.termContainer.resize$ }
+    get alternateScreenActive$ (): Observable<boolean> { return this.termContainer.alternateScreenActive$ }
+
     constructor (
         private zone: NgZone,
         private app: AppService,
@@ -129,7 +133,7 @@ export class TerminalTabComponent extends BaseTabComponent {
         // this.session.output$.bufferTime(10).subscribe((datas) => {
         this.session.output$.subscribe(data => {
             this.zone.run(() => {
-                this.output$.next(data)
+                this.output.next(data)
                 this.write(data)
             })
         })
@@ -181,7 +185,7 @@ export class TerminalTabComponent extends BaseTabComponent {
         })
 
         setTimeout(() => {
-            this.output$.subscribe(() => {
+            this.output.subscribe(() => {
                 this.displayActivity()
             })
         }, 1000)
@@ -278,7 +282,6 @@ export class TerminalTabComponent extends BaseTabComponent {
             this.termContainer.resize$.subscribe(({columns, rows}) => {
                 console.log(`Resizing to ${columns}x${rows}`)
                 this.zone.run(() => {
-                    this.size = { width: columns, height: rows }
                     if (this.session.open) {
                         this.session.resize(columns, rows)
                     }
@@ -341,7 +344,7 @@ export class TerminalTabComponent extends BaseTabComponent {
         if (this.sessionCloseSubscription) {
             this.sessionCloseSubscription.unsubscribe()
         }
-        this.output$.complete()
+        this.output.complete()
     }
 
     async destroy () {

+ 15 - 14
terminus-terminal/src/services/sessions.service.ts

@@ -20,32 +20,33 @@ export abstract class BaseSession {
     name: string
     recoveryId: string
     truePID: number
-    output$: Observable<string>
-    closed$: Observable<void>
-    destroyed$: Observable<void>
-    protected output_ = new Subject<string>()
-    protected closed_ = new Subject<void>()
-    protected destroyed_ = new Subject<void>()
+    protected output = new Subject<string>()
+    protected closed = new Subject<void>()
+    protected destroyed = new Subject<void>()
     private initialDataBuffer = ''
     private initialDataBufferReleased = false
 
+    get output$ (): Observable<string> { return this.output }
+    get closed$ (): Observable<void> { return this.closed }
+    get destroyed$ (): Observable<void> { return this.destroyed }
+
     constructor () {
-        this.output$ = this.output_.asObservable()
-        this.closed$ = this.closed_.asObservable()
-        this.destroyed$ = this.destroyed_.asObservable()
+        this.output$ = this.output.asObservable()
+        this.closed$ = this.closed.asObservable()
+        this.destroyed$ = this.destroyed.asObservable()
     }
 
     emitOutput (data: string) {
         if (!this.initialDataBufferReleased) {
             this.initialDataBuffer += data
         } else {
-            this.output_.next(data)
+            this.output.next(data)
         }
     }
 
     releaseInitialDataBuffer () {
         this.initialDataBufferReleased = true
-        this.output_.next(this.initialDataBuffer)
+        this.output.next(this.initialDataBuffer)
         this.initialDataBuffer = null
     }
 
@@ -60,9 +61,9 @@ export abstract class BaseSession {
     async destroy (): Promise<void> {
         if (this.open) {
             this.open = false
-            this.closed_.next()
-            this.destroyed_.next()
-            this.output_.complete()
+            this.closed.next()
+            this.destroyed.next()
+            this.output.complete()
             await this.gracefullyKillProcess()
         }
     }

+ 7 - 6
terminus-terminal/src/services/terminal.service.ts

@@ -7,10 +7,11 @@ import { TerminalTabComponent } from '../components/terminalTab.component'
 
 @Injectable()
 export class TerminalService {
-    shells$: Observable<IShell[]>
-    private shells_ = new AsyncSubject<IShell[]>()
+    private shells = new AsyncSubject<IShell[]>()
     private logger: Logger
 
+    get shells$ (): Observable<IShell[]> { return this.shells }
+
     constructor (
         private app: AppService,
         private sessions: SessionsService,
@@ -27,11 +28,11 @@ export class TerminalService {
     }
 
     async reloadShells () {
-        this.shells_ = new AsyncSubject<IShell[]>()
-        this.shells$ = this.shells_.asObservable()
+        this.shells = new AsyncSubject<IShell[]>()
+        this.shells$ = this.shells.asObservable()
         let shellLists = await Promise.all(this.config.enabledServices(this.shellProviders).map(x => x.provide()))
-        this.shells_.next(shellLists.reduce((a, b) => a.concat(b)))
-        this.shells_.complete()
+        this.shells.next(shellLists.reduce((a, b) => a.concat(b)))
+        this.shells.complete()
     }
 
     async openTab (shell?: IShell, cwd?: string): Promise<TerminalTabComponent> {

+ 3 - 2
terminus-terminal/src/terminalContainers/termContainer.ts

@@ -1,4 +1,5 @@
 import { Observable, Subject, AsyncSubject, ReplaySubject, BehaviorSubject } from 'rxjs'
+import { ResizeEvent } from '../api'
 
 export abstract class TermContainer {
     enableResizing = true
@@ -9,7 +10,7 @@ export abstract class TermContainer {
     protected bell = new Subject<void>()
     protected contentUpdated = new Subject<void>()
     protected input = new Subject<string>()
-    protected resize = new ReplaySubject<{columns: number, rows: number}>(1)
+    protected resize = new ReplaySubject<ResizeEvent>(1)
     protected dragOver = new Subject<DragEvent>()
     protected drop = new Subject<DragEvent>()
 
@@ -20,7 +21,7 @@ export abstract class TermContainer {
     get bell$ (): Observable<void> { return this.bell }
     get contentUpdated$ (): Observable<void> { return this.contentUpdated }
     get input$ (): Observable<string> { return this.input }
-    get resize$ (): Observable<{columns: number, rows: number}> { return this.resize }
+    get resize$ (): Observable<ResizeEvent> { return this.resize }
     get dragOver$ (): Observable<DragEvent> { return this.dragOver }
     get drop$ (): Observable<DragEvent> { return this.drop }