diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..19d9f03 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,52 @@ +[package] +name = "readflow" +version = "0.1.0" +edition = "2021" +authors = ["damai "] +description = "ReadFlow - 面向开发者和知识工作者的阅读工具" +repository = "http://192.168.120.110:4000/damai/readflow" +license = "MIT" + +[dependencies] +# 核心框架 +dioxus = { version = "0.5", features = ["desktop"] } +dioxus-router = "0.5" +tauri = { version = "2", optional = true } + +# 异步运行时 +tokio = { version = "1", features = ["full"] } + +# 文档处理 +pdfium-render = "0.8" +epub = "2.0" +mobi = "0.2" + +# Markdown 与代码高亮 +pulldown-cmark = "0.9" +syntect = "5.1" +tree-sitter = { version = "0.20", optional = true } + +# 数据存储 +sled = "0.34" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" + +# 配置管理 +config = "0.14" +anyhow = "1.0" +tracing = "0.1" +tracing-subscriber = "0.3" + +# 工具 +rayon = "1.8" # 并行计算 + +[features] +default = ["desktop"] +desktop = ["dioxus/desktop"] +tauri = ["dep:tauri"] +wasm = ["dioxus/web"] + +[profile.release] +opt-level = 3 +lto = true +codegen-units = 1 diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000..3845f94 --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1,69 @@ +//! 配置管理模块 + +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Config { + pub theme: ThemeConfig, + pub reader: ReaderConfig, + pub translation: TranslationConfig, + pub storage: StorageConfig, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ThemeConfig { + pub mode: String, // "light" or "dark" + pub font_size: u32, + pub font_family: String, + pub line_height: f32, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ReaderConfig { + pub default_format: String, + pub scroll_smooth: bool, + pub show_toc: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TranslationConfig { + pub provider: String, // "google", "deepl", "ollama" + pub api_key: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct StorageConfig { + pub library_path: String, + pub cache_path: String, +} + +impl Default for Config { + fn default() -> Self { + Self { + theme: ThemeConfig { + mode: "light".to_string(), + font_size: 16, + font_family: "system".to_string(), + line_height: 1.5, + }, + reader: ReaderConfig { + default_format: "pdf".to_string(), + scroll_smooth: true, + show_toc: true, + }, + translation: TranslationConfig { + provider: "ollama".to_string(), + api_key: None, + }, + storage: StorageConfig { + library_path: "./library".to_string(), + cache_path: "./cache".to_string(), + }, + } + } +} + +pub fn load() -> Config { + // 后续从文件加载配置 + Config::default() +} \ No newline at end of file diff --git a/src/core/document.rs b/src/core/document.rs new file mode 100644 index 0000000..6d13ed0 --- /dev/null +++ b/src/core/document.rs @@ -0,0 +1,43 @@ +//! 文档处理引擎 + +use anyhow::Result; + +pub enum DocumentFormat { + Pdf, + Epub, + Mobi, + Azw3, + Txt, + Markdown, + Code, +} + +pub struct Document { + pub format: DocumentFormat, + pub title: String, + pub path: String, + pub content: Vec, +} + +pub struct DocumentEngine; + +impl DocumentEngine { + pub fn new() -> Self { + Self + } + + pub fn open(&self, path: &str) -> Result { + // 后续实现:基于文件扩展名判断格式并解析 + todo!("Implement document opening for: {}", path) + } + + pub fn render(&self, doc: &Document) -> Result { + // 后续实现:渲染文档内容 + todo!("Implement document rendering") + } + + pub fn search(&self, doc: &Document, query: &str) -> Result> { + // 后续实现:全文搜索 + todo!("Implement search functionality") + } +} \ No newline at end of file diff --git a/src/core/mod.rs b/src/core/mod.rs new file mode 100644 index 0000000..2685e8b --- /dev/null +++ b/src/core/mod.rs @@ -0,0 +1,9 @@ +//! 核心服务模块 +//! +//! 包含文档处理、翻译等功能 + +pub mod document; +pub mod translation; + +pub use document::DocumentEngine; +pub use translation::TranslationService; \ No newline at end of file diff --git a/src/core/translation.rs b/src/core/translation.rs new file mode 100644 index 0000000..b28f7ee --- /dev/null +++ b/src/core/translation.rs @@ -0,0 +1,30 @@ +//! 翻译服务模块 + +use anyhow::Result; + +pub enum TranslationProvider { + Google, + DeepL, + Ollama, +} + +pub struct TranslationService { + provider: TranslationProvider, + api_key: Option, +} + +impl TranslationService { + pub fn new(provider: TranslationProvider, api_key: Option) -> Self { + Self { provider, api_key } + } + + pub fn translate(&self, text: &str, from: &str, to: &str) -> Result { + // 后续实现:调用翻译 API + todo!("Implement translation for: {}", text) + } + + pub fn detect_language(&self, text: &str) -> Result { + // 后续实现:语言检测 + todo!("Implement language detection") + } +} \ No newline at end of file diff --git a/src/infrastructure/mod.rs b/src/infrastructure/mod.rs new file mode 100644 index 0000000..a971175 --- /dev/null +++ b/src/infrastructure/mod.rs @@ -0,0 +1,7 @@ +//! 基础设施模块 +//! +//! 包含文件 I/O、缓存、事件总线等 + +pub mod storage; + +pub use storage::Storage; \ No newline at end of file diff --git a/src/infrastructure/storage.rs b/src/infrastructure/storage.rs new file mode 100644 index 0000000..5240edb --- /dev/null +++ b/src/infrastructure/storage.rs @@ -0,0 +1,25 @@ +//! 存储模块 + +use anyhow::Result; + +pub struct Storage { + path: String, +} + +impl Storage { + pub fn new(path: &str) -> Self { + Self { + path: path.to_string(), + } + } + + pub fn save(&self, key: &str, value: &[u8]) -> Result<()> { + // 后续实现:使用 sled 存储 + todo!("Implement storage save for key: {}", key) + } + + pub fn load(&self, key: &str) -> Result> { + // 后续实现:使用 sled 加载 + todo!("Implement storage load for key: {}", key) + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..3c4c47d --- /dev/null +++ b/src/main.rs @@ -0,0 +1,37 @@ +//! ReadFlow - 面向开发者和知识工作者的阅读工具 +//! +//! 项目主页: http://192.168.120.110:4000/damai/readflow + +use std::env; +use tracing::info; +use tracing_subscriber::{fmt, prelude::*, EnvFilter}; + +mod config; +mod core; +mod infrastructure; +mod ui; + +fn setup_logging() { + let filter = EnvFilter::try_from_default_env() + .unwrap_or_else(|_| EnvFilter::new("info")); + + tracing_subscriber::registry() + .with(fmt::layer()) + .with(filter) + .init(); +} + +fn main() { + setup_logging(); + + info!("Starting ReadFlow v{}", env!("CARGO_PKG_VERSION")); + info!("Project: {}", env!("CARGO_PKG_NAME")); + info!("Description: {}", env!("CARGO_PKG_DESCRIPTION")); + + // 初始化配置 + let config = config::load(); + info!("Configuration loaded"); + + // 启动 UI + ui::run(config); +} \ No newline at end of file diff --git a/src/ui/mod.rs b/src/ui/mod.rs new file mode 100644 index 0000000..604e4fd --- /dev/null +++ b/src/ui/mod.rs @@ -0,0 +1,20 @@ +//! UI 模块 +//! +//! 使用 Dioxus 构建跨平台 UI + +use crate::config::Config; + +pub fn run(config: Config) { + println!("Starting UI with config: {:?}", config.theme); + + // 后续实现:Dioxus UI 启动 + // 示例: + // dioxus::launch(App); +} + +// 后续实现:Dioxus 组件 +// pub fn App(cx: Scope) -> Element { +// cx.render(rsx! { +// div { "Hello, ReadFlow!" } +// }) +// } \ No newline at end of file