본문으로 건너뛰기
cccskills
무료GitHub에 공개

android

Work on the Android app — the thin WebView wrapper in `android/`. Use this whenever a task touches the Kotlin sources, the Gradle build, the WebView shell, the native settings screen, LMS server auto-discovery, the JS↔native bridge, app strings/i18n, or the Android CI/lint. Covers the "shell only, UI lives on the web" principle, the debug/release signing split, the static versioning F-Droid needs, and the min/target SDKs, so changes fit the wrapper.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md5.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Android app (WebView wrapper)

The Android app is a thin native shell: the whole UI is the web dashboard served by the Flask app, loaded in a full-screen WebView. Same principle as lms-material-app. Don't rebuild dashboard UI natively — if a feature belongs on screen, it belongs in the web page; the app only provides shell concerns (window, settings, discovery, a native bridge).

Everything lives under android/. Package com.werdeil.lyriondashboard, Kotlin, Gradle KTS, minSdk = 26 (Android 8.0), targetSdk = 35, compileSdk = 37, Java/JVM 17.

Layout

android/app/src/main/
├── java/com/werdeil/lyriondashboard/
│   ├── MainActivity.kt        # the WebView host + JS bridge
│   ├── SettingsActivity.kt    # native settings screen
│   ├── ServerDiscovery.kt     # LMS auto-discovery (UDP broadcast)
│   └── Insets.kt              # edge-to-edge window insets
├── res/values/strings.xml      # EN strings   (values-fr/ = FR)
├── res/xml/preferences.xml      # settings screen definition
└── AndroidManifest.xml

Build & lint

cd android
./gradlew assembleDebug   # -> app/build/outputs/apk/debug/app-debug.apk
./gradlew lintDebug       # Android Lint (gates CI)

CI is .github/workflows/android.yml: on every push touching android/** it runs lintDebug then assembleDebug and uploads the debug APK as an artifact. The release APK is built and attached only when a GitHub release is published (see the release skill).

Signing: debug vs release

  • Debug is signed with a committed app/debug.keystore (standard debug credentials) on purpose — so every ephemeral CI runner signs with the same key and Android will update the app over a previous install instead of refusing. Debug builds also use an applicationIdSuffix = ".debug" and a distinct label, so they install side by side with the release app.
  • Release signing is driven by environment variables (ANDROID_KEYSTORE_PATH and friends) so the release keystore is never committed. Without them a local release build stays unsigned, which is also what F-Droid wants — but the release workflow refuses to publish an unsigned APK: it validates the keystore up front and runs apksigner verify on the result (see the release skill).

Versioning (must stay static)

versionName and versionCode in app/build.gradle.kts are static literals, committed, because F-Droid builds from the tagged source and parses them from that file. versionCode packs the semver as X*10000 + Y*100 + Z. Don't compute them at build time. Bumping is the Release workflow's job — see the release skill.

The JS ↔ native bridge

MainActivity injects a window.LyrionApp object into the page. The web JS detects it, adds body.in-app, and wires the header menu to bridge.openMenu() / openSettings() and the card's pull-to-refresh gesture to bridge.reload() (see the frontend skill). If you add a native capability the page should call, expose it as a method on that bridge and guard the page-side use behind the object's presence, matching the existing pattern.

Auto-discovery

ServerDiscovery finds the Lyrion server via UDP broadcast on port 3483 (the standard LMS discovery protocol) and suggests http://<host>:1111 (assumes the dashboard runs on the same host). Caveat baked into the UX: discovery can't cross a VPN tunnel, so the settings screen lets the user enter the URL manually. Cleartext HTTP is allowed (LAN-only app).

Strings / i18n

App strings are bilingual like the web app: res/values/strings.xml (EN) and res/values-fr/strings.xml (FR) must carry the same keys. Store-listing texts live under fastlane/metadata/android/{en-US,fr-FR}/. Add a new string to both locales — never one only. The same tree holds images/icon.png, the 512x512 render of static/favicon.svg that F-Droid shows on the app page: its indexer cannot render the adaptive-icon XML, so without that bitmap the listing has no icon. full_description.txt is never hard-wrapped — F-Droid clients keep every newline, so a paragraph wrapped at 70 columns renders ragged; one paragraph (and one bullet) is one line, however long.

Checklist

  1. Keep it a shell — new UI goes in the web page, not native views.
  2. New user string → both values/ and values-fr/ strings.xml.
  3. New native capability the page uses → method on window.LyrionApp, guarded page-side by the bridge's presence.
  4. Leave versionName/versionCode static; bump via the Release workflow.
  5. ./gradlew lintDebug assembleDebug clean before pushing (CI runs both).

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

add-route

무료

Add or modify a Flask endpoint in the Lyrion Dashboard. Use this whenever a task adds a new URL/route, a JSON API endpoint, or a page — anything that registers a handler in `routes/`. Covers the repo's route → service → test layering, input validation, caching headers, security headers, i18n wiring, and the exact test pattern, so a new endpoint matches how `routes/` already works instead of reinventing the structure.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

werdeil/lyrion-dashboard32026년 10월 19일 업데이트

covers

무료

Work on album artwork — reading an image's dimensions, and embedding a folder's cover file into the tags of its tracks. Use this whenever a task touches `services/artwork.py`, the cover half of `services/tags.py`, or `scripts/embed_covers.py` / `embed_covers_cron.sh`. Covers why Lyrion shows the embedded artwork and never the folder file, how covers are compared, why images are never re-encoded, and what embedding costs in rewritten files.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

werdeil/lyrion-dashboard32026년 10월 19일 업데이트

database

무료

Read data from Lyrion's SQLite databases — library stats, stored lyrics, album covers, recent plays. Use this whenever a task queries `library.db` or `persist.db`, adds or changes a statistic, or touches `services/database.py`. Covers the read-only connection model (RO open + `ATTACH persist.db`), the key tables, the `play_counts` view over the Alternative Play Count plugin, the single-flight stats cache, and why the app must never write to these DBs. Reach for it before writing any SQL against the Lyrion databases.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

werdeil/lyrion-dashboard32026년 10월 19일 업데이트

frontend

무료

Work on the dashboard's frontend — the vanilla JS/CSS page with no framework or bundler. Use this whenever a task touches `static/nowplaying.js`, `static/style.css`, the Jinja templates (`templates/nowplaying.html`, `_icons.html`), the accent-color tinting, the karaoke lyrics sync, the now-playing poll, or the empty-state mosaic / recent-plays pile. Covers how the page is wired, how it reads i18n and data from the server, the ESLint gate, and the Android bridge, so changes match the existing patterns.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

werdeil/lyrion-dashboard32026년 10월 19일 업데이트

i18n

무료

Add, change, or translate user-facing text in the Lyrion Dashboard, which ships bilingual FR/EN. Use this whenever a task introduces a new visible string (a label, tooltip, aria-label, empty state, stat name), changes wording, or touches the README or a `docs/` page — so every string lands in both languages and the EN/FR documentation pairs stay in sync. Covers `i18n.py`, how templates and JS consume translations, and the parity rule.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

werdeil/lyrion-dashboard32026년 10월 19일 업데이트

lyrics

무료

Work on lyrics — the web fallback (LRCLIB, Musixmatch, NetEase, Genius), the in-memory cache, verification, and embedding lyrics into audio file tags. Use this whenever a task touches `services/lyrics.py`, `services/tags.py`, the `/lyrics.json` route, or `scripts/embed_lyrics.py` / `embed_lyrics_cron.sh` — adding or fixing a provider, changing caching/verification, or the batch tagger. Covers the provider contract, the synced-vs-plain rule, the read-only cache, and why writes only ever store plain text.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

werdeil/lyrion-dashboard32026년 10월 19일 업데이트

werdeil의 스킬 모두 보기

이 스킬의 문제 신고