update project documentation
This commit is contained in:
parent
5588d95957
commit
2cde9df163
224
FS.md
224
FS.md
@ -0,0 +1,224 @@
|
|||||||
|
# **WhspBrd — Functional Requirements**
|
||||||
|
|
||||||
|
## I. **Core Functional Requirements**
|
||||||
|
|
||||||
|
### 1. **Terminal-Based User Interface (TUI)**
|
||||||
|
|
||||||
|
* **Framework**: Use `gocui` for building a rich, responsive text-based UI.
|
||||||
|
* **Components**:
|
||||||
|
|
||||||
|
* Chat window (scrollable history).
|
||||||
|
* Contact list / chat list panel.
|
||||||
|
* Input field for typing messages.
|
||||||
|
* Status bar with connection/server/user status.
|
||||||
|
|
||||||
|
* **Image Rendering**:
|
||||||
|
|
||||||
|
* Render `.png`, `.jpg`, and `.gif` images in terminal using our own implementation of [Kitty graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/).
|
||||||
|
* Display avatars inline next to usernames.
|
||||||
|
* Display inline images within messages (resizable).
|
||||||
|
|
||||||
|
### 2. **Secure Messaging**
|
||||||
|
|
||||||
|
* **PGP Encryption**:
|
||||||
|
|
||||||
|
* All messages are encrypted locally using the recipient's PGP public key.
|
||||||
|
* Messages are decrypted only on the receiving client.
|
||||||
|
* **Message Routing**:
|
||||||
|
|
||||||
|
* Messages are routed through a central server only for delivery.
|
||||||
|
* Server does **not store** any message content.
|
||||||
|
* **Offline Message Storage**:
|
||||||
|
|
||||||
|
* Server temporarily caches messages for **offline users** for a configurable TTL (e.g., 12–48 hours).
|
||||||
|
* If the user does not connect in that window, the message is deleted, and the sender is notified.
|
||||||
|
|
||||||
|
### 3. **Client Data Management**
|
||||||
|
|
||||||
|
* **Local Storage**:
|
||||||
|
|
||||||
|
* All messages are stored client-side in `.json` files per conversation.
|
||||||
|
* Embedded images are stored as:
|
||||||
|
|
||||||
|
* RGBA raw data in JSON (Base64-encoded).
|
||||||
|
* A PNG copy in a parallel `media/` folder.
|
||||||
|
* **PGP Keys**:
|
||||||
|
|
||||||
|
* Each user maintains a local PGP key pair.
|
||||||
|
* Ability to import/export keys.
|
||||||
|
* Server can validate keys via a **Web of Trust** model.
|
||||||
|
|
||||||
|
### 4. **Systray & Notifications**
|
||||||
|
|
||||||
|
* **Systray Integration**:
|
||||||
|
|
||||||
|
* Use `getlantern/systray` for showing status icon.
|
||||||
|
* Show connection status, current server, unread message badge.
|
||||||
|
* **System Notifications**:
|
||||||
|
|
||||||
|
* Use `beeep` to show toast notifications (cross-platform).
|
||||||
|
* Trigger on:
|
||||||
|
|
||||||
|
* New message.
|
||||||
|
* User mentions.
|
||||||
|
* Connection status changes.
|
||||||
|
|
||||||
|
### 5. **Server Communication**
|
||||||
|
|
||||||
|
* **Server Role**:
|
||||||
|
|
||||||
|
* Acts as a message relay and presence manager.
|
||||||
|
* Handles identity validation through a Web of Trust.
|
||||||
|
* Temporary offline message cache (with expiry).
|
||||||
|
* **Multiple Server Support**:
|
||||||
|
|
||||||
|
* User can connect to multiple servers at once.
|
||||||
|
* Prioritize closest/fastest server for message delivery.
|
||||||
|
* **Server Authentication**:
|
||||||
|
|
||||||
|
* Server identifies users via PGP signature.
|
||||||
|
* No traditional password-based auth.
|
||||||
|
|
||||||
|
### 6. **CLI Messaging Tool (Non-TUI)**
|
||||||
|
|
||||||
|
* Quick command-line utility to send messages:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
whspbrd --to user123 --message "hey!"
|
||||||
|
```
|
||||||
|
|
||||||
|
* Designed for shell scripting, automation, cronjobs.
|
||||||
|
* Uses same encryption and delivery mechanism as TUI.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## II. Optional / Extended Functionality
|
||||||
|
|
||||||
|
### 1. **Peer-to-Peer Messaging (Local Network)**
|
||||||
|
|
||||||
|
* **Automatic LAN Discovery**:
|
||||||
|
|
||||||
|
* Bonjour/mDNS or UDP broadcast for peer discovery.
|
||||||
|
* **Direct LAN Messaging**:
|
||||||
|
|
||||||
|
* If users are in same network, bypass server and send messages directly.
|
||||||
|
* Messages still encrypted with PGP.
|
||||||
|
* **Fallback**: If P2P fails, fallback to server-based delivery.
|
||||||
|
|
||||||
|
### 2. **Plugin System (C Modules)**
|
||||||
|
|
||||||
|
* Optional C plugin support.
|
||||||
|
* Users can write extensions for:
|
||||||
|
|
||||||
|
* UI customization.
|
||||||
|
* Automation hooks.
|
||||||
|
* Custom message processors.
|
||||||
|
* Plugin sandboxing required to maintain app security.
|
||||||
|
|
||||||
|
### 3. **Music Sharing Integration (Linux Only)**
|
||||||
|
|
||||||
|
* Use `playerctl` and `MPRIS` to:
|
||||||
|
|
||||||
|
* Detect current track on Spotify/VLC/etc.
|
||||||
|
* Optionally share what you're listening to in status.
|
||||||
|
* Enable `/nowplaying` command to post track in chat.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## III. 🔧 Non-Functional Requirements
|
||||||
|
|
||||||
|
### 1. **Cross-Platform Support**
|
||||||
|
|
||||||
|
* Full support for:
|
||||||
|
|
||||||
|
* Linux
|
||||||
|
* macOS
|
||||||
|
* Windows (via WSL or native terminal)
|
||||||
|
* All features should work identically or degrade gracefully.
|
||||||
|
|
||||||
|
### 2. **Performance & Responsiveness**
|
||||||
|
|
||||||
|
* TUI should remain responsive even with long message histories.
|
||||||
|
* Image rendering must be optimized to avoid lag.
|
||||||
|
|
||||||
|
### 3. **Security**
|
||||||
|
|
||||||
|
* End-to-end encryption by default (no toggle).
|
||||||
|
* No unencrypted message is ever sent or stored.
|
||||||
|
* All key exchange and server handshake must be encrypted.
|
||||||
|
|
||||||
|
### 4. **Portability**
|
||||||
|
|
||||||
|
* App should be easy to compile with `go build` on all platforms.
|
||||||
|
* Minimal external dependencies.
|
||||||
|
|
||||||
|
### 5. **Configurability**
|
||||||
|
|
||||||
|
* Config file in JSON format.
|
||||||
|
* User can configure:
|
||||||
|
|
||||||
|
* Servers
|
||||||
|
* Avatar/image size
|
||||||
|
* Notification preferences
|
||||||
|
* Logging level
|
||||||
|
|
||||||
|
### 6. **Logging & Debugging**
|
||||||
|
|
||||||
|
* Optional encrypted log file support (for debugging).
|
||||||
|
* CLI flags like `--verbose`, `--log`, `--debug`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IV. 📦 Directory and File Structure Example
|
||||||
|
|
||||||
|
```shell
|
||||||
|
~/.config/whspbrd/
|
||||||
|
├── config.json
|
||||||
|
├── keys/
|
||||||
|
│ ├── private.asc
|
||||||
|
│ └── public.asc
|
||||||
|
├── messages/
|
||||||
|
│ ├── user123.json
|
||||||
|
│ └── user456.json
|
||||||
|
├── media/
|
||||||
|
│ ├── user123_avatar.png
|
||||||
|
│ └── msg_img_abc123.png
|
||||||
|
├── plugins/
|
||||||
|
│ └── music_status.so
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## V. 📌 Example Use Cases
|
||||||
|
|
||||||
|
### 1. TUI Chat
|
||||||
|
|
||||||
|
* Open app from terminal:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
whspbrd
|
||||||
|
```
|
||||||
|
|
||||||
|
* Chat using keyboard-driven TUI interface.
|
||||||
|
|
||||||
|
### 2. CLI Send
|
||||||
|
|
||||||
|
* Send message directly from terminal:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
whspbrd --to alice --message "Meeting at 5?"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Tray & Notifications
|
||||||
|
|
||||||
|
* App minimized to tray.
|
||||||
|
* Incoming message triggers `beeep` notification.
|
||||||
|
|
||||||
|
### 4. Local Network P2P
|
||||||
|
|
||||||
|
* Two devices on same Wi-Fi detect each other.
|
||||||
|
* Chat without routing via server.
|
||||||
|
|
||||||
|
### 5. Plugin Example
|
||||||
|
|
||||||
|
* Load plugin that sends an auto-reply or updates presence from external data.
|
||||||
24
README.md
Normal file
24
README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# WhspBrd
|
||||||
|
|
||||||
|
- Run main loop, for now
|
||||||
|
|
||||||
|
```shell
|
||||||
|
go run cmd/tui/main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
## File structure
|
||||||
|
|
||||||
|
- may be edited in accordance with [this project standard](https://github.com/golang-standards/project-layout)
|
||||||
|
|
||||||
|
### pkg
|
||||||
|
|
||||||
|
- reusable modules in other projects and used imports, like image manipulation, systray configuration etc...
|
||||||
|
|
||||||
|
### cmd
|
||||||
|
|
||||||
|
- future command line application structure using cobra in cli folder
|
||||||
|
- tui in tui folder, makes sense huh
|
||||||
|
|
||||||
|
### internal
|
||||||
|
|
||||||
|
- code that is not reusable and we don't want to share it with others, maybe parts of code in cmd will be moved here instead
|
||||||
@ -3,15 +3,30 @@
|
|||||||
## GO
|
## GO
|
||||||
|
|
||||||
- Klient aplikace pro uživatele a komunikace se serverem
|
- Klient aplikace pro uživatele a komunikace se serverem
|
||||||
- <https://github.com/jroimartin/gocui> - vizuální stránka aplikace, nejde rendrovat obrázky
|
- <https://github.com/jroimartin/gocui> - vizuální stránka aplikace JOO
|
||||||
- <https://github.com/rivo/tview> - vizuální stránka aplikace
|
- <https://github.com/dolmen-go/kittyimg> - rendrování obrázků v terminálu NEE, napsali jsme vlastní
|
||||||
- <https://github.com/dolmen-go/kittyimg> - rendrování obrázků v terminálu
|
|
||||||
(profilové obrázky nebo posílané médium)
|
(profilové obrázky nebo posílané médium)
|
||||||
|
- <https://github.com/getlantern/systray> - systray pro windows, linux, i macos
|
||||||
|
- <https://github.com/gographics/imagick> - image editing NEEE, nepotřebujeme actually
|
||||||
|
- <https://github.com/gen2brain/beeep> - notifikace an windows i linux
|
||||||
|
|
||||||
## C
|
## C
|
||||||
|
|
||||||
- Pro rendrování a hashovací algoritmy v klient aplikaci embeded v go kodu
|
- Pro rendrování a hashovací algoritmy v klient aplikaci embeded v go kodu
|
||||||
|
|
||||||
## Java
|
## Java?
|
||||||
|
|
||||||
- Server pro komunikaci mezi uživateli
|
- Server pro komunikaci mezi uživateli
|
||||||
|
|
||||||
|
## Magick pro změnu obrázků
|
||||||
|
|
||||||
|
- resize pro obrázky na 2 řádkovou resolution convert output.png\
|
||||||
|
\( +clone -alpha extract\
|
||||||
|
-draw 'fill black polygon 0,0 0,15 15,0 fill white circle 15,15 15,0'\
|
||||||
|
\( +clone -flip \) -compose Multiply -composite\
|
||||||
|
\( +clone -flop \) -compose Multiply -composite\
|
||||||
|
\) -alpha off -compose CopyOpacity -composite kogami-rounded.png
|
||||||
|
|
||||||
|
## Nápady
|
||||||
|
|
||||||
|
- načítat a sdílet přehrávanou hudbu (discord spotify integration, but with playerctl or some other music protocol)
|
||||||
|
|||||||
0
configs/config.json
Normal file
0
configs/config.json
Normal file
0
configs/servers/default/server.json
Normal file
0
configs/servers/default/server.json
Normal file
0
configs/servers/default/users/alice/alice.pub
Normal file
0
configs/servers/default/users/alice/alice.pub
Normal file
0
configs/servers/default/users/alice/messages.json
Normal file
0
configs/servers/default/users/alice/messages.json
Normal file
0
configs/servers/default/users/bob/bob.pub
Normal file
0
configs/servers/default/users/bob/bob.pub
Normal file
0
configs/servers/default/users/bob/messages.json
Normal file
0
configs/servers/default/users/bob/messages.json
Normal file
3
go.mod
3
go.mod
@ -3,9 +3,9 @@ module whspbrd
|
|||||||
go 1.24.2
|
go 1.24.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dolmen-go/kittyimg v0.0.0-20250507221057-648811cc98ed
|
|
||||||
github.com/getlantern/systray v1.2.2
|
github.com/getlantern/systray v1.2.2
|
||||||
github.com/jroimartin/gocui v0.5.0
|
github.com/jroimartin/gocui v0.5.0
|
||||||
|
golang.org/x/sys v0.30.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/rivo/uniseg v0.4.7 // indirect
|
require github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
@ -21,5 +21,4 @@ require (
|
|||||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
github.com/nsf/termbox-go v1.1.1 // indirect
|
github.com/nsf/termbox-go v1.1.1 // indirect
|
||||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
||||||
golang.org/x/sys v0.30.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@ -1,7 +1,5 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dolmen-go/kittyimg v0.0.0-20250507221057-648811cc98ed h1:kDKSQ5o62eFce2771pkdTu6kjv4I3s5dFhe6gXgSeUg=
|
|
||||||
github.com/dolmen-go/kittyimg v0.0.0-20250507221057-648811cc98ed/go.mod h1:2vk7ATPVcI7uW4Sh6PrSQvtO+Czmq8509xcg/y8Osd0=
|
|
||||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
|
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
|
||||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
|
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
|
||||||
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So=
|
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So=
|
||||||
|
|||||||
@ -6,13 +6,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Resize(img image.RGBA, width int, height int) (*image.RGBA, error) {
|
func Resize(img image.RGBA, width int, height int) (*image.RGBA, error) {
|
||||||
if width <= 0 || height <= 0 {
|
originalWidth := img.Bounds().Dx()
|
||||||
|
originalHeight := img.Bounds().Dy()
|
||||||
|
|
||||||
|
if width <= 0 && height <= 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
} else if width <= 0 {
|
||||||
|
width = int(float64(height) * float64(originalWidth) / float64(originalHeight))
|
||||||
|
} else if height <= 0 {
|
||||||
|
height = int(float64(width) * float64(originalHeight) / float64(originalWidth))
|
||||||
}
|
}
|
||||||
|
|
||||||
newImg := image.NewRGBA(image.Rect(0, 0, width, height))
|
newImg := image.NewRGBA(image.Rect(0, 0, width, height))
|
||||||
scaleX := float64(img.Bounds().Dx()) / float64(width)
|
scaleX := float64(originalWidth) / float64(width)
|
||||||
scaleY := float64(img.Bounds().Dy()) / float64(height)
|
scaleY := float64(originalHeight) / float64(height)
|
||||||
|
|
||||||
for y := 0; y < height; y++ {
|
for y := 0; y < height; y++ {
|
||||||
for x := 0; x < width; x++ {
|
for x := 0; x < width; x++ {
|
||||||
|
|||||||
@ -7,9 +7,12 @@ in
|
|||||||
webkitgtk
|
webkitgtk
|
||||||
openssl
|
openssl
|
||||||
libayatana-appindicator
|
libayatana-appindicator
|
||||||
|
#imagemagickBig
|
||||||
];
|
];
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
pkg-config
|
pkg-config
|
||||||
];
|
];
|
||||||
dbus = pkgs.dbus;
|
dbus = pkgs.dbus;
|
||||||
|
|
||||||
|
#PKG_CONFIG_PATH = "${pkgs.imagemagickBig.dev}/lib/pkgconfig";
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user