From db3bb4016f954b640ff9302f8b8fe415ebb464ba Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 16 Apr 2026 18:59:45 +0200 Subject: [PATCH] fix(plugins): load community plugins via static import (#7149) Replaces runtime HttpClient fetch of assets/community-plugins.json with a TypeScript JSON import. The XHR to file:// inside the Electron ASAR could fail with "Http failure during parsing", surfacing an error snack bar on every visit to the plugin settings. Static import bundles the data at build time and eliminates the failure path entirely. --- .../plugin-management.component.ts | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/app/plugins/ui/plugin-management/plugin-management.component.ts b/src/app/plugins/ui/plugin-management/plugin-management.component.ts index e1970b95aa..e696e69940 100644 --- a/src/app/plugins/ui/plugin-management/plugin-management.component.ts +++ b/src/app/plugins/ui/plugin-management/plugin-management.component.ts @@ -5,8 +5,6 @@ import { inject, signal, } from '@angular/core'; -import { toSignal } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; import { PluginService } from '../../plugin.service'; import { PluginInstance } from '../../plugin-api.model'; import { PluginMetaPersistenceService } from '../../plugin-meta-persistence.service'; @@ -34,15 +32,14 @@ import { PluginIconComponent } from '../plugin-icon/plugin-icon.component'; import { PluginConfigDialogComponent } from '../plugin-config-dialog/plugin-config-dialog.component'; import { IS_ELECTRON } from '../../../app.constants'; import { PluginLog } from '../../../core/log'; -import { SnackService } from '../../../core/snack/snack.service'; import { PluginBridgeService } from '../../plugin-bridge.service'; -import { catchError, of } from 'rxjs'; import { CollapsibleComponent } from '../../../ui/collapsible/collapsible.component'; import { LanguageCode } from '../../../core/locale.constants'; import { GlobalConfigService } from '../../../features/config/global-config.service'; import { confirmDialog } from '../../../util/native-dialogs'; import { Store } from '@ngrx/store'; import { selectAll as selectAllIssueProviders } from '../../../features/issue/store/issue-provider.selectors'; +import COMMUNITY_PLUGINS_DATA from '../../../../assets/community-plugins.json'; interface CommunityPlugin { name: string; @@ -83,8 +80,6 @@ export class PluginManagementComponent { private readonly _translateService = inject(TranslateService); private readonly _globalConfigService = inject(GlobalConfigService); private readonly _dialog = inject(MatDialog); - private readonly _http = inject(HttpClient); - private readonly _snackService = inject(SnackService); private readonly _store = inject(Store); private readonly _pluginBridge = inject(PluginBridgeService); private readonly _allIssueProviders = this._store.selectSignal(selectAllIssueProviders); @@ -122,18 +117,8 @@ export class PluginManagementComponent { } as const; /* eslint-enable @typescript-eslint/naming-convention */ - readonly communityPlugins = toSignal( - this._http.get('assets/community-plugins.json').pipe( - catchError((err) => { - PluginLog.err('Failed to load community plugins:', err); - this._snackService.open({ - type: 'ERROR', - msg: T.PLUGINS.FAILED_TO_LOAD_COMMUNITY_PLUGINS, - }); - return of([] as CommunityPlugin[]); - }), - ), - { initialValue: [] }, + readonly communityPlugins = signal( + COMMUNITY_PLUGINS_DATA as CommunityPlugin[], ); T: typeof T = T;