Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,31 @@ storage_state = true

Declare the **narrowest** HTTP allowlist that works — it's shown to the user before install and enforced at runtime.

### Translating what the user reads

WaveFlow ships in 17 languages, but your manifest lives outside its translation files — so the app can only show what you write here. Add the translations in a **sibling `*_i18n` table**, leaving the English string exactly where it is:

```toml
[plugin]
description = "Fetches Apple Music's animated album covers."

[plugin.description_i18n]
fr = "Récupère les pochettes animées d'Apple Music."
de = "Holt animierte Albumcover von Apple Music."

[[options]]
key = "prefer_hevc"
type = "bool"
label = "Prefer 4K HEVC covers"

[options.label_i18n]
fr = "Préférer les pochettes 4K HEVC"
```

Locale codes: `en` `fr` `de` `es` `it` `nl` `pt` `pt-BR` `ru` `tr` `id` `ja` `ko` `zh-CN` `zh-TW` `ar` `hi`. Any subset is fine — WaveFlow falls back exact code → base language (`pt-BR` → `pt`) → `en` → any entry. Keep brand and codec tokens (`WaveFlow`, `Apple Music`, `Last.fm`, `HEVC`…) verbatim.

> **Do not replace the string with a language map.** WaveFlow ≥ 1.8.0 also accepts `[plugin.description]` as an inline `en = … / fr = …` table, but a host predating that expects a string, errors on the table, and **drops your plugin entirely**. The sibling form is ignored by old hosts and understood by new ones, so it costs you nothing and needs no `min_app_version` bump.

## 4. Release it

Tag a semver release in your plugin repo. Copy [`templates/plugin-release.yml`](templates/plugin-release.yml) into `.github/workflows/` — it is a **single job** (no OS matrix) that:
Expand All @@ -68,6 +93,7 @@ Open a PR against this repo adding your entry to [`registry.json`](registry.json
- `version` = the release tag (without `v`).
- `blake3` = the hash the release workflow printed. **This is what the app verifies.** Get it wrong and installs fail closed.
- `permissions` = a byte-for-byte mirror of your `manifest.toml` `[permissions]`.
- `description` = a plain string, **always**. `registry.json` is one document fetched by every WaveFlow ever installed; an older build that finds an object here fails to decode the entire catalogue from all three delivery paths and its store goes dark — for every plugin, not just yours. Translations go in the optional `description_i18n` map next to it, which old builds ignore.

CI validates your entry against [the schema](schema/registry.schema.json). Once merged, your plugin appears in every user's in-app store within minutes (raw.githubusercontent + jsDelivr are the delivery paths).

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ Every entry is validated against [`schema/registry.schema.json`](schema/registry
"id": "apple-artwork",
"name": "Apple Motion Artwork",
"description": "Fetches Apple Music's animated album covers and plays them behind the now-playing view.",
"description_i18n": {
"fr": "Récupère les pochettes animées d'Apple Music et les affiche derrière la vue En cours de lecture."
},
"author": "InstaZDLL",
"repo": "InstaZDLL/waveflow-plugin-apple-artwork",
"homepage": "https://github.com/InstaZDLL/waveflow-plugin-apple-artwork",
Expand Down
18 changes: 18 additions & 0 deletions registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@
"id": "apple-artwork",
"name": "Apple Motion Artwork",
"description": "Animated album covers from Apple Music, rendered behind the now-playing view.",
"description_i18n": {
"fr": "Pochettes d'album animées depuis Apple Music, affichées derrière la vue En cours de lecture.",
"de": "Animierte Albumcover aus Apple Music, hinter der Ansicht „Wird gespielt“ dargestellt.",
"es": "Portadas de álbum animadas de Apple Music, mostradas detrás de la vista Reproduciendo ahora.",
"it": "Copertine animate degli album da Apple Music, mostrate dietro la vista In riproduzione.",
"nl": "Geanimeerde albumhoezen van Apple Music, weergegeven achter de weergave Speelt nu.",
"pt": "Capas de álbum animadas do Apple Music, apresentadas por trás da vista Agora a reproduzir.",
"pt-BR": "Capas de álbum animadas do Apple Music, exibidas atrás da tela Tocando agora.",
"ru": "Анимированные обложки альбомов из Apple Music, отображаемые позади экрана «Сейчас играет».",
"tr": "Apple Music'ten animasyonlu albüm kapakları, Şimdi çalıyor görünümünün arkasında gösterilir.",
"id": "Sampul album animasi dari Apple Music, ditampilkan di belakang tampilan Sedang diputar.",
"ja": "Apple Music のアニメーションアルバムカバーを「再生中」画面の背景に表示します。",
"ko": "Apple Music의 애니메이션 앨범 커버를 '지금 재생 중' 화면 뒤에 표시합니다.",
"zh-CN": "来自 Apple Music 的动态专辑封面,显示在“正在播放”视图后方。",
"zh-TW": "來自 Apple Music 的動態專輯封面,顯示於「現在播放」畫面後方。",
"ar": "أغلفة ألبومات متحركة من Apple Music، تُعرض خلف واجهة «قيد التشغيل».",
"hi": "Apple Music से एनिमेटेड एल्बम कवर, \"अब चल रहा है\" व्यू के पीछे दिखाए जाते हैं।"
},
"author": "InstaZDLL",
"repo": "InstaZDLL/waveflow-plugin-apple-artwork",
"homepage": "https://github.com/InstaZDLL/waveflow-plugin-apple-artwork",
Expand Down
12 changes: 11 additions & 1 deletion schema/registry.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,17 @@
"description": "Stable plugin id. MUST equal the install-dir name and the manifest.toml [plugin] id — the app refuses a mismatch."
},
"name": { "type": "string", "minLength": 1, "description": "Human-readable display name." },
"description": { "type": "string", "minLength": 1, "description": "One or two sentences shown on the store card." },
"description": { "type": "string", "minLength": 1, "description": "One or two sentences shown on the store card. MUST stay a plain string: this file is fetched by every WaveFlow ever installed, and a build predating localized descriptions fails to decode the whole catalogue if it finds an object here — its store goes dark. Translations belong in description_i18n." },
"description_i18n": {
"type": "object",
"minProperties": 1,
"additionalProperties": { "type": "string", "minLength": 1 },
"propertyNames": {
"enum": ["en", "fr", "de", "es", "it", "nl", "pt", "pt-BR", "ru", "tr", "id", "ja", "ko", "zh-CN", "zh-TW", "ar", "hi"],
"description": "Exactly the codes WaveFlow ships, case included. A permissive pattern would wave through a typo like \"pt-br\" or \"jp\": the app looks the key up verbatim, so the entry would simply never be shown, silently. Add a code here when WaveFlow adds a locale."
},
"description": "Translations of `description`, keyed by the app's locale codes (en, fr, de, es, it, nl, pt, pt-BR, ru, tr, id, ja, ko, zh-CN, zh-TW, ar, hi). WaveFlow 1.8.0+ shows the entry in the user's language and falls back exact code → base language → en → any entry; older builds ignore this field and render `description` as before. Keep brand tokens (WaveFlow, Apple Music, Last.fm, HEVC…) verbatim."
},
"author": { "type": "string", "minLength": 1 },
"repo": {
"type": "string",
Expand Down
Loading