feat: v0.1.0 — client Sailfish per hermes-webui con voce

- ApiClient HTTP/SSE: login, sessioni, chat/start, stream SSE, transcribe, tts
- ChatModel: streaming live + risincronizzazione dallo stato del server
- CookieJar persistente (0600, mai la password); Settings
- Recorder OGG/Opus (fallback WAV/PCM, retry); Player TTS (QMediaPlayer)
- UI Silica: splash, login, sessioni, chat (dettatura + read-aloud), settings, cover
- Sailjail Internet;Audio;Microphone; icone; spec RPM; docs PROTOCOL/BUILD
- tests/core_test: unit parser SSE + integrazione live (probe :8899)
This commit is contained in:
2026-09-12 07:11:20 +02:00
commit 9c6a1242f7
36 changed files with 2954 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
"""Icone per harbour-hermes: bolla di chat con onde sonore, palette Nord.
Uso: python3 scripts/make_icons.py [<output_dir>] [<name>]
Scrive <out>/<size>x<size>/<name>.png per 86, 108, 128, 172.
"""
import sys
import os
from PIL import Image, ImageDraw
BG = (46, 52, 64) # #2E3440
ACCENT = (136, 192, 208) # #88C0D0
PAGE = (229, 233, 240) # #E5E9F0
WAVE = (163, 190, 140) # #A3BE8C
def draw_icon(size):
img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
d = ImageDraw.Draw(img)
m = size * 0.05
d.rounded_rectangle([m, m, size - m, size - m], radius=size * 0.16, fill=BG)
# bolla di chat a sinistra
bx0, by0 = size * 0.18, size * 0.26
bx1, by1 = size * 0.56, size * 0.62
d.rounded_rectangle([bx0, by0, bx1, by1], radius=size * 0.07, fill=PAGE)
d.polygon([(size * 0.30, by1 - size * 0.01),
(size * 0.20, size * 0.74),
(size * 0.40, by1)], fill=PAGE)
# onde sonore a destra (tre archi concentrici)
cx, cy = size * 0.66, size * 0.585
for i, rr in enumerate((0.085, 0.155, 0.225)):
r = size * rr
d.arc([cx - r, cy - r, cx + r, cy + r], 300, 60,
fill=ACCENT if i < 2 else WAVE,
width=max(2, int(size * 0.028)))
# puntino sorgente
pr = size * 0.035
d.ellipse([cx - pr, cy - pr, cx + pr, cy + pr], fill=ACCENT)
return img
def main():
out_dir = sys.argv[1] if len(sys.argv) > 1 else "icons"
name = sys.argv[2] if len(sys.argv) > 2 else "harbour-hermes"
for s in (86, 108, 128, 172):
d = os.path.join(out_dir, "%dx%d" % (s, s))
os.makedirs(d, exist_ok=True)
draw_icon(s).save(os.path.join(d, name + ".png"))
print("icone scritte in %s/ (86..172)" % out_dir)
if __name__ == "__main__":
main()