diff --git a/fdroid/com.helixnotes.app.yml b/fdroid/com.helixnotes.app.yml
new file mode 100644
index 0000000..95dc1ac
--- /dev/null
+++ b/fdroid/com.helixnotes.app.yml
@@ -0,0 +1,174 @@
+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
diff --git a/package.json b/package.json
index 04f85c8..ed519ac 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "helixnotes",
"private": true,
"license": "AGPL-3.0-or-later",
- "version": "1.2.0",
+ "version": "1.2.1",
"type": "module",
"scripts": {
"dev": "vite dev",
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index d0e4c2e..36e06c2 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -1849,7 +1849,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "helixnotes"
-version = "1.2.0"
+version = "1.2.1"
dependencies = [
"arboard",
"chrono",
@@ -1876,6 +1876,7 @@ dependencies = [
"tauri-plugin-opener",
"tauri-plugin-single-instance",
"tauri-plugin-updater",
+ "tauri-plugin-window-state",
"tokio",
"uuid",
"walkdir",
@@ -3141,7 +3142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
dependencies = [
"libc",
- "windows-sys 0.45.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -5262,6 +5263,21 @@ dependencies = [
"zip 4.6.1",
]
+[[package]]
+name = "tauri-plugin-window-state"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73736611e14142408d15353e21e3cca2f12a3cfb523ad0ce85999b6d2ef1a704"
+dependencies = [
+ "bitflags 2.11.0",
+ "log",
+ "serde",
+ "serde_json",
+ "tauri",
+ "tauri-plugin",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "tauri-runtime"
version = "2.10.0"
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 177fc6e..9e2f0aa 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "helixnotes"
-version = "1.2.0"
+version = "1.2.1"
description = "Local markdown note-taking app"
authors = ["HelixNotes"]
license = "AGPL-3.0-or-later"
@@ -41,6 +41,7 @@ rustls = { version = "0.23", default-features = false, features = ["ring", "logg
[target.'cfg(not(target_os = "android"))'.dependencies]
tauri-plugin-updater = "2"
tauri-plugin-single-instance = "2"
+tauri-plugin-window-state = "2"
arboard = { version = "3", features = ["image-data", "wayland-data-control"] }
png = "0.17"
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp", "gif"] }
diff --git a/src-tauri/capabilities/desktop.json b/src-tauri/capabilities/desktop.json
index c18cf3e..78d56da 100644
--- a/src-tauri/capabilities/desktop.json
+++ b/src-tauri/capabilities/desktop.json
@@ -5,6 +5,7 @@
"platforms": ["linux", "macOS", "windows"],
"windows": ["main"],
"permissions": [
- "updater:default"
+ "updater:default",
+ "window-state:default"
]
}
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs
index 0e1e90f..9174e0e 100644
--- a/src-tauri/src/lib.rs
+++ b/src-tauri/src/lib.rs
@@ -180,6 +180,7 @@ pub fn run() {
}));
builder = builder.plugin(tauri_plugin_updater::Builder::new().build());
+ builder = builder.plugin(tauri_plugin_window_state::Builder::default().build());
builder = builder.on_window_event(move |window, event| {
match event {
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index 2a98071..d73aee4 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -1,7 +1,7 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "HelixNotes",
- "version": "1.2.0",
+ "version": "1.2.1",
"identifier": "com.helixnotes.app",
"build": {
"frontendDist": "../build",
diff --git a/src/lib/components/AppLayout.svelte b/src/lib/components/AppLayout.svelte
index d8564b2..3ec64c6 100644
--- a/src/lib/components/AppLayout.svelte
+++ b/src/lib/components/AppLayout.svelte
@@ -192,34 +192,49 @@
}
// Android back gesture / hardware back button support
- let mobileNavFromPopstate = false;
+ // We maintain a simple counter of how many views deep we are.
+ // sidebar=0, notelist=1, editor=2. Each forward nav pushes, back pops.
+ let historyDepth = 0;
+ let navFromPopstate = false;
if (isMobile) {
- // Seed initial history state
- history.replaceState({ mobileView: 'sidebar' }, '');
+ history.replaceState({ mobileView: 'sidebar', depth: 0 }, '');
- // When mobileView changes forward, push browser history so Android back gesture works
$effect(() => {
const view = $mobileView;
- if (mobileNavFromPopstate) {
- mobileNavFromPopstate = false;
+ if (navFromPopstate) {
+ navFromPopstate = false;
return;
}
- // Replace state to track current view
- history.pushState({ mobileView: view }, '');
+ const targetDepth = view === 'sidebar' ? 0 : view === 'notelist' ? 1 : 2;
+ if (targetDepth > historyDepth) {
+ // Forward navigation — push entries for each level skipped
+ for (let d = historyDepth + 1; d <= targetDepth; d++) {
+ const v = d === 1 ? 'notelist' : 'editor';
+ history.pushState({ mobileView: v, depth: d }, '');
+ }
+ historyDepth = targetDepth;
+ } else if (targetDepth < historyDepth) {
+ // Programmatic back (e.g. mobileBack button) — go back in history
+ const steps = historyDepth - targetDepth;
+ historyDepth = targetDepth;
+ navFromPopstate = true; // suppress the popstate that history.go triggers
+ history.go(-steps);
+ }
});
window.addEventListener('popstate', (e) => {
- const currentView = $mobileView;
- if (currentView === 'sidebar') {
- // Already at root — let Android handle it (exit app)
+ if (navFromPopstate) {
+ navFromPopstate = false;
return;
}
- mobileNavFromPopstate = true;
- if (currentView === 'editor') $mobileView = 'notelist';
- else if (currentView === 'notelist') $mobileView = 'sidebar';
- // Push state again so next back gesture also works
- history.pushState({ mobileView: $mobileView }, '');
+ const state = e.state;
+ const targetDepth = state?.depth ?? 0;
+ historyDepth = targetDepth;
+ navFromPopstate = true;
+ if (targetDepth === 0) $mobileView = 'sidebar';
+ else if (targetDepth === 1) $mobileView = 'notelist';
+ else $mobileView = 'editor';
});
}
@@ -525,12 +540,7 @@
-
-