All checks were successful
Trigger cinny-mobile / dispatch (push) Successful in 2s
Bots can publish a declarative panel UI that takes over a room; user actions are sent as im.paarrot.ui.action timeline events.
68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
import React, { useCallback } from 'react';
|
||
import { Box, Button, Header, Text, config } from 'folds';
|
||
import { Room } from 'matrix-js-sdk';
|
||
import { Page } from '../../components/page';
|
||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
|
||
import { useStateEvent } from '../../hooks/useStateEvent';
|
||
import { useRoomName } from '../../hooks/useRoomMeta';
|
||
import {
|
||
MessageEvent,
|
||
PaarrotUiActionContent,
|
||
StateEvent,
|
||
} from '../../../types/matrix/room';
|
||
import { parsePaarrotUiContent } from '../../utils/room';
|
||
import { RoomAppSchema } from './RoomAppSchema';
|
||
import * as css from './RoomAppView.css';
|
||
|
||
type RoomAppViewProps = {
|
||
room: Room;
|
||
onShowChat: () => void;
|
||
};
|
||
|
||
export function RoomAppView({ room, onShowChat }: RoomAppViewProps) {
|
||
const mx = useMatrixClient();
|
||
const useAuthentication = useMediaAuthentication();
|
||
const roomName = useRoomName(room);
|
||
const uiEvent = useStateEvent(room, StateEvent.PaarrotUi);
|
||
const content = parsePaarrotUiContent(uiEvent?.getContent());
|
||
const title = content?.title || roomName || 'Room App';
|
||
|
||
const handleAction = useCallback(
|
||
async (payload: PaarrotUiActionContent) => {
|
||
await mx.sendEvent(room.roomId, MessageEvent.PaarrotUiAction as any, payload);
|
||
},
|
||
[mx, room.roomId]
|
||
);
|
||
|
||
return (
|
||
<Page>
|
||
<Header className={css.Header} size="600">
|
||
<Box grow="Yes" alignItems="Center" gap="200">
|
||
<Box grow="Yes" alignItems="Center" gap="200" minWidth="0">
|
||
<Text size="H6" truncate>
|
||
{title}
|
||
</Text>
|
||
</Box>
|
||
<Button size="300" variant="Secondary" radii="300" onClick={onShowChat}>
|
||
<Text size="B300">Show chat</Text>
|
||
</Button>
|
||
</Box>
|
||
</Header>
|
||
<Box className={css.Body} grow="Yes" direction="Column" style={{ gap: config.space.S400 }}>
|
||
{content ? (
|
||
<RoomAppSchema
|
||
mx={mx}
|
||
content={content}
|
||
uiEventId={uiEvent?.getId()}
|
||
useAuthentication={useAuthentication}
|
||
onAction={handleAction}
|
||
/>
|
||
) : (
|
||
<Text size="T400">This room’s app UI is missing or invalid.</Text>
|
||
)}
|
||
</Box>
|
||
</Page>
|
||
);
|
||
}
|