refactor: cleanup

This commit is contained in:
zhom
2026-07-25 22:59:13 +04:00
parent 59a3e5f2a1
commit b9070693ed
49 changed files with 1204 additions and 2208 deletions
-54
View File
@@ -1,54 +0,0 @@
import { invoke } from "@tauri-apps/api/core";
import { useEffect, useState } from "react";
import i18n from "@/i18n";
export function useBrowserSupport() {
const [supportedBrowsers, setSupportedBrowsers] = useState<string[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const loadSupportedBrowsers = async () => {
try {
setIsLoading(true);
setError(null);
const browsers = await invoke<string[]>("get_supported_browsers");
setSupportedBrowsers(browsers);
} catch (err) {
console.error("Failed to load supported browsers:", err);
setError(
err instanceof Error
? err.message
: i18n.t("errors.loadSupportedBrowsersFailed"),
);
} finally {
setIsLoading(false);
}
};
void loadSupportedBrowsers();
}, []);
const isBrowserSupported = (browser: string): boolean => {
return supportedBrowsers.includes(browser);
};
const checkBrowserSupport = async (browser: string): Promise<boolean> => {
try {
return await invoke<boolean>("is_browser_supported_on_platform", {
browserStr: browser,
});
} catch (err) {
console.error(`Failed to check support for browser ${browser}:`, err);
return false;
}
};
return {
supportedBrowsers,
isLoading,
error,
isBrowserSupported,
checkBrowserSupport,
};
}
-76
View File
@@ -1,76 +0,0 @@
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { useCallback, useEffect, useState } from "react";
import i18n from "@/i18n";
import type { Extension, ExtensionGroup } from "@/types";
export function useExtensionEvents() {
const [extensions, setExtensions] = useState<Extension[]>([]);
const [extensionGroups, setExtensionGroups] = useState<ExtensionGroup[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const loadExtensions = useCallback(async () => {
try {
const exts = await invoke<Extension[]>("list_extensions");
setExtensions(exts);
setError(null);
} catch (err: unknown) {
console.error("Failed to load extensions:", err);
setExtensions([]);
}
}, []);
const loadExtensionGroups = useCallback(async () => {
try {
const groups = await invoke<ExtensionGroup[]>("list_extension_groups");
setExtensionGroups(groups);
setError(null);
} catch (err: unknown) {
console.error("Failed to load extension groups:", err);
setExtensionGroups([]);
}
}, []);
const loadAll = useCallback(async () => {
await Promise.all([loadExtensions(), loadExtensionGroups()]);
}, [loadExtensions, loadExtensionGroups]);
useEffect(() => {
let unlisten: (() => void) | undefined;
const setup = async () => {
try {
await loadAll();
unlisten = await listen("extensions-changed", () => {
void loadAll();
});
} catch (err) {
console.error("Failed to setup extension event listeners:", err);
setError(
i18n.t("errors.setupExtensionListenersFailed", {
error: JSON.stringify(err),
}),
);
} finally {
setIsLoading(false);
}
};
void setup();
return () => {
if (unlisten) unlisten();
};
}, [loadAll]);
return {
extensions,
extensionGroups,
isLoading,
error,
loadExtensions,
loadExtensionGroups,
loadAll,
};
}
+21 -41
View File
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { getCurrentOS, type OperatingSystem } from "@/lib/platform";
// Platform-specific imports
let macOSPermissions:
@@ -25,21 +26,23 @@ interface UsePermissionsReturn {
isMicrophoneAccessGranted: boolean;
isCameraAccessGranted: boolean;
isInitialized: boolean;
currentOS: OperatingSystem | null;
requiresSystemPermissions: boolean;
}
export function usePermissions(): UsePermissionsReturn {
export function usePermissions(active = true): UsePermissionsReturn {
const [isMicrophoneAccessGranted, setIsMicrophoneAccessGranted] =
useState(false);
const [isCameraAccessGranted, setIsCameraAccessGranted] = useState(false);
const [currentPlatform, setCurrentPlatform] = useState<string | null>(null);
const [currentOS, setCurrentOS] = useState<OperatingSystem | null>(null);
const [isInitialized, setIsInitialized] = useState(false);
const intervalRef = useRef<NodeJS.Timeout | null>(null);
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
// Check permissions status
const checkPermissions = useCallback(async () => {
if (!currentPlatform) return;
if (!currentOS) return;
if (currentPlatform !== "macos") {
if (currentOS !== "macos") {
// Windows/Linux - assume permissions are granted
setIsMicrophoneAccessGranted(true);
setIsCameraAccessGranted(true);
@@ -58,19 +61,19 @@ export function usePermissions(): UsePermissionsReturn {
setIsMicrophoneAccessGranted(micGranted);
setIsCameraAccessGranted(camGranted);
setIsInitialized(true);
}
} catch (error) {
console.error("Failed to check permissions on macOS:", error);
} finally {
setIsInitialized(true);
}
}, [currentPlatform]);
}, [currentOS]);
// Request permission
const requestPermission = useCallback(
async (type: PermissionType): Promise<boolean> => {
// Non-macOS platforms do not require this permission gate.
if (!currentPlatform || currentPlatform !== "macos") return true;
if ((currentOS ?? getCurrentOS()) !== "macos") return true;
// macOS - use the permissions API
try {
@@ -96,59 +99,34 @@ export function usePermissions(): UsePermissionsReturn {
await permissions.requestCameraPermission();
}
for (let attempt = 0; attempt < 8; attempt += 1) {
const granted = await readPermission();
if (granted) return true;
await new Promise((resolve) => setTimeout(resolve, 1000));
}
// Read once immediately. The hook's macOS poll keeps watching for
// delayed TCC propagation without holding this request (and any next
// system prompt) open for several extra seconds.
return readPermission();
} catch (error) {
console.error(`Failed to request ${type} permission on macOS:`, error);
return false;
}
},
[currentPlatform],
[currentOS],
);
// Initialize platform detection and start interval checking
useEffect(() => {
const initializePlatform = () => {
try {
// Detect platform - on macOS we need permissions, on others we don't
const userAgent = navigator.userAgent;
let platformName = "unknown";
if (userAgent.includes("Mac")) {
platformName = "macos";
} else if (userAgent.includes("Win")) {
platformName = "windows";
} else if (userAgent.includes("Linux")) {
platformName = "linux";
}
setCurrentPlatform(platformName);
} catch (error) {
console.error("Failed to detect platform:", error);
// Fallback - assume non-macOS
setCurrentPlatform("unknown");
}
};
initializePlatform();
setCurrentOS(getCurrentOS());
}, []);
// Set up interval checking when platform is determined.
// On non-macOS platforms, permissions are always granted — a single check
// is enough and we skip the interval entirely to avoid burning CPU.
useEffect(() => {
if (!currentPlatform) return;
if (!currentOS || !active) return;
// Initial check
void checkPermissions();
// Only poll on macOS where permissions can change at runtime
if (currentPlatform !== "macos") return;
if (currentOS !== "macos") return;
intervalRef.current = setInterval(() => {
void checkPermissions();
@@ -160,12 +138,14 @@ export function usePermissions(): UsePermissionsReturn {
intervalRef.current = null;
}
};
}, [currentPlatform, checkPermissions]);
}, [active, currentOS, checkPermissions]);
return {
requestPermission,
isMicrophoneAccessGranted,
isCameraAccessGranted,
isInitialized,
currentOS,
requiresSystemPermissions: currentOS === "macos",
};
}