Disallow any types

This commit is contained in:
2026-03-09 23:02:52 +01:00
parent 3b1aab4985
commit dc6746c882
40 changed files with 961 additions and 476 deletions

View File

@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/member-ordering, @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/member-ordering, */
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {
@@ -33,10 +33,7 @@ import {
MAX_AUTO_SAVE_SIZE_BYTES
} from '../../../../../core/services/attachment.service';
import { KlipyService } from '../../../../../core/services/klipy.service';
import {
DELETED_MESSAGE_CONTENT,
Message
} from '../../../../../core/models';
import { DELETED_MESSAGE_CONTENT, Message } from '../../../../../core/models';
import {
ChatAudioPlayerComponent,
ChatVideoPlayerComponent,
@@ -81,7 +78,7 @@ const MERMAID_LINE_BREAK_PATTERN = /\r\n?/g;
const REMARK_PROCESSOR = unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkBreaks) as any;
.use(remarkBreaks);
interface ChatMessageAttachmentViewModel extends Attachment {
isAudio: boolean;
@@ -133,7 +130,7 @@ export class ChatMessageItemComponent {
readonly repliedMessage = input<Message | undefined>();
readonly currentUserId = input<string | null>(null);
readonly isAdmin = input(false);
readonly remarkProcessor: any = REMARK_PROCESSOR;
readonly remarkProcessor = REMARK_PROCESSOR;
readonly replyRequested = output<ChatMessageReplyEvent>();
readonly deleteRequested = output<ChatMessageDeleteEvent>();

View File

@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/member-ordering, id-length, id-denylist, @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/member-ordering, id-length, id-denylist, */
import {
Component,
inject,
@@ -19,6 +19,12 @@ const TYPING_TTL = 3_000;
const PURGE_INTERVAL = 1_000;
const MAX_SHOWN = 4;
interface TypingSignalingMessage {
type: string;
displayName: string;
oderId: string;
}
@Component({
selector: 'app-typing-indicator',
standalone: true,
@@ -38,12 +44,16 @@ export class TypingIndicatorComponent {
const webrtc = inject(WebRTCService);
const destroyRef = inject(DestroyRef);
const typing$ = webrtc.onSignalingMessage.pipe(
filter((msg: any) => msg?.type === 'user_typing' && msg.displayName && msg.oderId),
tap((msg: any) => {
filter((msg): msg is TypingSignalingMessage =>
msg?.type === 'user_typing' &&
typeof msg.displayName === 'string' &&
typeof msg.oderId === 'string'
),
tap((msg) => {
const now = Date.now();
this.typingMap.set(String(msg.oderId), {
name: String(msg.displayName),
this.typingMap.set(msg.oderId, {
name: msg.displayName,
expiresAt: now + TYPING_TTL
});
})

View File

@@ -29,10 +29,7 @@ import {
selectVoiceChannels
} from '../../../store/rooms/rooms.selectors';
import { SettingsModalService } from '../../../core/services/settings-modal.service';
import {
selectCurrentUser,
selectIsCurrentUserAdmin
} from '../../../store/users/users.selectors';
import { selectCurrentUser, selectIsCurrentUserAdmin } from '../../../store/users/users.selectors';
import { VoiceWorkspaceService } from '../../../core/services/voice-workspace.service';
@Component({

View File

@@ -549,10 +549,13 @@ export class RoomsSidePanelComponent {
return false;
}
const peerKeys = [user?.oderId, user?.id, userId].filter(
const peerKeys = [
user?.oderId,
user?.id,
userId
].filter(
(candidate): candidate is string => !!candidate
);
const stream = peerKeys
.map((peerKey) => this.webrtc.getRemoteScreenShareStream(peerKey))
.find((candidate) => !!candidate && candidate.getVideoTracks().length > 0) || null;

View File

@@ -12,10 +12,7 @@ import { Router } from '@angular/router';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucidePlus } from '@ng-icons/lucide';
import {
Room,
User
} from '../../core/models/index';
import { Room, User } from '../../core/models/index';
import { selectSavedRooms, selectCurrentRoom } from '../../store/rooms/rooms.selectors';
import { selectCurrentUser } from '../../store/users/users.selectors';
import { VoiceSessionService } from '../../core/services/voice-session.service';

View File

@@ -8,10 +8,7 @@ import {
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import {
Actions,
ofType
} from '@ngrx/effects';
import { Actions, ofType } from '@ngrx/effects';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { Store } from '@ngrx/store';
import { lucideX } from '@ng-icons/lucide';

View File

@@ -14,7 +14,6 @@ import { lucideUserX, lucideBan } from '@ng-icons/lucide';
import {
Room,
RoomMember,
User,
UserRole
} from '../../../../core/models/index';
import { RoomsActions } from '../../../../store/rooms/rooms.actions';

View File

@@ -26,10 +26,7 @@ import {
import { SettingsModalService, SettingsPage } from '../../../core/services/settings-modal.service';
import { selectSavedRooms, selectCurrentRoom } from '../../../store/rooms/rooms.selectors';
import { selectCurrentUser } from '../../../store/users/users.selectors';
import {
Room,
UserRole
} from '../../../core/models/index';
import { Room, UserRole } from '../../../core/models/index';
import { findRoomMember } from '../../../store/rooms/room-members.helpers';
import { WebRTCService } from '../../../core/services/webrtc.service';
@@ -191,7 +188,6 @@ export class SettingsModalComponent {
const targetId = this.modal.targetServerId();
const currentRoomId = this.currentRoom()?.id ?? null;
const selectedId = this.selectedServerId();
const hasSelected = !!selectedId && rooms.some((room) => room.id === selectedId);
if (!hasSelected) {

View File

@@ -20,14 +20,8 @@ import { WebRTCService } from '../../../../core/services/webrtc.service';
import { VoicePlaybackService } from '../../../voice/voice-controls/services/voice-playback.service';
import { NotificationAudioService, AppSound } from '../../../../core/services/notification-audio.service';
import { PlatformService } from '../../../../core/services/platform.service';
import {
loadVoiceSettingsFromStorage,
saveVoiceSettingsToStorage
} from '../../../../core/services/voice-settings.storage';
import {
SCREEN_SHARE_QUALITY_OPTIONS,
ScreenShareQuality
} from '../../../../core/services/webrtc';
import { loadVoiceSettingsFromStorage, saveVoiceSettingsToStorage } from '../../../../core/services/voice-settings.storage';
import { SCREEN_SHARE_QUALITY_OPTIONS, ScreenShareQuality } from '../../../../core/services/webrtc';
interface AudioDevice {
deviceId: string;
@@ -46,6 +40,10 @@ interface DesktopSettingsElectronApi {
relaunchApp?: () => Promise<boolean>;
}
type DesktopSettingsWindow = Window & {
electronAPI?: DesktopSettingsElectronApi;
};
@Component({
selector: 'app-voice-settings',
standalone: true,
@@ -87,7 +85,9 @@ export class VoiceSettingsComponent {
askScreenShareQuality = signal(true);
hardwareAcceleration = signal(true);
hardwareAccelerationRestartRequired = signal(false);
readonly selectedScreenShareQualityDescription = computed(() => this.screenShareQualityOptions.find((option) => option.id === this.screenShareQuality())?.description ?? '');
readonly selectedScreenShareQualityDescription = computed(
() => this.screenShareQualityOptions.find((option) => option.id === this.screenShareQuality())?.description ?? ''
);
constructor() {
this.loadVoiceSettings();
@@ -294,7 +294,7 @@ export class VoiceSettingsComponent {
private getElectronApi(): DesktopSettingsElectronApi | null {
return typeof window !== 'undefined'
? (window as any).electronAPI as DesktopSettingsElectronApi
? (window as DesktopSettingsWindow).electronAPI ?? null
: null;
}
}

View File

@@ -26,6 +26,16 @@ import { PlatformService } from '../../core/services/platform.service';
import { STORAGE_KEY_CURRENT_USER_ID } from '../../core/constants';
import { LeaveServerDialogComponent } from '../../shared';
interface WindowControlsAPI {
minimizeWindow?: () => void;
maximizeWindow?: () => void;
closeWindow?: () => void;
}
type ElectronWindow = Window & {
electronAPI?: WindowControlsAPI;
};
@Component({
selector: 'app-title-bar',
standalone: true,
@@ -54,6 +64,10 @@ export class TitleBarComponent {
private webrtc = inject(WebRTCService);
private platform = inject(PlatformService);
private getWindowControlsApi(): WindowControlsAPI | undefined {
return (window as ElectronWindow).electronAPI;
}
isElectron = computed(() => this.platform.isElectron);
showMenuState = computed(() => false);
@@ -73,26 +87,23 @@ export class TitleBarComponent {
/** Minimize the Electron window. */
minimize() {
const api = (window as any).electronAPI;
const api = this.getWindowControlsApi();
if (api?.minimizeWindow)
api.minimizeWindow();
api?.minimizeWindow?.();
}
/** Maximize or restore the Electron window. */
maximize() {
const api = (window as any).electronAPI;
const api = this.getWindowControlsApi();
if (api?.maximizeWindow)
api.maximizeWindow();
api?.maximizeWindow?.();
}
/** Close the Electron window. */
close() {
const api = (window as any).electronAPI;
const api = this.getWindowControlsApi();
if (api?.closeWindow)
api.closeWindow();
api?.closeWindow?.();
}
/** Navigate to the login page. */

View File

@@ -23,22 +23,21 @@ import {
import { WebRTCService } from '../../../core/services/webrtc.service';
import { VoiceSessionService } from '../../../core/services/voice-session.service';
import {
loadVoiceSettingsFromStorage,
saveVoiceSettingsToStorage
} from '../../../core/services/voice-settings.storage';
import { loadVoiceSettingsFromStorage, saveVoiceSettingsToStorage } from '../../../core/services/voice-settings.storage';
import { ScreenShareQuality } from '../../../core/services/webrtc';
import { UsersActions } from '../../../store/users/users.actions';
import { selectCurrentUser } from '../../../store/users/users.selectors';
import {
DebugConsoleComponent,
ScreenShareQualityDialogComponent
} from '../../../shared';
import { DebugConsoleComponent, ScreenShareQualityDialogComponent } from '../../../shared';
@Component({
selector: 'app-floating-voice-controls',
standalone: true,
imports: [CommonModule, NgIcon, DebugConsoleComponent, ScreenShareQualityDialogComponent],
imports: [
CommonModule,
NgIcon,
DebugConsoleComponent,
ScreenShareQualityDialogComponent
],
viewProviders: [
provideIcons({
lucideMic,
@@ -283,6 +282,7 @@ export class FloatingVoiceControlsComponent implements OnInit, OnDestroy {
includeSystemAudio: this.includeSystemAudio(),
quality
});
this.isScreenSharing.set(true);
} catch (_error) {
// Screen share request was denied or failed

View File

@@ -183,9 +183,9 @@ export class VoicePlaybackService {
return;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line
const anyAudio = pipeline.audioElement as any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line
const anyCtx = pipeline.context as any;
const tasks: Promise<unknown>[] = [];