Files
cinny/src/app/components/soundboard-pack-view/RoomSoundboardPack.tsx
T
jared c2598d21cd fix(dp): address TPVR review findings (DP2 redo, DP4 dedup, DP15 gap)
- DP2: the earlier seed fix was ineffective (allInvitesAtom populates post-mount,
  so first render is still empty). Rewrite to track invite room ids and stay
  'unarmed' until the initial sync settles (+3s grace), notifying only for ids that
  first appear after arming — robust to the async population race.
- DP4: batch the mutually-exclusive tag writes via Promise.all so a failure surfaces
  a single toast instead of one per operation.
- DP15: route the two remaining StateEvent writes (RoomSoundboardPack / RoomImagePack,
  which used an 'as unknown as keyof StateEvents' idiom the sweep missed) through the
  typed sendStateEvent helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:02:04 -04:00

46 lines
1.8 KiB
TypeScript

import React, { useCallback, useMemo } from 'react';
import { Room } from 'matrix-js-sdk';
import { usePowerLevels } from '../../hooks/usePowerLevels';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { SoundboardPackEditor } from './SoundboardPackEditor';
import { SoundboardContent, SoundboardPack } from '../../plugins/soundboard';
import { StateEvent } from '../../../types/matrix/room';
import { sendStateEvent } from '../../utils/room';
import { useRoomSoundboardPack } from '../../hooks/useSoundboardPacks';
import { PackAddress } from '../../plugins/custom-emoji/PackAddress';
import { randomStr } from '../../utils/common';
import { useRoomPermissions } from '../../hooks/useRoomPermissions';
import { useRoomCreators } from '../../hooks/useRoomCreators';
type RoomSoundboardPackProps = {
room: Room;
stateKey: string;
};
export function RoomSoundboardPack({ room, stateKey }: RoomSoundboardPackProps) {
const mx = useMatrixClient();
const userId = mx.getUserId()!;
const powerLevels = usePowerLevels(room);
const creators = useRoomCreators(room);
const permissions = useRoomPermissions(creators, powerLevels);
const canEdit = permissions.stateEvent(
StateEvent.LotusSoundboardRoom as unknown as keyof import('matrix-js-sdk').StateEvents,
userId,
);
const fallbackPack = useMemo(
() => new SoundboardPack(randomStr(4), {}, new PackAddress(room.roomId, stateKey)),
[room.roomId, stateKey],
);
const pack = useRoomSoundboardPack(room, stateKey) ?? fallbackPack;
const handleUpdate = useCallback(
async (content: SoundboardContent) => {
await sendStateEvent(mx, room.roomId, StateEvent.LotusSoundboardRoom, content, stateKey);
},
[mx, room.roomId, stateKey],
);
return <SoundboardPackEditor pack={pack} canEdit={canEdit} onUpdate={handleUpdate} />;
}