Skip to content

feat: improve toast UX#165

Merged
roitium merged 2 commits into
devfrom
chore/improve-toast-ux
Jan 25, 2026
Merged

feat: improve toast UX#165
roitium merged 2 commits into
devfrom
chore/improve-toast-ux

Conversation

@roitium
Copy link
Copy Markdown
Collaborator

@roitium roitium commented Jan 25, 2026

… IDs for better status management.

Summary by CodeRabbit

发布说明

  • 改进功能
    • 优化播放列表同步过程中的用户反馈机制,同步中的提示信息现在会持续显示直到操作完成。
    • 增强错误处理,同步失败时会正确关闭对应的提示信息,提供更清晰的操作状态。

✏️ Tip: You can customize this high-level summary in your review settings.

@roitium roitium added the enhancement New feature or request label Jan 25, 2026
@safedep
Copy link
Copy Markdown

safedep Bot commented Jan 25, 2026

SafeDep Report Summary

Green Malicious Packages Badge Green Vulnerable Packages Badge Green Risky License Badge

No dependency changes detected. Nothing to scan.

This report is generated by SafeDep Github App

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 25, 2026

Walkthrough

该PR在播放列表同步功能中实现了持久化的toast通知系统。修改涉及多个同步端点(本地、收藏、多页面)添加带ID的持久toast,通过mutation传递toastId以关联toast生命周期,并更新toast工具函数返回值以支持后续的dismiss操作。

Changes

内聚 / 文件 变更摘要
播放列表同步UI组件
src/app/playlist/local/[id].tsx, src/app/playlist/remote/collection/[id].tsx, src/app/playlist/remote/favorite/[id].tsx, src/app/playlist/remote/multipage/[bvid].tsx
将临时toast替换为持久化toast:创建 toastId = 'sync-playlist' 并调用 toast.show('同步中...', { id: toastId, duration: Infinity }),随后将 toastId 传递到对应的sync mutation中
Mutation Hook
src/hooks/mutations/db/playlist.ts
更新 usePlaylistSync 的mutation签名:mutationFn参数添加可选的 toastId?: string 字段;onSuccess回调改为接收 (id, { toastId }) 参数并使用toastId显示成功toast;onError回调改为接收 (error, { remoteSyncId, type, toastId }) 并在错误时dismiss对应的toast
Toast工具函数
src/utils/toast.ts
showsuccesserrorinfo 方法添加返回值:现在返回对应sonner调用的结果(原先为void)

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as 播放列表页面
    participant Toast as Toast系统
    participant Mutation as Sync Mutation
    participant API as 后端API
    
    User->>UI: 点击同步按钮
    activate UI
    UI->>Toast: toast.show('同步中...', {id: 'sync-playlist', duration: Infinity})
    activate Toast
    Toast-->>UI: 返回 toastId
    deactivate Toast
    
    UI->>Mutation: mutate({remoteSyncId, type, toastId: 'sync-playlist'})
    deactivate UI
    
    activate Mutation
    Mutation->>API: 发起同步请求
    activate API
    
    alt 同步成功
        API-->>Mutation: 返回成功结果
        Mutation->>Toast: toast.success(..., {id: 'sync-playlist'})
        activate Toast
        Toast->>Toast: 替换toast为成功状态
        deactivate Toast
        Mutation->>UI: 导航到本地播放列表
    else 同步失败
        API-->>Mutation: 返回错误
        Mutation->>Toast: toast.dismiss('sync-playlist')
        activate Toast
        Toast->>Toast: 关闭loading toast
        deactivate Toast
        Mutation->>Mutation: 记录错误日志
    end
    
    deactivate API
    deactivate Mutation
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • BBPlayer#163: 本PR对toast返回值和使用方式的改变直接基于PR #163中的sonner集成改造,两个PR密切相关。

Poem

🐰 持久的提示在屏幕舞动,
同步的过程不再默默进行,
一个ID唤醒了toast的灵魂,
成功或失败,都能优雅落幕。
兔兔欢呼,代码更显温柔!🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题'feat: improve toast UX'准确概括了本次变更的核心内容——改进吐司通知的用户体验,通过引入持久化吐司ID和改进吐司管理机制。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/app/playlist/remote/favorite/[id].tsx (1)

85-110: setRefreshing(false) 执行时机错误导致刷新状态无效。

setRefreshing(false) 在 Line 109 同步调用,但 syncFavorite 是异步操作。这意味着 refreshing 状态几乎立即被设为 false,使得刷新指示器无法正确反映同步进度。

🔧 建议的修复方案
 	const handleSync = useCallback(() => {
 		if (favoriteData?.pages.flatMap((page) => page.medias).length === 0) {
 			toast.info('收藏夹为空,无需同步')
 			return
 		}
 		const toastId = 'sync-playlist'
 		toast.show('同步中...', { id: toastId, duration: Infinity })
 		setRefreshing(true)
 		syncFavorite(
 			{
 				remoteSyncId: Number(id),
 				type: 'favorite',
 				toastId,
 			},
 			{
 				onSuccess: (id) => {
+					setRefreshing(false)
 					if (!id) return
 					router.replace({
 						pathname: '/playlist/local/[id]',
 						params: { id: String(id) },
 					})
 				},
+				onError: () => {
+					setRefreshing(false)
+				},
 			},
 		)
-		setRefreshing(false)
 	}, [favoriteData?.pages, id, router, syncFavorite])

或者使用 onSettled 回调统一处理:

 		syncFavorite(
 			{ ... },
 			{
 				onSuccess: (id) => { ... },
+				onSettled: () => {
+					setRefreshing(false)
+				},
 			},
 		)
-		setRefreshing(false)
src/app/playlist/remote/collection/[id].tsx (1)

78-99: setRefreshing(false) 执行时机错误。

favorite/[id].tsx 存在相同问题:setRefreshing(false) 在 Line 98 同步调用,而非等待异步 mutation 完成。

🔧 建议的修复方案
 	const handleSync = useCallback(() => {
 		const toastId = 'sync-playlist'
 		toast.show('同步中...', { id: toastId, duration: Infinity })
 		setRefreshing(true)
 		syncCollection(
 			{
 				remoteSyncId: Number(id),
 				type: 'collection',
 				toastId,
 			},
 			{
 				onSuccess: (id) => {
+					setRefreshing(false)
 					if (!id) return
 					router.replace({
 						pathname: '/playlist/local/[id]',
 						params: { id: String(id) },
 					})
 				},
+				onSettled: () => {
+					setRefreshing(false)
+				},
 			},
 		)
-		setRefreshing(false)
 	}, [id, router, syncCollection])
src/app/playlist/remote/multipage/[bvid].tsx (1)

101-122: setRefreshing(false) 执行时机错误。

favorite/[id].tsxcollection/[id].tsx 存在相同问题。建议统一修复所有三个文件的 handleSync 回调。

🔧 建议的修复方案
 	const handleSync = useCallback(() => {
 		const toastId = 'sync-playlist'
 		toast.show('同步中...', { id: toastId, duration: Infinity })
 		setRefreshing(true)
 		syncMultipage(
 			{
 				remoteSyncId: bv2av(bvid),
 				type: 'multi_page',
 				toastId,
 			},
 			{
 				onSuccess: (id) => {
+					setRefreshing(false)
 					if (!id) return
 					router.replace({
 						pathname: '/playlist/local/[id]',
 						params: { id: String(id) },
 					})
 				},
+				onSettled: () => {
+					setRefreshing(false)
+				},
 			},
 		)
-		setRefreshing(false)
 	}, [bvid, router, syncMultipage])

@roitium roitium merged commit 22dd919 into dev Jan 25, 2026
3 checks passed
@roitium roitium deleted the chore/improve-toast-ux branch January 25, 2026 03:56
@roitium
Copy link
Copy Markdown
Collaborator Author

roitium commented Jan 25, 2026

/build-nightly

@github-actions
Copy link
Copy Markdown
Contributor

⏹️ Nightly 构建已取消

构建被新的 /build-nightly 请求取消。

@roitium
Copy link
Copy Markdown
Collaborator Author

roitium commented Jan 25, 2026

/build-nightly

@github-actions
Copy link
Copy Markdown
Contributor

✅ Nightly 构建成功

信息
📝 Commit 8d1584c
📦 下载 Nightly Release
🔗 详情 Workflow

APK 已上传到 Nightly Release 🚀

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant