Skip to content

Commit e3bc7b8

Browse files
committed
feat: implement drafts sidebar group
1 parent 1f5425e commit e3bc7b8

File tree

3 files changed

+98
-1
lines changed

3 files changed

+98
-1
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { useSyncExternalStore, useCallback, useRef } from 'react';
2+
3+
const MESSAGEBOX_PREFIX = 'messagebox_';
4+
5+
const areSetsEqual = (a: Set<string>, b: Set<string>): boolean => {
6+
if (a.size !== b.size) return false;
7+
for (const item of a) {
8+
if (!b.has(item)) return false;
9+
}
10+
return true;
11+
};
12+
13+
const emptySet = new Set<string>();
14+
15+
export const useDraftRoomIds = (enabled = true): Set<string> => {
16+
const cacheRef = useRef<Set<string>>(new Set());
17+
18+
const getSnapshot = useCallback(() => {
19+
if (!enabled) {
20+
return emptySet;
21+
}
22+
23+
if (typeof window === 'undefined' || !window.localStorage) {
24+
return cacheRef.current;
25+
}
26+
27+
const draftRoomIds = new Set<string>();
28+
29+
try {
30+
const keys = Object.keys(localStorage);
31+
for (const key of keys) {
32+
if (!key.startsWith(MESSAGEBOX_PREFIX)) {
33+
continue;
34+
}
35+
36+
const content = localStorage.getItem(key);
37+
if (!content?.trim()) {
38+
continue;
39+
}
40+
41+
const roomId = key.substring(MESSAGEBOX_PREFIX.length);
42+
draftRoomIds.add(roomId);
43+
}
44+
} catch (error) {
45+
console.error('Error reading drafts from localStorage:', error);
46+
}
47+
48+
if (!areSetsEqual(cacheRef.current, draftRoomIds)) {
49+
cacheRef.current = draftRoomIds;
50+
}
51+
52+
return cacheRef.current;
53+
}, [enabled]);
54+
55+
const subscribe = useCallback((callback: () => void) => {
56+
if (!enabled) {
57+
return () => {};
58+
}
59+
60+
const handleStorageChange = (e: StorageEvent) => {
61+
if (e.key?.startsWith(MESSAGEBOX_PREFIX) || e.key === null) {
62+
callback();
63+
}
64+
};
65+
66+
window.addEventListener('storage', handleStorageChange);
67+
68+
const handleLocalUpdate = (e: Event) => {
69+
if (e instanceof CustomEvent && e.detail?.key?.startsWith(MESSAGEBOX_PREFIX)) {
70+
callback();
71+
}
72+
};
73+
window.addEventListener('localStorageUpdated', handleLocalUpdate);
74+
75+
return () => {
76+
window.removeEventListener('storage', handleStorageChange);
77+
window.removeEventListener('localStorageUpdated', handleLocalUpdate);
78+
};
79+
}, [enabled]);
80+
81+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
82+
};

apps/meteor/client/sidebar/hooks/useRoomList.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
33
import type { SubscriptionWithRoom, TranslationKey } from '@rocket.chat/ui-contexts';
44
import { useUserPreference, useUserSubscriptions, useSetting } from '@rocket.chat/ui-contexts';
55
import { useVideoConfIncomingCalls } from '@rocket.chat/ui-video-conf';
6+
import { useFeaturePreview } from '@rocket.chat/ui-client';
67
import { useMemo } from 'react';
78

9+
import { useDraftRoomIds } from './useDraftRoomIds';
810
import { useSortQueryOptions } from '../../hooks/useSortQueryOptions';
911
import { useOmnichannelEnabled } from '../../views/omnichannel/hooks/useOmnichannelEnabled';
1012
import { useQueuedInquiries } from '../../views/omnichannel/hooks/useQueuedInquiries';
@@ -19,6 +21,7 @@ const order = [
1921
'Open_Livechats',
2022
'On_Hold_Chats',
2123
'Unread',
24+
'Drafts',
2225
'Favorites',
2326
'Teams',
2427
'Discussions',
@@ -40,7 +43,8 @@ export const useRoomList = ({ collapsedGroups }: { collapsedGroups?: string[] })
4043
const showOmnichannel = useOmnichannelEnabled();
4144
const sidebarGroupByType = useUserPreference('sidebarGroupByType');
4245
const favoritesEnabled = useUserPreference('sidebarShowFavorites');
43-
const sidebarOrder = useUserPreference<typeof order>('sidebarSectionsOrder') ?? order;
46+
const sidebarDrafts = useFeaturePreview('sidebarDrafts');
47+
const sidebarOrder = useUserPreference<typeof order>('sidebarSectionsOrder') ?? order;
4448
const isDiscussionEnabled = useSetting('Discussion_enabled');
4549
const sidebarShowUnread = useUserPreference('sidebarShowUnread');
4650

@@ -52,12 +56,15 @@ export const useRoomList = ({ collapsedGroups }: { collapsedGroups?: string[] })
5256

5357
const incomingCalls = useVideoConfIncomingCalls();
5458

59+
const draftRoomIds = useDraftRoomIds(sidebarDrafts);
60+
5561
const queue = inquiries.enabled ? inquiries.queue : emptyQueue;
5662

5763
const { groupsCount, groupsList, roomList, groupedUnreadInfo } = useDebouncedValue(
5864
useMemo(() => {
5965
const isCollapsed = (groupTitle: string) => collapsedGroups?.includes(groupTitle);
6066

67+
const drafts = new Set();
6168
const incomingCall = new Set();
6269
const favorite = new Set();
6370
const team = new Set();
@@ -82,6 +89,10 @@ export const useRoomList = ({ collapsedGroups }: { collapsedGroups?: string[] })
8289
return unread.add(room);
8390
}
8491

92+
if (sidebarDrafts && draftRoomIds.has(room.rid)) {
93+
return drafts.add(room);
94+
}
95+
8596
if (favoritesEnabled && room.f) {
8697
return favorite.add(room);
8798
}
@@ -122,6 +133,8 @@ export const useRoomList = ({ collapsedGroups }: { collapsedGroups?: string[] })
122133

123134
sidebarShowUnread && unread.size && groups.set('Unread', unread);
124135

136+
sidebarDrafts && drafts.size && groups.set('Drafts', drafts);
137+
125138
favoritesEnabled && favorite.size && groups.set('Favorites', favorite);
126139

127140
sidebarGroupByType && team.size && groups.set('Teams', team);
@@ -193,6 +206,7 @@ export const useRoomList = ({ collapsedGroups }: { collapsedGroups?: string[] })
193206
rooms,
194207
showOmnichannel,
195208
inquiries.enabled,
209+
draftRoomIds,
196210
queue,
197211
sidebarShowUnread,
198212
favoritesEnabled,

apps/meteor/server/settings/accounts.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ export const createAccountSettings = () =>
749749
'Open_Livechats',
750750
'On_Hold_Chats',
751751
'Unread',
752+
'Drafts',
752753
'Favorites',
753754
'Teams',
754755
'Discussions',

0 commit comments

Comments
 (0)