Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e399c357d8 |
@@ -74,6 +74,7 @@ Die Oberfläche gibt es auf Deutsch und Englisch; ink-notes folgt der Systemspra
|
||||
|
||||
### Updates
|
||||
- Die App prüft auf neue Versionen auf Gitea und installiert sie auf Wunsch. Installiert wird nur, wenn die Minisign-Signatur und die SHA-256-Prüfsumme stimmen (Details unten).
|
||||
- Als Flatpak sucht ink-notes nicht selbst nach Updates; die kommen dann über die Software-Verwaltung (`flatpak update`).
|
||||
|
||||
---
|
||||
|
||||
@@ -190,6 +191,17 @@ Mehr dazu in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md), das Speicherformat
|
||||
|
||||
Veröffentlicht wird über Gitea Actions ([`.gitea/workflows/release.yaml`](.gitea/workflows/release.yaml)), sobald ein Tag `vX.Y.Z` gepusht wird: Tests, Pakete bauen, signieren, Release anlegen. Manuell geht es mit `GITEA_TOKEN=… ./scripts/publish-gitea-release.sh`.
|
||||
|
||||
### Flatpak
|
||||
|
||||
Das Manifest liegt in [`packaging/flatpak/`](packaging/flatpak/) (Runtime `org.freedesktop.Platform` 26.08, Rust aus der SDK-Erweiterung `rust-stable`). Lokal bauen und installieren:
|
||||
|
||||
```bash
|
||||
flatpak-builder --user --install --force-clean target/flatpak-build packaging/flatpak/eu.pansi.ink-notes.yml
|
||||
flatpak run eu.pansi.ink-notes
|
||||
```
|
||||
|
||||
Nach jeder Änderung an `Cargo.lock` muss `packaging/flatpak/cargo-sources.json` mit dem [flatpak-cargo-generator](https://github.com/flatpak/flatpak-builder-tools/tree/master/cargo) neu erzeugt werden (`python3 flatpak-cargo-generator.py Cargo.lock -o packaging/flatpak/cargo-sources.json`). In der Sandbox darf ink-notes Bilder, Downloads und Schreibtisch lesen und in den Dokumente-Ordner exportieren; die Notizbücher liegen unter `~/.var/app/eu.pansi.ink-notes/`.
|
||||
|
||||
### Release-Signatur einrichten (einmalig)
|
||||
|
||||
Updates werden in der App nur mit gültiger Minisign-Signatur installiert. Signiert wird mit [rsign2](https://crates.io/crates/rsign2) (`cargo install rsign2 --locked`). Schlüsselpaar ohne Passwort erzeugen (es wird nur als CI-Secret verwendet):
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=ink-notes
|
||||
GenericName=Notizbuch- & Inking-App
|
||||
Comment=Handschriftliche Notizen mit Stift, Touch und Maus; PDFs beschriften
|
||||
GenericName=Note-Taking & Inking App
|
||||
GenericName[de]=Notizbuch- & Inking-App
|
||||
Comment=Handwritten notes with pen, touch and mouse; annotate PDFs
|
||||
Comment[de]=Handschriftliche Notizen mit Stift, Touch und Maus; PDFs beschriften
|
||||
Exec=ink-notes %F
|
||||
Icon=eu.pansi.ink-notes
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Office;Graphics;Utility;
|
||||
Keywords=Note;Notiz;Pen;Stift;Ink;Inking;Stylus;Drawing;Zeichnen;PDF;Vector;Text;Annotation;
|
||||
Categories=Office;Graphics;
|
||||
Keywords=Note;Pen;Ink;Inking;Stylus;Drawing;PDF;Vector;Text;Annotation;
|
||||
Keywords[de]=Notiz;Stift;Ink;Inking;Stylus;Zeichnen;PDF;Vektor;Text;Annotation;
|
||||
StartupWMClass=eu.pansi.ink-notes
|
||||
MimeType=application/x-inknotes;
|
||||
Actions=NewWindow;
|
||||
|
||||
[Desktop Action NewWindow]
|
||||
Name=Neues Fenster
|
||||
Name=New Window
|
||||
Name[de]=Neues Fenster
|
||||
Exec=ink-notes
|
||||
|
||||
@@ -4,22 +4,34 @@
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>MIT</project_license>
|
||||
<name>ink-notes</name>
|
||||
<summary>Notizbuch-App für Stift, Touch und Maus</summary>
|
||||
<summary>Handwritten notes with pen, touch and mouse</summary>
|
||||
<summary xml:lang="de">Notizbuch-App für Stift, Touch und Maus</summary>
|
||||
<description>
|
||||
<p>
|
||||
ink-notes ist eine Notizbuch-App für Linux, geschrieben in Rust mit wgpu. Handschrift wird als
|
||||
ink-notes is a notebook app for Linux tablets and convertibles. Handwriting is stored as
|
||||
vectors; write with a pen, your finger, a touchpad or a mouse.
|
||||
</p>
|
||||
<p xml:lang="de">
|
||||
ink-notes ist eine Notizbuch-App für Linux-Tablets und Convertibles. Handschrift wird als
|
||||
Vektoren gespeichert; geschrieben wird mit Stift, Finger, Touchpad oder Maus.
|
||||
</p>
|
||||
<p>Funktionen:</p>
|
||||
<p>Features:</p>
|
||||
<p xml:lang="de">Funktionen:</p>
|
||||
<ul>
|
||||
<li>Stift und Textmarker mit Druckstärke, Glättung beim Schreiben und Ecken-Erhaltung</li>
|
||||
<li>Radierer für ganze Striche, Teilstriche oder nur Textmarker; virtuelles Lineal</li>
|
||||
<li>Formerkennung (Linien, Pfeile, Kreise, Ellipsen, Rechtecke, Dreiecke, Rauten, Koordinatensysteme)</li>
|
||||
<li>Auswählen, Verschieben, Drehen, Skalieren und Umfärben; Rückgängig für alle Änderungen</li>
|
||||
<li>Textfelder, Bilder und PDF-Import zum Beschriften (Querformat-Folien bekommen Querformat-Seiten)</li>
|
||||
<li>Durchgehendes Scrollen, Zoom von 25 bis 1000 Prozent, Papier- und Musterfarben</li>
|
||||
<li>Mehrere Notizbücher, automatisches Speichern im Hintergrund</li>
|
||||
<li>Export als PDF (mit durchsuchbarem Text), PNG oder SVG</li>
|
||||
<li>Pens and highlighter with pressure, smoothing while writing and sharp corners</li>
|
||||
<li xml:lang="de">Stifte und Textmarker mit Druckstärke, Glättung beim Schreiben und Ecken-Erhaltung</li>
|
||||
<li>Shape recognition: hold at the end of a stroke to get clean lines, arrows, circles, rectangles, triangles and coordinate systems</li>
|
||||
<li xml:lang="de">Formerkennung: am Strichende halten für saubere Linien, Pfeile, Kreise, Rechtecke, Dreiecke und Koordinatensysteme</li>
|
||||
<li>Eraser for whole strokes, partial strokes or highlighter only; virtual ruler</li>
|
||||
<li xml:lang="de">Radierer für ganze Striche, Teilstriche oder nur Textmarker; virtuelles Lineal</li>
|
||||
<li>Select, move, rotate, scale and recolor; undo for every change</li>
|
||||
<li xml:lang="de">Auswählen, Verschieben, Drehen, Skalieren und Umfärben; Rückgängig für alle Änderungen</li>
|
||||
<li>Text boxes, images and PDF import to annotate lecture slides and worksheets</li>
|
||||
<li xml:lang="de">Textfelder, Bilder und PDF-Import zum Beschriften von Vorlesungsfolien und Übungsblättern</li>
|
||||
<li>Notebooks in folders, continuous scrolling, automatic saving in the background</li>
|
||||
<li xml:lang="de">Notizbücher in Ordnern, durchgehendes Scrollen, automatisches Speichern im Hintergrund</li>
|
||||
<li>Export as PDF (with searchable text), PNG or SVG</li>
|
||||
<li xml:lang="de">Export als PDF (mit durchsuchbarem Text), PNG oder SVG</li>
|
||||
</ul>
|
||||
</description>
|
||||
<launchable type="desktop-id">eu.pansi.ink-notes.desktop</launchable>
|
||||
@@ -29,12 +41,46 @@
|
||||
<categories>
|
||||
<category>Office</category>
|
||||
<category>Graphics</category>
|
||||
<category>Utility</category>
|
||||
</categories>
|
||||
<keywords>
|
||||
<keyword>notes</keyword>
|
||||
<keyword>handwriting</keyword>
|
||||
<keyword>stylus</keyword>
|
||||
<keyword>pen</keyword>
|
||||
<keyword>PDF</keyword>
|
||||
<keyword>annotate</keyword>
|
||||
</keywords>
|
||||
<supports>
|
||||
<control>pointing</control>
|
||||
<control>touch</control>
|
||||
<control>tablet</control>
|
||||
</supports>
|
||||
<developer id="eu.pansi">
|
||||
<name>Harald</name>
|
||||
<name>Harald Pansi</name>
|
||||
</developer>
|
||||
<url type="homepage">https://gitea.pansi.eu/harald/ink-notes</url>
|
||||
<url type="bugtracker">https://gitea.pansi.eu/harald/ink-notes/issues</url>
|
||||
<url type="vcs-browser">https://gitea.pansi.eu/harald/ink-notes</url>
|
||||
<branding>
|
||||
<color type="primary" scheme_preference="light">#a8c8f0</color>
|
||||
<color type="primary" scheme_preference="dark">#1f3a5f</color>
|
||||
</branding>
|
||||
<content_rating type="oars-1.1" />
|
||||
<releases>
|
||||
<release version="0.25.0" date="2026-10-09">
|
||||
<description>
|
||||
<p>English user interface; the language follows the system and can be changed in the menu. Holding to snap a shape tolerates a slightly trembling pen.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.24.0" date="2026-10-09">
|
||||
<description>
|
||||
<p>Axis cross from two crossing strokes.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.23.0" date="2026-10-09">
|
||||
<description>
|
||||
<p>The on-screen keyboard of GNOME appears when tapping a text field.</p>
|
||||
</description>
|
||||
</release>
|
||||
</releases>
|
||||
</component>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
# Flatpak-Manifest für ink-notes (Flathub).
|
||||
#
|
||||
# Lokal bauen und installieren (aus dem Repository-Wurzelverzeichnis):
|
||||
# flatpak-builder --user --install --force-clean target/flatpak-build \
|
||||
# packaging/flatpak/eu.pansi.ink-notes.yml
|
||||
#
|
||||
# cargo-sources.json nach jeder Änderung an Cargo.lock neu erzeugen:
|
||||
# python3 flatpak-cargo-generator.py Cargo.lock -o packaging/flatpak/cargo-sources.json
|
||||
# (flatpak-builder-tools, https://github.com/flatpak/flatpak-builder-tools/tree/master/cargo)
|
||||
#
|
||||
# Für die Einreichung bei Flathub die Quelle `type: dir` durch das Release-Tag ersetzen
|
||||
# (type: git, url, tag, commit).
|
||||
id: eu.pansi.ink-notes
|
||||
runtime: org.freedesktop.Platform
|
||||
runtime-version: '26.08'
|
||||
sdk: org.freedesktop.Sdk
|
||||
sdk-extensions:
|
||||
- org.freedesktop.Sdk.Extension.rust-stable
|
||||
command: ink-notes
|
||||
finish-args:
|
||||
- --socket=wayland
|
||||
- --socket=fallback-x11
|
||||
- --share=ipc
|
||||
- --device=dri
|
||||
# Die eingebaute Dateiauswahl (Bilder und PDFs einfügen) arbeitet ohne Desktop-Portal und
|
||||
# bietet Bilder, Downloads und Schreibtisch an; Export (PDF, PNG, SVG) in den Dokumente-Ordner.
|
||||
# Ziehen aus dem Dateimanager geht über das Dokumenten-Portal auch aus anderen Ordnern.
|
||||
- --filesystem=xdg-pictures:ro
|
||||
- --filesystem=xdg-download:ro
|
||||
- --filesystem=xdg-desktop:ro
|
||||
- --filesystem=xdg-documents
|
||||
build-options:
|
||||
append-path: /usr/lib/sdk/rust-stable/bin
|
||||
env:
|
||||
CARGO_HOME: /run/build/ink-notes/cargo
|
||||
modules:
|
||||
- name: ink-notes
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- cargo --offline build --release --locked
|
||||
- install -Dm755 target/release/ink-notes /app/bin/ink-notes
|
||||
- install -Dm644 packaging/eu.pansi.ink-notes.desktop /app/share/applications/eu.pansi.ink-notes.desktop
|
||||
- install -Dm644 packaging/eu.pansi.ink-notes.metainfo.xml /app/share/metainfo/eu.pansi.ink-notes.metainfo.xml
|
||||
- install -Dm644 assets/ink-notes.svg /app/share/icons/hicolor/scalable/apps/eu.pansi.ink-notes.svg
|
||||
- install -Dm644 assets/ink-notes.png /app/share/icons/hicolor/256x256/apps/eu.pansi.ink-notes.png
|
||||
sources:
|
||||
- type: dir
|
||||
path: ../..
|
||||
skip:
|
||||
- target
|
||||
- .git
|
||||
- .flatpak-builder
|
||||
- ideas.txt
|
||||
- issue.txt
|
||||
- cargo-sources.json
|
||||
@@ -1,18 +1,22 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=ink-notes
|
||||
GenericName=Notizbuch- & Inking-App
|
||||
Comment=Handschriftliche Notizen mit Stift, Touch und Maus; PDFs beschriften
|
||||
GenericName=Note-Taking & Inking App
|
||||
GenericName[de]=Notizbuch- & Inking-App
|
||||
Comment=Handwritten notes with pen, touch and mouse; annotate PDFs
|
||||
Comment[de]=Handschriftliche Notizen mit Stift, Touch und Maus; PDFs beschriften
|
||||
Exec=ink-notes %F
|
||||
Icon=eu.pansi.ink-notes
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Office;Graphics;Utility;
|
||||
Keywords=Note;Notiz;Pen;Stift;Ink;Inking;Stylus;Drawing;Zeichnen;PDF;Vector;Text;Annotation;
|
||||
Categories=Office;Graphics;
|
||||
Keywords=Note;Pen;Ink;Inking;Stylus;Drawing;PDF;Vector;Text;Annotation;
|
||||
Keywords[de]=Notiz;Stift;Ink;Inking;Stylus;Zeichnen;PDF;Vektor;Text;Annotation;
|
||||
StartupWMClass=eu.pansi.ink-notes
|
||||
MimeType=application/x-inknotes;
|
||||
Actions=NewWindow;
|
||||
|
||||
[Desktop Action NewWindow]
|
||||
Name=Neues Fenster
|
||||
Name=New Window
|
||||
Name[de]=Neues Fenster
|
||||
Exec=ink-notes
|
||||
|
||||
@@ -4,22 +4,34 @@
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>MIT</project_license>
|
||||
<name>ink-notes</name>
|
||||
<summary>Notizbuch-App für Stift, Touch und Maus</summary>
|
||||
<summary>Handwritten notes with pen, touch and mouse</summary>
|
||||
<summary xml:lang="de">Notizbuch-App für Stift, Touch und Maus</summary>
|
||||
<description>
|
||||
<p>
|
||||
ink-notes ist eine Notizbuch-App für Linux, geschrieben in Rust mit wgpu. Handschrift wird als
|
||||
ink-notes is a notebook app for Linux tablets and convertibles. Handwriting is stored as
|
||||
vectors; write with a pen, your finger, a touchpad or a mouse.
|
||||
</p>
|
||||
<p xml:lang="de">
|
||||
ink-notes ist eine Notizbuch-App für Linux-Tablets und Convertibles. Handschrift wird als
|
||||
Vektoren gespeichert; geschrieben wird mit Stift, Finger, Touchpad oder Maus.
|
||||
</p>
|
||||
<p>Funktionen:</p>
|
||||
<p>Features:</p>
|
||||
<p xml:lang="de">Funktionen:</p>
|
||||
<ul>
|
||||
<li>Stift und Textmarker mit Druckstärke, Glättung beim Schreiben und Ecken-Erhaltung</li>
|
||||
<li>Radierer für ganze Striche, Teilstriche oder nur Textmarker; virtuelles Lineal</li>
|
||||
<li>Formerkennung (Linien, Pfeile, Kreise, Ellipsen, Rechtecke, Dreiecke, Rauten, Koordinatensysteme)</li>
|
||||
<li>Auswählen, Verschieben, Drehen, Skalieren und Umfärben; Rückgängig für alle Änderungen</li>
|
||||
<li>Textfelder, Bilder und PDF-Import zum Beschriften (Querformat-Folien bekommen Querformat-Seiten)</li>
|
||||
<li>Durchgehendes Scrollen, Zoom von 25 bis 1000 Prozent, Papier- und Musterfarben</li>
|
||||
<li>Mehrere Notizbücher, automatisches Speichern im Hintergrund</li>
|
||||
<li>Export als PDF (mit durchsuchbarem Text), PNG oder SVG</li>
|
||||
<li>Pens and highlighter with pressure, smoothing while writing and sharp corners</li>
|
||||
<li xml:lang="de">Stifte und Textmarker mit Druckstärke, Glättung beim Schreiben und Ecken-Erhaltung</li>
|
||||
<li>Shape recognition: hold at the end of a stroke to get clean lines, arrows, circles, rectangles, triangles and coordinate systems</li>
|
||||
<li xml:lang="de">Formerkennung: am Strichende halten für saubere Linien, Pfeile, Kreise, Rechtecke, Dreiecke und Koordinatensysteme</li>
|
||||
<li>Eraser for whole strokes, partial strokes or highlighter only; virtual ruler</li>
|
||||
<li xml:lang="de">Radierer für ganze Striche, Teilstriche oder nur Textmarker; virtuelles Lineal</li>
|
||||
<li>Select, move, rotate, scale and recolor; undo for every change</li>
|
||||
<li xml:lang="de">Auswählen, Verschieben, Drehen, Skalieren und Umfärben; Rückgängig für alle Änderungen</li>
|
||||
<li>Text boxes, images and PDF import to annotate lecture slides and worksheets</li>
|
||||
<li xml:lang="de">Textfelder, Bilder und PDF-Import zum Beschriften von Vorlesungsfolien und Übungsblättern</li>
|
||||
<li>Notebooks in folders, continuous scrolling, automatic saving in the background</li>
|
||||
<li xml:lang="de">Notizbücher in Ordnern, durchgehendes Scrollen, automatisches Speichern im Hintergrund</li>
|
||||
<li>Export as PDF (with searchable text), PNG or SVG</li>
|
||||
<li xml:lang="de">Export als PDF (mit durchsuchbarem Text), PNG oder SVG</li>
|
||||
</ul>
|
||||
</description>
|
||||
<launchable type="desktop-id">eu.pansi.ink-notes.desktop</launchable>
|
||||
@@ -29,12 +41,46 @@
|
||||
<categories>
|
||||
<category>Office</category>
|
||||
<category>Graphics</category>
|
||||
<category>Utility</category>
|
||||
</categories>
|
||||
<keywords>
|
||||
<keyword>notes</keyword>
|
||||
<keyword>handwriting</keyword>
|
||||
<keyword>stylus</keyword>
|
||||
<keyword>pen</keyword>
|
||||
<keyword>PDF</keyword>
|
||||
<keyword>annotate</keyword>
|
||||
</keywords>
|
||||
<supports>
|
||||
<control>pointing</control>
|
||||
<control>touch</control>
|
||||
<control>tablet</control>
|
||||
</supports>
|
||||
<developer id="eu.pansi">
|
||||
<name>Harald</name>
|
||||
<name>Harald Pansi</name>
|
||||
</developer>
|
||||
<url type="homepage">https://gitea.pansi.eu/harald/ink-notes</url>
|
||||
<url type="bugtracker">https://gitea.pansi.eu/harald/ink-notes/issues</url>
|
||||
<url type="vcs-browser">https://gitea.pansi.eu/harald/ink-notes</url>
|
||||
<branding>
|
||||
<color type="primary" scheme_preference="light">#a8c8f0</color>
|
||||
<color type="primary" scheme_preference="dark">#1f3a5f</color>
|
||||
</branding>
|
||||
<content_rating type="oars-1.1" />
|
||||
<releases>
|
||||
<release version="0.25.0" date="2026-10-09">
|
||||
<description>
|
||||
<p>English user interface; the language follows the system and can be changed in the menu. Holding to snap a shape tolerates a slightly trembling pen.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.24.0" date="2026-10-09">
|
||||
<description>
|
||||
<p>Axis cross from two crossing strokes.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.23.0" date="2026-10-09">
|
||||
<description>
|
||||
<p>The on-screen keyboard of GNOME appears when tapping a text field.</p>
|
||||
</description>
|
||||
</release>
|
||||
</releases>
|
||||
</component>
|
||||
|
||||
+13
-2
@@ -46,7 +46,9 @@ pub fn sanitize_filename_component(title: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Ermittelt das Standard-Dokumentenverzeichnis ($XDG_DOCUMENTS_DIR mit Fallback ~/Documents).
|
||||
/// Ermittelt das Standard-Dokumentenverzeichnis: `$XDG_DOCUMENTS_DIR`, sonst der Eintrag in
|
||||
/// `~/.config/user-dirs.dirs` (z. B. „Dokumente“), sonst `~/Documents`. Im Flatpak ist nur
|
||||
/// dieser Ordner beschreibbar, der Fallback allein träfe bei deutschen Systemen daneben.
|
||||
pub fn default_documents_dir() -> PathBuf {
|
||||
if let Ok(dir) = std::env::var("XDG_DOCUMENTS_DIR") {
|
||||
if !dir.trim().is_empty() {
|
||||
@@ -56,7 +58,16 @@ pub fn default_documents_dir() -> PathBuf {
|
||||
|
||||
if let Ok(home) = std::env::var("HOME") {
|
||||
if !home.trim().is_empty() {
|
||||
return PathBuf::from(home).join("Documents");
|
||||
let home = PathBuf::from(home);
|
||||
let user_dirs =
|
||||
std::fs::read_to_string(home.join(".config/user-dirs.dirs")).unwrap_or_default();
|
||||
if let Some(dir) =
|
||||
crate::file_picker::parse_user_dir(&user_dirs, "XDG_DOCUMENTS_DIR", &home)
|
||||
.filter(|dir| *dir != home)
|
||||
{
|
||||
return dir;
|
||||
}
|
||||
return home.join("Documents");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,9 +66,11 @@ pub const EN: &[(&str, &str)] = &[
|
||||
("Die beschädigte Originaldatei wurde in Quarantäne gesichert:", "The damaged original file was saved to quarantine:"),
|
||||
("Die Datei ist kein lesbares PDF", "The file is not a readable PDF"),
|
||||
("Die einzige Seite eines Notizbuchs kann nicht gelöscht werden", "The only page of a notebook cannot be deleted"),
|
||||
("Die Flatpak-Version wird über die Software-Verwaltung aktualisiert.", "The Flatpak version is updated through the software manager."),
|
||||
("Die heruntergeladene Datei existiert nicht mehr.", "The downloaded file no longer exists."),
|
||||
("die oberste Ebene", "the top level"),
|
||||
("Die Zwischenablage ist leer", "The clipboard is empty"),
|
||||
("Diese Version wird über die Software-Verwaltung aktualisiert (z. B. GNOME Software oder „flatpak update“).", "This version is updated through the software manager (e.g. GNOME Software or “flatpak update”)."),
|
||||
("Dieser Ordner ist leer.", "This folder is empty."),
|
||||
("Dokument '{title}' erstellt", "Document '{title}' created"),
|
||||
("Dokument '{title}' geöffnet", "Document '{title}' opened"),
|
||||
|
||||
@@ -4281,6 +4281,18 @@ pub fn render_ui(
|
||||
ui.label(egui::RichText::new(format!("({})", runtime_name)).color(egui::Color32::from_gray(150)));
|
||||
});
|
||||
|
||||
if !updater.runtime().self_update_allowed() {
|
||||
ui.add_space(8.0);
|
||||
ui.label(
|
||||
egui::RichText::new(t!(
|
||||
"Diese Version wird über die Software-Verwaltung aktualisiert \
|
||||
(z. B. GNOME Software oder „flatpak update“)."
|
||||
))
|
||||
.color(egui::Color32::from_gray(210)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(egui::RichText::new(t!("Server:")).color(egui::Color32::from_gray(180)));
|
||||
ui.label(egui::RichText::new(format!("{}/{}/{}", updater.config().server_url, updater.config().repo_owner, updater.config().repo_name)).color(egui::Color32::from_gray(210)));
|
||||
@@ -4446,7 +4458,8 @@ pub fn render_ui(
|
||||
let action_label = match updater.runtime() {
|
||||
crate::updater::RuntimeEnvironment::AppImage { .. } => t!("🚀 AppImage aktualisieren & ausführen"),
|
||||
crate::updater::RuntimeEnvironment::DebPackage { .. } => t!("📦 Paket mit Software-Center öffnen / installieren"),
|
||||
crate::updater::RuntimeEnvironment::PortableOrDev { .. } => t!("📂 Im Dateimanager anzeigen"),
|
||||
crate::updater::RuntimeEnvironment::PortableOrDev { .. }
|
||||
| crate::updater::RuntimeEnvironment::Flatpak => t!("📂 Im Dateimanager anzeigen"),
|
||||
};
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
|
||||
@@ -118,11 +118,20 @@ pub enum RuntimeEnvironment {
|
||||
DebPackage { binary_path: PathBuf },
|
||||
/// Aus Quellcode / Entwicklungs-Binary (z.B. target/debug oder target/release)
|
||||
PortableOrDev { binary_path: PathBuf },
|
||||
/// Als Flatpak installiert: Updates kommen über die Software-Verwaltung, ink-notes lädt
|
||||
/// selbst nichts herunter (Vorgabe von Flathub)
|
||||
Flatpak,
|
||||
}
|
||||
|
||||
impl RuntimeEnvironment {
|
||||
/// Erkennt die aktuelle Laufzeitumgebung anhand der Umgebung und des Binärpfads.
|
||||
pub fn detect() -> Self {
|
||||
if is_flatpak(
|
||||
std::env::var("FLATPAK_ID").ok().as_deref(),
|
||||
Path::new("/.flatpak-info").exists(),
|
||||
) {
|
||||
return RuntimeEnvironment::Flatpak;
|
||||
}
|
||||
let appimage_var = std::env::var("APPIMAGE").ok();
|
||||
let current_exe = std::env::current_exe().unwrap_or_else(|_| PathBuf::from("ink-notes"));
|
||||
Self::detect_from(appimage_var.as_deref(), ¤t_exe)
|
||||
@@ -156,8 +165,20 @@ impl RuntimeEnvironment {
|
||||
RuntimeEnvironment::AppImage { .. } => t!("AppImage (Portabel)"),
|
||||
RuntimeEnvironment::DebPackage { .. } => t!("System-Paket (.deb)"),
|
||||
RuntimeEnvironment::PortableOrDev { .. } => t!("Entwicklung / Lokal"),
|
||||
RuntimeEnvironment::Flatpak => "Flatpak",
|
||||
}
|
||||
}
|
||||
|
||||
/// Ob ink-notes selbst nach Updates suchen und sie installieren darf
|
||||
pub fn self_update_allowed(&self) -> bool {
|
||||
!matches!(self, RuntimeEnvironment::Flatpak)
|
||||
}
|
||||
}
|
||||
|
||||
/// Läuft ink-notes in einer Flatpak-Sandbox (`FLATPAK_ID` gesetzt oder `/.flatpak-info`
|
||||
/// vorhanden)?
|
||||
pub fn is_flatpak(flatpak_id: Option<&str>, info_file_exists: bool) -> bool {
|
||||
flatpak_id.is_some_and(|id| !id.trim().is_empty()) || info_file_exists
|
||||
}
|
||||
|
||||
/// Bereinigt und validiert einen Asset-Dateinamen gegen Path Traversal Angriffe.
|
||||
@@ -578,6 +599,9 @@ impl UpdaterController {
|
||||
|
||||
/// Fragt im Hintergrund die Gitea-API ab.
|
||||
pub fn check_for_updates(&mut self) {
|
||||
if !self.runtime.self_update_allowed() {
|
||||
return;
|
||||
}
|
||||
if matches!(
|
||||
self.status,
|
||||
UpdaterStatus::Checking | UpdaterStatus::Downloading { .. }
|
||||
@@ -887,6 +911,10 @@ impl UpdaterController {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
RuntimeEnvironment::Flatpak => Err(t!(
|
||||
"Die Flatpak-Version wird über die Software-Verwaltung aktualisiert."
|
||||
)
|
||||
.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1074,6 +1102,19 @@ dcdeb7ac87d9e6cb8022e5a71bc7f2c56d779b4fce4efdd5bae5be3b0214884a ink-notes_0.1.
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flatpak_detection_disables_self_update() {
|
||||
assert!(is_flatpak(Some("eu.pansi.ink-notes"), false));
|
||||
assert!(is_flatpak(None, true));
|
||||
assert!(!is_flatpak(Some(" "), false));
|
||||
assert!(!is_flatpak(None, false));
|
||||
assert!(!RuntimeEnvironment::Flatpak.self_update_allowed());
|
||||
assert!(
|
||||
RuntimeEnvironment::detect_from(None, Path::new("/usr/bin/ink-notes"))
|
||||
.self_update_allowed()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_https_enforcement() {
|
||||
let config = UpdaterConfig {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//! Das Flatpak baut ohne Netz aus `packaging/flatpak/cargo-sources.json`; jede Abhängigkeit
|
||||
//! aus `Cargo.lock` muss dort stehen, sonst schlägt der Flatpak-Build fehl.
|
||||
|
||||
#[test]
|
||||
fn cargo_sources_cover_cargo_lock() {
|
||||
let lock = include_str!("../Cargo.lock");
|
||||
let sources = include_str!("../packaging/flatpak/cargo-sources.json");
|
||||
let mut missing = Vec::new();
|
||||
for package in lock.split("[[package]]").skip(1) {
|
||||
let field = |key: &str| {
|
||||
package.lines().find_map(|line| {
|
||||
line.strip_prefix(key)
|
||||
.map(|rest| rest.trim().trim_matches('"').to_string())
|
||||
})
|
||||
};
|
||||
// Nur Pakete aus crates.io (das eigene Paket hat keine Quelle)
|
||||
if field("source = ").is_none() {
|
||||
continue;
|
||||
}
|
||||
let (Some(name), Some(version)) = (field("name = "), field("version = ")) else {
|
||||
continue;
|
||||
};
|
||||
let crate_file = format!("/{name}-{version}.crate\"");
|
||||
if !sources.contains(&crate_file) {
|
||||
missing.push(format!("{name} {version}"));
|
||||
}
|
||||
}
|
||||
assert!(
|
||||
missing.is_empty(),
|
||||
"cargo-sources.json ist veraltet (flatpak-cargo-generator neu ausführen), es fehlen: {}",
|
||||
missing.join(", ")
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user