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,
ElementRef,
@@ -100,24 +99,22 @@ const RECENT_SEARCHES_STORAGE_KEY = 'metoyou_dashboard_recent_searches';
}
})
export class DashboardComponent implements OnInit {
private readonly appI18n = inject(AppI18nService);
private store = inject(Store);
private router = inject(Router);
private serverDirectory = inject(ServerDirectoryFacade);
private friendsService = inject(FriendService);
private readonly viewport = inject(ViewportService);
private searchSubject = new Subject<string>();
private readonly searchInputRef = viewChild<ElementRef<HTMLInputElement>>('searchInput');
readonly isMobile = this.viewport.isMobile;
searchQuery = signal('');
serverResults = this.store.selectSignal(selectSearchResults);
isSearching = this.store.selectSignal(selectIsSearching);
savedRooms = this.store.selectSignal(selectSavedRooms);
currentUser = this.store.selectSignal(selectCurrentUser);
popularServers = signal<ServerInfo[]>([]);
recentSearches = signal<string[]>(this.loadRecentSearches());
private users = this.store.selectSignal(selectAllUsers);
/** True while the user is actively typing a query. */
isSearchMode = computed(() => this.searchQuery().trim().length > 0);
@@ -125,37 +122,6 @@ export class DashboardComponent implements OnInit {
/** Server matches limited for the quick-search list. */
topServerResults = computed(() => this.serverResults().slice(0, QUICK_RESULT_LIMIT));
/** Every distinct person known to the account (known users plus saved-room members), excluding self. */
private discoveredPeople = computed<User[]>(() => {
const currentKey = this.currentUserKey();
const byKey = new Map<string, User>();
for (const user of this.users()) {
byKey.set(user.oderId || user.id, user);
}
for (const room of this.savedRooms()) {
for (const member of room.members ?? []) {
const key = member.oderId || member.id;
if (byKey.has(key)) {
continue;
}
byKey.set(key, {
id: member.id,
oderId: key,
username: member.username,
displayName: member.displayName,
avatarUrl: member.avatarUrl,
status: 'disconnected'
} as User);
}
}
return Array.from(byKey.values()).filter((user) => (user.oderId || user.id) !== currentKey);
});
/** People matches derived from known users and saved-room members. */
topPeopleResults = computed<User[]>(() => {
const query = this.searchQuery().trim()
@@ -200,6 +166,63 @@ export class DashboardComponent implements OnInit {
/** True for a brand-new account with no servers and no known people. */
isNewUser = computed(() => this.savedRooms().length === 0 && this.users().length === 0);
private readonly appI18n = inject(AppI18nService);
private store = inject(Store);
private router = inject(Router);
private serverDirectory = inject(ServerDirectoryFacade);
private friendsService = inject(FriendService);
private readonly viewport = inject(ViewportService);
private searchSubject = new Subject<string>();
private readonly searchInputRef = viewChild<ElementRef<HTMLInputElement>>('searchInput');
private users = this.store.selectSignal(selectAllUsers);
/** Every distinct person known to the account (known users plus saved-room members), excluding self. */
private discoveredPeople = computed<User[]>(() => {
const currentKey = this.currentUserKey();
const byKey = new Map<string, User>();
for (const user of this.users()) {
byKey.set(user.oderId || user.id, user);
}
for (const room of this.savedRooms()) {
for (const member of room.members ?? []) {
const key = member.oderId || member.id;
if (byKey.has(key)) {
continue;
}
byKey.set(key, {
id: member.id,
oderId: key,
username: member.username,
displayName: member.displayName,
avatarUrl: member.avatarUrl,
status: 'disconnected'
} as User);
}
}
return Array.from(byKey.values()).filter((user) => (user.oderId || user.id) !== currentKey);
});
@HostListener('document:keydown', ['$event'])
onGlobalKeydown(event: KeyboardEvent): void {
if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'k') {
event.preventDefault();
this.searchInputRef()?.nativeElement.focus();
}
}
ngOnInit(): void {
this.store.dispatch(RoomsActions.loadRooms());
@@ -217,14 +240,6 @@ export class DashboardComponent implements OnInit {
});
}
@HostListener('document:keydown', ['$event'])
onGlobalKeydown(event: KeyboardEvent): void {
if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'k') {
event.preventDefault();
this.searchInputRef()?.nativeElement.focus();
}
}
onSearchChange(query: string): void {
this.searchQuery.set(query);
this.searchSubject.next(query);
@@ -357,4 +372,5 @@ export class DashboardComponent implements OnInit {
.filter((value): value is string => typeof value === 'string')
.some((value) => value.toLowerCase().includes(query));
}
}