diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..14061f572a98ac84dc0505dda07afc88e4caeee6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{js,jsx,ts,tsx,json,jsonc,css,md,yml,yaml}] +indent_style = space +indent_size = 2 + +[*.rs] +indent_style = space +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000000000000000000000000000000000000..03da83a829969cd0b8804a12d4039256d61be4c8 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,22 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "semi": false, + "singleQuote": true, + "jsxSingleQuote": true, + "sortImports": { + "internalPattern": ["@/"], + "newlinesBetween": true, + "groups": [ + "builtin", + "external", + "internal", + ["parent", "sibling", "index"], + "style", + "unknown" + ] + }, + "sortTailwindcss": { + "stylesheet": "ui/app/globals.css", + "functions": ["cn", "clsx", "cva", "tw"] + } +} diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 99092e48bd41f3b5ea8ea7479df6716149fdeb61..0000000000000000000000000000000000000000 --- a/.prettierrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "plugins": ["prettier-plugin-tailwindcss"], - "semi": false, - "singleQuote": true, - "jsxSingleQuote": true -} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..7302972d5098e3473b5ab4d4c6baeff5ce3919d5 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "oxc.oxc-vscode", + "EditorConfig.EditorConfig", + "bradlc.vscode-tailwindcss", + "rust-lang.rust-analyzer" + ], + "unwantedRecommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] +} diff --git a/bun.lock b/bun.lock index c42207096fd5aa51c42ce0936193036a65dc6354..b5d6a67074e752600a091bea88fe1497ff8be1c5 100644 --- a/bun.lock +++ b/bun.lock @@ -7,8 +7,7 @@ "@playwright/test": "^1.59.1", "@tauri-apps/cli": "^2.10.1", "git-cliff": "^2.12.0", - "prettier": "^3.8.3", - "prettier-plugin-tailwindcss": "^0.7.2", + "oxfmt": "^0.45.0", }, }, "ui": { @@ -371,6 +370,44 @@ "@orval/zod": ["@orval/zod@8.8.0", "", { "dependencies": { "@orval/core": "8.8.0", "remeda": "^2.33.6" } }, "sha512-ouKzo7srJXuwsZmNzp8nXkM6lwiYCZoSRYFH1JFAYF77SK7AEoFul8AYObzebqmHIXC4GLUNOsxHT9N0NE8zmQ=="], + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.45.0", "", { "os": "android", "cpu": "arm" }, "sha512-A/UMxFob1fefCuMeGxQBulGfFE38g2Gm23ynr3u6b+b7fY7/ajGbNsa3ikMIkGMLJW/TRoQaMoP1kME7S+815w=="], + + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.45.0", "", { "os": "android", "cpu": "arm64" }, "sha512-L63z4uZmHjgvvqvMJD7mwff8aSBkM0+X4uFr6l6U5t6+Qc9DCLVZWIunJ7Gm4fn4zHPdSq6FFQnhu9yqqobxIg=="], + + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.45.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UV34dd623FzqT+outIGndsCA/RBB+qgB3XVQhgmmJ9PJwa37NzPC9qzgKeOhPKxVk2HW+JKldQrVL54zs4Noww=="], + + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.45.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-pMNJv0CMa1pDefVPeNbuQxibh8ITpWDFEhMC/IBB9Zlu76EbgzYwrzI4Cb11mqX2+rIYN70UTrh3z06TM59ptQ=="], + + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.45.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-xTcRoxbbo61sW2+ZRPeH+vp/o9G8gkdhiVumFU+TpneiPm14c79l6GFlxPXlCE9bNWikigbsrvJw46zCVAQFfg=="], + + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.45.0", "", { "os": "linux", "cpu": "arm" }, "sha512-hWL8Hdni+3U1mPFx1UtWeGp3tNb6EhBAUHRMbKUxVkOp3WwoJbpVO2bfUVbS4PfpledviXXNHSTl1veTa6FhkQ=="], + + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.45.0", "", { "os": "linux", "cpu": "arm" }, "sha512-6Blt/0OBT7vvfQpqYuYbpbFLPqSiaYpEJzUUWhinPEuADypDbtV1+LdjM0vYBNGPvnj85ex7lTerEX6JGcPt9w=="], + + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.45.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jLjoLfe+hGfjhA8hNBSdw85yCA8ePKq7ME4T+g6P9caQXvmt6IhE2X7iVjnVdkmYUWEzZrxlh4p6RkDmAMJY/A=="], + + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.45.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-XQKXZIKYJC3GQJ8FnD3iMntpw69Wd9kDDK/Xt79p6xnFYlGGxSNv2vIBvRTDg5CKByWFWWZLCRDOXoP/m6YN4g=="], + + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.45.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+g5RiG+xOkdrCWkKodv407nTvMq4vYM18Uox2MhZBm/YoqFxxJpWKsloskFFG5NU13HGPw1wzYjjOVcyd9moCA=="], + + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.45.0", "", { "os": "linux", "cpu": "none" }, "sha512-V7dXKoSyEbWAkkSF4JJNtF+NJZDmJoSarSoP30WCsB3X636Rehd3CvxBj49FIJxEBFWhvcUjGSHVeU8Erck1bQ=="], + + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.45.0", "", { "os": "linux", "cpu": "none" }, "sha512-Vdelft1sAEYojVGgcODEFXSWYQYlIvoyIGWebKCuUibd1tvS1TjTx413xG2ZLuHpYj45CkN/ztMLMX6jrgqpgg=="], + + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.45.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-RR7xKgNpqwENnK0aYCGYg0JycY2n93J0reNjHyes+I9Gq52dH95x+CBlnlAQHCPfz6FGnKA9HirgUl14WO6o7w=="], + + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.45.0", "", { "os": "linux", "cpu": "x64" }, "sha512-U/QQ0+BQNSHxjuXR/utvXnQ50Vu5kUuqEomZvQ1/3mhgbBiMc2WU9q5kZ5WwLp3gnFIx9ibkveoRSe2EZubkqg=="], + + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.45.0", "", { "os": "linux", "cpu": "x64" }, "sha512-o5TLOUCF0RWQjsIS06yVC+kFgp092/yLe6qBGSUvtnmTVw9gxjpdQSXc3VN5Cnive4K11HNstEZF8ROKHfDFSw=="], + + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.45.0", "", { "os": "none", "cpu": "arm64" }, "sha512-RnGcV3HgPuOjsGx/k9oyRNKmOp+NBLGzZTdPDYbc19r7NGeYPplnUU/BfU35bX2Y/O4ejvHxcfkvW2WoYL/gsg=="], + + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.45.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-v3Vj7iKKsUFwt9w5hsqIIoErKVoENC6LoqfDlteOQ5QMDCXihlqLoxpmviUhXnNncg4zV6U9BPwlBbwa+qm4wg=="], + + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.45.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-N8yotPBX6ph0H3toF4AEpdCeVPrdcSetj+8eGiZGsrLsng3bs/Q5HPu4bbSxip5GBPx5hGbGHrZwH4+rcrjhHA=="], + + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.45.0", "", { "os": "win32", "cpu": "x64" }, "sha512-w5MMTRCK1dpQeRA+HHqXQXyN33DlG/N2LOYxJmaT4fJjcmZrbNnqw7SmIk7I2/a2493PPLZ+2E/Ar6t2iKVMug=="], + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.60.0", "", { "os": "android", "cpu": "arm" }, "sha512-YdeJKaZckDQL1qa62a1aKq/goyq48aX3yOxaaWqWb4sau4Ee4IiLbamftNLU3zbePky6QsDj6thnSSzHRBjDfA=="], "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.60.0", "", { "os": "android", "cpu": "arm64" }, "sha512-7ANS7PpXCfq84xZQ8E5WPs14gwcuPcl+/8TFNXfpSu0CQBXz3cUo2fDpHT8v8HJN+Ut02eacvMAzTnc9s6X4tw=="], @@ -1211,6 +1248,8 @@ "orval": ["orval@8.8.0", "", { "dependencies": { "@commander-js/extra-typings": "^14.0.0", "@orval/angular": "8.8.0", "@orval/axios": "8.8.0", "@orval/core": "8.8.0", "@orval/fetch": "8.8.0", "@orval/hono": "8.8.0", "@orval/mcp": "8.8.0", "@orval/mock": "8.8.0", "@orval/query": "8.8.0", "@orval/solid-start": "8.8.0", "@orval/swr": "8.8.0", "@orval/zod": "8.8.0", "@scalar/json-magic": "^0.12.4", "@scalar/openapi-parser": "^0.25.6", "@scalar/openapi-types": "0.6.1", "chokidar": "^5.0.0", "commander": "^14.0.2", "enquirer": "^2.4.1", "execa": "^9.6.1", "find-up": "8.0.0", "fs-extra": "^11.3.2", "jiti": "^2.6.1", "js-yaml": "4.1.1", "remeda": "^2.33.6", "string-argv": "^0.3.2", "tsconfck": "^3.1.6", "typedoc": "^0.28.17", "typedoc-plugin-coverage": "^4.0.2", "typedoc-plugin-markdown": "^4.10.0" }, "peerDependencies": { "prettier": ">=3.0.0" }, "optionalPeers": ["prettier"], "bin": { "orval": "dist/bin/orval.mjs" } }, "sha512-jcHcAmXCvC0g+1acsUOv722ICuXCJ0tmRl3+e0kj1lgFVsuGYame+jRZUrNtpkEZgF1RlDtmL91yFsVHv3X1eA=="], + "oxfmt": ["oxfmt@0.45.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.45.0", "@oxfmt/binding-android-arm64": "0.45.0", "@oxfmt/binding-darwin-arm64": "0.45.0", "@oxfmt/binding-darwin-x64": "0.45.0", "@oxfmt/binding-freebsd-x64": "0.45.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.45.0", "@oxfmt/binding-linux-arm-musleabihf": "0.45.0", "@oxfmt/binding-linux-arm64-gnu": "0.45.0", "@oxfmt/binding-linux-arm64-musl": "0.45.0", "@oxfmt/binding-linux-ppc64-gnu": "0.45.0", "@oxfmt/binding-linux-riscv64-gnu": "0.45.0", "@oxfmt/binding-linux-riscv64-musl": "0.45.0", "@oxfmt/binding-linux-s390x-gnu": "0.45.0", "@oxfmt/binding-linux-x64-gnu": "0.45.0", "@oxfmt/binding-linux-x64-musl": "0.45.0", "@oxfmt/binding-openharmony-arm64": "0.45.0", "@oxfmt/binding-win32-arm64-msvc": "0.45.0", "@oxfmt/binding-win32-ia32-msvc": "0.45.0", "@oxfmt/binding-win32-x64-msvc": "0.45.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-0o/COoN9fY50bjVeM7PQsNgbhndKurBIeTIcspW033OumksjJJmIVDKjAk5HMwU/GHTxSOdGDdhJ6BRzGPmsHg=="], + "oxlint": ["oxlint@1.60.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.60.0", "@oxlint/binding-android-arm64": "1.60.0", "@oxlint/binding-darwin-arm64": "1.60.0", "@oxlint/binding-darwin-x64": "1.60.0", "@oxlint/binding-freebsd-x64": "1.60.0", "@oxlint/binding-linux-arm-gnueabihf": "1.60.0", "@oxlint/binding-linux-arm-musleabihf": "1.60.0", "@oxlint/binding-linux-arm64-gnu": "1.60.0", "@oxlint/binding-linux-arm64-musl": "1.60.0", "@oxlint/binding-linux-ppc64-gnu": "1.60.0", "@oxlint/binding-linux-riscv64-gnu": "1.60.0", "@oxlint/binding-linux-riscv64-musl": "1.60.0", "@oxlint/binding-linux-s390x-gnu": "1.60.0", "@oxlint/binding-linux-x64-gnu": "1.60.0", "@oxlint/binding-linux-x64-musl": "1.60.0", "@oxlint/binding-openharmony-arm64": "1.60.0", "@oxlint/binding-win32-arm64-msvc": "1.60.0", "@oxlint/binding-win32-ia32-msvc": "1.60.0", "@oxlint/binding-win32-x64-msvc": "1.60.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-tnRzTWiWJ9pg3ftRWnD0+Oqh78L6ZSwcEudvCZaER0PIqiAnNyXj5N1dPwjmNpDalkKS9m/WMLN1CTPUBPmsgw=="], "p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="], @@ -1255,8 +1294,6 @@ "prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="], - "prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.7.2", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-hermes": "*", "@prettier/plugin-oxc": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-multiline-arrays": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-hermes", "@prettier/plugin-oxc", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-multiline-arrays", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-svelte"] }, "sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA=="], - "pretty-ms": ["pretty-ms@9.3.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ=="], "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], @@ -1375,6 +1412,8 @@ "terser-webpack-plugin": ["terser-webpack-plugin@5.4.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "terser": "^5.31.1" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g=="], + "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], diff --git a/package.json b/package.json index cc8a64dce98fee23a98f012b1e134856eddc55e5..f5db63adfe355dbe8c65150fc849a89341d2fe06 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,20 @@ { - "devDependencies": { - "@playwright/test": "^1.59.1", - "@tauri-apps/cli": "^2.10.1", - "git-cliff": "^2.12.0", - "prettier": "^3.8.3", - "prettier-plugin-tailwindcss": "^0.7.2" - }, + "workspaces": [ + "ui/" + ], "scripts": { "dev": "bun run scripts/dev.ts tauri dev -- --profile=release-with-debug", "build": "bun run scripts/dev.ts tauri build --no-bundle", "cargo": "bun run scripts/dev.ts cargo", "lint:ui": "bun run --filter ui lint", - "format": "prettier --write ui/ --ignore-path ui/.gitignore", + "format": "oxfmt ui package.json .oxfmtrc.json .vscode", + "format:check": "oxfmt --check ui package.json .oxfmtrc.json .vscode", "test:e2e": "playwright test" }, - "workspaces": [ - "ui/" - ] + "devDependencies": { + "@playwright/test": "^1.59.1", + "@tauri-apps/cli": "^2.10.1", + "git-cliff": "^2.12.0", + "oxfmt": "^0.45.0" + } } diff --git a/ui/.oxlintrc.json b/ui/.oxlintrc.json index 8b323020423f935cfceb82f5b7012b8c421aef72..f1c796096ed7449a1c8a17829c2459a65c92bf09 100644 --- a/ui/.oxlintrc.json +++ b/ui/.oxlintrc.json @@ -1,12 +1,6 @@ { "$schema": "../node_modules/oxlint/configuration_schema.json", - "plugins": [ - "eslint", - "typescript", - "unicorn", - "oxc", - "react" - ], + "plugins": ["eslint", "typescript", "unicorn", "oxc", "react"], "categories": { "correctness": "error" }, @@ -30,11 +24,5 @@ "typescript/no-this-alias": "warn", "unicorn/prefer-string-starts-ends-with": "warn" }, - "ignorePatterns": [ - ".next/", - "out/", - "dist/", - "build/", - "coverage/" - ] + "ignorePatterns": [".next/", "out/", "dist/", "build/", "coverage/"] } diff --git a/ui/app/(app)/layout.tsx b/ui/app/(app)/layout.tsx index 5963d122c42fe33e1f7ae4e485969a1e4e836c9d..994a9eac1854ac316e7350d029fa64c1f5e6a162 100644 --- a/ui/app/(app)/layout.tsx +++ b/ui/app/(app)/layout.tsx @@ -4,7 +4,7 @@ import { MenuBar } from '@/components/MenuBar' export default function AppLayout({ children }: { children: React.ReactNode }) { return ( -
- Something went wrong. -
{errorMessage}
Something went wrong.
- {t('common.initializing')} -
{t('common.initializing')}
+
{progress?.filename ?? '\u00A0'}
{t('navigator.title')}
- {totalPages - ? t('navigator.pages', { count: totalPages }) - : t('navigator.empty')} +
+ {totalPages ? t('navigator.pages', { count: totalPages }) : t('navigator.empty')}
+ + {t('settings.title')} {TABS.map(({ id, icon: Icon, labelKey }) => ( @@ -288,7 +264,7 @@ export function SettingsDialog({ key={id} onClick={() => setTab(id)} data-active={tab === id} - className='text-muted-foreground hover:text-foreground data-[active=true]:bg-accent data-[active=true]:text-accent-foreground flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition' + className='flex items-center gap-3 rounded-lg px-3 py-2 text-sm text-muted-foreground transition hover:text-foreground data-[active=true]:bg-accent data-[active=true]:text-accent-foreground' > {t(labelKey)} @@ -322,12 +298,8 @@ export function SettingsDialog({ base_url: v || null, })) } - onBaseUrlBlur={() => - appConfig && void persistConfig(appConfig) - } - onApiKeyChange={(id, v) => - setApiKeyDrafts((c) => ({ ...c, [id]: v })) - } + onBaseUrlBlur={() => appConfig && void persistConfig(appConfig)} + onApiKeyChange={(id, v) => setApiKeyDrafts((c) => ({ ...c, [id]: v }))} onSaveKey={(id) => { const key = apiKeyDrafts[id]?.trim() if (!key || !appConfig) return @@ -349,8 +321,7 @@ export function SettingsDialog({ if (!appConfig) return const providers = [...(appConfig.providers ?? [])] const idx = providers.findIndex((p) => p.id === id) - if (idx >= 0) - providers[idx] = { ...providers[idx], api_key: null } + if (idx >= 0) providers[idx] = { ...providers[idx], api_key: null } void persistConfig({ ...appConfig, providers }).then(() => setApiKeyDrafts((c) => { const n = { ...c } @@ -428,7 +399,7 @@ function AppearancePane() { key={value} onClick={() => setTheme(value)} data-active={theme === value} - className='border-border bg-card text-muted-foreground hover:border-foreground/30 data-[active=true]:border-primary data-[active=true]:text-foreground flex flex-col items-center gap-2 rounded-xl border px-4 py-4 transition' + className='flex flex-col items-center gap-2 rounded-xl border border-border bg-card px-4 py-4 text-muted-foreground transition hover:border-foreground/30 data-[active=true]:border-primary data-[active=true]:text-foreground' > {t(labelKey)} @@ -438,10 +409,7 @@ function AppearancePane() { - i18n.changeLanguage(v)} - > + i18n.changeLanguage(v)}> @@ -512,9 +480,7 @@ function EnginesPane({ return ( - - {t('settings.enginesDescription')} - + {t('settings.enginesDescription')} {sections.map(({ label, key, engines }) => ( {label} @@ -564,17 +530,14 @@ function ProvidersPane({ if (!catalogs.length) return ( - + {t('settings.loadingProviders')} ) return ( - + {catalogs.map((provider) => { const cfg = config?.providers?.find((p) => p.id === provider.id) @@ -590,37 +553,25 @@ function ProvidersPane({ : 'bg-muted-foreground' return ( - + - + {provider.name} {provider.error && ( - - {provider.error} - + {provider.error} )} {provider.requiresBaseUrl && ( - - {t('settings.localLlmBaseUrl')} - + {t('settings.localLlmBaseUrl')} - onBaseUrlChange(provider.id, e.target.value) - } + onChange={(e) => onBaseUrlChange(provider.id, e.target.value)} onBlur={onBaseUrlBlur} placeholder='https://api.example.com/v1' /> @@ -633,12 +584,9 @@ function ProvidersPane({ - onApiKeyChange(provider.id, e.target.value) - } + onChange={(e) => onApiKeyChange(provider.id, e.target.value)} onKeyDown={(e) => { - if (e.key === 'Enter' && hasDraft) - onSaveKey(provider.id) + if (e.key === 'Enter' && hasDraft) onSaveKey(provider.id) }} placeholder={ cfg?.api_key === '[REDACTED]' @@ -648,10 +596,7 @@ function ProvidersPane({ className='[&::-ms-reveal]:hidden' /> {hasDraft ? ( - onSaveKey(provider.id)} - > + onSaveKey(provider.id)}> {t('settings.apiKeySave')} ) : cfg?.api_key === '[REDACTED]' ? ( @@ -697,9 +642,7 @@ function KeybindsPane() { const { t } = useTranslation() const shortcuts = usePreferencesStore((state) => state.shortcuts) const setShortcuts = usePreferencesStore((state) => state.setShortcuts) - const resetShortcutsStore = usePreferencesStore( - (state) => state.resetShortcuts, - ) + const resetShortcutsStore = usePreferencesStore((state) => state.resetShortcuts) const [pendingShortcuts, setPendingShortcuts] = useState(shortcuts) const [recordingKey, setRecordingKey] = useState(null) const [error, setError] = useState(null) @@ -821,20 +764,14 @@ function KeybindsPane() { return ( - - + + {SHORTCUT_ITEMS.map((item) => { const currentVal = pendingShortcuts[item.key] const hasConflict = (conflictCounts.get(currentVal) || 0) > 1 return ( - + {t(item.labelKey)} {hasConflict && ( @@ -863,11 +800,11 @@ function KeybindsPane() { - + @@ -898,9 +835,7 @@ function KeybindsPane() { {t('settings.shortcutReset')} - - {t('settings.shortcutResetDescription')} - + {t('settings.shortcutResetDescription')} {t('common.cancel')} @@ -947,27 +882,18 @@ function StoragePane({ return ( <> - + {t('settings.dataPath')} - onPathChange(e.target.value)} - /> - + onPathChange(e.target.value)} /> + {t('settings.dataPathDescription')} - - {t('settings.httpConnectTimeout')} - + {t('settings.httpConnectTimeout')} onHttpConnectTimeoutChange(e.target.value)} /> - + {t('settings.httpConnectTimeoutDescription')} @@ -991,7 +917,7 @@ function StoragePane({ value={httpReadTimeout} onChange={(e) => onHttpReadTimeoutChange(e.target.value)} /> - + {t('settings.httpReadTimeoutDescription')} @@ -1007,20 +933,18 @@ function StoragePane({ value={httpMaxRetries} onChange={(e) => onHttpMaxRetriesChange(e.target.value)} /> - + {t('settings.httpMaxRetriesDescription')} - {error && {error}} + {error && {error}} setConfirmOpen(true)} disabled={!dataPath.trim() || saving || unchanged} > - {saving - ? t('settings.restartApplying') - : t('settings.restartApply')} + {saving ? t('settings.restartApplying') : t('settings.restartApply')} @@ -1067,30 +991,19 @@ function AboutPane({ return ( - + - - Koharu - - - {t('settings.aboutTagline')} - + Koharu + {t('settings.aboutTagline')} - + - - {version || '...'} - + {version || '...'} {status === 'loading' && ( - + )} {status === 'latest' && ( @@ -1120,9 +1033,7 @@ function AboutPane({ - void openExternalUrl('https://github.com/mayocream') - } + onClick={() => void openExternalUrl('https://github.com/mayocream')} > Mayo @@ -1131,9 +1042,7 @@ function AboutPane({ - void openExternalUrl(`https://github.com/${GITHUB_REPO}`) - } + onClick={() => void openExternalUrl(`https://github.com/${GITHUB_REPO}`)} > GitHub @@ -1158,11 +1067,9 @@ function Section({ return ( - {title} + {title} {description && ( - - {description} - + {description} )} {children} diff --git a/ui/components/Updater.tsx b/ui/components/Updater.tsx index d42e97a4c139388ffbc300b9a5bba090c05e3b84..2063f7779cf5f465289c4f19178e880a6810ab58 100644 --- a/ui/components/Updater.tsx +++ b/ui/components/Updater.tsx @@ -1,24 +1,14 @@ 'use client' -import { - createContext, - useContext, - useEffect, - useState, - type ReactNode, -} from 'react' import type { Update } from '@tauri-apps/plugin-updater' +import { Download, RefreshCw, AlertCircle } from 'lucide-react' +import { createContext, useContext, useEffect, useState, type ReactNode } from 'react' +import { Trans, useTranslation } from 'react-i18next' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' -import { Trans, useTranslation } from 'react-i18next' -import { Download, RefreshCw, AlertCircle } from 'lucide-react' -import { - Dialog, - DialogContent, - DialogDescription, - DialogTitle, -} from '@/components/ui/dialog' + import { Button } from '@/components/ui/button' +import { Dialog, DialogContent, DialogDescription, DialogTitle } from '@/components/ui/dialog' import { Progress } from '@/components/ui/progress' import { ScrollArea } from '@/components/ui/scroll-area' import { Separator } from '@/components/ui/separator' @@ -197,19 +187,17 @@ function PromptView({ return ( <> - + - - {t('updater.available.title')} - + {t('updater.available.title')} , + strong: , }} /> @@ -218,16 +206,12 @@ function PromptView({ {update.body ? ( - - - {update.body} - + + {update.body} ) : ( - - {t('updater.noNotes')} - + {t('updater.noNotes')} )}
{t('settings.title')}
- {t('settings.enginesDescription')} -
{t('settings.enginesDescription')}
{t('settings.loadingProviders')}
- {provider.error} -
{provider.error}
+ onPathChange(e.target.value)} /> +
{t('settings.dataPathDescription')}
{t('settings.httpConnectTimeoutDescription')}
{t('settings.httpReadTimeoutDescription')}
{t('settings.httpMaxRetriesDescription')}
{error}
- {t('settings.aboutTagline')} -
{t('settings.aboutTagline')}
- {description} -
{description}