fix: restore build and stabilize E2E cross-signal behavior
Revert the automated member-ordering pass that broke Angular field init (TS2729) and disable that rule until a safe reorder strategy exists. Fix modal/confirm dialog i18n defaults via template fallbacks, search all active endpoints (including offline), register foreign rooms with actor owner IDs, sync profile display names from avatar summaries, and guard dm-chat when a private call converts to a group conversation. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
import {
|
||||
Component,
|
||||
effect,
|
||||
@@ -114,19 +115,28 @@ export interface ServerDiscoverySection {
|
||||
templateUrl: './server-browser.component.html'
|
||||
})
|
||||
export class ServerBrowserComponent implements OnInit {
|
||||
private store = inject(Store);
|
||||
private router = inject(Router);
|
||||
private db = inject(DatabaseService);
|
||||
private externalLinks = inject(ExternalLinkService);
|
||||
private serverDirectory = inject(ServerDirectoryFacade);
|
||||
private webrtc = inject(RealtimeSessionFacade);
|
||||
private pluginRequirements = inject(PluginRequirementService);
|
||||
private pluginStore = inject(PluginStoreService);
|
||||
private injector = inject(Injector);
|
||||
private readonly i18n = inject(AppI18nService);
|
||||
private readonly signalServerAuthorize = inject(SignalServerAuthorizeService);
|
||||
private searchSubject = new Subject<string>();
|
||||
private banLookupRequestVersion = 0;
|
||||
|
||||
/** Discovery sections shown when the search query is empty. */
|
||||
@Input() discoverySections: ServerDiscoverySection[] = [];
|
||||
|
||||
/** Title for the onboarding empty state when there is nothing to show. */
|
||||
@Input() emptyStateTitle?: string;
|
||||
|
||||
/** Supporting copy for the onboarding empty state. */
|
||||
@Input() emptyStateMessage?: string;
|
||||
|
||||
/** Placeholder for the search input. */
|
||||
@Input() searchPlaceholder?: string;
|
||||
|
||||
/** Whether the My Servers quick bar is shown. */
|
||||
@Input() showMyServers = true;
|
||||
|
||||
@@ -142,95 +152,6 @@ export class ServerBrowserComponent implements OnInit {
|
||||
return this.searchPlaceholder ?? this.i18n.instant('servers.browser.search.placeholder');
|
||||
}
|
||||
|
||||
searchQuery = '';
|
||||
|
||||
searchResults = this.store.selectSignal(selectSearchResults);
|
||||
|
||||
isSearching = this.store.selectSignal(selectIsSearching);
|
||||
|
||||
error = this.store.selectSignal(selectRoomsError);
|
||||
|
||||
savedRooms = this.store.selectSignal(selectSavedRooms);
|
||||
|
||||
currentUser = this.store.selectSignal(selectCurrentUser);
|
||||
|
||||
activeEndpoints = this.serverDirectory.activeServers;
|
||||
|
||||
bannedServerLookup = signal<Record<string, boolean>>({});
|
||||
|
||||
bannedServerName = signal('');
|
||||
|
||||
showBannedDialog = signal(false);
|
||||
|
||||
showPasswordDialog = signal(false);
|
||||
|
||||
passwordPromptServer = signal<ServerInfo | null>(null);
|
||||
|
||||
joinPassword = signal('');
|
||||
|
||||
joinPasswordError = signal<string | null>(null);
|
||||
|
||||
joinErrorMessage = signal<string | null>(null);
|
||||
|
||||
joinedServerMenuId = signal<string | null>(null);
|
||||
|
||||
leaveDialogRoom = signal<Room | null>(null);
|
||||
|
||||
pluginConsentDialog = signal<JoinPluginConsentDialog | null>(null);
|
||||
|
||||
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);
|
||||
|
||||
/** True while the user is actively searching (non-empty query). */
|
||||
get isSearchMode(): boolean {
|
||||
return this.searchQuery.trim().length > 0;
|
||||
}
|
||||
|
||||
/** Discovery sections that actually contain servers. */
|
||||
get visibleSections(): ServerDiscoverySection[] {
|
||||
return this.discoverySections.filter((section) => section.servers.length > 0);
|
||||
}
|
||||
|
||||
/** True when there is nothing to render outside of search mode. */
|
||||
get showEmptyState(): boolean {
|
||||
return !this.isSearchMode && this.visibleSections.length === 0;
|
||||
}
|
||||
|
||||
private store = inject(Store);
|
||||
|
||||
private router = inject(Router);
|
||||
|
||||
private db = inject(DatabaseService);
|
||||
|
||||
private externalLinks = inject(ExternalLinkService);
|
||||
|
||||
private serverDirectory = inject(ServerDirectoryFacade);
|
||||
|
||||
private webrtc = inject(RealtimeSessionFacade);
|
||||
|
||||
private pluginRequirements = inject(PluginRequirementService);
|
||||
|
||||
private pluginStore = inject(PluginStoreService);
|
||||
|
||||
private injector = inject(Injector);
|
||||
|
||||
private readonly i18n = inject(AppI18nService);
|
||||
|
||||
private readonly signalServerAuthorize = inject(SignalServerAuthorizeService);
|
||||
|
||||
private searchSubject = new Subject<string>();
|
||||
|
||||
private banLookupRequestVersion = 0;
|
||||
|
||||
serverCardTitle(server: ServerInfo): string {
|
||||
return this.isJoinedServer(server)
|
||||
? this.i18n.instant('servers.browser.card.doubleClickOpen', { name: server.name })
|
||||
@@ -279,6 +200,31 @@ export class ServerBrowserComponent implements OnInit {
|
||||
: this.i18n.instant('servers.plugins.readme');
|
||||
}
|
||||
|
||||
searchQuery = '';
|
||||
searchResults = this.store.selectSignal(selectSearchResults);
|
||||
isSearching = this.store.selectSignal(selectIsSearching);
|
||||
error = this.store.selectSignal(selectRoomsError);
|
||||
savedRooms = this.store.selectSignal(selectSavedRooms);
|
||||
currentUser = this.store.selectSignal(selectCurrentUser);
|
||||
activeEndpoints = this.serverDirectory.activeServers;
|
||||
bannedServerLookup = signal<Record<string, boolean>>({});
|
||||
bannedServerName = signal('');
|
||||
showBannedDialog = signal(false);
|
||||
showPasswordDialog = signal(false);
|
||||
passwordPromptServer = signal<ServerInfo | null>(null);
|
||||
joinPassword = signal('');
|
||||
joinPasswordError = signal<string | null>(null);
|
||||
joinErrorMessage = signal<string | null>(null);
|
||||
joinedServerMenuId = signal<string | null>(null);
|
||||
leaveDialogRoom = signal<Room | null>(null);
|
||||
pluginConsentDialog = signal<JoinPluginConsentDialog | null>(null);
|
||||
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);
|
||||
|
||||
// The reactive effect is created in ngOnInit with an explicit injector so the
|
||||
// component can be instantiated outside a change-detection context (e.g. unit tests).
|
||||
ngOnInit(): void {
|
||||
@@ -301,6 +247,21 @@ export class ServerBrowserComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
/** True while the user is actively searching (non-empty query). */
|
||||
get isSearchMode(): boolean {
|
||||
return this.searchQuery.trim().length > 0;
|
||||
}
|
||||
|
||||
/** Discovery sections that actually contain servers. */
|
||||
get visibleSections(): ServerDiscoverySection[] {
|
||||
return this.discoverySections.filter((section) => section.servers.length > 0);
|
||||
}
|
||||
|
||||
/** True when there is nothing to render outside of search mode. */
|
||||
get showEmptyState(): boolean {
|
||||
return !this.isSearchMode && this.visibleSections.length === 0;
|
||||
}
|
||||
|
||||
onSearchChange(query: string): void {
|
||||
this.searchSubject.next(query);
|
||||
}
|
||||
@@ -763,5 +724,4 @@ export class ServerBrowserComponent implements OnInit {
|
||||
|
||||
return hasRoomBanForUser(bans, currentUser, currentUserId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user