Skip to content

Commit

Permalink
Merge pull request #8416 from Clem-Fern/connectable-refactoring
Browse files Browse the repository at this point in the history
Refactoring connectable tab
  • Loading branch information
Eugeny committed May 16, 2023
2 parents a494d9c + 539ad0b commit fac6ec5
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 155 deletions.
50 changes: 11 additions & 39 deletions tabby-serial/src/components/serialTab.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
import colors from 'ansi-colors'
import { Component, Injector } from '@angular/core'
import { first } from 'rxjs'
import { GetRecoveryTokenOptions, Platform, SelectorService } from 'tabby-core'
import { BaseTerminalTabComponent, Reconnectable } from 'tabby-terminal'
import { Platform, SelectorService } from 'tabby-core'
import { BaseTerminalTabComponent, ConnectableTerminalTabComponent } from 'tabby-terminal'
import { SerialSession, BAUD_RATES, SerialProfile } from '../api'

/** @hidden */
Expand All @@ -14,7 +13,7 @@ import { SerialSession, BAUD_RATES, SerialProfile } from '../api'
styleUrls: ['./serialTab.component.scss', ...BaseTerminalTabComponent.styles],
animations: BaseTerminalTabComponent.animations,
})
export class SerialTabComponent extends BaseTerminalTabComponent<SerialProfile> implements Reconnectable {
export class SerialTabComponent extends ConnectableTerminalTabComponent<SerialProfile> {
session: SerialSession|null = null
Platform = Platform

Expand All @@ -28,8 +27,6 @@ export class SerialTabComponent extends BaseTerminalTabComponent<SerialProfile>
}

ngOnInit () {
this.logger = this.log.create('terminalTab')

this.subscribeUntilDestroyed(this.hotkeys.hotkey$, hotkey => {
if (!this.hasFocus) {
return
Expand All @@ -54,12 +51,9 @@ export class SerialTabComponent extends BaseTerminalTabComponent<SerialProfile>
})
}

protected onFrontendReady (): void {
this.initializeSession()
super.onFrontendReady()
}

async initializeSession () {
super.initializeSession()

const session = new SerialSession(this.injector, this.profile)
this.setSession(session)

Expand All @@ -82,38 +76,16 @@ export class SerialTabComponent extends BaseTerminalTabComponent<SerialProfile>
this.write(`\r\n${colors.black.bgWhite(' Serial ')} ${msg}\r\n`)
this.session?.resize(this.size.columns, this.size.rows)
})
this.attachSessionHandler(this.session!.destroyed$, () => {
if (this.frontend) {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgWhite(' SERIAL ') + ` session closed\r\n`)

if (this.profile.behaviorOnSessionEnd === 'reconnect') {
this.reconnect()
} else if (this.profile.behaviorOnSessionEnd === 'keep' || this.profile.behaviorOnSessionEnd === 'auto' && !this.isSessionExplicitlyTerminated()) {
this.write(this.translate.instant(_('Press any key to reconnect')) + '\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open) {
this.reconnect()
}
})
}
}
})
super.attachSessionHandlers()
}

async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise<any> {
return {
type: 'app:serial-tab',
profile: this.profile,
savedState: options?.includeState && this.frontend?.saveState(),
}
}
protected onSessionDestroyed (): void {
if (this.frontend) {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgWhite(' SERIAL ') + ` session closed\r\n`)

async reconnect (): Promise<void> {
this.session?.destroy()
await this.initializeSession()
this.session?.releaseInitialDataBuffer()
super.onSessionDestroyed()
}
}

async changeBaudRate () {
Expand Down
59 changes: 10 additions & 49 deletions tabby-ssh/src/components/sshTab.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
import colors from 'ansi-colors'
import { Component, Injector, HostListener } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { first } from 'rxjs'
import { GetRecoveryTokenOptions, Platform, ProfilesService, RecoveryToken } from 'tabby-core'
import { BaseTerminalTabComponent, Reconnectable } from 'tabby-terminal'
import { Platform, ProfilesService } from 'tabby-core'
import { BaseTerminalTabComponent, ConnectableTerminalTabComponent } from 'tabby-terminal'
import { SSHService } from '../services/ssh.service'
import { KeyboardInteractivePrompt, SSHSession } from '../session/ssh'
import { SSHPortForwardingModalComponent } from './sshPortForwardingModal.component'
Expand All @@ -22,15 +21,14 @@ import { SSHMultiplexerService } from '../services/sshMultiplexer.service'
],
animations: BaseTerminalTabComponent.animations,
})
export class SSHTabComponent extends BaseTerminalTabComponent<SSHProfile> implements Reconnectable {
export class SSHTabComponent extends ConnectableTerminalTabComponent<SSHProfile> {
Platform = Platform
sshSession: SSHSession|null = null
session: SSHShellSession|null = null
sftpPanelVisible = false
sftpPath = '/'
enableToolbar = true
activeKIPrompt: KeyboardInteractivePrompt|null = null
private reconnectOffered = false

constructor (
injector: Injector,
Expand All @@ -46,8 +44,6 @@ export class SSHTabComponent extends BaseTerminalTabComponent<SSHProfile> implem
}

ngOnInit (): void {
this.logger = this.log.create('terminalTab')

this.subscribeUntilDestroyed(this.hotkeys.hotkey$, hotkey => {
if (!this.hasFocus) {
return
Expand All @@ -73,11 +69,6 @@ export class SSHTabComponent extends BaseTerminalTabComponent<SSHProfile> implem
super.ngOnInit()
}

protected onFrontendReady (): void {
this.initializeSession()
super.onFrontendReady()
}

async setupOneSession (injector: Injector, profile: SSHProfile, multiplex = true): Promise<SSHSession> {
let session = await this.sshMultiplexer.getSession(profile)
if (!multiplex || !session || !profile.options.reuseSession) {
Expand Down Expand Up @@ -150,29 +141,13 @@ export class SSHTabComponent extends BaseTerminalTabComponent<SSHProfile> implem
return session
}

protected attachSessionHandlers (): void {
const session = this.session!
this.attachSessionHandler(session.destroyed$, () => {
if (this.frontend) {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgWhite(' SSH ') + ` ${this.sshSession?.profile.options.host}: session closed\r\n`)
protected onSessionDestroyed (): void {
if (this.frontend) {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgWhite(' SSH ') + ` ${this.sshSession?.profile.options.host}: session closed\r\n`)

if (this.profile.behaviorOnSessionEnd === 'reconnect') {
this.reconnect()
} else if (this.profile.behaviorOnSessionEnd === 'keep' || this.profile.behaviorOnSessionEnd === 'auto' && !this.isSessionExplicitlyTerminated()) {
if (!this.reconnectOffered) {
this.reconnectOffered = true
this.write(this.translate.instant(_('Press any key to reconnect')) + '\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open && this.reconnectOffered) {
this.reconnect()
}
})
}
}
}
})
super.attachSessionHandlers()
super.onSessionDestroyed()
}
}

private async initializeSessionMaybeMultiplex (multiplex = true): Promise<void> {
Expand All @@ -196,7 +171,7 @@ export class SSHTabComponent extends BaseTerminalTabComponent<SSHProfile> implem
}

async initializeSession (): Promise<void> {
this.reconnectOffered = false
await super.initializeSession()
try {
await this.initializeSessionMaybeMultiplex(true)
} catch {
Expand All @@ -209,25 +184,11 @@ export class SSHTabComponent extends BaseTerminalTabComponent<SSHProfile> implem
}
}

async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise<RecoveryToken> {
return {
type: 'app:ssh-tab',
profile: this.profile,
savedState: options?.includeState && this.frontend?.saveState(),
}
}

showPortForwarding (): void {
const modal = this.ngbModal.open(SSHPortForwardingModalComponent).componentInstance as SSHPortForwardingModalComponent
modal.session = this.sshSession!
}

async reconnect (): Promise<void> {
this.session?.destroy()
await this.initializeSession()
this.session?.releaseInitialDataBuffer()
}

async canClose (): Promise<boolean> {
if (!this.session?.open) {
return true
Expand Down
59 changes: 10 additions & 49 deletions tabby-telnet/src/components/telnetTab.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
import colors from 'ansi-colors'
import { Component, Injector } from '@angular/core'
import { first } from 'rxjs'
import { GetRecoveryTokenOptions, Platform, RecoveryToken } from 'tabby-core'
import { BaseTerminalTabComponent, Reconnectable } from 'tabby-terminal'
import { Platform } from 'tabby-core'
import { BaseTerminalTabComponent, ConnectableTerminalTabComponent } from 'tabby-terminal'
import { TelnetProfile, TelnetSession } from '../session'


Expand All @@ -14,10 +13,9 @@ import { TelnetProfile, TelnetSession } from '../session'
styleUrls: ['./telnetTab.component.scss', ...BaseTerminalTabComponent.styles],
animations: BaseTerminalTabComponent.animations,
})
export class TelnetTabComponent extends BaseTerminalTabComponent<TelnetProfile> implements Reconnectable {
export class TelnetTabComponent extends ConnectableTerminalTabComponent<TelnetProfile> {
Platform = Platform
session: TelnetSession|null = null
private reconnectOffered = false

// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor (
Expand All @@ -28,8 +26,6 @@ export class TelnetTabComponent extends BaseTerminalTabComponent<TelnetProfile>
}

ngOnInit (): void {
this.logger = this.log.create('telnetTab')

this.subscribeUntilDestroyed(this.hotkeys.hotkey$, hotkey => {
if (this.hasFocus && hotkey === 'restart-telnet-session') {
this.reconnect()
Expand All @@ -39,38 +35,17 @@ export class TelnetTabComponent extends BaseTerminalTabComponent<TelnetProfile>
super.ngOnInit()
}

protected onFrontendReady (): void {
this.initializeSession()
super.onFrontendReady()
}

protected attachSessionHandlers (): void {
const session = this.session!
this.attachSessionHandler(session.destroyed$, () => {
if (this.frontend) {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgWhite(' TELNET ') + ` ${this.session?.profile.options.host}: session closed\r\n`)
protected onSessionDestroyed (): void {
if (this.frontend) {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgWhite(' TELNET ') + ` ${this.session?.profile.options.host}: session closed\r\n`)

if (this.profile.behaviorOnSessionEnd === 'reconnect') {
this.reconnect()
} else if (this.profile.behaviorOnSessionEnd === 'keep' || this.profile.behaviorOnSessionEnd === 'auto' && !this.isSessionExplicitlyTerminated()) {
if (!this.reconnectOffered) {
this.reconnectOffered = true
this.write(this.translate.instant(_('Press any key to reconnect')) + '\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open && this.reconnectOffered) {
this.reconnect()
}
})
}
}
}
})
super.attachSessionHandlers()
super.onSessionDestroyed()
}
}

async initializeSession (): Promise<void> {
this.reconnectOffered = false
await super.initializeSession()

const session = new TelnetSession(this.injector, this.profile)
this.setSession(session)
Expand All @@ -96,20 +71,6 @@ export class TelnetTabComponent extends BaseTerminalTabComponent<TelnetProfile>
}
}

async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise<RecoveryToken> {
return {
type: 'app:telnet-tab',
profile: this.profile,
savedState: options?.includeState && this.frontend?.saveState(),
}
}

async reconnect (): Promise<void> {
this.session?.destroy()
await this.initializeSession()
this.session?.releaseInitialDataBuffer()
}

async canClose (): Promise<boolean> {
if (!this.session?.open) {
return true
Expand Down
16 changes: 9 additions & 7 deletions tabby-terminal/src/api/baseTerminalTab.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { BaseSession } from '../session'

import { Frontend } from '../frontends/frontend'
import { XTermFrontend, XTermWebGLFrontend } from '../frontends/xtermFrontend'
import { ResizeEvent, BaseTerminalProfile, isReconnectable } from './interfaces'
import { ResizeEvent, BaseTerminalProfile } from './interfaces'
import { TerminalDecorator } from './decorator'
import { SearchPanelComponent } from '../components/searchPanel.component'
import { MultifocusService } from '../services/multifocus.service'
Expand Down Expand Up @@ -312,11 +312,6 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
case 'scroll-to-bottom':
this.frontend?.scrollToBottom()
break
case 'reconnect-tab':
if (isReconnectable(this)) {
this.reconnect()
}
break
}
})

Expand Down Expand Up @@ -784,7 +779,7 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
})

this.attachSessionHandler(this.session.destroyed$, () => {
this.setSession(null)
this.onSessionDestroyed()
})

this.attachSessionHandler(this.session.oscProcessor.copyRequested$, content => {
Expand All @@ -793,6 +788,13 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
})
}

/**
* Method called when session is destroyed. Set the session to null
*/
protected onSessionDestroyed (): void {
this.setSession(null)
}

protected detachSessionHandlers (): void {
this.sessionHandlers.cancelAll()
}
Expand Down
Loading

0 comments on commit fac6ec5

Please sign in to comment.