diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..f452a33 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +node_modules +src-tauri \ No newline at end of file diff --git a/.prettierrc.json5 b/.prettierrc.json5 index 652bd21..85ca632 100644 --- a/.prettierrc.json5 +++ b/.prettierrc.json5 @@ -4,4 +4,4 @@ singleQuote: false, trailingComma: "all", printWidth: 100, -} \ No newline at end of file +} diff --git a/postcss.config.js b/postcss.config.js index 2e7af2b..2aa7205 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -3,4 +3,4 @@ export default { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/src-tauri/src/kanji.rs b/src-tauri/src/kanji.rs index 0813676..3dc362d 100644 --- a/src-tauri/src/kanji.rs +++ b/src-tauri/src/kanji.rs @@ -1,4 +1,4 @@ -use sqlx::{Row, SqlitePool}; +use sqlx::{sqlite::SqliteRow, Row, SqlitePool}; use tauri::State; pub struct KanjiDb(pub SqlitePool); @@ -6,9 +6,7 @@ pub struct KanjiDb(pub SqlitePool); #[derive(Debug, Derivative, Serialize, Deserialize)] #[derivative(Default)] pub struct GetKanjiOptions { - /// For looking up an existing one - character: Option, - + #[serde(default)] #[derivative(Default(value = "10"))] how_many: u32, } @@ -26,47 +24,68 @@ pub struct GetKanjiResult { kanji: Vec, } +fn build_kanji(row: SqliteRow) -> Kanji { + let character = row.get("Character"); + let meaning = row.get("Meaning"); + let most_used_rank = row.get("MostUsedRank"); + Kanji { + character, + meaning, + most_used_rank, + } +} + #[tauri::command] pub async fn get_kanji( - state: State<'_, KanjiDb>, + db: State<'_, KanjiDb>, options: Option, ) -> Result { let opts = options.unwrap_or_default(); let result = sqlx::query( r#" - SELECT * FROM KanjiSet - LEFT JOIN KanjiMeaningSet ON KanjiSet.ID = KanjiMeaningSet.Kanji_ID - GROUP BY KanjiSet.ID - HAVING MostUsedRank IS NOT NULL - ORDER BY MostUsedRank - LIMIT ? + SELECT * FROM KanjiSet + LEFT JOIN KanjiMeaningSet ON KanjiSet.ID = KanjiMeaningSet.Kanji_ID + GROUP BY KanjiSet.ID + HAVING MostUsedRank IS NOT NULL + ORDER BY MostUsedRank + LIMIT ? "#, ) .bind(opts.how_many) - .fetch_all(&state.0) + .fetch_all(&db.0) .await .map_err(|_| ())?; - let kanji = result - .into_iter() - .map(|row| { - let character = row.get("Character"); - let meaning = row.get("Meaning"); - let most_used_rank = row.get("MostUsedRank"); - Kanji { - character, - meaning, - most_used_rank, - } - }) - .collect(); + let kanji = result.into_iter().map(build_kanji).collect(); let count = sqlx::query("SELECT COUNT(*) FROM KanjiSet") - .fetch_one(&state.0) + .fetch_one(&db.0) .await .map_err(|_| ())?; let count = count.try_get(0).map_err(|_| ())?; Ok(GetKanjiResult { kanji, count }) } + +#[tauri::command] +pub async fn get_single_kanji( + db: State<'_, KanjiDb>, + character: String, +) -> Result, ()> { + let result = sqlx::query( + r#" + SELECT * FROM KanjiSet + LEFT JOIN KanjiMeaningSet ON KanjiSet.ID = KanjiMeaningSet.Kanji_ID + GROUP BY KanjiSet.ID + HAVING MostUsedRank IS NOT NULL + AND Kanji.Character = ? + "#, + ) + .bind(character) + .fetch_one(&db.0) + .await + .map_err(|_| ())?; + + Ok(Some(build_kanji(result))) +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 9a3520f..25bbd41 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -41,7 +41,11 @@ async fn main() -> Result<()> { tauri::Builder::default() .manage(KanjiDb(kanji_pool)) .system_tray(tray) - .invoke_handler(tauri::generate_handler![greet, kanji::get_kanji]) + .invoke_handler(tauri::generate_handler![ + greet, + kanji::get_kanji, + kanji::get_single_kanji + ]) .run(tauri::generate_context!()) .context("error while running tauri application")?; diff --git a/src/App.module.scss b/src/App.module.scss index ad1797f..c678a43 100644 --- a/src/App.module.scss +++ b/src/App.module.scss @@ -15,9 +15,8 @@ main.main { flex-grow: 1; display: inline-block; padding: 12px; - } .link-active { background-color: skyblue; -} \ No newline at end of file +} diff --git a/src/App.tsx b/src/App.tsx index 14ba876..8628c3d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,10 @@ import { Link, RouterProvider, createHashRouter } from "react-router-dom"; import KanjiPane from "./panes/KanjiPane"; import classNames from "classnames"; -import { ChakraProvider } from '@chakra-ui/react' +import { ChakraProvider } from "@chakra-ui/react"; import HomePane from "./panes/HomePane"; import { createBrowserRouter } from "react-router-dom"; -import { Outlet, Route, createRoutesFromElements, useLocation } from "react-router"; +import { Outlet, Route, createRoutesFromElements, matchPath, useLocation } from "react-router"; import SrsPane from "./panes/SrsPane"; import VocabPane from "./panes/VocabPane"; import SettingsPane from "./panes/SettingsPane"; @@ -20,11 +20,15 @@ function Layout() {
    {routes.map((route) => { if (!route.title) return undefined; - const active = route.path == location.pathname; - const className = classNames(styles.link, active && styles['link-active']); - return
  • - {route.title} -
  • + const active = matchPath({ path: route.path }, location.pathname); + const className = classNames(styles.link, active && styles["link-active"]); + return ( +
  • + + {route.title} + +
  • + ); })}
@@ -38,22 +42,19 @@ export default function App() { createRoutesFromElements( }> {routes.map((route, idx) => ( - + ))} - - ) + , + ), ); - return - - - - + return ( + + + + + + ); } const routes = [ diff --git a/src/components/KanjiDisplay.module.scss b/src/components/KanjiDisplay.module.scss index 4b19e67..01b9844 100644 --- a/src/components/KanjiDisplay.module.scss +++ b/src/components/KanjiDisplay.module.scss @@ -7,4 +7,4 @@ $kanjiDisplaySize: 80px; font-size: $kanjiDisplaySize * 0.8; text-align: center; vertical-align: middle; -} \ No newline at end of file +} diff --git a/src/components/KanjiDisplay.tsx b/src/components/KanjiDisplay.tsx index 454f2b2..437f2fc 100644 --- a/src/components/KanjiDisplay.tsx +++ b/src/components/KanjiDisplay.tsx @@ -1,7 +1,7 @@ import { invoke } from "@tauri-apps/api/tauri"; import { GetKanjiResult } from "../panes/KanjiPane"; -import { Kanji } from "../types/Kanji" -import styles from "./KanjiDisplay.module.scss" +import { Kanji } from "../types/Kanji"; +import styles from "./KanjiDisplay.module.scss"; import useSWR from "swr"; interface KanjiDisplayProps { @@ -9,11 +9,23 @@ interface KanjiDisplayProps { } export default function KanjiDisplay({ kanjiCharacter }: KanjiDisplayProps) { - const { data, error, isLoading } = useSWR(["get_kanji", kanjiCharacter], invoke); + const { data, error, isLoading } = useSWR(["get_single_kanji", kanjiCharacter], ([command, character]) => invoke(command, { character })); - return <> -
- {kanjiCharacter} -
- -} \ No newline at end of file + return ( + <> +
{kanjiCharacter}
+ + {JSON.stringify(isLoading)} + +

+ data: + {JSON.stringify(data)} +

+ +

+ error: + {JSON.stringify(error)} +

+ + ); +} diff --git a/src/main.tsx b/src/main.tsx index 5b72ba0..441616f 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -7,5 +7,5 @@ import "./styles.css"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - + , ); diff --git a/src/panes/HomePane.tsx b/src/panes/HomePane.tsx index 8a8d289..65937d5 100644 --- a/src/panes/HomePane.tsx +++ b/src/panes/HomePane.tsx @@ -1,5 +1,3 @@ export default function HomePane() { - return <> - hellosu - -} \ No newline at end of file + return <>hellosu; +} diff --git a/src/panes/KanjiPane.module.scss b/src/panes/KanjiPane.module.scss index 0049012..7661505 100644 --- a/src/panes/KanjiPane.module.scss +++ b/src/panes/KanjiPane.module.scss @@ -7,4 +7,4 @@ .kanji-link { padding: 4px 8px; border: 1px solid lightgray; -} \ No newline at end of file +} diff --git a/src/panes/KanjiPane.tsx b/src/panes/KanjiPane.tsx index 05bf1d8..0e4eac3 100644 --- a/src/panes/KanjiPane.tsx +++ b/src/panes/KanjiPane.tsx @@ -14,24 +14,30 @@ export interface GetKanjiResult { interface KanjiListProps { data: GetKanjiResult; - selectedCharacter: string; + selectedCharacter?: string; } function KanjiList({ data, selectedCharacter }: KanjiListProps) { - return <> - Displaying {data.kanji.length} of {data.count} results. - - {data.kanji.map(kanji => - - {kanji.character} - {kanji.meaning} - #{kanji.most_used_rank} most used - - )} - - + return ( + <> + Displaying {data.kanji.length} of {data.count} results. + {data.kanji.map((kanji) => ( + + + + {kanji.character} + + {kanji.meaning} + #{kanji.most_used_rank} most used + + + ))} + + ); } export default function KanjiPane() { @@ -43,15 +49,15 @@ export default function KanjiPane() { {JSON.stringify(error)} {JSON.stringify(selectedKanji)} - - + + {data && } {selectedKanji ? : "nothing selected"} - + ); } diff --git a/src/panes/SettingsPane.tsx b/src/panes/SettingsPane.tsx index 769932c..e0f093a 100644 --- a/src/panes/SettingsPane.tsx +++ b/src/panes/SettingsPane.tsx @@ -1,3 +1,3 @@ export default function SettingsPane() { - return <> -} \ No newline at end of file + return <>; +} diff --git a/src/panes/SrsPane.tsx b/src/panes/SrsPane.tsx index 84830e8..fde7e52 100644 --- a/src/panes/SrsPane.tsx +++ b/src/panes/SrsPane.tsx @@ -1,3 +1,3 @@ export default function SrsPane() { - return <> -} \ No newline at end of file + return <>; +} diff --git a/src/panes/VocabPane.tsx b/src/panes/VocabPane.tsx index 234bfac..d84f6f2 100644 --- a/src/panes/VocabPane.tsx +++ b/src/panes/VocabPane.tsx @@ -1,3 +1,3 @@ export default function VocabPane() { - return <> -} \ No newline at end of file + return <>; +} diff --git a/src/styles.css b/src/styles.css index bd6213e..b5c61c9 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,3 +1,3 @@ @tailwind base; @tailwind components; -@tailwind utilities; \ No newline at end of file +@tailwind utilities; diff --git a/src/types/Kanji.ts b/src/types/Kanji.ts index 7882787..171d3ca 100644 --- a/src/types/Kanji.ts +++ b/src/types/Kanji.ts @@ -2,4 +2,4 @@ export interface Kanji { character: string; meaning: string; most_used_rank: number; -} \ No newline at end of file +} diff --git a/tailwind.config.js b/tailwind.config.js index fe0f090..be89b72 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,11 +1,10 @@ /** @type {import('tailwindcss').Config} */ export default { - content: ["./src/**/*.{html,js,jsx,ts,tsx}", - "./node_modules/flowbite/**/*.js"], + content: ["./src/**/*.{html,js,jsx,ts,tsx}", "./node_modules/flowbite/**/*.js"], theme: { extend: {}, }, plugins: [require("flowbite/plugin")], -}; \ No newline at end of file +};