Repository navigation
2.0.6 - #276
Merged
Merged
2.0.6#276
Conversation
…translation Brings the main features of the mobile app to the desktop app. Player - New "Player" section: opens a folder, scans only tags and durations (no Spotify lookup), lists tracks with lazily loaded covers, search and sort. Play all, Shuffle (every track once per round, the chosen one first) and Repeat off/all/one, remembered between sessions. Recent folders as chips. - Playback never lowers quality. Files the web view can decode (FLAC, MP3, WAV, Ogg, Opus, AAC) are streamed untouched. Others (ALAC, AIFF, WavPack, TTA, APE, WMA...) are decoded once to a cached lossless FLAC copy with the same sample rate and bit depth. core/playback.py decides; core/media_server.py is a loopback-only, token-protected HTTP server with Range support for the desktop window; /api/media does the same in web mode. - Full-screen Now Playing view: cover, tinted background, quality line, controls, queue in play order, volume. Lyrics come from a .lrc next to the file or the file's own tag, in any LRC flavour: line-synced, enhanced word-by-word (<mm:ss.xx> tags, v1:/v2: singers, [bg:] backing vocals, [x-translation:]/[x-romaji:] lines). Word fill with a soft edge, lift and glow on held words, intro/instrumental dots, right-aligned second singer. Scroll and defocus follow the mobile lyrics screen: focus anchored near the top, critically damped spring with trailing rows, defocus by distance, 4 s pause after a manual scroll. Fix Local Files - Convert dialog (all targets of core/transcode, bitrate and bit-depth / sample-rate caps); a lossless target on a lossy source is refused. - Tag editor: edits only the typed fields, keeps every other tag, cover and lyrics, backs up the file and restores it if the write fails. Fixes FLAC covers surviving a replace/remove (mutagen's delete() leaves pictures). - Audio analysis: technical details and a spectrogram drawn by ffmpeg. - Library reorganiser: moves files into folders built from their tags after a dry-run preview; never overwrites, never leaves the chosen folder. Following - "New this week": releases of followed artists from the discography listings, no track fetches, cached for 30 minutes. Release now carries its full date. - Concerts reported by an extension (same contract as the mobile app) show on the artist card with venue-local times and an .ics download. The metadata merge no longer drops the extension's extras when the built-in answer has none. Lyrics translation - OpenAI, OpenRouter, Gemini, Anthropic or any OpenAI-compatible server with the user's own key, stored in a private file and never sent back to the page. Line by line, so timestamps survive; save as <name>.<lang>.lrc. Other - The folder picker is shared by Fix Local Files and the Player, and starts from the path in the field instead of "/", which the web build refuses. - index.html loads styles.css, toast-system.js and app.js with a timestamp instead of a hand-kept ?v= suffix; webapp.py injects the browser shim at an explicit marker instead of matching a script tag. - Checkboxes inside modals keep their own size.
…istaking them for Deezer
Fails when the markup loses an element the script looks up, when an inline handler names an undefined function, or when the script selects a class nothing produces. A frozen inventory covers ids reached indirectly.
tests/visual/capture_tui.py draws the twelve panels at 80x24 and 120x40 in both Mornye themes, against an empty throw-away home, and can compare a fresh capture with the committed baseline.
A per-extension 'Allow local network access' switch in Settings -> Extensions. When on, the hosts of the URLs in that extension's non-secret text settings get past the network guard, so a Jellyfin server on 192.168.x.x works without MORNYE_EXT_ALLOW_PRIVATE_NETWORK opening the whole local network to every extension. Stored by the host, admin-only over the web.
An installed extension of type lyrics_provider that defines fetchLyrics (Jellyfin, Apple Music) is now a provider named ext:<name>, ranked with the built-in ones. The GUI and TUI add them to their provider lists, off by default, and --lyrics-providers accepts ext:<name>. Line-synced answers become LRC, unsynced ones stay plain text.
Explore gets a Feed picker: Spotify, as before, or any installed extension declaring capabilities.homeFeed (Jellyfin, Apple Music, YouTube Music...). Each item gets an open_url the URL box can open: the item's own web link, the manifest's share template, or for a self-hosted source the configured server plus its fragment link.
A setting with a long description squeezed its text field to 25px, so Jellyfin's Server URL could not be read or edited. The fields keep at least 200px and the description wraps instead.
A link to a source with no built-in client, such as a Jellyfin server's .../web/#/details?id=..., was handed to the Spotify client and could only fail. It now goes to the extension whose urlHandler claims it, and its tracks remember that extension. A track from an extension declaring skipBuiltInFallback is downloaded by that extension alone, and one from an extension declaring skipMetadataEnrichment keeps its own tags.
A line timed as one piece ('<00:51.00>I don't know how ... stay') drew
its lit copy on a single row: it ran off the right edge ('...you to
trea') while the dim copy underneath wrapped and stayed grey. Every
piece is now split into words, its time shared out by length, and a
piece with no end of its own lasts about a third of a second a word,
never past the next line.
tests/visual/capture_gui.py starts mornye --web on an empty throw-away data folder and saves the ten views, dark and light, at desktop, 768 and 375 wide, through Playwright and the installed Chrome. The URL box's typing animation is frozen, and --compare ignores anti-aliasing noise. Playwright is an optional 'visual' extra.
164 of the 217 style="" attributes become u-* utility classes at the end of styles.css, one declaration each, so a new stylesheet can reach every look decision. What stays inline is what app.js clears at runtime (display, opacity...) and eleven declarations an id or attribute rule would otherwise override. Every element's computed style is unchanged (1472 elements, desktop and phone, dark and light, compared before and after), and the GUI screenshots match the baseline. A test keeps new inline styles out.
The style="" attributes in the markup app.js builds become the same u-* utilities as index.html's. Colours that carry a meaning become a data-tone (muted, ok, warn, error) instead of a colour string: the animated-artwork check, extension health, signed sessions and conflicting reorganise rows; the Save button's border follows data-dirty. Fixed padding and grid values set from JS become classes. What is still written inline is computed or behaviour: shown/hidden, progress widths, lyric motion, cover images. Computed styles of every element in every view and settings tab, desktop and phone, are unchanged; the GUI screenshots match the baseline. The screenshot diff now ignores up to 20 stray anti-aliased pixels.
Now Playing's white-on-artwork ink and its tints, a barcode's black on white, the glyphs on a status dot and on the player's main button become theme-independent tokens (branding_tokens.FIXED), declared once in :root; translucent shades use channel tokens, rgba(var(--media-ink-rgb), .62). The toasts lose fallbacks that could never apply. Masks keep their black, which is an alpha channel. New tests: the fixed tokens match the module and the light theme leaves them alone, and no declaration names a raw colour. Computed styles are unchanged everywhere.
Static pages in docs/mocks on one stylesheet that holds the proposed token v2 values (graphite surfaces, amber signal, state colours), with the three signature elements: the quality readout, the segment meter and the legend set in a panel's border. The TUI mock is generated at 120x40 by make_tui_mock.py. For approval before token v2 (voce 8).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.