feat: sync notebooks between devices via a synced folder (Issue #49, stage 1)

- Storage location setting: the notebooks can be moved into a folder kept in
  sync by Nextcloud, Google Drive, Syncthing etc. (subfolder `ink-notes`);
  existing notebooks are copied there if it is still empty, the originals stay.
- Changes from other devices are taken over while everything local is saved:
  changed pages are reloaded, new/removed/reordered pages and titles come in
  through the manifest. A page file still being synced is retried later
  instead of being set aside as damaged.
- Conflict copies made by sync clients become pages of their own.
- `.opened_by.json` marks the device that has a notebook open; opening a
  notebook open elsewhere shows a warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
haraldandClaude Opus 5.5 committed 2026-10-27 13:09:39 +01:00
1 parent 41ee32e1f7
commit 9b34e30475
13 files changed
+976 -9

No files matched your search

+5
View File
@@ -24,6 +24,8 @@ pub enum PickerKind {
Image,
/// PDF, Xournal++, Rnote or Saber file to import as a new notebook
Import,
/// Folder for the notebooks (Issue #49): lists folders only
Folder,
}
impl PickerKind {
@@ -32,6 +34,7 @@ impl PickerKind {
match self {
PickerKind::Image => is_supported_image_path(path),
PickerKind::Import => crate::import::is_importable_path(path),
PickerKind::Folder => false,
}
}
}
@@ -64,6 +67,7 @@ impl FilePicker {
let preferred = match kind {
PickerKind::Image => tn!("🖼 Bilder"),
PickerKind::Import => tn!("⬇ Downloads"),
PickerKind::Folder => tn!("🏠 Persönlicher Ordner"),
};
let all = shortcuts();
all.iter()
@@ -225,6 +229,7 @@ mod tests {
"Uni.sbn2"
]
);
assert_eq!(names(PickerKind::Folder), ["aOrdner", "zOrdner"]);
}
#[test]