This commit is contained in:
Michael Zhang 2023-06-11 15:08:16 -05:00
parent d369118da3
commit ace93534ad
10 changed files with 95 additions and 27 deletions

1
.envrc
View file

@ -1,3 +1,4 @@
strict_env strict_env
export HOUHOU_SRC=$PWD export HOUHOU_SRC=$PWD
export DATABASE_URL=$HOUHOU_SRC/src-tauri/SrsDatabase.sqlite

View file

@ -4,3 +4,5 @@
*-shm *-shm
*-wal *-wal
SrsDatabase.sqlite

View file

@ -0,0 +1,18 @@
CREATE TABLE [SrsEntrySet] (
[ID] integer NOT NULL PRIMARY KEY AUTOINCREMENT,
[CreationDate] bigint NOT NULL DEFAULT CURRENT_TIMESTAMP,
[NextAnswerDate] bigint,
[Meanings] [nvarchar(300)] NOT NULL,
[Readings] [nvarchar(100)] NOT NULL,
[CurrentGrade] smallint NOT NULL DEFAULT 0,
[FailureCount] integer NOT NULL DEFAULT 0,
[SuccessCount] integer NOT NULL DEFAULT 0,
[AssociatedVocab] [nvarchar(100)],
[AssociatedKanji] [nvarchar(10)],
[MeaningNote] [nvarchar(1000)],
[ReadingNote] [nvarchar(1000)],
[SuspensionDate] bigint,
[Tags] [nvarchar(300)],
[LastUpdateDate] BIGINT,
[IsDeleted] BOOLEAN NOT NULL DEFAULT false,
[ServerId] integer);

View file

@ -29,6 +29,7 @@ impl Kanji {
let character = row.get("Character"); let character = row.get("Character");
let meaning = row.get("Meaning"); let meaning = row.get("Meaning");
let most_used_rank = row.get("MostUsedRank"); let most_used_rank = row.get("MostUsedRank");
Kanji { Kanji {
character, character,
meaning, meaning,

View file

@ -7,23 +7,23 @@ extern crate derivative;
extern crate serde; extern crate serde;
mod kanji; mod kanji;
mod srs;
use std::str::FromStr; use std::str::FromStr;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
use tauri::SystemTray; use tauri::SystemTray;
use tokio::fs;
use crate::kanji::KanjiDb; use crate::kanji::KanjiDb;
use crate::srs::SrsDb;
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
let app_dir = dirs::config_dir().unwrap().join("houhou");
fs::create_dir_all(&app_dir).await?;
// Open kanji db // Open kanji db
let kanji_db_options = let kanji_db_options =
SqliteConnectOptions::from_str("./KanjiDatabase.sqlite")?.read_only(true); SqliteConnectOptions::from_str("./KanjiDatabase.sqlite")?.read_only(true);
@ -31,15 +31,28 @@ async fn main() -> Result<()> {
.connect_with(kanji_db_options) .connect_with(kanji_db_options)
.await?; .await?;
// Open SRS db
let srs_db_path = app_dir.join("srs_db.sqlite");
let srs_db_options =
SqliteConnectOptions::from_str(&srs_db_path.display().to_string())?
.create_if_missing(true);
println!("Opening srs database at {} ...", srs_db_path.display());
let srs_pool = SqlitePoolOptions::new()
.connect_with(srs_db_options)
.await?;
println!("Running migrations...");
sqlx::migrate!().run(&srs_pool).await?;
// System tray // System tray
let tray = SystemTray::new(); let tray = SystemTray::new();
// Build tauri // Build tauri
tauri::Builder::default() tauri::Builder::default()
.manage(KanjiDb(kanji_pool)) .manage(KanjiDb(kanji_pool))
.manage(SrsDb(srs_pool))
.system_tray(tray) .system_tray(tray)
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
greet, srs::get_srs_stats,
kanji::get_kanji, kanji::get_kanji,
kanji::get_single_kanji kanji::get_single_kanji
]) ])

9
src-tauri/src/srs.rs Normal file
View file

@ -0,0 +1,9 @@
use sqlx::SqlitePool;
use tauri::State;
pub struct SrsDb(pub SqlitePool);
#[tauri::command]
pub async fn get_srs_stats(db: State<'_, SrsDb>) -> Result<(), ()> {
Ok(())
}

View file

@ -27,5 +27,5 @@ main.main {
.link-active { .link-active {
border-top-color: #09c; border-top-color: #09c;
background-color: lightskyblue; background-color: hsl(203, 91%, 91%);
} }

View file

@ -0,0 +1,3 @@
export default function DashboardReviewStats() {
return <></>;
}

View file

@ -6,12 +6,24 @@
.kanji-link { .kanji-link {
padding: 4px 8px; padding: 4px 8px;
border: 1px solid lightgray; border-left: 4px solid transparent;
user-select: none;
} }
.kanji-list-scroll { .kanji-list-scroll {
direction: rtl;
overflow-y: scroll;
}
.kanji-list-inner {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
overflow-y: scroll;
direction: ltr;
}
.kanji-link-active {
border-left-color: #09c;
background-color: hsl(203, 91%, 91%);
} }

View file

@ -6,6 +6,7 @@ import styles from "./KanjiPane.module.scss";
import { Link, useParams } from "react-router-dom"; import { Link, useParams } from "react-router-dom";
import KanjiDisplay from "../components/KanjiDisplay"; import KanjiDisplay from "../components/KanjiDisplay";
import { Kanji } from "../types/Kanji"; import { Kanji } from "../types/Kanji";
import classNames from "classnames";
export interface GetKanjiResult { export interface GetKanjiResult {
count: number; count: number;
@ -25,10 +26,13 @@ function KanjiList({ data, selectedCharacter }: KanjiListProps) {
</small> </small>
<div className={styles["kanji-list-scroll"]}> <div className={styles["kanji-list-scroll"]}>
{data.kanji.map((kanji) => ( <div className={styles["kanji-list-inner"]}>
<Link {data.kanji.map((kanji) => {
const active = kanji.character == selectedCharacter;
const className = classNames(styles['kanji-link'], active && styles['kanji-link-active'])
return <Link
key={kanji.character} key={kanji.character}
className={styles["kanji-link"]} className={className}
to={`/kanji/${kanji.character}`} to={`/kanji/${kanji.character}`}
> >
<Grid templateRows="repeat(2, 1fr)" templateColumns="1fr 3fr"> <Grid templateRows="repeat(2, 1fr)" templateColumns="1fr 3fr">
@ -36,10 +40,15 @@ function KanjiList({ data, selectedCharacter }: KanjiListProps) {
{kanji.character} {kanji.character}
</GridItem> </GridItem>
<GridItem>{kanji.meaning}</GridItem> <GridItem>{kanji.meaning}</GridItem>
<GridItem>#{kanji.most_used_rank} most used</GridItem> <GridItem>
<small>
#{kanji.most_used_rank} most used
</small>
</GridItem>
</Grid> </Grid>
</Link> </Link>
))} })}
</div>
</div> </div>
</> </>
); );