Fix: lint errors

This commit is contained in:
Alex P 2025-08-04 20:30:39 +03:00
parent 575abb75f0
commit 3dc196bab5
5 changed files with 78 additions and 27 deletions

View File

@ -22,14 +22,20 @@ import AudioControlPopover from "@/components/popovers/AudioControlPopover";
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation"; import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
import api from "@/api"; import api from "@/api";
// Type for microphone error
interface MicrophoneError {
type: 'permission' | 'device' | 'network' | 'unknown';
message: string;
}
// Type for microphone hook return value // Type for microphone hook return value
interface MicrophoneHookReturn { interface MicrophoneHookReturn {
isMicrophoneActive: boolean; isMicrophoneActive: boolean;
isMicrophoneMuted: boolean; isMicrophoneMuted: boolean;
microphoneStream: MediaStream | null; microphoneStream: MediaStream | null;
startMicrophone: (deviceId?: string) => Promise<{ success: boolean; error?: any }>; startMicrophone: (deviceId?: string) => Promise<{ success: boolean; error?: MicrophoneError }>;
stopMicrophone: () => Promise<{ success: boolean; error?: any }>; stopMicrophone: () => Promise<{ success: boolean; error?: MicrophoneError }>;
toggleMicrophoneMute: () => Promise<{ success: boolean; error?: any }>; toggleMicrophoneMute: () => Promise<{ success: boolean; error?: MicrophoneError }>;
syncMicrophoneState: () => Promise<void>; syncMicrophoneState: () => Promise<void>;
} }

View File

@ -25,14 +25,20 @@ import {
PointerLockBar, PointerLockBar,
} from "./VideoOverlay"; } from "./VideoOverlay";
// Type for microphone error
interface MicrophoneError {
type: 'permission' | 'device' | 'network' | 'unknown';
message: string;
}
// Interface for microphone hook return type // Interface for microphone hook return type
interface MicrophoneHookReturn { interface MicrophoneHookReturn {
isMicrophoneActive: boolean; isMicrophoneActive: boolean;
isMicrophoneMuted: boolean; isMicrophoneMuted: boolean;
microphoneStream: MediaStream | null; microphoneStream: MediaStream | null;
startMicrophone: (deviceId?: string) => Promise<{ success: boolean; error?: any }>; startMicrophone: (deviceId?: string) => Promise<{ success: boolean; error?: MicrophoneError }>;
stopMicrophone: () => Promise<{ success: boolean; error?: any }>; stopMicrophone: () => Promise<{ success: boolean; error?: MicrophoneError }>;
toggleMicrophoneMute: () => Promise<{ success: boolean; error?: any }>; toggleMicrophoneMute: () => Promise<{ success: boolean; error?: MicrophoneError }>;
syncMicrophoneState: () => Promise<void>; syncMicrophoneState: () => Promise<void>;
} }

View File

@ -11,14 +11,20 @@ import { useAudioLevel } from "@/hooks/useAudioLevel";
import api from "@/api"; import api from "@/api";
import notifications from "@/notifications"; import notifications from "@/notifications";
// Type for microphone error
interface MicrophoneError {
type: 'permission' | 'device' | 'network' | 'unknown';
message: string;
}
// Type for microphone hook return value // Type for microphone hook return value
interface MicrophoneHookReturn { interface MicrophoneHookReturn {
isMicrophoneActive: boolean; isMicrophoneActive: boolean;
isMicrophoneMuted: boolean; isMicrophoneMuted: boolean;
microphoneStream: MediaStream | null; microphoneStream: MediaStream | null;
startMicrophone: (deviceId?: string) => Promise<{ success: boolean; error?: any }>; startMicrophone: (deviceId?: string) => Promise<{ success: boolean; error?: MicrophoneError }>;
stopMicrophone: () => Promise<{ success: boolean; error?: any }>; stopMicrophone: () => Promise<{ success: boolean; error?: MicrophoneError }>;
toggleMicrophoneMute: () => Promise<{ success: boolean; error?: any }>; toggleMicrophoneMute: () => Promise<{ success: boolean; error?: MicrophoneError }>;
syncMicrophoneState: () => Promise<void>; syncMicrophoneState: () => Promise<void>;
} }
@ -276,9 +282,9 @@ export default function AudioControlPopover({ microphone }: AudioControlPopoverP
const videoElement = document.querySelector('video'); const videoElement = document.querySelector('video');
if (videoElement && 'setSinkId' in videoElement) { if (videoElement && 'setSinkId' in videoElement) {
try { try {
await (videoElement as any).setSinkId(deviceId); await (videoElement as HTMLVideoElement & { setSinkId: (deviceId: string) => Promise<void> }).setSinkId(deviceId);
console.log('Audio output device changed to:', deviceId); console.log('Audio output device changed to:', deviceId);
} catch (error) { } catch (error: unknown) {
console.error('Failed to change audio output device:', error); console.error('Failed to change audio output device:', error);
} }
} else { } else {

View File

@ -43,7 +43,7 @@ export const useAudioLevel = (stream: MediaStream | null): AudioLevelHookResult
try { try {
// Create audio context and analyser // Create audio context and analyser
const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)(); const audioContext = new (window.AudioContext || (window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext)();
const analyser = audioContext.createAnalyser(); const analyser = audioContext.createAnalyser();
const source = audioContext.createMediaStreamSource(stream); const source = audioContext.createMediaStreamSource(stream);
@ -68,8 +68,8 @@ export const useAudioLevel = (stream: MediaStream | null): AudioLevelHookResult
// Calculate RMS (Root Mean Square) for more accurate level representation // Calculate RMS (Root Mean Square) for more accurate level representation
let sum = 0; let sum = 0;
for (let i = 0; i < dataArray.length; i++) { for (const value of dataArray) {
sum += dataArray[i] * dataArray[i]; sum += value * value;
} }
const rms = Math.sqrt(sum / dataArray.length); const rms = Math.sqrt(sum / dataArray.length);

View File

@ -1,4 +1,5 @@
import { useCallback, useEffect, useRef } from "react"; import { useCallback, useEffect, useRef } from "react";
import { useRTCStore } from "@/hooks/stores"; import { useRTCStore } from "@/hooks/stores";
import api from "@/api"; import api from "@/api";
@ -97,9 +98,9 @@ export function useMicrophone() {
// Make debug function available globally for console access // Make debug function available globally for console access
useEffect(() => { useEffect(() => {
(window as any).debugMicrophoneState = debugMicrophoneState; (window as Window & { debugMicrophoneState?: () => unknown }).debugMicrophoneState = debugMicrophoneState;
return () => { return () => {
delete (window as any).debugMicrophoneState; delete (window as Window & { debugMicrophoneState?: () => unknown }).debugMicrophoneState;
}; };
}, [debugMicrophoneState]); }, [debugMicrophoneState]);
@ -396,7 +397,7 @@ export function useMicrophone() {
isStartingRef.current = false; isStartingRef.current = false;
return { success: false, error: micError }; return { success: false, error: micError };
} }
}, [peerConnection, setMicrophoneStream, setMicrophoneSender, setMicrophoneActive, setMicrophoneMuted, syncMicrophoneState, stopMicrophoneStream]); }, [peerConnection, setMicrophoneStream, setMicrophoneSender, setMicrophoneActive, setMicrophoneMuted, stopMicrophoneStream, isMicrophoneActive, isMicrophoneMuted, microphoneStream]);
// Stop microphone // Stop microphone
const stopMicrophone = useCallback(async (): Promise<{ success: boolean; error?: MicrophoneError }> => { const stopMicrophone = useCallback(async (): Promise<{ success: boolean; error?: MicrophoneError }> => {
@ -519,7 +520,15 @@ export function useMicrophone() {
try { try {
const stats = await microphoneSender.getStats(); const stats = await microphoneSender.getStats();
const audioStats: any[] = []; const audioStats: {
id: string;
type: string;
kind: string;
packetsSent?: number;
bytesSent?: number;
timestamp?: number;
ssrc?: number;
}[] = [];
stats.forEach((report, id) => { stats.forEach((report, id) => {
if (report.type === 'outbound-rtp' && report.kind === 'audio') { if (report.type === 'outbound-rtp' && report.kind === 'audio') {
@ -576,7 +585,7 @@ export function useMicrophone() {
// 3. Test audio level detection manually // 3. Test audio level detection manually
try { try {
const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)(); const audioContext = new (window.AudioContext || (window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext)();
const analyser = audioContext.createAnalyser(); const analyser = audioContext.createAnalyser();
const source = audioContext.createMediaStreamSource(stream); const source = audioContext.createMediaStreamSource(stream);
@ -595,8 +604,8 @@ export function useMicrophone() {
analyser.getByteFrequencyData(dataArray); analyser.getByteFrequencyData(dataArray);
let sum = 0; let sum = 0;
for (let i = 0; i < dataArray.length; i++) { for (const value of dataArray) {
sum += dataArray[i] * dataArray[i]; sum += value * value;
} }
const rms = Math.sqrt(sum / dataArray.length); const rms = Math.sqrt(sum / dataArray.length);
const level = Math.min(100, (rms / 255) * 100); const level = Math.min(100, (rms / 255) * 100);
@ -672,13 +681,37 @@ export function useMicrophone() {
// Make debug functions available globally for console access // Make debug functions available globally for console access
useEffect(() => { useEffect(() => {
(window as any).debugMicrophone = debugMicrophoneState; (window as Window & {
(window as any).checkAudioStats = checkAudioTransmissionStats; debugMicrophone?: () => unknown;
(window as any).testMicrophoneAudio = testMicrophoneAudio; checkAudioStats?: () => unknown;
testMicrophoneAudio?: () => unknown;
}).debugMicrophone = debugMicrophoneState;
(window as Window & {
debugMicrophone?: () => unknown;
checkAudioStats?: () => unknown;
testMicrophoneAudio?: () => unknown;
}).checkAudioStats = checkAudioTransmissionStats;
(window as Window & {
debugMicrophone?: () => unknown;
checkAudioStats?: () => unknown;
testMicrophoneAudio?: () => unknown;
}).testMicrophoneAudio = testMicrophoneAudio;
return () => { return () => {
delete (window as any).debugMicrophone; delete (window as Window & {
delete (window as any).checkAudioStats; debugMicrophone?: () => unknown;
delete (window as any).testMicrophoneAudio; checkAudioStats?: () => unknown;
testMicrophoneAudio?: () => unknown;
}).debugMicrophone;
delete (window as Window & {
debugMicrophone?: () => unknown;
checkAudioStats?: () => unknown;
testMicrophoneAudio?: () => unknown;
}).checkAudioStats;
delete (window as Window & {
debugMicrophone?: () => unknown;
checkAudioStats?: () => unknown;
testMicrophoneAudio?: () => unknown;
}).testMicrophoneAudio;
}; };
}, [debugMicrophoneState, checkAudioTransmissionStats, testMicrophoneAudio]); }, [debugMicrophoneState, checkAudioTransmissionStats, testMicrophoneAudio]);