fix: browser bug with plugins, and improve joining

This commit is contained in:
2026-05-04 23:35:40 +02:00
parent a49e18b9f0
commit 0f6cb3ee77
7 changed files with 264 additions and 27 deletions

View File

@@ -18,6 +18,8 @@ import {
} from 'rxjs';
import { NgIcon, provideIcons } from '@ng-icons/core';
import {
lucideExternalLink,
lucideFileText,
lucideSearch,
lucideUsers,
lucideLock,
@@ -39,6 +41,7 @@ import {
User,
type PluginRequirementSummary
} from '../../../../shared-kernel';
import { ExternalLinkService } from '../../../../core/platform';
import { SettingsModalService } from '../../../../core/services/settings-modal.service';
import { DatabaseService } from '../../../../infrastructure/persistence';
import { type ServerInfo } from '../../domain/models/server-directory.model';
@@ -49,10 +52,15 @@ import {
LeaveServerDialogComponent,
type LeaveServerDialogResult
} from '../../../../shared';
import { ChatMessageMarkdownComponent } from '../../../chat';
import { hasRoomBanForUser } from '../../../access-control';
import { UserSearchListComponent } from '../../../direct-message/feature/user-search-list/user-search-list.component';
import { RealtimeSessionFacade } from '../../../../core/realtime';
import { PluginRequirementService, PluginStoreService } from '../../../plugins';
import {
PluginRequirementService,
PluginStoreService,
type PluginStoreReadme
} from '../../../plugins';
interface JoinPluginConsentDialog {
optional: PluginRequirementSummary[];
@@ -68,12 +76,15 @@ interface JoinPluginConsentDialog {
CommonModule,
FormsModule,
NgIcon,
ChatMessageMarkdownComponent,
ConfirmDialogComponent,
LeaveServerDialogComponent,
UserSearchListComponent
],
viewProviders: [
provideIcons({
lucideExternalLink,
lucideFileText,
lucideSearch,
lucideUsers,
lucideLock,
@@ -94,6 +105,7 @@ export class ServerSearchComponent implements OnInit {
private router = inject(Router);
private settingsModal = inject(SettingsModalService);
private db = inject(DatabaseService);
private externalLinks = inject(ExternalLinkService);
private serverDirectory = inject(ServerDirectoryFacade);
private webrtc = inject(RealtimeSessionFacade);
private pluginRequirements = inject(PluginRequirementService);
@@ -122,6 +134,9 @@ export class ServerSearchComponent implements OnInit {
selectedOptionalPluginIds = signal<Set<string>>(new Set());
pluginConsentBusy = signal(false);
pluginConsentError = signal<string | null>(null);
pluginConsentReadme = signal<PluginStoreReadme | null>(null);
pluginConsentReadmeLoadingId = signal<string | null>(null);
pluginConsentReadmeError = signal<string | null>(null);
// Create dialog state
showCreateDialog = signal(false);
@@ -306,6 +321,7 @@ export class ServerSearchComponent implements OnInit {
this.pluginConsentDialog.set(null);
this.selectedOptionalPluginIds.set(new Set());
this.pluginConsentError.set(null);
this.closePluginConsentReadme();
}
toggleOptionalPluginInstall(pluginId: string, checked: boolean): void {
@@ -345,6 +361,7 @@ export class ServerSearchComponent implements OnInit {
this.pluginConsentDialog.set(null);
this.selectedOptionalPluginIds.set(new Set());
this.closePluginConsentReadme();
} catch (error) {
this.pluginConsentError.set(error instanceof Error ? error.message : 'Unable to install server plugins');
} finally {
@@ -352,6 +369,45 @@ export class ServerSearchComponent implements OnInit {
}
}
async openPluginConsentReadme(requirement: PluginRequirementSummary): Promise<void> {
this.pluginConsentReadmeError.set(null);
this.pluginConsentReadmeLoadingId.set(requirement.pluginId);
try {
const readme = await this.pluginStore.loadRequirementReadme(requirement);
this.pluginConsentReadme.set(readme);
} catch (error) {
this.pluginConsentReadmeError.set(error instanceof Error ? error.message : 'Unable to load plugin readme');
} finally {
this.pluginConsentReadmeLoadingId.set(null);
}
}
closePluginConsentReadme(): void {
this.pluginConsentReadme.set(null);
this.pluginConsentReadmeError.set(null);
this.pluginConsentReadmeLoadingId.set(null);
}
openPluginSource(requirement: PluginRequirementSummary): void {
const sourceUrl = this.getPluginSourceUrl(requirement);
if (sourceUrl) {
this.externalLinks.open(sourceUrl);
}
}
getPluginSourceUrl(requirement: PluginRequirementSummary): string | null {
const candidate = requirement.manifest?.homepage ?? requirement.sourceUrl ?? requirement.installUrl ?? requirement.manifest?.bugs ?? null;
return candidate?.startsWith('http://') || candidate?.startsWith('https://') ? candidate : null;
}
hasPluginReadme(requirement: PluginRequirementSummary): boolean {
return !!requirement.manifest?.readme;
}
async confirmPasswordJoin(): Promise<void> {
const server = this.passwordPromptServer();