Skip to content

spotify-lyrics - #214

Merged
ItsLemmy merged 28 commits into
noctalia-dev:mainfrom
goatnath:main
Aug 6, 2026
Merged

spotify-lyrics#214
ItsLemmy merged 28 commits into
noctalia-dev:mainfrom
goatnath:main

Conversation

@goatnath

@goatnath goatnath commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Plugin

  • Id: <goatnath/spotify-lyrics>
  • New plugin
  • Update to an existing plugin (version bumped in plugin.toml)

What it does

Adds a seamless, time-synced scrolling lyrics panel for the Noctalia desktop shell. It integrates directly into the Noctalia bar via a small glyph next to the media widget, which toggle an auto-scrolling lyrics card pulled from a background daemon.

External dependencies

Requires playerctl and the syncedlyrics Python package. It uses a standalone background Python daemon (spotify_lyrics_daemon.py) to monitor media state and fetch lyrics without needing Spotify API keys. The plugin reads state locally from ~/.cache/noctalia/lyrics/current.json.

Testing

  • Tested on Niri
  • Tested on Hyprland
  • Tested on Sway
  • Tested on another compositor:
  • Noctalia version tested against: Latest
  • Plugin API level: 3

Screenshots / Videos

recording_20260805_213318.mp4

Checklist

  • The directory name matches the part of id after the / in plugin.toml exactly.
  • It ships plugin.toml, README.md, thumbnail.webp, and translations/en.json.
  • README.md follows the
    README template, documents
    every entry id and dependency, and includes exact panel IPC commands and launcher prefixes where applicable.
  • I created thumbnail.webp with the thumbnail generator.
  • version follows semver and is bumped in this PR; plugin_api is the oldest API level this plugin requires.
  • Every non-English translation in this PR uses a locale supported by Noctalia core, and I can read, write, and
    understand that language well enough to review and maintain it (no unreviewed machine/LLM translations).
  • I did not edit catalog.toml; CI generates it.
  • This PR touches exactly one plugin directory.

Code review attestation

Plugins run as trusted, unsandboxed Luau in the user's session. Confirm:

  • The code is readable and not obfuscated, minified, or generated.
  • It does not download and execute remote code.
  • Every network call, filesystem write, and spawned process is something the description above accounts for.
  • I have the right to publish this code under the license declared in plugin.toml.

@goatnath

goatnath commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

I have made the required changes suggested in the previous PR and I request you to check this and feel free to point out anything you think needs to be changed

@ItsLemmy

ItsLemmy commented Aug 2, 2026

Copy link
Copy Markdown
Contributor
  1. blocking - spotify-lyrics/plugin.toml:7

The manifest declares no dependencies, but spotify-lyrics/spotify_lyrics_daemon.py:6 requires the syncedlyrics Python package and spotify-lyrics/spotify_lyrics_daemon.py:101executes playerctl. The Python runtime is also required to run the daemon. spotify-lyrics/README.md:20 documents only part of this requirement outside the template's required
"## Requirements" section.

This hides mandatory runtime prerequisites from the catalog and plugin metadata. Declare all runtime requirements in dependencies and document the matching exact names under
"## Requirements".

@ItsLemmy
ItsLemmy marked this pull request as draft August 2, 2026 15:45
@goatnath
goatnath marked this pull request as ready for review August 3, 2026 04:58
@ItsLemmy

ItsLemmy commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
  1. blocking - lyrics/lyrics.luau:85

Commit ef91e6f modifies the existing h465855hgg/lyrics plugin, although this PR declares itself as a new goatnath/spotify-lyrics plugin and attests that it touches exactly one plugin directory.

Remove the lyrics/lyrics.luau change from this PR. Any update to the existing lyrics plugin should be reviewed separately with its own manifest version bump and functional scope.

@ItsLemmy
ItsLemmy marked this pull request as draft August 3, 2026 12:34
goatnath added 13 commits August 3, 2026 22:19
…base

Root cause: the charUnits per-character width estimation consistently
underestimated real rendered widths because the 0.80 multipliers in
getLineWidth and getLinesCount cancelled each other out, making the
effective calculation ignore the safety margin entirely.

Fix: replaced the complex charUnits/toChars/getLineWidth machinery with
a simple #text / chars-per-line heuristic using a conservative 0.60x
character width factor. This reliably overestimates line count, ensuring
the panel always allocates enough height for wrapped text.

Quality of life improvements:
- Split monolithic render() into renderEmpty/renderPaused/renderPlaying
- Reduced update interval from 33ms (30 FPS) to 100ms (10 FPS)
- Removed file-read timer (reads every frame at lower FPS instead)
- Added clear section headers and inline documentation
- Removed all dead code (charUnits, toChars, getLineWidth, etc.)
… fix

The root cause of the lyrics spilling was never in the Lua code.
Noctalia panels are sized exclusively by plugin.toml, not by minHeight
on the column layout. Since we had removed width/height from plugin.toml
to make sizing 'dynamic', noctalia used a tiny default that couldn't
contain wrapped lyrics. minHeight on ui.column had zero effect on the
actual panel window size.

Set height=280 to comfortably fit 3 lyrics lines even when they wrap.
Long lyrics (>40 chars) now get progressively smaller fonts:
- Every 15 chars beyond 40 reduces font by 2px
- Minimum font: 10px (panel) / 11px (widget)

This prevents vertical overflow regardless of container size by
ensuring long lines take up less vertical space when they wrap.
goatnath added 3 commits August 5, 2026 11:23
- Updated bar.luau to toggle correct panel ID
- Replaced ~ in noctalia.readFile with absolute path since Lua doesn't auto-expand it
- Updated plugin.toml height to 280 and id to noctalia/spotify-lyrics
@goatnath
goatnath marked this pull request as ready for review August 5, 2026 16:06
@ItsLemmy

ItsLemmy commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
  1. blocking - spotify-lyrics/plugin.toml:7

    dependencies = [] is still empty. The plugin requires playerctl, python3,
    and the syncedlyrics Python package to function (spotify_lyrics_daemon.py:6,
    spotify_lyrics_daemon.py:101). The README "Requirements" section documents
    these, but the manifest omits them from the machine-readable dependencies
    field. This was flagged in the previous review and has not been addressed.

    Declare all runtime dependencies in the dependencies array so the catalog
    and plugin manager can surface them to users.

  2. blocking - spotify-lyrics/plugin.toml:1

    The manifest id is "noctalia/spotify-lyrics", using the "noctalia" author
    namespace. The PR submitter is goatnath, and the PR template declares the
    id as "<goatnath/spotify-lyrics>". The "noctalia" prefix implies official
    provenance and is misleading. Change the id to "goatnath/spotify-lyrics".

  3. blocking - spotify-lyrics/bar.luau:10

    The file path is hardcoded to "/home/goatnath/.cache/noctalia/lyrics/current.json".
    This will not work for any other user. Use a relative or home-directory-resolved
    path (e.g. via noctalia.env or os.getenv("HOME")).

  4. non-blocking - spotify-lyrics/widget.luau

    This file implements a desktop widget (desktopWidget.render()) but the
    manifest contains no [[desktop_widget]] entry. The file ships with the
    plugin but will never be loaded by Noctalia. Either add a
    [[desktop_widget]] section to plugin.toml or remove the file.

  5. blocking - spotify-lyrics/README.md:11

    The README "Plugin" section lists the id as "noctalia/spotify-lyrics",
    which must be updated to match whatever the corrected manifest id becomes.

  6. non-blocking - spotify-lyrics/README.md

    The README does not follow the repository README template structure. It has
    non-standard sections ("Why it's great", "Usage") instead of the template's
    required sections. The "## Requirements" heading is present, which is the
    minimum conditional section needed, but the overall structure diverges from
    the template.

@ItsLemmy

ItsLemmy commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

This PR is going backward now xD more stuff to fix than last time.

@ItsLemmy
ItsLemmy marked this pull request as draft August 5, 2026 21:48
@goatnath

goatnath commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Oh shucks I added the files from my personal repository into this

- Change plugin id from noctalia/ to goatnath/ namespace
- Declare runtime dependencies: playerctl, python3, syncedlyrics
- Replace hardcoded /home/goatnath path with noctalia.expandPath()
- Add [[desktop_widget]] manifest entry for widget.luau
- Rewrite README to follow README_TEMPLATE.md structure
- Update all references to use corrected plugin id
@goatnath
goatnath marked this pull request as ready for review August 6, 2026 01:38
@ItsLemmy
ItsLemmy merged commit e439ccd into noctalia-dev:main Aug 6, 2026
1 check passed
@goatnath

goatnath commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Finally 😭

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants