Compare commits

..
7 Commits
13 changed files with 209 additions and 207 deletions
+16 -26
View File
@@ -5,7 +5,7 @@ A local markdown note-taking app built with Tauri, SvelteKit, and Rust.
Your notes are stored as standard Markdown files on your local filesystem. Your notes are stored as standard Markdown files on your local filesystem.
No cloud, no lock-in. No cloud, no lock-in.
## Download (v1.2.0) ## Download (v1.2.1)
### Linux ### Linux
@@ -23,23 +23,23 @@ curl -fsSL https://repo.arkhost.com/gpg.key | sudo gpg --dearmor -o /usr/share/k
#### AppImage (Arch, Fedora 43+, openSUSE Tumbleweed) #### AppImage (Arch, Fedora 43+, openSUSE Tumbleweed)
[Download AppImage](https://download.helixnotes.com/releases/v1.2.0/HelixNotes_1.2.0_amd64.AppImage) [Download AppImage](https://download.helixnotes.com/releases/v1.2.1/HelixNotes_1.2.1_amd64.AppImage)
#### .deb (manual) #### .deb (manual)
[Download .deb](https://codeberg.org/ArkHost/HelixNotes/releases/download/v1.2.0/HelixNotes_1.2.0_amd64.deb) Ubuntu 22.04+ [Download .deb](https://codeberg.org/ArkHost/HelixNotes/releases/download/v1.2.1/HelixNotes_1.2.1_amd64.deb) (Ubuntu 22.04+)
### Windows ### Windows
[Download Installer](https://codeberg.org/ArkHost/HelixNotes/releases/download/v1.2.0/HelixNotes_1.2.0_x64-setup.exe) Windows 10/11 [Download Installer](https://codeberg.org/ArkHost/HelixNotes/releases/download/v1.2.1/HelixNotes_1.2.1_x64-setup.exe) (Windows 10/11)
### macOS ### macOS
[Download .dmg](https://codeberg.org/ArkHost/HelixNotes/releases/download/v1.2.0/HelixNotes_1.2.0_x64.dmg) — macOS (Intel, runs on Apple Silicon via Rosetta) [Download .dmg](https://codeberg.org/ArkHost/HelixNotes/releases/download/v1.2.1/HelixNotes_1.2.1_x64.dmg) (Intel, runs on Apple Silicon via Rosetta)
### Android ### Android
[Download APK](https://download.helixnotes.com/releases/v1.2.0/HelixNotes_1.2.0_android.apk) — Tested on Android 16 [Download APK](https://download.helixnotes.com/releases/v1.2.1/HelixNotes_1.2.1_android.apk)
--- ---
@@ -47,26 +47,16 @@ All releases: [codeberg.org/ArkHost/HelixNotes/releases](https://codeberg.org/Ar
## Features ## Features
- **Markdown editor** with rich formatting toolbar, slash commands, source mode toggle, and code syntax highlighting - Markdown editor with toolbar, slash commands, source mode, code highlighting
- **Wiki-links** — link notes with `[[Note Title]]` syntax - `[[Wiki-links]]` and graph view
- **Graph view** — visualize connections between your notes - Full-text search (Tantivy)
- **Outline panel** — heading navigation for long notes - Outline panel, daily notes, tags, drag-and-drop
- **Full-text search** powered by Tantivy - Math (KaTeX), PDF preview, Obsidian import
- **Math support** — KaTeX rendering for inline and block equations - AI writing tools (Ollama / Anthropic / OpenAI)
- **Daily notes** — one-click button to create or open today's note - Version history with diffs, automatic backups
- **AI writing tools** — improve, summarize, translate, and more (Ollama / Anthropic / OpenAI) - Multi-window, file associations, focus mode, view mode
- **Version history** — per-note snapshots with diff view - Themes, accent colors, fonts
- **Backups** — automatic zip-based vault backups - Local files, no cloud
- **PDF preview** — inline rendering of embedded PDFs
- **Tag management** — organize notes with tags, bulk edit from context menu
- **Drag-and-drop** — move notes between notebooks, reorganize notebooks by dragging
- **Obsidian import** — convert Obsidian wiki-links to standard markdown
- **Multi-window** — open notes in separate windows (right-click → "Open in New Window")
- **File associations** — open .md files from your file manager directly in HelixNotes
- **Themes** — light/dark mode with customizable accent colors, fonts, and line height
- **Focus mode** — distraction-free writing
- **View mode** — read-only toggle for distraction-free reading
- **Local** — everything stays on your machine
Full documentation: [helixnotes.com/docs](https://helixnotes.com/docs.html) Full documentation: [helixnotes.com/docs](https://helixnotes.com/docs.html)
@@ -0,0 +1,3 @@
- Internal note links ([[wiki-links]] open the linked note)
- Mobile UI improvements
- Window state persistence (desktop)
@@ -0,0 +1,12 @@
Markdown note-taking app built with Tauri and Rust. Your notes are stored as standard Markdown files on your device.
Features:
- Markdown editor with toolbar, slash commands, and code highlighting
- [[Wiki-links]] and graph view
- Full-text search
- Outline panel, daily notes, tags
- Math (KaTeX) and PDF preview
- AI writing tools (Ollama, Anthropic, OpenAI)
- Version history with diffs
- Obsidian import
- Themes, accent colors, fonts
@@ -0,0 +1 @@
Local markdown note-taking app. No cloud, no lock-in.
@@ -0,0 +1 @@
HelixNotes
-174
View File
@@ -1,174 +0,0 @@
Categories:
- Writing
- Office
License: AGPL-3.0-or-later
AuthorName: ArkHost
AuthorWebSite: https://helixnotes.com
SourceCode: https://codeberg.org/ArkHost/HelixNotes
IssueTracker: https://codeberg.org/ArkHost/HelixNotes/issues
Changelog: https://codeberg.org/ArkHost/HelixNotes/releases
AutoName: HelixNotes
RepoType: git
Repo: https://codeberg.org/ArkHost/HelixNotes.git
Builds:
- versionName: 1.2.0
versionCode: 10200001
commit: v1.2.0
timeout: 10800
sudo:
- apt-get update
- apt-get install -y make pkg-config libssl-dev
output: src-tauri/gen/android/app/build/outputs/apk/arm64/release/app-arm64-release-unsigned.apk
srclibs:
- rustup@1.28.1
- esbuild@v0.25.0
prebuild:
- export RUSTUP_HOME="$$rustup$$/rustup"
- export CARGO_HOME="$$rustup$$/cargo"
- $$rustup$$/rustup-init.sh -y --no-modify-path
- export PATH="$$CARGO_HOME$$/bin:$PATH"
- rustup target add aarch64-linux-android
- cargo install tauri-cli --version ^2.10.0 --locked
- cd $$esbuild$$
- GOPATH="$PWD/gopath" go build -o esbuild-bin ./cmd/esbuild
- cd $$helixnotes$$
scandelete:
- src-tauri/gen/android/.gradle
build:
- export RUSTUP_HOME="$$rustup$$/rustup"
- export CARGO_HOME="$$rustup$$/cargo"
- export PATH="$$CARGO_HOME$$/bin:$$esbuild$$:$PATH"
- ln -sf $$esbuild$$/esbuild-bin $$esbuild$$/esbuild
- export NDK_HOME="$$NDK$$"
- export ANDROID_HOME="$$SDK$$"
- corepack enable
- corepack prepare pnpm@latest --activate
- pnpm install --frozen-lockfile
- cargo tauri android build --apk --split-per-abi --ci
ndk: 27.0.12077973
gradle:
- yes
- versionName: 1.2.0
versionCode: 10200002
commit: v1.2.0
timeout: 10800
sudo:
- apt-get update
- apt-get install -y make pkg-config libssl-dev
output: src-tauri/gen/android/app/build/outputs/apk/arm/release/app-arm-release-unsigned.apk
srclibs:
- rustup@1.28.1
- esbuild@v0.25.0
prebuild:
- export RUSTUP_HOME="$$rustup$$/rustup"
- export CARGO_HOME="$$rustup$$/cargo"
- $$rustup$$/rustup-init.sh -y --no-modify-path
- export PATH="$$CARGO_HOME$$/bin:$PATH"
- rustup target add armv7-linux-androideabi
- cargo install tauri-cli --version ^2.10.0 --locked
- cd $$esbuild$$
- GOPATH="$PWD/gopath" go build -o esbuild-bin ./cmd/esbuild
- cd $$helixnotes$$
scandelete:
- src-tauri/gen/android/.gradle
build:
- export RUSTUP_HOME="$$rustup$$/rustup"
- export CARGO_HOME="$$rustup$$/cargo"
- export PATH="$$CARGO_HOME$$/bin:$$esbuild$$:$PATH"
- ln -sf $$esbuild$$/esbuild-bin $$esbuild$$/esbuild
- export NDK_HOME="$$NDK$$"
- export ANDROID_HOME="$$SDK$$"
- corepack enable
- corepack prepare pnpm@latest --activate
- pnpm install --frozen-lockfile
- cargo tauri android build --apk --split-per-abi --ci
ndk: 27.0.12077973
gradle:
- yes
- versionName: 1.2.0
versionCode: 10200003
commit: v1.2.0
timeout: 10800
sudo:
- apt-get update
- apt-get install -y make pkg-config libssl-dev
output: src-tauri/gen/android/app/build/outputs/apk/x86/release/app-x86-release-unsigned.apk
srclibs:
- rustup@1.28.1
- esbuild@v0.25.0
prebuild:
- export RUSTUP_HOME="$$rustup$$/rustup"
- export CARGO_HOME="$$rustup$$/cargo"
- $$rustup$$/rustup-init.sh -y --no-modify-path
- export PATH="$$CARGO_HOME$$/bin:$PATH"
- rustup target add i686-linux-android
- cargo install tauri-cli --version ^2.10.0 --locked
- cd $$esbuild$$
- GOPATH="$PWD/gopath" go build -o esbuild-bin ./cmd/esbuild
- cd $$helixnotes$$
scandelete:
- src-tauri/gen/android/.gradle
build:
- export RUSTUP_HOME="$$rustup$$/rustup"
- export CARGO_HOME="$$rustup$$/cargo"
- export PATH="$$CARGO_HOME$$/bin:$$esbuild$$:$PATH"
- ln -sf $$esbuild$$/esbuild-bin $$esbuild$$/esbuild
- export NDK_HOME="$$NDK$$"
- export ANDROID_HOME="$$SDK$$"
- corepack enable
- corepack prepare pnpm@latest --activate
- pnpm install --frozen-lockfile
- cargo tauri android build --apk --split-per-abi --ci
ndk: 27.0.12077973
gradle:
- yes
- versionName: 1.2.0
versionCode: 10200004
commit: v1.2.0
timeout: 10800
sudo:
- apt-get update
- apt-get install -y make pkg-config libssl-dev
output: src-tauri/gen/android/app/build/outputs/apk/x86_64/release/app-x86_64-release-unsigned.apk
srclibs:
- rustup@1.28.1
- esbuild@v0.25.0
prebuild:
- export RUSTUP_HOME="$$rustup$$/rustup"
- export CARGO_HOME="$$rustup$$/cargo"
- $$rustup$$/rustup-init.sh -y --no-modify-path
- export PATH="$$CARGO_HOME$$/bin:$PATH"
- rustup target add x86_64-linux-android
- cargo install tauri-cli --version ^2.10.0 --locked
- cd $$esbuild$$
- GOPATH="$PWD/gopath" go build -o esbuild-bin ./cmd/esbuild
- cd $$helixnotes$$
scandelete:
- src-tauri/gen/android/.gradle
build:
- export RUSTUP_HOME="$$rustup$$/rustup"
- export CARGO_HOME="$$rustup$$/cargo"
- export PATH="$$CARGO_HOME$$/bin:$$esbuild$$:$PATH"
- ln -sf $$esbuild$$/esbuild-bin $$esbuild$$/esbuild
- export NDK_HOME="$$NDK$$"
- export ANDROID_HOME="$$SDK$$"
- corepack enable
- corepack prepare pnpm@latest --activate
- pnpm install --frozen-lockfile
- cargo tauri android build --apk --split-per-abi --ci
ndk: 27.0.12077973
gradle:
- yes
AllowedAPKSigningKeys: TODO_YOUR_APK_SIGNING_CERT_SHA256
AutoUpdateMode: Version
UpdateCheckMode: Tags ^v[\d.]+$
CurrentVersion: 1.2.0
CurrentVersionCode: 10200004
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "helixnotes", "name": "helixnotes",
"private": true, "private": true,
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"version": "1.2.1", "version": "1.2.2",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite dev", "dev": "vite dev",
+18 -1
View File
@@ -633,6 +633,7 @@ dependencies = [
"iana-time-zone", "iana-time-zone",
"js-sys", "js-sys",
"num-traits", "num-traits",
"pure-rust-locales",
"serde", "serde",
"wasm-bindgen", "wasm-bindgen",
"windows-link 0.2.1", "windows-link 0.2.1",
@@ -1849,7 +1850,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "helixnotes" name = "helixnotes"
version = "1.2.1" version = "1.2.2"
dependencies = [ dependencies = [
"arboard", "arboard",
"chrono", "chrono",
@@ -1867,6 +1868,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"serde_yaml", "serde_yaml",
"sys-locale",
"tantivy", "tantivy",
"tauri", "tauri",
"tauri-build", "tauri-build",
@@ -3589,6 +3591,12 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "pure-rust-locales"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d"
[[package]] [[package]]
name = "pxfm" name = "pxfm"
version = "0.1.27" version = "0.1.27"
@@ -4770,6 +4778,15 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "sys-locale"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "system-deps" name = "system-deps"
version = "6.2.2" version = "6.2.2"
+3 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "helixnotes" name = "helixnotes"
version = "1.2.1" version = "1.2.2"
description = "Local markdown note-taking app" description = "Local markdown note-taking app"
authors = ["HelixNotes"] authors = ["HelixNotes"]
license = "AGPL-3.0-or-later" license = "AGPL-3.0-or-later"
@@ -26,7 +26,8 @@ serde_yaml = "0.9"
log = "0.4" log = "0.4"
notify = "8" notify = "8"
walkdir = "2" walkdir = "2"
chrono = { version = "0.4", features = ["serde"] } chrono = { version = "0.4", features = ["serde", "unstable-locales"] }
sys-locale = "0.3"
uuid = { version = "1", features = ["v4"] } uuid = { version = "1", features = ["v4"] }
tantivy = "0.22" tantivy = "0.22"
gray_matter = "0.2" gray_matter = "0.2"
+54 -2
View File
@@ -1,6 +1,6 @@
use crate::types::{NoteContent, NoteEntry, NoteMeta, NotebookEntry, VaultState}; use crate::types::{NoteContent, NoteEntry, NoteMeta, NotebookEntry, VaultState};
use crate::vault::frontmatter; use crate::vault::frontmatter;
use chrono::{Local, Utc}; use chrono::{Local, Locale, Utc};
use rayon::prelude::*; use rayon::prelude::*;
use std::fs; use std::fs;
use std::io::Read; use std::io::Read;
@@ -449,10 +449,62 @@ pub fn create_note(
}) })
} }
fn get_system_locale() -> Locale {
let sys = sys_locale::get_locale().unwrap_or_else(|| "en-US".to_string());
let lang = sys.split(&['-', '_', '.'][..]).next().unwrap_or("en");
match lang {
"af" => Locale::af_ZA,
"ar" => Locale::ar_SA,
"be" => Locale::be_BY,
"bg" => Locale::bg_BG,
"ca" => Locale::ca_ES,
"cs" => Locale::cs_CZ,
"da" => Locale::da_DK,
"de" => Locale::de_DE,
"el" => Locale::el_GR,
"es" => Locale::es_ES,
"et" => Locale::et_EE,
"fi" => Locale::fi_FI,
"fr" => Locale::fr_FR,
"he" => Locale::he_IL,
"hi" => Locale::hi_IN,
"hr" => Locale::hr_HR,
"hu" => Locale::hu_HU,
"id" => Locale::id_ID,
"is" => Locale::is_IS,
"it" => Locale::it_IT,
"ja" => Locale::ja_JP,
"ka" => Locale::ka_GE,
"ko" => Locale::ko_KR,
"lt" => Locale::lt_LT,
"lv" => Locale::lv_LV,
"mk" => Locale::mk_MK,
"nb" | "no" => Locale::nb_NO,
"nl" => Locale::nl_NL,
"nn" => Locale::nn_NO,
"pl" => Locale::pl_PL,
"pt" => Locale::pt_BR,
"ro" => Locale::ro_RO,
"ru" => Locale::ru_RU,
"sk" => Locale::sk_SK,
"sl" => Locale::sl_SI,
"sq" => Locale::sq_AL,
"sr" => Locale::sr_RS,
"sv" => Locale::sv_SE,
"th" => Locale::th_TH,
"tr" => Locale::tr_TR,
"uk" => Locale::uk_UA,
"vi" => Locale::vi_VN,
"zh" => Locale::zh_CN,
_ => Locale::en_US,
}
}
pub fn create_daily_note(vault_path: &str) -> Result<NoteEntry, String> { pub fn create_daily_note(vault_path: &str) -> Result<NoteEntry, String> {
let today = Local::now(); let today = Local::now();
let date_str = today.format("%Y-%m-%d").to_string(); let date_str = today.format("%Y-%m-%d").to_string();
let title = today.format("%B %d, %Y").to_string(); let locale = get_system_locale();
let title = today.format_localized("%B %d, %Y", locale).to_string();
let dir = Path::new(vault_path).join("Daily"); let dir = Path::new(vault_path).join("Daily");
fs::create_dir_all(&dir).map_err(|e| e.to_string())?; fs::create_dir_all(&dir).map_err(|e| e.to_string())?;
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "HelixNotes", "productName": "HelixNotes",
"version": "1.2.1", "version": "1.2.2",
"identifier": "com.helixnotes.app", "identifier": "com.helixnotes.app",
"build": { "build": {
"frontendDist": "../build", "frontendDist": "../build",
+91
View File
@@ -179,3 +179,94 @@ body.resizing {
display: none !important; display: none !important;
} }
} }
/* ── Print / Export PDF ── */
@media print {
/* Hide everything except editor content */
.titlebar,
.sidebar-panel,
.notelist-panel,
.resize-handle,
.toolbar-actions,
.editor-body-wrapper .note-search-bar,
.formatting-toolbar,
.editor-formatting-bar,
.history-panel,
.outline-panel,
.graph-panel,
.ai-panel,
.link-context-menu,
.image-toolbar,
.selection-bar {
display: none !important;
}
/* Force light theme colors for PDF */
:root, :root.dark {
--bg-primary: #ffffff !important;
--bg-secondary: #f8f9fa !important;
--bg-tertiary: #f0f1f3 !important;
--bg-editor: #ffffff !important;
--text-primary: #1a1a2e !important;
--text-secondary: #495057 !important;
--text-tertiary: #868e96 !important;
--text-accent: #5b6abf !important;
--accent: #5b6abf !important;
--border-color: #e2e5e9 !important;
--border-light: #f0f1f3 !important;
}
html, body {
height: auto;
overflow: visible;
background: white !important;
color: #1a1a2e !important;
font-size: 12pt;
padding: 0;
}
/* Override all scoped height/overflow constraints for print flow */
* {
overflow: visible !important;
height: auto !important;
max-height: none !important;
min-height: 0 !important;
}
.app-layout {
display: block !important;
}
.editor-panel {
width: 100% !important;
min-width: 0 !important;
}
.ProseMirror {
padding: 0 !important;
max-width: 100% !important;
background: white !important;
color: #1a1a2e !important;
}
/* Ensure images fit within page */
.ProseMirror img {
max-width: 100% !important;
page-break-inside: avoid;
}
/* Avoid breaking inside these elements */
h1, h2, h3, h4, h5, h6 {
page-break-after: avoid;
}
pre, blockquote, table, figure {
page-break-inside: avoid;
}
/* Code blocks with light background */
.ProseMirror pre, .ProseMirror code {
background: #f8f9fa !important;
color: #1a1a2e !important;
}
}
+8
View File
@@ -1073,6 +1073,14 @@
</svg> </svg>
Move to... Move to...
</button> </button>
{#if !isMobile}
<button onclick={async () => { const n = contextMenu!.note; contextMenu = null; await selectNote(n); setTimeout(() => window.print(), 300); }}>
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/>
</svg>
Print / Export to PDF
</button>
{/if}
<button class="danger" onclick={() => handleDelete(contextMenu!.note)}> <button class="danger" onclick={() => handleDelete(contextMenu!.note)}>
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/> <path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>