feat(ui): guard desktop-only actions with a clear browser-preview message

This commit is contained in:
pj committed 2026-06-20 14:30:07 -04:00
1 parent f8ddde5e91
commit 5e1582fc39
3 files changed
+20 -4

No files matched your search

+16
View File
@@ -10,6 +10,10 @@ import { useBook } from "./store/useBook";
import type { Book } from "./model/book"; import type { Book } from "./model/book";
import { chooseSavePath, openBook, writeBook } from "./project"; import { chooseSavePath, openBook, writeBook } from "./project";
import { exportEpub, exportPdf } from "./export/exporters"; import { exportEpub, exportPdf } from "./export/exporters";
import { isDesktop } from "./ipc";
const DESKTOP_ONLY =
'This runs in the desktop app only — open the window from "pnpm tauri dev" (you are viewing the browser preview).';
function App() { function App() {
const [dock, setDock] = useState(true); const [dock, setDock] = useState(true);
@@ -31,6 +35,10 @@ function App() {
const chapter = chapters[idx]; const chapter = chapters[idx];
const handleSave = useCallback(async () => { const handleSave = useCallback(async () => {
if (!isDesktop) {
setNotice(DESKTOP_ONLY);
return;
}
try { try {
const { book, path } = useBook.getState(); const { book, path } = useBook.getState();
const target = path ?? (await chooseSavePath(book)); const target = path ?? (await chooseSavePath(book));
@@ -44,6 +52,10 @@ function App() {
}, [markSaved]); }, [markSaved]);
const handleOpen = useCallback(async () => { const handleOpen = useCallback(async () => {
if (!isDesktop) {
setNotice(DESKTOP_ONLY);
return;
}
try { try {
const result = await openBook(); const result = await openBook();
if (result) replaceBook(result.book, result.path); if (result) replaceBook(result.book, result.path);
@@ -54,6 +66,10 @@ function App() {
const runExport = async (label: string, fn: (book: Book) => Promise<void>) => { const runExport = async (label: string, fn: (book: Book) => Promise<void>) => {
setExportOpen(false); setExportOpen(false);
if (!isDesktop) {
setNotice(DESKTOP_ONLY);
return;
}
try { try {
await fn(useBook.getState().book); await fn(useBook.getState().book);
} catch (e) { } catch (e) {
+2 -4
View File
@@ -3,7 +3,7 @@ import { generateHTML } from "@tiptap/core";
import { useBook } from "../store/useBook"; import { useBook } from "../store/useBook";
import { editorExtensions } from "../editor/extensions"; import { editorExtensions } from "../editor/extensions";
import { bookToPdfInputs } from "../export/typst"; import { bookToPdfInputs } from "../export/typst";
import { compilePdf } from "../ipc"; import { compilePdf, isDesktop } from "../ipc";
import { PdfPreview } from "./PdfPreview"; import { PdfPreview } from "./PdfPreview";
const TRIM_LABEL: Record<string, string> = { const TRIM_LABEL: Record<string, string> = {
@@ -13,10 +13,8 @@ const TRIM_LABEL: Record<string, string> = {
a5: "A5", a5: "A5",
}; };
const inTauri = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
export function Dock() { export function Dock() {
return inTauri ? <PdfDock /> : <HtmlDock />; return isDesktop ? <PdfDock /> : <HtmlDock />;
} }
function PdfDock() { function PdfDock() {
+2
View File
@@ -1,5 +1,7 @@
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
export const isDesktop = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
export interface ImageInput { export interface ImageInput {
path: string; path: string;
data: string; data: string;