From 8c4e36b23a6f5c95995fb52df9eb81a39de3bfd1 Mon Sep 17 00:00:00 2001 From: neoapps-dev Date: Thu, 13 Aug 2026 19:18:38 +0300 Subject: [PATCH] fix: screenshots on windows and android --- src-tauri/Cargo.lock | 7 ++ src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 9 ++ src/components/common/ScreenshotImage.tsx | 102 ++-------------------- src/components/views/ScreenshotsView.tsx | 12 +-- 5 files changed, 30 insertions(+), 102 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index cd9ca6f..2a4b246 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1913,6 +1913,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + [[package]] name = "httparse" version = "1.10.1" @@ -4742,6 +4748,7 @@ dependencies = [ "gtk", "heck 0.5.0", "http 1.4.0", + "http-range", "image 0.25.10", "jni", "libc", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5e466a1..7a142c2 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] tauri-build = { version = "2", features = [] } [dependencies] -tauri = { version = "2", features = ["tray-icon", "image-png"] } +tauri = { version = "2", features = ["protocol-asset", "tray-icon", "image-png"] } tauri-plugin-opener = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 897c57c..473e97c 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -10,6 +10,15 @@ "frontendDist": "../dist" }, "app": { + "security": { + "assetProtocol": { + "enable": true, + "scope": { + "allow": ["**"], + "requireLiteralLeadingDot": false + } + } + }, "windows": [ { "label": "main", diff --git a/src/components/common/ScreenshotImage.tsx b/src/components/common/ScreenshotImage.tsx index 087bcb4..ed74f76 100644 --- a/src/components/common/ScreenshotImage.tsx +++ b/src/components/common/ScreenshotImage.tsx @@ -1,5 +1,5 @@ -import { useState, useEffect, useRef } from "react"; -import { TauriService } from "../../services/TauriService"; +import { useState } from "react"; +import { convertFileSrc } from "@tauri-apps/api/core"; interface ScreenshotImageProps { path: string; className?: string; @@ -9,50 +9,6 @@ interface ScreenshotImageProps { fallbackSrc?: string; } -const imgCache = new Map(); -let activeLoads = 0; -const MAX_CONCURRENT = 4; -const loadQueue: Array<() => void> = []; -function dequeue() { - while (activeLoads < MAX_CONCURRENT && loadQueue.length > 0) { - const next = loadQueue.shift()!; - activeLoads++; - next(); - } -} - -function enqueueLoad( - path: string, - onLoad: (url: string) => void, - onError: () => void, -) { - const cached = imgCache.get(path); - if (cached) { - onLoad(cached); - return; - } - - const run = () => { - TauriService.readScreenshotAsDataUrl(path) - .then((url) => { - imgCache.set(path, url); - onLoad(url); - }) - .catch(() => onError()) - .finally(() => { - activeLoads--; - dequeue(); - }); - }; - - if (activeLoads < MAX_CONCURRENT) { - activeLoads++; - run(); - } else { - loadQueue.push(run); - } -} - export function ScreenshotImage({ path, className, @@ -61,62 +17,18 @@ export function ScreenshotImage({ style, fallbackSrc, }: ScreenshotImageProps) { - const [src, setSrc] = useState(fallbackSrc); - const imgRef = useRef(null); - const loadedRef = useRef(false); - useEffect(() => { - const el = imgRef.current?.parentElement || imgRef.current; - if (!el) return; - let cancelled = false; - const doLoad = () => { - if (loadedRef.current) return; - loadedRef.current = true; - enqueueLoad( - path, - (url) => { - if (!cancelled) setSrc(url); - }, - () => { - if (!cancelled && fallbackSrc) setSrc(fallbackSrc); - }, - ); - }; - - if (loading === "eager") { - doLoad(); - return () => { - cancelled = true; - }; - } - - const observer = new IntersectionObserver( - ([entry]) => { - if (entry.isIntersecting) { - observer.disconnect(); - doLoad(); - } - }, - { rootMargin: "800px" }, - ); - observer.observe(el); - return () => { - cancelled = true; - observer.disconnect(); - }; - }, [path, fallbackSrc, loading]); - const handleError = () => { - if (fallbackSrc) setSrc(fallbackSrc); - }; + const [hasError, setHasError] = useState(false); return ( {alt} { + if (fallbackSrc) setHasError(true); + }} /> ); } diff --git a/src/components/views/ScreenshotsView.tsx b/src/components/views/ScreenshotsView.tsx index b8cd5d8..a2540fa 100644 --- a/src/components/views/ScreenshotsView.tsx +++ b/src/components/views/ScreenshotsView.tsx @@ -274,7 +274,7 @@ const ScreenshotsView = memo(function ScreenshotsView() { initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} - className="fixed inset-0 z-[200] bg-black/90 flex flex-col items-center justify-center p-8 backdrop-blur-md" + className="fixed inset-0 z-[200] bg-black/90 flex flex-col items-center justify-center p-4 sm:p-8 backdrop-blur-md" onClick={() => setSelectedScreenshot(null)} > e.stopPropagation()} > -
+
@@ -318,7 +318,7 @@ const ScreenshotsView = memo(function ScreenshotsView() {
-
+