mirror of
https://github.com/Eugeny/tabby.git
synced 2025-06-19 02:49:56 +00:00
203 lines
5.3 KiB
TypeScript
203 lines
5.3 KiB
TypeScript
import { Observable, Subject } from 'rxjs'
|
|
import { EmbeddedViewRef, ViewContainerRef, ViewRef } from '@angular/core'
|
|
import { RecoveryToken } from '../api/tabRecovery'
|
|
import { BaseComponent } from './base.component'
|
|
|
|
/**
|
|
* Represents an active "process" inside a tab,
|
|
* for example, a user process running inside a terminal tab
|
|
*/
|
|
export interface BaseTabProcess {
|
|
name: string
|
|
}
|
|
|
|
/**
|
|
* Abstract base class for custom tab components
|
|
*/
|
|
export abstract class BaseTabComponent extends BaseComponent {
|
|
/**
|
|
* Parent tab (usually a SplitTabComponent)
|
|
*/
|
|
parent: BaseTabComponent|null = null
|
|
|
|
/**
|
|
* Current tab title
|
|
*/
|
|
title: string
|
|
|
|
/**
|
|
* User-defined title override
|
|
*/
|
|
customTitle: string
|
|
|
|
/**
|
|
* Last tab activity state
|
|
*/
|
|
hasActivity = false
|
|
|
|
/**
|
|
* ViewRef to the tab DOM element
|
|
*/
|
|
hostView: ViewRef
|
|
|
|
/**
|
|
* CSS color override for the tab's header
|
|
*/
|
|
color: string|null = null
|
|
|
|
hasFocus = false
|
|
|
|
/**
|
|
* Ping this if your recovery state has been changed and you want
|
|
* your tab state to be saved sooner
|
|
*/
|
|
protected recoveryStateChangedHint = new Subject<void>()
|
|
protected viewContainer?: ViewContainerRef
|
|
|
|
/* @hidden */
|
|
viewContainerEmbeddedRef?: EmbeddedViewRef<any>
|
|
|
|
private progressClearTimeout: number
|
|
private titleChange = new Subject<string>()
|
|
private focused = new Subject<void>()
|
|
private blurred = new Subject<void>()
|
|
private progress = new Subject<number|null>()
|
|
private activity = new Subject<boolean>()
|
|
private destroyed = new Subject<void>()
|
|
|
|
private _destroyCalled = false
|
|
|
|
get focused$ (): Observable<void> { return this.focused }
|
|
get blurred$ (): Observable<void> { return this.blurred }
|
|
get titleChange$ (): Observable<string> { return this.titleChange }
|
|
get progress$ (): Observable<number|null> { return this.progress }
|
|
get activity$ (): Observable<boolean> { return this.activity }
|
|
get destroyed$ (): Observable<void> { return this.destroyed }
|
|
get recoveryStateChangedHint$ (): Observable<void> { return this.recoveryStateChangedHint }
|
|
|
|
protected constructor () {
|
|
super()
|
|
this.focused$.subscribe(() => {
|
|
this.hasFocus = true
|
|
})
|
|
this.blurred$.subscribe(() => {
|
|
this.hasFocus = false
|
|
})
|
|
}
|
|
|
|
setTitle (title: string): void {
|
|
this.title = title
|
|
if (!this.customTitle) {
|
|
this.titleChange.next(title)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets visual progressbar on the tab
|
|
*
|
|
* @param {type} progress: value between 0 and 1, or `null` to remove
|
|
*/
|
|
setProgress (progress: number|null): void {
|
|
this.progress.next(progress)
|
|
if (progress) {
|
|
if (this.progressClearTimeout) {
|
|
clearTimeout(this.progressClearTimeout)
|
|
}
|
|
this.progressClearTimeout = setTimeout(() => {
|
|
this.setProgress(null)
|
|
}, 5000) as any
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Shows the acticity marker on the tab header
|
|
*/
|
|
displayActivity (): void {
|
|
this.hasActivity = true
|
|
this.activity.next(true)
|
|
}
|
|
|
|
/**
|
|
* Removes the acticity marker from the tab header
|
|
*/
|
|
clearActivity (): void {
|
|
this.hasActivity = false
|
|
this.activity.next(false)
|
|
}
|
|
|
|
/**
|
|
* Override this and implement a [[TabRecoveryProvider]] to enable recovery
|
|
* for your custom tab
|
|
*
|
|
* @return JSON serializable tab state representation
|
|
* for your [[TabRecoveryProvider]] to parse
|
|
*/
|
|
async getRecoveryToken (): Promise<RecoveryToken|null> {
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Override this to enable task completion notifications for the tab
|
|
*/
|
|
async getCurrentProcess (): Promise<BaseTabProcess|null> {
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Return false to prevent the tab from being closed
|
|
*/
|
|
async canClose (): Promise<boolean> {
|
|
return true
|
|
}
|
|
|
|
emitFocused (): void {
|
|
this.focused.next()
|
|
}
|
|
|
|
emitBlurred (): void {
|
|
this.blurred.next()
|
|
}
|
|
|
|
insertIntoContainer (container: ViewContainerRef): EmbeddedViewRef<any> {
|
|
this.viewContainerEmbeddedRef = container.insert(this.hostView) as EmbeddedViewRef<any>
|
|
this.viewContainer = container
|
|
return this.viewContainerEmbeddedRef
|
|
}
|
|
|
|
removeFromContainer (): void {
|
|
if (!this.viewContainer || !this.viewContainerEmbeddedRef) {
|
|
return
|
|
}
|
|
this.viewContainer.detach(this.viewContainer.indexOf(this.viewContainerEmbeddedRef))
|
|
this.viewContainerEmbeddedRef = undefined
|
|
this.viewContainer = undefined
|
|
}
|
|
|
|
/**
|
|
* Called before the tab is closed
|
|
*/
|
|
destroy (skipDestroyedEvent = false): void {
|
|
if (this._destroyCalled) {
|
|
return
|
|
}
|
|
this._destroyCalled = true
|
|
this.focused.complete()
|
|
this.blurred.complete()
|
|
this.titleChange.complete()
|
|
this.progress.complete()
|
|
this.activity.complete()
|
|
this.recoveryStateChangedHint.complete()
|
|
if (!skipDestroyedEvent) {
|
|
this.destroyed.next()
|
|
}
|
|
this.destroyed.complete()
|
|
this.hostView.destroy()
|
|
}
|
|
|
|
/** @hidden */
|
|
ngOnDestroy (): void {
|
|
this.destroy()
|
|
super.ngOnDestroy()
|
|
}
|
|
}
|