fix: restrict call button to DMs and invite-only rooms only

This commit is contained in:
root
2026-05-15 15:44:51 -04:00
parent 549634dca0
commit b2d36d79e6
2 changed files with 3 additions and 21 deletions
+1 -2
View File
@@ -58,8 +58,7 @@ A full custom theme engine layered on top of Cinny's vanilla-extract theming:
- Listens on both main window and EC iframe `contentWindow` for reliable key capture
- Implemented via `CallControl.setMicrophone()` public method on the widget bridge
- **Noise suppression toggle**: Settings > General > Calls — passes `noiseSuppression` URL parameter to the embedded Element Call widget
- **DM calls**: Phone button in DM room header starts a 1-on-1 call via `useCallStart(true)`. `Room.tsx` switches to CallView layout when the DM has an active call embed. Standard voice rooms were already supported; this extends call support to all direct messages.
- **Call button scoping**: The upstream Cinny 4.12.1 call button (voice + video dropdown) is restricted to DMs and invite-only rooms only (`join_rule: invite`). Public rooms and space-restricted channels are excluded to prevent accidental mass-notifications in large communities. `Room.tsx` switches to CallView layout when a call embed is active in the current room.
- **Poll display**: `m.poll.start` events (both stable Matrix 1.7 `m.poll` content key and MSC3381 unstable `org.matrix.msc3381.poll.start`) render as read-only poll cards inside the standard message bubble — question and answer options shown. Registered as top-level event renderers AND inside the `EncryptedContent` callback so encrypted polls also display after decryption. "Open in Element to vote" note displayed. Implemented in `PollContent.tsx`.
- **Deleted message placeholder**: Redacted `m.room.message`, `m.room.encrypted`, and `m.sticker` events no longer disappear from the timeline. Instead they reach the existing `RedactedContent` component (trash icon + italic "This message has been deleted" with reason if provided), matching Element, FluffyChat, Commet, and Nheko behaviour. One-line change in the `eventRenderer` filter in `RoomTimeline.tsx`.
- **Incoming DM call notification**: When another user starts a call in a DM room, a fixed-position notification appears with the caller's avatar and display name, Answer and Decline buttons, and a Web Audio API double-pulse ring tone. The notification auto-dismisses after 30 seconds or when the caller leaves. Fully themed for both LotusGuild Terminal TDS (dark navy `#060c14` background, orange border, neon-green Answer button, JetBrains Mono font, pulsing indicator dot) and standard Cinny dark/light mode (CSS variable theming, folds `Button` with `variant="Success"/"Critical"`). Implemented in `useIncomingDmCall` hook (watches `MatrixRTCSessionManagerEvents.SessionStarted`, filters encrypted ≤2-member rooms, ignores self) and `IncomingCallNotification` component mounted inside `CallEmbedProvider` in `Router.tsx`.
- **Picture-in-picture (PiP)**: When navigating away from a call room while in an active call, the call embed shrinks to a 280x158px floating window in the bottom-right corner. The PiP window is **draggable** — drag it anywhere on screen to move it out of the way. Clicking (without dragging) navigates back to the call room. Drag vs click distinguished by a 5px movement threshold; touch drag supported. Imperative style overrides on `callEmbedRef.current` via `useEffect` — a wrapper div cannot be used because `useCallEmbedPlacementSync` writes `top/left/width/height` directly onto that element.
+2 -19
View File
@@ -404,7 +404,6 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) {
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
const [pinMenuAnchor, setPinMenuAnchor] = useState<RectCords>();
const direct = useIsDirectRoom();
const startCall = useCallStart(true);
const pinnedEvents = useRoomPinnedEvents(room);
const encryptionEvent = useStateEvent(room, StateEvent.RoomEncryption);
@@ -521,23 +520,6 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) {
</Box>
<Box shrink="No">
{direct && !callView && (
<TooltipProvider
position="Bottom"
offset={4}
tooltip={
<Tooltip>
<Text>Start Call</Text>
</Tooltip>
}
>
{(triggerRef) => (
<IconButton fill="None" ref={triggerRef} onClick={() => startCall(room)}>
<Icon size="400" src={Icons.Phone} />
</IconButton>
)}
</TooltipProvider>
)}
{!encryptedRoom && (
<TooltipProvider
position="Bottom"
@@ -612,7 +594,8 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) {
</FocusTrap>
}
/>
{!room.isCallRoom() && livekitSupported && rtcSupported && hasCallPermission && (
{!room.isCallRoom() && livekitSupported && rtcSupported && hasCallPermission &&
(direct || room.getJoinRule() === 'invite') && (
<CallButton />
)}
{screenSize === ScreenSize.Desktop && (