feat: make Jellyfin an optional source instead of the default

Revert the jellyfin-only default introduced by PR #123 so upgrading
users keep their online sources; Jellyfin becomes opt-in:

- default enabledProviders is now the online set (netease/qq/bilibili/
  youtube/kugou); defaultPlatform() uses a fixed priority order
  (netease -> qq -> kugou -> jellyfin -> bilibili -> youtube) instead
  of jellyfin-first, so chat/REST/WebUI default to netease again
- Settings: Jellyfin card is always visible with a new enable toggle
  (its enabled bit is enabledProviders membership); guards against
  clobbering other providers before the list loads
- Setup wizard: saving the Jellyfin step auto-enables the source when
  a server URL was entered
- Search/player store fallbacks flip from jellyfin to netease; !help
  no longer hardcodes Jellyfin lines
- tests: update default-platform assertions, add coverage for the new
  default set, legacy configs without enabledProviders, priority
  order, and explicit jellyfin-only configs
- README: reframe Jellyfin as optional (badges, command table, quality
  tiers, dedicated section, changelog), document the enabledProviders
  default and the v1.10.0 jellyfin-only window fix, credit @ItsEricRao

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
saopig1andClaude Fable 5 committed 2026-07-14 00:54:34 +08:00
1 parent 3841fa80d3
commit 750ad9b1cc
12 files changed
+270 -72

No files matched your search

+16 -4
View File
@@ -61,7 +61,7 @@
<div v-if="currentStep === 2" class="step-content">
<h2>连接 Jellyfin (可选)</h2>
<p class="subtitle">连接自建 Jellyfin 服务器作为主音源;也可稍后在「设置」中配置</p>
<p class="subtitle">连接自建 Jellyfin 服务器作为额外音源;保存后自动启用,也可稍后在「设置」中配置</p>
<div class="form-group">
<label>服务器地址</label>
<input v-model="jellyfin.serverUrl" placeholder="https://jellyfin.example.com" class="input" />
@@ -130,8 +130,8 @@ const nickname = ref('MusicBot');
const defaultChannel = ref('');
const channelId = ref('');
// Jellyfin — the primary music source. Optional: skipping leaves it
// configurable later in Settings.
// Jellyfin — optional self-hosted music source. Skipping leaves it
// configurable later in Settings; saving here also enables it.
const jellyfin = reactive({
serverUrl: '',
authMode: 'userpass' as 'userpass' | 'apikey',
@@ -182,7 +182,19 @@ async function testJellyfin() {
async function saveJellyfinAndNext() {
jellyfinSaving.value = true;
try {
await axios.post('/api/bot/settings', { jellyfin: { ...jellyfin } });
// Jellyfin is opt-in (not in the default enabledProviders), so completing
// this step also enables the source — a configured-but-dark Jellyfin would
// be baffling. enabledProviders is full-replace: fetch the current list
// and append. Only do this when a server URL was actually entered.
const payload: Record<string, unknown> = { jellyfin: { ...jellyfin } };
if (jellyfin.serverUrl.trim()) {
const cur = await axios.get('/api/bot/settings');
const ep: unknown = cur.data?.enabledProviders;
if (Array.isArray(ep) && !ep.includes('jellyfin')) {
payload.enabledProviders = [...ep, 'jellyfin'];
}
}
await axios.post('/api/bot/settings', payload);
currentStep.value = 3;
} catch {
jellyfinTestOk.value = false;