mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat: add recent tools tracking via localStorage
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
import { useSyncExternalStore } from "react";
|
||||||
|
|
||||||
|
const STORAGE_KEY = "snapotter-recent-tools";
|
||||||
|
const MAX_RECENT = 5;
|
||||||
|
|
||||||
|
let listeners: Array<() => void> = [];
|
||||||
|
|
||||||
|
function getSnapshot(): string[] {
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(STORAGE_KEY);
|
||||||
|
return raw ? JSON.parse(raw) : [];
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function subscribe(listener: () => void) {
|
||||||
|
listeners.push(listener);
|
||||||
|
return () => {
|
||||||
|
listeners = listeners.filter((l) => l !== listener);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function recordRecentTool(toolId: string) {
|
||||||
|
const current = getSnapshot();
|
||||||
|
const updated = [toolId, ...current.filter((id) => id !== toolId)].slice(0, MAX_RECENT);
|
||||||
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
|
||||||
|
listeners.forEach((l) => l());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useRecentTools(): string[] {
|
||||||
|
return useSyncExternalStore(subscribe, getSnapshot, () => []);
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ import type { PreviewTransform } from "@/components/tools/rotate-settings";
|
|||||||
import { useTranslation } from "@/contexts/i18n-context";
|
import { useTranslation } from "@/contexts/i18n-context";
|
||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import { useMobile } from "@/hooks/use-mobile";
|
import { useMobile } from "@/hooks/use-mobile";
|
||||||
|
import { recordRecentTool } from "@/hooks/use-recent-tools";
|
||||||
import { usePageTitle } from "@/hooks/use-page-title";
|
import { usePageTitle } from "@/hooks/use-page-title";
|
||||||
import { formatFileSize } from "@/lib/download";
|
import { formatFileSize } from "@/lib/download";
|
||||||
import { format } from "@/lib/format";
|
import { format } from "@/lib/format";
|
||||||
@@ -197,6 +198,13 @@ export function ToolPage() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAiTool) fetchFeatures();
|
if (isAiTool) fetchFeatures();
|
||||||
}, [isAiTool, fetchFeatures]);
|
}, [isAiTool, fetchFeatures]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (tool) {
|
||||||
|
recordRecentTool(tool.id);
|
||||||
|
}
|
||||||
|
}, [tool]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
files,
|
files,
|
||||||
entries,
|
entries,
|
||||||
|
|||||||
Reference in New Issue
Block a user