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
export HOUHOU_SRC=$PWD
export DATABASE_URL=$HOUHOU_SRC/src-tauri/SrsDatabase.sqlite

View file

@ -4,3 +4,5 @@
*-shm
*-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 meaning = row.get("Meaning");
let most_used_rank = row.get("MostUsedRank");
Kanji {
character,
meaning,

View file

@ -7,23 +7,23 @@ extern crate derivative;
extern crate serde;
mod kanji;
mod srs;
use std::str::FromStr;
use anyhow::{Context, Result};
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
use tauri::SystemTray;
use tokio::fs;
use crate::kanji::KanjiDb;
// 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)
}
use crate::srs::SrsDb;
#[tokio::main]
async fn main() -> Result<()> {
let app_dir = dirs::config_dir().unwrap().join("houhou");
fs::create_dir_all(&app_dir).await?;
// Open kanji db
let kanji_db_options =
SqliteConnectOptions::from_str("./KanjiDatabase.sqlite")?.read_only(true);
@ -31,15 +31,28 @@ async fn main() -> Result<()> {
.connect_with(kanji_db_options)
.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
let tray = SystemTray::new();
// Build tauri
tauri::Builder::default()
.manage(KanjiDb(kanji_pool))
.manage(SrsDb(srs_pool))
.system_tray(tray)
.invoke_handler(tauri::generate_handler![
greet,
srs::get_srs_stats,
kanji::get_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 {
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 {
padding: 4px 8px;
border: 1px solid lightgray;
border-left: 4px solid transparent;
user-select: none;
}
.kanji-list-scroll {
direction: rtl;
overflow-y: scroll;
}
.kanji-list-inner {
display: flex;
flex-direction: column;
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 KanjiDisplay from "../components/KanjiDisplay";
import { Kanji } from "../types/Kanji";
import classNames from "classnames";
export interface GetKanjiResult {
count: number;
@ -25,10 +26,13 @@ function KanjiList({ data, selectedCharacter }: KanjiListProps) {
</small>
<div className={styles["kanji-list-scroll"]}>
{data.kanji.map((kanji) => (
<Link
<div className={styles["kanji-list-inner"]}>
{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}
className={styles["kanji-link"]}
className={className}
to={`/kanji/${kanji.character}`}
>
<Grid templateRows="repeat(2, 1fr)" templateColumns="1fr 3fr">
@ -36,10 +40,15 @@ function KanjiList({ data, selectedCharacter }: KanjiListProps) {
{kanji.character}
</GridItem>
<GridItem>{kanji.meaning}</GridItem>
<GridItem>#{kanji.most_used_rank} most used</GridItem>
<GridItem>
<small>
#{kanji.most_used_rank} most used
</small>
</GridItem>
</Grid>
</Link>
))}
})}
</div>
</div>
</>
);