- Drop "Claude" prefix from titles, center all three - Replace verbose "Current Session" / "Current Week" labels with rounded pills above the bar; reset countdown moves below the bar - Extend bar to fill panel inner width (was 8px short) - Symmetric vertical pill placement within panel - Spinner: per-frame hold times + ping-pong indexing, modeled on Claude Code's Cavalry triangle oscillator (turn-around frames hold ~2x longer) - Bottom spinner re-centered between weekly panel and screen edge - screenshot.sh: 480x320 -> 480x480 for the new panel - CLAUDE.md: document screenshot.sh + temporary boot-screen swap as the standard self-QA workflow for UI changes
68 lines
1.7 KiB
Bash
Executable File
68 lines
1.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# Take a screenshot from the Waveshare AMOLED display via LVGL snapshot.
|
|
# Usage: ./screenshot.sh [output.png] [port]
|
|
|
|
OUTPUT="${1:-screenshot.png}"
|
|
PORT="${2:-/dev/ttyACM0}"
|
|
|
|
TMPRAW=$(mktemp /tmp/screenshot_XXXXXX.raw)
|
|
trap "rm -f '$TMPRAW'" EXIT
|
|
|
|
echo "Taking screenshot from $PORT..."
|
|
|
|
python3 - "$PORT" "$TMPRAW" << 'PYEOF'
|
|
import serial, sys
|
|
|
|
port_path, raw_path = sys.argv[1], sys.argv[2]
|
|
|
|
port = serial.Serial(port_path, 115200, timeout=10)
|
|
port.reset_input_buffer()
|
|
port.write(b"screenshot\n")
|
|
port.flush()
|
|
|
|
while True:
|
|
line = port.readline().decode("utf-8", errors="replace").strip()
|
|
if line.startswith("SCREENSHOT_START"):
|
|
parts = line.split()
|
|
w, h, raw_size = int(parts[1]), int(parts[2]), int(parts[3])
|
|
break
|
|
if line == "SCREENSHOT_ERR":
|
|
print("Device reported screenshot error", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
data = b""
|
|
while len(data) < raw_size:
|
|
chunk = port.read(min(4096, raw_size - len(data)))
|
|
if not chunk:
|
|
print(f"Timeout: got {len(data)} of {raw_size} bytes", file=sys.stderr)
|
|
sys.exit(1)
|
|
data += chunk
|
|
|
|
with open(raw_path, "wb") as f:
|
|
f.write(data)
|
|
|
|
for _ in range(10):
|
|
line = port.readline().decode("utf-8", errors="replace").strip()
|
|
if line == "SCREENSHOT_END":
|
|
break
|
|
|
|
port.close()
|
|
print(f"Captured {w}x{h} ({len(data)} bytes)")
|
|
PYEOF
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "Screenshot capture failed"
|
|
exit 1
|
|
fi
|
|
|
|
ffmpeg -y -f rawvideo -pixel_format rgb565le -video_size 480x480 \
|
|
-i "$TMPRAW" -update 1 -frames:v 1 "$OUTPUT" 2>/dev/null || true
|
|
|
|
|
|
if [ -f "$OUTPUT" ]; then
|
|
echo "Saved: $OUTPUT"
|
|
else
|
|
echo "Error: conversion failed"
|
|
exit 1
|
|
fi
|