Skip to content

Commit 3ec3671

Browse files
authored
chore(demo): add message actions configuration (#3115)
1 parent f95f287 commit 3ec3671

File tree

15 files changed

+566
-68
lines changed

15 files changed

+566
-68
lines changed

examples/vite/src/App.tsx

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {
1919
Button,
2020
Chat,
2121
ChatView,
22-
createIcon,
2322
DialogManagerProvider,
2423
MessageReactions,
2524
type NotificationListProps,
@@ -67,6 +66,8 @@ import {
6766
getReactionsVariant,
6867
getSystemMessageVariant,
6968
} from './CustomMessageUi';
69+
import { ConfigurableMessageActions } from './CustomMessageActions';
70+
import { SidebarToggle } from './Sidebar/SidebarToggle.tsx';
7071

7172
init({ data });
7273

@@ -176,36 +177,6 @@ const ConfigurableNotificationList = (props: NotificationListProps) => {
176177
return <NotificationList {...props} verticalAlignment={verticalAlignment} />;
177178
};
178179

179-
const IconSidebar = createIcon(
180-
'IconSidebar',
181-
<path
182-
d='M6.875 3.75V16.25M3.125 3.75H16.875C17.2202 3.75 17.5 4.02982 17.5 4.375V15.625C17.5 15.9702 17.2202 16.25 16.875 16.25H3.125C2.77982 16.25 2.5 15.9702 2.5 15.625V4.375C2.5 4.02982 2.77982 3.75 3.125 3.75Z'
183-
fill='none'
184-
stroke='currentColor'
185-
strokeLinecap='round'
186-
strokeLinejoin='round'
187-
strokeWidth='1.5'
188-
/>,
189-
);
190-
191-
const SidebarToggle = () => {
192-
const { closeSidebar, openSidebar, sidebarOpen } = useSidebar();
193-
const { t } = useTranslationContext();
194-
return (
195-
<Button
196-
appearance='ghost'
197-
aria-label={sidebarOpen ? t('aria/Collapse sidebar') : t('aria/Expand sidebar')}
198-
circular
199-
className='str-chat__header-sidebar-toggle'
200-
onClick={sidebarOpen ? closeSidebar : openSidebar}
201-
size='md'
202-
variant='secondary'
203-
>
204-
<IconSidebar />
205-
</Button>
206-
);
207-
};
208-
209180
const language = new URLSearchParams(window.location.search).get('language');
210181
const i18nInstance = language ? new Streami18n({ language: language as any }) : undefined;
211182

@@ -405,6 +376,7 @@ const App = () => {
405376
Search: CustomChannelSearch,
406377
HeaderEndContent: SidebarToggle,
407378
HeaderStartContent: SidebarToggle,
379+
MessageActions: ConfigurableMessageActions,
408380
...messageUiOverrides,
409381
}}
410382
>

examples/vite/src/AppSettings/AppSettings.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,18 @@
453453
color: var(--text-primary);
454454
}
455455

456+
.app__settings-modal__field .str-chat__form__switch-field {
457+
border: 1px solid var(--border-core-default);
458+
border-radius: 10px;
459+
padding: 10px 12px;
460+
}
461+
462+
.app__settings-modal__field-comment {
463+
color: var(--text-secondary);
464+
font-size: 13px;
465+
line-height: 1.4;
466+
}
467+
456468
.app__settings-modal__options-row {
457469
display: flex;
458470
gap: 10px;

examples/vite/src/AppSettings/AppSettings.tsx

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,29 @@ import React from 'react';
22
import {
33
Button,
44
ChatViewSelectorButton,
5-
createIcon,
65
GlobalModal,
76
IconBell,
87
IconEmoji,
98
IconMessageBubble,
109
} from 'stream-chat-react';
1110
import { type ComponentType, useState } from 'react';
1211

13-
const IconGear = createIcon(
14-
'IconGear',
15-
<path d='M13.5667 8.00031C13.5667 7.81566 13.4743 7.64281 13.3206 7.54034L12.7503 7.16046C12.0815 6.71442 11.7583 5.90079 11.9388 5.11749L12.0472 4.64777C12.092 4.45315 12.034 4.24906 11.8929 4.10773C11.7515 3.96629 11.5467 3.90753 11.3519 3.95245L10.8831 4.06085C10.0996 4.24168 9.28525 3.91849 8.8392 3.24933L8.45932 2.67902C8.35689 2.52558 8.18474 2.43303 8.00034 2.43292C7.81575 2.43292 7.64286 2.5254 7.54037 2.67902L7.16049 3.24933C6.7145 3.91832 5.90097 4.24146 5.11752 4.06085L4.6478 3.95245C4.45304 3.90767 4.24908 3.9664 4.10776 4.10773C3.96643 4.24905 3.9077 4.45301 3.95248 4.64777L4.06088 5.11749C4.24149 5.90094 3.91835 6.71447 3.24936 7.16046L2.67905 7.54034C2.52543 7.64282 2.43295 7.81572 2.43295 8.00031C2.43306 8.18471 2.52561 8.35686 2.67905 8.45929L3.24936 8.83917C3.91852 9.28522 4.24171 10.0995 4.06088 10.8831L3.95248 11.3519C3.90756 11.5467 3.96632 11.7514 4.10776 11.8929C4.24909 12.034 4.45317 12.092 4.6478 12.0472L5.11752 11.9388C5.90082 11.7583 6.71445 12.0814 7.16049 12.7503L7.54037 13.3206C7.64284 13.4743 7.81569 13.5667 8.00034 13.5667C8.18484 13.5666 8.35691 13.4742 8.45932 13.3206L8.8392 12.7503C9.2574 12.123 9.99909 11.8004 10.7357 11.9114L10.8831 11.9388L11.3519 12.0472C11.5467 12.0922 11.7505 12.0334 11.8919 11.8919C12.0334 11.7504 12.0922 11.5467 12.0472 11.3519L11.9388 10.8831C11.7581 10.0996 12.0812 9.28525 12.7503 8.83917L13.3206 8.45929C13.4742 8.35688 13.5666 8.18481 13.5667 8.00031ZM9.23373 8.00031C9.23373 7.31925 8.68135 6.76708 8.00034 6.76691C7.31917 6.76691 6.76694 7.31914 6.76694 8.00031C6.76711 8.68132 7.31928 9.2337 8.00034 9.2337C8.68124 9.23353 9.23356 8.68121 9.23373 8.00031ZM10.433 8.00031C10.4328 9.34395 9.34398 10.4327 8.00034 10.4329C6.65654 10.4329 5.56692 9.34406 5.56674 8.00031C5.56674 6.6564 6.65643 5.56671 8.00034 5.56671C9.34409 5.56689 10.433 6.65651 10.433 8.00031ZM14.7669 8.00031C14.7668 8.58607 14.474 9.13337 13.9867 9.45831L13.4164 9.8382C13.1627 10.0072 13.0404 10.3155 13.1087 10.6126L13.2171 11.0823C13.355 11.6803 13.1744 12.3067 12.7406 12.7405C12.3067 13.1744 11.6803 13.355 11.0824 13.2171L10.6126 13.1087C10.3155 13.0403 10.0073 13.1627 9.83823 13.4163L9.45834 13.9866C9.1334 14.4739 8.5861 14.7668 8.00034 14.7669C7.41454 14.7669 6.86735 14.4739 6.54233 13.9866L6.16245 13.4163C5.99328 13.1626 5.6843 13.0402 5.38705 13.1087L4.9183 13.2171C4.32022 13.3552 3.69313 13.1746 3.25912 12.7405C2.82535 12.3066 2.64568 11.6802 2.78354 11.0823L2.89194 10.6126C2.96027 10.3155 2.83695 10.0072 2.58334 9.8382L2.01401 9.45831C1.52667 9.13338 1.23384 8.58608 1.23373 8.00031C1.23373 7.4144 1.52657 6.86729 2.01401 6.5423L2.58334 6.16241C2.83709 5.99325 2.96042 5.68417 2.89194 5.38702L2.78354 4.91827C2.64553 4.32022 2.82513 3.69309 3.25912 3.25909C3.69312 2.8251 4.32025 2.6455 4.9183 2.78351L5.38705 2.89191C5.6842 2.96039 5.99328 2.83706 6.16245 2.58331L6.54233 2.01398C6.86732 1.52654 7.41443 1.2337 8.00034 1.2337C8.58611 1.23381 9.13341 1.52663 9.45834 2.01398L9.83823 2.58331C10.0073 2.83692 10.3156 2.96024 10.6126 2.89191L11.0824 2.78351C11.6803 2.64565 12.3067 2.82532 12.7406 3.25909C13.1746 3.6931 13.3552 4.3202 13.2171 4.91827L13.1087 5.38702C13.0402 5.68427 13.1626 5.99325 13.4164 6.16241L13.9867 6.5423C14.4739 6.86732 14.7669 7.41451 14.7669 8.00031Z' />,
16-
{ viewBox: '0 0 16 16' },
17-
);
18-
19-
const IconLightBulb = createIcon(
20-
'IconLightBulb',
21-
<>
22-
<path d='M12.2328 6.66736C12.2328 4.32904 10.3378 2.43302 7.99945 2.43298C5.66113 2.43298 3.76508 4.32901 3.76508 6.66736C3.76509 8.03465 4.4128 9.25078 5.42035 10.0258C5.44202 10.0425 5.46556 10.0594 5.48871 10.0765C6.00058 10.4543 6.43207 11.0657 6.43207 11.8119V12.6664C6.43232 13.5319 7.13392 14.2338 7.99945 14.2338C8.86496 14.2337 9.56658 13.5318 9.56683 12.6664V11.8119C9.56683 11.0657 9.99831 10.4543 10.5102 10.0765C10.5335 10.0593 10.556 10.0424 10.5776 10.0258L10.7631 9.87537C11.6644 9.09822 12.2328 7.94919 12.2328 6.66736ZM13.433 6.66736C13.433 8.42299 12.6002 9.98457 11.31 10.9769C11.2807 10.9995 11.2513 11.0205 11.2231 11.0414C10.9238 11.2623 10.767 11.55 10.767 11.8119V12.6664C10.7668 14.1946 9.5277 15.4329 7.99945 15.433C6.47116 15.433 5.23213 14.1946 5.23187 12.6664V11.8119C5.23187 11.5827 5.11171 11.3346 4.88129 11.1283L4.77582 11.0424L4.6889 10.9769C3.39867 9.98457 2.56587 8.42301 2.56586 6.66736C2.56586 3.66628 4.99838 1.23376 7.99945 1.23376C11.0005 1.2338 13.433 3.6663 13.433 6.66736Z' />
23-
<path d='M10.1669 11.2338C10.4982 11.2338 10.7665 11.502 10.7665 11.8334C10.7665 12.1647 10.4982 12.433 10.1669 12.433H5.83193C5.50056 12.433 5.23232 12.1647 5.23232 11.8334C5.23232 11.502 5.50056 11.2338 5.83193 11.2338H10.1669Z' />
24-
</>,
25-
{ viewBox: '0 0 16 16' },
26-
);
27-
const IconTextDirection = createIcon(
28-
'IconTextDirection',
29-
<path d='M9.5 2H12.5C12.7761 2 13 2.22386 13 2.5C13 2.77614 12.7761 3 12.5 3H11V12.5C11 12.7761 10.7761 13 10.5 13C10.2239 13 10 12.7761 10 12.5V3H9V12.5C9 12.7761 8.77614 13 8.5 13C8.22386 13 8 12.7761 8 12.5V8H7.5C5.567 8 4 6.433 4 4.5C4 2.567 5.567 1 7.5 1H9.5V2ZM8 3H7.5C6.11929 3 5 4.11929 5 4.5C5 5.88071 6.11929 7 7.5 7H8V3ZM3.85355 13.8536C3.65829 14.0488 3.34171 14.0488 3.14645 13.8536L1.14645 11.8536C0.951184 11.6583 0.951184 11.3417 1.14645 11.1464C1.34171 10.9512 1.65829 10.9512 1.85355 11.1464L3 12.2929V9.5C3 9.22386 3.22386 9 3.5 9C3.77614 9 4 9.22386 4 9.5V12.2929L5.14645 11.1464C5.34171 10.9512 5.65829 10.9512 5.85355 11.1464C6.04882 11.3417 6.04882 11.6583 5.85355 11.8536L3.85355 13.8536Z' />,
30-
{ viewBox: '0 0 16 16' },
31-
);
32-
3312
import { ActionsMenu } from './ActionsMenu';
3413
import { GeneralTab } from './tabs/General';
14+
import { MessageActionsTab } from './tabs/MessageActions';
3515
import { NotificationsTab } from './tabs/Notifications';
3616
import { ReactionsTab } from './tabs/Reactions';
3717
import { SidebarTab } from './tabs/Sidebar';
3818
import { appSettingsStore, useAppSettingsState } from './state';
19+
import { IconGear, IconLightBulb, IconSidebar, IconTextDirection } from '../icons.tsx';
3920

40-
type TabId = 'general' | 'notifications' | 'reactions' | 'sidebar';
21+
type TabId = 'general' | 'messageActions' | 'notifications' | 'reactions' | 'sidebar';
4122

4223
const tabConfig: { Icon: ComponentType; id: TabId; title: string }[] = [
4324
{ Icon: IconGear, id: 'general', title: 'General' },
25+
{ Icon: IconMessageBubble, id: 'messageActions', title: 'Message Actions' },
4426
{ Icon: IconBell, id: 'notifications', title: 'Notifications' },
45-
{ Icon: IconMessageBubble, id: 'sidebar', title: 'Sidebar' },
27+
{ Icon: IconSidebar, id: 'sidebar', title: 'Sidebar' },
4628
{ Icon: IconEmoji, id: 'reactions', title: 'Reactions' },
4729
];
4830

@@ -151,6 +133,7 @@ export const AppSettings = ({ iconOnly = true }: { iconOnly?: boolean }) => {
151133
role='tabpanel'
152134
>
153135
{activeTab === 'general' && <GeneralTab />}
136+
{activeTab === 'messageActions' && <MessageActionsTab />}
154137
{activeTab === 'notifications' && <NotificationsTab />}
155138
{activeTab === 'sidebar' && <SidebarTab />}
156139
{activeTab === 'reactions' && <ReactionsTab />}

examples/vite/src/AppSettings/state.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ export type NotificationsSettingsState = {
2020
verticalAlignment: 'bottom' | 'top';
2121
};
2222

23+
export type MessageActionsSettingsState = {
24+
customMessageActions: {
25+
delete: {
26+
enableOptionConfiguration: boolean;
27+
};
28+
markOwnUnread: boolean;
29+
};
30+
};
31+
2332
export const LEFT_PANEL_MIN_WIDTH = 260;
2433
export const THREAD_PANEL_MIN_WIDTH = 260;
2534

@@ -40,6 +49,7 @@ export type PanelLayoutSettingsState = {
4049

4150
export type AppSettingsState = {
4251
chatView: ChatViewSettingsState;
52+
messageActions: MessageActionsSettingsState;
4353
notifications: NotificationsSettingsState;
4454
panelLayout: PanelLayoutSettingsState;
4555
reactions: ReactionsSettingsState;
@@ -66,6 +76,14 @@ const defaultAppSettingsState: AppSettingsState = {
6676
chatView: {
6777
iconOnly: true,
6878
},
79+
messageActions: {
80+
customMessageActions: {
81+
delete: {
82+
enableOptionConfiguration: false,
83+
},
84+
markOwnUnread: false,
85+
},
86+
},
6987
notifications: {
7088
verticalAlignment: 'bottom',
7189
},
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { SwitchField } from 'stream-chat-react';
2+
import { appSettingsStore, useAppSettingsState } from '../../state';
3+
4+
export const MessageActionsTab = () => {
5+
const {
6+
messageActions,
7+
messageActions: { customMessageActions },
8+
} = useAppSettingsState();
9+
10+
return (
11+
<div className='app__settings-modal__content-stack'>
12+
<div className='app__settings-modal__field'>
13+
<div className='app__settings-modal__field-label'>Delete message</div>
14+
<SwitchField
15+
checked={customMessageActions.delete.enableOptionConfiguration}
16+
id='delete-enable-option-configuration-switch'
17+
onChange={(event) =>
18+
appSettingsStore.partialNext({
19+
messageActions: {
20+
...messageActions,
21+
customMessageActions: {
22+
...customMessageActions,
23+
delete: {
24+
enableOptionConfiguration: event.target.checked,
25+
},
26+
},
27+
},
28+
})
29+
}
30+
>
31+
Enabled option configuration
32+
</SwitchField>
33+
<div className='app__settings-modal__field-comment'>
34+
It enables to configure delete request params in the Delete Message Alert like
35+
<strong>"Delete only for me"</strong>, <strong>"Hard delete"</strong>.
36+
</div>
37+
</div>
38+
39+
<div className='app__settings-modal__field'>
40+
<div className='app__settings-modal__field-label'>Mark as unread</div>
41+
<SwitchField
42+
checked={customMessageActions.markOwnUnread}
43+
id='mark-own-messages-unread-switch'
44+
onChange={(event) =>
45+
appSettingsStore.partialNext({
46+
messageActions: {
47+
...messageActions,
48+
customMessageActions: {
49+
...customMessageActions,
50+
markOwnUnread: event.target.checked,
51+
},
52+
},
53+
})
54+
}
55+
>
56+
Mark own messages as unread too
57+
</SwitchField>
58+
</div>
59+
</div>
60+
);
61+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './MessageActionsTab';

0 commit comments

Comments
 (0)