Skip to content

v0.3.2

Choose a tag to compare

@miaoledor miaoledor released this 28 Aug 02:16
· 236 commits to main since this release

What's New in v0.3.0 – v0.3.2

This release is the biggest update since the initial counter launch — 142 commits across three minor versions. The headline changes are a completely rewritten rendering engine (imgcore), a unified theme model (cards + characters merged into one), a brand-new in-browser theme editor, and 6 new character themes.


🎨 New: In-Browser Theme Editor (v0.3.2)

A full visual workbench for creating and editing themes without leaving the browser — no local toolchain required.

  • Visual canvas with zoom controls, collapsible sidebars, grid overlay, and coordinate display
  • Layer panel: drag-to-reorder with FLIP animation, editable layer names, per-layer image picker, index badges
  • Quick edit mode with animated mode-switching; defaults to quick mode on load
  • Drag images directly onto the canvas; position editing via drag or numeric inputs
  • Text layer controls (collapsible by default) for counter text styling
  • Export: preview as SVG, export as PNG image, or export full theme ZIP
  • Auto-save to localStorage with manual save-as-draft and draft management
  • Upload guide: GitHub PR flow modal with email hint (replaces disabled upload button)
  • Mobile-first layout: sidebars stack on top, canvas gets priority space, pointer-capture fixes for touch dragging
  • Light theme matching the main site (previously dark)

New API endpoints:

  • POST /api/editor/preview — render a preview SVG from editor state
  • POST /api/editor/export — export a full theme package (ZIP)

The upload channel (POST /api/themes) is reserved for a future release and not yet implemented.


🏗️ New: Unified Rendering Engine (imgcore)

The rendering core was rewritten from scratch around a clean layer-stack model. The server now only calls composer.Compose — all rendering logic lives in internal/imgcore.

  • Layer interface with four implementations: ImageLayer, RandomPickLayer (multi-frame random), GroupLayer (PSD coordinate mapping), TextLayer (counter text)
  • composer.Compose merges all layers sorted by ZIndex; viewBox = max(bg width, text width) × (bg height + text height)
  • Seed-driven PRNG for deterministic per-request random rendering (every request picks a fresh frame/layer combo)
  • scale (controls background display size) and fsize (controls text font size) are now independent
  • Text positioning: x/y (pixels) or rx/ry (ratio 0–1); defaults to centered below the image
  • Theme registry loads f-theme JSON from embedded assets at startup

🔀 Unified Theme Model

Cards and characters are no longer separate concepts — they're all just themes with different layer stacks.

  • Merged character themes into assets/theme/<name>/ (previously separate directories)
  • Loader auto-dispatches single-layer (frames directly in dir) vs. multi-layer (ren.json + config.json + ren/*.webp) based on whether ren.json exists
  • Removed the mode/kind/seq parameters entirely — all themes now random-pick per request
  • Unified theme showcase gallery on the website (single gallery section, no more tabs)
  • Variant count exposed via GET /api/themes and shown as a badge on showcase cards (variations: N)
  • Z-order convention documented and enforced: ascending bottom-to-top; gen-character uses natural order (lass → eye → mouth → face)

🎭 New Character Themes

6 new character themes added, all generated via a parameterized multi-character pipeline:

  • furi
  • miyu
  • minato
  • yuzu
  • nanami
  • hinata (regenerated via the unified pipeline)

The old single-purpose gen-hinata script was replaced by a reusable gen-character generator.


⚡ Performance & Asset Optimization

  • All theme PNGs converted to WebP format (smaller payload, faster loads)
  • Added PNG/JPG → WebP conversion script (scripts/)
  • Removed unreachable arc-text and geometry helper dead code from imgcore
  • Removed unused ImageCarousel component and randomNum util from the frontend

🔐 Admin & Security

  • ADMIN_KEY config and admin auth middleware added
  • Server BodyLimit and timeouts increased to handle large editor payloads safely
  • Tests cover demo multi-frame caching and admin auth flows

🌐 Website & UX

  • Language switcher: pinned to top-right, scrolls with content, added to editor toolbar
  • About page: split into a separate page with a KUN-style auto-paging notice board
  • Navigation: anchor links now correctly navigate back to home from other pages
  • Theme showcase: dropdown polish, variant badge anchored to card corner
  • Replaced Google Fonts fetch with a local font stack (no external dependency, faster, privacy-friendly)

🧪 Testing

Significantly expanded test coverage:

  • imgcore/composer: integration tests for card scale, text, Z-order; f-theme registry loader tests
  • server: bridge helper unit tests, position Y-coordinate verification, demo multi-frame cache + admin auth
  • editor: end-to-end tests for card and character theme flows
  • gen-character: unit tests for pure generation functions

📚 Documentation

  • Multi-layer theme format and Z-order convention documented
  • Character theme JSON schemas documented
  • Theme export workflow and admin key auth design docs
  • Theme upload + review/voting design docs (for the future upload channel)
  • All stale references synced with the current codebase after the theme unification refactor

📦 Upgrade Notes

  • No database migration needed — tb_count schema is unchanged
  • New env var: ADMIN_KEY (optional — only needed if you use admin-protected endpoints)
  • Theme directory structure changed: character themes moved into assets/theme/<name>/. If you have custom themes outside the standard structure, regenerate them via gen-character or move them manually
  • All theme assets are now WebP; ensure your gen-themes-json.js / check-theme workflows are up to date
  • godotenv is now a direct dependency (was previously transitive)

Full changelog: compare [v0.2.10...v0.3.2](https://github.com/miaoledor/Lolicount/compare/v0.2.10...v0.3.2)