diff --git a/src-tauri/tauri.linux-aarch64.conf.json b/src-tauri/tauri.linux-aarch64.conf.json index 9a36657..75419f4 100644 --- a/src-tauri/tauri.linux-aarch64.conf.json +++ b/src-tauri/tauri.linux-aarch64.conf.json @@ -29,6 +29,7 @@ "targets": ["deb", "rpm"], "createUpdaterArtifacts": true, "licenseFile": "../LICENSE", + "category": "Utility", "icon": [ "icons/32x32.png", "icons/128x128.png", diff --git a/src-tauri/tauri.linux-flatpak.conf.json b/src-tauri/tauri.linux-flatpak.conf.json index d8bc6b1..d7f3e0b 100644 --- a/src-tauri/tauri.linux-flatpak.conf.json +++ b/src-tauri/tauri.linux-flatpak.conf.json @@ -29,6 +29,7 @@ "targets": ["deb"], "createUpdaterArtifacts": true, "licenseFile": "../LICENSE", + "category": "Utility", "icon": [ "icons/32x32.png", "icons/128x128.png", diff --git a/src-tauri/tauri.linux-x86_64.conf.json b/src-tauri/tauri.linux-x86_64.conf.json index 68782ee..6cb67e3 100644 --- a/src-tauri/tauri.linux-x86_64.conf.json +++ b/src-tauri/tauri.linux-x86_64.conf.json @@ -29,6 +29,7 @@ "targets": ["deb", "rpm", "appimage"], "createUpdaterArtifacts": true, "licenseFile": "../LICENSE", + "category": "Utility", "icon": [ "icons/32x32.png", "icons/128x128.png", diff --git a/src/App.tsx b/src/App.tsx index cf73e21..b9dca06 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,7 @@ import { AppContext } from "@/providers/appContextProvider"; import { useEffect, useRef, useState } from "react"; import { arch, exeExtension } from "@tauri-apps/plugin-os"; import { downloadDir, join, resourceDir, tempDir } from "@tauri-apps/api/path"; -import { useBasePathsStore, useCurrentVideoMetadataStore, useDownloaderPageStatesStore, useDownloadStatesStore, useKvPairsStatesStore, useSettingsPageStatesStore } from "@/services/store"; +import { useBasePathsStore, useCurrentVideoMetadataStore, useDownloaderPageStatesStore, useDownloadStatesStore, useEnvironmentStore, useKvPairsStatesStore, useSettingsPageStatesStore } from "@/services/store"; import { isObjEmpty} from "@/utils"; import { Command } from "@tauri-apps/plugin-shell"; import { useUpdateDownloadStatus } from "@/services/mutations"; @@ -27,6 +27,8 @@ import { useLogger } from "@/helpers/use-logger"; import useDownloader from "@/helpers/use-downloader"; import usePotServer from "@/helpers/use-pot-server"; import { useLinuxRegisterer } from "@/helpers/use-linux-registerer"; +import { invoke } from "@tauri-apps/api/core"; + export default function App({ children }: { children: React.ReactNode }) { const { data: downloadStates, isSuccess: isSuccessFetchingDownloadStates } = useFetchAllDownloadStates(); @@ -37,6 +39,10 @@ export default function App({ children }: { children: React.ReactNode }) { const globalDownloadStates = useDownloadStatesStore((state) => state.downloadStates); const setDownloadStates = useDownloadStatesStore((state) => state.setDownloadStates); const setPath = useBasePathsStore((state) => state.setPath); + const isFlatpak = useEnvironmentStore(state => state.isFlatpak); + const setIsFlatpak = useEnvironmentStore((state) => state.setIsFlatpak); + const setIsAppimage = useEnvironmentStore((state) => state.setIsAppimage); + const setAppDirPath = useEnvironmentStore((state) => state.setAppDirPath); const setIsUsingDefaultSettings = useSettingsPageStatesStore((state) => state.setIsUsingDefaultSettings); const setSettingsKey = useSettingsPageStatesStore((state) => state.setSettingsKey); @@ -120,6 +126,26 @@ export default function App({ children }: { children: React.ReactNode }) { }; }, [stopPotServer]); + // Detect sandboxed environments + useEffect(() => { + const detectEnvironment = async () => { + try { + const flatpak = await invoke('is_flatpak'); + setIsFlatpak(flatpak); + const appimage = await invoke('is_appimage'); + if (appimage) { + setIsAppimage(true); + setAppDirPath(appimage); + } else { + setIsAppimage(false); + } + } catch (e) { + console.error('Failed to detect environment:', e); + } + }; + detectEnvironment(); + }, [setIsFlatpak, setIsAppimage, setAppDirPath]); + // Listen for websocket messages useEffect(() => { const unlisten = listen('websocket-message', (event) => { @@ -187,7 +213,7 @@ export default function App({ children }: { children: React.ReactNode }) { const resourceDirPath = await resourceDir(); const ffmpegPath = await join(resourceDirPath, 'binaries', `ffmpeg-${currentArch}${currentExeExtension ? '.' + currentExeExtension : ''}`); - const tempDownloadDirPath = await join(tempDirPath, config.appPkgName, 'downloads'); + const tempDownloadDirPath = isFlatpak ? await join(downloadDirPath, config.appName, '.tempdownloads') : await join(tempDirPath, config.appPkgName, 'downloads'); const appDownloadDirPath = await join(downloadDirPath, config.appName); if (!await fs.exists(tempDownloadDirPath)) fs.mkdir(tempDownloadDirPath, { recursive: true }).then(() => { console.log(`Created DIR: ${tempDownloadDirPath}`) }); @@ -206,7 +232,7 @@ export default function App({ children }: { children: React.ReactNode }) { } }; initPaths(); - }, [DOWNLOAD_DIR, setPath]); + }, [DOWNLOAD_DIR, setPath, isFlatpak]); // Fetch app version useEffect(() => { @@ -278,6 +304,10 @@ export default function App({ children }: { children: React.ReactNode }) { console.log("Auto-update check already performed in this session, skipping"); return; } + if (isFlatpak) { + console.log("Flatpak detected! Skipping yt-dlp auto-update"); + return; + } hasRunYtDlpAutoUpdateRef.current = true; console.log("Checking yt-dlp auto-update with loaded config values:", { autoUpdate: YTDLP_AUTO_UPDATE, diff --git a/src/helpers/use-linux-registerer.ts b/src/helpers/use-linux-registerer.ts index 8f8e3b9..94be1cd 100644 --- a/src/helpers/use-linux-registerer.ts +++ b/src/helpers/use-linux-registerer.ts @@ -1,9 +1,7 @@ import { join, resourceDir, homeDir } from "@tauri-apps/api/path"; import * as fs from "@tauri-apps/plugin-fs"; import { useKvPairs } from "@/helpers/use-kvpairs"; -import { useSettingsPageStatesStore } from "@/services/store"; -import { invoke } from "@tauri-apps/api/core"; -import { useLogger } from "@/helpers/use-logger"; +import { useEnvironmentStore, useSettingsPageStatesStore } from "@/services/store"; import { Command } from "@tauri-apps/plugin-shell"; interface FileMap { @@ -16,11 +14,10 @@ interface FileMap { export function useLinuxRegisterer() { const { saveKvPair } = useKvPairs(); const appVersion = useSettingsPageStatesStore(state => state.appVersion); - const LOG = useLogger(); const registerToLinux = async () => { try { - const isFlatpak = await invoke('is_flatpak'); + const isFlatpak = useEnvironmentStore(state => state.isFlatpak); const resourceDirPath = isFlatpak ? '/app/lib/neodlp' : await resourceDir(); const homeDirPath = await homeDir(); const flatpakChromeManifestContent = { @@ -51,8 +48,6 @@ export function useLinuxRegisterer() { { source: 'neodlp-msghost', destination: '.local/bin/neodlp-msghost', dir: '.local/bin/' }, ]; - LOG.info("LINUX REGISTERER", `Is Flatpak: ${isFlatpak}, Resource dir: ${resourceDirPath}, Home dir: ${homeDirPath}`); - if (isFlatpak) { for (const file of filesToCopyFlatpak) { const sourcePath = await join(resourceDirPath, file.source); @@ -65,20 +60,16 @@ export function useLinuxRegisterer() { const writeOutput = await writeCommand.execute(); if (writeOutput.code === 0) { console.log(`File ${file.destination} created successfully at ${destinationPath}`); - LOG.info("LINUX REGISTERER", `File ${file.destination} created successfully at ${destinationPath}`); } else { console.error(`Failed to create file ${file.destination} at ${destinationPath}:`, writeOutput.stderr); - LOG.error("LINUX REGISTERER", `Failed to create file ${file.destination} at ${destinationPath}: ${writeOutput.stderr}`); return { success: false, message: 'Failed to register' }; } } else { const copyOutput = await copyCommand.execute(); if (copyOutput.code === 0) { console.log(`File ${file.source} copied successfully to ${destinationPath}`); - LOG.info("LINUX REGISTERER", `File ${file.source} copied successfully to ${destinationPath}`); } else { console.error(`Failed to copy file ${file.source} to ${destinationPath}:`, copyOutput.stderr); - LOG.error("LINUX REGISTERER", `Failed to copy file ${file.source} to ${destinationPath}: ${copyOutput.stderr}`); return { success: false, message: 'Failed to register' }; } } @@ -93,14 +84,11 @@ export function useLinuxRegisterer() { if (dirExists) { await fs.copyFile(sourcePath, destinationPath); console.log(`File ${file.source} copied successfully to ${destinationPath}`); - LOG.info("LINUX REGISTERER", `File ${file.source} copied successfully to ${destinationPath}`); } else { await fs.mkdir(destinationDir, { recursive: true }) console.log(`Created dir ${destinationDir}`); - LOG.info("LINUX REGISTERER", `Created dir ${destinationDir}`); await fs.copyFile(sourcePath, destinationPath); console.log(`File ${file.source} copied successfully to ${destinationPath}`); - LOG.info("LINUX REGISTERER", `File ${file.source} copied successfully to ${destinationPath}`); } } } @@ -108,7 +96,6 @@ export function useLinuxRegisterer() { return { success: true, message: 'Registered successfully' } } catch (error) { console.error('Error copying files:', error); - LOG.error("LINUX REGISTERER", `Error copying files: ${error}`); return { success: false, message: 'Failed to register' } } } diff --git a/src/helpers/use-ytdlp-updater.ts b/src/helpers/use-ytdlp-updater.ts index fc6cec1..9484612 100644 --- a/src/helpers/use-ytdlp-updater.ts +++ b/src/helpers/use-ytdlp-updater.ts @@ -1,4 +1,4 @@ -import { useSettingsPageStatesStore } from "@/services/store"; +import { useEnvironmentStore, useSettingsPageStatesStore } from "@/services/store"; import { useKvPairs } from "@/helpers/use-kvpairs"; import { Command } from "@tauri-apps/plugin-shell"; import { invoke } from "@tauri-apps/api/core"; @@ -17,7 +17,7 @@ export function useYtDlpUpdater() { const updateYtDlp = async () => { const CURRENT_TIMESTAMP = Date.now(); - const isFlatpak = await invoke('is_flatpak'); + const isFlatpak = useEnvironmentStore(state => state.isFlatpak); setIsUpdatingYtDlp(true); LOG.info('NEODLP', 'Updating yt-dlp to latest version'); try { diff --git a/src/services/store.ts b/src/services/store.ts index cb33561..277a87c 100644 --- a/src/services/store.ts +++ b/src/services/store.ts @@ -1,4 +1,4 @@ -import { BasePathsStore, CurrentVideoMetadataStore, DownloadActionStatesStore, DownloaderPageStatesStore, DownloadStatesStore, KvPairsStatesStore, LibraryPageStatesStore, LogsStore, SettingsPageStatesStore } from '@/types/store'; +import { BasePathsStore, CurrentVideoMetadataStore, DownloadActionStatesStore, DownloaderPageStatesStore, DownloadStatesStore, EnvironmentStore, KvPairsStatesStore, LibraryPageStatesStore, LogsStore, SettingsPageStatesStore } from '@/types/store'; import { create } from 'zustand'; export const useBasePathsStore = create((set) => ({ @@ -352,3 +352,12 @@ export const useLogsStore = create((set) => ({ addLog: (log) => set((state) => ({ logs: [...state.logs, log] })), clearLogs: () => set(() => ({ logs: [] })) })); + +export const useEnvironmentStore = create((set) => ({ + isFlatpak: false, + isAppimage: false, + appDirPath: null, + setIsFlatpak: (isFlatpak) => set(() => ({ isFlatpak })), + setIsAppimage: (isAppimage) => set(() => ({ isAppimage })), + setAppDirPath: (path) => set(() => ({ appDirPath: path })) +})); diff --git a/src/types/store.ts b/src/types/store.ts index 5643eae..524be4a 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -152,3 +152,12 @@ export interface LogsStore { addLog: (log: Log) => void; clearLogs: () => void; } + +export interface EnvironmentStore { + isFlatpak: boolean; + isAppimage: boolean; + appDirPath: string | null; + setIsFlatpak: (isFlatpak: boolean) => void; + setIsAppimage: (isAppimage: boolean) => void; + setAppDirPath: (path: string) => void; +}