Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,233 changes: 388 additions & 845 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@
"@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.2",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-dialog": "^2.2.0",
"@tauri-apps/plugin-fs": "^2.0.3",
"@tauri-apps/plugin-http": "^2.2.0",
"@tauri-apps/plugin-log": "^2.2.0",
"@tauri-apps/plugin-shell": "^2",
"@tauri-apps/plugin-stronghold": "^2.0.0",
"@tauri-apps/plugin-updater": "^2.0.0",
"@tauri-apps/plugin-websocket": "^2.2.0",
"@tiptap/extension-highlight": "^2.10.3",
Expand All @@ -44,7 +43,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-resizable-panels": "^2.1.7",
"react-router-dom": "^7.0.2",
"react-router": "^7.0.2",
"react-slick": "^0.30.2",
"slick-carousel": "^1.8.1",
"tailwind-merge": "^2.1.0"
Expand Down
11 changes: 7 additions & 4 deletions apps/desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@ hypr-db = { path = "../../../crates/db", package = "db" }
hypr-audio = { path = "../../../crates/audio", package = "audio" }

tauri = { workspace = true, features = ["tray-icon"] }
tauri-plugin-shell = "2"
tauri-plugin-updater = "2"
tauri-plugin-fs = "2"
tauri-plugin-stronghold = "2"
tauri-plugin-positioner = "2"
tauri-plugin-single-instance = { version = "2", features = ["deep-link"] }
tauri-plugin-sql = { version = "2", features = ["sqlite"] }
tauri-plugin-log = "2"
tauri-plugin-deep-link = "2"
tauri-plugin-websocket = "2"
tauri-plugin-http = "2"
tauri-plugin-dialog = "2"
tauri-plugin-global-shortcut = "2"
tauri-plugin-store = "2"
tauri-plugin-notification = "2"
tauri-plugin-autostart = "2"

specta = { workspace = true }
specta-typescript = { workspace = true }
Expand All @@ -54,5 +59,3 @@ futures = "0.3.31"
flume = "0.11.1"
objc = "0.2.7"
cap-media = { workspace = true }
tauri-plugin-websocket = "2.2.0"
tauri-plugin-http = "2.2.0"
2 changes: 1 addition & 1 deletion apps/desktop/src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"windows": ["main"],
"permissions": [
"core:default",
"shell:allow-open",
"positioner:default",
"fs:default",
"sql:default",
"sql:allow-execute",
"websocket:default",
"store:default",
{
"identifier": "http:default",
"allow": [{ "url": "https://*.tauri.app" }]
Expand Down
58 changes: 58 additions & 0 deletions apps/desktop/src-tauri/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use serde::{Deserialize, Serialize};
use specta::Type;

#[derive(Debug, Serialize, Deserialize, Type)]
#[serde(untagged)]
pub enum Config {
V0(ConfigV0),
}

#[derive(Debug, Serialize, Deserialize, Type)]
struct ConfigV0 {
version: u8,
language: Language,
user_name: String,
}

impl Default for Config {
fn default() -> Self {
Self::V0(ConfigV0::default())
}
}

impl Default for ConfigV0 {
fn default() -> Self {
Self {
version: 0,
language: Language::default(),
user_name: "You".to_string(),
}
}
}

#[derive(Debug, Serialize, Deserialize, Type)]
enum Language {
English,
Korean,
}

impl Default for Language {
fn default() -> Self {
Self::English
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_default_config() {
let config = Config::default();
match config {
Config::V0(cfg_v0) => {
assert_eq!(cfg_v0.version, 0);
}
}
}
}
35 changes: 34 additions & 1 deletion apps/desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use cap_media::feeds::{AudioInputFeed, AudioInputSamplesSender};
use std::path::PathBuf;
use tauri::{AppHandle, Manager};
use tauri_plugin_store::StoreExt;
use tokio::sync::RwLock;

mod audio;
mod config;
mod db;
mod file;
mod permissions;
Expand Down Expand Up @@ -78,6 +80,21 @@ fn list_recordings(app: AppHandle) -> Result<Vec<(String, PathBuf)>, String> {
Ok(Vec::new())
}

#[tauri::command]
#[specta::specta]
fn set_config(app: AppHandle, config: config::Config) {
let store = app.store("store.json").unwrap();
store.set("config", serde_json::json!(config));
}

#[tauri::command]
#[specta::specta]
fn get_config(app: AppHandle) -> config::Config {
let store = app.store("store.json").unwrap();
let value = store.get("config").unwrap();
serde_json::from_value(value).unwrap()
}

fn recordings_path(app: &AppHandle) -> PathBuf {
let path = app.path().app_data_dir().unwrap().join("recordings");
std::fs::create_dir_all(&path).unwrap_or_default();
Expand All @@ -92,6 +109,8 @@ fn recording_path(app: &AppHandle, recording_id: &str) -> PathBuf {
pub fn run() {
let specta_builder = tauri_specta::Builder::new()
.commands(tauri_specta::collect_commands![
set_config,
get_config,
list_audio_devices,
start_recording,
stop_recording,
Expand Down Expand Up @@ -151,7 +170,6 @@ pub fn run() {
builder
// https://v2.tauri.app/plugin/deep-linking/#desktop
.plugin(tauri_plugin_deep_link::init())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_websocket::init())
// TODO: https://v2.tauri.app/plugin/updater/#building
Expand All @@ -160,6 +178,21 @@ pub fn run() {
let handler = specta_builder.invoke_handler();
move |invoke| handler(invoke)
})
.setup(|app| {
#[cfg(desktop)]
{
use tauri_plugin_autostart::ManagerExt;

let _ = app.handle().plugin(tauri_plugin_autostart::init(
tauri_plugin_autostart::MacosLauncher::LaunchAgent,
Some(vec![]),
));

let autostart_manager = app.autolaunch();
let _ = autostart_manager.enable();
}
Ok(())
})
.setup(move |app| {
let app = app.handle().clone();

Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { BrowserRouter, Routes, Route } from "react-router";
import { useEffect } from "react";
import NavBar from "./components/layout/NavBar";
import Home from "./pages/Home";
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/components/layout/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import { useNavigate, useLocation } from "react-router";
import SearchModal from "../modals/search/SearchModal";
import SettingsModal from "../modals/settings/SettingsModal";
import { useUI } from "../../contexts/UIContext";
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/components/modals/search/SearchModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import "../../../styles/cmdk.css";

import { useState, useEffect } from "react";
import { Command } from "cmdk";
import { useNavigate } from "react-router-dom";
import { useNavigate } from "react-router";
import { mockNotes } from "../../../mocks/data";

const SearchModal = () => {
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useNavigate } from "react-router";
import { mockNotes } from "../mocks/data";
import { UpcomingEvents } from "../components/home/UpcomingEvents";
import { PastNotes } from "../components/home/PastNotes";
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/pages/Note.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect } from "react";
import { useParams } from "react-router-dom";
import { useParams } from "react-router";
import { useSpeechRecognition } from "../hooks/useSpeechRecognition";
import SidePanel from "../components/note/SidePanel";
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
Expand Down
4 changes: 0 additions & 4 deletions apps/desktop/src/types/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

// This file has been generated by Specta. DO NOT EDIT.

export type Config = { id: string; language: Language; user_name: string }

export type Language = "English" | "Korean"

export type Session = { id: string; start: string; end: string | null; tags: string[]; raw_memo: string; processed_memo: string; raw_transcript: string }

export type Transcript = { speakers: string[]; blocks: TranscriptBlock[] }
Expand Down
13 changes: 13 additions & 0 deletions apps/desktop/src/types/tauri.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
/** user-defined commands **/

export const commands = {
async setConfig(config: Config): Promise<void> {
await TAURI_INVOKE("set_config", { config });
},
async getConfig(): Promise<Config> {
return await TAURI_INVOKE("get_config");
},
async listAudioDevices(): Promise<string[]> {
return await TAURI_INVOKE("list_audio_devices");
},
Expand Down Expand Up @@ -34,6 +40,13 @@ export const commands = {

/** user-defined types **/

export type Config = ConfigV0;
export type ConfigV0 = {
version: number;
language: Language;
user_name: string;
};
export type Language = "English" | "Korean";
export type OSPermission =
| "screenRecording"
| "camera"
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src/utils/dialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// https://v2.tauri.app/plugin/dialog/#javascript

export * from '@tauri-apps/plugin-dialog';
57 changes: 0 additions & 57 deletions crates/db/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,6 @@ use anyhow::Result;
pub trait SqliteExecutor<'c>: sqlx::Executor<'c, Database = sqlx::Sqlite> {}
impl<'c, T: sqlx::Executor<'c, Database = sqlx::Sqlite>> SqliteExecutor<'c> for T {}

pub async fn get_config<'c, E: SqliteExecutor<'c>>(e: E) -> Result<types::Config> {
let ret = sqlx::query_as("SELECT * FROM config").fetch_one(e).await?;

Ok(ret)
}

pub async fn create_config<'c, E: SqliteExecutor<'c>>(e: E) -> Result<types::Config> {
let config = types::Config::default();

let ret = sqlx::query_as(
"INSERT INTO config (
id, language, user_name
) VALUES (?, ?, ?)
RETURNING *",
)
.bind(config.id)
.bind(config.language)
.bind(config.user_name)
.fetch_one(e)
.await?;

Ok(ret)
}

pub async fn update_config<'c, E: SqliteExecutor<'c>>(
e: E,
config: types::Config,
) -> Result<types::Config> {
let ret = sqlx::query_as(
r#"
UPDATE config
SET language = ?,
user_name = ?
WHERE id = ?
RETURNING *
"#,
)
.bind(config.language)
.bind(config.user_name)
.bind(config.id)
.fetch_one(e)
.await?;

Ok(ret)
}

pub async fn create_session<'c, E: SqliteExecutor<'c>>(e: E) -> Result<types::Session> {
let session = types::Session::default();

Expand Down Expand Up @@ -113,17 +67,6 @@ mod tests {
use super::*;
use sqlx::sqlite::SqlitePool;

#[sqlx::test]
async fn test_config(pool: SqlitePool) {
let _ = create_config(&pool).await.unwrap();
let mut config = get_config(&pool).await.unwrap();
assert_eq!(config.language, types::Language::English);

config.language = types::Language::Korean;
let config = update_config(&pool, config).await.unwrap();
assert_eq!(config.language, types::Language::Korean);
}

#[sqlx::test]
async fn test_create_session(pool: SqlitePool) {
let sessions = list_sessions(&pool).await.unwrap();
Expand Down
27 changes: 0 additions & 27 deletions crates/db/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,13 @@ use time::OffsetDateTime;
use uuid::Uuid;

pub fn register_all(collection: &mut specta_util::TypeCollection) {
collection.register::<Language>();
collection.register::<Config>();
collection.register::<Session>();
collection.register::<Transcript>();
collection.register::<TranscriptBlock>();
}

// All public struct must derive 'Debug, Serialize, Deserialize, specta::Type'.

#[allow(dead_code)]
#[derive(Debug, Serialize, Deserialize, specta::Type, PartialEq, sqlx::Type)]
pub enum Language {
English,
Korean,
}

#[allow(dead_code)]
#[derive(Debug, Serialize, Deserialize, specta::Type, sqlx::FromRow)]
pub struct Config {
pub id: Uuid,
pub language: Language,
pub user_name: String,
}

impl Default for Config {
fn default() -> Self {
Self {
id: Uuid::new_v4(),
language: Language::English,
user_name: "You".to_string(),
}
}
}

#[allow(dead_code)]
#[derive(Debug, Serialize, Deserialize, specta::Type, sqlx::FromRow)]
pub struct Session {
Expand Down
Loading
Loading