diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c7ed89 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vibe/ diff --git a/README.md b/README.md index 0f38d4a..2d004a8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,259 @@ -# doxa +# DOXA -Sada nástrojů pracující s textem z rodiny Doxa \ No newline at end of file +

+ MIT license + Go + JavaScript + Platforms +

+ +

+ English | + Čeština +

+ +--- + +## 🌍 DOXA + +**DOXA** is a collection of three minimalist, locally-focused applications for note management, message encryption, and command-line text processing. All projects share a common philosophy: **complete independence, privacy, and control over your data**. No cloud services, no tracking, no external dependencies. Your data belongs only to you. + +--- + +## 📌 Projects in the DOXA Collection + +### 1. 📝 [DOXA Notes](doxa-notes/) + +**Web and desktop application for note management** + +- **Description**: A minimalist note-taking application built on pure web standards (HTML5, CSS3, Vanilla JavaScript). Allows creating, editing, organizing, and exporting notes in an open JSON format. +- **Philosophy**: Local-first, no cloud databases, no tracking. Data is stored in the browser (LocalStorage/IndexedDB) or in local files. +- **Technologies**: Vanilla JavaScript (ES6+), HTML5, CSS3, JSON. +- **Platforms**: Web (browser), Linux (AppImage). +- **Features**: + - Tag support for note organization. + - Auto-save and manual JSON export/import. + - Dark/light mode and system settings. + - Drag & drop for reordering notes. + +📖 [Read detailed documentation](doxa-notes/README.md) + +--- + +### 2. 💻 [DOXA CLI](doxa-cli/) + +**Command-line application for note management** + +- **Description**: A command-line interface (CLI) version of DOXA Notes. Written in Go, it offers a modern Terminal User Interface (TUI) for managing notes directly from the terminal. +- **Philosophy**: Same philosophy as DOXA Notes – fully local, no external dependencies, data in JSON format. +- **Technologies**: Go (Golang), Bubble Tea (TUI framework). +- **Platforms**: Linux, FreeBSD. +- **Features**: + - Add, view, edit, delete, and search notes. + - Export and import notes in JSON format. + - Full compatibility with DOXA Notes (shared JSON format). + - Tag and filter support. + +📖 [Read detailed documentation](doxa-cli/README.md) + +--- + +### 3. 🔐 [DOXA Secret](doxa-secret/) + +**Tool for encrypting and protecting secret messages** + +- **Description**: A minimalist tool for encrypting text messages using custom alphabets defined in JSON. Each character is converted into a unique 5-character code. +- **Philosophy**: Local encryption, no data sent to servers. Your secrets remain only on your device. +- **Technologies**: Go (Golang), Bubble Tea (TUI framework). +- **Platforms**: Linux, FreeBSD. +- **Features**: + - Custom encryption alphabets (JSON format). + - Support for multiple ciphers and switching between them. + - Automatic diacritic normalization (basic Latin only). + - Import and export of encrypted messages (TXT format). + - Bilingual interface (Czech/English). + +⚠️ **Important**: The application works only with basic Latin characters (no diacritics). Czech diacritics are automatically normalized (e.g., "ž" → "z", "á" → "a"). + +📖 [Read detailed documentation](doxa-secret/README.md) + +--- + +## 🔗 Common Features of All DOXA Projects + +| Feature | DOXA Notes | DOXA CLI | DOXA Secret | +|---------|------------|----------|--------------| +| **Local Data Storage** | ✅ | ✅ | ✅ | +| **Open Format (JSON)** | ✅ | ✅ | ✅ | +| **No Cloud Dependencies** | ✅ | ✅ | ✅ | +| **Open Source (MIT)** | ✅ | ✅ | ✅ | +| **Minimalist Design** | ✅ | ✅ | ✅ | +| **Tag Support** | ✅ | ✅ | ❌ | +| **Search and Filtering** | ✅ | ✅ | ❌ | +| **Encryption** | ❌ | ❌ | ✅ | + +--- + +## 🛠 Installation + +Each project has its own installation process. Detailed guides can be found in the respective README files: + +- [DOXA Notes – Installation](doxa-notes/03_install.md) +- [DOXA CLI – Installation](doxa-cli/README.md#installation) +- [DOXA Secret – Installation](doxa-secret/README_EN.md#installation) + +--- + +## 📜 License + +All projects in the DOXA collection are **open-source** and licensed under the **MIT License**. See the `LICENSE` files in each project for details. + +--- + +## 💡 DOXA Philosophy + +> "No matter how complex the circumstances around you are, when you build your own temple of ideas, you start from the first stone. This code is your first stone." +> — Stoic reference from Kankys + +DOXA believes in: +- **Digital Sovereignty**: Your data belongs to you. +- **Minimalism**: Less is more. Clean code, clear mind. +- **Local-First**: No cloud dependencies, no tracking. +- **Openness**: Open code, open data, open mind. + +--- + +## 📞 Contact and Support + +- **Author**: Kankys +- **Repositories**: + - [DOXA on Codeberg](https://codeberg.org/Kankys/doxa) + + +--- + +--- + +# 🇨🇿 DOXA (CZ) + +

+ English | + Čeština +

+ +--- + +## 🌍 DOXA + +**DOXA** je sbírka tří minimalistických, lokálně orientovaných aplikací pro správu poznámek, šifrování zpráv a práci s textem z příkazové řádky. Všechny projekty sdílejí společnou filozofii: **úplná nezávislost, soukromí a kontrola nad vašimi daty**. Žádné cloudové služby, žádné sledování, žádné externí závislosti. Vaše data patří pouze vám. + +--- + +## 📌 Projekty v kolekci DOXA + +### 1. 📝 [DOXA Notes](doxa-notes/) + +**Webová a desktopová aplikace pro správu poznámek** + +- **Popis**: Minimalistická poznámková aplikace postavená na čistých webových standardech (HTML5, CSS3, Vanilla JavaScript). Umožňuje vytvářet, upravovat, organizovat a exportovat poznámky v otevřeném JSON formátu. +- **Filozofie**: Local-first, žádné cloudové databáze, žádné sledování. Data se ukládají v prohlížeči (LocalStorage/IndexedDB) nebo v lokálních souborech. +- **Technologie**: Vanilla JavaScript (ES6+), HTML5, CSS3, JSON. +- **Platformy**: Web (prohlížeč), Linux (AppImage). +- **Vlastnosti**: + - Podpora tagů pro organizaci poznámek. + - Automatické ukládání (autosave) a manuální export/import JSON. + - Tmavý/světlý režim a systémové nastavení. + - Drag & drop pro přeskupování poznámek. + +📖 [Přečtěte si podrobnější dokumentaci](doxa-notes/README.md) + +--- + +### 2. 💻 [DOXA CLI](doxa-cli/) + +**Terminálová aplikace pro správu poznámek** + +- **Popis**: Příkazová řádka (CLI) verze DOXA Notes. Napsána v jazyce Go, nabízí moderní terminálové uživatelské rozhraní (TUI) pro správu poznámek přímo z terminálu. +- **Filozofie**: Stejná filozofie jako DOXA Notes – plně lokální, žádné externí závislosti, data v JSON formátu. +- **Technologie**: Go (Golang), Bubble Tea (TUI framework). +- **Platformy**: Linux, FreeBSD. +- **Vlastnosti**: + - Přidávání, prohlížení, úprava, mazání a vyhledávání poznámek. + - Export a import poznámek v JSON formátu. + - Plná kompatibilita s DOXA Notes (sdílený JSON formát). + - Podpora tagů a filtrování. + +📖 [Přečtěte si podrobnější dokumentaci](doxa-cli/README_CZ.md) + +--- + +### 3. 🔐 [DOXA Secret](doxa-secret/) + +**Nástroj pro šifrování a ochranu tajných zpráv** + +- **Popis**: Minimalistický nástroj pro šifrování textových zpráv pomocí vlastních abeced definovaných v JSON. Každý znak je převeden na unikátní 5znakový kód. +- **Filozofie**: Lokální šifrování, žádné odesílání dat na servery. Vaše tajemství zůstávají pouze na vašem zařízení. +- **Technologie**: Go (Golang), Bubble Tea (TUI framework). +- **Platformy**: Linux, FreeBSD. +- **Vlastnosti**: + - Vlastní šifrovací abecedy (JSON formát). + - Podpora více šifer a přepínání mezi nimi. + - Automatická normalizace diakritiky (pouze základní latinka). + - Import a export šifrovaných zpráv (TXT formát). + - Dvoujazyčné rozhraní (česky/anglicky). + +⚠️ **Důležité**: Aplikace pracuje pouze se znaky základní latinky (bez diakritiky). Česká diakritika je automaticky normalizována (např. "ž" → "z", "á" → "a"). + +📖 [Přečtěte si podrobnější dokumentaci](doxa-secret/README.md) + +--- + +## 🔗 Společné vlastnosti všech projektů DOXA + +| Vlastnost | DOXA Notes | DOXA CLI | DOXA Secret | +|-----------|------------|----------|--------------| +| **Lokální uložení dat** | ✅ | ✅ | ✅ | +| **Otevřený formát (JSON)** | ✅ | ✅ | ✅ | +| **Žádné cloudové závislosti** | ✅ | ✅ | ✅ | +| **Open Source (MIT)** | ✅ | ✅ | ✅ | +| **Minimalistický design** | ✅ | ✅ | ✅ | +| **Podpora tagů** | ✅ | ✅ | ❌ | +| **Vyhledávání a filtrování** | ✅ | ✅ | ❌ | +| **Šifrování** | ❌ | ❌ | ✅ | + +--- + +## 🛠 Instalace + +Každý projekt má vlastní instalační postup. Podrobné návody naleznete v příslušných README souborech: + +- [DOXA Notes – Instalace](doxa-notes/03_install.md) +- [DOXA CLI – Instalace](doxa-cli/README_CZ.md#instalace) +- [DOXA Secret – Instalace](doxa-secret/README.md#instalace) + +--- + +## 📜 Licence + +Všechny projekty v kolekci DOXA jsou **open-source** a licencovány pod **MIT licencí**. Podrobnosti naleznete v souborech `LICENSE` v jednotlivých projektech. + +--- + +## 💡 Filozofie DOXA + +> "Nezáleží na tom, jak složité jsou okolnosti kolem tebe. Když stavíš vlastní chrám myšlenek, začínáš od prvního kamene. Tento kód je tvým prvním kamenem." +> — Stoický odkaz od Kankyse + +DOXA věří v: +- **Digitální suverenitu**: Vaše data patří vám. +- **Minimalismus**: Méně je více. Čistý kód, čistá mysl. +- **Lokální první**: Žádné cloudové závislosti, žádné sledování. +- **Otevřenost**: Otevřený kód, otevřená data, otevřená mysl. + +--- + +## 📞 Kontakt a podpora + +- **Autor**: Kankys +- **Repozitáře**: + - [DOXA na Codeberg](https://codeberg.org/Kankys/doxa) \ No newline at end of file diff --git a/doxa-cli/About.md b/doxa-cli/About.md new file mode 100644 index 0000000..b69ca57 --- /dev/null +++ b/doxa-cli/About.md @@ -0,0 +1,46 @@ +# **🇬🇧 DOXA-CLI PROJECT** + +##### **🇨🇿 [Czech Version](About_CZ.md)** + +#### **Technical and architectural manifesto of a minimalist terminal-based note-taking application** + +**Project goal:** To create a companion to the web-based [DOXA Notes](https://doxa-notes.org/), bringing the exact same philosophy into the focused environment of the command line. Built with the Go language, DOXA-CLI operates entirely locally, utilizing the identical open JSON data standard without relying on external clouds or complex frameworks. + +## **1\. TECHNICAL ARCHITECTURE** + +To maintain maximum speed, raw performance, and absolute minimalism, DOXA-CLI is built on solid foundations: +Language: Pure Go (Golang) ensuring native compilation, high execution speed, and zero heavy runtime dependencies. +Interface: Terminal User Interface (CLI) designed to keep the mind free from graphical clutter and focused purely on text. +Data layer: Fully compatible JSON format shared with the web version. Notes contain unique timestamps, identifiers, content, tags. + +## **2\. DATA FORMAT STRUCTURE (JSON)** + +Ensuring seamless interoperability with the web version, DOXA-CLI reads and writes data using the standard shared schema: + +JSON +\[ + { + "id": + "name": " ", + "content": " ", + "tags": \[ + " " + \], + "folder": " ", // unused/empty + "created\_at": " ", + "modified\_at": " " + } +\] + +## **3\. LOCAL EXECUTION & PHILOSOPHY** + +**Architecture (Purely local execution)** +**Technical storage solution** \- Data resides directly on your local disk in a standardized JSON file (doxa\_notes.json), giving you absolute control with zero network latency. +**Security aspect** \- Total self-reliance. Your thoughts remain entirely on your machine. + +## **License** + +The application is open-source and licensed under the MIT license. +\-- +"The terminal asks for nothing, distracts by nothing, and offers total control. Bring order to your thoughts through pure code." — Stoic reference from Kankys + diff --git a/doxa-cli/About_CZ.md b/doxa-cli/About_CZ.md new file mode 100644 index 0000000..c4338c5 --- /dev/null +++ b/doxa-cli/About_CZ.md @@ -0,0 +1,43 @@ +# **🇨🇿 PROJEKT DOXA-CLI** + +#### **Technický a architektonický manifest minimalistické terminálové poznámkové aplikace** + +**Záměr projektu:** Vytvořit věrnou sestru webové verze [DOXA Notes](https://doxa-notes.org/), která přenáší stejnou myšlenku do soustředěného prostředí příkazové řádky. Aplikace je napsaná v jazyce Go, funguje zcela lokálně a sdílí identický otevřený formát JSON bez závislosti na cloudu či složitých knihovnách. + +## **1\. TECHNICKÁ ARCHITEKTURA** + +Pro zachování maximální rychlosti, surového výkonu a absolutního minimalismu je DOXA-CLI postavena na pevných základech: +Jazyk: Čisté Go (Golang), které zaručuje nativní kompilaci, vysokou rychlost provedení a žádné zbytečné externí závislosti. +Rozhraní: Terminálové rozhraní (CLI), které zbavuje mysl grafického chaosu a nechává vyniknout čistému textu. +Datová vrstva: Plně kompatibilní formát JSON sdílený s webovou verzí. Poznámky obsahují přesná časová razítka, identifikátory, obsah, štítky. + +## **2\. STRUKTURA DATOVÉHO FORMÁTU (JSON)** + +Pro zajištění dokonalé propojenosti s webovou verzí čte a zapisuje DOXA-CLI data ve stejném sdíleném schématu: + +JSON +\[ + { + "id": + "name": " ", + "content": " ", + "tags": \[ + " " + \], + "folder": " ", // nepoužito/prázdné + "created\_at": " ", + "modified\_at": " " + } +\] + +## **3\. LOKÁLNÍ SPUŠTĚNÍ A FILOZOFIE** + +**Architektura (Čistě lokální běh)** +**Technické řešení úložiště** \- Data sídlí přímo na tvém lokálním disku ve standardizovaném souboru JSON (doxa\_notes.json), což ti dává absolutní kontrolu bez jakékoliv závislosti na síti. +**Bezpečnostní aspekt** \- Úplná soběstačnost. Tvoje myšlenky zůstávají pevně na tvém stroji. + +## **Licence** + +Aplikace je open-source a licencována pod MIT licencí. +\-- +"Terminál nežádá nic, neodvádí pozornost ničím a nabízí úplnou kontrolu. Vnes řád do svých myšlenek skrze čistý kód." \ No newline at end of file diff --git a/doxa-cli/LICENSE b/doxa-cli/LICENSE new file mode 100644 index 0000000..28192f8 --- /dev/null +++ b/doxa-cli/LICENSE @@ -0,0 +1,18 @@ +MIT License + +Copyright (c) 2026 Kankys + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/doxa-cli/MANUAL.md b/doxa-cli/MANUAL.md new file mode 100644 index 0000000..be31f64 --- /dev/null +++ b/doxa-cli/MANUAL.md @@ -0,0 +1,223 @@ +# 🦅 USER MANUAL (DOXA-CLI) + +**DOXA-CLI** is a minimalist, local-first command-line notes management tool. It is designed to bring the same philosophy of focus and utility from the web-based [DOXA Notes](https://doxa-notes.org/) into your terminal, utilizing the exact same open JSON data standard without relying on external clouds. Written in **Go**, it offers a modern Terminal User Interface (**TUI**) built with Charm's Bubble Tea and Lip Gloss. + +

+ Go 1.22+ + MIT license + Tested on Linux +

+

+ freeBSD +

+ + +--- + +## TABLE OF CONTENTS +1. [Installation & Execution](#1-installation--execution) +2. [Storage Architecture & Schema](#2-storage-architecture--schema) +3. [Interactive Interface & States](#3-interactive-interface--states) +4. [Keyboard Shortcuts Reference](#4-keyboard-shortcuts-reference) +5. [Export System Details](#5-export-system-details) +6. [Uninstallation](#6-uninstallation) + +--- + +## 1. INSTALLATION & EXECUTION + +### Prerequisites +Before installing, make sure you have **Go** installed on your system (version **1.20** or higher is recommended). + +### Installation Steps (Linux / macOS) +1. **Clone the repository:** + ```bash + git clone https://codeberg.org/Kankys/doxa-cli.git + cd doxa-cli + ``` +2. **Run the installation script:** + ```bash + chmod +x install.sh + ./install.sh + ``` + *The script checks your Go installation, downloads all Go modules, compiles the binary, installs the executable `doxa-cli` to `~/.local/bin/`, and prepares an empty JSON database file at `~/.doxa-cli/doxa_notes.json`.* + +3. **Add to PATH (if necessary):** + If the `doxa-cli` command is not recognized, add the following line to your shell profile (e.g., `~/.bashrc` or `~/.zshrc`): + ```bash + export PATH=$PATH:$HOME/.local/bin + ``` + Then restart your terminal or reload your profile using `source ~/.bashrc`. + +### Post-Installation Cleanup +Once completed, you can safely remove the cloned repository directory: +```bash +rm -rf doxa-cli +``` + +# **Operation and installation of doxa-cli on FreeBSD** + +Building the application for FreeBSD does not always work correctly, if the instructions below do not help you, you can run it directly from the repository. And in .bashrc, make an alias for `doxa-cli`. You can run the application from the repository directly from the directory where it is cloned with the command `go run .`. + +The FreeBSD system has its own specifics - it uses different default shells, kernel module management and interpreter paths than Linux. For a problem-free operation of the application, proceed as follows: + +## **1\. Editing the installation script (install.sh)** + +Before running the installation, it is necessary to check the header (shebang) of the install.sh script, because FreeBSD strictly requires the correct path to the command interpreter: + +> * Open install.sh and make sure that the first line refers to the universal path, not hard-coded to the Linux bash: +```bash +\#\!/usr/bin/env bash +``` + +## **2\. Running the installation** + +Standard cloning and running procedure: + +```bash +git clone https://codeberg.org/Kankys/doxa-cli.git +cd doxa-cli +chmod \+x install.sh +./install.sh +rm \-rf doxa-cli +``` +*The script will automatically compile the application and place the binary file in the \~/.local/bin/ directory.* + +## **3\. Setting the PATH environment variable for FreeBSD (sh shell)** + +FreeBSD uses /bin/sh as the default shell, which does not support the source command. To permanently and immediately enable the doxa-cli command, follow these steps: + +> 1. **Add the path to the profile:** +```bash +echo 'export PATH="$PATH:$HOME/.local/bin"' \>\> \~/.profile +``` +> 2. **Load the changes into the current terminal (using a dot, not the source command):** +```bash +. ~/.profile +``` + +--- + +## 2. STORAGE ARCHITECTURE & SCHEMA + +The application runs **strictly locally**, keeping all your ideas entirely on your machine. + +- **Storage Location:** `~/.doxa-cli/doxa_notes.json` (falls back to a local `doxa_notes.json` in the current working directory if the user home directory cannot be resolved). +- **Backups:** To backup your notes, simply copy `doxa_notes.json` to a backup location regularly. + +### JSON Data Structure +Notes are written using a standardized JSON schema, ensuring perfect interoperability with the DOXA web client: +```json +[ + { + "id": 1722240000000, + "name": "My Note", + "content": "Note content with support for multi-line strings.", + "tags": ["personal", "work"], + "folder": "", // unused/empty + "created_at": "2026-07-29T14:30:00Z", + "modified_at": "2026-07-29T14:35:00Z" + } +] +``` + +--- + +## 3. INTERACTIVE INTERFACE & STATES + +The application automatically scales and adjusts to your active terminal window size: + +### A. Notes List (Main View) (`StateViewNotes`) +The dashboard displays your list of notes. +- Scroll through notes using the arrow keys or `j`/`k`. +- The selected note expands to display its full content, ID, and tags. +- The bottom bar contains available key shortcuts and a colored status bar showing operation confirmations. + +### B. Add / Edit Note Forms (`StateAddNote` / `StateEditNote`) +An interactive form with three inputs: +1. **Name:** (Required) Name of the note. +2. **Content:** (Required) Large multi-line text input. +3. **Tags:** (Optional) Comma-separated list of tags. + +*Use the `Tab` or `Shift+Tab` keys to traverse between form inputs.* + +### C. Search Field (`StateSearch`) +Allows you to perform a case-insensitive full-text filter on the notes database. Matches are evaluated across names, contents, and tags. + +### D. Browse Tags Screen (`StateBrowse`) +A specialized menu that displays a unique collection of all tags currently in use. +- Press `t` to list all tags. +- Select an item and press `Enter` to filter the main note list by your choice. + +### E. Delete Confirmation Dialogue (`StateConfirmDelete`) +A safety box showcasing the name and a snippet of the note selected for deletion, requiring a strict `y` (Yes) or `n` (No) keypress to prevent accidental loss of data. + +--- + +## 4. KEYBOARD SHORTCUTS REFERENCE + +### Global Commands +| Key | Action | +| :--- | :--- | +| `ctrl + c` | Instantly exit the application from any screen | +| `q` / `esc` | Go back to the previous screen / Cancel current action / Quit application (from the main view) | + +### Notes List (Main View) Commands (`StateViewNotes`) +| Key | Action | +| :--- | :--- | +| `↑` / `k` | Move selection up | +| `↓` / `j` | Move selection down | +| `1` | Create a new note | +| `2` / `Enter` | Edit the selected note | +| `3` | Export the selected note to a raw text file | +| `4` | Delete the selected note (requires confirmation) | +| `/` | Start searching | +| `b` | Browse by Tag | +| `l` | Toggle user interface language (CS <=> EN) | + +### Form Inputs (Add / Edit Note) +| Key | Action | +| :--- | :--- | +| `Tab` | Move cursor focus to the next field (Name -> Content -> Tags -> Name...) | +| `Shift + Tab` | Move cursor focus to the previous field | +| `Enter` | **Inside Content field:** Inserts a new line (carriage return).
**Inside any other field:** Saves/submits the form. | + +### Browse Mode (`StateBrowse`) +| Key | Action | +| :--- | :--- | +| `t` | Display **Tags** list | +| `↑` / `k` / `↓` / `j` | Scroll through the items | +| `Enter` | Filter main note list by the selected tag | + +--- + +## 5. EXPORT SYSTEM DETAILS + +Pressing key `3` on a note in the main list outputs its contents to a plain `.txt` file: + +- **Export Directory:** `~/doxa-cli-txt/` (automatically created). +- **Output Filename:** `_.txt` (spaces are automatically escaped into underscores). +- **Exported File Schema:** + *(Note: The exported header fields are written using Czech labels as hardcoded in the Go export engine).* + ```text + Název: + Tagy: + Vytvořeno: YYYY-MM-DD HH:MM + + + ``` + +--- + +## 6. UNINSTALLATION + +To fully uninstall DOXA-CLI from your machine: + +1. **Remove the executable binary:** + ```bash + rm ~/.local/bin/doxa-cli + ``` +2. **Remove the configuration and local database (Warning: This will delete all of your notes!):** + ```bash + rm -rf ~/.doxa-cli + ``` diff --git a/doxa-cli/MANUAL_CZ.md b/doxa-cli/MANUAL_CZ.md new file mode 100644 index 0000000..505f44a --- /dev/null +++ b/doxa-cli/MANUAL_CZ.md @@ -0,0 +1,224 @@ +# 🦅 NÁVOD K POUŽITÍ (DOXA-CLI) + +**DOXA-CLI** je minimalistický, lokálně orientovaný nástroj pro správu poznámek z příkazové řádky. Slouží jako přímý ekvivalent k webové verzi [DOXA Notes](https://doxa-notes.org/), se kterou sdílí filozofii soustředění a identický datový formát JSON. Aplikace je napsaná v jazyce **Go** a využívá moderní terminálové rozhraní (**TUI**) postavené na knihovnách Bubble Tea a Lip Gloss od Charm. + +

+ Go 1.22+ + MIT license + Tested on Linux +

+

+ freeBSD +

+ +--- + +## OBSAH +1. [Instalace a spuštění](#1-instalace-a-spuštění) +2. [Chování a struktura úložiště](#2-chování-a-struktura-úložiště) +3. [Uživatelské rozhraní a stavy](#3-uživatelské-rozhraní-a-stavy) +4. [Klávesové zkratky a ovládání](#4-klávesové-zkratky-a-ovládání) +5. [Detaily o exportu](#5-detaily-o-exportu) +6. [Odinstalace](#6-odinstalace) + +--- + +## 1. INSTALACE A SPUŠTĚNÍ + +### Systémové předpoklady +Před instalací je nutné mít na systému nainstalované vývojové prostředí **Go** (verze **1.20** nebo vyšší). + +### Postup instalace (Linux / macOS) +1. **Stažení repozitáře:** + ```bash + git clone https://codeberg.org/Kankys/doxa-cli.git + cd doxa-cli + ``` +2. **Spuštění instalačního skriptu:** + ```bash + chmod +x install.sh + ./install.sh + ``` + *Instalační skript automaticky stáhne závislosti Go, zkompiluje aplikaci, přesune binární soubor `doxa-cli` do adresáře `~/.local/bin/` a vytvoří výchozí prázdnou databázi v `~/.doxa-cli/doxa_notes.json`.* + +3. **Přidání do PATH (pokud je potřeba):** + Pokud po instalaci nelze příkaz `doxa-cli` spustit, přidejte do svého profilu (např. `~/.bashrc` nebo `~/.zshrc`) následující řádek: + ```bash + export PATH=$PATH:$HOME/.local/bin + ``` + Následně restartujte terminál nebo načtěte změny pomocí `source ~/.bashrc`. + +### Úklid po instalaci +Jakmile skript doběhne, složku s klonovaným repozitářem můžete bezpečně odstranit: +```bash +rm -rf doxa-cli +``` + + + +# **Provoz a instalace doxa-cli na FreeBSD** + +Build aplikace pro FreeBSD nefunguje vždy korektně, pokud vám nepomůže návod níže je možné ji spouštět přímo z repozitáře. A v .bashrc si udělat alias pro `doxa-cli`. Alikaci z repozitáře spustíte přímo z adresáře, kde je klonován příkazem `go run .`. + +Systém FreeBSD má svá specifika – používá odlišné výchozí shelly, správu modulů jádra a cesty k interpretům než Linux. Pro bezproblémový chod aplikace postupuj následovně: + +## **1\. Úprava instalačního skriptu (install.sh)** + +Před spuštěním instalace je nutné zkontrolovat hlavičku (shebang) skriptu install.sh, protože FreeBSD striktně vyžaduje správnou cestu k interpretu příkazů: + +> * Otevři install.sh a ujisti se, že první řádek odkazuje na univerzální cestu, nikoli natvrdo na linuxový bash: +```bash +\#\!/usr/bin/env bash +``` + +## **2\. Spuštění instalace** + +Standardní postup klonování a spuštění: + +```bash +git clone https://codeberg.org/Kankys/doxa-cli.git +cd doxa-cli +chmod \+x install.sh +./install.sh +rm \-rf doxa-cli +``` +*Skript automaticky zkompiluje aplikaci a umístí binární soubor do adresáře \~/.local/bin/.* + +## **3\. Nastavení proměnné prostředí PATH pro FreeBSD (shell sh)** + +FreeBSD používá ve výchozím stavu jako standardní shell /bin/sh, který nepodporuje příkaz source. Pro trvalé i okamžité zprístupnění příkazu doxa-cli proveď tyto kroky: + +> 1. **Přidej cestu do profilu:** + ```bash + echo 'export PATH="$PATH:$HOME/.local/bin"' \>\> \~/.profile + ``` +> 2. **Načti změny v aktuálním terminálu (pomocí tečky, nikoliv příkazu source):** + ```bash + . ~/.profile + ``` + + +--- + +## 2. CHOVÁNÍ A STRUKTURA ÚLOŽIŠTĚ + +Aplikace funguje **zcela offline** a data ukládá na váš lokální disk. + +- **Umístění databáze:** `~/.doxa-cli/doxa_notes.json` (na systémech, kde nelze detekovat domovský adresář, se vytvoří `doxa_notes.json` v aktuálním pracovním adresáři). +- **Záloha:** Pro zálohu stačí zkopírovat soubor `doxa_notes.json` na bezpečné místo. + +### Formát dat (JSON) +Každá poznámka v JSON poli obsahuje následující strukturu kompatibilní s webovou verzí DOXA Notes: +```json +[ + { + "id": 1722240000000, + "name": "Moje Poznámka", + "content": "Obsah poznámky s podporou více řádků.", + "tags": ["osobní", "práce"], + "folder": "", // nepoužito/prázdné + "created_at": "2026-07-29T14:30:00Z", + "modified_at": "2026-07-29T14:35:00Z" + } +] +``` + +--- + +## 3. UŽIVATELSKÉ ROZHRANÍ A STAVY + +Aplikace se dynamicky přizpůsobuje velikosti terminálu a nabízí několik stavů: + +### A. Hlavní seznam poznámek (`StateViewNotes`) +Zde vidíte přehled všech uložených poznámek. +- Pomocí šipek vybíráte aktivní poznámku. +- U vybrané poznámky se zobrazí její kompletní obsah, ID a přiřazené tagy. +- Ve spodní části obrazovky se nachází menu rychlých akcí a stavový řádek (ukazuje potvrzení o uložení, úpravě či exportu). + +### B. Formulář pro Přidání / Úpravu poznámky (`StateAddNote` / `StateEditNote`) +Interaktivní rozhraní se 3 vstupními poli: +1. **Název:** (Povinné) Název vaší poznámky. +2. **Obsah:** (Povinné) Víceřádkové pole pro text poznámky. +3. **Tagy:** (Nepovinné) Štítky oddělené čárkou. + +*Pohyb mezi poli se provádí klávesou `Tab` (dopředu) nebo `Shift+Tab` (dozadu).* + +### C. Vyhledávání (`StateSearch`) +Umožňuje fulltextově filtrovat seznam poznámek. Vyhledává se shoda v názvu, obsahu i v jednotlivých tazích (velikost písmen se ignoruje). + +### D. Procházení Tagů (`StateBrowse`) +Umožňuje rychle vyfiltrovat poznámky na základě existujících tagů. +- Klávesou `t` zobrazíte seznam všech existujících tagů. +- Výběrem položky a stisknutím `Enter` aplikujete filtr na hlavní seznam poznámek. + +### E. Potvrzení smazání (`StateConfirmDelete`) +Bezpečnostní mezikrok, který zobrazí detail odstraňované poznámky a vyžaduje explicitní potvrzení stisknutím klávesy `y` (Ano) nebo `n` (Ne). + +--- + +## 4. KLÁVESOVÉ ZKRATKY A OVLÁDÁNÍ + +### Globální ovládání +| Klávesa | Akce | +| :--- | :--- | +| `ctrl + c` | Okamžité ukončení aplikace z jakéhokoliv stavu | +| `q` / `esc` | Návrat do předchozího stavu / Zrušení akce / Ukončení aplikace (z hlavního seznamu) | + +### Ovládání v Hlavním seznamu poznámek (`StateViewNotes`) +| Klávesa | Akce | +| :--- | :--- | +| `↑` / `k` | Posunout výběr nahoru | +| `↓` / `j` | Posunout výběr dolů | +| `1` | Přidat novou poznámku (otevře formulář) | +| `2` / `Enter` | Upravit vybranou poznámku (otevře formulář) | +| `3` | Exportovat vybranou poznámku | +| `4` | Smazat vybranou poznámku (otevře potvrzovací dialog) | +| `/` | Otevřít vyhledávání | +| `l` | Přepnout jazyk rozhraní (CS <=> EN) | + +### Ovládání ve formulářích (Přidání / Úprava) +| Klávesa | Akce | +| :--- | :--- | +| `Tab` | Přechod na další pole (Název -> Obsah -> Tagy -> Název...) | +| `Shift + Tab` | Přechod na předchozí pole | +| `Enter` | **Pokud jste v poli Obsah:** Vloží nový řádek.
**Pokud jste v jakémkoliv jiném poli:** Uloží poznámku. | + +### Ovládání v režimu Procházení (`StateBrowse`) +| Klávesa | Akce | +| :--- | :--- | +| `t` | Přepnout na seznam **Tagů** | +| `↑` / `k` / `↓` / `j` | Pohyb v seznamu | +| `Enter` | Filtrovat hlavní seznam podle vybrané tagu | + +--- + +## 5. DETAILY O EXPORTU + +Při stisknutí klávesy `3` na vybrané poznámce v hlavním seznamu dojde k exportu poznámky do čistého textového souboru. + +- **Adresář exportu:** `~/doxa-cli-txt/` (bude automaticky vytvořen v domovském adresáři). +- **Název exportovaného souboru:** `_.txt` (mezery v názvu jsou nahrazeny podtržítky). +- **Vnitřní struktura exportovaného souboru:** + *(Poznámka: Hlavička exportu je generována s českými popisky bez ohledu na zvolený jazyk rozhraní).* + ```text + Název: + Tagy: + Vytvořeno: RRRR-MM-DD HH:MM + + + ``` + +--- + +## 6. ODINSTALACE + +Pokud se rozhodnete aplikaci ze systému odstranit, postupujte takto: + +1. **Smazání spustitelného souboru:** + ```bash + rm ~/.local/bin/doxa-cli + ``` +2. **Smazání databáze a konfigurace (Upozornění: Smaže všechny vaše poznámky!):** + ```bash + rm -rf ~/.doxa-cli + ``` diff --git a/doxa-cli/README.md b/doxa-cli/README.md new file mode 100644 index 0000000..8f309d7 --- /dev/null +++ b/doxa-cli/README.md @@ -0,0 +1,91 @@ +DOXA-CLI + +DOXA-CLI is a command-line tool for managing your notes. It allows you to add, view, edit, delete, export notes, as well as filter and search them. The application is written in Go and offers a modern Terminal User Interface (TUI). + +

+ Go 1.22+ + MIT license + Tested on Linux +

+

+ freeBSD +

+ +## Prerequisites + +Before installing DOXA-CLI, it is assumed that you have **Go installed on your system. The recommended version is 1.20 or higher. +You can download Go from the official website: [https://go.dev/doc/install](https://go.dev/doc/install) + +![dashboard](screen/dashboard.png) + +## Installation + +To install DOXA-CLI on your system, follow these steps: + +1. **Clone the repository**: +Get the latest version of the code from Git: +``` bash +git clone https://codeberg.org/Kankys/doxa-cli.git +cd doxa-cli # Go to the project directory +``` + +2. **Run the installation script**: +``` bash +chmod +x install.sh +./install.sh +``` +The installation script will do the following: +* Check if you have Go installed. +* Download all necessary Go modules and project dependencies. +* Compile the application for your operating system. +* Install the `doxa-cli` executable file in the `$HOME/.local/bin/` directory. +* Creates the `~/doxa-cli` configuration directory and the `doxa_notes.json` file if they do not exist. + +3. **Add to PATH (if necessary)**: +After successful installation, you should be able to run `doxa-cli` from another location in the terminal. If the `doxa-cli` command is not recognized, it is assumed that the `$HOME/.local/bin` directory is not in your `PATH` system variable. + +You can fix this by adding the following line to your shell profile (e.g. `~/.bashrc` for Bash, `~/.zshrc` for Zsh, or `~/.profile` for other systems): +``` bash +export PATH=$PATH:$HOME/.local/bin +``` +After editing the profile file, **restart the terminal** or load the profile (e.g. `source ~/.bashrc`). + +## Post-installation cleanup + +Once the installation is successfully completed, the source files in the project directory are no longer needed. You can delete the entire folder with the cloned repository: + +``` bash +rm -rf doxa-cli +``` + +## Usage + +After successful installation, you can run the application from another directory by typing: +``` bash +doxa-cli +``` +For detailed control in the TUI interface, follow the help displayed directly in the application. + +## Backup + +To backup your notes, you must save the `doxa_notes.json` file from the `~/.doxa-cli` configuration directory anywhere in your backup directory. + +**Note**: The `doxa_notes.json` file contains all your notes and it is important to save it regularly. + +## Uninstall + +To uninstall DOXA-CLI, follow these steps: + +1. **Remove the executable**: +Remove the binary from your PATH: +``` bash +rm ~/.local/bin/doxa-cli +``` +*(If you installed the binary in a different directory, use its path.)* + +2. **Remove the configuration directory (optional)**: +If you want to remove all application data and configuration, the configuration directory: +``` bash +rm -rf ~/.doxa-cli +``` +**WARNING**: This step will delete ALL your notes. If you want to keep your data, skip this step. \ No newline at end of file diff --git a/doxa-cli/README_CZ.md b/doxa-cli/README_CZ.md new file mode 100644 index 0000000..bad52e6 --- /dev/null +++ b/doxa-cli/README_CZ.md @@ -0,0 +1,93 @@ +DOXA-CLI + +DOXA-CLI je nástroj pro správu vašich poznámek z příkazové řádky. Umožňuje přidávat, zobrazovat, upravovat, mazat, exportovat poznámky a také je filtrovat a vyhledávat. Aplikace je napsána v Go a nabízí moderní terminálové uživatelské rozhraní (TUI). + +

+ Go 1.22+ + MIT license + Tested on Linux +

+

+ freeBSD +

+ +## Předpoklady + +Před instalací DOXA-CLI se ujistěte, že máte na svém systému nainstalovaný **Go**. Doporučená verze je 1.20 nebo vyšší. +Stáhnout Go můžete z oficiálního webu: [https://go.dev/doc/install](https://go.dev/doc/install) + +![dashboard](screen/dashboard.png) + +## Instalace + +Pro instalaci DOXA-CLI na váš systém postupujte podle následujících kroků: + +1. **Naklonujte repozitář**: + Získejte nejnovější verzi kódu z Gitea: + ```bash + git clone https://codeberg.org/Kankys/doxa-cli.git + cd doxa-cli # Přejděte do adresáře projektu + ``` + +2. **Spusťte instalační skript**: + ```bash + chmod +x install.sh + ./install.sh + ``` + Instalační skript provede následující: + * Zkontroluje, zda máte nainstalované Go. + * Stáhne všechny potřebné Go moduly a závislosti projektu. + * Zkompiluje aplikaci pro váš operační systém. + * Nainstaluje spustitelný soubor `doxa-cli` do adresáře `$HOME/.local/bin/`. + * Vytvoří konfigurační adresář `~/.doxa-cli` a soubor `doxa_notes.json`, pokud neexistují. + +3. **Přidání do PATH (pokud je nutné)**: + Po úspěšné instalaci byste měli být schopni spustit `doxa-cli` z jakéhokoli místa v terminálu. Pokud příkaz `doxa-cli` není rozpoznán, je pravděpodobné, že adresář `$HOME/.local/bin` není ve vaší systémové proměnné `PATH`. + + Můžete to opravit přidáním následujícího řádku do vašeho shell profilu (např. `~/.bashrc` pro Bash, `~/.zshrc` pro Zsh, nebo `~/.profile` pro jiné systémy): + ```bash + export PATH=$PATH:$HOME/.local/bin + ``` + Po úpravě souboru profilu **restartujte terminál** nebo načtěte profil (např. `source ~/.bashrc`). + +## Úklid po instalaci + +Jakmile je instalace úspěšně dokončena, zdrojové soubory v adresáři projektu již nejsou potřeba. Celou složku s klonovaným repozitářem můžete smazat: + +```bash +rm -rf doxa-cli +``` + +## Použití + +Po úspěšné instalaci můžete aplikaci spustit z jakéhokoliv adresáře zadáním: +```bash +doxa-cli +``` +Pro detailní ovládání v TUI rozhraní se řiďte nápovědou zobrazovanou přímo v aplikaci. + +## Záloha + +Pro zálohu vašich poznámek je nutné si uložit soubor `doxa_notes.json` z konfiguračního adresáře `~/.doxa-cli` kamkoliv do vašeho záložního adresáře. + +**Poznámka**: Soubor `doxa_notes.json` obsahuje všechny vaše poznámky a je důležité si jej pravidelně uložit. + + + +## Odinstalace + +Pro odinstalaci DOXA-CLI postupujte takto: + +1. **Odstraňte spustitelný soubor**: + Odstraňte binárku aplikace z vašeho PATH: + ```bash + rm ~/.local/bin/doxa-cli + ``` + *(Pokud jste binárku nainstalovali do jiného adresáře, použijte jeho cestu.)* + +2. **Odstraňte konfigurační adresář (volitelné)**: + Pokud chcete odstranit i veškerá data a konfiguraci aplikace, odstraňte konfigurační adresář: + ```bash + rm -rf ~/.doxa-cli + ``` + **UPOZORNĚNÍ**: Tento krok smaže VŠECHNY vaše poznámky. Pokud si chcete data ponechat, tento krok vynechejte. \ No newline at end of file diff --git a/doxa-cli/Screen.md b/doxa-cli/Screen.md new file mode 100644 index 0000000..93fafe0 --- /dev/null +++ b/doxa-cli/Screen.md @@ -0,0 +1,15 @@ +![install](screen/install.png) + +![dashboard](screen/dashboard.png) + +![home](screen/home.png) + +![new-note](screen/new-note.png) + +![add-note](screen/add-note.png) + +![delete-note](screen/delete.png) + +![search](screen/search.png) + +![tags](screen/tags.png) diff --git a/doxa-cli/Support.md b/doxa-cli/Support.md new file mode 100644 index 0000000..2baf5d5 --- /dev/null +++ b/doxa-cli/Support.md @@ -0,0 +1,9 @@ +### 🇬🇧 If you want to support this project or my future ones, I would be very grateful. All support goes towards my education or directly to the infrastructure as payments for VPS or payments for development-related services. + + + +#### 🇨🇿 Pokud chcete podpořit tento projekt, nebo mé dálší budu vám velmi vděčný. Veškerá podpora jde na má vzdělání nebo přímo do ifrastruktury jako platby za VPS či platby za služby spojené s vývojem. + +--- + +![podpora](screen/podpora.png) \ No newline at end of file diff --git a/doxa-cli/go.mod b/doxa-cli/go.mod new file mode 100644 index 0000000..1d6d0d2 --- /dev/null +++ b/doxa-cli/go.mod @@ -0,0 +1,30 @@ +module doxa-cli + +go 1.26.5 + +require ( + github.com/atotto/clipboard v0.1.4 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/bubbles v1.0.0 // indirect + github.com/charmbracelet/bubbletea v1.3.10 // indirect + github.com/charmbracelet/colorprofile v0.4.1 // indirect + github.com/charmbracelet/lipgloss v1.1.0 // indirect + github.com/charmbracelet/x/ansi v0.11.6 // indirect + github.com/charmbracelet/x/cellbuf v0.0.15 // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect + github.com/clipperhouse/displaywidth v0.9.0 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.5.0 // indirect + github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect + github.com/lucasb-eyer/go-colorful v1.3.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/termenv v0.16.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.3.8 // indirect +) diff --git a/doxa-cli/go.sum b/doxa-cli/go.sum new file mode 100644 index 0000000..48170d0 --- /dev/null +++ b/doxa-cli/go.sum @@ -0,0 +1,65 @@ +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc= +github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= +github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= +github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= +github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= +github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= +github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= +github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= +github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= +github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= +github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= +github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= +github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= +github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= +github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= +github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA= +github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U= +github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= diff --git a/doxa-cli/install.sh b/doxa-cli/install.sh new file mode 100755 index 0000000..9ff69e8 --- /dev/null +++ b/doxa-cli/install.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +# DOXA-CLI Installation Script + +# --- Nastavení --- + +APP_NAME="doxa-cli" +INSTALL_DIR="$HOME/.local/bin" +CONFIG_DIR="$HOME/.doxa-cli" +CONFIG_FILE="doxa_notes.json" + +# --- Funkce --- + +error_exit() { + echo -e "\033[1;31mERROR: $1\033[0m" >&2 + exit 1 +} + +success_message() { + echo -e "\033[1;32mSUCCESS: $1\033[0m" +} + +info_message() { + echo -e "\033[1;34mINFO: $1\033[0m" +} + +# --- Hlavní část skriptu --- + +info_message "Kontrola Go instalace..." +if ! command -v go &> /dev/null +then + error_exit "Go není nainstalováno. Prosím, nainstalujte Go před spuštěním tohoto skriptu." +fi +success_message "Go je nainstalováno." + +info_message "Stažení závislostí projektu..." +if ! go mod download +then + error_exit "Nepodařilo se stáhnout závislosti Go. Zkontrolujte GO moduly a připojení k internetu." +fi +success_message "Závislosti projektu úspěšně staženy." + +info_message "Kompilace aplikace..." +APP_BINARY="$APP_NAME" +if ! go build -o "$APP_BINARY" . +then + error_exit "Nepodařilo se zkompilovat aplikaci. Zkontrolujte chyby v kódu." +fi +success_message "Aplikace úspěšně zkompilována do './$APP_BINARY'." + +info_message "Instalace aplikace..." + +if ! mkdir -p "$INSTALL_DIR" +then + error_exit "Nepodařilo se vytvořit cílový adresář '$INSTALL_DIR'. Zkontrolujte oprávnění." +fi + +if ! cp "$APP_BINARY" "$INSTALL_DIR/" +then + error_exit "Nepodařilo se zkopírovat binárku do '$INSTALL_DIR'. Zkontrolujte oprávnění." +fi + +chmod +x "$INSTALL_DIR/$APP_NAME" +success_message "Aplikace '$APP_NAME' úspěšně nainstalována do '$INSTALL_DIR'." + +info_message "Nastavení konfiguračního adresáře..." + +if ! mkdir -p "$CONFIG_DIR" +then + error_exit "Nepodařilo se vytvořit konfigurační adresář '$CONFIG_DIR'. Zkontrolujte oprávnění." +fi + +if [ ! -f "$CONFIG_DIR/$CONFIG_FILE" ] +then + echo "[]" > "$CONFIG_DIR/$CONFIG_FILE" + if [ $? -ne 0 ] + then + error_exit "Nepodařilo se vytvořit konfigurační soubor '$CONFIG_DIR/$CONFIG_FILE'." + fi + success_message "Konfigurační soubor '$CONFIG_DIR/$CONFIG_FILE' vytvořen." +else + info_message "Konfigurační soubor '$CONFIG_DIR/$CONFIG_FILE' již existuje." +fi + +info_message "Instalace dokončena." +success_message "Nyní můžete spustit aplikaci '$APP_NAME' z jakéhokoli místa v terminálu." +echo "" +echo -e "\033[1;33mPRO TIP:\nPokud \`$APP_NAME\` nefunguje z jakéhokoli místa, možná budete muset přidat '$INSTALL_DIR' do vašeho PATH.\nČasto se to dělá přidáním následujícího řádku do vašich shell profilů (~/.bashrc, ~/.zshrc, ~/.profile):\n\nexport PATH=\$PATH:$INSTALL_DIR\n\nPoté restartujte terminál nebo načtěte profil (např. \`source ~/.bashrc\`).\033[0m" +echo "" + +# Vyčištění +rm "$APP_BINARY" + +exit 0 \ No newline at end of file diff --git a/doxa-cli/main.go b/doxa-cli/main.go new file mode 100644 index 0000000..f9ca273 --- /dev/null +++ b/doxa-cli/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "os" + + tea "github.com/charmbracelet/bubbletea" +) + +func main() { + // Inicializace Bubble Tea modelu pomocí NewModel() z tui.go + m := NewModel() + + // Spuštění Bubble Tea programu + p := tea.NewProgram(m) + if _, err := p.Run(); err != nil { + fmt.Printf("Chyba při spuštění programu: %v\n", err) + os.Exit(1) + } +} diff --git a/doxa-cli/main_test.go b/doxa-cli/main_test.go new file mode 100644 index 0000000..9a622f4 --- /dev/null +++ b/doxa-cli/main_test.go @@ -0,0 +1,12 @@ +package main + +import "testing" + +func TestTruncate(t *testing.T) { + result := truncate("Ahoj světe", 5) + expected := "Ahoj..." + + if result != expected { + t.Errorf("Očekáváno %q, ale dostali jsme %q", expected, result) + } +} \ No newline at end of file diff --git a/doxa-cli/notes.go b/doxa-cli/notes.go new file mode 100644 index 0000000..f6fe8f7 --- /dev/null +++ b/doxa-cli/notes.go @@ -0,0 +1,55 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "time" +) + +type Note struct { + ID int64 `json:"id"` + Name string `json:"name"` + Content string `json:"content"` + Tags []string `json:"tags"` + Folder string `json:"folder"` + CreatedAt time.Time `json:"created_at"` + ModifiedAt time.Time `json:"modified_at"` +} + +func getStoragePath() string { + home, err := os.UserHomeDir() + if err != nil { + return "doxa_notes.json" // fallback do aktuálního adresáře + } + configDir := filepath.Join(home, ".doxa-cli") + + // Vytvoření složky, pokud neexistuje + if _, err := os.Stat(configDir); os.IsNotExist(err) { + os.MkdirAll(configDir, 0755) + } + + return filepath.Join(configDir, "doxa_notes.json") +} + +func loadNotes() []Note { + path := getStoragePath() + file, err := os.ReadFile(path) + if err != nil { + return []Note{} + } + var notes []Note + json.Unmarshal(file, ¬es) + return notes +} + +func saveNotes(notes []Note) { + path := getStoragePath() + data, err := json.MarshalIndent(notes, "", " ") + if err != nil { + fmt.Println("Chyba při ukládání dat:", err) + return + } + os.WriteFile(path, data, 0644) +} \ No newline at end of file diff --git a/doxa-cli/screen/add-note.png b/doxa-cli/screen/add-note.png new file mode 100644 index 0000000..c7b68fa Binary files /dev/null and b/doxa-cli/screen/add-note.png differ diff --git a/doxa-cli/screen/dashboard.png b/doxa-cli/screen/dashboard.png new file mode 100644 index 0000000..04629a7 Binary files /dev/null and b/doxa-cli/screen/dashboard.png differ diff --git a/doxa-cli/screen/delete.png b/doxa-cli/screen/delete.png new file mode 100644 index 0000000..2086bf0 Binary files /dev/null and b/doxa-cli/screen/delete.png differ diff --git a/doxa-cli/screen/home.png b/doxa-cli/screen/home.png new file mode 100644 index 0000000..e5048b3 Binary files /dev/null and b/doxa-cli/screen/home.png differ diff --git a/doxa-cli/screen/install.png b/doxa-cli/screen/install.png new file mode 100644 index 0000000..78480a2 Binary files /dev/null and b/doxa-cli/screen/install.png differ diff --git a/doxa-cli/screen/new-note.png b/doxa-cli/screen/new-note.png new file mode 100644 index 0000000..84beaed Binary files /dev/null and b/doxa-cli/screen/new-note.png differ diff --git a/doxa-cli/screen/podpora.png b/doxa-cli/screen/podpora.png new file mode 100644 index 0000000..a87a4fb Binary files /dev/null and b/doxa-cli/screen/podpora.png differ diff --git a/doxa-cli/screen/search.png b/doxa-cli/screen/search.png new file mode 100644 index 0000000..9ee6c0f Binary files /dev/null and b/doxa-cli/screen/search.png differ diff --git a/doxa-cli/screen/tags.png b/doxa-cli/screen/tags.png new file mode 100644 index 0000000..b61c168 Binary files /dev/null and b/doxa-cli/screen/tags.png differ diff --git a/doxa-cli/translations.go b/doxa-cli/translations.go new file mode 100644 index 0000000..a762389 --- /dev/null +++ b/doxa-cli/translations.go @@ -0,0 +1,110 @@ +package main + +type Translation struct { + Title string + MenuAdd string + MenuEdit string + MenuExport string + MenuDelete string + MenuQuit string + MenuLang string + MenuSearch string + MenuBrowse string + ListTitle string + NoNotes string + AddTitle string + EditTitle string + LabelName string + LabelContent string + LabelTags string + PlaceholderName string + PlaceholderContent string + PlaceholderTags string + HelpForm string + HelpList string + StatusSaved string + StatusEdited string + StatusDeleted string + StatusExported string + ErrRequired string + SearchTitle string + BrowseTags string + AllNotes string + ConfirmDelete string + ConfirmYes string + ConfirmNo string + HelpModal string +} + +var Translations = map[string]Translation{ + "cs": { + Title: "DOXA-CLI 🦅", + MenuAdd: "1: Přidat", + MenuEdit: "2: Upravit", + MenuExport: "3: Export", + MenuDelete: "4: Smazat", + MenuQuit: "q: Konec", + MenuLang: "l: EN", + MenuSearch: "/: Hledat", + MenuBrowse: "b: Tagy", + ListTitle: "--- SEZNAM POZNÁMEK ---", + NoNotes: " (Prázdno...)", + AddTitle: "PŘIDAT POZNÁMKU", + EditTitle: "UPRAVIT POZNÁMKU", + LabelName: "Název:", + LabelContent: "Obsah:", + LabelTags: "Tagy:", + PlaceholderName: "Název (povinné)", + PlaceholderContent: "Enter: Nový řádek | Tab: Další pole", + PlaceholderTags: "Tagy (nepovinné, oddělené čárkou)", + HelpForm: "[Tab] Další pole | [Enter] Uložit (mimo obsah) | [q] Zrušit", + HelpList: "↑/↓: Vybrat | Enter: Upravit | /: Hledat | b: Procházet", + StatusSaved: "Poznámka uložena.", + StatusEdited: "Změny uloženy.", + StatusDeleted: "Poznámka smazána.", + StatusExported: "Poznámka vyexportována.", + ErrRequired: "Chyba: Název a obsah jsou povinné!", + SearchTitle: "HLEDAT: ", + BrowseTags: "TAGY", + AllNotes: "Všechny poznámky", + ConfirmDelete: "Opravdu chcete smazat tuto poznámku?", + ConfirmYes: "y: Ano", + ConfirmNo: "n: Ne / Esc", + HelpModal: "q: Zavřít | 2: Editovat | ↑/↓: Posun", + }, + "en": { + Title: "DOXA-CLI 🦅", + MenuAdd: "1: Add", + MenuEdit: "2: Edit", + MenuExport: "3: Export", + MenuDelete: "4: Delete", + MenuQuit: "q: Quit", + MenuLang: "l: CS", + MenuSearch: "/: Search", + MenuBrowse: "b: Tags", + ListTitle: "--- NOTES LIST ---", + NoNotes: " (Empty...)", + AddTitle: "ADD NOTE", + EditTitle: "EDIT NOTE", + LabelName: "Name:", + LabelContent: "Content:", + LabelTags: "Tags:", + PlaceholderName: "Name (required)", + PlaceholderContent: "Enter: New line | Tab: Next field", + PlaceholderTags: "Tags (optional, comma separated)", + HelpForm: "[Tab] Next field | [Enter] Save (outside content) | [q] Cancel", + HelpList: "↑/↓: Select | Enter: Edit | /: Search | b: Browse", + StatusSaved: "Note saved.", + StatusEdited: "Changes saved.", + StatusDeleted: "Note deleted.", + StatusExported: "Note exported.", + ErrRequired: "Error: Name and content are required!", + SearchTitle: "SEARCH: ", + BrowseTags: "TAGS", + AllNotes: "All notes", + ConfirmDelete: "Are you sure you want to delete this note?", + ConfirmYes: "y: Yes", + ConfirmNo: "n: No / Esc", + HelpModal: "q: Close | 2: Edit | ↑/↓: Scroll", + }, +} diff --git a/doxa-cli/tui.go b/doxa-cli/tui.go new file mode 100644 index 0000000..83fa84c --- /dev/null +++ b/doxa-cli/tui.go @@ -0,0 +1,749 @@ +package main + +import ( + "fmt" + "os" + "strings" + "time" + + "github.com/charmbracelet/bubbles/textarea" + "github.com/charmbracelet/bubbles/textinput" + "github.com/charmbracelet/bubbles/viewport" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +var ( + appStyle = lipgloss.NewStyle(). + Padding(1, 2). + Border(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("62")) + + titleStyle = lipgloss.NewStyle(). + Bold(true). + Foreground(lipgloss.Color("#FAFAFA")). + Background(lipgloss.Color("#7D56F4")). + Padding(0, 1). + MarginBottom(1) + + selectedStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("#7D56F4")). + Bold(true) + + statusStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("205")) + + focusedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("205")) + cursorStyle = focusedStyle.Copy() + + confirmBoxStyle = lipgloss.NewStyle(). + Border(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("205")). + Padding(1, 2).Align(lipgloss.Center) +) + +type AppState int + +const ( + StateStartup AppState = iota + StateViewNotes + StateViewNoteModal + StateAddNote + StateEditNote + StateSearch + StateBrowseTags + StateConfirmDelete +) +type model struct { + notes []Note + filteredNotes []Note + cursor int + state AppState + browseTags []string + filterText string + textInputs []textinput.Model + contentInput textarea.Model + searchInput textinput.Model + viewport viewport.Model + ready bool + focusIndex int + selectedNoteID int64 + statusMsg string + lang string + width int + height int +} + +func NewModel() model { + inputs := make([]textinput.Model, 2) + for i := range inputs { + t := textinput.New() + t.Cursor.Style = cursorStyle + inputs[i] = t + } + inputs[0].Focus() + inputs[0].PromptStyle = focusedStyle + inputs[0].TextStyle = focusedStyle + + ta := textarea.New() + ta.SetWidth(60) + ta.SetHeight(8) + ta.FocusedStyle.CursorLine = lipgloss.NewStyle().Background(lipgloss.Color("62")) + + si := textinput.New() + si.Prompt = "🔍 " + si.Placeholder = "Hledat..." + + m := model{ + notes: loadNotes(), + cursor: 0, + state: StateStartup, + textInputs: inputs, + contentInput: ta, + searchInput: si, + focusIndex: 0, + lang: "cs", + } + m.applyFilter() + m.updatePlaceholders() + return m +} + +func (m model) Init() tea.Cmd { + return tea.Batch(textinput.Blink, textarea.Blink, tea.EnterAltScreen) +} + +func (m *model) applyFilter() { + if m.filterText == "" { + m.filteredNotes = m.notes + } else { + m.filteredNotes = []Note{} + query := strings.ToLower(m.filterText) + for _, n := range m.notes { + if strings.Contains(strings.ToLower(n.Name), query) || + strings.Contains(strings.ToLower(n.Content), query) || + strings.Contains(strings.ToLower(strings.Join(n.Tags, " ")), query) { + m.filteredNotes = append(m.filteredNotes, n) + } + } + } + if m.cursor >= len(m.filteredNotes) { + m.cursor = 0 + if len(m.filteredNotes) > 0 { + m.cursor = len(m.filteredNotes) - 1 + } + } +} + +func (m *model) getBrowseTags() { + set := make(map[string]bool) + for _, n := range m.notes { + for _, t := range n.Tags { + if t != "" { + set[t] = true + } + } + } + m.browseTags = []string{} + for k := range set { + m.browseTags = append(m.browseTags, k) + } + // Manual sort + for i := 0; i < len(m.browseTags); i++ { + for j := i + 1; j < len(m.browseTags); j++ { + if m.browseTags[i] > m.browseTags[j] { + m.browseTags[i], m.browseTags[j] = m.browseTags[j], m.browseTags[i] + } + } + } + m.cursor = 0 +} + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmd tea.Cmd + tr := Translations[m.lang] + + switch msg := msg.(type) { + case tea.WindowSizeMsg: + m.width = msg.Width + m.height = msg.Height + m.contentInput.SetWidth(msg.Width - 25) + m.contentInput.SetHeight(m.height/2 - 5) + + headerHeight := 6 + footerHeight := 3 + vpHeight := msg.Height - headerHeight - footerHeight + if vpHeight < 1 { + vpHeight = 1 + } + + if !m.ready { + m.viewport = viewport.New(msg.Width-6, vpHeight) + m.ready = true + } else { + m.viewport.Width = msg.Width - 6 + m.viewport.Height = vpHeight + } + + case tea.KeyMsg: + switch msg.String() { + case "ctrl+c": + return m, tea.Quit + case "esc": + if m.state == StateConfirmDelete { + m.state = StateViewNotes + m.statusMsg = "" + return m, nil + } + if m.state == StateViewNotes { + if m.filterText != "" { + m.filterText = "" + m.applyFilter() + return m, nil + } + return m, tea.Quit + } + m.resetToView() + return m, nil + case "q": + if m.state == StateStartup { + return m, tea.Quit + } + if m.state == StateConfirmDelete { + m.state = StateViewNotes + m.statusMsg = "" + return m, nil + } + if m.state == StateViewNoteModal { + m.state = StateViewNotes + // Reset viewport to full list size + headerHeight := 6 + footerHeight := 3 + vpHeight := m.height - headerHeight - footerHeight + if vpHeight < 1 { vpHeight = 1 } + m.viewport.Width = m.width - 6 + m.viewport.Height = vpHeight + return m, nil + } + if m.state == StateViewNotes { + if m.filterText != "" { + m.filterText = "" + m.applyFilter() + return m, nil + } + return m, tea.Quit + } + m.resetToView() + return m, nil + + case "l": + if m.state == StateViewNotes { + if m.lang == "cs" { + m.lang = "en" + } else { + m.lang = "cs" + } + m.updatePlaceholders() + return m, nil + } + + case "/": + if m.state == StateViewNotes { + m.state = StateSearch + m.searchInput.Focus() + m.searchInput.SetValue("") + return m, nil + } + + + case "tab", "shift+tab": + if m.state == StateAddNote || m.state == StateEditNote { + if msg.String() == "shift+tab" { + m.focusIndex-- + } else { + m.focusIndex++ + } + if m.focusIndex > 2 { + m.focusIndex = 0 + } + if m.focusIndex < 0 { + m.focusIndex = 2 + } + return m.updateFocus() + } + + case "up", "k": + if m.state == StateViewNotes && m.cursor > 0 { + m.cursor-- + m.viewport.LineUp(1) + } + if m.state == StateViewNoteModal { + m.viewport.LineUp(1) + } + if m.state == StateBrowseTags && m.cursor > 0 { + m.cursor-- + } + case "down", "j": + if m.state == StateViewNotes { + max := len(m.filteredNotes) + if m.cursor < max-1 { + m.cursor++ + m.viewport.LineDown(1) + } + } + if m.state == StateViewNoteModal { + m.viewport.LineDown(1) + } + if m.state == StateBrowseTags { + max := len(m.browseTags) + if m.cursor < max-1 { + m.cursor++ + } + } + + case "enter": + switch m.state { + case StateStartup: + m.state = StateViewNotes + case StateViewNotes: + if len(m.filteredNotes) > 0 { + m.state = StateViewNoteModal + m.selectedNoteID = m.filteredNotes[m.cursor].ID + + var n Note + for _, note := range m.notes { + if note.ID == m.selectedNoteID { + n = note + break + } + } + + modalContent := fmt.Sprintf("%s\n---\n[%d] %s\n\n%s\n\nTagy: %s", + tr.HelpModal, + n.ID, n.Name, n.Content, strings.Join(n.Tags, ", "), + ) + + // Set viewport size for modal (smaller than full screen) + modalWidth := m.width - 20 + if modalWidth < 40 { modalWidth = 40 } + modalHeight := m.height - 10 + if modalHeight < 10 { modalHeight = 10 } + + m.viewport.Width = modalWidth + m.viewport.Height = modalHeight + m.viewport.SetContent(modalContent) + m.viewport.YOffset = 0 + } + case StateSearch: + m.filterText = m.searchInput.Value() + m.applyFilter() + m.state = StateViewNotes + case StateBrowseTags: + if len(m.browseTags) > 0 { + m.filterText = m.browseTags[m.cursor] + m.applyFilter() + } + m.state = StateViewNotes + case StateAddNote: + if m.focusIndex != 1 { + m.handleAddNote() + } + case StateEditNote: + if m.focusIndex != 1 { + m.handleEditNote() + } + case StateConfirmDelete: + if m.focusIndex == 0 { + m.handleDeleteNote() + m.state = StateViewNotes + m.statusMsg = tr.StatusDeleted + return m, nil + } else { + m.state = StateViewNotes + m.statusMsg = "" + return m, nil + } + } + + case "b": + if m.state == StateViewNotes { + m.state = StateBrowseTags + m.getBrowseTags() + return m, nil + } + case "1": + if m.state == StateViewNotes { + m.state = StateAddNote + m.resetInputs() + m.textInputs[0].SetValue("") + m.updatePlaceholders() + return m, nil + } + case "2": + if m.state == StateViewNotes && len(m.filteredNotes) > 0 { + m.state = StateEditNote + m.selectedNoteID = m.filteredNotes[m.cursor].ID + m.populateInputs(m.filteredNotes[m.cursor]) + return m, nil + } + if m.state == StateViewNoteModal { + for _, n := range m.notes { + if n.ID == m.selectedNoteID { + m.state = StateEditNote + m.populateInputs(n) + break + } + } + return m, nil + } + case "3": + if m.state == StateViewNotes && len(m.filteredNotes) > 0 { + exportNote(m.notes, m.filteredNotes[m.cursor].ID) + m.statusMsg = tr.StatusExported + } + case "4": + if m.state == StateViewNotes && len(m.filteredNotes) > 0 { + m.state = StateConfirmDelete + m.selectedNoteID = m.filteredNotes[m.cursor].ID + m.focusIndex = 0 + } + } + } + + if m.state == StateSearch { + m.searchInput, cmd = m.searchInput.Update(msg) + return m, cmd + } + + if m.state == StateAddNote || m.state == StateEditNote { + if m.focusIndex == 1 { + m.contentInput, cmd = m.contentInput.Update(msg) + } else { + idx := m.focusIndex + if idx > 1 { + idx-- + } + m.textInputs[idx], cmd = m.textInputs[idx].Update(msg) + } + return m, cmd + } + + if m.state == StateConfirmDelete { + if msg, ok := msg.(tea.KeyMsg); ok { + switch msg.String() { + case "y": + m.handleDeleteNote() + m.state = StateViewNotes + m.statusMsg = tr.StatusDeleted + return m, nil + case "n", "esc": + m.state = StateViewNotes + m.statusMsg = "" + return m, nil + } + } + } + + return m, nil +} + +func (m *model) updateFocus() (tea.Model, tea.Cmd) { + var cmds []tea.Cmd + for i := range m.textInputs { + m.textInputs[i].Blur() + m.textInputs[i].PromptStyle = lipgloss.NewStyle() + } + m.contentInput.Blur() + m.searchInput.Blur() + + switch m.focusIndex { + case 0: + cmds = append(cmds, m.textInputs[0].Focus()) + m.textInputs[0].PromptStyle = focusedStyle + case 1: + cmds = append(cmds, m.contentInput.Focus()) + case 2: + cmds = append(cmds, m.textInputs[1].Focus()) + m.textInputs[1].PromptStyle = focusedStyle + } + return m, tea.Batch(cmds...) +} + +func (m model) View() string { + tr := Translations[m.lang] + var b strings.Builder + + b.WriteString(titleStyle.Render(tr.Title)) + b.WriteString("\n") + + if m.statusMsg != "" { + b.WriteString(statusStyle.Render(m.statusMsg) + "\n\n") + } + + switch m.state { + case StateStartup: + eagle := ` + _ + ( ` + lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Render("`") + ` + \ ` + lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Render("\\") + ` + / / _ + __ / / ( \ + ( "---" / / / + \ / / / + \ /-----' / + \ / / + \ / / + '-------' +` + b.WriteString(lipgloss.Place(m.width-12, 14, lipgloss.Center, lipgloss.Center, + eagle + "\n" + + lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#7D56F4")).Render("DOXA-CLI 🦅") + "\n\n" + + "Local-First Notes & Sovereignty\n\n" + + "Enter: Start | q: Quit\n\n" + + "License: MIT | © 2026 Kankys")) + + + case StateSearch: + b.WriteString(tr.SearchTitle + "\n" + m.searchInput.View() + "\n\n" + tr.HelpForm) + + case StateBrowseTags: + b.WriteString(fmt.Sprintf("--- %s ---\n", tr.BrowseTags)) + b.WriteString("Enter: Filtrovat | q: Zpět\n\n") + for i, item := range m.browseTags { + cursor := " " + if m.cursor == i { + cursor = "> " + } + b.WriteString(fmt.Sprintf("%s%s\n", cursor, item)) + } + + case StateViewNotes: + filterInfo := "" + if m.filterText != "" { + filterInfo = fmt.Sprintf(" [Filtr: %s]", m.filterText) + } + + var listBuilder strings.Builder + if len(m.filteredNotes) == 0 { + listBuilder.WriteString(tr.NoNotes + "\n") + } else { + for i, n := range m.filteredNotes { + if m.cursor == i { + listBuilder.WriteString(selectedStyle.Render(fmt.Sprintf("> [%d] %s", n.ID, n.Name)) + "\n") + } else { + listBuilder.WriteString(fmt.Sprintf(" [%d] %s\n", n.ID, n.Name)) + } + } + } + + if m.ready { + m.viewport.SetContent(listBuilder.String()) + } + + b.WriteString(fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s\n\n", + tr.MenuAdd, tr.MenuEdit, tr.MenuExport, tr.MenuDelete, tr.MenuSearch, tr.MenuBrowse, tr.MenuLang)) + b.WriteString(tr.ListTitle + filterInfo + "\n") + + if m.ready { + b.WriteString(m.viewport.View() + "\n") + } else { + b.WriteString(listBuilder.String()) + } + b.WriteString("\n" + tr.HelpList) + + case StateAddNote, StateEditNote: + title := tr.AddTitle + if m.state == StateEditNote { + title = fmt.Sprintf("%s (%d)", tr.EditTitle, m.selectedNoteID) + } + b.WriteString(title + "\n\n") + + b.WriteString(fmt.Sprintf("%-8s %s\n", tr.LabelName, m.textInputs[0].View())) + b.WriteString(fmt.Sprintf("%-8s\n%s\n\n", tr.LabelContent, m.contentInput.View())) + b.WriteString(fmt.Sprintf("%-8s %s\n", tr.LabelTags, m.textInputs[1].View())) + + b.WriteString("\n" + tr.HelpForm) + + case StateViewNoteModal: + if m.ready { + b.WriteString(confirmBoxStyle.Render(m.viewport.View())) + } else { + b.WriteString(confirmBoxStyle.Render("Načítání...")) + } + + case StateConfirmDelete: + var noteToDelete Note + found := false + for _, n := range m.notes { + if n.ID == m.selectedNoteID { + noteToDelete = n + found = true + break + } + } + + if !found { + m.state = StateViewNotes + m.statusMsg = "Chyba: Poznámka k smazání nebyla nalezena!" + return "" + } + + confirmText := fmt.Sprintf("%s\n\n[%d] %s\nObsah: %s\n\n%s | %s", + tr.ConfirmDelete, + noteToDelete.ID, + noteToDelete.Name, + truncate(noteToDelete.Content, 40), + tr.ConfirmYes, tr.ConfirmNo, + ) + b.WriteString(confirmBoxStyle.Render(confirmText)) + } + + content := b.String() + if m.width > 0 && m.height > 0 { + return appStyle.Width(m.width - 6).Height(m.height - 4).Render(content) + } + return appStyle.Render(content) +} + +func (m *model) updatePlaceholders() { + tr := Translations[m.lang] + m.textInputs[0].Placeholder = tr.PlaceholderName + m.contentInput.Placeholder = tr.PlaceholderContent + m.textInputs[1].Placeholder = tr.PlaceholderTags +} + +func (m *model) resetToView() { + m.state = StateViewNotes + m.statusMsg = "" + m.filterText = "" + m.applyFilter() + m.resetInputs() +} + +func (m *model) resetInputs() { + for i := range m.textInputs { + m.textInputs[i].SetValue("") + m.textInputs[i].Blur() + } + m.contentInput.SetValue("") + m.searchInput.SetValue("") + m.focusIndex = 0 + m.updateFocus() +} + +func (m *model) populateInputs(n Note) { + m.textInputs[0].SetValue(n.Name) + m.contentInput.SetValue(n.Content) + m.textInputs[1].SetValue(strings.Join(n.Tags, ", ")) + m.focusIndex = 0 + m.updateFocus() +} + +func (m *model) handleAddNote() { + tr := Translations[m.lang] + name := m.textInputs[0].Value() + content := m.contentInput.Value() + if name == "" || content == "" { + m.statusMsg = tr.ErrRequired + return + } + tags := []string{} + if m.textInputs[1].Value() != "" { + tags = strings.Split(m.textInputs[1].Value(), ",") + for i := range tags { + tags[i] = strings.TrimSpace(tags[i]) + } + } + now := time.Now() + m.notes = append(m.notes, Note{ + ID: now.UnixMilli(), Name: name, Content: content, Folder: "", Tags: tags, CreatedAt: now, ModifiedAt: now, + }) + saveNotes(m.notes) + m.applyFilter() + m.statusMsg = tr.StatusSaved + m.state = StateViewNotes +} + +func (m *model) handleEditNote() { + tr := Translations[m.lang] + for i, n := range m.notes { + if n.ID == m.selectedNoteID { + m.notes[i].Name = m.textInputs[0].Value() + m.notes[i].Content = m.contentInput.Value() + m.notes[i].Folder = "" + tags := []string{} + if m.textInputs[1].Value() != "" { + tags = strings.Split(m.textInputs[1].Value(), ",") + for j := range tags { + tags[j] = strings.TrimSpace(tags[j]) + } + } + m.notes[i].Tags = tags + m.notes[i].ModifiedAt = time.Now() + break + } + } + saveNotes(m.notes) + m.applyFilter() + m.statusMsg = tr.StatusEdited + m.state = StateViewNotes +} + +func (m *model) handleDeleteNote() { + noteIndex := -1 + for i, n := range m.notes { + if n.ID == m.selectedNoteID { + noteIndex = i + break + } + } + + if noteIndex != -1 { + m.notes = append(m.notes[:noteIndex], m.notes[noteIndex+1:]...) + saveNotes(m.notes) + } + m.applyFilter() +} + +func exportNote(notes []Note, id int64) { + for _, note := range notes { + if note.ID == id { + homeDir, err := os.UserHomeDir() + if err != nil { + fmt.Printf("Chyba při zjišťování domovského adresáře: %v\n", err) + return + } + + exportDir := fmt.Sprintf("%s/doxa-cli-txt", homeDir) + if err := os.MkdirAll(exportDir, 0755); err != nil { + fmt.Printf("Chyba při vytváření adresáře pro export: %v\n", err) + return + } + + fileName := fmt.Sprintf("%s_%d.txt", strings.ReplaceAll(note.Name, " ", "_"), note.ID) + fullPath := fmt.Sprintf("%s/%s", exportDir, fileName) + + file, err := os.Create(fullPath) + if err != nil { + fmt.Printf("Chyba při vytváření souboru pro export: %v\n", err) + return + } + defer file.Close() + + content := fmt.Sprintf("Název: %s\nTagy: %s\nVytvořeno: %s\n\n%s", + note.Name, strings.Join(note.Tags, ", "), note.CreatedAt.Format("2006-01-02 15:04"), note.Content) + + _, _ = file.WriteString(content) + return + } + } +} + +func truncate(s string, max int) string { + if len(s) > max { + return strings.TrimSpace(s[:max]) + "..." + } + return s +} + +type errMsg error \ No newline at end of file diff --git a/doxa-cli/web/img/dashboard.png b/doxa-cli/web/img/dashboard.png new file mode 100644 index 0000000..04629a7 Binary files /dev/null and b/doxa-cli/web/img/dashboard.png differ diff --git a/doxa-cli/web/img/logo.jpg b/doxa-cli/web/img/logo.jpg new file mode 100644 index 0000000..a69da5b Binary files /dev/null and b/doxa-cli/web/img/logo.jpg differ diff --git a/doxa-cli/web/index.html b/doxa-cli/web/index.html new file mode 100644 index 0000000..8b52e3d --- /dev/null +++ b/doxa-cli/web/index.html @@ -0,0 +1,335 @@ + + + + + + DOXA cli + + + + +
+
+
+
+
+
+
+
+
bash - doxa-cli
+
+ +
+ +
+

DOXA cli

+ + +
+

DOXA-CLI je nástroj pro správu vašich poznámek z příkazové řádky. Umožňuje přidávat, zobrazovat, upravovat, mazat, exportovat poznámky a také je filtrovat a vyhledávat. Aplikace je napsána v Go a nabízí moderní terminálové uživatelské rozhraní (TUI).

+
+ +
+

DOXA-CLI is a command-line tool for managing your notes. It allows you to add, view, edit, delete, export notes, as well as filter and search them. The application is written in Go and offers a modern Terminal User Interface (TUI).

+
+ +

+ Go 1.22+ + MIT license + Tested on Linux +

+

+ freeBSD +

+

+ Dashboard +

+ + +
+
+ 🔥 Důležité: Podrobný návod k použití, instalaci a přehled klávesových zkratek naleznete v oficiálním manuálu: + Český uživatelský manuál (MANUAL_CZ.md) +
+ +
$ instalace
+
git clone https://codeberg.org/Kankys/doxa-cli.git
+cd doxa-cli
+chmod +x install.sh
+./install.sh
+ +
$ vlastnosti
+
    +
  • Jazyk: Čisté Go (Golang), které zaručuje nativní kompilaci, vysokou rychlost provedení a žádné zbytečné externí závislosti.
  • +
  • Rozhraní: Terminálové rozhraní (CLI), které zbavuje mysl grafického chaosu a nechává vyniknout čistému textu.
  • +
  • Datová vrstva: Plně kompatibilní formát JSON sdílený s webovou verzí. Poznámky obsahují přesná časová razítka, identifikátory, obsah a štítky.
  • +
+ +
$ použití
+
# Spuštění aplikace
+doxa-cli
+ +
$ odkazy
+

Zdrojový kód, dokumentaci, návody a další informace naleznete na Codebergu.

+

Web DOXA Notes naleznete na oficálním webu.

+

Web doxa-secret naleznete na oficálním webu.

+ + +
+ + +
+
+ 🔥 Important: A detailed guide for installation, and keyboard shortcuts can be found in the official manual: + English User Manual (MANUAL.md) +
+ +
$ installation
+
git clone https://codeberg.org/Kankys/doxa-cli.git
+cd doxa-cli
+chmod +x install.sh
+./install.sh
+ +
$ features
+
    +
  • Language: Clean Go (Golang) ensuring native compilation, fast execution speeds, and no bloated external dependencies.
  • +
  • Interface: Terminal-based interface (CLI) to strip away graphical noise and let pure text stand out.
  • +
  • Data Layer: Fully compatible JSON format shared with the web version. Notes include accurate timestamps, IDs, content, and tags.
  • +
+ +
$ usage
+
# Start the application
+doxa-cli
+ +
$ links
+

Source code, documentation, guides, and more can be found on Codeberg.

+

DOXA Notes web can be found on the official website.

+

doxa-secret web can be found on the official website.

+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doxa-notes/.gitignore b/doxa-notes/.gitignore new file mode 100644 index 0000000..591b95b --- /dev/null +++ b/doxa-notes/.gitignore @@ -0,0 +1 @@ +.vibe/ \ No newline at end of file diff --git a/doxa-notes/01_manifest.md b/doxa-notes/01_manifest.md new file mode 100644 index 0000000..4452103 --- /dev/null +++ b/doxa-notes/01_manifest.md @@ -0,0 +1,25 @@ +# Manifest digitální suverenity a minimalistického myšlení +### Záměr projektu: +Vytvořit absolutně nezávislé, bezpečné a minimalistické prostředí pro uchovávání lidských myšlenek, poznámek a životních reflexí. V souladu se základními principy osobní svobody a soběstačnosti aplikace vědomě odmítá cloudové databáze, servery třetích stran a centralizovaná API. DOXA věří, že lidská mysl nepotřebuje být sledována algoritmy, aby mohla růst. + +### 1. Radikální Local-First Filozofie + +Aplikace funguje na principu absolutní decentralizace. Běží na tvém zařízení a tam také umírá i žije. + + * Žádný backend, žádné API: DOXA vědomě neobsahuje žádný kód pro odesílání dat na vzdálené servery. Tím je eliminováno riziko úniku dat, výpadku serveru nebo změny obchodních podmínek poskytovatele. + * Absolutní soukromí: Data jsou uložena výhradně v tvém prohlížeči (localStorage) nebo lokálním souboru. Co napíšeš, to zůstává tvým výhradním vlastnictvím. + ## 2. Formát JSON: Trvanlivost napříč dekádami + + Data jsou strukturována do otevřeného, čistého a lidsky čitelného formátu JSON. Žádné proprietární databáze. + + * Tvá data ti patří. Díky možnosti manuálního exportu si můžeš svůj myšlenkový fond odnést kamkoli – uložit si ho na svůj bezpečný lokální disk, nahrát na vlastní Git (GitHub/Gitea), nebo jej synchronizovat skrze cloudovou službu, kterou ty sám uznáš za bezpečnou. + * Čistota formátu zaručuje, že tvé poznámky budou čitelné i za dvacet let na jakémkoli zařízení, bez ohledu na to, zda DOXA bude stále existovat. + ## 3. Technická čistota a minimalismus (Vanilla Stack) + + Pro zachování maximální rychlosti, nezávislosti a nulových externích závislostí je aplikace postavena výhradně na čistých webových standardech: + + * Frontend (HTML5/CSS3): Minimalistické rozhraní, které nezatěžuje mysl barevným chaosem a vizuálním balastem moderního internetu. + * + * Logika (Vanilla JavaScript ES6+): Žádné těžkopádné frameworky (React/Vue), které podléhají módním trendům a neustálým změnám. + + **Čistý kód je trvanlivý jako tesání do kamene. „Nezáleží na tom, jak složité jsou okolnosti kolem tebe. Když stavíš vlastní chrám myšlenek, začínáš od prvního kamene. Tento kód a tvá data jsou tvým vlastním, nedobytným hradem.“**— Stoický odkaz pro svobodné myslitele \ No newline at end of file diff --git a/doxa-notes/02_manuals.md b/doxa-notes/02_manuals.md new file mode 100644 index 0000000..1595e83 --- /dev/null +++ b/doxa-notes/02_manuals.md @@ -0,0 +1,64 @@ +# Návod k použití — DOXA (v26.07.01) + +### Vytvoření nové poznámky + + Klikni na tlačítko ➕ Nová poznámka a zadej název. + Položka se objeví v seznamu. Klikem načteš název a obsah do editoru nahoře. + Uprav obsah a klikni Uložit nyní. + +## Tagy + +Tagy jsou slova nebo fráze, která popisuje obsah poznámky. V aplikaci Doxa díky nim můžete filtrovat poznámky podle tagu. + + * Klikni do pole tagy a zadej název tagu (uloží se stejně s poznámkou). + * Poznámku pomocí tagu pak vyhledáš v poli s lupou Filtrovat poznámky podle tagu.... + +### Editace a mazání + + * Inline: klikni na poznámku, uprav obsah a stiskni Uložit nyní. + * Modal: klikni na ikonu ✎ vedle položky pro pokročilou editaci v modal okně. + * Mazání: ikona 🗑 u položky — po potvrzení se poznámka smaže. + +### Přesouvání pořadí poznámek + + Použij šipky ↑ / ↓ u položek. + Nebo přetahuj položky (drag & drop) na požadované místo — při přetažení se ukáže indikátor vložení. + +### Přepínání vzhledu + +V horním menu najdeš tlačítko pro přepínání vzhledu. Aplikace podporuje tři režimy: + + * Světlý — ikona: ☀️ + * Tmavý — ikona: 🌙 + * Respektovat systém — ikona: 🌓 — aplikace bude sledovat systémovou volbu (prefers-color-scheme) a automaticky se přepne, pokud se změní systémový motiv. + +Kliknutím na tlačítko v menu cyklíš mezi režimy (Light → Dark → System). Vybraná volba se uloží do localStorage pod klíčem doxa_theme a přetrvá mezi stránkami a obnovami. Pokud chceš volbu resetovat, otevři konzoli prohlížeče a spusť: localStorage.removeItem('doxa_theme') nebo vymaž storage v nástrojích pro vývojáře. + +### Automatické ukládání + +Aplikace nyní automaticky ukládá změny poznámek lokálně během psaní (autosave). V běžném prohlížeči se změny ukládají do localStorage (klíč doxa_notes_v1) bez nutnosti manuálního ukládání — data se uloží po krátké prodlevě. Pokud aplikaci spouštíš v Electron/Node režimu, změny se zapisují přímo do lokálního souboru. + +**Průběžně si úkládej i JSON soubor manuálně!!** + +### Manuální uložení + +Vedle editoru najdeš tlačítko Uložit nyní. I když autosave ukládá průběžně, tlačítko je užitečné v těchto případech: + + Okamžité uložení — provede persist bez čekání na autosave (užitečné před zavřením aplikace nebo pokud chcete rychlou jistotu, že jsou změny zapsány). + Vizuální potvrzení — po uložení se zobrazí stav „Uloženo“, což dává uživateli okamžitou zpětnou vazbu. + Bez stažení — tlačítko Uložit poznámku neprovádí stažení souboru; pokud chcete stáhnout JSON, použijte tlačítko Exportovat JSON. + +Pro přenos dat mezi zařízeními použijte tlačítko Exportovat JSON (stáhne soubor doxa.json), nebo z konzole spusťte saveNotesToFile(true). + +### Import / Export + +Pro import klikni Importovat JSON a vyber soubor. Podporované formáty: + + Objekt s polem notes: { "notes": [ ... ] } + Přímo pole: [ { ... }, { ... } ] + +Export je nyní dostupný přes tlačítko Exportovat JSON (vedle tlačítka Uložit). Aplikace zároveň provádí autosave lokálně — nic neztratíte, pokud zapomenete manuálně uložit. Chcete-li stáhnout JSON přes skript, můžete také spustit v konzoli saveNotesToFile(true). + +### Bezpečnost a zálohy + +Výchozí režim je local‑first: data zůstávají ve tvém prohlížeči (localStorage) nebo lokálním souboru, aplikace je sama neodesílá. \ No newline at end of file diff --git a/doxa-notes/03_install.md b/doxa-notes/03_install.md new file mode 100644 index 0000000..0dd1f2e --- /dev/null +++ b/doxa-notes/03_install.md @@ -0,0 +1,32 @@ +# Instalace +### Rychlý start - pouze pro variantu spouštění aplikace u sebe lokalně + +Pokud aplikaci spouštíš z webu https://doxa-notes.org/ tento návod není validní! + + 1.Stáhni/klonuj repozitář a přejdi do složky aplikace: + + **cd doxa/wep_app** + + Spusť jednoduchý lokální server (doporučeno): + + **python3 -m http.server 8000** + + a otevři v prohlížeči: **http://localhost:8000** + + 2. Alternativně můžeš použít Node.js a pomocí npm install nainstaluj live-server a následně spusť pomocí příkazu: **live-server** ve složce aplikace. + +### Desktop App + +1. Stáhni si desktop verzi aplikace z [Codeberg uložiště projektu](https://codeberg.org/Kankys/doxa/releases) +2. Staženou aplikaci spustíš spustíš otevřením souboru windows Dlinux - .AppImage +3. Soubory aplikací najdeš ve složce: + +```bash +Na tvém Linuxu: ~/.config/doxa/ +``` + +**Nezapomeň si dělat pravidélné zálohy JSON (exportovat JSON)** + +**Nezapomeň si pravidelně aktualizovat aplikaci, abys mohl mít nejnovější verzi.** + +Desktop app: nevycházejí s pravidelností jako web app, z důvodu buildu a náročnosti na zdroje. Desktop app bude vydáván pouze po větších funkčních změnách. \ No newline at end of file diff --git a/doxa-notes/04_instrukce.md b/doxa-notes/04_instrukce.md new file mode 100644 index 0000000..cb5ef27 --- /dev/null +++ b/doxa-notes/04_instrukce.md @@ -0,0 +1,23 @@ +# Bugs + +Nalezené chyby prosím hlašte na Gitu projektu (kde naleznete hlášené či nevyřešené bugy) [Link na hlášení chyb](https://codeberg.org/Kankys/doxa/issues) + +# Repozitář + +Pokud chcete přispět svým kódem budu velice rád, ale je tu několik pravidel: + +* před větší feature, vždy zvažte jestli úprava je vhodná, případně ji nejdříve prodiskutujme. Škoda zahodit Pull Request z důvodu směřování projektu jiným směrem. + +* Vždy si odpíchněte větev z master. Do master nikdy nic ne push(ovat)!! Vždy udělejte Pull Request do masteru. + +* Do souboru PR.md vždy před Pull Request vložte do tabulky název větve, stručný popis změn a jméno. + + + +# Automatizované testy + +* Testy jsou psané v Playwright a v TypeScript +* Využíváme POM +* Pokud je to možné s novou funkcionalitou úprávýme řádně testy + +# Podporovatelé a přispěvovatelé \ No newline at end of file diff --git a/doxa-notes/05_release.md b/doxa-notes/05_release.md new file mode 100644 index 0000000..f4efdab --- /dev/null +++ b/doxa-notes/05_release.md @@ -0,0 +1,25 @@ +## Release notes: +| Branch | Change | Version|Name | +| --- | --- | --- | --- | +| dokumentace01 | Vytvoření struktury dokumentace a první kód aplikace | Kankys | +|update_app |dark/light mode, oprv textací, rozšíření návodu, přídaní markdown a tlačítek| 26.O6.01.beta|Kankys | +| dokumentace02 | oprava issue https://codeberg.org/Kankys/doxa/issues/3, textové editace, přidání baneru | 26.06.02.beta|Kankys | +| dokumentace03 | smazani server casti, oprava textaci, vytvoření manifest | 26.6.02.beta|Kankys | +| desktop_app_electron | vytvoření app pro **windows a linux**, upravené návody |26.06.03.beta |Kankys | +|new_project_doxa|přejmenování projektu na Doxa, nový repozitář, new css style návrh | 26.06.04.beta|Kankys | +| tags |přidání tagů do poznámek | 26.06.05.beta|Kankys | +| first_stable | nová doména doxa-notes.org, první stabilní vydání, rychlá volba /, funkce náhledu poznámek, rozdělení doxa-notes.org na web app a desktop app | 26.07.01|Kankys | +|bug-H1| oprava bugu v h1| 26.07.01.|Kankys | +|wiki| přidání wiki stránky (mkdocs)| 26.07.02.|Kankys | +| playwright| založení playwright testů, úprava SEO | 26.07.03.| Kankys | +|web_zalozky | přidání systému složek, rozšíření hledání|26.07.04| kankys| +|playwright-configuration| konfigurace playwright, aktualizace package.json, upravit AppPage.ts| 26.07.04| Kankys| +|en_wiki + roller| přidání wiki stránky (mkdocs) v EN + roller| 26.07.05.|Kankys | + +Verze: se označují rok.měsíc.verze (26.06.03.beta) + +První ostrá verze výjde jako (předpoklad): 26.07.01 + +Desktop app: nevycházejí s pravidelností jako web app, z důvodu buildu a náročnosti na zdroje. Desktop app bude vydáván pouze po větších funkčních změnách. + +Desktop aplikace pro Linux a Windows jsou zabaleny do instalátorů AppImage - Linux a exe (Windows). \ No newline at end of file diff --git a/doxa-notes/06_todo.md b/doxa-notes/06_todo.md new file mode 100644 index 0000000..b6df409 --- /dev/null +++ b/doxa-notes/06_todo.md @@ -0,0 +1,9 @@ +# TODO + +- [x] Desktop app linux +- [ ] Desktop app macOS +- [X] Export poznámky do Markdown +- [ ] Lokalizace do AJ +- [X] tagy +- [X] rychlé vyhledávaní +- [X] vlastní doména diff --git a/doxa-notes/LICENSE b/doxa-notes/LICENSE new file mode 100644 index 0000000..28192f8 --- /dev/null +++ b/doxa-notes/LICENSE @@ -0,0 +1,18 @@ +MIT License + +Copyright (c) 2026 Kankys + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/doxa-notes/README.md b/doxa-notes/README.md new file mode 100644 index 0000000..52ae017 --- /dev/null +++ b/doxa-notes/README.md @@ -0,0 +1,116 @@ +# 🇬🇧 DOXA Notes PROJECT + +##### 🇨🇿 [Czech Version](#czech-version) + +#### Technical and architectural manifesto of a minimalist note-taking application + +**Project goal:** To create an absolutely independent, secure and minimalist environment for storing people's +thoughts, notes and life reflections. In accordance with the liberal principles of self-sufficiency, the application does not rely on +third-party cloud databases, but operates fully locally with the open JSON format on its own server +backend. + +## 1. TECHNICAL ARCHITECTURE +To maintain maximum speed, code purity and zero external dependencies, the application will be built on a pure +web standard (so-called Vanilla stack): + +Frontend: Semantic HTML5 for structure, CSS3 for a minimalist interface that does not burden the mind with colorful chaos. + +Client logic: Pure JavaScript (ES6+) without frameworks (React/Vue). Everything runs natively in the browser. + +Data layer: Standardized JSON format. Notes are structured as an array of objects, where each +item has a unique identifier, timestamp, and text content. + +Desktop applications for Linux and Windows are packaged in AppImage installers - Linux and exe (Windows). + +## 2. DATA FORMAT STRUCTURE (JSON) +Data purity ensures that your thoughts will be readable even in twenty years on any device. The basic schema of one note is as follows: + +```json +{ +"notes": [ +{ +"id": "1719147600000", +"title": "Morning reflection", +"content": "Digital illusion denied today. Mind is calm and steady.", +"created_at": "2026-06-23T08:00:00Z", +"updated_at": "2026-06-23T08:00:00Z"} + +]} +``` +## 3. VPS DEPLOYMENT STRATEGY (DOXA.LUKAN.CZ) +Since the application (web version) will run on its own virtual private network (VPS) with the architecture: + +### **Architecture (Purely client-side)** + +**Technical data storage solution** - The application runs on a subdomain, but the data is stored in the browser (LocalStorage / IndexedDB) with option to manually export/import JSON file. + +**Security aspect** - Absolute security. No data leaves your browser to the network. + +## License + +The application is open-source and licensed under the MIT license. + +-- + +"It doesn't matter how complex the circumstances around you are. When you build your own temple of ideas, you start from the first stone. This code is your first stone." — Stoic reference from Kankys + +--- +
+ +# 🇨🇿 PROJEKT DOXA Notes + +#### Technický a architektonický manifest minimalistické poznámkové aplikace + +**Záměr projektu:** Vytvořit absolutně nezávislé, bezpečné a minimalistické prostředí pro uchovávání lidských +myšlenek, poznámek a životních reflexí. V souladu se liberálními principy soběstačnosti aplikace nespoléhá na +cloudové databáze třetích stran, nýbrž operuje plně lokálně s otevřeným formátem JSON na vlastním serverovém +zázemí. + +## 1. TECHNICKÁ ARCHITEKTURA +Pro zachování maximální rychlosti, čistoty kódu a nulových externích závislostí bude aplikace postavena na čistém +webovém standardu (tzv. Vanilla stack): + +Frontend: Sémantické HTML5 pro strukturu, CSS3 pro minimalistické rozhraní, které nezatěžuje mysl +barevným chaosem. + +Klientská logika: Čistý JavaScript (ES6+) bez frameworků (React/Vue). Vše běží nativně v prohlížeči. + +Datová vrstva: Standardizovaný formát JSON. Poznámky jsou strukturovány jako pole objektů, kde každá +položka má jednoznačný identifikátor, časové razítko a textový obsah. + +Desktop aplikace pro Linux a Windows jsou zabaleny do instalátorů AppImage - Linux a exe (Windows). + +## 2. STRUKTURA DATOVÉHO FORMÁTU (JSON) +Čistota dat zaručuje, že tvé myšlenky budou čitelné i za dvacet let na jakémkoli zařízení. Základní schéma jedné +poznámky vypadá následovně: + +```json +{ +"notes": [ +{ +"id": "1719147600000", +"title": "Ranní reflexe", +"content": "Dnes odepřena digitální iluze. Mysl je klidná a pevná.", +"created_at": "2026-06-23T08:00:00Z", +"updated_at": "2026-06-23T08:00:00Z" +} +] +} +``` +## 3. STRATEGIE NASAZENÍ NA VPS (DOXA.LUKAN.CZ) +Jelikož aplikace (webová verze) bude běží na vlastní virtuální privátní síti (VPS) s architekturou: + +### **Architektura (Čistě klientská)** + +**Technické řešení ukládání dat** - Aplikace běží na subdoméně, ale data se ukládají v prohlížeči (LocalStorage / IndexedDB) s možností manuálního exportu/importu JSON souboru. + +**Bezpečnostní aspekt** - Absolutní bezpečnost. Žádná data neodcházejí z tvého prohlížeči na síť. + + +## Licence + +Aplikace je open-source a licencována pod MIT licencí. + +-- + +"Nezáleží na tom, jak složité jsou okolnosti kolem tebe. Když stavíš vlastní chrám myšlenek, začínáš od prvního kamene. Tento kód je tvým prvním kamenem." — Stoický odkaz od Kankyse \ No newline at end of file diff --git a/doxa-notes/desktop_app_dev/build/about.html b/doxa-notes/desktop_app_dev/build/about.html new file mode 100644 index 0000000..f01e339 --- /dev/null +++ b/doxa-notes/desktop_app_dev/build/about.html @@ -0,0 +1,104 @@ + + + + + O projektu — DOXA + + + + + + + + +
+ + +

O projektu — DOXA

+ + + +

Doxa notes

+ +

Manifest digitální suverenity a minimalistického myšlení

+

Záměr projektu:

+

Vytvořit absolutně nezávislé, bezpečné a minimalistické prostředí pro uchovávání lidských myšlenek, poznámek a životních reflexí. V souladu se základními principy osobní svobody a soběstačnosti aplikace vědomě odmítá cloudové databáze, servery třetích stran a centralizovaná API. Doxa věří, že lidská mysl nepotřebuje být sledována algoritmy, aby mohla růst.

+

1. Radikální Local-First Filozofie

+

Aplikace funguje na principu absolutní decentralizace. Běží na tvém zařízení a tam také umírá i žije.

+
    +
  • Žádný backend, žádné API: Doxa vědomě neobsahuje žádný kód pro odesílání dat na vzdálené servery. Tím je eliminováno riziko úniku dat, výpadku serveru nebo změny obchodních podmínek poskytovatele.
  • +
  • Absolutní soukromí: Data jsou uložena výhradně v tvém prohlížeči (localStorage) nebo lokálním souboru. Co napíšeš, to zůstává tvým výhradním vlastnictvím.
  • +
+

2. Formát JSON: Trvanlivost napříč dekádami

+

Data jsou strukturována do otevřeného, čistého a lidsky čitelného formátu JSON. Žádné proprietární databáze.

+
    +
  • Tvá data ti patří. Díky možnosti manuálního exportu si můžeš svůj myšlenkový fond odnést kamkoli – uložit si ho na svůj bezpečný lokální disk, nahrát na vlastní Git (GitHub/Gitea), nebo jej synchronizovat skrze cloudovou službu, kterou ty sám uznáš za bezpečnou.
  • +
  • Čistota formátu zaručuje, že tvé poznámky budou čitelné i za dvacet let na jakémkoli zařízení, bez ohledu na to, zda Doxa bude stále existovat.
  • +
+

3. Technická čistota a minimalismus (Vanilla Stack)

+

Pro zachování maximální rychlosti, nezávislosti a nulových externích závislostí je aplikace postavena výhradně na čistých webových standardech:

+
    +
  • Frontend (HTML5/CSS3): Minimalistické rozhraní, které nezatěžuje mysl barevným chaosem a vizuálním balastem moderního internetu.
  • +
  • Logika (Vanilla JavaScript ES6+): Žádné těžkopádné frameworky (React/Vue), které podléhají módním trendům a neustálým změnám. Čistý kód je trvanlivý jako tesání do kamene.
  • +
+

„Nezáleží na tom, jak složité jsou okolnosti kolem tebe. Když stavíš vlastní chrám myšlenek, začínáš od prvního kamene. Tento kód a tvá data jsou tvým vlastním, nedobytným hradem.“ + + — Stoický odkaz pro svobodné myslitele

+
+

Architektura

+
    +
  • Frontend: čisté HTML/CSS/JS (bez frameworků).
  • +
  • Datový formát: otevřený JSON — trvanlivý a přenosný.
  • +
  • + Local‑first: data jsou lokální (localStorage nebo soubor). +
  • +
+ +

Co bylo přidáno naposledy

+
  • Podpora více poznámek v jednom JSON (název + obsah).
  • +
  • Přidání, editace (inline + modal), mazání poznámek.
  • +
  • Přesouvání pořadí (šípky + drag & drop).
  • +
  • + Import / Export JSON a fallback mezi localStorage a lokálním + souborem (Electron). +
  • +
  • Přidána Markdown podpora
  • + + +

    Další plány

    +
      + +
    • Rozšíření UI (hledání, tagy, historie/undo).
    • +
    +
    +

    + Projekt najdeš v repozitáři + Codeberg. Pokud chceš přispět, otevři issue nebo PR. +

    +

    Web autora, další projekty a podpora: Lukáš Kanka

    +

    Aplikace je open-source a licencována pod MIT licencí.

    +
    + +

    Zpět na hlavní stránku

    +
    +