feat(stage): stage IPC handlers and composer focus

Phase 525 adds approve-stage-speaker and demote-stage-speaker handlers plus composer-focus-channel after join, request, and approve.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-24 11:22:34 -04:00
co-authored by Cursor
parent 7fdb7e1aff
commit 46f5ce0e00
2 changed files with 37 additions and 1 deletions
+3 -1
View File
@@ -2,6 +2,8 @@
Pearcord desktop UI IPC dispatch and automated flow scenarios for Bare smokes. Mirrors `apps/pearcord` pear-pipe message handling.
**v0.8.488 (Phase 525):** `join-stage`, `request-stage-speak`, `approve-stage-speaker`, and `demote-stage-speaker` emit `composer-focus-channel` in guild mode. Bundle: `npm run test:phase525-stage` (app repo).
**v0.8.487 (Phase 524):** `join-voice`, `join-voice-listen`, and `leave-voice` emit `composer-focus-channel` when `platform.activeChannelId` is set (guild mode), matching messaging/reaction focus behavior. Bundle: `npm run test:phase524-voice` (app repo).
## Mission
@@ -49,7 +51,7 @@ Returns `false` for unknown types (caller may log).
| Announcements | `set-announcement-crosspost`, `set-announcement-hub-publish`, `subscribe-remote-announcement-hub`, `follow-announcement` |
| Boosts / stickers | `contribute-guild-boost`, `upsert-guild-sticker`, `upsert-sticker-pack` |
| Profile | `update-profile-cosmetics`, `set-profile-banner-image`, step-up PIN types |
| Voice / screen | `join-voice`, `join-voice-listen`, `join-stage`, `voice-capture-chunk`, `display-capture-frame` |
| Voice / screen | `join-voice`, `join-voice-listen`, `leave-voice`, `join-stage`, `request-stage-speak`, `approve-stage-speaker`, `demote-stage-speaker`, `voice-capture-chunk`, `display-capture-frame` |
| Notifications | `mark-all-notifications-read` (emits `mark-all-notifications-read-cleared` + `composer-focus-channel`, v0.8.407), `mark-notification-read` (calls `platform.markNotificationRead`, emits `mark-notification-read-cleared` + `notificationChannelId`, v0.8.407), `open-notification` (marks read via `markNotificationRead`, emits `composer-focus-channel`, v0.8.407), `mark-channel-read` (emits `mark-channel-read-cleared` + `threadChannelId` for threads, v0.8.287), `refresh-notifications` (v0.8.236) |
| Workers | `export-integration-worker-script`, `run-worker-install-trial`, `announce-worker-release` |
| Moderation / channels | `ban-member`, `upsert-channel-overwrite`, forum/thread types |
+34
View File
@@ -519,6 +519,12 @@ async function dispatchUiMessage (platform, msg, hooks = {}) {
try {
await platform.joinStageChannel(msg.channelId)
pushState()
if (platform.activeChannelId && platform.mode === 'guild') {
send({
type: 'composer-focus-channel',
channelId: platform.activeChannelId
})
}
} catch (err) {
const errMsg = err?.message || String(err)
if (/voice channel is full/i.test(errMsg)) {
@@ -537,6 +543,12 @@ async function dispatchUiMessage (platform, msg, hooks = {}) {
try {
await platform.requestStageSpeak()
pushState()
if (platform.activeChannelId && platform.mode === 'guild') {
send({
type: 'composer-focus-channel',
channelId: platform.activeChannelId
})
}
} catch (err) {
if (/voice channel is full/i.test(err?.message || '')) {
send({ type: 'error', message: err.message })
@@ -632,6 +644,28 @@ async function dispatchUiMessage (platform, msg, hooks = {}) {
}
return true
}
if (t === 'approve-stage-speaker') {
await platform.approveStageSpeaker(msg.userId)
if (platform.activeChannelId && platform.mode === 'guild') {
send({
type: 'composer-focus-channel',
channelId: platform.activeChannelId
})
}
pushState()
return true
}
if (t === 'demote-stage-speaker') {
await platform.demoteStageSpeaker(msg.userId)
if (platform.activeChannelId && platform.mode === 'guild') {
send({
type: 'composer-focus-channel',
channelId: platform.activeChannelId
})
}
pushState()
return true
}
if (t === 'start-screen-share') {
resetDisplayCaptureTrace()
await platform.startScreenShare(msg.label)