diff --git a/biome.json b/biome.json index 99c2eab..2d26205 100644 --- a/biome.json +++ b/biome.json @@ -12,6 +12,7 @@ ".svelte-kit", "build", "src/lib/components/ui/**", + "src/lib/utils.ts", "src-tauri/**" ] }, diff --git a/bun.lockb b/bun.lockb index d8f67c6..e3d28a5 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index cfa2d06..25fa85b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "narrow", - "version": "0.1.0", + "version": "0.1.1", "description": "", "type": "module", "scripts": { @@ -12,17 +12,18 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "tauri": "tauri", "lint": "biome lint", - "format": "biome format --write" + "format": "biome format --write", + "bump": "bunx tauri-version patch" }, "license": "MIT", "dependencies": { "@fontsource-variable/m-plus-2": "^5.1.0", "@l4ph/web-novel-parser": "npm:@jsr/l4ph__web-novel-parser", "@macfja/svelte-persistent-store": "^2.4.1", - "@tauri-apps/api": "^2.0.0-rc.4", + "@tauri-apps/api": "^2.0.0-rc.5", "@tauri-apps/cli": "^2.0.0-rc.16", - "@tauri-apps/plugin-dialog": "^2.0.0-rc.1", - "@tauri-apps/plugin-fs": "^2.0.0-rc.2", + "@tauri-apps/plugin-dialog": "github:tauri-apps/tauri-plugin-dialog#v2", + "@tauri-apps/plugin-fs": "github:tauri-apps/tauri-plugin-fs#v2", "bits-ui": "^0.21.15", "clsx": "^2.1.1", "lucide-svelte": "^0.441.0", @@ -38,20 +39,20 @@ "@biomejs/biome": "1.9.2", "@svelte-put/shortcut": "^3.1.1", "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "^2.5.27", + "@sveltejs/kit": "^2.5.28", "@sveltejs/vite-plugin-svelte": "^4.0.0-next.7", "@tailwindcss/typography": "^0.5.15", - "@tailwindcss/vite": "^4.0.0-alpha.24", + "@tailwindcss/vite": "^4.0.0-alpha.25", "@types/bun": "latest", - "@types/node": "^22.5.5", + "@types/node": "^22.7.0", "autoprefixer": "^10.4.20", "eslint-plugin-svelte": "^2.44.0", - "svelte": "^5.0.0-next.257", + "svelte": "^5.0.0-next.259", "svelte-check": "^4.0.2", - "tailwindcss": "^4.0.0-alpha.24", - "tslib": "^2.4.1", + "tailwindcss": "^4.0.0-alpha.25", + "tslib": "^2.7.0", "typescript": "^5.6.2", - "vite": "^5.4.7" + "vite": "^5.4.8" }, "module": "index.ts" } diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 9750029..94abde8 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -195,9 +195,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.82" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", @@ -945,9 +945,9 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fdeflate" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" dependencies = [ "simd-adler32", ] @@ -1542,9 +1542,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", @@ -1555,7 +1555,6 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] @@ -1819,9 +1818,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libloading" @@ -2491,26 +2490,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "pin-project-lite" version = "0.2.14" @@ -2536,9 +2515,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plist" @@ -2768,9 +2747,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +checksum = "62871f2d65009c0256aed1b9cfeeb8ac272833c404e13d53d400cd0dad7a2ac0" dependencies = [ "bitflags 2.6.0", ] @@ -3406,9 +3385,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.30.1" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e7ede56f9ef03a0bb384c7b2bed4f3985ee7f3f79ec887c50d8466eec21096" +checksum = "06e48d7c56b3f7425d061886e8ce3b6acfab1993682ed70bef50fd133d721ee6" dependencies = [ "bitflags 2.6.0", "cocoa", @@ -3743,7 +3722,7 @@ dependencies = [ [[package]] name = "tawri" -version = "0.1.0" +version = "0.1.1" dependencies = [ "serde", "serde_json", @@ -3786,18 +3765,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -3949,27 +3928,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - [[package]] name = "tower-service" version = "0.3.3" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9130c85..88e45bd 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tawri" -version = "0.1.0" +version = "0.1.1" description = "A Tauri App" authors = ["L4Ph"] edition = "2021" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index b9fac87..21b023f 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -9,6 +9,7 @@ "core:default", "shell:allow-open", "fs:default", + "fs:allow-write-text-file", "dialog:default" ] } \ No newline at end of file diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 7e38ecd..440520d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "productName": "tawri", - "version": "0.1.0", + "version": "0.1.1", "identifier": "moe.l4ph.tawri", "build": { "beforeDevCommand": "bun run dev", @@ -31,4 +31,4 @@ "icons/icon.ico" ] } -} +} \ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 2302aa9..1ddc14b 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -6,11 +6,6 @@ import { insertRubyToTextarea } from "./utils/insert-ruby-to-textarea"; import { insertEmphasisToTextarea } from "./utils/insert-emphasis-to-textarea"; import * as Dialog from "$lib/components/ui/dialog"; import Button from "@/components/ui/button/button.svelte"; -import { - persist, - type PersistentStore, - createLocalStorage, -} from "@macfja/svelte-persistent-store"; import { writable } from "svelte/store"; import CodeMirror from "svelte-codemirror-editor"; import ScrollArea from "@/components/ui/scroll-area/scroll-area.svelte"; @@ -27,28 +22,29 @@ import { isTauriApp } from "./utils/is-tauri-app"; import { open as openDialog } from "@tauri-apps/plugin-dialog"; import { listen } from "@tauri-apps/api/event"; import { readTextFileOnTauri } from "./utils/read-text-file-on-tauri"; +import { writeTextFileOnTauri } from "./utils/write-text-file-on-tauri"; -let inputText: PersistentStore = persist( - writable(""), - createLocalStorage(), - "inputText", -); -let preview = ""; +let inputText = $state(""); let textarea: Textarea; -let open = true; -let fileInput: HTMLInputElement; +let open = $state(true); +let fileInput = $state(null); +let textFilePath = $state(""); +let preview = $derived.by(() => { + const parsedHtml = parseNarouNovel(inputText); + return parsedHtml; +}); let urlSearchParams = $page.url.searchParams; if (urlSearchParams) { const result = generateSearchParamsToText(urlSearchParams); if (result) { - inputText.set(result); + inputText = result; } } function handleFileChange(event: Event) { readTextFileOnBrowser(event, (text: string) => { - inputText.set(text); + inputText = text; }); } @@ -57,8 +53,6 @@ function CopyUrlToClipboard(inputText: string) { navigator.clipboard.writeText(url); } -$: preview = parseNarouNovel($inputText); - if (isTauriApp()) { listen("open_file", async () => { try { @@ -72,11 +66,37 @@ if (isTauriApp()) { }, ], }); - readTextFileOnTauri(filePath); + if (filePath) { + textFilePath = filePath; + } + const text = await readTextFileOnTauri(filePath); + if (text !== undefined) { + inputText = text; + toast.success("ファイルを正常に読み込みました。"); + } } catch (error) { console.error("エラーが発生しました:", error); } }); + + listen("save_file", async () => { + try { + writeTextFileOnTauri(textFilePath, inputText); + toast.success("ファイルが正常に保存されました。"); + } catch (error) { + console.error("ファイル保存中にエラーが発生しました:", error); + toast.error("ファイルの保存に失敗しました。"); + } + }); + + listen("save_as", async () => { + try { + toast.info(`"名前を付けて保存"機能は現在開発中です。`); + } catch (error) { + console.error("ファイル保存中にエラーが発生しました:", error); + toast.error("ファイルの保存に失敗しました。"); + } + }); } @@ -87,16 +107,16 @@ if (isTauriApp()) { key: 'i', modifier: 'ctrl', callback: () => { - const updatedText = insertRubyToTextarea(textarea, $inputText) || $inputText; - inputText.set(updatedText); + const updatedText = insertRubyToTextarea(textarea, inputText) || inputText; + inputText = updatedText; } }, { key: 'b', modifier: 'ctrl', callback: () => { - const updatedText = insertEmphasisToTextarea(textarea, $inputText) || $inputText; - inputText.set(updatedText); + const updatedText = insertEmphasisToTextarea(textarea, inputText) || inputText; + inputText = updatedText; } }, ], @@ -104,7 +124,7 @@ if (isTauriApp()) { />
- {#if ($inputText === "" || !inputText) && !isTauriApp() } + {#if (inputText === "" || !inputText) && !isTauriApp() } @@ -114,11 +134,11 @@ if (isTauriApp()) {

Ctrl + iでルビ / Ctrl + bで傍点が入力できます。

- - +
@@ -127,7 +147,7 @@ if (isTauriApp()) {
- {CopyUrlToClipboard($inputText)} }>URLをコピー - {toast("未実装です。")} }>小説本文をコピー + {#if !isTauriApp()} + {CopyUrlToClipboard(inputText)} }>URLをコピー + {/if} + { + // TODO: 小説本文のコピー機能を実装する + toast.info(`"小説本文をコピー"機能は現在開発中です。`); + } }>小説本文をコピー ルビを振る diff --git a/src/routes/utils/read-text-file-on-tauri.ts b/src/routes/utils/read-text-file-on-tauri.ts index fbd3921..75d1701 100644 --- a/src/routes/utils/read-text-file-on-tauri.ts +++ b/src/routes/utils/read-text-file-on-tauri.ts @@ -1,12 +1,21 @@ import { readTextFile } from "@tauri-apps/plugin-fs"; -export function readTextFileOnTauri(filePath: string | null) { - if (filePath && typeof filePath === "string") { - console.log("選択されたファイルのパス:", filePath); - const text = readTextFile(filePath); - console.log("ファイルの内容:", text); - // inputText.set(text) - } else { +export async function readTextFileOnTauri( + filePath: string | null, +): Promise { + if (!filePath || typeof filePath !== "string") { console.log("ファイルが選択されませんでした"); + return undefined; + } + + try { + const text = await readTextFile(filePath); + return text; + } catch (error) { + console.error( + `ファイル '${filePath}' の読み込み中にエラーが発生しました:`, + error, + ); + return undefined; } } diff --git a/src/routes/utils/write-text-file-on-tauri.ts b/src/routes/utils/write-text-file-on-tauri.ts new file mode 100644 index 0000000..d77deb9 --- /dev/null +++ b/src/routes/utils/write-text-file-on-tauri.ts @@ -0,0 +1,28 @@ +import { writeTextFile } from "@tauri-apps/plugin-fs"; + +export async function writeTextFileOnTauri( + filePath: string, + inputText: string, +) { + try { + await writeTextFile(filePath, inputText); + console.log("ファイルの書き込みに成功しました。"); + return true; + } catch (error) { + console.error("ファイルの書き込み中にエラーが発生しました:", error); + if (error instanceof Error) { + return { + success: false, + error: { + message: error.message, + name: error.name, + stack: error.stack, + }, + }; + } + return { + success: false, + error: "不明なエラーが発生しました。", + }; + } +} diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 0000000..cbcf866 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Sitemap : https://tawri.l4ph.moe/sitemap.xml \ No newline at end of file diff --git a/static/sitemap.xml b/static/sitemap.xml new file mode 100644 index 0000000..3da40a7 --- /dev/null +++ b/static/sitemap.xml @@ -0,0 +1,6 @@ + + + + https://tawri.l4ph.moe + + \ No newline at end of file