/
githubmirror
/
tabby
Обзор
Документация
Войти
/
githubmirror
/
tabby
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
tabby-plugin-manager/src/components/pluginsSettingsTab.component.ts
166 строк
6 KB
Eugene
clean up the plugin manager
13 июл 2026, 11:41
Не верифицирован
13 июл 2026, 11:41
d33ba48
Код
Авторство
О чём код?
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker' import { BehaviorSubject, Observable, debounceTime, distinctUntilChanged, first, tap, switchMap, map } from 'rxjs' import semverGt from 'semver/functions/gt' import { Component, HostBinding, Input } from '@angular/core' import { ConfigService, PlatformService, PluginInfo } from 'tabby-core' import { PluginManagerService } from '../services/pluginManager.service' enum BusyState { Installing = 'Installing', Uninstalling = 'Uninstalling' } const FORCE_ENABLE = ['tabby-core', 'tabby-settings', 'tabby-electron', 'tabby-web', 'tabby-plugin-manager'] _('Search plugins') /** @hidden */ @Component({ templateUrl: './pluginsSettingsTab.component.pug', styleUrls: ['./pluginsSettingsTab.component.scss'], }) export class PluginsSettingsTabComponent { BusyState = BusyState @Input() availablePlugins$: Observable<PluginInfo[]> @Input() availablePluginsQuery$ = new BehaviorSubject<string>('') @Input() availablePluginsReady = false @Input() installedPluginsQuery$ = new BehaviorSubject<string>('') @Input() knownUpgrades: Record<string, PluginInfo|null> = {} @Input() busy = new Map<string, BusyState>() @Input() erroredPlugin: string @Input() errorMessage: string @HostBinding('class.content-box') true installedPlugins$: PluginInfo[] = [] installedFilter = '' availableFilter = '' constructor ( private config: ConfigService, private platform: PlatformService, public pluginManager: PluginManagerService, ) { } ngOnInit () { this.availablePlugins$ = this.availablePluginsQuery$ .asObservable() .pipe( debounceTime(200), distinctUntilChanged(), switchMap(query => { this.availablePluginsReady = false return this.pluginManager.listAvailable(query).pipe(tap(() => { this.availablePluginsReady = true })) }), ) this.availablePlugins$.pipe(first(), map((plugins: PluginInfo[]) => { plugins.sort((a, b) => a.name > b.name ? 1 : -1) return plugins })).subscribe(available => { for (const plugin of this.pluginManager.installedPlugins) { this.knownUpgrades[plugin.name] = available.find(x => x.name === plugin.name && semverGt(x.version, plugin.version)) ?? null } }) this.installedPluginsQuery$ .asObservable() .pipe( debounceTime(200), distinctUntilChanged(), switchMap(query => { return this.pluginManager.listInstalled(query) }), ).subscribe(plugin => { this.installedPlugins$ = plugin }) } openPluginsFolder (): void { this.platform.openPath(this.pluginManager.userPluginsPath) } searchAvailable (query: string) { this.availablePluginsQuery$.next(query) } searchInstalled (query: string) { this.installedPluginsQuery$.next(query) } isAlreadyInstalled (plugin: PluginInfo): boolean { return this.pluginManager.installedPlugins.some(x => x.name === plugin.name) } async installPlugin (plugin: PluginInfo): Promise<void> { this.busy.set(plugin.name, BusyState.Installing) try { await this.pluginManager.installPlugin(plugin) this.busy.delete(plugin.name) this.config.requestRestart() } catch (err) { console.error('Error installing plugin', plugin.name, err) this.erroredPlugin = plugin.name this.errorMessage = err this.busy.delete(plugin.name) throw err } } async uninstallPlugin (plugin: PluginInfo): Promise<void> { this.busy.set(plugin.name, BusyState.Uninstalling) try { await this.pluginManager.uninstallPlugin(plugin) this.busy.delete(plugin.name) this.config.requestRestart() } catch (err) { console.error('Error uninstalling plugin', plugin.name, err) this.erroredPlugin = plugin.name this.errorMessage = err this.busy.delete(plugin.name) throw err } } async upgradePlugin (plugin: PluginInfo): Promise<void> { await this.installPlugin(this.knownUpgrades[plugin.name]!) this.knownUpgrades[plugin.name] = null } showPluginInfo (plugin: PluginInfo) { this.platform.openExternal('https://www.npmjs.com/package/' + plugin.packageName) } showPluginHomepage (plugin: PluginInfo) { this.platform.openExternal(plugin.homepage ?? '') } isPluginEnabled (plugin: PluginInfo) { return !this.config.store.pluginBlacklist.includes(plugin.name) } canDisablePlugin (plugin: PluginInfo) { return !FORCE_ENABLE.includes(plugin.packageName) } togglePlugin (plugin: PluginInfo) { if (this.isPluginEnabled(plugin)) { this.disablePlugin(plugin) } else { this.enablePlugin(plugin) } } enablePlugin (plugin: PluginInfo) { this.config.store.pluginBlacklist = this.config.store.pluginBlacklist.filter(x => x !== plugin.name) this.config.save() this.config.requestRestart() } disablePlugin (plugin: PluginInfo) { this.config.store.pluginBlacklist = [...this.config.store.pluginBlacklist, plugin.name] this.config.save() this.config.requestRestart() } }