Commit Graph
11 Commits
Author SHA1 Message Date
TIANYAO ZHANGandClaude Opus 5.5 ac4a12d8bd feat(fm): let each web user link their own NetEase account for personal FM (#164)
With several people sharing one bot, personal FM always followed the one
account the bot was logged in with. Each signed-in (non-guest) web user
can now scan a QR code under Settings → 账户 to link their own NetEase
account; FM they start from the WebUI then comes from their account.

- user_music_cookies table (per user + platform, dropped with the user).
- NeteaseProvider.pollQrLogin returns the cookie without storing it, so
  a personal login can never replace the bot's shared account;
  checkQrCodeStatus is now built on it. withCookie gives a view bound to
  another account.
- /api/me/music/netease: status / qrcode / qrcode/status / unlink, acting
  only on req.user. The cookie never leaves the server.
- POST /api/player/:botId/fm uses the caller's linked account for
  NetEase. Songs still resolve through the shared provider when played.

TeamSpeak chat !fm keeps using the shared account: chat users are not
tied to web accounts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-27 22:02:31 +08:00
saopig1andClaude Opus 4.8 a1cc0b8574 feat(search): server-side offset pagination through providers + /search route (#115 backend)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 14:36:54 +08:00
Slldyd2077 fbb127a86d feat: resolve trial-only playback via trialDuration/effectiveDuration
VIP songs for non-VIP accounts return a ~30s trial fragment. The player used the full duration for isNearEnd, so the trial end didn't trigger auto-advance (~60s stall), and currentSong.duration stayed full, leaving the UI progress stuck.

- provider.ts: SongUrlResult {url, trialDuration?}; getSongUrl signature
- netease.ts: parseNeteaseTrial (freeTrialInfo start/end in seconds) + getSongUrl
- qq.ts: parseQqTrial (isTryout/tryEnd) + getSongUrl
- bilibili/youtube: getSongUrl returns {url}
- instance.ts: resolveAndPlay uses effectiveDuration = trialDuration ?? duration -> nearEnd at trial end -> native auto-advance; BotStatus.effectiveDuration
- VIP account: freeTrialInfo absent -> full duration -> full playback (no toggle)

Backward compatible (optional fields; getSongUrl has a single caller, updated).
Tests: parseTrial assertions (seconds/alias/ms-fallback). 14 pass.
2026-06-28 21:06:52 +08:00
Slldyd2077 7b2bd0ea6a feat: expose vip flag on Song for trial-only detection
Add optional vip?: boolean to the Song interface so downstream clients
(e.g. PowerfulTS) can mark copyright-restricted songs that non-VIP users
can only play as a trial fragment, before playback starts.

- provider.ts: add optional vip?: boolean (backward compatible)
- netease.ts: extract mapNeteaseSongs() pure fn; map fee to vip
  (1=VIP, 4=album-only). fee=8 (free low-quality) is excluded because
  it plays in full, just at lower quality.
- qq.ts: mapQqSongs() maps pay.payplay/paytrackprice to vip (one fix
  covers all callers); getDailyRecommendSongs inline mapping too.
- tests: vip mapping assertions for netease fee (1/4=vip, 0/8=free) and
  qq pay fields.
2026-06-28 17:12:57 +08:00
NoSetViolinandClaude Opus 4.7 997bb17ceb feat(search): add tabbed category navigation + align NetEase result counts
- Replace single-page layout with pill-slider tabs (单曲/专辑/歌单) under
  the search box, showing only one category at a time with result counts
- NetEase album/playlist search limit raised from 5 to 10 to match QQ

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 16:56:18 +08:00
saopig1andClaude Sonnet 4.6 a2453784c1 feat(netease): include albums in search results
Add mapNeteaseAlbums pure helper and wire cloudsearch?type=10 as the third Promise.all arm in search(), replacing the hardcoded albums:[].

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 20:17:46 +08:00
saopig1andClaude Opus 4.7 900191eca5 fix(api): add getPlaylistDetail provider method for QQ playlist detail
The /playlist/:id/detail route was hardcoded to call the NetEase API
path /playlist/detail on whatever provider was selected. For QQ this
hit a non-existent path, so clicking into any QQ playlist showed
"歌单不存在或加载失败".

Replace the platform-specific hack in the route handler with a proper
getPlaylistDetail method on MusicProvider. Implement it for NetEase
(porting the existing /playlist/detail logic) and QQ (calling
/getSongListDetail and reading from response.cdlist[0]).

Pre-existing bug exposed by the QQ source tab.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:05:48 +08:00
saopig1andClaude Opus 4.6 b74c8e8add feat: add audio quality selector (standard to jymaster/Hi-Res)
- MusicProvider interface: setQuality/getQuality methods
- NeteaseProvider: passes quality level to /song/url/v1
- Default: exhigh (320kbps MP3)
- Settings page: 6-option grid selector
- GET/POST /api/music/quality endpoints

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 03:37:26 +08:00
saopig1andClaude Opus 4.6 67584d2622 feat: add YesPlayMusic-style home page with daily recs, FM, and user playlists
Add backend endpoints for daily recommended songs, personal FM, user
playlists, and playlist detail. Extend NeteaseProvider and MusicProvider
interface with getDailyRecommendSongs and getUserPlaylists. Rewrite Home
page with FM card, daily recommendations grid, and user playlists section.
Fix Playlist view to fetch detail and songs from separate endpoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 02:07:11 +08:00
saopig1andClaude Opus 4.6 9755ba2909 fix: QR login now persists cookies, shows server-generated QR image, passes timestamp
- Auth router accepts CookieStore and persists cookies on login
- NeteaseProvider passes timestamp to prevent cached QR responses
- QR image from server used directly (qrimg field)
- Cookie saved to disk on confirmed QR scan

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 01:47:25 +08:00
saopig1andClaude Opus 4.6 94902fc2c4 feat: add music source service — NetEase/QQ providers, unified interface, cookie auth
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 00:39:47 +08:00