Files
Voiced/README.md
T
xavierk 63422d9060 Add font import for Now, Gotham and Open Sauce One overrides; package fonts for Void
Font import:
- Migration M6 adds user_fonts; files are stored content-addressed under
  the local data dir. New Rust commands inspect, import, list, read and
  remove fonts, refusing WOFF2, collections, variable fonts and
  restricted fsType, and unpacking WOFF1 to plain sfnt.
- Imported fonts register in the render worker as user:<Face> families
  with an italic alias, and are pinned in the frozen render prefs so
  issued invoices can still re-render. Fonts referenced by issued
  invoices are hidden, never deleted.
- Size and tracking compensations tuned for the substitutes apply only
  while the face is not overridden; default output and fingerprint
  goldens are unchanged.
- Settings gets a Fonts section with a licence acknowledgement.

Void packaging:
- Install fonts to /usr/share/fonts/voiced with per-family OFL licences,
  set font_dirs, and add INSTALL/REMOVE scripts that run fc-cache.
  xbps-create carries both scripts (verified in a void-glibc container).
- Fix xbps-create dependency specs in build-xbps.sh.
2026-10-04 13:58:06 +05:30

154 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Voiced
An offline-first desktop invoicing app for **Arun P**, built by **Bongbetic**.
Voiced turns a few details into a clean, GST-ready PDF invoice. It keeps a running
invoice-number series in a local database, remembers your vendor and bank details, and
exports print-ready PDFs — no account, no network required.
## Features
- **Automatic invoice numbering** — a persistent series (e.g. `AP/2026-001`) that keeps
counting up, with a one-click "start a new series" that resets the counter.
- **Guided first-run setup** — your name, address, contact, PAN, GSTIN, logo, signature and
bank details, pre-filled from your existing invoice and editable at any time.
- **Two line-item modes** — a fixed amount, or a rate × quantity where the unit can be per
second / minute / hour / session / unit (e.g. 10 sessions × ₹2,500).
- **GST support** — toggle taxes on/off and split as **CGST + SGST** (within state) or
**IGST** (inter-state), with live totals and Indian amount-in-words.
- **Signatures** — attach a PNG/JPEG per invoice, or omit it and the invoice notes that it is
computer-generated and needs no signature.
- **PDF export** — a print-ready A4 invoice styled to match the original `format.pdf`.
- **Saved clients**, invoice history with re-export, and light/dark (Carbon g10/g100) themes.
- **Input validation** for PAN, IFSC, GSTIN, email and phone.
## Tech stack
| Layer | Choice |
| --------- | ------------------------------------------------------------------- |
| Shell | [Tauri v2](https://v2.tauri.app/) (Rust core, WebView2 on Windows) |
| UI | React + TypeScript + [IBM Carbon Design System](https://carbondesignsystem.com/) (`@carbon/react`) |
| Fonts | IBM Plex, self-hosted (works offline) |
| Storage | SQLite via `rusqlite` (bundled) |
| PDF | `@react-pdf/renderer` with bundled IBM Plex |
## Prerequisites
- **Node.js 20+** and npm
- **Rust** (stable) via [rustup](https://rustup.rs/)
- Linux dev only: WebKitGTK 4.1, libsoup3, GTK3, librsvg, `pkg-config`, `clang`/`llvm`/`lld`
## Development
```bash
npm install
npm run app:dev # launches the desktop app with hot reload
```
Other scripts:
```bash
npm run build # type-check + build the web frontend
npm run app:build # package the app for the current platform
```
## Building for Windows (cross-compile from Linux/macOS)
Tauri only supports the MSVC target. Cross-compiling uses [`cargo-xwin`](https://github.com/rust-cross/cargo-xwin)
and produces an **NSIS installer** plus a portable `.exe`. A `.msi` still requires a real
Windows host.
```bash
# one-time setup
rustup target add x86_64-pc-windows-msvc
cargo install --locked cargo-xwin
# plus NSIS (makensis), LLVM/LLD and clang on the host
npm run app:build:windows
```
Output lands in `src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/` and the
portable binary in the sibling `release/` folder.
### Notes for Linux hosts without an `nsis` package
`makensis` is required for the installer, and Tauri also fetches a small NSIS plugin. On
distributions that don't package NSIS (e.g. Void Linux):
1. Provide `makensis` (e.g. extract it from your distribution's or an upstream package) and
put it on `PATH`.
2. Point `makensis` at a full NSIS data directory (3.11 recommended, for `Win/RestartManager.nsh`);
it looks in the directory compiled into the binary unless `NSISDIR` is set.
3. Pre-seed Tauri's plugin cache so it does not have to download it:
```
mkdir -p ~/.cache/tauri/NSIS/Plugins/x86-unicode/additional
# nsis_tauri_utils.dll (SHA1 75197fee3c6a814fe035788d1c34ead39349b860)
# from https://github.com/tauri-apps/nsis-tauri-utils/releases
```
With those in place, `npm run app:build:windows` produces the NSIS `-setup.exe` and the
portable `voiced.exe`.
## Installing on Void Linux
Two ways to get a native `.xbps` package.
### Prebuilt binary package (no xbps-src needed)
```bash
./packaging/void/build-xbps.sh # -> build/void/repo/voiced-<version>_1.<arch>.xbps
echo "repository=$(pwd)/build/void/repo" | sudo tee /etc/xbps.d/99-voiced-local.conf
sudo xbps-install -Sy voiced
```
Launch **Voiced** from the application menu, or run `voiced`. Remove it with
`sudo xbps-remove voiced`.
The package installs `/usr/bin/voiced`, a desktop entry and hicolor icons, and depends on
`libwebkit2gtk41`.
**Fonts on Void.** The package also installs the bundled TTF fonts under
`/usr/share/fonts/voiced/<family>/` and each family's OFL licence under
`/usr/share/licenses/voiced/`. The `voiced/` subdirectory avoids file conflicts with Void's own
`font-ibm-plex-ttf` and `noto-fonts-ttf`. The `INSTALL` and `REMOVE` scripts in `packaging/void/`
run `fc-cache -f /usr/share/fonts/voiced` after install and removal. `xbps-create` packs them from
the destdir root (checked with xbps 0.60.7).
### Building through xbps-src
Copy `packaging/void/template` into a `void-packages` checkout and build it the standard way:
```bash
mkdir -p void-packages/srcpkgs/voiced
cp packaging/void/template packaging/void/INSTALL packaging/void/REMOVE void-packages/srcpkgs/voiced/
cd void-packages && ./xbps-src pkg voiced
```
See the comments at the top of the template about the private source archive and checksums.
## Where data lives
| What | Location |
| ------------------- | ------------------------------------------------------------- |
| Database | `<app-data>/voiced.db` — on Windows `%APPDATA%\com.bongbetic.voiced\` |
| Logos & signatures | `<app-data>/assets/` |
## Project layout
```
src/ React + Carbon frontend
views/ Onboarding · NewInvoice · InvoiceHistory · SeriesSettings · AppSettings
components/ AppShell · InvoicePreview · ImagePicker
pdf/ InvoiceDocument (react-pdf template)
lib/ api · types · invoice · numberToWords · validators · format · pdf
src-tauri/ Rust backend (Tauri commands, SQLite schema, asset store)
public/brand/ Bongbetic + vendor brand assets
public/fonts/ IBM Plex (woff/woff2)
packaging/void/ Void Linux packaging (xbps-src template + build script + desktop entry)
```
## Ownership
© Bongbetic. All rights reserved. This is a private application.