From 537f8675db77a34ca1f084cd161ccbbbd435f692 Mon Sep 17 00:00:00 2001 From: tianma-if Date: Sun, 23 Aug 2026 17:13:30 +0800 Subject: [PATCH] feat: add quick memo switcher and update demo seed notes --- apps/api/src/demo-attachments.ts | 19 +- apps/api/src/demo-seed-data.ts | 431 +++++++++++++++++- apps/desktop/src/main/index.mjs | 4 +- apps/web/src/components/QuickMemoSwitcher.tsx | 119 +++++ apps/web/src/components/WorkspaceApp.tsx | 103 ++++- apps/web/src/lib/app-helpers.test.mjs | 60 ++- apps/web/src/lib/app-helpers.ts | 62 ++- docs/demo-sample-note.md | 196 ++++++++ docs/demo-sample-note.zh-CN.md | 196 ++++++++ packages/shared/src/i18n/en-US.ts | 31 +- packages/shared/src/i18n/zh-CN.ts | 31 +- 11 files changed, 1196 insertions(+), 56 deletions(-) create mode 100644 apps/web/src/components/QuickMemoSwitcher.tsx create mode 100644 docs/demo-sample-note.md create mode 100644 docs/demo-sample-note.zh-CN.md diff --git a/apps/api/src/demo-attachments.ts b/apps/api/src/demo-attachments.ts index 962ae87f..252124b6 100644 --- a/apps/api/src/demo-attachments.ts +++ b/apps/api/src/demo-attachments.ts @@ -45,22 +45,7 @@ export const decodeDemoAttachment = (resource: DemoAttachmentSeed): Uint8Array = return Uint8Array.from(binary, (character) => character.charCodeAt(0)); }; -export const DEMO_ATTACHMENT_MARKDOWN_ZH = ` -### 📎 7. 附件上传与下载示例 +export const DEMO_ATTACHMENT_MARKDOWN_ZH = ""; -下面这些是真实存储在 Demo R2 中的示例附件,点击即可下载,帮助你快速体验不同文件类型的附件能力: +export const DEMO_ATTACHMENT_MARKDOWN_EN = ""; -- [📄 产品简介 PDF:edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob) -- [📊 功能矩阵 CSV:feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob) -- [📦 附件示例压缩包:edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob) -`; - -export const DEMO_ATTACHMENT_MARKDOWN_EN = ` -### 📎 7. Attachment Upload & Download Demo - -These are real sample files stored in the Demo R2 bucket. Click any card to download and try different attachment types: - -- [📄 Product brief PDF: edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob) -- [📊 Feature matrix CSV: feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob) -- [📦 Attachment demo archive: edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob) -`; diff --git a/apps/api/src/demo-seed-data.ts b/apps/api/src/demo-seed-data.ts index 21076ab8..534bb378 100644 --- a/apps/api/src/demo-seed-data.ts +++ b/apps/api/src/demo-seed-data.ts @@ -16,42 +16,438 @@ export const DEMO_SEED_NOTEBOOKS = [ { id: "nb_demo_features", parentId: "nb_projects", name: "功能演示", slug: "demo-features", icon: "notebook", color: "#0891b2", sortOrder: 21 }, { id: "nb_demo_features_en", parentId: "nb_projects", name: "Feature Demos", slug: "feature-demos", icon: "notebook", color: "#0e7490", sortOrder: 22 }, ]; + export const DEMO_SEED_MEMOS_ZH = [ { id: "memo_demo_overview", notebookId: "nb_demo_features", - title: "🌟 欢迎使用 EdgeEver", - tags: ["overview", "features", "demo"], + title: "🌿 欢迎使用 EdgeEver:为极客与创作者打造的现代开源知识库", + tags: ["overview", "guide", "features", "ai-agent"], isPinned: true, markdown: - "## 🚀 开启您的 EdgeEver 笔记之旅\n\n> **EdgeEver** 是一款专为极客与创作者打造的现代开源 Serverless 个人知识库。它找回了经典的**印象笔记三栏式双视图布局**,以 Cloudflare 免费额度提供 **100% 免费**的自建云端,数据完全掌控,并原生集成 AI Agent (MCP) 接口。\n\n---\n\n### ⚡ 1. 核心产品特性对比\n\n*提示:在线模式下点击表格单元格可以直接修改文本;右键可快捷操作行列。*\n\n| 核心维度 | 传统云笔记 (如 Evernote) | 本地知识库 (如 Obsidian) | EdgeEver 极客笔记 |\n| :--- | :--- | :--- | :--- |\n| **云端托管成本** | 商业订阅高昂 ($10+/月) | 官方同步收费 ($5/月) | **100% 免费 (Cloudflare 免费额度)** |\n| **数据与隐私** | 封闭平台,导出受限 | 本地文件,同步需配置 | **完全掌控 (D1 SQLite 数据库 / R2 / WebDAV)** |\n| **编辑体验** | 富文本编辑 | 纯 Markdown | **双视图自由切换 (富文本 / Markdown 源码)** |\n| **多端支持** | 限制设备数量 | 移动端配置繁琐 | **Web / PWA / Android / macOS / iOS (审核中)** |\n| **创作者排版** | 无优化,格式易乱 | 需借助外部工具 | **微信公众号、Substack 一键富文本格式复制** |\n| **AI 原生集成** | 限制/仅特定付费版本 | 需繁琐的第三方插件 | **原生支持 MCP 协议与标准 OpenAPI** |\n\n---\n\n### 🎨 2. 沉浸式写作与排版美学\n\nEdgeEver 追求极致的创作体验,将设计美学融于字里行间:\n\n- **双视图编辑器**:点击右上角 `` 按钮,可在**所见即所得富文本**与 **Markdown 源码**间无缝切换,格式完全兼容。\n- **左侧可折叠大纲**:提供固定或折叠的大纲目录视图,支持点击标题平滑滚动定位,助您轻松掌控长文结构。\n- **8+ 款精致编辑器主题**:可在 **个人中心 / 设置** 中一键切换如 `WeChat Classic Green (微信经典绿)`、`Modern Mint (薄荷青)`、`minimal-emerald (极简祖母绿)` 等排版风格。\n- **自媒体一键排版复制**:专为创作者设计。点击右上角“复制到公众号”按钮,系统会自动将笔记转化为带行内样式的公众号美化格式,直接粘贴至微信公众号、Substack 或 WordPress 后台,排版与代码高亮完美保真。\n- **列表缩进与快捷操作**:支持快捷缩进列表,双击或选中文本可通过快捷键快速关联已有笔记。\n\n---\n\n### 📝 3. 模板中心与单篇导出\n\n- **可视化推荐模板库**:内置多种精美模板,点击即可弹窗预览。支持在当前笔记本中一键套用模板创建笔记,并支持一键返回列表。\n- **用户自定义模板**:您可以将常用笔记结构保存为自定义模板,实现效率翻倍。\n- **单篇便捷导出**:支持将当前笔记一键导出为标准的 `.md` Markdown 文件或排版优美的 `.pdf` 电子文档,便于独立归档与分发。\n\n---\n\n### 📊 4. 原生 Mermaid 动态图表渲染\n\n在代码块中使用 `mermaid` 标记,即可实时渲染高保真的动态逻辑图。支持多款**精致图表主题**选择,且微信复制时尺寸完美兼容:\n\n#### 1️⃣ 架构流程图 (Flowchart)\n```mermaid\nflowchart TD\n subgraph Client[\"📱 客户端生态\"]\n A[\"Web / PWA 浏览器\"]\n B[\"macOS / Android / iOS 客户端\"]\n end\n\n subgraph Backend[\"⚡ Cloudflare Serverless\"]\n C[\"Cloudflare Workers API\"]\n D[(\"D1 SQLite 数据库\")]\n E[(\"R2 资源存储\")]\n end\n\n A & B --> C\n C <--> D & E\n```\n\n#### 2️⃣ 交互时序图 (Sequence Diagram)\n```mermaid\nsequenceDiagram\n autonumber\n actor User as 用户\n participant App as 客户端 App\n participant Worker as Cloudflare Worker API\n participant D1 as D1 数据库\n\n User->>App: 编辑并保存笔记\n App->>Worker: POST /api/v1/memos (提交更改)\n Worker->>D1: 写入笔记 & 更新修订版本\n D1-->>Worker: 返回成功 (revision + 1)\n Worker-->>App: 200 OK (同步最新游标)\n App-->>User: 界面显示「已保存」\n```\n\n---\n\n### 📁 5. 多端覆盖、自动同步与剪藏\n\n- **全平台多端覆盖**:已发布 Web、Android 原生 App 以及 macOS 桌面端(支持 Apple Silicon 和 Intel Mac),iOS 客户端正在 App Store 审核中。\n- **网页裁剪器 (Web Clipper)**:已上架 Chrome, Edge 和 Firefox 插件商店,支持一键剪藏网页。\n- **微信文章一键剪藏**:在手机上直接将微信公众号文章分享至 EdgeEver App,系统将智能提取正文并保存为可编辑笔记。\n- **离线草稿与同步队列**:无网环境下自动保存本地,恢复连线后自动入队同步;支持在设置中灵活配置自动同步间隔。\n\n---\n\n### 🖼️ 6. 多媒体集成与图片前端压缩\n\n支持直接拖拽或粘贴插入图片与文件附件。本地浏览器会在上传前自动对图片进行 WebP 高保真压缩,缩减 **50% - 90%** 的体积,大幅加快加载速度并节省您的云端存储空间。\n\n![EdgeEver 极客猫猫](/api/v1/resources/res_demo_cat_image/blob)\n\n---\n\n### 🤖 7. 面向 AI Agent 的原生生态\n\nEdgeEver 走在 AI 时代前沿,为 AI 协作者提供了原生支持:\n\n1. **REST API**:提供标准的 OpenAPI 接口,接口定义见 `/api/openapi.json`。\n2. **MCP (Model Context Protocol) 接口**:内置 MCP 服务端点 `/mcp`。像 Antigravity, Claude Code, Cursor 等 AI Agent 可以直接连接并安全地读写您的笔记库,实现笔记自动整理、标签归纳与双向联动。\n\n---\n\n### 🔒 8. 个人空间隔离与安全分享\n\n- **多账号与管理员中心**:支持多账号独立登录,数据物理隔离。系统提供防暴力破解的安全防护。\n- **多活跃设备管理**:个人设置中可直观查看当前账户在哪些设备登录,并可随时强制下线其他设备。\n- **可撤销的公开分享**:支持生成单独笔记的公开分享链接(列表及正文顶部可直观感知分享状态),他人无需登录即可查阅最新内容,您也可以随时关闭分享。\n\n---\n\n> 🎯 **快速探索建议**:\n> - 试试点击右上角的**微信图标**,将排版精美的富文本直接粘贴至公众号或 WordPress 后台;\n> - 试试在 **个人中心 / 设置 / 编辑器主题** 中切换您喜爱的写作风格;\n> - 按下 `Cmd/Ctrl + Shift + F` 开启 Zen 专注模式,享受无干扰的写作空间;\n> - 鼠标拖拽左侧的笔记本,体验无限层级目录的顺滑管理;\n> - 在个人中心或侧边栏点击“恢复 Demo 数据”,即可随时一键将整个演示环境恢复如初。" + `# EdgeEver Logo 欢迎使用 EdgeEver:为极客与创作者打造的现代开源知识库 + +> **EdgeEver** 是一款兼具**经典三栏美学**与 **AI 原生动力**的开源 Serverless / 容器化个人知识库。它既找回了极客们钟爱的经典印象笔记式双视图与树状目录,又以零服务器成本、完全数据自主、全端原生覆盖与深度 MCP 智能体协同,重新定义了下一代个人第二大脑。 + +--- + +## ⚡ 1. 为什么选择 EdgeEver? + +*提示:在编辑器模式下,你可以直接点击任意表格单元格进行行内编辑,或右键快捷插入/删除行列。* + +| 核心维度 | 传统商业云笔记 (如 Evernote) | 本地离线知识库 (如 Obsidian) | EdgeEver 极客知识库 | +| :--- | :--- | :--- | :--- | +| **云端托管成本** | 商业订阅高昂($10+/月) | 官方云同步收费($5+/月) | **100% 永久免费 (Cloudflare 免费额度 / Docker 自建)** | +| **数据资产所有权** | 专有格式封闭,导出困难 | 本地 Markdown,移动端同步繁琐 | **完全自主掌控 (D1 SQLite 数据库 / R2 / 无损 ZIP 导出)** | +| **写作与编辑体验** | 仅富文本,排版易错乱 | 纯 Markdown,缺乏沉浸所见即所得 | **双视图自由切换 (所见即所得富文本 ⇄ Markdown 源码)** | +| **自媒体排版分发** | 无样式优化,格式丢失 | 需借助外部排版扩展或工具 | **一键复制到微信公众号 / Substack / Medium / WordPress** | +| **社交卡片分享** | 截图粗糙或无排版设计 | 需第三方插件实现 | **内置 8 款精美海报主题,支持自定义字体与 PNG/JPEG 导出** | +| **AI 原生集成生态** | 封闭收费,仅限特定功能 | 需配置复杂的第三方插件 | **原生内置 MCP 服务端点 (\`/mcp\`) 与行内 AI 智能体协同** | +| **全平台多端覆盖** | 限制免费设备登录数量 | 多端同步与移动端体验门槛高 | **Web / PWA / Android / iOS / macOS / Windows (即将推出)** | + +--- + +## 🏗️ 2. 全景架构与生态联动 + +通过下面的 Mermaid 架构图,你可以清晰了解 EdgeEver 如何将多端客户端、零成本云基础设施与 AI Agent 紧密串联: + +\`\`\`mermaid +flowchart TD + subgraph MultiClients["全端客户端矩阵"] + C1["Web / PWA (离线草稿 & 增量同步)"] + C2["macOS 桌面端 (Electron + Rust Sidecar)"] + C3["Android 原生 App (Expo + SQLite)"] + C4["iOS 原生 App (SwiftUI + GRDB)"] + C5["浏览器剪藏插件 (Chrome / Edge / Firefox)"] + end + + subgraph CoreEngine["业务与数据服务层"] + API["Hono API 引擎 (Cloudflare Workers / Docker)"] + MCP["原生 MCP Endpoint (/mcp 2026-07-28 & 2025)"] + D1[("D1 / SQLite 数据库 (双向同步 & 修订版本)")] + R2[("R2 / S3 资源存储 (图片与多媒体附件)")] + end + + subgraph AIAgents["AI 智能体与外部生态"] + A1["Claude Code / Cursor / Antigravity"] + A2["行内 AI 助手 (OpenAI / Gemini / DeepSeek)"] + A3["Notion 数据库 / 飞书多维表格联动"] + end + + MultiClients <==>|REST API & 同步游标| API + API <==> D1 & R2 + MCP <==> D1 & R2 + A1 <==>|MCP Tools / SSE| MCP + A2 -.->|BYOK 密钥直连| MultiClients + A1 -.->|双向数据同步| A3 +\`\`\` + +--- + +## 🎨 3. 极致创作体验与排版美学 + +EdgeEver 将高效与优雅融入每一处交互细节,助你专注于思考与表达: + +### 🖥️ 双视图编辑器与沉浸模式 +- **自由切换视图**:点击右上角 \`\` 按钮或使用快捷键,可在**所见即所得富文本**与 **Markdown 源码**间无缝切换,实时双向保真。 +- **左侧可折叠大纲**:自动解析文档 \`H1-H3\` 标题层级,支持点击平滑滚动跳转,助你轻松把控万字长文。 +- **Zen 专注模式**:按下 \`Cmd/Ctrl + Shift + F\`,隐藏所有侧边栏与干扰元素,进入纯粹写作心流。 +- **阅读保护模式 (Reading Protection)**:日常翻阅或查阅笔记时,按下 \`Cmd/Ctrl + E\` 即可一键开启只读保护,锁定当前编辑状态,避免沉浸阅读时误触键盘或意外改动笔记内容;再次按下即可随手切回编辑。 + +### 🎭 精选排版主题与一键自媒体发布 +- **内置排版主题**:支持一键切换 \`WeChat Classic Green (微信经典绿)\`、\`Modern Mint (薄荷青)\`、\`Minimal Emerald (极简祖母绿)\`、\`Outline Emerald (大纲祖母绿)\` 等风格。 +- **一键排版复制**:专为内容创作者设计。点击顶部工具栏的**微信公众号图标**,系统自动将当前笔记转为内联 CSS 样式的优雅富文本,直接粘贴至微信公众号后台、Substack 或 WordPress,排版与代码高亮完美保真。 + +### 🖼️ 8 套精美社交分享海报 (Poster Cards) +点击右上角“分享为卡片”,即可将任意笔记或片段渲染为高清分享海报,支持: +- **8 大主题风格**:\`Slate (岩灰)\`、\`Aurora (极光青)\`、\`Sunset (落日暖橙)\`、\`Midnight (暗夜极客)\`、\`Mint (清爽薄荷)\`、\`Notepad (复古便签)\`、\`Xuan (宣纸水墨)\`、\`Lavender (薰衣草紫)\`。 +- **排版定制**:支持无衬线 (Sans)、宋体/明朝 (Serif)、等宽代码 (Mono) 字体切换,自由选择紧凑、标准或宽幅卡片,一键导出为高清晰度 PNG 或 JPEG 图片。 + +--- + +## ⌨️ 4. 效率工具箱:斜杠指令、双链与数学公式 + +### 🪄 斜杠指令 (Slash Commands) +在正文空白行输入 \`/\` 或直接按下 \`空格键\`,即可呼出快捷指令菜单: +- 快速插入 \`H1/H2/H3\` 标题、引用、分割线、代码块与富文本表格; +- 输入 \`/date\`、\`/time\` 或 \`/now\` 快速插入当前标准时间戳; +- 插入附件、图片或调起行内 AI 智能助手。 + +### 🔗 知识双链与笔记引用 +在编辑器中输入 \`@\` 或插入 \`#memo=<笔记ID>\` 链接,即可建立笔记间的双向关联,点击即可在工作区内快速打开关联笔记,构建结构化网状知识库。 + +### 📐 KaTeX 专业数学公式渲染 +EdgeEver 原生支持 LaTeX 数学表达式,无论是行内微积分还是多行物理方程,均可毫秒级高保真渲染: + +- **行内公式**:例如质能方程 $E = mc^2$,以及正态分布概率密度函数 $f(x) = \\frac{1}{\\sigma \\sqrt{2\\pi}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}$。 +- **多行独立公式块**: +$$ +\\oint_{\\partial \\Omega} \\mathbf{E} \\cdot d\\mathbf{S} = \\frac{1}{\\varepsilon_0} \\iiint_{\\Omega} \\rho \\, dV, \\quad \\oint_{\\partial \\Omega} \\mathbf{B} \\cdot d\\mathbf{S} = 0 +$$ + +### ✅ 交互式待办清单 (Task Lists) +- [x] 体验 EdgeEver 双视图与大纲导航 +- [x] 探索 8 款编辑器主题与 8 套社交海报卡片 +- [ ] 尝试使用斜杠指令 \`/\` 插入当前日期与结构化表格 +- [ ] 配置个人 AI API Key,体验行内智能总结与续写 +- [ ] 开启 MCP 协议,让 AI Agent 协助整理工作区 + +--- + +## 🤖 5. AI 原生协同与 MCP 智能体生态 + +EdgeEver 走在 AI 时代前沿,将大语言模型与智能体深度融入知识管理生命周期: + +\`\`\`mermaid +sequenceDiagram + autonumber + actor User as 创作者 / 知识工作者 + participant Client as EdgeEver 多端应用 + participant MCP as EdgeEver MCP 服务端点 + participant Agent as AI Agent (Claude / Cursor / Antigravity) + participant Database as Notion / 飞书多维表格 + + User->>Client: 快速记录碎片想法与会议灵感 + Agent->>MCP: tools/call memo_search (检索近期未整理笔记) + MCP-->>Agent: 返回结构化 Markdown 笔记内容与标签 + Agent->>Agent: 理解内容、自动提炼核心摘要并归类标签 + Agent->>MCP: tools/call memo_update (写回智能总结与增强标签) + Agent->>Database: 同步结构化字段至个人知识总库 + Client-->>User: 客户端毫秒级感知更新,笔记井井有条 +\`\`\` + +### 1️⃣ 行内 AI 助手 (Inline AI Assistant) +在正文空白行直接按下 **\`空格键 (Space)\`**、输入 **\`/ai\`**、通过 **\`/\`** 斜杠指令菜单,或选中文本点击浮动工具栏中的 **AI 按钮**,即可即时呼出 AI 写作助手面板: +- **精炼总结与要点提取**:一键压缩提炼全文核心结论、提取待办事项与关键行动项; +- **格式保真智能翻译**:在严格保留原有 Markdown、数学公式、链接与代码块的前提下,精准翻译多国语言; +- **内容重塑与风格改写**:支持改进表达、修正错别字与语法、转为社交媒体(如小红书/推特)风格,或按上下文顺滑续写; +- **BYOK 隐私直连 (Bring Your Own Key)**:支持直连 OpenAI、Anthropic Claude、Google Gemini、DeepSeek 及各类 OpenAI 兼容的中继 API,数据完全由端侧直发,不经过任何第三方中转。 + +### 2️⃣ 开放 MCP 协议 (Model Context Protocol) +在**设置 → MCP 设置**中生成专属令牌,即可将 EdgeEver 接入 Claude Code、Cursor、Antigravity、OpenClaw 等主流 AI 编码助手与智能体平台: +- **无缝读写**:支持标准 MCP 端点 \`/mcp\`(兼容最新的无状态 \`2026-07-28\` 协议与经典握手协议); +- **自动化流转**:AI Agent 可自动读取笔记、智能归档、批量打标,甚至与 Notion、飞书多维表格建立跨平台自动化同步。 + +--- + +## 📱 6. 全平台原生覆盖、离线同步与智能剪藏 + +- **多端原生支持**: + - **Web / PWA**:支持现代浏览器全功能运行与离线安装; + - **Android 原生客户端**:基于 Expo 与 SQLite 构建,已上架 Google Play,并提供签名 APK 下载; + - **iOS 原生客户端**:基于 Swift / SwiftUI 与 GRDB 原生实现,流畅细腻,已上架 App Store; + - **macOS 桌面端**:Electron + Rust 高性能 Sidecar,支持 Apple Silicon 和 Intel Mac,内置静默后台更新; + - **Windows 桌面端**:已开发完毕,即将正式推出。 +- **浏览器网页剪藏 (Web Clipper)**:已在 Chrome、Edge 和 Firefox 官方扩展商店发布,一键剔除网页广告,将正文纯净沉淀为 Markdown 笔记。 +- **微信公众号一键剪藏**:在移动端系统分享菜单中,直接将微信文章分享到 EdgeEver,客户端将自动提取图文排版并转换为可编辑笔记。 +- **离线草稿与弹性同步**:地铁、飞行模式等无网络环境下自由编辑,重新联网后自动入队完成增量同步与冲突协调。 + +--- + +## 📦 7. 多媒体管理、无损备份与零成本自建 + +### 🖼️ 智能本地图片压缩 +在笔记中粘贴或拖入高分辨率图片时,前端会在本地自动将其转码压缩为 WebP 格式,在保证视觉无损的前提下**减少 50% - 90% 的体积**,大幅降低云端存储占用并提升跨端加载速度。 + +![EdgeEver 极客猫猫吉祥物](/api/v1/resources/res_demo_cat_image/blob) + +### 📎 多类型附件自由挂载 +支持在笔记中嵌入 PDF 文档、CSV 表格、压缩包及多媒体资源,点击即可在线预览或下载: +- [📄 产品白皮书 PDF:edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob) +- [📊 功能矩阵 CSV:feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob) +- [📦 示例附件压缩包:edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob) + +### 🚀 两种自建部署方案:Serverless 与 Docker +1. **Cloudflare Serverless(推荐,永久 100% 免费)**:基于 Workers + D1 数据库 + R2 对象存储构建,完全处于 Cloudflare 免费额度内,无需采购服务器,免运维、免证书续期。 +2. **Docker 一键自建(VPS / NAS / 家用服务器)**: + \`\`\`sh + # 国际 VPS / NAS 极速安装(GHCR 镜像) + curl -fsSL https://edgeever.org/install.sh | bash + + # 大陆地区 VPS / NAS 镜像加速(腾讯云 TCR 镜像) + curl -fsSL https://edgeever-installer-1256854452.cos.ap-guangzhou.myqcloud.com/install.sh | bash -s -- --mirror tcr + \`\`\` + 单命令自动配置 Docker Compose 环境,并内置每日定时自动更新。 + +### 💾 绝对的数据自由:无损 ZIP 导入与导出 +在**个人中心 → 导入与导出**中,可随时将完整笔记库打包导出为结构清晰的 ZIP 压缩包。解压后即为包含标准 YAML Front Matter、相对路径附件图片与完整修订版本的纯 Markdown 文件树,随时可在 Obsidian、VS Code 等任意工具中无缝打开,永不担心平台绑定! + +--- + +> 💡 **快速体验小贴士**: +> 1. 点击右上角 **\`\`** 体验丝滑的双视图切换; +> 2. 按下 **\`Cmd/Ctrl + E\`** 试一试阅读保护模式,锁定只读避免误改内容; +> 3. 按下 **\`Cmd/Ctrl + O\`** 呼出快速切换器 (Quick Switcher); +> 4. 点击顶部 **微信图标**,体验一键带格式排版复制; +> 5. 点击 **“分享为卡片”**,挑选一款你心仪的社交海报风格并导出; +> 6. 随时在侧边栏或设置中点击 **“恢复 Demo 数据”**,一键重置演示工作区。 +`, }, ]; + export const DEMO_SEED_REVISIONS = [ { id: "rev_demo_revision_1", memoId: "memo_demo_overview", revision: 1, - title: "🌟 欢迎使用 EdgeEver", + title: "🌿 欢迎使用 EdgeEver:为极客与创作者打造的现代开源知识库", markdown: - "## 🌟 欢迎使用 EdgeEver(草稿)\n\n- 印象笔记经典三栏与自建 Serverless\n- 可视化表格与 Markdown 源码双向切换", + "## 🌿 欢迎使用 EdgeEver(初版草稿)\n\n- 印象笔记经典三栏与自建 Serverless\n- 可视化表格与 Markdown 源码双向切换\n- 原生 MCP 与 AI 智能体协同", }, { id: "rev_demo_revision_1_en", memoId: "memo_demo_overview_en", revision: 1, - title: "🌟 Welcome to EdgeEver", + title: "🌿 Welcome to EdgeEver: Modern Open-Source Knowledge Base for Geeks & Creators", markdown: - "## 🌟 Welcome to EdgeEver (Draft)\n\n- Classic Evernote 3-pane layout & Serverless self-hosted\n- Visual table editing & Markdown source toggle", + "## 🌿 Welcome to EdgeEver (Initial Draft)\n\n- Classic Evernote 3-pane layout & Serverless self-hosted\n- Visual table editing & Markdown source toggle\n- Native MCP & AI agent synergy", }, ]; + export const DEMO_MEMO_ENGLISH = { memo_demo_overview: { - title: "🌟 Welcome to EdgeEver", + title: "🌿 Welcome to EdgeEver: Modern Open-Source Knowledge Base for Geeks & Creators", markdown: - "## 🚀 Get Started with EdgeEver: The Geek's Knowledge Base\n\n> **EdgeEver** is a modern, open-source, serverless personal knowledge base built for geeks and creators. It restores the classic **Evernote-style three-pane layout**, while offering **100% free hosting** using Cloudflare's free tier, full data ownership, dual-view editing, and native AI Agent (MCP) integration.\n\n---\n\n### ⚡ 1. Feature Comparison\n\n*Tip: Click any cell in the table below to edit directly; right-click in editor mode to insert/delete rows or columns.*\n\n| Metric | Traditional Cloud Notes (e.g. Evernote) | Local Offline Notes (e.g. Obsidian) | EdgeEver Notes |\n| :--- | :--- | :--- | :--- |\n| **Hosting Cost** | High monthly fee ($10+/mo) | Official sync fee ($5/mo) | **100% Free (Cloudflare Free Tier)** |\n| **Data & Privacy** | Closed platform, locked export | Local files, sync needs setup | **Full Ownership (D1 SQLite, R2, WebDAV)** |\n| **Editing Mode** | Rich Text | Pure Markdown | **Seamless Dual-View Toggle (Rich Text / MD)** |\n| **Device Sync** | Limits active devices | Complicated mobile setup | **Web / PWA / Android / macOS / iOS (In Review)** |\n| **For Creators** | No formatting optimizations | Requires 3rd-party tools | **One-Click Rich Copy for WeChat & Substack** |\n| **AI Integration**| Paid/Limited versions only | Requires heavy plugin config | **Native MCP Protocol & Standard OpenAPI** |\n\n---\n\n### 🎨 2. Immersive Writing & Typography Aesthetics\n\nEdgeEver is crafted to provide a distraction-free and beautiful writing experience:\n\n- **Seamless Dual-View Editor**: Click the `` button in the top right to switch effortlessly between **WYSIWYG Rich Text** and **Markdown Source Code** with 100% compatibility.\n- **Collapsible Outline View**: Enjoy a fixed or collapsible sidebar outline of your document headings. Click any heading to navigate smoothly.\n- **8+ Exquisite Editor Themes**: Change your writing vibe instantly in **User Settings / Profile** with preset themes such as `WeChat Classic Green`, `Modern Mint`, `minimal-emerald`, and more.\n- **One-Click Publishing Export**: Built for publishers. Click \"Copy for WeChat / Publishing\" to automatically format your note with inline CSS. Paste it directly into WeChat, Substack, Medium, or WordPress editor while preserving layout and syntax highlighting.\n- **List Indentation & Quick Link**: Use quick keys for list indents, and double-click or select text to quickly link to existing notes with shortcut hints.\n\n---\n\n### 📝 3. Template Center & Single-Note Export\n\n- **Visual Template Library**: Access a curated collection of note templates with live modal preview cards. Instantly create notes using a template and jump back with one click.\n- **Custom Templates**: Save your frequent note structures as custom templates to double your productivity.\n- **Flexible File Export**: Export the current note as a standard `.md` Markdown file or a beautifully styled `.pdf` document for offline archival and sharing.\n\n---\n\n### 📊 4. Native Mermaid Diagram Rendering\n\nUse standard `mermaid` fenced code blocks to render beautiful diagrams in real time, with support for **selectable diagram themes** and dimension-preserved copying:\n\n#### 1️⃣ System Flowchart\n```mermaid\nflowchart TD\n subgraph Client[\"📱 Clients Ecosystem\"]\n A[\"Web / PWA\"]\n B[\"macOS / Android / iOS Apps\"]\n end\n\n subgraph Backend[\"⚡ Cloudflare Serverless\"]\n C[\"Cloudflare Workers API\"]\n D[(\"D1 SQLite DB\")]\n E[(\"R2 Object Storage\")]\n end\n\n A & B --> C\n C <--> D & E\n```\n\n#### 2️⃣ Interactive Sequence Diagram\n```mermaid\nsequenceDiagram\n autonumber\n actor User as User\n participant App as EdgeEver Client\n participant Worker as Cloudflare Worker API\n participant D1 as D1 Database\n\n User->>App: Edit and save note\n App->>Worker: POST /api/v1/memos (Save changes)\n Worker->>D1: Write note content & update revision\n D1-->>Worker: Return success (revision + 1)\n Worker-->>App: 200 OK (Latest sync cursor)\n App-->>User: Status updated to \"Saved\"\n```\n\n---\n\n### 📁 5. Multi-Device Sync, Offline Queue & Clipping\n\n- **Everywhere You Need It**: Native clients are available for Web, Android, and macOS (Intel & Apple Silicon), with the iOS client under App Store review.\n- **Web Clipper**: Available on Chrome, Edge, and Firefox Add-ons stores to save webpage contents with one click.\n- **Mobile WeChat Clipper**: Share any WeChat article to EdgeEver on your phone, and it automatically extracts the article content as an editable note.\n- **Offline Sync & Queue**: Keep writing even without network. Your edits are queued locally and synchronized automatically when connection resumes. Customize sync intervals in settings.\n\n---\n\n### 🖼️ 6. Rich Media & Smart Image Compression\n\nDrag-and-drop or paste images directly into your editor. EdgeEver compresses images locally to WebP before upload, reducing file sizes by **50% - 90%** to save bandwidth and Cloudflare storage.\n\n![EdgeEver Mascot: Geek Cat](/api/v1/resources/res_demo_cat_image/blob)\n\n---\n\n### 🤖 7. Native AI Agent Ecosystem (Agent-Ready)\n\nEdgeEver is architected natively for the AI era:\n\n1. **REST API**: Provides complete OpenAPI definitions at `/api/openapi.json`.\n2. **MCP (Model Context Protocol) Endpoint**: Accessible at `/mcp`, allowing AI agents (like Antigravity, Claude Code, and Cursor) to securely connect, read, and write notes in your workspace for automated tags, summaries, and edits.\n\n---\n\n### 🔒 8. Account Isolation & Secure Sharing\n\n- **Multi-Tenant Isolation**: Supports multiple user accounts with independent workspace databases and brute-force login protection.\n- **Active Devices Session Control**: Check active login locations and user agents, and revoke other sessions with one tap in settings.\n- **Revocable Note Sharing**: Share a note publicly with a secure link and toggle it off anytime. Active sharing status is visible on the note list and editor header.\n\n---\n\n> 🎯 **Quick Try**:\n> - Click the **WeChat Icon** in the top bar and paste the styled rich text directly into WeChat, Substack, or WordPress;\n> - Swap **Editor Themes** in **Settings** to find your favorite color scheme;\n> - Press `Cmd/Ctrl + Shift + F` to enter Focus Mode for distraction-free writing;\n> - Drag and drop notebooks in the left list to experiment with infinite nesting;\n> - Click \"Reset Demo Data\" in the sidebar or settings to reset the workspace state at any time!" + `# EdgeEver Logo Welcome to EdgeEver: Modern Open-Source Knowledge Base for Geeks & Creators + +> **EdgeEver** is an open-source, AI-native, and portable serverless/containerized personal knowledge base that revives the beloved **Evernote-style three-pane layout**. Designed for geeks and content creators, it combines 100% free serverless hosting, absolute data ownership, native cross-platform clients, and seamless AI Agent (MCP) synergy to redefine your digital second brain. + +--- + +## ⚡ 1. Why Choose EdgeEver? + +*Tip: In editor mode, click any table cell to edit text directly, or right-click to insert/delete rows and columns.* + +| Dimension | Traditional Cloud Notes (e.g. Evernote) | Local Offline Notes (e.g. Obsidian) | EdgeEver Geek Knowledge Base | +| :--- | :--- | :--- | :--- | +| **Hosting Cost** | Costly commercial subscriptions ($10+/mo) | Official cloud sync subscription ($5+/mo) | **100% Free Forever (Cloudflare Free Tier / Docker Self-Hosted)** | +| **Data Ownership** | Proprietary lock-in, hard to export | Local Markdown, cumbersome mobile sync | **Full Ownership (D1 SQLite, R2 Storage, Lossless ZIP Archives)** | +| **Editing Experience** | Rich text only, fragile formatting | Plain Markdown, lacks WYSIWYG flow | **Seamless Dual-View (WYSIWYG Rich Text ⇄ Markdown Source)** | +| **Publishing Ready** | No typography styling, loses format | Requires 3rd-party plugins or scripts | **One-Click Rich Copy for WeChat, Substack, Medium & WordPress** | +| **Social Poster Cards** | Basic screenshots without styling | Requires external tools or plugins | **8 Built-in Exquisite Poster Themes with Typography Options & PNG/JPEG Export** | +| **Native AI Ecosystem** | Paywalled, limited features | Heavy plugin setup required | **Native MCP Server (\`/mcp\`) & Inline AI Agent Synergy** | +| **Cross-Platform Matrix** | Restricts active free devices | Complex setup across platforms | **Web / PWA / Android / iOS / macOS / Windows (Coming Soon)** | + +--- + +## 🏗️ 2. Architectural Overview & Ecosystem + +The Mermaid diagram below demonstrates how EdgeEver connects cross-platform clients, zero-cost cloud infrastructure, and AI Agents into a cohesive workflow: + +\`\`\`mermaid +flowchart TD + subgraph MultiClients["Client Matrix"] + C1["Web / PWA (Offline Drafts & Sync Queue)"] + C2["macOS Desktop (Electron + Rust Sidecar)"] + C3["Android Native App (Expo + SQLite)"] + C4["iOS Native App (SwiftUI + GRDB)"] + C5["Web Clipper (Chrome / Edge / Firefox)"] + end + + subgraph CoreEngine["Service & Storage Core"] + API["Hono API Engine (Cloudflare Workers / Docker)"] + MCP["Native MCP Endpoint (/mcp 2026-07-28 & 2025)"] + D1[("D1 / SQLite Database (Sync Cursor & Revisions)")] + R2[("R2 / S3 Storage (Images & Media Attachments)")] + end + + subgraph AIAgents["AI Agents & Integrations"] + A1["Claude Code / Cursor / Antigravity"] + A2["Inline AI Assistant (OpenAI / Gemini / DeepSeek)"] + A3["Notion DB / Feishu Bitable Sync"] + end + + MultiClients <==>|REST API & Sync Cursor| API + API <==> D1 & R2 + MCP <==> D1 & R2 + A1 <==>|MCP Tools / SSE| MCP + A2 -.->|BYOK Direct Key| MultiClients + A1 -.->|Bi-directional Sync| A3 +\`\`\` + +--- + +## 🎨 3. Immersive Writing & Typography Aesthetics + +EdgeEver is engineered to provide a distraction-free, elegant writing experience: + +### 🖥️ Dual-View Editor & Focus Modes +- **Seamless Dual-View**: Click the \`\` button in the top-right corner (or use shortcuts) to instantly toggle between **WYSIWYG Rich Text** and **Markdown Source Code** with 100% fidelity. +- **Collapsible Outline Navigation**: Automatically indexes \`H1-H3\` heading hierarchies with smooth jump scrolling, keeping lengthy documents organized. +- **Zen Focus Mode**: Press \`Cmd/Ctrl + Shift + F\` to hide sidebars and distractions, immersing yourself in pure writing flow. +- **Reading Protection Mode**: When reading or reviewing notes, press \`Cmd/Ctrl + E\` to toggle read-only protection, locking the editor to prevent accidental edits while browsing; press it again to seamlessly resume editing. + +### 🎭 Curated Typography Themes & Publishing Export +- **Preset Editor Themes**: Switch effortlessly between \`WeChat Classic Green\`, \`Modern Mint\`, \`Minimal Emerald\`, \`Outline Emerald\`, and more. +- **One-Click Publishing Export**: Built for publishers and bloggers. Click the **WeChat Icon** in the top bar to format your note with inline CSS. Paste directly into WeChat Official Account editor, Substack, Medium, or WordPress while preserving layout and syntax highlighting. + +### 🖼️ 8 Exquisite Social Poster Themes +Click **"Share as Card"** in the top-right menu to turn any note into an eye-catching poster card: +- **8 Themes**: \`Slate\`, \`Aurora\`, \`Sunset\`, \`Midnight\`, \`Mint\`, \`Notepad\` (skeuomorphic paper), \`Xuan\` (rice paper & Chinese ink), \`Lavender\`. +- **Customizable Typography**: Switch between Sans, Serif (Songti/Ming), and Monospace fonts, select compact, standard, or wide card widths, and export as high-resolution PNG or JPEG. + +--- + +## ⌨️ 4. Power Productivity Toolbox: Slash Commands, Backlinks & Math + +### 🪄 Slash Commands +Type \`/\` or press \`Space\` on an empty line to invoke the command menu: +- Insert \`H1/H2/H3\` headings, quotes, horizontal rules, code blocks, and rich tables; +- Use \`/date\`, \`/time\`, or \`/now\` to insert current timestamps instantly; +- Attach files, insert images, or summon the inline AI assistant. + +### 🔗 Bi-directional Note Links & Backlinks +Type \`@\` or insert \`#memo=\` links to establish bi-directional references across your knowledge base, building an interconnected web of thoughts. + +### 📐 KaTeX Professional LaTeX Mathematics +Native support for KaTeX renders complex mathematical equations in milliseconds: + +- **Inline Math**: For instance, Einstein's mass-energy equivalence $E = mc^2$ or the Gaussian probability density function $f(x) = \\frac{1}{\\sigma \\sqrt{2\\pi}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}$. +- **Display Block Math**: +$$ +\\oint_{\\partial \\Omega} \\mathbf{E} \\cdot d\\mathbf{S} = \\frac{1}{\\varepsilon_0} \\iiint_{\\Omega} \\rho \\, dV, \\quad \\oint_{\\partial \\Omega} \\mathbf{B} \\cdot d\\mathbf{S} = 0 +$$ + +### ✅ Interactive Task Lists +- [x] Explore EdgeEver's dual-view editing and outline navigation +- [x] Experiment with 8 editor themes and 8 social poster card styles +- [ ] Try typing \`/\` on an empty line to insert current timestamp and tables +- [ ] Connect your AI API Key to experience inline summarization and continuation +- [ ] Connect AI Agents via MCP to automate note categorization + +--- + +## 🤖 5. Native AI Agent Synergy & MCP Protocol + +EdgeEver is architected for the agentic AI era, weaving LLMs directly into the knowledge management lifecycle: + +\`\`\`mermaid +sequenceDiagram + autonumber + actor User as Creator / Knowledge Worker + participant Client as EdgeEver Clients + participant MCP as EdgeEver MCP Endpoint + participant Agent as AI Agent (Claude / Cursor / Antigravity) + participant Database as Notion / Feishu Bitable + + User->>Client: Capture quick spark or meeting notes + Agent->>MCP: tools/call memo_search (Query unprocessed memos) + MCP-->>Agent: Returns structured Markdown & tags + Agent->>Agent: Analyzes content, extracts key takeaways & tags + Agent->>MCP: tools/call memo_update (Writes back summary & tags) + Agent->>Database: Syncs structured records to master database + Client-->>User: Sub-second live updates in client UI +\`\`\` + +### 1️⃣ Inline AI Assistant +Press the **\`Space\` bar** in an empty block, type **\`/ai\`**, use the **\`/\`** slash command menu, or select text and click the **AI button** on the floating toolbar to instantly summon the AI writing assistant: +- **Summarization & Action Items**: Condense documents into key takeaways, conclusions, and actionable todos; +- **Format-Preserving Translation**: Translate accurately into multiple languages while strictly preserving Markdown, math equations, links, and code blocks; +- **Rewriting & Style Transformation**: Improve phrasing, fix spelling/grammar, adapt to social media styles (e.g. Xiaohongshu / Twitter), or continue writing seamlessly; +- **BYOK Direct Key (Bring Your Own Key)**: Direct client-side connection with OpenAI, Anthropic Claude, Google Gemini, DeepSeek, and OpenAI-compatible relays with zero third-party data transit. + +### 2️⃣ Model Context Protocol (MCP) Integration +Generate an API token in **Settings → MCP Settings** to connect EdgeEver directly with Claude Code, Cursor, Antigravity, OpenClaw, and other agent platforms: +- **Direct Reading & Writing**: Connect via the \`/mcp\` endpoint (supports stateless \`2026-07-28\` protocol and handshake-based 2025 specs); +- **Automated Workflows**: Let AI Agents read, organize, summarize, tag, and synchronize notes with Notion databases and Feishu Bitable. + +--- + +## 📱 6. Multi-Platform Ecosystem, Offline Sync & Smart Clipping + +- **Cross-Platform Native Apps**: + - **Web / PWA**: Full-featured in modern browsers with offline installation support; + - **Android Native App**: Built with Expo & SQLite, available on Google Play and GitHub Releases; + - **iOS Native App**: Native Swift / SwiftUI with GRDB local mirror, available on the App Store; + - **macOS Desktop App**: Electron + Rust Sidecar for Apple Silicon & Intel Mac with silent background updates; + - **Windows Desktop App**: Development is complete, coming soon. +- **Browser Web Clipper**: Available on Chrome, Edge, and Firefox extension stores to extract clean, ad-free Markdown articles in one click. +- **Mobile WeChat Article Clipper**: Share any WeChat article to EdgeEver on your phone to automatically extract and format it as an editable note. +- **Offline Drafts & Sync Queue**: Keep writing seamlessly without network connectivity; changes are queued locally and automatically synced once reconnected. + +--- + +## 📦 7. Rich Media, Lossless Portability & Zero-Cost Hosting + +### 🖼️ Smart Client-Side Image Compression +When pasting or dragging images into notes, EdgeEver compresses them to WebP locally in your browser before upload, **reducing file size by 50% - 90%** while preserving visual fidelity. + +![EdgeEver Mascot: Geek Cat](/api/v1/resources/res_demo_cat_image/blob) + +### 📎 Universal File Attachments +Embed PDFs, spreadsheets, archives, and multimedia files directly in notes for preview or download: +- [📄 Product brief PDF: edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob) +- [📊 Feature matrix CSV: feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob) +- [📦 Sample attachment archive: edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob) + +### 🚀 Zero-Cost Serverless & Docker Self-Hosting +1. **Cloudflare Serverless (Recommended, 100% Free Forever)**: Runs entirely within Cloudflare's free tier (Workers + D1 SQLite + R2 Storage). No server bills, no VPS maintenance. +2. **Docker One-Command Deployment (VPS / NAS / Home Server)**: + \`\`\`sh + # International VPS / NAS installer (GHCR image) + curl -fsSL https://edgeever.org/install.sh | bash + + # Mainland China mirror installer (Tencent TCR image) + curl -fsSL https://edgeever-installer-1256854452.cos.ap-guangzhou.myqcloud.com/install.sh | bash -s -- --mirror tcr + \`\`\` + Configures Docker Compose and automated daily background updates with one command. + +### 💾 Complete Data Freedom: Lossless ZIP Portability +Export your entire library at any time from **Profile → Import and export**. The archive contains pure Markdown files with standard YAML Front Matter, relative media paths, and full revision histories—compatible with Obsidian, VS Code, and any plain text editor. + +--- + +> 💡 **Quick Exploration Tips**: +> 1. Click **\`\`** in the top right to try seamless dual-view toggling; +> 2. Press **\`Cmd/Ctrl + E\`** to test reading protection mode against accidental edits; +> 3. Press **\`Cmd/Ctrl + O\`** to summon the Quick Switcher; +> 4. Click the **WeChat Icon** to copy formatted rich text ready for publishing; +> 5. Click **"Share as Card"** to export a stunning social poster card; +> 6. Click **"Reset Demo Data"** in settings or the sidebar anytime to restore the demo workspace. +`, }, } as const; + export const DEMO_SEED_MEMOS_EN = DEMO_SEED_MEMOS_ZH.map((memo) => { const english = DEMO_MEMO_ENGLISH[memo.id as keyof typeof DEMO_MEMO_ENGLISH]; if (!english) { @@ -66,12 +462,25 @@ export const DEMO_SEED_MEMOS_EN = DEMO_SEED_MEMOS_ZH.map((memo) => { markdown: `${english.markdown}${DEMO_ATTACHMENT_MARKDOWN_EN}`, }; }).filter((memo): memo is NonNullable => memo !== null); + export const DEMO_SEED_MEMOS_ZH_WITH_ATTACHMENTS = DEMO_SEED_MEMOS_ZH.map((memo) => ({ ...memo, markdown: `${memo.markdown}${DEMO_ATTACHMENT_MARKDOWN_ZH}`, })); + export const DEMO_SEED_MEMOS = [...DEMO_SEED_MEMOS_ZH_WITH_ATTACHMENTS, ...DEMO_SEED_MEMOS_EN]; + export const DEMO_SEED_RESOURCES = [ + { + id: "res_demo_logo", + memoId: "memo_demo_overview", + filename: "edgeever-icon.svg", + mimeType: "image/svg+xml", + width: 1024, + height: 1024, + svg: + 'EdgeEverAn open cat face in near-black on the EdgeEver green rounded tile.\n \n', + }, { id: "res_demo_cat_image", memoId: "memo_demo_overview", @@ -80,8 +489,10 @@ export const DEMO_SEED_RESOURCES = [ width: 960, height: 540, svg: - ''}, + '', + }, ] as const; + export const DEMO_SEED_ATTACHMENT_RESOURCES = [...DEMO_SEED_RESOURCES, ...DEMO_ATTACHMENT_RESOURCES]; export const DEMO_SEED_NOTEBOOK_IDS = DEMO_SEED_NOTEBOOKS.map((notebook) => notebook.id); export const DEMO_SEED_MEMO_IDS = DEMO_SEED_MEMOS.map((memo) => memo.id); diff --git a/apps/desktop/src/main/index.mjs b/apps/desktop/src/main/index.mjs index 26aa92fc..a22c2c0f 100644 --- a/apps/desktop/src/main/index.mjs +++ b/apps/desktop/src/main/index.mjs @@ -397,8 +397,8 @@ const buildApplicationMenu = () => { { label: "View", submenu: [ - { label: "Focus Search", accelerator: "CmdOrCtrl+K", click: () => sendDesktopCommand("focus-search") }, - { label: "Toggle Focus Mode", accelerator: "CmdOrCtrl+Shift+F", click: () => sendDesktopCommand("toggle-focus-mode") }, + { label: "Focus Search", accelerator: "CmdOrCtrl+Shift+F", click: () => sendDesktopCommand("focus-search") }, + { label: "Toggle Focus Mode", click: () => sendDesktopCommand("toggle-focus-mode") }, { type: "separator" }, { role: "togglefullscreen" }, { role: "resetZoom" }, { role: "zoomIn" }, { role: "zoomOut" }, ], diff --git a/apps/web/src/components/QuickMemoSwitcher.tsx b/apps/web/src/components/QuickMemoSwitcher.tsx new file mode 100644 index 00000000..5a600035 --- /dev/null +++ b/apps/web/src/components/QuickMemoSwitcher.tsx @@ -0,0 +1,119 @@ +import { useDeferredValue, useEffect, useState } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { FileText, LoaderCircle } from "lucide-react"; +import { useTranslation } from "react-i18next"; +import type { MemoSummary } from "@edgeever/shared"; +import type { EdgeEverRepository } from "@/lib/repository"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + COMMAND_ITEM_STRONG_SELECTED_CLASS_NAME, +} from "@/components/ui/command"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogTitle, +} from "@/components/ui/dialog"; + +type QuickMemoSwitcherProps = { + open: boolean; + query: string; + repository: EdgeEverRepository; + onOpenChange: (open: boolean) => void; + onQueryChange: (query: string) => void; + onOpenMemo: (memo: MemoSummary) => void; +}; + +const EMPTY_MEMOS: MemoSummary[] = []; + +export const QuickMemoSwitcher = ({ + open, + query, + repository, + onOpenChange, + onQueryChange, + onOpenMemo, +}: QuickMemoSwitcherProps) => { + const { t } = useTranslation(); + const [selectedMemoId, setSelectedMemoId] = useState(""); + const deferredQuery = useDeferredValue(query.trim()); + const memoQuery = useQuery({ + queryKey: ["quick-memo-switcher", deferredQuery], + queryFn: () => repository.listMemos({ + notebookId: null, + q: deferredQuery, + trash: false, + filter: "all", + sort: "updated-desc", + offset: 0, + limit: 50, + }), + enabled: open, + staleTime: 15_000, + }); + const memos = memoQuery.data?.memos ?? EMPTY_MEMOS; + const loading = memoQuery.isPending || memoQuery.isFetching; + + useEffect(() => { + setSelectedMemoId((current) => ( + memos.some((memo) => memo.id === current) ? current : memos[0]?.id ?? "" + )); + }, [memos]); + + return ( + + + {t("quickSwitcher.title")} + {t("quickSwitcher.description")} + + + + {loading ? ( +
+ + {t("quickSwitcher.loading")} +
+ ) : ( + <> + {t("quickSwitcher.empty")} + + {memos.map((memo) => ( + onOpenMemo(memo)} + > + +
+
{memo.title}
+ {memo.excerpt ? ( +
{memo.excerpt}
+ ) : null} +
+
+ ))} +
+ + )} +
+
+ {t("quickSwitcher.openHint")} + {t("quickSwitcher.closeHint")} +
+
+
+
+ ); +}; diff --git a/apps/web/src/components/WorkspaceApp.tsx b/apps/web/src/components/WorkspaceApp.tsx index 20d56683..5ba9ebaf 100644 --- a/apps/web/src/components/WorkspaceApp.tsx +++ b/apps/web/src/components/WorkspaceApp.tsx @@ -25,6 +25,7 @@ import { DrawerTitle, } from "@/components/ui/drawer"; import { MemoListPane, MemoSelectionActionBar } from "./MemoListPane"; +import { QuickMemoSwitcher } from "./QuickMemoSwitcher"; import { AppConfirmDialog, MemoDeleteConfirmDialog, NotebookNameDialog } from "./dialogs/ConfirmDialogs"; import { api } from "@/lib/api"; import { @@ -704,6 +705,7 @@ export const WorkspaceApp = ({ const autoSelectedDemoNotebookRef = useRef(false); const [createdMemoEditId, setCreatedMemoEditId] = useState(null); const pendingCreatedMemoIdRef = useRef(null); + const pendingQuickSwitcherMemoIdRef = useRef(null); const creatingMemoSelectionRef = useRef(false); const memoDocumentActionIdRef = useRef(0); const [memoDocumentActionRequest, setMemoDocumentActionRequest] = useState(null); @@ -795,6 +797,8 @@ export const WorkspaceApp = ({ : "home" ); const [mobileSearchFocusToken, setMobileSearchFocusToken] = useState(0); + const [quickSwitcherOpen, setQuickSwitcherOpen] = useState(false); + const [quickSwitcherQuery, setQuickSwitcherQuery] = useState(""); const [noteSearchFocusToken, setNoteSearchFocusToken] = useState(0); const [noteReplaceFocusToken, setNoteReplaceFocusToken] = useState(0); const [noteAiAssistantOpenToken, setNoteAiAssistantOpenToken] = useState(0); @@ -1357,6 +1361,13 @@ export const WorkspaceApp = ({ return; } + if (pendingQuickSwitcherMemoIdRef.current) { + if (!memos.some((memo) => memo.id === pendingQuickSwitcherMemoIdRef.current)) { + return; + } + pendingQuickSwitcherMemoIdRef.current = null; + } + if (createdMemoEditId && selectedMemoId === createdMemoEditId) { // Keep the create request alive until the editor consumes it. The new // memo can appear in the list before its detail query has mounted the @@ -2216,11 +2227,40 @@ export const WorkspaceApp = ({ setActivePane("memos"); }; - const handleMobileSearch = () => { + const handleMobileSearch = useCallback(() => { setMobileBottomNavActive("search"); setActivePane("memos"); setMobileSearchFocusToken((value) => value + 1); - }; + }, []); + + const handleGlobalSearch = useCallback(() => { + navigateWorkspaceHome(); + setMemoView("notebook"); + setSelectedTag(null); + setSelectedNotebookId(null); + setMemoFilterMode("all"); + setRightView("editor"); + clearMemoSelection(); + handleMobileSearch(); + }, [clearMemoSelection, handleMobileSearch, navigateWorkspaceHome, setSelectedNotebookId]); + + const handleOpenQuickSwitcherMemo = useCallback((memo: MemoSummary) => { + pendingQuickSwitcherMemoIdRef.current = memo.id; + setQuickSwitcherOpen(false); + setQuickSwitcherQuery(""); + navigateWorkspaceHome(); + setMemoView("notebook"); + setSelectedTag(null); + setSelectedNotebookId(memo.notebookId); + setSearch(""); + setMemoFilterMode("all"); + setRightView("editor"); + clearMemoSelection(); + clearPendingCreatedMemo(); + setCreatedMemoEditId(null); + setSelectedMemoId(memo.id); + setActivePane("editor"); + }, [clearMemoSelection, clearPendingCreatedMemo, navigateWorkspaceHome, setSelectedMemoId, setSelectedNotebookId]); const handleCancelMobileSearch = () => { setSearch(""); @@ -2336,7 +2376,7 @@ export const WorkspaceApp = ({ const removeCommandListener = bridge.onCommand((command) => { if (command === "new-memo") handleCreateMemo(); if (command === "new-notebook") handleCreateNotebook(); - if (command === "focus-search") handleMobileSearch(); + if (command === "focus-search") handleGlobalSearch(); if (command === "toggle-focus-mode") toggleDesktopFocusMode(); if (command === "sync-now") { void runQueuedSync(); @@ -2366,7 +2406,7 @@ export const WorkspaceApp = ({ removeCommandListener(); removeMarkdownListener(); }; - }, [createMemoMutation, defaultMemoNotebookId, handleCreateMemo, handleCreateNotebook, handleMobileSearch, notebooks, selectedNotebookId, toggleDesktopFocusMode]); + }, [createMemoMutation, defaultMemoNotebookId, handleCreateMemo, handleCreateNotebook, handleGlobalSearch, notebooks, selectedNotebookId, toggleDesktopFocusMode]); const handleWorkspaceBackRequest = useCallback(() => { if (appNoticeDialog) { @@ -2535,6 +2575,16 @@ export const WorkspaceApp = ({ return; } + if (action === "openQuickSwitcher") { + event.preventDefault(); + if (event.repeat || event.isComposing) { + return; + } + setQuickSwitcherQuery(""); + setQuickSwitcherOpen(true); + return; + } + const targetElement = event.target instanceof Element ? event.target : null; const isEditorTextTarget = Boolean(targetElement?.closest(".ProseMirror")); @@ -2546,7 +2596,8 @@ export const WorkspaceApp = ({ mobileNotebookPickerOpen || notebookDeleteConfirmation || notebookNameDialog || - templatesOpen + templatesOpen || + quickSwitcherOpen ); if ( @@ -2554,6 +2605,8 @@ export const WorkspaceApp = ({ || action === "saveAndSync" || action === "toggleReadingProtection" || action === "toggleEditorMode" + || action === "openPreviousMemo" + || action === "openNextMemo" ) { // These replace browser-level commands, so consume them throughout the // workspace even when the current editor cannot perform the action. @@ -2569,8 +2622,15 @@ export const WorkspaceApp = ({ setNoteSaveAndSyncToken((value) => value + 1); } else if (action === "toggleReadingProtection") { setNoteReadingProtectionToggleToken((value) => value + 1); - } else { + } else if (action === "toggleEditorMode") { setNoteEditorModeToggleToken((value) => value + 1); + } else { + const targetMemoId = action === "openPreviousMemo" ? previousMemoId : nextMemoId; + if (targetMemoId) { + clearPendingCreatedMemo(); + setCreatedMemoEditId(null); + setSelectedMemoId(targetMemoId); + } } return; } @@ -2585,10 +2645,7 @@ export const WorkspaceApp = ({ if (action === "focusSearch") { event.preventDefault(); - if (event.shiftKey || !selectedMemoId || !isDesktopViewport()) { - if (event.shiftKey) { - setSearch(""); - } + if (!selectedMemoId || !isDesktopViewport()) { clearMemoSelection(); handleMobileSearch(); return; @@ -2598,6 +2655,12 @@ export const WorkspaceApp = ({ return; } + if (action === "focusGlobalSearch") { + event.preventDefault(); + handleGlobalSearch(); + return; + } + if (action === "focusReplace") { if (!selectedMemoId || memoView === "trash" || !isDesktopViewport()) { return; @@ -2628,11 +2691,13 @@ export const WorkspaceApp = ({ rightView, appNoticeDialog, canCreateMemo, + clearPendingCreatedMemo, clearMemoSelection, createNotebookMutation.isPending, createMemoMutation.isPending, handleCreateNotebook, handleCreateMemo, + handleGlobalSearch, handleMobileSearch, shortcutSettings, emptyTrashConfirmationOpen, @@ -2641,7 +2706,11 @@ export const WorkspaceApp = ({ mobileNotebookPickerOpen, notebookDeleteConfirmation, notebookNameDialog, + nextMemoId, + previousMemoId, + quickSwitcherOpen, selectedMemoId, + setSelectedMemoId, templatesOpen, ]); @@ -3140,6 +3209,20 @@ export const WorkspaceApp = ({ + { + setQuickSwitcherOpen(open); + if (!open) { + setQuickSwitcherQuery(""); + } + }} + onQueryChange={setQuickSwitcherQuery} + onOpenMemo={handleOpenQuickSwitcherMemo} + /> + {memoDeleteConfirmation && ( { }); describe("workspace shortcut preferences", () => { - test("provides AI, save, sync, reading protection, and editor mode defaults", () => { + test("provides navigation, AI, save, reading protection, and editor mode defaults", () => { + expect(DEFAULT_SHORTCUT_SETTINGS.focusGlobalSearch).toEqual({ + key: "f", + ctrlOrMeta: true, + shift: true, + alt: false, + }); + expect(DEFAULT_SHORTCUT_SETTINGS.openQuickSwitcher).toEqual({ + key: "o", + ctrlOrMeta: true, + shift: false, + alt: false, + }); + expect(DEFAULT_SHORTCUT_SETTINGS.openPreviousMemo.key).toBe("["); + expect(DEFAULT_SHORTCUT_SETTINGS.openNextMemo.key).toBe("]"); expect(DEFAULT_SHORTCUT_SETTINGS.openAiAssistant).toEqual({ key: "j", ctrlOrMeta: true, @@ -251,7 +265,27 @@ describe("workspace shortcut preferences", () => { alt: false, }); expect(DEFAULT_SHORTCUT_SETTINGS.toggleReadingProtection).toEqual({ - key: "l", + key: "e", + ctrlOrMeta: true, + shift: false, + alt: false, + }); + }); + + test("migrates the unreleased reading protection shortcut without replacing custom bindings", () => { + const values = installLocalStorage(); + values.set(SHORTCUT_SETTINGS_STORAGE_KEY, JSON.stringify({ + toggleReadingProtection: { key: "l", ctrlOrMeta: true, shift: true, alt: false }, + })); + expect(readShortcutSettingsPreference().toggleReadingProtection).toEqual( + DEFAULT_SHORTCUT_SETTINGS.toggleReadingProtection, + ); + + values.set(SHORTCUT_SETTINGS_STORAGE_KEY, JSON.stringify({ + toggleReadingProtection: { key: "r", ctrlOrMeta: true, shift: true, alt: false }, + })); + expect(readShortcutSettingsPreference().toggleReadingProtection).toEqual({ + key: "r", ctrlOrMeta: true, shift: true, alt: false, @@ -267,6 +301,10 @@ describe("workspace shortcut preferences", () => { const settings = readShortcutSettingsPreference(); expect(settings.createMemo.key).toBe("m"); expect(settings.openAiAssistant).toEqual(DEFAULT_SHORTCUT_SETTINGS.openAiAssistant); + expect(settings.focusGlobalSearch).toEqual(DEFAULT_SHORTCUT_SETTINGS.focusGlobalSearch); + expect(settings.openQuickSwitcher).toEqual(DEFAULT_SHORTCUT_SETTINGS.openQuickSwitcher); + expect(settings.openPreviousMemo).toEqual(DEFAULT_SHORTCUT_SETTINGS.openPreviousMemo); + expect(settings.openNextMemo).toEqual(DEFAULT_SHORTCUT_SETTINGS.openNextMemo); expect(settings.saveAndSync).toEqual(DEFAULT_SHORTCUT_SETTINGS.saveAndSync); expect(settings.toggleReadingProtection).toEqual(DEFAULT_SHORTCUT_SETTINGS.toggleReadingProtection); expect(settings.toggleEditorMode).toEqual(DEFAULT_SHORTCUT_SETTINGS.toggleEditorMode); @@ -282,6 +320,22 @@ describe("workspace shortcut preferences", () => { ...modifiers, }); + expect(getShortcutActionForEvent( + keyboardEvent("f", { metaKey: true, shiftKey: true }), + DEFAULT_SHORTCUT_SETTINGS, + )).toBe("focusGlobalSearch"); + expect(getShortcutActionForEvent( + keyboardEvent("o", { ctrlKey: true }), + DEFAULT_SHORTCUT_SETTINGS, + )).toBe("openQuickSwitcher"); + expect(getShortcutActionForEvent( + keyboardEvent("[", { metaKey: true }), + DEFAULT_SHORTCUT_SETTINGS, + )).toBe("openPreviousMemo"); + expect(getShortcutActionForEvent( + keyboardEvent("]", { ctrlKey: true }), + DEFAULT_SHORTCUT_SETTINGS, + )).toBe("openNextMemo"); expect(getShortcutActionForEvent( keyboardEvent("j", { metaKey: true }), DEFAULT_SHORTCUT_SETTINGS, @@ -291,7 +345,7 @@ describe("workspace shortcut preferences", () => { DEFAULT_SHORTCUT_SETTINGS, )).toBe("saveAndSync"); expect(getShortcutActionForEvent( - keyboardEvent("l", { ctrlKey: true, shiftKey: true }), + keyboardEvent("e", { ctrlKey: true }), DEFAULT_SHORTCUT_SETTINGS, )).toBe("toggleReadingProtection"); expect(getShortcutActionForEvent( diff --git a/apps/web/src/lib/app-helpers.ts b/apps/web/src/lib/app-helpers.ts index 531219c4..57e773da 100644 --- a/apps/web/src/lib/app-helpers.ts +++ b/apps/web/src/lib/app-helpers.ts @@ -17,7 +17,11 @@ export type ShortcutAction = | "createMemo" | "createNotebook" | "focusSearch" + | "focusGlobalSearch" | "focusReplace" + | "openQuickSwitcher" + | "openPreviousMemo" + | "openNextMemo" | "openAiAssistant" | "saveAndSync" | "toggleReadingProtection" @@ -190,11 +194,31 @@ export const getShortcutActionOptions = ( label: t("shortcuts.actions.focusSearch.label"), description: t("shortcuts.actions.focusSearch.description"), }, + { + value: "focusGlobalSearch", + label: t("shortcuts.actions.focusGlobalSearch.label"), + description: t("shortcuts.actions.focusGlobalSearch.description"), + }, { value: "focusReplace", label: t("shortcuts.actions.focusReplace.label"), description: t("shortcuts.actions.focusReplace.description"), }, + { + value: "openQuickSwitcher", + label: t("shortcuts.actions.openQuickSwitcher.label"), + description: t("shortcuts.actions.openQuickSwitcher.description"), + }, + { + value: "openPreviousMemo", + label: t("shortcuts.actions.openPreviousMemo.label"), + description: t("shortcuts.actions.openPreviousMemo.description"), + }, + { + value: "openNextMemo", + label: t("shortcuts.actions.openNextMemo.label"), + description: t("shortcuts.actions.openNextMemo.description"), + }, { value: "openAiAssistant", label: t("shortcuts.actions.openAiAssistant.label"), @@ -221,13 +245,24 @@ export const DEFAULT_SHORTCUT_SETTINGS: ShortcutSettings = { createMemo: { key: "n", ctrlOrMeta: true, shift: false, alt: false }, createNotebook: { key: "n", ctrlOrMeta: true, shift: true, alt: false }, focusSearch: { key: "f", ctrlOrMeta: true, shift: false, alt: false }, + focusGlobalSearch: { key: "f", ctrlOrMeta: true, shift: true, alt: false }, focusReplace: { key: "h", ctrlOrMeta: true, shift: false, alt: false }, + openQuickSwitcher: { key: "o", ctrlOrMeta: true, shift: false, alt: false }, + openPreviousMemo: { key: "[", ctrlOrMeta: true, shift: false, alt: false }, + openNextMemo: { key: "]", ctrlOrMeta: true, shift: false, alt: false }, openAiAssistant: { key: "j", ctrlOrMeta: true, shift: false, alt: false }, saveAndSync: { key: "s", ctrlOrMeta: true, shift: false, alt: false }, - toggleReadingProtection: { key: "l", ctrlOrMeta: true, shift: true, alt: false }, + toggleReadingProtection: { key: "e", ctrlOrMeta: true, shift: false, alt: false }, toggleEditorMode: { key: "/", ctrlOrMeta: true, shift: false, alt: false }, }; +const LEGACY_READING_PROTECTION_SHORTCUT: ShortcutBinding = { + key: "l", + ctrlOrMeta: true, + shift: true, + alt: false, +}; + const SHORTCUT_ALIASES: Partial> = { focusReplace: [{ key: "h", ctrlOrMeta: true, shift: true, alt: false }], }; @@ -236,7 +271,11 @@ const SHORTCUT_ACTION_VALUES: ShortcutAction[] = [ "createMemo", "createNotebook", "focusSearch", + "focusGlobalSearch", "focusReplace", + "openQuickSwitcher", + "openPreviousMemo", + "openNextMemo", "openAiAssistant", "saveAndSync", "toggleReadingProtection", @@ -440,15 +479,18 @@ export const readShortcutSettingsPreference = (): ShortcutSettings => { } const parsedValue = JSON.parse(rawValue) as Partial; - return SHORTCUT_ACTION_VALUES.reduce( - (settings, action) => ({ - ...settings, - [action]: isShortcutBinding(parsedValue[action]) - ? { ...parsedValue[action], key: normalizeShortcutKey(parsedValue[action].key) } - : DEFAULT_SHORTCUT_SETTINGS[action], - }), - { ...DEFAULT_SHORTCUT_SETTINGS } - ); + return SHORTCUT_ACTION_VALUES.reduce((settings, action) => { + const storedBinding = parsedValue[action]; + const normalizedBinding = isShortcutBinding(storedBinding) + ? { ...storedBinding, key: normalizeShortcutKey(storedBinding.key) } + : DEFAULT_SHORTCUT_SETTINGS[action]; + const binding = action === "toggleReadingProtection" + && shortcutBindingsEqual(normalizedBinding, LEGACY_READING_PROTECTION_SHORTCUT) + ? DEFAULT_SHORTCUT_SETTINGS.toggleReadingProtection + : normalizedBinding; + + return { ...settings, [action]: binding }; + }, { ...DEFAULT_SHORTCUT_SETTINGS }); } catch { return DEFAULT_SHORTCUT_SETTINGS; } diff --git a/docs/demo-sample-note.md b/docs/demo-sample-note.md new file mode 100644 index 00000000..b12c47e4 --- /dev/null +++ b/docs/demo-sample-note.md @@ -0,0 +1,196 @@ +# EdgeEver Logo Welcome to EdgeEver: Modern Open-Source Knowledge Base for Geeks & Creators + +> **EdgeEver** is an open-source, AI-native, and portable serverless/containerized personal knowledge base that revives the beloved **Evernote-style three-pane layout**. Designed for geeks and content creators, it combines 100% free serverless hosting, absolute data ownership, native cross-platform clients, and seamless AI Agent (MCP) synergy to redefine your digital second brain. + +--- + +## ⚡ 1. Why Choose EdgeEver? + +*Tip: In editor mode, click any table cell to edit text directly, or right-click to insert/delete rows and columns.* + +| Dimension | Traditional Cloud Notes (e.g. Evernote) | Local Offline Notes (e.g. Obsidian) | EdgeEver Geek Knowledge Base | +| :--- | :--- | :--- | :--- | +| **Hosting Cost** | Costly commercial subscriptions ($10+/mo) | Official cloud sync subscription ($5+/mo) | **100% Free Forever (Cloudflare Free Tier / Docker Self-Hosted)** | +| **Data Ownership** | Proprietary lock-in, hard to export | Local Markdown, cumbersome mobile sync | **Full Ownership (D1 SQLite, R2 Storage, Lossless ZIP Archives)** | +| **Editing Experience** | Rich text only, fragile formatting | Plain Markdown, lacks WYSIWYG flow | **Seamless Dual-View (WYSIWYG Rich Text ⇄ Markdown Source)** | +| **Publishing Ready** | No typography styling, loses format | Requires 3rd-party plugins or scripts | **One-Click Rich Copy for WeChat, Substack, Medium & WordPress** | +| **Social Poster Cards** | Basic screenshots without styling | Requires external tools or plugins | **8 Built-in Exquisite Poster Themes with Typography Options & PNG/JPEG Export** | +| **Native AI Ecosystem** | Paywalled, limited features | Heavy plugin setup required | **Native MCP Server (`/mcp`) & Inline AI Agent Synergy** | +| **Cross-Platform Matrix** | Restricts active free devices | Complex setup across platforms | **Web / PWA / Android / iOS / macOS / Windows (Coming Soon)** | + +--- + +## 🏗️ 2. Architectural Overview & Ecosystem + +The Mermaid diagram below demonstrates how EdgeEver connects cross-platform clients, zero-cost cloud infrastructure, and AI Agents into a cohesive workflow: + +```mermaid +flowchart TD + subgraph MultiClients["Client Matrix"] + C1["Web / PWA (Offline Drafts & Sync Queue)"] + C2["macOS Desktop (Electron + Rust Sidecar)"] + C3["Android Native App (Expo + SQLite)"] + C4["iOS Native App (SwiftUI + GRDB)"] + C5["Web Clipper (Chrome / Edge / Firefox)"] + end + + subgraph CoreEngine["Service & Storage Core"] + API["Hono API Engine (Cloudflare Workers / Docker)"] + MCP["Native MCP Endpoint (/mcp 2026-07-28 & 2025)"] + D1[("D1 / SQLite Database (Sync Cursor & Revisions)")] + R2[("R2 / S3 Storage (Images & Media Attachments)")] + end + + subgraph AIAgents["AI Agents & Integrations"] + A1["Claude Code / Cursor / Antigravity"] + A2["Inline AI Assistant (OpenAI / Gemini / DeepSeek)"] + A3["Notion DB / Feishu Bitable Sync"] + end + + MultiClients <==>|REST API & Sync Cursor| API + API <==> D1 & R2 + MCP <==> D1 & R2 + A1 <==>|MCP Tools / SSE| MCP + A2 -.->|BYOK Direct Key| MultiClients + A1 -.->|Bi-directional Sync| A3 +``` + +--- + +## 🎨 3. Immersive Writing & Typography Aesthetics + +EdgeEver is engineered to provide a distraction-free, elegant writing experience: + +### 🖥️ Dual-View Editor & Focus Modes +- **Seamless Dual-View**: Click the `` button in the top-right corner (or use shortcuts) to instantly toggle between **WYSIWYG Rich Text** and **Markdown Source Code** with 100% fidelity. +- **Collapsible Outline Navigation**: Automatically indexes `H1-H3` heading hierarchies with smooth jump scrolling, keeping lengthy documents organized. +- **Zen Focus Mode**: Press `Cmd/Ctrl + Shift + F` to hide sidebars and distractions, immersing yourself in pure writing flow. +- **Reading Protection Mode**: When reading or reviewing notes, press `Cmd/Ctrl + E` to toggle read-only protection, locking the editor to prevent accidental edits while browsing; press it again to seamlessly resume editing. + +### 🎭 Curated Typography Themes & Publishing Export +- **Preset Editor Themes**: Switch effortlessly between `WeChat Classic Green`, `Modern Mint`, `Minimal Emerald`, `Outline Emerald`, and more. +- **One-Click Publishing Export**: Built for publishers and bloggers. Click the **WeChat Icon** in the top bar to format your note with inline CSS. Paste directly into WeChat Official Account editor, Substack, Medium, or WordPress while preserving layout and syntax highlighting. + +### 🖼️ 8 Exquisite Social Poster Themes +Click **"Share as Card"** in the top-right menu to turn any note into an eye-catching poster card: +- **8 Themes**: `Slate`, `Aurora`, `Sunset`, `Midnight`, `Mint`, `Notepad` (skeuomorphic paper), `Xuan` (rice paper & Chinese ink), `Lavender`. +- **Customizable Typography**: Switch between Sans, Serif (Songti/Ming), and Monospace fonts, select compact, standard, or wide card widths, and export as high-resolution PNG or JPEG. + +--- + +## ⌨️ 4. Power Productivity Toolbox: Slash Commands, Backlinks & Math + +### 🪄 Slash Commands +Type `/` or press `Space` on an empty line to invoke the command menu: +- Insert `H1/H2/H3` headings, quotes, horizontal rules, code blocks, and rich tables; +- Use `/date`, `/time`, or `/now` to insert current timestamps instantly; +- Attach files, insert images, or summon the inline AI assistant. + +### 🔗 Bi-directional Note Links & Backlinks +Type `@` or insert `#memo=` links to establish bi-directional references across your knowledge base, building an interconnected web of thoughts. + +### 📐 KaTeX Professional LaTeX Mathematics +Native support for KaTeX renders complex mathematical equations in milliseconds: + +- **Inline Math**: For instance, Einstein's mass-energy equivalence $E = mc^2$ or the Gaussian probability density function $f(x) = \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}$. +- **Display Block Math**: +$$ +\oint_{\partial \Omega} \mathbf{E} \cdot d\mathbf{S} = \frac{1}{\varepsilon_0} \iiint_{\Omega} \rho \, dV, \quad \oint_{\partial \Omega} \mathbf{B} \cdot d\mathbf{S} = 0 +$$ + +### ✅ Interactive Task Lists +- [x] Explore EdgeEver's dual-view editing and outline navigation +- [x] Experiment with 8 editor themes and 8 social poster card styles +- [ ] Try typing `/` on an empty line to insert current timestamp and tables +- [ ] Connect your AI API Key to experience inline summarization and continuation +- [ ] Connect AI Agents via MCP to automate note categorization + +--- + +## 🤖 5. Native AI Agent Synergy & MCP Protocol + +EdgeEver is architected for the agentic AI era, weaving LLMs directly into the knowledge management lifecycle: + +```mermaid +sequenceDiagram + autonumber + actor User as Creator / Knowledge Worker + participant Client as EdgeEver Clients + participant MCP as EdgeEver MCP Endpoint + participant Agent as AI Agent (Claude / Cursor / Antigravity) + participant Database as Notion / Feishu Bitable + + User->>Client: Capture quick spark or meeting notes + Agent->>MCP: tools/call memo_search (Query unprocessed memos) + MCP-->>Agent: Returns structured Markdown & tags + Agent->>Agent: Analyzes content, extracts key takeaways & tags + Agent->>MCP: tools/call memo_update (Writes back summary & tags) + Agent->>Database: Syncs structured records to master database + Client-->>User: Sub-second live updates in client UI +``` + +### 1️⃣ Inline AI Assistant +Press the **`Space` bar** in an empty block, type **`/ai`**, use the **`/`** slash command menu, or select text and click the **AI button** on the floating toolbar to instantly summon the AI writing assistant: +- **Summarization & Action Items**: Condense documents into key takeaways, conclusions, and actionable todos; +- **Format-Preserving Translation**: Translate accurately into multiple languages while strictly preserving Markdown, math equations, links, and code blocks; +- **Rewriting & Style Transformation**: Improve phrasing, fix spelling/grammar, adapt to social media styles (e.g. Xiaohongshu / Twitter), or continue writing seamlessly; +- **BYOK Direct Key (Bring Your Own Key)**: Direct client-side connection with OpenAI, Anthropic Claude, Google Gemini, DeepSeek, and OpenAI-compatible relays with zero third-party data transit. + +### 2️⃣ Model Context Protocol (MCP) Integration +Generate an API token in **Settings → MCP Settings** to connect EdgeEver directly with Claude Code, Cursor, Antigravity, OpenClaw, and other agent platforms: +- **Direct Reading & Writing**: Connect via the `/mcp` endpoint (supports stateless `2026-07-28` protocol and handshake-based 2025 specs); +- **Automated Workflows**: Let AI Agents read, organize, summarize, tag, and synchronize notes with Notion databases and Feishu Bitable. + +--- + +## 📱 6. Multi-Platform Ecosystem, Offline Sync & Smart Clipping + +- **Cross-Platform Native Apps**: + - **Web / PWA**: Full-featured in modern browsers with offline installation support; + - **Android Native App**: Built with Expo & SQLite, available on Google Play and GitHub Releases; + - **iOS Native App**: Native Swift / SwiftUI with GRDB local mirror, available on the App Store; + - **macOS Desktop App**: Electron + Rust Sidecar for Apple Silicon & Intel Mac with silent background updates; + - **Windows Desktop App**: Development is complete, coming soon. +- **Browser Web Clipper**: Available on Chrome, Edge, and Firefox extension stores to extract clean, ad-free Markdown articles in one click. +- **Mobile WeChat Article Clipper**: Share any WeChat article to EdgeEver on your phone to automatically extract and format it as an editable note. +- **Offline Drafts & Sync Queue**: Keep writing seamlessly without network connectivity; changes are queued locally and automatically synced once reconnected. + +--- + +## 📦 7. Rich Media, Lossless Portability & Zero-Cost Hosting + +### 🖼️ Smart Client-Side Image Compression +When pasting or dragging images into notes, EdgeEver compresses them to WebP locally in your browser before upload, **reducing file size by 50% - 90%** while preserving visual fidelity. + +![EdgeEver Mascot: Geek Cat](/api/v1/resources/res_demo_cat_image/blob) + +### 📎 Universal File Attachments +Embed PDFs, spreadsheets, archives, and multimedia files directly in notes for preview or download: +- [📄 Product brief PDF: edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob) +- [📊 Feature matrix CSV: feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob) +- [📦 Sample attachment archive: edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob) + +### 🚀 Zero-Cost Serverless & Docker Self-Hosting +1. **Cloudflare Serverless (Recommended, 100% Free Forever)**: Runs entirely within Cloudflare's free tier (Workers + D1 SQLite + R2 Storage). No server bills, no VPS maintenance. +2. **Docker One-Command Deployment (VPS / NAS / Home Server)**: + ```sh + # International VPS / NAS installer (GHCR image) + curl -fsSL https://edgeever.org/install.sh | bash + + # Mainland China mirror installer (Tencent TCR image) + curl -fsSL https://edgeever-installer-1256854452.cos.ap-guangzhou.myqcloud.com/install.sh | bash -s -- --mirror tcr + ``` + Configures Docker Compose and automated daily background updates with one command. + +### 💾 Complete Data Freedom: Lossless ZIP Portability +Export your entire library at any time from **Profile → Import and export**. The archive contains pure Markdown files with standard YAML Front Matter, relative media paths, and full revision histories—compatible with Obsidian, VS Code, and any plain text editor. + +--- + +> 💡 **Quick Exploration Tips**: +> 1. Click **``** in the top right to try seamless dual-view toggling; +> 2. Press **`Cmd/Ctrl + E`** to test reading protection mode against accidental edits; +> 3. Press **`Cmd/Ctrl + O`** to summon the Quick Switcher; +> 4. Click the **WeChat Icon** to copy formatted rich text ready for publishing; +> 5. Click **"Share as Card"** to export a stunning social poster card; +> 6. Click **"Reset Demo Data"** in settings or the sidebar anytime to restore the demo workspace. diff --git a/docs/demo-sample-note.zh-CN.md b/docs/demo-sample-note.zh-CN.md new file mode 100644 index 00000000..368607f2 --- /dev/null +++ b/docs/demo-sample-note.zh-CN.md @@ -0,0 +1,196 @@ +# EdgeEver Logo 欢迎使用 EdgeEver:为极客与创作者打造的现代开源知识库 + +> **EdgeEver** 是一款兼具**经典三栏美学**与 **AI 原生动力**的开源 Serverless / 容器化个人知识库。它既找回了极客们钟爱的经典印象笔记式双视图与树状目录,又以零服务器成本、完全数据自主、全端原生覆盖与深度 MCP 智能体协同,重新定义了下一代个人第二大脑。 + +--- + +## ⚡ 1. 为什么选择 EdgeEver? + +*提示:在编辑器模式下,你可以直接点击任意表格单元格进行行内编辑,或右键快捷插入/删除行列。* + +| 核心维度 | 传统商业云笔记 (如 Evernote) | 本地离线知识库 (如 Obsidian) | EdgeEver 极客知识库 | +| :--- | :--- | :--- | :--- | +| **云端托管成本** | 商业订阅高昂($10+/月) | 官方云同步收费($5+/月) | **100% 永久免费 (Cloudflare 免费额度 / Docker 自建)** | +| **数据资产所有权** | 专有格式封闭,导出困难 | 本地 Markdown,移动端同步繁琐 | **完全自主掌控 (D1 SQLite 数据库 / R2 / 无损 ZIP 导出)** | +| **写作与编辑体验** | 仅富文本,排版易错乱 | 纯 Markdown,缺乏沉浸所见即所得 | **双视图自由切换 (所见即所得富文本 ⇄ Markdown 源码)** | +| **自媒体排版分发** | 无样式优化,格式丢失 | 需借助外部排版扩展或工具 | **一键复制到微信公众号 / Substack / Medium / WordPress** | +| **社交卡片分享** | 截图粗糙或无排版设计 | 需第三方插件实现 | **内置 8 款精美海报主题,支持自定义字体与 PNG/JPEG 导出** | +| **AI 原生集成生态** | 封闭收费,仅限特定功能 | 需配置复杂的第三方插件 | **原生内置 MCP 服务端点 (`/mcp`) 与行内 AI 智能体协同** | +| **全平台多端覆盖** | 限制免费设备登录数量 | 多端同步与移动端体验门槛高 | **Web / PWA / Android / iOS / macOS / Windows (即将推出)** | + +--- + +## 🏗️ 2. 全景架构与生态联动 + +通过下面的 Mermaid 架构图,你可以清晰了解 EdgeEver 如何将多端客户端、零成本云基础设施与 AI Agent 紧密串联: + +```mermaid +flowchart TD + subgraph MultiClients["全端客户端矩阵"] + C1["Web / PWA (离线草稿 & 增量同步)"] + C2["macOS 桌面端 (Electron + Rust Sidecar)"] + C3["Android 原生 App (Expo + SQLite)"] + C4["iOS 原生 App (SwiftUI + GRDB)"] + C5["浏览器剪藏插件 (Chrome / Edge / Firefox)"] + end + + subgraph CoreEngine["业务与数据服务层"] + API["Hono API 引擎 (Cloudflare Workers / Docker)"] + MCP["原生 MCP Endpoint (/mcp 2026-07-28 & 2025)"] + D1[("D1 / SQLite 数据库 (双向同步 & 修订版本)")] + R2[("R2 / S3 资源存储 (图片与多媒体附件)")] + end + + subgraph AIAgents["AI 智能体与外部生态"] + A1["Claude Code / Cursor / Antigravity"] + A2["行内 AI 助手 (OpenAI / Gemini / DeepSeek)"] + A3["Notion 数据库 / 飞书多维表格联动"] + end + + MultiClients <==>|REST API & 同步游标| API + API <==> D1 & R2 + MCP <==> D1 & R2 + A1 <==>|MCP Tools / SSE| MCP + A2 -.->|BYOK 密钥直连| MultiClients + A1 -.->|双向数据同步| A3 +``` + +--- + +## 🎨 3. 极致创作体验与排版美学 + +EdgeEver 将高效与优雅融入每一处交互细节,助你专注于思考与表达: + +### 🖥️ 双视图编辑器与沉浸模式 +- **自由切换视图**:点击右上角 `` 按钮或使用快捷键,可在**所见即所得富文本**与 **Markdown 源码**间无缝切换,实时双向保真。 +- **左侧可折叠大纲**:自动解析文档 `H1-H3` 标题层级,支持点击平滑滚动跳转,助你轻松把控万字长文。 +- **Zen 专注模式**:按下 `Cmd/Ctrl + Shift + F`,隐藏所有侧边栏与干扰元素,进入纯粹写作心流。 +- **阅读保护模式 (Reading Protection)**:日常翻阅或查阅笔记时,按下 `Cmd/Ctrl + E` 即可一键开启只读保护,锁定当前编辑状态,避免沉浸阅读时误触键盘或意外改动笔记内容;再次按下即可随手切回编辑。 + +### 🎭 精选排版主题与一键自媒体发布 +- **内置排版主题**:支持一键切换 `WeChat Classic Green (微信经典绿)`、`Modern Mint (薄荷青)`、`Minimal Emerald (极简祖母绿)`、`Outline Emerald (大纲祖母绿)` 等风格。 +- **一键排版复制**:专为内容创作者设计。点击顶部工具栏的**微信公众号图标**,系统自动将当前笔记转为内联 CSS 样式的优雅富文本,直接粘贴至微信公众号后台、Substack 或 WordPress,排版与代码高亮完美保真。 + +### 🖼️ 8 套精美社交分享海报 (Poster Cards) +点击右上角“分享为卡片”,即可将任意笔记或片段渲染为高清分享海报,支持: +- **8 大主题风格**:`Slate (岩灰)`、`Aurora (极光青)`、`Sunset (落日暖橙)`、`Midnight (暗夜极客)`、`Mint (清爽薄荷)`、`Notepad (复古便签)`、`Xuan (宣纸水墨)`、`Lavender (薰衣草紫)`。 +- **排版定制**:支持无衬线 (Sans)、宋体/明朝 (Serif)、等宽代码 (Mono) 字体切换,自由选择紧凑、标准或宽幅卡片,一键导出为高清晰度 PNG 或 JPEG 图片。 + +--- + +## ⌨️ 4. 效率工具箱:斜杠指令、双链与数学公式 + +### 🪄 斜杠指令 (Slash Commands) +在正文空白行输入 `/` 或直接按下 `空格键`,即可呼出快捷指令菜单: +- 快速插入 `H1/H2/H3` 标题、引用、分割线、代码块与富文本表格; +- 输入 `/date`、`/time` 或 `/now` 快速插入当前标准时间戳; +- 插入附件、图片或调起行内 AI 智能助手。 + +### 🔗 知识双链与笔记引用 +在编辑器中输入 `@` 或插入 `#memo=<笔记ID>` 链接,即可建立笔记间的双向关联,点击即可在工作区内快速打开关联笔记,构建结构化网状知识库。 + +### 📐 KaTeX 专业数学公式渲染 +EdgeEver 原生支持 LaTeX 数学表达式,无论是行内微积分还是多行物理方程,均可毫秒级高保真渲染: + +- **行内公式**:例如质能方程 $E = mc^2$,以及正态分布概率密度函数 $f(x) = \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}$。 +- **多行独立公式块**: +$$ +\oint_{\partial \Omega} \mathbf{E} \cdot d\mathbf{S} = \frac{1}{\varepsilon_0} \iiint_{\Omega} \rho \, dV, \quad \oint_{\partial \Omega} \mathbf{B} \cdot d\mathbf{S} = 0 +$$ + +### ✅ 交互式待办清单 (Task Lists) +- [x] 体验 EdgeEver 双视图与大纲导航 +- [x] 探索 8 款编辑器主题与 8 套社交海报卡片 +- [ ] 尝试使用斜杠指令 `/` 插入当前日期与结构化表格 +- [ ] 配置个人 AI API Key,体验行内智能总结与续写 +- [ ] 开启 MCP 协议,让 AI Agent 协助整理工作区 + +--- + +## 🤖 5. AI 原生协同与 MCP 智能体生态 + +EdgeEver 走在 AI 时代前沿,将大语言模型与智能体深度融入知识管理生命周期: + +```mermaid +sequenceDiagram + autonumber + actor User as 创作者 / 知识工作者 + participant Client as EdgeEver 多端应用 + participant MCP as EdgeEver MCP 服务端点 + participant Agent as AI Agent (Claude / Cursor / Antigravity) + participant Database as Notion / 飞书多维表格 + + User->>Client: 快速记录碎片想法与会议灵感 + Agent->>MCP: tools/call memo_search (检索近期未整理笔记) + MCP-->>Agent: 返回结构化 Markdown 笔记内容与标签 + Agent->>Agent: 理解内容、自动提炼核心摘要并归类标签 + Agent->>MCP: tools/call memo_update (写回智能总结与增强标签) + Agent->>Database: 同步结构化字段至个人知识总库 + Client-->>User: 客户端毫秒级感知更新,笔记井井有条 +``` + +### 1️⃣ 行内 AI 助手 (Inline AI Assistant) +在正文空白行直接按下 **`空格键 (Space)`**、输入 **`/ai`**、通过 **`/`** 斜杠指令菜单,或选中文本点击浮动工具栏中的 **AI 按钮**,即可即时呼出 AI 写作助手面板: +- **精炼总结与要点提取**:一键压缩提炼全文核心结论、提取待办事项与关键行动项; +- **格式保真智能翻译**:在严格保留原有 Markdown、数学公式、链接与代码块的前提下,精准翻译多国语言; +- **内容重塑与风格改写**:支持改进表达、修正错别字与语法、转为社交媒体(如小红书/推特)风格,或按上下文顺滑续写; +- **BYOK 隐私直连 (Bring Your Own Key)**:支持直连 OpenAI、Anthropic Claude、Google Gemini、DeepSeek 及各类 OpenAI 兼容的中继 API,数据完全由端侧直发,不经过任何第三方中转。 + +### 2️⃣ 开放 MCP 协议 (Model Context Protocol) +在**设置 → MCP 设置**中生成专属令牌,即可将 EdgeEver 接入 Claude Code、Cursor、Antigravity、OpenClaw 等主流 AI 编码助手与智能体平台: +- **无缝读写**:支持标准 MCP 端点 `/mcp`(兼容最新的无状态 `2026-07-28` 协议与经典握手协议); +- **自动化流转**:AI Agent 可自动读取笔记、智能归档、批量打标,甚至与 Notion、飞书多维表格建立跨平台自动化同步。 + +--- + +## 📱 6. 全平台原生覆盖、离线同步与智能剪藏 + +- **多端原生支持**: + - **Web / PWA**:支持现代浏览器全功能运行与离线安装; + - **Android 原生客户端**:基于 Expo 与 SQLite 构建,已上架 Google Play,并提供签名 APK 下载; + - **iOS 原生客户端**:基于 Swift / SwiftUI 与 GRDB 原生实现,流畅细腻,已上架 App Store; + - **macOS 桌面端**:Electron + Rust 高性能 Sidecar,支持 Apple Silicon 和 Intel Mac,内置静默后台更新; + - **Windows 桌面端**:已开发完毕,即将正式推出。 +- **浏览器网页剪藏 (Web Clipper)**:已在 Chrome、Edge 和 Firefox 官方扩展商店发布,一键剔除网页广告,将正文纯净沉淀为 Markdown 笔记。 +- **微信公众号一键剪藏**:在移动端系统分享菜单中,直接将微信文章分享到 EdgeEver,客户端将自动提取图文排版并转换为可编辑笔记。 +- **离线草稿与弹性同步**:地铁、飞行模式等无网络环境下自由编辑,重新联网后自动入队完成增量同步与冲突协调。 + +--- + +## 📦 7. 多媒体管理、无损备份与零成本自建 + +### 🖼️ 智能本地图片压缩 +在笔记中粘贴或拖入高分辨率图片时,前端会在本地自动将其转码压缩为 WebP 格式,在保证视觉无损的前提下**减少 50% - 90% 的体积**,大幅降低云端存储占用并提升跨端加载速度。 + +![EdgeEver 极客猫猫吉祥物](/api/v1/resources/res_demo_cat_image/blob) + +### 📎 多类型附件自由挂载 +支持在笔记中嵌入 PDF 文档、CSV 表格、压缩包及多媒体资源,点击即可在线预览或下载: +- [📄 产品白皮书 PDF:edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob) +- [📊 功能矩阵 CSV:feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob) +- [📦 示例附件压缩包:edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob) + +### 🚀 两种自建部署方案:Serverless 与 Docker +1. **Cloudflare Serverless(推荐,永久 100% 免费)**:基于 Workers + D1 数据库 + R2 对象存储构建,完全处于 Cloudflare 免费额度内,无需采购服务器,免运维、免证书续期。 +2. **Docker 一键自建(VPS / NAS / 家用服务器)**: + ```sh + # 国际 VPS / NAS 极速安装(GHCR 镜像) + curl -fsSL https://edgeever.org/install.sh | bash + + # 大陆地区 VPS / NAS 镜像加速(腾讯云 TCR 镜像) + curl -fsSL https://edgeever-installer-1256854452.cos.ap-guangzhou.myqcloud.com/install.sh | bash -s -- --mirror tcr + ``` + 单命令自动配置 Docker Compose 环境,并内置每日定时自动更新。 + +### 💾 绝对的数据自由:无损 ZIP 导入与导出 +在**个人中心 → 导入与导出**中,可随时将完整笔记库打包导出为结构清晰的 ZIP 压缩包。解压后即为包含标准 YAML Front Matter、相对路径附件图片与完整修订版本的纯 Markdown 文件树,随时可在 Obsidian、VS Code 等任意工具中无缝打开,永不担心平台绑定! + +--- + +> 💡 **快速体验小贴士**: +> 1. 点击右上角 **``** 体验丝滑的双视图切换; +> 2. 按下 **`Cmd/Ctrl + E`** 试一试阅读保护模式,锁定只读避免误改内容; +> 3. 按下 **`Cmd/Ctrl + O`** 呼出快速切换器 (Quick Switcher); +> 4. 点击顶部 **微信图标**,体验一键带格式排版复制; +> 5. 点击 **“分享为卡片”**,挑选一款你心仪的社交海报风格并导出; +> 6. 随时在侧边栏或设置中点击 **“恢复 Demo 数据”**,一键重置演示工作区。 diff --git a/packages/shared/src/i18n/en-US.ts b/packages/shared/src/i18n/en-US.ts index 80f34725..540a7941 100644 --- a/packages/shared/src/i18n/en-US.ts +++ b/packages/shared/src/i18n/en-US.ts @@ -703,13 +703,29 @@ export const enUS = { description: "Create a new notebook at the current level.", }, focusSearch: { - label: "Search notes", - description: "Open search or focus search within the current note.", + label: "Search current note", + description: "Focus text search within the current note.", + }, + focusGlobalSearch: { + label: "Search all notes", + description: "Focus list search to find content across all notes.", }, focusReplace: { label: "Replace text", description: "Open replace in the current note.", }, + openQuickSwitcher: { + label: "Quick switcher", + description: "Search and open any note that is not in trash.", + }, + openPreviousMemo: { + label: "Previous note", + description: "Open the previous note in the current list.", + }, + openNextMemo: { + label: "Next note", + description: "Open the next note in the current list.", + }, openAiAssistant: { label: "Open AI assistant", description: "Open the inline AI composer at the current selection or cursor.", @@ -728,6 +744,17 @@ export const enUS = { }, }, }, + quickSwitcher: { + title: "Quick switcher", + description: "Search and open any note that is not in trash.", + placeholder: "Search note titles or content…", + recent: "Recently updated", + results: "Search results", + empty: "No matching notes", + loading: "Searching…", + openHint: "Open · Enter", + closeHint: "Close · Esc", + }, options: { memoDensity: { preview: "Preview list", diff --git a/packages/shared/src/i18n/zh-CN.ts b/packages/shared/src/i18n/zh-CN.ts index e71b7d74..6e9b214e 100644 --- a/packages/shared/src/i18n/zh-CN.ts +++ b/packages/shared/src/i18n/zh-CN.ts @@ -703,13 +703,29 @@ export const zhCN = { description: "在当前层级创建一个新笔记本。", }, focusSearch: { - label: "搜索笔记", - description: "打开搜索或聚焦笔记内搜索。", + label: "搜索当前笔记", + description: "聚焦当前笔记内的文本搜索。", + }, + focusGlobalSearch: { + label: "全局搜索笔记", + description: "聚焦笔记列表搜索,在全部笔记内容中查找。", }, focusReplace: { label: "替换文本", description: "在当前笔记中打开替换。", }, + openQuickSwitcher: { + label: "快速切换笔记", + description: "搜索并打开任意未删除的笔记。", + }, + openPreviousMemo: { + label: "上一篇笔记", + description: "打开当前列表中的上一篇笔记。", + }, + openNextMemo: { + label: "下一篇笔记", + description: "打开当前列表中的下一篇笔记。", + }, openAiAssistant: { label: "打开 AI 助手", description: "在当前选区或光标位置打开内联 AI 输入框。", @@ -728,6 +744,17 @@ export const zhCN = { }, }, }, + quickSwitcher: { + title: "快速切换笔记", + description: "搜索并打开任意未删除的笔记。", + placeholder: "搜索笔记标题或内容…", + recent: "最近更新", + results: "搜索结果", + empty: "没有找到匹配的笔记", + loading: "正在搜索…", + openHint: "打开 · Enter", + closeHint: "关闭 · Esc", + }, options: { memoDensity: { preview: "预览列表",