a9505ca5b2
Soundboard v2 — a near-parallel of the custom-emoji image-pack system for in-call audio clips. - Data model: 3-tier packs mirroring MSC2545 — room/space pack (state event io.lotus.soundboard, inherited by child rooms via parent-space aggregation), global refs (io.lotus.soundboard_rooms), and the personal pack (io.lotus.soundboard account data; the v1 flat-list content is migrated to the pack shape on read). New plugins/soundboard/ (readers, SoundboardPack, utils) + hooks/useSoundboardPacks (useRelevantSoundboardPacks = user U global U room, deduped). Unit-tested (migration + slug). - Management: reusable SoundboardPackEditor (name + emoji + per-clip volume + delete + upload + batched save), power-level-gated for room packs like emoji packs; a Soundboard page wired into Room + Space settings. - In-call: CallSoundboard rewritten as a Discord-style grid grouped by pack (emoji + name tiles), sourcing room+parent-space U personal clips; a Manage toggle embeds the editors; per-clip volume x master volume on playback. - Spam guard: host gates on a playing key (fork enforces one clip at a time). - Control bar: Mute-Screenshare moved next to the Screenshare button. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
30 lines
792 B
TypeScript
30 lines
792 B
TypeScript
import { SoundboardMeta } from './types';
|
|
|
|
/** Parallels custom-emoji/PackMetaReader (no usage tiers for soundboard). */
|
|
export class SoundboardMetaReader {
|
|
private readonly meta: SoundboardMeta;
|
|
|
|
constructor(meta: SoundboardMeta) {
|
|
this.meta = meta;
|
|
}
|
|
|
|
get name(): string | undefined {
|
|
const displayName = this.meta.display_name;
|
|
return typeof displayName === 'string' ? displayName : undefined;
|
|
}
|
|
|
|
get avatar(): string | undefined {
|
|
const avatarURL = this.meta.avatar_url;
|
|
return typeof avatarURL === 'string' ? avatarURL : undefined;
|
|
}
|
|
|
|
get attribution(): string | undefined {
|
|
const { attribution } = this.meta;
|
|
return typeof attribution === 'string' ? attribution : undefined;
|
|
}
|
|
|
|
get content(): SoundboardMeta {
|
|
return this.meta;
|
|
}
|
|
}
|