Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5a231be
fix(ui)[app]: opening and closing animation for folder nodes in file …
Keshav-writes-code Apr 22, 2026
ccd231c
feat(docs): add inital docs for planning state management
Keshav-writes-code Apr 2, 2026
2a8bb31
feat: add inital implementation
Keshav-writes-code Apr 3, 2026
c514955
feat(docs): update with a better plan
Keshav-writes-code Apr 4, 2026
a002226
feat(ui): make satoshi the default sans font
Keshav-writes-code Apr 4, 2026
6db9581
feat: add latex support
Keshav-writes-code Apr 4, 2026
963799d
feat: add inital implementation
Keshav-writes-code Apr 5, 2026
8892f7c
feat(docs): add more context
Keshav-writes-code Apr 5, 2026
cf8bf49
feat: add some checkpoint code that doesn't work
Keshav-writes-code Apr 5, 2026
975db84
feat: add intial load logic
Keshav-writes-code Apr 19, 2026
f47b681
refac(dev_docs): move to core concepts
Keshav-writes-code Apr 20, 2026
4aa963c
refac: move placeholder data to svele compoennt
Keshav-writes-code Apr 20, 2026
b707ec9
feat: add save logic to the config
Keshav-writes-code Apr 20, 2026
f92565b
refac: eleminate the idea of keeping the persistent in rust memory al…
Keshav-writes-code Apr 20, 2026
c33e094
feat: make setup of config dir run on startup
Keshav-writes-code Apr 20, 2026
b9ae6c9
fix: make the state merging do deep merge of the 2 objects
Keshav-writes-code Apr 20, 2026
6bed18a
fix: remove unnccessary write permission for the config file in load_…
Keshav-writes-code Apr 20, 2026
101b641
feat: migrate to custom persustent layer and remove legacy persistent…
Keshav-writes-code Apr 21, 2026
7702baf
refac: make update workpsaces function take the WorkspaceMetadata tup…
Keshav-writes-code Apr 22, 2026
8041a2b
fix!: duplicating issue of the recent workspaces
Keshav-writes-code Apr 22, 2026
867f1e0
refac: remove unwanted setuff
Keshav-writes-code Apr 22, 2026
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
28 changes: 14 additions & 14 deletions apps/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,37 +32,37 @@
"vitest": "^4.0.18"
},
"dependencies": {
"@codemirror/commands": "catalog:",
"@codemirror/lang-markdown": "catalog:",
"@codemirror/language": "catalog:",
"@codemirror/language-data": "catalog:",
"@codemirror/state": "catalog:",
"@codemirror/view": "catalog:",
"@iconify-json/carbon": "^1.2.19",
"@iconify-json/tabler": "catalog:",
"@lezer/markdown": "catalog:",
"@prosemark/core": "catalog:",
"@prosemark/paste-rich-text": "catalog:",
"@prosemark/render-html": "catalog:",
"@saurl/tauri-plugin-safe-area-insets-css-api": "^0.1.0",
"@tauri-apps/api": "^2.10.1",
"@tauri-apps/plugin-clipboard-manager": "~2.3.2",
"@tauri-apps/plugin-dialog": "~2.6.0",
"@tauri-apps/plugin-fs": "~2.4.5",
"@tauri-apps/plugin-opener": "~2.5.3",
"@tauri-apps/plugin-os": "~2.3.2",
"@tauri-apps/plugin-store": "~2.4.2",
"@unocss/preset-icons": "catalog:",
"@unocss/preset-mini": "^66.6.2",
"@unocss/reset": "^66.6.2",
"@unocss/transformer-variant-group": "^66.6.2",
"@workspace/shared-assets": "workspace:*",
"daisyui": "catalog:",
"deepmerge": "^4.3.1",
"html2canvas-pro": "^2.0.2",
"jspdf": "^4.2.0",
"svelte-animated-details": "^1.0.2",
"svelte-sonner": "^1.0.7",
"tauri-plugin-android-fs-api": "^26.1.0",
"zod": "^4.3.6",
"@codemirror/commands": "catalog:",
"@codemirror/lang-markdown": "catalog:",
"@codemirror/language": "catalog:",
"@codemirror/language-data": "catalog:",
"@codemirror/state": "catalog:",
"@codemirror/view": "catalog:",
"@lezer/markdown": "catalog:",
"@prosemark/core": "catalog:",
"@prosemark/render-html": "catalog:",
"@prosemark/paste-rich-text": "catalog:",
"daisyui": "catalog:",
"@workspace/shared-assets": "workspace:*"
"zod": "^4.3.6"
}
}
32 changes: 3 additions & 29 deletions apps/app/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/app/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ log = "0.4"
tauri = { version = "2.10.2", features = [] }
tauri-plugin-log = "2"
tauri-plugin-fs = { version = "2", features = ['watch'] }
tauri-plugin-store = "2"
tauri-plugin-dialog = "2"
tauri-plugin-os = "2"
urlencoding = "2"
Expand All @@ -37,6 +36,7 @@ tauri-plugin-safe-area-insets-css = "0.2"
tauri-plugin-clipboard-manager = "2"
futures = "0.3"
rayon = "1.10"
chrono = { version = "0.4.44", features = ["serde"] }

[profile.dev]
incremental = true # Compile your binary in smaller steps.
Expand Down
2 changes: 0 additions & 2 deletions apps/app/src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"permissions": [
"core:default",
"fs:default",
"store:default",
"dialog:default",
"core:window:allow-start-dragging",
"core:window:allow-close",
Expand All @@ -24,4 +23,3 @@
"clipboard-manager:allow-write-text"
]
}

1 change: 1 addition & 0 deletions apps/app/src-tauri/src/features/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod file_system;
pub mod sync;
pub mod persistency;
18 changes: 18 additions & 0 deletions apps/app/src-tauri/src/features/persistency/commands.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use super::structs::AppPersistentStates;
use tauri::AppHandle;

#[tauri::command]
pub fn get_persistent_states(app: AppHandle) -> Result<AppPersistentStates, String> {
let mut temp_states = AppPersistentStates::new();
temp_states.load_states(&app).map_err(|e| e.to_string())?;
Ok(temp_states)
}

#[tauri::command]
pub fn save_persistent_states(app: AppHandle, states: AppPersistentStates) -> Result<(), String> {
let mut temp_states = AppPersistentStates::new();
temp_states
.save_states(&app, &states)
.map_err(|e| e.to_string())?;
Ok(())
}
2 changes: 2 additions & 0 deletions apps/app/src-tauri/src/features/persistency/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// pub fn migrate_1_to_2() {}
// pub fn migrate_2_to_3() {}
3 changes: 3 additions & 0 deletions apps/app/src-tauri/src/features/persistency/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod commands;
mod migrations;
pub mod structs;
131 changes: 131 additions & 0 deletions apps/app/src-tauri/src/features/persistency/structs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::{
error::Error,
fs::{self, File},
path::PathBuf,
};
use tauri::{AppHandle, Manager};

const CONFIG_FILE_NAME: &str = "config.json";
const LATEST_SCHEMA_V: u8 = 1;

// Global Struct
#[derive(Serialize, Deserialize, Clone)]
struct GenericPath {
path: PathBuf,
document_top_tree_uri: Option<PathBuf>,
}

// Domain : Wokrspace
#[derive(Serialize, Deserialize, Clone)]
struct WorkspaceMetaData {
path: GenericPath,
last_accessed: DateTime<Utc>,
recent_filenode_path: Option<GenericPath>,
}

#[derive(Serialize, Deserialize, Clone)]
struct AppConfig {
workspaces_metadata: Vec<WorkspaceMetaData>,
}

impl AppConfig {
pub fn new() -> Self {
Self {
workspaces_metadata: vec![],
}
}
}

#[derive(Serialize, Deserialize, Clone)]
struct AppSecureConfig {
llm_api: String,
}

impl AppSecureConfig {
pub fn new() -> Self {
Self {
llm_api: "".to_string(),
}
}
}

// Main Parent State
#[derive(Serialize, Deserialize, Clone)]
pub struct AppPersistentStates {
schema_version: u8,
app_config: AppConfig,
secure: AppSecureConfig,
}

impl AppPersistentStates {
pub fn new() -> Self {
Self {
schema_version: 1,
app_config: AppConfig::new(),
secure: AppSecureConfig::new(),
}
}
pub fn save_states(
&mut self,
app: &AppHandle,
states: &AppPersistentStates,
) -> Result<(), Box<dyn Error>> {
self.schema_version = states.schema_version;
self.app_config = states.app_config.clone();
self.secure = states.secure.clone();

let path = app.path().app_config_dir().unwrap().join(CONFIG_FILE_NAME);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}

let file = File::create(path)?;
serde_json::to_writer_pretty(&file, &self)?;

Ok(())
}

pub fn load_states(&mut self, app: &AppHandle) -> Result<(), Box<dyn Error>> {
// Setup Config Path
self.setup_config_path(app)?;

let path = app.path().app_config_dir().unwrap().join(CONFIG_FILE_NAME);
let file = fs::File::options().read(true).open(path)?;
*self = serde_json::from_reader(&file)?;

// Run migrations if needed
if self.schema_version == LATEST_SCHEMA_V {
return Ok(());
}

Err(format!(
"Current Schema version is Unsuppoirted : {}",
self.schema_version
)
.into())

// Future Migration Pipeline (Uncomment when LATEST_SCHEMA_V is 2)
// while self.schema_version < LATEST_SCHEMA_V {
// match self.schema_version {
// 1 => migrate_1_to_2(&mut self),
// _ => return Err("The Schema is not Valid".into()),
// }
// }

// Ok(())
}
pub fn setup_config_path(&self, app: &AppHandle) -> Result<(), Box<dyn Error>> {
let path = app.path().app_config_dir().unwrap().join(CONFIG_FILE_NAME);
// Create the file path if doesn't exists
if !path.exists() {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let file = File::create(&path)?;
serde_json::to_writer_pretty(&file, &self)?;
}
Ok(())
}
}
9 changes: 7 additions & 2 deletions apps/app/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::features::persistency::structs::AppPersistentStates;

mod features;

#[cfg(all(test, not(target_os = "android")))]
Expand All @@ -10,16 +12,19 @@ pub fn run() {
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_store::Builder::new().build())
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_android_fs::init())
.plugin(tauri_plugin_safe_area_insets_css::init())
.invoke_handler(tauri::generate_handler![
features::file_system::build_file_tree,
features::file_system::android::move_file_android,
features::file_system::android::move_directory_android
features::file_system::android::move_directory_android,
features::persistency::commands::get_persistent_states,
features::persistency::commands::save_persistent_states
])
.setup(|app| {
let app_config = AppPersistentStates::new();
app_config.setup_config_path(app.handle())?;
if cfg!(debug_assertions) {
app.handle().plugin(
tauri_plugin_log::Builder::default()
Expand Down
10 changes: 4 additions & 6 deletions apps/app/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
import { Toaster } from 'svelte-sonner';
import Main from '@/components/main_section/index.svelte';
import AppSettings from '@/components/general/app_settings/index.svelte';
import { drawer_open } from '@/lib/states/global/index.svelte';
import { attach_window_listeners } from './lib/operations/window_listeners';
$effect(() => {
const detach = attach_window_listeners();
return () => detach.then((f) => f()); // Handle the async setup/cleanup
});
import { drawer_open } from '@/lib/states/session/global/index.svelte';
import { onMount } from 'svelte';
import { initialize_app } from '@/lib/operations/initialization';
onMount(initialize_app);
</script>

<div
Expand Down
Loading
Loading