Skip to content

Commit 5ebe8b6

Browse files
committed
feat: wire FederationBanner into ChatLayout and export federation API from package index
1 parent ec37e1d commit 5ebe8b6

4 files changed

Lines changed: 91 additions & 3 deletions

File tree

packages/react/src/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
export { default as EmbeddedChat } from './views/EmbeddedChat';
2+
export { FederationProvider, useFederation } from './context/FederationContext';
3+
export { isMatrixUser, parseMatrixUserId, getMatrixDisplayLabel, getMatrixInitials, getAvatarColor } from './lib/federationUtils';
4+
export { default as MatrixAvatar } from './views/Message/MatrixAvatar';
5+
export { default as FederationBanner } from './views/FederationBanner/FederationBanner';

packages/react/src/stories/EmbeddedChatFederated.stories.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ export default {
55
component: EmbeddedChat,
66
};
77

8+
/**
9+
* Connect to a Matrix-bridged Rocket.Chat room.
10+
*
11+
* Set env vars before running Storybook:
12+
* STORYBOOK_RC_HOST=http://your-rc-server:3000
13+
* STORYBOOK_FEDERATED_ROOM_ID=<room-id-with-federation-enabled>
14+
*
15+
* What this demonstrates with federation={true}:
16+
* - FederationBanner appears below the header when the room is federated
17+
* - Matrix users (@user:homeserver.tld) show coloured initials avatars
18+
* - Green "Matrix" badge next to sender name in every message
19+
* - Full @user:homeserver shown as username in message header
20+
* - Non-Matrix (RC) users render normally — no changes to existing behaviour
21+
*/
822
export const FederatedRoom = {
923
args: {
1024
host: process.env.STORYBOOK_RC_HOST || 'http://localhost:3000',
@@ -16,9 +30,7 @@ export const FederatedRoom = {
1630
showUsername: true,
1731
enableThreads: true,
1832
hideHeader: false,
19-
auth: {
20-
flow: 'PASSWORD',
21-
},
33+
auth: { flow: 'PASSWORD' },
2234
dark: false,
2335
federation: true,
2436
},
@@ -31,3 +43,11 @@ export const FederatedRoomDark = {
3143
channelName: 'federated-room (dark)',
3244
},
3345
};
46+
47+
export const FederatedRoomAnonymous = {
48+
args: {
49+
...FederatedRoom.args,
50+
anonymousMode: true,
51+
channelName: 'federated-room (anonymous)',
52+
},
53+
};

packages/react/src/views/ChatLayout/ChatLayout.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import Roominfo from '../RoomInformation/RoomInformation';
2525
import UserInformation from '../UserInformation/UserInformation';
2626
import ChatBody from '../ChatBody/ChatBody';
2727
import ChatInput from '../ChatInput/ChatInput';
28+
import FederationBanner from '../FederationBanner/FederationBanner';
2829
import useDropBox from '../../hooks/useDropBox';
2930
import AttachmentPreview from '../AttachmentPreview/AttachmentPreview';
3031
import useAttachmentWindowStore from '../../store/attachmentwindow';
@@ -109,6 +110,7 @@ const ChatLayout = () => {
109110
onDrop={(e) => handleDragDrop(e)}
110111
>
111112
<Box css={styles.chatMain}>
113+
<FederationBanner />
112114
<ChatBody
113115
anonymousMode={anonymousMode}
114116
showRoles={showRoles}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React from 'react';
2+
import { css } from '@emotion/react';
3+
import { Box, useTheme } from '@embeddedchat/ui-elements';
4+
import { useFederation } from '../../context/FederationContext';
5+
6+
const getStyles = (theme) => ({
7+
banner: css`
8+
display: flex;
9+
align-items: center;
10+
gap: 0.4rem;
11+
padding: 0.35rem 1rem;
12+
background: #0dbd8b18;
13+
border-bottom: 1px solid #0dbd8b44;
14+
font-size: 0.72rem;
15+
font-weight: 600;
16+
color: #0dbd8b;
17+
letter-spacing: 0.03em;
18+
`,
19+
dot: css`
20+
width: 6px;
21+
height: 6px;
22+
border-radius: 50%;
23+
background: #0dbd8b;
24+
flex-shrink: 0;
25+
`,
26+
homeserver: css`
27+
font-weight: 400;
28+
opacity: 0.75;
29+
margin-left: 2px;
30+
`,
31+
});
32+
33+
/**
34+
* FederationBanner
35+
*
36+
* Renders a slim banner below the chat header when the active room is
37+
* Matrix-bridged. Hidden when the room is not federated or detection is
38+
* still in flight.
39+
*
40+
* Activated automatically by FederationProvider — no props needed.
41+
*/
42+
const FederationBanner = () => {
43+
const { isFederated, matrixHomeserver, federationLoading } = useFederation();
44+
const { theme } = useTheme();
45+
const styles = getStyles(theme);
46+
47+
if (federationLoading || !isFederated) return null;
48+
49+
return (
50+
<Box css={styles.banner} aria-live="polite" role="status">
51+
<Box css={styles.dot} />
52+
🔗 Matrix federated room
53+
{matrixHomeserver && (
54+
<Box is="span" css={styles.homeserver}>
55+
· {matrixHomeserver}
56+
</Box>
57+
)}
58+
</Box>
59+
);
60+
};
61+
62+
export default FederationBanner;

0 commit comments

Comments
 (0)