From 23e93f096984edbe2b473ffa2781cdd7990b3fa7 Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Thu, 9 Aug 2018 12:37:14 -0700 Subject: [PATCH] rxjs cleanup --- .../src/components/baseTab.component.ts | 27 +++++++++---- terminus-core/src/services/app.service.ts | 39 +++++++++++-------- terminus-core/src/services/config.service.ts | 8 ++-- terminus-core/src/services/hostApp.service.ts | 30 ++++++++------ .../src/services/touchbar.service.ts | 3 +- terminus-terminal/src/api.ts | 4 +- .../src/components/terminalTab.component.ts | 17 ++++---- .../src/services/sessions.service.ts | 29 +++++++------- .../src/services/terminal.service.ts | 13 ++++--- .../src/terminalContainers/termContainer.ts | 5 ++- 10 files changed, 105 insertions(+), 70 deletions(-) diff --git a/terminus-core/src/components/baseTab.component.ts b/terminus-core/src/components/baseTab.component.ts index 04bec98b..f48b5ed7 100644 --- a/terminus-core/src/components/baseTab.component.ts +++ b/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() customTitle: string hasActivity = false - focused$ = new Subject() - blurred$ = new Subject() hasFocus = false hostView: ViewRef + protected titleChange = new Subject() + protected focused = new Subject() + protected blurred = new Subject() + + get focused$ (): Observable { return this.focused } + get blurred$ (): Observable { return this.blurred } + get titleChange$ (): Observable { 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() } } diff --git a/terminus-core/src/services/app.service.ts b/terminus-core/src/services/app.service.ts index 03c45304..5b678233 100644 --- a/terminus-core/src/services/app.service.ts +++ b/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() lastTabIndex = 0 logger: Logger - tabsChanged$ = new Subject() - tabOpened$ = new Subject() - tabClosed$ = new Subject() - ready$ = new AsyncSubject() + + private activeTabChange = new Subject() + private tabsChanged = new Subject() + private tabOpened = new Subject() + private tabClosed = new Subject() + private ready = new AsyncSubject() + + get activeTabChange$ (): Observable { return this.activeTabChange } + get tabOpened$ (): Observable { return this.tabOpened } + get tabsChanged$ (): Observable { return this.tabsChanged } + get tabClosed$ (): Observable { return this.tabClosed } + get ready$ (): Observable { 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 { @@ -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() } } diff --git a/terminus-core/src/services/config.service.ts b/terminus-core/src/services/config.service.ts index ea421d2a..5912003c 100644 --- a/terminus-core/src/services/config.service.ts +++ b/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() restartRequested: boolean + private changed = new Subject() private _store: any private path: string private defaults: any private servicesCache: { [id: string]: Function[] } = null + get changed$ (): Observable { 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 { diff --git a/terminus-core/src/services/hostApp.service.ts b/terminus-core/src/services/hostApp.service.ts index 44435be7..90b2788d 100644 --- a/terminus-core/src/services/hostApp.service.ts +++ b/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() ready = new EventEmitter() shown = new EventEmitter() - secondInstance$ = new Subject<{ argv: string[], cwd: string }>() isFullScreen = false + private preferencesMenu = new Subject() + private secondInstance = new Subject() private logger: Logger + get preferencesMenu$ (): Observable { return this.preferencesMenu } + get secondInstance$ (): Observable { 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 () { diff --git a/terminus-core/src/services/touchbar.service.ts b/terminus-core/src/services/touchbar.service.ts index c8ebafda..b98a64ee 100644 --- a/terminus-core/src/services/touchbar.service.ts +++ b/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() private titleSubscriptions = new Map() private tabsSegmentedControl: TouchBarSegmentedControl private tabSegments: SegmentedControlSegment[] = [] diff --git a/terminus-terminal/src/api.ts b/terminus-terminal/src/api.ts index 9e238ad8..9ceca5f1 100644 --- a/terminus-terminal/src/api.ts +++ b/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 { diff --git a/terminus-terminal/src/components/terminalTab.component.ts b/terminus-terminal/src/components/terminalTab.component.ts index 3185487a..e1469a38 100644 --- a/terminus-terminal/src/components/terminalTab.component.ts +++ b/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() htermVisible = false shell: IShell + private output = new Subject() private bellPlayer: HTMLAudioElement private contextMenu: any private termContainerSubscriptions: Subscription[] = [] + get input$ (): Observable { return this.termContainer.input$ } + get output$ (): Observable { return this.output } + get resize$ (): Observable { return this.termContainer.resize$ } + get alternateScreenActive$ (): Observable { 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 () { diff --git a/terminus-terminal/src/services/sessions.service.ts b/terminus-terminal/src/services/sessions.service.ts index dfdc26e7..ca6f3afa 100644 --- a/terminus-terminal/src/services/sessions.service.ts +++ b/terminus-terminal/src/services/sessions.service.ts @@ -20,32 +20,33 @@ export abstract class BaseSession { name: string recoveryId: string truePID: number - output$: Observable - closed$: Observable - destroyed$: Observable - protected output_ = new Subject() - protected closed_ = new Subject() - protected destroyed_ = new Subject() + protected output = new Subject() + protected closed = new Subject() + protected destroyed = new Subject() private initialDataBuffer = '' private initialDataBufferReleased = false + get output$ (): Observable { return this.output } + get closed$ (): Observable { return this.closed } + get destroyed$ (): Observable { 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 { 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() } } diff --git a/terminus-terminal/src/services/terminal.service.ts b/terminus-terminal/src/services/terminal.service.ts index 9392a508..7b5ad4fb 100644 --- a/terminus-terminal/src/services/terminal.service.ts +++ b/terminus-terminal/src/services/terminal.service.ts @@ -7,10 +7,11 @@ import { TerminalTabComponent } from '../components/terminalTab.component' @Injectable() export class TerminalService { - shells$: Observable - private shells_ = new AsyncSubject() + private shells = new AsyncSubject() private logger: Logger + get shells$ (): Observable { return this.shells } + constructor ( private app: AppService, private sessions: SessionsService, @@ -27,11 +28,11 @@ export class TerminalService { } async reloadShells () { - this.shells_ = new AsyncSubject() - this.shells$ = this.shells_.asObservable() + this.shells = new AsyncSubject() + 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 { diff --git a/terminus-terminal/src/terminalContainers/termContainer.ts b/terminus-terminal/src/terminalContainers/termContainer.ts index 0791fc45..0eba8e62 100644 --- a/terminus-terminal/src/terminalContainers/termContainer.ts +++ b/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() protected contentUpdated = new Subject() protected input = new Subject() - protected resize = new ReplaySubject<{columns: number, rows: number}>(1) + protected resize = new ReplaySubject(1) protected dragOver = new Subject() protected drop = new Subject() @@ -20,7 +21,7 @@ export abstract class TermContainer { get bell$ (): Observable { return this.bell } get contentUpdated$ (): Observable { return this.contentUpdated } get input$ (): Observable { return this.input } - get resize$ (): Observable<{columns: number, rows: number}> { return this.resize } + get resize$ (): Observable { return this.resize } get dragOver$ (): Observable { return this.dragOver } get drop$ (): Observable { return this.drop }