Compare commits
No commits in common. "170ef52154f7a923c39e2bf4ce96673e40dfc65c" and "d249d0f00d2b543a1b9bb8cab65a4faa3b1c83db" have entirely different histories.
170ef52154
...
d249d0f00d
3 changed files with 8 additions and 34 deletions
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "folio",
|
"name": "folio",
|
||||||
"version": "0.1.3",
|
"version": "0.1.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "folio",
|
"name": "folio",
|
||||||
"version": "0.1.3",
|
"version": "0.1.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tiptap/core": "^2.27.2",
|
"@tiptap/core": "^2.27.2",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "folio",
|
"name": "folio",
|
||||||
"version": "0.1.3",
|
"version": "0.1.2",
|
||||||
"description": "A simple, local, open-source desktop writing app.",
|
"description": "A simple, local, open-source desktop writing app.",
|
||||||
"productName": "Folio",
|
"productName": "Folio",
|
||||||
"author": "Folio Contributors",
|
"author": "Folio Contributors",
|
||||||
|
|
|
||||||
|
|
@ -502,36 +502,14 @@ function currentBookTitle(): string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GTK save dialogs started with a bare filename (no directory) re-synthesize
|
|
||||||
// the name from the last-browsed folder when the user navigates, producing
|
|
||||||
// names like "Some Folder/.odt". Always hand them an absolute path. The last
|
|
||||||
// export folder is remembered so exports reopen where the user left them.
|
|
||||||
function exportDefaultPath(filename: string): string {
|
|
||||||
const last = getSetting<string>("lastExportDir", "");
|
|
||||||
const dir =
|
|
||||||
last && fs.existsSync(last) && fs.statSync(last).isDirectory()
|
|
||||||
? last
|
|
||||||
: app.getPath("documents");
|
|
||||||
return path.join(dir, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rememberExportDir(filePath: string): void {
|
|
||||||
try {
|
|
||||||
setSetting("lastExportDir", path.dirname(filePath));
|
|
||||||
} catch {
|
|
||||||
// best-effort only
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleIpc("folio:exportMarkdown", async () => {
|
handleIpc("folio:exportMarkdown", async () => {
|
||||||
const bp = requireBook();
|
const bp = requireBook();
|
||||||
const { canceled, filePath } = await showSaveDialog({
|
const { canceled, filePath } = await showSaveDialog({
|
||||||
title: "Export combined Markdown",
|
title: "Export combined Markdown",
|
||||||
defaultPath: exportDefaultPath(`${currentBookTitle()}.md`),
|
defaultPath: `${currentBookTitle()}.md`,
|
||||||
filters: [{ name: "Markdown", extensions: ["md"] }],
|
filters: [{ name: "Markdown", extensions: ["md"] }],
|
||||||
});
|
});
|
||||||
if (canceled || !filePath) return { canceled: true } as const;
|
if (canceled || !filePath) return { canceled: true } as const;
|
||||||
rememberExportDir(filePath);
|
|
||||||
fs.writeFileSync(filePath, combineMarkdown(bp), "utf-8");
|
fs.writeFileSync(filePath, combineMarkdown(bp), "utf-8");
|
||||||
return { ok: true, filePath };
|
return { ok: true, filePath };
|
||||||
});
|
});
|
||||||
|
|
@ -540,11 +518,10 @@ handleIpc("folio:exportZip", async () => {
|
||||||
const bp = requireBook();
|
const bp = requireBook();
|
||||||
const { canceled, filePath } = await showSaveDialog({
|
const { canceled, filePath } = await showSaveDialog({
|
||||||
title: "Export book bundle (ZIP)",
|
title: "Export book bundle (ZIP)",
|
||||||
defaultPath: exportDefaultPath(`${currentBookTitle()}.zip`),
|
defaultPath: `${currentBookTitle()}.zip`,
|
||||||
filters: [{ name: "ZIP Archive", extensions: ["zip"] }],
|
filters: [{ name: "ZIP Archive", extensions: ["zip"] }],
|
||||||
});
|
});
|
||||||
if (canceled || !filePath) return { canceled: true } as const;
|
if (canceled || !filePath) return { canceled: true } as const;
|
||||||
rememberExportDir(filePath);
|
|
||||||
const buf = await buildZip(bp);
|
const buf = await buildZip(bp);
|
||||||
fs.writeFileSync(filePath, buf);
|
fs.writeFileSync(filePath, buf);
|
||||||
return { ok: true, filePath };
|
return { ok: true, filePath };
|
||||||
|
|
@ -572,12 +549,11 @@ requireBook();
|
||||||
} else {
|
} else {
|
||||||
const { canceled, filePath: chosen } = await showSaveDialog({
|
const { canceled, filePath: chosen } = await showSaveDialog({
|
||||||
title: "Export as PDF",
|
title: "Export as PDF",
|
||||||
defaultPath: exportDefaultPath(`${base}${suffix}.pdf`),
|
defaultPath: `${base}${suffix}.pdf`,
|
||||||
filters: [{ name: "PDF Document", extensions: ["pdf"] }],
|
filters: [{ name: "PDF Document", extensions: ["pdf"] }],
|
||||||
});
|
});
|
||||||
if (canceled || !chosen) return { canceled: true } as const;
|
if (canceled || !chosen) return { canceled: true } as const;
|
||||||
filePath = chosen.endsWith(".pdf") ? chosen : `${chosen}.pdf`;
|
filePath = chosen.endsWith(".pdf") ? chosen : `${chosen}.pdf`;
|
||||||
rememberExportDir(filePath);
|
|
||||||
}
|
}
|
||||||
const win = getWindow();
|
const win = getWindow();
|
||||||
if (!win) return { error: "No window is open." };
|
if (!win) return { error: "No window is open." };
|
||||||
|
|
@ -614,7 +590,7 @@ async function exportOffice(format: "docx" | "odt", chapterIds?: string[] | null
|
||||||
} else {
|
} else {
|
||||||
const { canceled, filePath: chosen } = await showSaveDialog({
|
const { canceled, filePath: chosen } = await showSaveDialog({
|
||||||
title: `Export${selected ? " Selected Chapters" : " Full Book"} as ${format.toUpperCase()}`,
|
title: `Export${selected ? " Selected Chapters" : " Full Book"} as ${format.toUpperCase()}`,
|
||||||
defaultPath: exportDefaultPath(`${base}${suffix}.${ext}`),
|
defaultPath: `${base}${suffix}.${ext}`,
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
name: format === "docx" ? "Word Document" : "OpenDocument Text",
|
name: format === "docx" ? "Word Document" : "OpenDocument Text",
|
||||||
|
|
@ -624,7 +600,6 @@ async function exportOffice(format: "docx" | "odt", chapterIds?: string[] | null
|
||||||
});
|
});
|
||||||
if (canceled || !chosen) return { canceled: true } as const;
|
if (canceled || !chosen) return { canceled: true } as const;
|
||||||
filePath = chosen.endsWith(`.${ext}`) ? chosen : `${chosen}.${ext}`;
|
filePath = chosen.endsWith(`.${ext}`) ? chosen : `${chosen}.${ext}`;
|
||||||
rememberExportDir(filePath);
|
|
||||||
}
|
}
|
||||||
const meta = loadBook(bp);
|
const meta = loadBook(bp);
|
||||||
const chapters = selected
|
const chapters = selected
|
||||||
|
|
@ -656,11 +631,10 @@ handleIpc("folio:saveChapterAs", async (_e, id: string) => {
|
||||||
if (!entry) return { error: "Chapter not found" };
|
if (!entry) return { error: "Chapter not found" };
|
||||||
const { canceled, filePath } = await showSaveDialog({
|
const { canceled, filePath } = await showSaveDialog({
|
||||||
title: "Save Chapter As",
|
title: "Save Chapter As",
|
||||||
defaultPath: exportDefaultPath(`${entry.title}.md`),
|
defaultPath: `${entry.title}.md`,
|
||||||
filters: [{ name: "Markdown", extensions: ["md"] }],
|
filters: [{ name: "Markdown", extensions: ["md"] }],
|
||||||
});
|
});
|
||||||
if (canceled || !filePath) return { canceled: true } as const;
|
if (canceled || !filePath) return { canceled: true } as const;
|
||||||
rememberExportDir(filePath);
|
|
||||||
const content = getChapterContent(bp, id);
|
const content = getChapterContent(bp, id);
|
||||||
fs.writeFileSync(filePath, content, "utf-8");
|
fs.writeFileSync(filePath, content, "utf-8");
|
||||||
return { ok: true, filePath };
|
return { ok: true, filePath };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue