feat: complete Phase 1 - game library, lifecycle, realtime sync

- Seed 33 popular games across 5 platforms via admin API script
- Add GameDetailDialog with game info and quick-team button
- Update GamesLibrary with game card click to open detail dialog
- Update Home hot games to open detail dialog instead of navigating
- Rewrite invitation accept: frontend auto-joins team + updates status
- Add user status reset on team dissolution (endGame)
- Add start game / dissolve buttons to TeamSessionPanel lifecycle
- Integrate realtime subscriptions in GroupView and Layout
- Add notification store realtime invitation listener
- Add placeholder images for game covers and avatars
- Remove Go hooks, add JS hooks placeholder + Docker mount

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
congsh
2026-04-17 20:23:39 +08:00
parent 0bcf39bb4b
commit 802712c662
17 changed files with 394 additions and 180 deletions
+22 -1
View File
@@ -77,8 +77,29 @@ export async function respondInvitation(
updateData.rejectReason = rejectReason
}
// 后端 hook 会自动处理:加入 team members + 更新用户状态
// 更新邀请状态
await pb.collection('invitations').update(invitationId, updateData)
// 接受邀请:前端处理加入 team session + 更新用户状态
if (response === 'accepted') {
const user = pb.authStore.model
if (!user) return
// 获取邀请详情以找到 team session
const invitation = await pb.collection('invitations').getOne(invitationId) as any
const teamSessionId = invitation.teamSession
// 加入 team session
const session = await pb.collection('team_sessions').getOne(teamSessionId) as any
const members: string[] = session.members || []
if (!members.includes(user.id)) {
members.push(user.id)
await pb.collection('team_sessions').update(teamSessionId, { members })
}
// 更新用户状态为 in_team
await pb.collection('users').update(user.id, { status: 'in_team' })
}
}
// 订阅邀请变更
+16 -2
View File
@@ -49,9 +49,23 @@ export async function updateTeamStatus(sessionId: string, status: TeamStatus): P
return pb.collection('team_sessions').update(sessionId, updateData) as unknown as TeamSession
}
// 结束游戏(解散临时小组)
// 结束游戏(解散临时小组 + 重置成员状态
export async function endGame(sessionId: string) {
return updateTeamStatus(sessionId, 'dissolved')
const session = await pb.collection('team_sessions').getOne(sessionId) as any
const members: string[] = session.members || []
// 解散临时小组
await updateTeamStatus(sessionId, 'dissolved')
// 重置所有成员状态为 idle
for (const memberId of members) {
try {
const user = await pb.collection('users').getOne(memberId) as any
if (user && user.status === 'in_team') {
await pb.collection('users').update(memberId, { status: 'idle' })
}
} catch (_) {}
}
}
// 加入临时小组