~bigbes/memestudio · issues

trqpihcpj8p84im72kat53knd1gir4ue · 20 rows

idcontent_hashtitledescriptiondesignacceptance_criterianotesstatuspriorityissue_typeassigneeestimated_minutescreated_atcreated_byownerupdated_atclosed_atclosed_by_sessionexternal_refspec_idcompaction_levelcompacted_atcompacted_at_commitoriginal_sizesenderephemeralwisp_typepinnedis_templatemol_typework_typesource_systemmetadatasource_repoclose_reasonevent_kindactortargetpayloadawait_typeawait_idtimeout_nswaitershook_beadrole_beadagent_statelast_activityrole_typerigdue_atdefer_untilno_historystarted_atis_blocked
memestudio-0pn2d3546992fa62b4fb012904f36311d7b53068eec339edc5bb7116e67b67e5b55Template search / Cmd-K filteringThe sidebar 'Search templates' box and Cmd-K are static markup. Wire real filtering of the template tiles (and gallery) by name.closed2featureNULLNULL2026-07-18T15:21:26ZEugene Blikhbigbes@gmail.com2026-07-18T18:51:30Z2026-07-18T18:51:30ZNULL0NULLNULLNULL000�{}Wired real template search: sidebar #tplSearch input filters the template grid by name (case-insensitive), ⌘K focuses it (inline field, not a modal — respects invariant 1), Escape clears+blurs. data-tpl keeps original index so filtered tiles click through; #tplCount shows matches/total. Also fixed a latent bug where the hidden attr on .side-group/.memes was overridden by display:flex (My memes group leaked into the no-backend view). Verified headlessly.0NULLNULLNULL0NULL0
memestudio-1ar2518a690d46b48ebda1885f57efeaced5de3054d756567e8a0eb99b10b31032dNamed saves — 'my memes' galleryBackend autosaves ONE document. Add a memes table (id, name, doc json, thumb, updated_at) + API (list/create/open/delete) and a sidebar 'My memes' list so you can save, name, and reopen multiple memes. Autosave the current draft on top.closed1featureEugene BlikhNULL2026-07-18T15:21:24ZEugene Blikhbigbes@gmail.com2026-07-18T18:25:32Z2026-07-18T18:25:32ZNULL0NULLNULLNULL000�{}Named saves shipped: memes table + list/create/get/put/delete API; 'My memes' sidebar with save (create-or-update-in-place), open, inline rename, delete, and compose() thumbnails. ⌘S + New. Live /api/doc autosave stays the draft. Verified full-stack in headless Chrome incl. reload persistence and no-backend fallback.0NULLNULLNULL02026-07-18T18:16:40Z0
memestudio-1hv3ba5e17af917b3b11ed1a8e9252904435506dd6f67ff50ac65d8ee1f1b700dd3Canvas zoomThe -/100%/+ zoom control is static markup; the canvas never scales. Add real zoom that scales the stage visually without changing output size, and make drag/draw/pointer math divide by the scale so hit-testing stays correct.closed2featureEugene BlikhNULL2026-07-18T15:21:25ZEugene Blikhbigbes@gmail.com2026-07-19T21:13:59Z2026-07-19T21:13:59ZNULL0NULLNULLNULL000�{}Implemented 25%-200% preview zoom with native-coordinate pointer conversion across all editor gestures; verified unchanged compositor dimensions and full interaction coverage in headless Chrome.0NULLNULLNULL02026-07-19T21:06:21Z0
memestudio-2og340ec60a8e26a4753d58bd8e45081523a26923f7bd9d8e6b30de3fe8d9371c28Dedicated eraser / Draw-Erase modeThe Brush inspector spec shows a Draw/Erase mode toggle that isn't wired. Add an eraser: either a real erase mode that removes ink under the cursor, or at minimum a 'Clear drawing' action. Today removal is select-a-stroke + Delete, or undo.closed1featureEugene BlikhNULL2026-07-18T15:21:23ZEugene Blikhbigbes@gmail.com2026-07-18T18:05:46Z2026-07-18T18:05:46ZNULL0NULLNULLNULL000�{}Implemented Draw/Erase mode toggle + Clear-drawing action. Erase drags remove whole strokes under the cursor (vector model), one undo step per gesture; Clear wipes the ink layer in one step. Verified in headless Chrome via __ms.0NULLNULLNULL02026-07-18T18:01:21Z0
memestudio-5tg9f0c3bb66b0a4acbb843705e883b950bc48326ffb0fc9fb4e1fe61e74cd01d63Make preset text editable and add image transform workflowPreset captions are partly baked into layout markup, text styling lacks outline/background controls, two obsolete presets remain exposed, placed images only have one resize behavior, and imported or pasted images cannot be cropped before insertion. Unify preset captions with editable text layers, add explicit text outline and bubble-background styling, remove Speech bubble and 3-panel presets, add ratio-locked versus stretch image resizing, and route image insertion through a live crop preview.Use per-preset starter text definitions that seed real state.texts only when a preset is selected, so DOM editing, history, persistence, and compose share one model. Extend text records with outlineColor and a background object while preserving defaults for old documents. Extend placed-image records with resizeMode and make the existing corner gesture preserve ratio only in locked mode. Build one native crop dialog backed by canvas, with draggable image positioning and zoom, returning a normalized data URL through the existing image-processing pipeline; use it for gallery imports, base-template imports, and clipboard image files.Every visible preset caption is represented by an editable/exported text layer; outline color is configurable with presets and a custom picker; text background supports Transparent and Bubble, with Bubble background color, radius, and background-only opacity; Speech bubble and 3-panel presets are removed and preset counts remain accurate; placed images can switch between locked-aspect resize and free stretch, persist that mode, and export identically; file imports and clipboard image paste can preview, reposition, zoom, crop, or use the full image before insertion; existing documents migrate safely; browser interaction checks plus Go, JS, and Docker gates pass.closed1featureEugene BlikhNULL2026-07-19T23:43:06ZEugene Blikhbigbes@gmail.com2026-07-20T00:04:41Z2026-07-20T00:04:41ZNULL0NULLNULLNULL000�{}Implemented editable text layers for every remaining preset; configurable outline and Bubble styling; removed Speech bubble and 3-panel; added Ratio/Stretch placed-image resizing; added live crop workflow for base/gallery imports and clipboard paste; documented and validated JS, browser interactions/migration, Go test/race/vet/build, and Docker build.0NULLNULLNULL02026-07-19T23:43:09Z0
memestudio-6zd53e44e106af84ad93c7d13fae980f2efb887c97d0f6da002106a9384196c3a71Paste-from-clipboard into template picker and galleryGlobal paste already drops a clipboard image as a placed overlay layer. Add a Paste affordance in (1) the template picker (base image / preset slot) and (2) the image gallery (built-in-style user image), reusing the crop + prepareImage flow via navigator.clipboard.read().open2featureNULLNULL2026-07-24T09:56:20ZEugene Blikhbigbes@gmail.com2026-07-24T09:56:20ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
memestudio-7ho64a474bb242581d985c6bf88de3d906ab0322e804eacdea7ce575653ded4442eReal gallery sticker thumbnailsThe 12 built-in 'Insert image' gallery items are hue-gradient placeholders (GALLERY array). Only user-imported images are real bitmaps. Seed real sticker images (e.g. a small bundled set or reuse the imgflip fetcher) so the built-in gallery is real.closed2featureEugene BlikhNULL2026-07-18T15:21:25ZEugene Blikhbigbes@gmail.com2026-07-19T21:31:53Z2026-07-19T21:31:53ZNULL0NULLNULLNULL000�{}Replaced all twelve gallery placeholders with bundled original 640px transparent PNG stickers, added alpha-aware preview/edge/compositor rendering, persisted sticker metadata, and verified browser and container packaging behavior.0NULLNULLNULL02026-07-19T21:14:12Z0
memestudio-80185c866ea39779ef7b6b4ac31c44d6fa77818d2a892de5b9e7fba78d836237d90Drop preset-baked 'Ship it' captionNow that real text layers exist, the hardcoded 'Ship it' caption baked into the classic preset (and similar baked captions) is redundant and overlaps user text. Make presets pure layouts; the classic base should be image-only.closed2choreNULLNULL2026-07-18T15:21:24ZEugene Blikhbigbes@gmail.com2026-07-18T18:56:08Z2026-07-18T18:56:08ZNULL0NULLNULLNULL000�{}Classic preset is now image-only: dropped the baked 'Ship it' caption from the DOM core(), the compositor (CORE_PAINT.classic, incl. its backing scrim), and the layer-list indicator row. Removed the now-dead .bar CSS. Multi-panel presets keep their illustrative captions (preset furniture on still-mock layouts) — the concrete overlap-with-user-text harm was classic-specific. Verified: classic has no .meme-text/.bar/Ship-it row, export works, other presets unchanged.0NULLNULLNULL0NULL0
memestudio-8mr1e3adb3219ffb8ca6883db4f88a88857b55ff0f877cf99795ceb9302198c6020Use selected images inside presets and expose meme actionsNon-classic presets currently render placeholder gradients instead of the selected template, image mirroring is hard to discover, saved memes can only be renamed through a hidden double-click gesture, and the inspector contains an unwanted local-render footer. Make preset image slots use the active template automatically with an explicit way to choose replacement images, expose mirroring for inserted image layers, add a visible rename action for My Memes, and remove the footer.Represent preset image cells as addressable slots. Resolve each slot from a user override first, then the active template, then the existing placeholder. Render the same resolution path in DOM previews and canvas export, and let users select a slot to choose an existing gallery/template image or import through the current crop workflow. Keep placed-image mirroring on the layer model but expose it as a clear Mirror control. Add an explicit rename button to each saved-meme row while preserving inline rename behavior.Demotivator, 4-panel, 2-panel, Comparison, and Deep-fried show the active template inside their image areas automatically; each preset image area can be replaced when no suitable template is selected and DOM/export agree; image layers have an obvious horizontal mirror action that persists and exports; My Memes rows have a visible rename action; the Local/Rendered in your browser footer is gone; old documents load with placeholder fallbacks; browser interaction checks plus JS, Go, and Docker gates pass.closed1featureEugene BlikhNULL2026-07-20T00:22:44ZEugene Blikhbigbes@gmail.com2026-07-20T00:36:10Z2026-07-20T00:36:10ZNULL0NULLNULLNULL000�{}Implemented active-template inheritance and persisted per-panel overrides for all non-classic presets, Image-tool panel replacement and upload fallback, explicit image Mirror controls, a visible end-to-end My Memes rename action, and removed the local-render footer. Validated static/browser workflows, backend persistence and rename, old-state migration, Go test/race/vet/build, JS syntax, and Docker build.0NULLNULLNULL02026-07-20T00:22:52Z0
memestudio-a3d3a306a5786d9fcb59334913b41e11ecf57e83d90198c4828ce6fd967d6342bb2Image corner-radius inspector rowThe image inspector spec has a Radius slider; placed images use a fixed 3px radius. Add radius to placed state + render + compositor (roundRect).closed3taskEugene BlikhNULL2026-07-18T15:21:27ZEugene Blikhbigbes@gmail.com2026-07-19T21:50:25Z2026-07-19T21:50:25ZNULL0NULLNULLNULL000�{}Added a 0–40px image-radius slider with a 3px compatibility default, live DOM updates, rounded compositor clipping for images and stickers, and persistence coverage.0NULLNULLNULL02026-07-19T21:45:55Z0
memestudio-am397a231f676cad2fc0004e66e5e92e164c57125a7281f3035fbb02018cdd9b045Compact template rail and restore scrollable canvasThe first-start library exposes 100 templates directly in the sidebar. That makes the sidebar's min-content height expand the app grid, vertically centers the canvas against the oversized page, and leaves most of the canvas inaccessible. Keep six popular/selected templates in the rail, move the full searchable library into an overlay picker, preserve Imgflip popularity order, and constrain sidebar/stage/inspector scrolling to the viewport.Keep six quick templates in the sidebar: the first six by Imgflip catalog rank, replacing the sixth with the active template when needed. Put all templates plus upload in a native dialog with its own search; sidebar search and Browse all open it, and Escape/native focus handling close it. Persist catalog rank in SQLite and run a one-time metadata-only rank migration for databases created before the rank column, without redownloading image blobs. Constrain the grid/flex min-heights to 100dvh, make the stage independently scrollable, size the zoom wrapper to transformed dimensions, and support wheel/scrollbar plus space- or middle-drag panning.The sidebar renders at most six template tiles plus an All templates action; the full 100-template library is searchable and selectable in a keyboard-accessible overlay; Imgflip catalog order drives popularity and the active template remains visible in the quick rail; the app stays exactly viewport-high; sidebar, stage, and inspector scroll independently; an oversized or zoomed canvas can be reached by scrolling/panning; relevant server, JavaScript, CSS, and Docker checks pass.closed1bugEugene BlikhNULL2026-07-19T23:12:23ZEugene Blikhbigbes@gmail.com2026-07-19T23:25:57Z2026-07-19T23:25:57ZNULL0NULLNULLNULL000�{}Implemented six-template quick rail, searchable native full-library picker, persisted Imgflip popularity rank with metadata-only legacy migration, viewport-constrained independent scrolling, zoom-aware stage sizing, and space/middle-button panning. Go tests including race, vet/build, JS syntax, Docker build, and a 100-template headless browser interaction check pass.0NULLNULLNULL02026-07-19T23:12:28Z0
memestudio-bvs5b738fb26ed5b906e488d30af360a443d9ab3440d74626a53b8d1ad9a18c9f55Package the Go server for deployContainerize server/: CGO_ENABLED=0 static build (pure-Go SQLite), a Dockerfile (or single static binary + systemd unit), embed or ship the built editor static files + templates/. Config via flags/env (-addr, -db, -static).closed1taskEugene BlikhNULL2026-07-18T15:21:49ZEugene Blikhbigbes@gmail.com2026-07-19T21:03:54Z2026-07-19T21:03:54ZNULL0NULLNULLNULL000�{}Added and validated a scratch-based Docker package with a static Go binary, bundled editor/templates, persistent SQLite volume, env/flag configuration, and runtime smoke coverage.0NULLNULLNULL02026-07-19T20:52:08Z0
memestudio-c0zaad56e0412a304347fd94e59b5816a7e41091f3f1fadcffa1cab65bd1b407f79Deploy Meme Studio to phoebe-labStand up the memestudio stack in phoebe-lab: the Go server behind Traefik + Authelia forwardAuth at memes.bigb.es, with a small volume for the SQLite file (doc + image blobs). Stateful (was planned stateless). Wire the reverse-proxy auth, TLS, and a persistent volume.Deployment explicitly deferred by the user on 2026-07-20. Packaging is complete, but do not deploy to phoebe-lab until the user authorizes it.open1epicNULL2026-07-18T15:21:48ZEugene Blikhbigbes@gmail.com2026-07-19T21:06:13ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL02026-07-19T21:04:26Z0
memestudio-cv9c7513e9eb2351dd76b0e09ab18b020c7be5ff5170feca97dc4a4fe08336a0806Dynamic breadcrumbThe 'Templates / Drake Hotline Bling' breadcrumb is static. Reflect the selected template/base name.closed3choreEugene BlikhNULL2026-07-18T15:21:27ZEugene Blikhbigbes@gmail.com2026-07-19T21:52:46Z2026-07-19T21:52:46ZNULL0NULLNULLNULL000�{}Made the breadcrumb derive from the active template or uploaded base, with safe truncation and full-name title; verified selection, reload, and restored-history transitions.0NULLNULLNULL02026-07-19T21:50:34Z0
memestudio-d6593edcb7d20f77d0441dc0cff0f2c4aac04d9d9cff51c13a4d8499383f35519aaFetch Imgflip templates once on first server startMove Imgflip template acquisition out of the image/build path. On the first server start, launch a non-blocking Go job that fetches the Imgflip catalog and image bytes into SQLite; subsequent starts reuse the stored templates without contacting Imgflip. Update the template-serving path, packaging, documentation, and tests to match.Add SQLite templates plus a singleton import-completion row. Startup launches an Imgflip importer goroutine; it downloads the catalog and bounded image bodies concurrently, then commits usable templates and the completion marker in one transaction. GET /api/templates returns 202 + Retry-After until that marker exists and a manifest-shaped response afterward; GET /api/templates/{id} serves the stored blob. The browser renders immediately and polls the API in the background, while static-only hosting keeps its built-in placeholders. Remove the Docker network-fetch stage and the obsolete generator.The server starts without waiting for Imgflip; an empty database triggers one background import; imported template metadata and image bytes persist in SQLite; a populated database does not refetch on restart; the UI can load templates through the server; builds no longer fetch or bundle generated templates; relevant Go and frontend tests/build checks pass.closed1featureEugene BlikhNULL2026-07-19T22:34:41ZEugene Blikhbigbes@gmail.com2026-07-19T22:46:14Z2026-07-19T22:46:14ZNULL0NULLNULLNULL000�{}Implemented asynchronous first-start Imgflip import into SQLite, local template APIs, browser readiness polling, build-stage removal, documentation, and restart/failure tests.0NULLNULLNULL02026-07-19T22:34:45Z0
memestudio-djc3bee86e47cc17d380694d04901226b02ef09215bd5a35acd55954f3d6379c6d1Reconcile manifest vs saved docOn load, a saved doc fully replaces templates and the manifest bootstrap is skipped, so rebuilding the template library won't surface new templates in an existing doc. Decide/implement a merge (keep the doc's on-selection + uploads, refresh the library list).closed3taskEugene BlikhNULL2026-07-18T15:21:28ZEugene Blikhbigbes@gmail.com2026-07-19T21:38:16Z2026-07-19T21:38:16ZNULL0NULLNULLNULL000�{}Merged saved template state with the current manifest by ID, preserving the active template and user uploads; added browser and backend-startup regression coverage.0NULLNULLNULL02026-07-19T21:32:05Z0
memestudio-jf092f42636d3dd18980eca726c8ce3b2f483f8aed0aa6381655d44a62d8053e3f0Rotate/scale text layersText layers only move + change font-size (matches the spec). Give them the same rotate/scale handles as placed images if desired — reuse beginTransform-style math.in_progress3featureEugene BlikhNULL2026-07-18T15:21:27ZEugene Blikhbigbes@gmail.com2026-07-18T19:27:06ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL02026-07-18T19:27:06Z0
memestudio-l6t1980dcc25dac467f5b5ad1ecf8647acc3830a2ada6f359f8e6dc50e376dec4f9Font choice beyond ImpactThe Text inspector Font row is a static 'Impact' field. Make it a real picker (Impact + a couple of system faces), stored per text layer, honoured in textsHTML + drawText.closed3featureEugene BlikhNULL2026-07-18T15:21:26ZEugene Blikhbigbes@gmail.com2026-07-18T19:03:50Z2026-07-18T19:03:50ZNULL0NULLNULLNULL000�{}Font row is now a real per-layer picker: FONTS map (Impact + system Sans/Serif, invariant 6), stored as texts[].font, honoured in textsHTML (inline font-family) and drawText (ctx.font via fontCSS) so preview==export. Wired via data-text-font seg with per-button font previews; one undo step; backward-compatible (missing font → impact). Fixed a real bug: double-quoted family stacks truncated the style="…" attribute — switched to single quotes. Verified headlessly + screenshot.0NULLNULLNULL02026-07-18T18:56:43Z0
memestudio-ql583cd7076724cc2b4d7d45dd0d18afa00756105e9af85c0e56007a77b278856c8Default to Select and make preset panels independentThe editor currently starts in the wrong tool mode and fills every picture slot in multi-image presets from one active template. Start in Select mode, make every preset picture panel independently selectable, and add a per-text-layer maximum-width control so wrapping can be adjusted in both the editor and export.New documents start in Select mode; multi-image presets do not duplicate one template into every panel; each panel can be assigned independently through the editor; saved documents preserve assignments; selected text exposes a persisted max-width control that matches DOM wrapping and exported output; existing documents remain compatible.closed2featureEugene BlikhNULL2026-07-20T07:37:41ZEugene Blikhbigbes@gmail.com2026-07-20T07:52:36Z2026-07-20T07:52:36ZNULL0NULLNULLNULL000�{}Implemented Select as the default tool, independent multi-image preset slots, and per-text maximum-width controls; verified preview/export behavior in Chrome and passed Go/JS/Docker quality gates.0NULLNULLNULL02026-07-20T07:37:52Z0
memestudio-uc316589fc733d9bff3048338a4420f02c9b4c4758f38a9068ab7664ab72516e5cbPersist undo history across reloadUndo/redo history is in-memory; a reload restores the document but not the undo stack. Optionally persist a bounded history (or accept as-is).closed3taskEugene BlikhNULL2026-07-18T15:21:28ZEugene Blikhbigbes@gmail.com2026-07-19T21:45:41Z2026-07-19T21:45:41ZNULL0NULLNULLNULL000�{}Persisted a validated undo/redo window in the live draft, capped at 24 entries and 1 MiB; restored it across reload and reloads images referenced by restored states.0NULLNULLNULL02026-07-19T21:38:26Z0