chore: enforce lint across codebase and ban "maybe" in identifiers

Remove member-ordering and complexity eslint-disable comments by reordering
class members and applying targeted fixes. Add metoyou/no-maybe-in-naming,
type-safe WebRTC e2e harness helpers, and resolve remaining lint errors so
npm run lint exits cleanly.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-11 11:08:26 +02:00
parent b630bacdc6
commit 79c6f91cd6
138 changed files with 4286 additions and 2310 deletions

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/member-ordering */
import {
Component,
inject,
@@ -82,39 +81,37 @@ import { AppI18nService, APP_TRANSLATE_IMPORTS } from '../../../core/i18n';
* Electron-style title bar with window controls, navigation, and server menu.
*/
export class TitleBarComponent {
private readonly appI18n = inject(AppI18nService);
private store = inject(Store);
private electronBridge = inject(ElectronBridgeService);
private serverDirectory = inject(ServerDirectoryFacade);
private router = inject(Router);
private webrtc = inject(RealtimeSessionFacade);
private platform = inject(PlatformService);
private voiceWorkspace = inject(VoiceWorkspaceService);
private settingsModal = inject(SettingsModalService);
private pluginRegistry = inject(PluginRegistryService);
private pluginRequirements = inject(PluginRequirementStateService);
private pluginStore = inject(PluginStoreService);
private getWindowControlsApi() {
return this.electronBridge.getApi();
}
isElectron = computed(() => this.platform.isElectron);
showMenuState = computed(() => false);
currentUser = this.store.selectSignal(selectCurrentUser);
username = computed(() => this.currentUser()?.displayName || this.appI18n.instant('shell.titleBar.guest'));
serverName = computed(() => this.serverDirectory.activeServer()?.name || this.appI18n.instant('shell.titleBar.noServer'));
isConnected = computed(() => this.webrtc.isConnected());
isReconnecting = computed(() => !this.webrtc.isConnected() && this.webrtc.hasEverConnected());
isAuthed = computed(() => !!this.currentUser());
currentRoom = this.store.selectSignal(selectCurrentRoom);
activeChannelId = this.store.selectSignal(selectActiveChannelId);
textChannels = this.store.selectSignal(selectTextChannels);
voiceChannels = this.store.selectSignal(selectVoiceChannels);
isVoiceWorkspaceExpanded = this.voiceWorkspace.isExpanded;
isSignalServerReconnecting = this.store.selectSignal(selectIsSignalServerReconnecting);
signalServerCompatibilityError = this.store.selectSignal(selectSignalServerCompatibilityError);
isInDirectMessage = toSignal(
this.router.events.pipe(
filter((navigationEvent): navigationEvent is NavigationEnd => navigationEvent instanceof NavigationEnd),
@@ -122,6 +119,7 @@ export class TitleBarComponent {
),
{ initialValue: this.router.url.startsWith('/dm/') }
);
isInRoomView = toSignal(
this.router.events.pipe(
filter((navigationEvent): navigationEvent is NavigationEnd => navigationEvent instanceof NavigationEnd),
@@ -129,8 +127,11 @@ export class TitleBarComponent {
),
{ initialValue: this.router.url.startsWith('/room/') }
);
inRoom = computed(() => !!this.currentRoom() && this.isInRoomView());
roomName = computed(() => this.currentRoom()?.name || '');
activeTextChannelName = computed(() => {
const textChannels = this.textChannels();
@@ -143,12 +144,14 @@ export class TitleBarComponent {
return activeChannel ? activeChannel.name : id;
});
connectedVoiceChannelName = computed(() => {
const voiceChannelId = this.currentUser()?.voiceState?.roomId;
const voiceChannel = this.voiceChannels().find((channel) => channel.id === voiceChannelId);
return voiceChannel?.name || this.appI18n.instant('shell.titleBar.voiceLounge');
});
roomContextMeta = computed(() => {
if (!this.currentRoom()) {
return '';
@@ -162,9 +165,11 @@ export class TitleBarComponent {
return parts.join(' | ');
});
showRoomCompatibilityNotice = computed(() =>
this.inRoom() && !!this.signalServerCompatibilityError()
);
showRoomReconnectNotice = computed(() =>
this.inRoom()
&& !this.signalServerCompatibilityError()
@@ -174,21 +179,57 @@ export class TitleBarComponent {
|| this.isReconnecting()
)
);
serverPluginCount = computed(() => this.pluginRegistry.entries()
.filter((entry) => getPluginInstallScope(entry.manifest) === 'server')
.length);
hasServerPlugins = computed(() => this.inRoom() && this.serverPluginCount() > 0);
requiredPluginRequirements = this.pluginRequirements.missingRequiredRequirements;
optionalPluginRequirement = computed(() => this.inRoom() ? this.pluginRequirements.visibleOptionalRequirements()[0] ?? null : null);
optionalPluginRequirementCount = computed(() => this.pluginRequirements.visibleOptionalRequirements().length);
private _showMenu = signal(false);
showMenu = computed(() => this._showMenu());
showLeaveConfirm = signal(false);
inviteStatus = signal<string | null>(null);
creatingInvite = signal(false);
pluginRequirementBusy = signal(false);
pluginRequirementError = signal<string | null>(null);
private readonly appI18n = inject(AppI18nService);
private store = inject(Store);
private electronBridge = inject(ElectronBridgeService);
private serverDirectory = inject(ServerDirectoryFacade);
private router = inject(Router);
private webrtc = inject(RealtimeSessionFacade);
private platform = inject(PlatformService);
private voiceWorkspace = inject(VoiceWorkspaceService);
private settingsModal = inject(SettingsModalService);
private pluginRegistry = inject(PluginRegistryService);
private pluginRequirements = inject(PluginRequirementStateService);
private pluginStore = inject(PluginStoreService);
private _showMenu = signal(false);
/** Minimize the Electron window. */
minimize() {
const api = this.getWindowControlsApi();
@@ -256,15 +297,6 @@ export class TitleBarComponent {
}
}
/** Open the unified leave-server confirmation dialog. */
private openLeaveConfirm() {
this._showMenu.set(false);
if (this.currentRoom()) {
this.showLeaveConfirm.set(true);
}
}
/** Toggle the server dropdown menu. */
toggleMenu() {
this.inviteStatus.set(null);
@@ -354,6 +386,34 @@ export class TitleBarComponent {
this._showMenu.set(false);
}
/** Log out the current user, disconnect from signaling, and navigate to login. */
logout() {
this._showMenu.set(false);
// Disconnect from signaling server - this broadcasts "user_left" to all
// servers the user was a member of, so other users see them go offline.
this.webrtc.disconnect();
clearStoredCurrentUserId();
this.store.dispatch(MessagesActions.clearMessages());
this.store.dispatch(RoomsActions.resetRoomsState());
this.store.dispatch(UsersActions.resetUsersState());
this.router.navigate(['/login']);
}
private getWindowControlsApi() {
return this.electronBridge.getApi();
}
/** Open the unified leave-server confirmation dialog. */
private openLeaveConfirm() {
this._showMenu.set(false);
if (this.currentRoom()) {
this.showLeaveConfirm.set(true);
}
}
private async installServerRequirements(requirements: PluginRequirementSummary[]): Promise<void> {
const room = this.currentRoom();
@@ -373,21 +433,6 @@ export class TitleBarComponent {
}
}
/** Log out the current user, disconnect from signaling, and navigate to login. */
logout() {
this._showMenu.set(false);
// Disconnect from signaling server - this broadcasts "user_left" to all
// servers the user was a member of, so other users see them go offline.
this.webrtc.disconnect();
clearStoredCurrentUserId();
this.store.dispatch(MessagesActions.clearMessages());
this.store.dispatch(RoomsActions.resetRoomsState());
this.store.dispatch(UsersActions.resetUsersState());
this.router.navigate(['/login']);
}
private async copyInviteLink(inviteUrl: string): Promise<void> {
if (navigator.clipboard?.writeText) {
try {
@@ -427,4 +472,5 @@ export class TitleBarComponent {
sourceUrl: room.sourceUrl
};
}
}