42 Commits
Author SHA1 Message Date
Jannik d157d34fca Optimize frontend rendering, CSS, and backend history caching 2026-07-04 23:14:47 +02:00
Jannik b888d3d3fb Auto-Commit: 2026-07-04 22:51:07 2026-07-04 22:51:07 +02:00
Jannik fa05cfded7 fix: increase max_tokens for Minimax-M3 to prevent truncated JSON 2026-06-15 19:41:51 +02:00
Jannik 5e16a7049f chore: remove hardcoded api keys from minimax test scripts 2026-06-14 11:14:39 +02:00
Jannik 1abd2d1d59 Auto-Commit: 2026-06-13 15:16:41 2026-06-13 15:16:41 +02:00
Jannik ad326c7efa chore: update .gitignore with temp files and venv 2026-06-13 14:10:18 +02:00
Jannik 6c1a8cd281 feat: add chat ai link to header 2026-06-04 20:27:41 +02:00
Jannik ade33edc6d feat: visually highlight the recommended video ai button 2026-06-04 20:20:05 +02:00
Jannik d7aa7a349a fix: tool recommendation and lyrics text selection 2026-06-04 13:48:26 +02:00
Jannik 0932357cdf fix: normalize newlines for lyrics replacement 2026-06-04 13:25:53 +02:00
Jannik cee3d24582 style: fix custom cursor on labels 2026-06-04 12:56:55 +02:00
Jannik b1b77c1714 style: make settings page wider for better prompt editing 2026-06-04 12:54:15 +02:00
Jannik cba6a173e6 chore: user tweaks to system prompts 2026-06-04 12:51:17 +02:00
Jannik 5bc3b6bbcb feat: improve video AI tool links UX and copy prompt on click 2026-06-04 12:49:01 +02:00
Jannik 8e36ec5ca5 fix: add missing hooks and fix type error 2026-06-04 11:53:00 +02:00
Jannik f4cb318175 feat: add editable system prompts from web UI 2026-06-04 11:31:56 +02:00
Jannik ecd75a7fb5 fix: dynamically suggest video tools based on env configuration 2026-06-04 11:21:23 +02:00
Jannik ab5a967fe4 feat: add configurable video AI links 2026-06-04 11:11:36 +02:00
Jannik 9dddaffdd4 fix: resolve 500 error on partial lyrics regeneration and fix mobile scrolling by removing overflow: hidden 2026-06-04 10:51:48 +02:00
Jannik 0353a5a9af fix: increase max_tokens and handle unclosed think blocks for style generation 2026-06-04 08:50:58 +02:00
Jannik 5dae92f137 UI: Change Suno hover color to orange 2026-06-04 00:52:15 +02:00
Jannik cacb11b8e7 UI: Add custom glowing I-beam text cursor 2026-06-04 00:51:37 +02:00
Jannik 4769d2a9b8 UI: Change light mode icon to a lightbulb 2026-06-04 00:46:35 +02:00
Jannik 5249d87b59 UI: Add Suno link to header 2026-06-04 00:42:10 +02:00
Jannik 478c611d05 UI: Make layout fully responsive for mobile and tablet 2026-06-04 00:40:26 +02:00
Jannik 1a964a43a7 UI: Add custom glowing cursors matching the app theme 2026-06-04 00:34:58 +02:00
Jannik 7981b1d146 UI polish: updated favicon, smoothed animated bars, and slowed down gradient animations 2026-06-04 00:28:02 +02:00
Jannik 3a2c738bd0 UI enhancements, i18n, history drawer, and requested features 2026-06-04 00:01:32 +02:00
Jannik c3e167bde9 feat: major UI overhaul - 1/3+2/3 layout, animated logo, history drawer, editable titles, Czech, dark default, playful design 2026-06-03 23:06:56 +02:00
Jannik 8d09b17467 fix: add server-side retry logic for intermittent LLM JSON parse failures 2026-06-03 22:55:33 +02:00
Jannik 2fda90729e fix: resolve typescript and tailwind compilation errors 2026-06-03 22:09:56 +02:00
Jannik d34d34565f feat: complete UI overhaul (liquid glass theme, i18n, FontAwesome) 2026-06-03 22:00:37 +02:00
Jannik e5a9936066 Fix CSS: add postcss config, safelist stagger-N, drop dead rules
The page was loading with effectively no Tailwind utility classes
because there was no postcss.config.js — Vite didn't know to run
Tailwind's PostCSS plugin. The preflight and @apply references in
src/index.css were partially working (because some Tailwind processing
was happening implicitly), but the JIT content scanner wasn't running,
so all utility classes (flex, grid, p-*, text-fg, bg-bg, …) were
missing from the build. The page rendered as unstyled HTML.

postcss.config.js — newly added. Tells Vite to run tailwindcss +
autoprefixer. Written in plain UTF-8 (the earlier draft saved as
UTF-16 with BOM, which Node couldn't parse, hence the 'Syntax Error'
in the file viewer).

tailwind.config.js — added a safelist for the dynamic
`stagger-${index}` classes used in ResultCard.tsx. The JIT
content scanner can't resolve a template literal, so without the
safelist the four matching rules (stagger-0 … stagger-4) got purged
from the build even though they're used at runtime. Adding them to
the safelist keeps them alive.

src/index.css — dropped three dead rules (card-hover, btn-primary,
gradient-bg-soft) that the modern UI redesign made unused. They
were in the file but never referenced by any .tsx, so the
content-aware purger was stripping them anyway; explicit removal
keeps the source honest.
2026-06-03 19:53:58 +02:00
Jannik 9980d5ba20 Remove duplicate MelodyMuse brand row in InputPanel
The home page header already shows a small equalizer + 'MelodyMuse'
wordmark. Having a second brand row inside the InputPanel was
redundant and pushed the textarea down. Removed it; the form now
starts directly with the 'Music idea' label. Bumped the textarea
rows from 4 to 5 to fill the freed space.

Also added: the server-status check on the home page now re-runs
every 30s, so the 'Server offline' hint in the header stays current
without a manual refresh.
2026-06-03 17:37:11 +02:00
Jannik 040a063860 Add YouTube channel link to the home page header
Subtle link in the top-right of the home page header pointing at
https://www.youtube.com/@AIWentNonsense. Lucide Youtube icon plus
'YouTube' label, hidden on small screens. Opens in a new tab with
rel=noopener noreferrer. Sits to the left of the (conditional)
'Server offline' indicator.
2026-06-03 12:50:16 +02:00
Jannik 81aefe0700 Modernize the UI and fix the equalizer sizing bug
Bug fix

- EqualizerIcon: the SVG was rendering at the wrong size (filling
  its parent) because it had no explicit width/height attributes.
  Now it accepts a size prop with a 24px default and the SVG element
  carries the size as width/height attributes, with the className
  on top. Can't accidentally balloon.

Design

- Stripped the light-mode CSS — the app is dark-only now, and the
  theme toggle was a no-op (clicking it just toggled a class that
  had no matching rules). ThemeToggle.tsx and lib/theme.ts are
  gone; initTheme() call removed from main.tsx.

- Reworked the input form:
    • brand row is now small + refined (icon + wordmark, no huge
      gradient title)
    • Options is a single subtle collapsible card with a chevron and
      a count badge showing how many options are non-default
    • Vocals is now a segmented pill (single rounded container, two
      flat segments) instead of two full-width grid buttons
    • Generate button is slightly smaller (py-3.5, text-sm) and
      uses a softer shadow (shadow-violet-900/20)

- Empty state in the results panel: dashed-border card, soft
  gradient blur behind the music icon, cleaner copy.

- Results header: smaller heading, the 'Regenerate All' and
  'Cancel' buttons are now tiny ghost-style pills in the top-right.

- Sticky ZIP bar: softer shadow, more refined copy.

- Result cards: smaller icon, single-line title, the Regenerate
  button is now an inline pill that fits next to Revert + Copy.

- Home page header now has a tiny equalizer icon + 'MelodyMuse'
  wordmark on the left (was just text). Settings page header has
  the back arrow on the left and the title, no theme toggle.

- Global CSS: added modern focus-visible ring, custom selection
  color, subtle scrollbar thumb, slightly tweaked the gradient
  text to a softer violet-300 → cyan-300 instead of the loud
  violet-400 → fuchsia-400 → cyan-400.
2026-06-03 10:49:58 +02:00
Jannik 3096669a13 Polish: draft autosave, history refresh, outdated footer, more
Bug fixes / UX

- Footer: the privacy line still claimed 'generation runs in your
  browser'. Now correctly says the generation runs on the server and
  the key never reaches the browser.

- History panel: when the panel was open while a new generation
  completed, the new entry didn't appear until the user closed and
  re-opened the panel. The history module now dispatches a custom
  'melodymuse-history-updated' event on every write; the panel
  listens and re-reads. removeFromHistory/clearHistory emit too.
  writeAll is also now try/catch'd against quota errors.

- Auto-save the input form: the input is persisted to localStorage
  ('melodymuse-draft', debounced 400ms) so a refresh doesn't wipe
  what the user was typing. The initial state hydrates from the
  draft on mount.

- Cmd/Ctrl+Enter now works in the Music style field as well as
  the idea field — shared onKeyDown handler, propagated through the
  StyleField sub-component.

- Full regen ('Generate' / 'Regenerate All') now clears the previous
  assets before kicking off the new request, so the skeleton state
  shows during the round-trip instead of stale cards with a spinner
  on top. Per-section regen still leaves the other cards intact.

- Settings → Local data: the in-progress draft is now listed
  alongside history and theme, and has its own 'Clear in-progress
  draft' button. The 'Clear all local data' button clears it too.
2026-06-03 08:59:31 +02:00
Jannik 1f82825849 Remove deploy/ folder (belongs in Jannik-Cloud)
The Dockerfile, docker-compose snippet, Caddy fragment, and
generate-env.sh now live alongside the rest of the Jannik-Cloud
services — that's the one place that already knows how to manage
them. The MelodyMuse repo is now app-only: source, build config,
the Node server, and docs.

The README's 'Docker / Jannik-Cloud' subsection is replaced with a
short note pointing the reader at the Jannik-Cloud service directory
and the project-layout section no longer lists deploy/.
2026-06-03 08:25:00 +02:00
Jannik d8b25ec6ab Move LLM key to the server, add random-style buttons
Architectural change

The browser no longer talks to the LLM directly. A new Node server
(server.mjs) sits in the middle:

  [Browser] → [Node :3000] → [LLM provider]
    (no key)    (key in .env)

server.mjs is the production runtime: it serves the built SPA out of
dist/ and exposes three JSON endpoints that proxy to the LLM with
credentials held in process.env. The browser-side llm.ts is now a thin
fetch wrapper.

- server.mjs: single-file Node server, no production deps
- server/prompts.mjs: system + user prompt construction (was client-side)
- src/lib/prompts.ts removed (moved server-side)
- src/lib/llm.ts rewritten — no more direct LLM calls, no more
  JSON extraction, no more validation; just fetch the proxy
- src/lib/types.ts: drop SaveConfigPayload/TestConnectionResult, add
  style_hint and ServerStatus
- vite.config.ts: proxy /api/* → localhost:3000 in dev
- .env.example: LLM_* and PORT/CORS_ORIGIN instead of Supabase values

New feature: random style buttons

The Options → Music style field now has two AI buttons that fill it
with a fresh Suno style description:
- 'Surprise me' → coherent, production-ready style (max 25 words)
- 'Go crazy'   → deliberately clashing genre mashup (max 25 words)

The buttons hit a dedicated /api/style/random endpoint on the server
that uses a small, focused system prompt. Each click overwrites the
field. Both buttons show a spinner and disable while a request is
in flight. Errors surface as toasts. AbortController is used so a
fast second click cancels the first.

When the Music style field is non-empty at generation time, its value
is sent to the model as style_hint and used as the basis for the full
120-word style field (per the updated system prompt).

Other UX

- Settings page is now a server-status page: green/red indicator,
  model + endpoint, re-check button. The API key is no longer
  configurable in the browser (it never was reachable anyway — now
  the UI is honest about that).
- Home page header shows a small 'Server offline' warning when the
  server is unreachable.
- Settings has a Local data section: list what's in localStorage
  with one-click clear-history and clear-all buttons (with confirm).
- Esc cancels any in-flight generation.
- ZIP filename falls back to 'song' if the title sanitizes to empty.

Deployment

deploy/ holds reference files (Dockerfile, docker-compose example,
Caddy fragment, generate-env.sh, README) for adding the service to a
Jannik-Cloud-style stack. The repo is intentionally not wired into
the Jannik-Cloud repo; copy the four files when ready.
2026-06-03 08:01:21 +02:00
Jannik b945417773 Add cancel, history, revert, and quality-of-life features
UX

- Add elapsed-time counter and Cancel button to in-flight generations,
  wired through AbortController so partial responses are discarded
  cleanly. The cancel action is available from both the input panel
  and the results header.
- Add a Recent generations panel below the input. The last 6 successful
  generations are saved to localStorage; one click reloads both the
  input fields and the generated assets.
- Add a Revert button to every editable card. It appears the moment
  the current value diverges from the last generated value and restores
  the field with a single click.
- Add an Empty state to the right panel with a friendly hint pointing
  at the Generate button and the Settings page.
- Add a 'Try an example' button that fills the input with a random
  starter idea (idea + mood + vocals).
- Add Cmd/Ctrl+Enter as a keyboard shortcut to generate.
- Add a Footer with project info and a privacy reminder.
- Add a 'Clear saved key' button to the Settings page so the user can
  remove the API key without overwriting it.

Bug fix

- Settings > Test Connection used to save the in-progress form values
  to localStorage before testing. It now uses the in-memory candidate
  config, so failed tests don't pollute the saved config.

Code quality

- Extract the duplicated useAutoHeight hook to src/lib/useAutoHeight.ts.
- Extract a useElapsed hook for the loading timer.
- Move InputValues into src/lib/types.ts (was duplicated in
  InputPanel.tsx) and add SECTION_LABELS, replacing the humanizeSection
  switch in HomePage.
- Centralize the filename sanitization: HomePage now calls
  sanitizeFilename from zip.ts instead of duplicating the regex.
- Add previewConfig / testConnectionWithConfig helpers to llm.ts to
  support in-memory connection tests.
2026-06-03 01:47:11 +02:00
Jannik d42410560f Build standalone MelodyMuse SPA
Drop the Supabase backend and call the AI provider directly from the
browser. The endpoint URL, API key, and model name are stored in
localStorage and used for direct /chat/completions requests.

- src/lib/llm.ts: config persistence, direct fetch, JSON extraction,
  shape validation, connection test
- src/lib/prompts.ts: full + partial-regeneration system prompts and
  user-message builder
- src/lib/{api,supabase}.ts removed
- supabase/ directory removed
- @supabase/supabase-js dropped from package.json
- README updated to describe the standalone architecture and CORS caveats
- .gitignore: drop Supabase entries, exclude *.tsbuildinfo
2026-06-03 01:25:22 +02:00
Jannik f2401d0c57 first commit 2026-06-03 01:07:07 +02:00