@messenger-box/tailwind-ui-inbox 10.0.3-alpha.71 → 10.0.3-alpha.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/lib/components/AIAgent/AIAgent.d.ts +14 -0
- package/lib/components/AIAgent/AIAgent.d.ts.map +1 -0
- package/lib/components/AIAgent/AIAgent.js +1148 -0
- package/lib/components/AIAgent/AIAgent.js.map +1 -0
- package/lib/components/AIAgent/index.d.ts +2 -0
- package/lib/components/AIAgent/index.d.ts.map +1 -0
- package/lib/components/InboxMessage/InputComponent.d.ts +9 -0
- package/lib/components/InboxMessage/InputComponent.d.ts.map +1 -0
- package/lib/components/InboxMessage/InputComponent.js +210 -0
- package/lib/components/InboxMessage/InputComponent.js.map +1 -0
- package/lib/components/InboxMessage/MessageInput.d.ts.map +1 -1
- package/lib/components/InboxMessage/MessageInput.js +14 -10
- package/lib/components/InboxMessage/MessageInput.js.map +1 -1
- package/lib/components/InboxMessage/MessageInputComponent.d.ts +9 -0
- package/lib/components/InboxMessage/MessageInputComponent.d.ts.map +1 -0
- package/lib/components/InboxMessage/MessageInputComponent.js +173 -0
- package/lib/components/InboxMessage/MessageInputComponent.js.map +1 -0
- package/lib/components/InboxMessage/Messages.d.ts.map +1 -1
- package/lib/components/InboxMessage/Messages.js +4 -54
- package/lib/components/InboxMessage/Messages.js.map +1 -1
- package/lib/components/InboxMessage/MessagesBuilderUi.d.ts +17 -0
- package/lib/components/InboxMessage/MessagesBuilderUi.d.ts.map +1 -0
- package/lib/components/InboxMessage/MessagesBuilderUi.js +162 -0
- package/lib/components/InboxMessage/MessagesBuilderUi.js.map +1 -0
- package/lib/components/InboxMessage/UploadImageButton.d.ts +1 -0
- package/lib/components/InboxMessage/UploadImageButton.d.ts.map +1 -1
- package/lib/components/InboxMessage/UploadImageButton.js +3 -3
- package/lib/components/InboxMessage/UploadImageButton.js.map +1 -1
- package/lib/components/InboxMessage/index.d.ts +3 -0
- package/lib/components/InboxMessage/index.d.ts.map +1 -1
- package/lib/components/InboxMessage/message-widgets/CommonMessage.d.ts.map +1 -1
- package/lib/components/InboxMessage/message-widgets/CommonMessage.js +11 -6
- package/lib/components/InboxMessage/message-widgets/CommonMessage.js.map +1 -1
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts +14 -0
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.js +1525 -0
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.js.map +1 -0
- package/lib/components/InboxMessage/message-widgets/PlainMessage.d.ts.map +1 -1
- package/lib/components/InboxMessage/message-widgets/PlainMessage.js +6 -3
- package/lib/components/InboxMessage/message-widgets/PlainMessage.js.map +1 -1
- package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.d.ts.map +1 -1
- package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.js +207 -12
- package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.js.map +1 -1
- package/lib/components/InboxMessage/message-widgets/index.d.ts +1 -0
- package/lib/components/InboxMessage/message-widgets/index.d.ts.map +1 -1
- package/lib/components/index.d.ts +2 -1
- package/lib/components/index.d.ts.map +1 -1
- package/lib/compute.d.ts.map +1 -1
- package/lib/compute.js +79 -3
- package/lib/compute.js.map +1 -1
- package/lib/config/env-config.d.ts +6 -0
- package/lib/config/env-config.d.ts.map +1 -1
- package/lib/config/env-config.js +19 -1
- package/lib/config/env-config.js.map +1 -1
- package/lib/container/AiInbox.d.ts +15 -0
- package/lib/container/AiInbox.d.ts.map +1 -0
- package/lib/container/AiInbox.js +1520 -0
- package/lib/container/AiInbox.js.map +1 -0
- package/lib/container/AiInboxWithLoader.d.ts +36 -0
- package/lib/container/AiInboxWithLoader.d.ts.map +1 -0
- package/lib/container/AiInboxWithLoader.js +300 -0
- package/lib/container/AiInboxWithLoader.js.map +1 -0
- package/lib/container/AiLandingInput.d.ts +4 -0
- package/lib/container/AiLandingInput.d.ts.map +1 -0
- package/lib/container/AiLandingInput.js +164 -0
- package/lib/container/AiLandingInput.js.map +1 -0
- package/lib/container/Inbox.d.ts.map +1 -1
- package/lib/container/Inbox.js +6 -4
- package/lib/container/Inbox.js.map +1 -1
- package/lib/container/InboxAiMessagesLoader.d.ts +36 -0
- package/lib/container/InboxAiMessagesLoader.d.ts.map +1 -0
- package/lib/container/InboxAiMessagesLoader.js +47 -0
- package/lib/container/InboxAiMessagesLoader.js.map +1 -0
- package/lib/container/InboxContainer.d.ts +12 -0
- package/lib/container/InboxContainer.d.ts.map +1 -0
- package/lib/container/InboxContainer.js +31 -0
- package/lib/container/InboxContainer.js.map +1 -0
- package/lib/container/InboxTemplate1.d.ts +15 -0
- package/lib/container/InboxTemplate1.d.ts.map +1 -0
- package/lib/container/InboxTemplate1.js +1375 -0
- package/lib/container/InboxTemplate1.js.map +1 -0
- package/lib/container/InboxTemplate1WithLoader.d.ts +36 -0
- package/lib/container/InboxTemplate1WithLoader.d.ts.map +1 -0
- package/lib/container/InboxTemplate2.d.ts +15 -0
- package/lib/container/InboxTemplate2.d.ts.map +1 -0
- package/lib/container/InboxTemplate2.js +1426 -0
- package/lib/container/InboxTemplate2.js.map +1 -0
- package/lib/container/InboxWithAiLoader.d.ts +15 -0
- package/lib/container/InboxWithAiLoader.d.ts.map +1 -0
- package/lib/container/InboxWithAiLoader.js +56 -0
- package/lib/container/InboxWithAiLoader.js.map +1 -0
- package/lib/container/ServiceInbox.js +1 -1
- package/lib/container/ServiceInbox.js.map +1 -1
- package/lib/container/ThreadMessages.js +1 -1
- package/lib/container/ThreadMessages.js.map +1 -1
- package/lib/container/ThreadMessagesInbox.js +1 -1
- package/lib/container/ThreadMessagesInbox.js.map +1 -1
- package/lib/container/Threads.js +1 -1
- package/lib/container/Threads.js.map +1 -1
- package/lib/container/index.d.ts +4 -1
- package/lib/container/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/machines/aiAgentMachine.d.ts +3 -0
- package/lib/machines/aiAgentMachine.d.ts.map +1 -0
- package/lib/machines/aiAgentMachine.js +1040 -0
- package/lib/machines/aiAgentMachine.js.map +1 -0
- package/lib/machines/types.d.ts +77 -0
- package/lib/machines/types.d.ts.map +1 -0
- package/lib/routes.json +40 -0
- package/lib/templates/InboxWithAi.d.ts +15 -0
- package/lib/templates/InboxWithAi.d.ts.map +1 -0
- package/lib/templates/InboxWithAi.js +405 -0
- package/lib/templates/InboxWithAi.js.map +1 -0
- package/lib/templates/InboxWithAi.tsx +502 -0
- package/package.json +7 -5
- package/src/components/AIAgent/AIAgent.tsx +1351 -0
- package/src/components/AIAgent/README.md +82 -0
- package/src/components/AIAgent/index.ts +1 -0
- package/src/components/InboxMessage/InputComponent.tsx +263 -0
- package/src/components/InboxMessage/MessageInput.tsx +73 -66
- package/src/components/InboxMessage/MessageInputComponent.tsx +245 -0
- package/src/components/InboxMessage/Messages.tsx +2 -56
- package/src/components/InboxMessage/MessagesBuilderUi.tsx +205 -0
- package/src/components/InboxMessage/UploadImageButton.tsx +3 -2
- package/src/components/InboxMessage/index.ts +3 -0
- package/src/components/InboxMessage/message-widgets/CommonMessage.tsx +39 -21
- package/src/components/InboxMessage/message-widgets/ModernMessageGroup.tsx +1968 -0
- package/src/components/InboxMessage/message-widgets/PlainMessage.tsx +6 -2
- package/src/components/InboxMessage/message-widgets/SlackLikeMessageGroup.tsx +306 -54
- package/src/components/InboxMessage/message-widgets/index.ts +1 -0
- package/src/components/index.ts +4 -0
- package/src/compute.ts +83 -2
- package/src/config/env-config.ts +6 -0
- package/src/container/AiInbox.tsx +1796 -0
- package/src/container/AiInboxWithLoader.tsx +356 -0
- package/src/container/AiLandingInput.tsx +168 -0
- package/src/container/Inbox.tsx +8 -5
- package/src/container/InboxAiMessagesLoader.tsx +68 -0
- package/src/container/InboxContainer.tsx +35 -0
- package/src/container/InboxTemplate1.tsx +1542 -0
- package/src/container/InboxTemplate1WithLoader.tsx +338 -0
- package/src/container/InboxTemplate2.tsx +1606 -0
- package/src/container/InboxWithAiLoader.tsx +76 -0
- package/src/container/index.ts +15 -1
- package/src/machines/aiAgentMachine.ts +1248 -0
- package/src/machines/types.ts +59 -0
- package/src/templates/InboxWithAi.tsx +502 -0
|
@@ -0,0 +1,1520 @@
|
|
|
1
|
+
import React__default,{useCallback,useMemo,useRef,useEffect,useReducer}from'react';import {orderBy,uniqBy}from'lodash-es';import {useSendMessagesMutation,MessagesDocument,OnChatMessageAddedDocument}from'common/graphql';import {useUploadFiles}from'@messenger-box/platform-client';import {RoomType}from'common';import {useSelector,shallowEqual}from'react-redux';import {useParams,useNavigate}from'@remix-run/react';import'../components/inbox/FilesList.js';import'../components/inbox/MessageItem.js';import'../components/inbox/ThreadItem.js';import'date-fns';import'@react-icons/all-files/bs/BsFlag.js';import'../components/InboxMessage/ConversationItem.js';import'../components/InboxMessage/ServiceConversationItem.js';import {LeftSidebar}from'../components/InboxMessage/LeftSidebar.js';import'react-i18next';import {config}from'../config/env-config.js';import'@react-icons/all-files/bi/BiImage.js';import {Messages}from'../components/InboxMessage/Messages.js';import'@react-icons/all-files/ai/AiOutlineSecurityScan.js';import'@react-icons/all-files/fi/FiCheck.js';import'@react-icons/all-files/bs/BsFillStarFill.js';import'@common-stack/components-pro';import'../enums/messenger-slot-fill-name-enum.js';import'../components/InboxMessage/ServiceInboxItem.js';import {MessageInputComponent}from'../components/InboxMessage/MessageInputComponent.js';import {objectId}from'@messenger-box/core';import'../components/AIAgent/AIAgent.js';import {userSelector}from'@adminide-stack/user-auth0-client';import {applyFooterStyles}from'./apply-footer-styles.js';import {ThreadsInbox}from'./ThreadsInbox.js';import {ThreadMessagesInbox}from'./ThreadMessagesInbox.js';import {useApolloClient}from'@apollo/client/index.js';import {SubscriptionHandler}from'../components/InboxMessage/SubscriptionHandler.js';const {
|
|
2
|
+
MESSAGES_PER_PAGE
|
|
3
|
+
} = config;
|
|
4
|
+
// Static utility hooks and components
|
|
5
|
+
const useMediaQuery = query => {
|
|
6
|
+
const [matches, setMatches] = React__default.useState(false);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (typeof window === 'undefined') return;
|
|
9
|
+
const mediaQuery = window.matchMedia(query);
|
|
10
|
+
const updateMatches = () => setMatches(mediaQuery.matches);
|
|
11
|
+
updateMatches();
|
|
12
|
+
mediaQuery.addEventListener('change', updateMatches);
|
|
13
|
+
return () => mediaQuery.removeEventListener('change', updateMatches);
|
|
14
|
+
}, [query]);
|
|
15
|
+
return matches;
|
|
16
|
+
};
|
|
17
|
+
// Hook to get window dimensions
|
|
18
|
+
const useWindowDimensions = () => {
|
|
19
|
+
const [windowDimensions, setWindowDimensions] = React__default.useState({
|
|
20
|
+
width: typeof window !== 'undefined' ? window.innerWidth : 1024,
|
|
21
|
+
height: typeof window !== 'undefined' ? window.innerHeight : 768
|
|
22
|
+
});
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (typeof window === 'undefined') return;
|
|
25
|
+
const handleResize = () => {
|
|
26
|
+
setWindowDimensions({
|
|
27
|
+
width: window.innerWidth,
|
|
28
|
+
height: window.innerHeight
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
window.addEventListener('resize', handleResize);
|
|
32
|
+
handleResize(); // Set initial dimensions
|
|
33
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
34
|
+
}, []);
|
|
35
|
+
return windowDimensions;
|
|
36
|
+
};
|
|
37
|
+
// Static components
|
|
38
|
+
const Spinner = React__default.memo(({
|
|
39
|
+
className = ''
|
|
40
|
+
}) => React__default.createElement("div", {
|
|
41
|
+
className: `animate-spin rounded-full border-4 border-gray-200 border-t-blue-500 ${className}`
|
|
42
|
+
}, React__default.createElement("span", {
|
|
43
|
+
className: "sr-only"
|
|
44
|
+
}, "Loading...")));
|
|
45
|
+
const Drawer = React__default.memo(({
|
|
46
|
+
isOpen,
|
|
47
|
+
onClose,
|
|
48
|
+
children,
|
|
49
|
+
title
|
|
50
|
+
}) => {
|
|
51
|
+
if (!isOpen) return null;
|
|
52
|
+
return React__default.createElement("div", {
|
|
53
|
+
className: "fixed inset-0 z-50 overflow-hidden"
|
|
54
|
+
}, React__default.createElement("div", {
|
|
55
|
+
className: "absolute inset-0 bg-black bg-opacity-50",
|
|
56
|
+
onClick: onClose
|
|
57
|
+
}), React__default.createElement("div", {
|
|
58
|
+
className: "absolute bottom-0 left-0 right-0 bg-white rounded-t-lg shadow-lg max-h-[80vh] flex flex-col overflow-hidden"
|
|
59
|
+
}, React__default.createElement("div", {
|
|
60
|
+
className: "flex items-center justify-between p-4 border-b border-gray-200 flex-shrink-0"
|
|
61
|
+
}, React__default.createElement("h2", {
|
|
62
|
+
className: "text-lg font-semibold truncate"
|
|
63
|
+
}, title), React__default.createElement("button", {
|
|
64
|
+
onClick: onClose,
|
|
65
|
+
className: "p-1 hover:bg-gray-100 rounded-full transition-colors flex-shrink-0 ml-2"
|
|
66
|
+
}, React__default.createElement("svg", {
|
|
67
|
+
className: "w-6 h-6",
|
|
68
|
+
fill: "none",
|
|
69
|
+
stroke: "currentColor",
|
|
70
|
+
viewBox: "0 0 24 24"
|
|
71
|
+
}, React__default.createElement("path", {
|
|
72
|
+
strokeLinecap: "round",
|
|
73
|
+
strokeLinejoin: "round",
|
|
74
|
+
strokeWidth: 2,
|
|
75
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
76
|
+
})))), React__default.createElement("div", {
|
|
77
|
+
className: "flex-1 p-4 overflow-y-auto",
|
|
78
|
+
style: {
|
|
79
|
+
minHeight: 0
|
|
80
|
+
}
|
|
81
|
+
}, children)));
|
|
82
|
+
});
|
|
83
|
+
const EmptyState = React__default.memo(() => React__default.createElement("div", {
|
|
84
|
+
className: "h-full flex items-center justify-center bg-gray-100 p-4 sm:p-6 overflow-hidden"
|
|
85
|
+
}, React__default.createElement("div", {
|
|
86
|
+
className: "text-center max-w-sm mx-auto"
|
|
87
|
+
}, React__default.createElement("div", {
|
|
88
|
+
className: "text-3xl sm:text-4xl text-gray-400 mb-4"
|
|
89
|
+
}, "\uD83D\uDCAC"), React__default.createElement("h3", {
|
|
90
|
+
className: "text-lg sm:text-xl font-semibold text-gray-600 mb-2"
|
|
91
|
+
}, "Welcome to Messenger"), React__default.createElement("p", {
|
|
92
|
+
className: "text-sm sm:text-base text-gray-500 leading-relaxed"
|
|
93
|
+
}, "Select a conversation from the sidebar to start messaging"))));
|
|
94
|
+
// Mobile preview reducer
|
|
95
|
+
const mobilePreviewReducer = (state, action) => {
|
|
96
|
+
if (action.type === 'update') {
|
|
97
|
+
return {
|
|
98
|
+
...state,
|
|
99
|
+
...action.payload
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return state;
|
|
103
|
+
};
|
|
104
|
+
const Inbox = props => {
|
|
105
|
+
const {
|
|
106
|
+
channelFilters: channelFilterProp,
|
|
107
|
+
channelRole,
|
|
108
|
+
supportServices,
|
|
109
|
+
data,
|
|
110
|
+
orgName,
|
|
111
|
+
pathPrefix = null
|
|
112
|
+
} = props;
|
|
113
|
+
const {
|
|
114
|
+
id: pathChannelId,
|
|
115
|
+
postId: pathPostId
|
|
116
|
+
} = useParams();
|
|
117
|
+
const navigate = useNavigate();
|
|
118
|
+
const apolloClient = useApolloClient();
|
|
119
|
+
// Reduced state - only UI state remains, data comes from Apollo cache
|
|
120
|
+
const [isBottomDrawerOpen, setBottomDrawer] = React__default.useState(false);
|
|
121
|
+
const [mobilePreviewState, localDispatch] = useReducer(mobilePreviewReducer, {
|
|
122
|
+
mobilePreviewVisibility: false,
|
|
123
|
+
mobilePreviewText: false,
|
|
124
|
+
mobilePreviewCTAText: false
|
|
125
|
+
});
|
|
126
|
+
// Hooks - improved responsive breakpoints with better granularity
|
|
127
|
+
const {
|
|
128
|
+
width: windowWidth,
|
|
129
|
+
height: windowHeight
|
|
130
|
+
} = useWindowDimensions();
|
|
131
|
+
const isMobileView = useMediaQuery('(max-width: 640px)');
|
|
132
|
+
const isSmallTabletView = useMediaQuery('(min-width: 641px) and (max-width: 900px)');
|
|
133
|
+
const isTabletView = useMediaQuery('(min-width: 901px) and (max-width: 1024px)');
|
|
134
|
+
const isDesktopView = useMediaQuery('(min-width: 1025px)');
|
|
135
|
+
const isLargeDesktopView = useMediaQuery('(min-width: 1440px)');
|
|
136
|
+
const isSmallScreen = useMediaQuery('(max-width: 900px)');
|
|
137
|
+
// const auth = useSelector(userSelector);
|
|
138
|
+
const auth = useSelector(userSelector, shallowEqual);
|
|
139
|
+
// const user = useSelector((state: any) => state.user, shallowEqual);
|
|
140
|
+
// Data destructuring from Apollo queries
|
|
141
|
+
const GetChannelsByUserQuery = data?.[0];
|
|
142
|
+
const {
|
|
143
|
+
data: userChannels,
|
|
144
|
+
loading: userChannelsLoading,
|
|
145
|
+
refetch: getChannelsRefetch
|
|
146
|
+
} = GetChannelsByUserQuery || {};
|
|
147
|
+
// Get data directly from Apollo cache instead of local state
|
|
148
|
+
const channels = useMemo(() => {
|
|
149
|
+
if (!userChannels?.channelsByUser && !userChannels?.supportServiceChannels) return [];
|
|
150
|
+
return uniqBy([...(userChannels?.supportServiceChannels ?? []), ...(userChannels?.channelsByUser ?? [])], 'id');
|
|
151
|
+
}, [userChannels]);
|
|
152
|
+
// Memoize stable channel array to prevent unnecessary re-renders
|
|
153
|
+
const stableChannels = useMemo(() => {
|
|
154
|
+
return channels || [];
|
|
155
|
+
}, [channels]);
|
|
156
|
+
// Memoized values derived from Apollo cache data
|
|
157
|
+
const channelFilters = useMemo(() => {
|
|
158
|
+
const filters = {
|
|
159
|
+
...channelFilterProp
|
|
160
|
+
};
|
|
161
|
+
const channelType = filters?.type ?? RoomType.Direct;
|
|
162
|
+
filters.type = supportServices ? [channelType, RoomType.Service] : channelType;
|
|
163
|
+
return filters;
|
|
164
|
+
}, [channelFilterProp, supportServices]);
|
|
165
|
+
const users = useMemo(() => {
|
|
166
|
+
return channels?.reduce((acc, curr) => {
|
|
167
|
+
const newMembers = curr.members?.filter(({
|
|
168
|
+
user
|
|
169
|
+
}) => !acc.find(({
|
|
170
|
+
id
|
|
171
|
+
}) => id === user.id)) || [];
|
|
172
|
+
return [...acc, ...newMembers.map(({
|
|
173
|
+
user
|
|
174
|
+
}) => user)];
|
|
175
|
+
}, []) || [];
|
|
176
|
+
}, [channels]);
|
|
177
|
+
// const currentUser = useMemo(
|
|
178
|
+
// () => users?.find((user) => user && user.alias?.includes(auth?.authUserId)),
|
|
179
|
+
// [users, auth?.authUserId],
|
|
180
|
+
// );
|
|
181
|
+
const currentUser = auth;
|
|
182
|
+
const channelName = useMemo(() => {
|
|
183
|
+
if (!channels || !pathChannelId) return '';
|
|
184
|
+
const currChannel = channels?.find(ch => ch.id === pathChannelId);
|
|
185
|
+
if (!currChannel) return '';
|
|
186
|
+
const {
|
|
187
|
+
members,
|
|
188
|
+
title,
|
|
189
|
+
type
|
|
190
|
+
} = currChannel;
|
|
191
|
+
if (type === RoomType.Direct && members?.length >= 2) {
|
|
192
|
+
const otherUser = members.find(member => member.user.id !== currentUser?.id);
|
|
193
|
+
if (otherUser?.user) {
|
|
194
|
+
const {
|
|
195
|
+
givenName,
|
|
196
|
+
familyName
|
|
197
|
+
} = otherUser.user;
|
|
198
|
+
if (givenName && familyName) return `${givenName} ${familyName}`;
|
|
199
|
+
return givenName || familyName || title || 'Direct Message';
|
|
200
|
+
}
|
|
201
|
+
return title || 'Direct Message';
|
|
202
|
+
}
|
|
203
|
+
if (type === RoomType.Direct && members?.length === 1) {
|
|
204
|
+
if (members[0].user?.givenName && members[0]?.user?.familyName) {
|
|
205
|
+
return `${members[0].user?.givenName} ${members[0].user?.familyName}`;
|
|
206
|
+
}
|
|
207
|
+
return members[0].user?.givenName || members[0].user?.familyName || 'Direct Message';
|
|
208
|
+
}
|
|
209
|
+
return title || 'Channel';
|
|
210
|
+
}, [channels, pathChannelId, currentUser]);
|
|
211
|
+
// Effects
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
applyFooterStyles();
|
|
214
|
+
// Optimistic refetch with cache update
|
|
215
|
+
const timeout = setTimeout(() => {
|
|
216
|
+
getChannelsRefetch?.({
|
|
217
|
+
role: channelRole,
|
|
218
|
+
criteria: orgName ? {
|
|
219
|
+
...channelFilters,
|
|
220
|
+
orgName: channelFilters?.orgName || orgName || ''
|
|
221
|
+
} : channelFilters,
|
|
222
|
+
supportServices: !!supportServices,
|
|
223
|
+
supportServiceCriteria: {
|
|
224
|
+
type: RoomType.Service
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}, 0);
|
|
228
|
+
return () => clearTimeout(timeout);
|
|
229
|
+
}, [channelRole, channelFilters, supportServices, getChannelsRefetch]);
|
|
230
|
+
// Optimistic navigation with cache updates
|
|
231
|
+
const handleSelectChannel = useCallback(async (channelId, pId = null) => {
|
|
232
|
+
// Optimistic UI update
|
|
233
|
+
const mainPath = orgName ? pId ? `/o/${orgName}/ai-messenger/${channelId}/${pId}` : `/o/${orgName}/ai-messenger/${channelId}` : pId ? `/inbox/${channelId}/${pId}` : `/inbox/${channelId}`;
|
|
234
|
+
const basePath = pathPrefix ? `${pathPrefix}${mainPath}` : mainPath;
|
|
235
|
+
const searchParams = new URLSearchParams();
|
|
236
|
+
// if (channelRole) searchParams.set('channelRole', channelRole);
|
|
237
|
+
// if (orgName) searchParams.set('orgName', orgName);
|
|
238
|
+
const newPath = searchParams.toString() ? `${basePath}?${searchParams.toString()}` : basePath;
|
|
239
|
+
navigate(newPath, {
|
|
240
|
+
replace: true
|
|
241
|
+
});
|
|
242
|
+
// Optimistically update Apollo cache for immediate UI feedback
|
|
243
|
+
try {
|
|
244
|
+
apolloClient.writeQuery({
|
|
245
|
+
query: MessagesDocument,
|
|
246
|
+
variables: {
|
|
247
|
+
channelId: channelId.toString(),
|
|
248
|
+
parentId: null,
|
|
249
|
+
limit: MESSAGES_PER_PAGE
|
|
250
|
+
},
|
|
251
|
+
data: {
|
|
252
|
+
messages: {
|
|
253
|
+
__typename: 'Messages',
|
|
254
|
+
data: [],
|
|
255
|
+
totalCount: 0,
|
|
256
|
+
messagesRefId: channelId
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
} catch (error) {
|
|
261
|
+
// Cache write might fail if query hasn't been executed yet, that's OK
|
|
262
|
+
console.debug('Cache write failed (expected on first load):', error);
|
|
263
|
+
}
|
|
264
|
+
}, [navigate, apolloClient, orgName, channelRole, pathPrefix]);
|
|
265
|
+
const detailSidebarOptions = useMemo(() => ({
|
|
266
|
+
isMobileView,
|
|
267
|
+
isSmallTabletView,
|
|
268
|
+
isTabletView,
|
|
269
|
+
isDesktopView,
|
|
270
|
+
isLargeDesktopView,
|
|
271
|
+
isSmallScreen,
|
|
272
|
+
setMobilePreviewCTAText: v => localDispatch({
|
|
273
|
+
payload: {
|
|
274
|
+
mobilePreviewCTAText: v
|
|
275
|
+
},
|
|
276
|
+
type: 'update'
|
|
277
|
+
}),
|
|
278
|
+
setMobilePreviewText: v => localDispatch({
|
|
279
|
+
payload: {
|
|
280
|
+
mobilePreviewText: v
|
|
281
|
+
},
|
|
282
|
+
type: 'update'
|
|
283
|
+
}),
|
|
284
|
+
setMobilePreviewVisibility: v => localDispatch({
|
|
285
|
+
payload: {
|
|
286
|
+
mobilePreviewVisibility: v
|
|
287
|
+
},
|
|
288
|
+
type: 'update'
|
|
289
|
+
})
|
|
290
|
+
}), [isMobileView, isSmallTabletView, isTabletView, isDesktopView, isLargeDesktopView, isSmallScreen]);
|
|
291
|
+
return React__default.createElement("div", {
|
|
292
|
+
className: "border-t border-gray-300 flex overflow-hidden",
|
|
293
|
+
style: {
|
|
294
|
+
height: `${windowHeight}px`,
|
|
295
|
+
maxHeight: '100vh'
|
|
296
|
+
}
|
|
297
|
+
}, React__default.createElement("div", {
|
|
298
|
+
className: `
|
|
299
|
+
flex-shrink-0 bg-gray-50 border-r border-gray-300 overflow-hidden transition-all duration-300 ease-in-out
|
|
300
|
+
${isMobileView && pathChannelId ? 'hidden' : ''}
|
|
301
|
+
`,
|
|
302
|
+
style: {
|
|
303
|
+
width: isMobileView && !pathChannelId ? '100%' : isMobileView && pathChannelId ? '0px' : isSmallTabletView ? `${Math.min(288, windowWidth * 0.35)}px` // w-72 or 35% of window
|
|
304
|
+
: isTabletView ? `${Math.min(320, windowWidth * 0.3)}px` // w-80 or 30% of window
|
|
305
|
+
: isLargeDesktopView ? `${Math.min(384, windowWidth * 0.25)}px` // w-96 or 25% of window
|
|
306
|
+
: `${Math.min(320, windowWidth * 0.28)}px`,
|
|
307
|
+
// w-80 or 28% of window
|
|
308
|
+
height: `${windowHeight}px`,
|
|
309
|
+
maxHeight: '100vh'
|
|
310
|
+
}
|
|
311
|
+
}, React__default.createElement(LeftSidebar, {
|
|
312
|
+
currentUser: currentUser,
|
|
313
|
+
userChannels: stableChannels,
|
|
314
|
+
userChannelsLoading: userChannelsLoading,
|
|
315
|
+
users: users,
|
|
316
|
+
handleSelectChannel: handleSelectChannel,
|
|
317
|
+
selectedChannelId: pathChannelId,
|
|
318
|
+
channelToTop: 0,
|
|
319
|
+
getChannelsRefetch: getChannelsRefetch,
|
|
320
|
+
role: channelRole,
|
|
321
|
+
messagesQuery: data?.[1],
|
|
322
|
+
windowHeight: windowHeight,
|
|
323
|
+
windowWidth: windowWidth
|
|
324
|
+
})), React__default.createElement("div", {
|
|
325
|
+
className: `
|
|
326
|
+
flex-1 min-w-0 flex flex-col overflow-hidden transition-all duration-300 ease-in-out
|
|
327
|
+
${isMobileView && !pathChannelId ? 'hidden' : 'flex'}
|
|
328
|
+
`,
|
|
329
|
+
style: {
|
|
330
|
+
minWidth: isSmallScreen ? '300px' : isDesktopView ? '500px' : '400px',
|
|
331
|
+
width: 'auto',
|
|
332
|
+
height: `${windowHeight}px`,
|
|
333
|
+
maxHeight: '100vh'
|
|
334
|
+
}
|
|
335
|
+
}, pathChannelId ? React__default.createElement(ContentComponent, {
|
|
336
|
+
channelId: pathChannelId,
|
|
337
|
+
postId: pathPostId,
|
|
338
|
+
channelRole: channelRole,
|
|
339
|
+
pathPrefix: props.pathPrefix,
|
|
340
|
+
isMobileView: isMobileView,
|
|
341
|
+
isSmallTabletView: isSmallTabletView,
|
|
342
|
+
isTabletView: isTabletView,
|
|
343
|
+
isDesktopView: isDesktopView,
|
|
344
|
+
isLargeDesktopView: isLargeDesktopView,
|
|
345
|
+
isSmallScreen: isSmallScreen,
|
|
346
|
+
windowWidth: windowWidth,
|
|
347
|
+
windowHeight: windowHeight,
|
|
348
|
+
mobilePreviewState: mobilePreviewState,
|
|
349
|
+
detailSidebarOptions: detailSidebarOptions,
|
|
350
|
+
isBottomDrawerOpen: isBottomDrawerOpen,
|
|
351
|
+
setBottomDrawer: setBottomDrawer,
|
|
352
|
+
channelName: channelName,
|
|
353
|
+
loaderdata: data
|
|
354
|
+
}) : React__default.createElement(EmptyState, null)), pathChannelId && data?.[1] && isDesktopView && React__default.createElement("div", {
|
|
355
|
+
className: "border-l border-gray-200 bg-white flex-shrink-0 overflow-hidden",
|
|
356
|
+
style: {
|
|
357
|
+
width: `${windowWidth * 0.35}px`,
|
|
358
|
+
// 40% of window width
|
|
359
|
+
height: `${windowHeight}px`,
|
|
360
|
+
maxHeight: '100vh'
|
|
361
|
+
}
|
|
362
|
+
}, React__default.createElement(RightSidebarWrapper, {
|
|
363
|
+
MessagesLoaderQuery: data?.[1],
|
|
364
|
+
selectedPost: null,
|
|
365
|
+
detailSidebarOptions: detailSidebarOptions
|
|
366
|
+
})));
|
|
367
|
+
};
|
|
368
|
+
const ContentComponent = React__default.memo(props => {
|
|
369
|
+
const {
|
|
370
|
+
channelId,
|
|
371
|
+
channelRole,
|
|
372
|
+
pathPrefix,
|
|
373
|
+
postId,
|
|
374
|
+
isMobileView,
|
|
375
|
+
isSmallTabletView,
|
|
376
|
+
isTabletView,
|
|
377
|
+
isDesktopView,
|
|
378
|
+
isLargeDesktopView,
|
|
379
|
+
isSmallScreen,
|
|
380
|
+
windowWidth,
|
|
381
|
+
windowHeight,
|
|
382
|
+
mobilePreviewState,
|
|
383
|
+
detailSidebarOptions,
|
|
384
|
+
isBottomDrawerOpen,
|
|
385
|
+
setBottomDrawer,
|
|
386
|
+
channelName,
|
|
387
|
+
loaderdata
|
|
388
|
+
} = props;
|
|
389
|
+
const ViewChannelDetailLoaderQuery = loaderdata?.[2];
|
|
390
|
+
const MessagesLoaderQuery = loaderdata?.[1];
|
|
391
|
+
const [selectedPost, setSelectedPost] = React__default.useState(null);
|
|
392
|
+
const {
|
|
393
|
+
data: channelData,
|
|
394
|
+
loading: channelLoading
|
|
395
|
+
} = ViewChannelDetailLoaderQuery || {};
|
|
396
|
+
const onMessageClick = useCallback(msg => {
|
|
397
|
+
setSelectedPost(msg);
|
|
398
|
+
}, []);
|
|
399
|
+
const channelsDetail = useMemo(() => {
|
|
400
|
+
return channelData?.viewChannelDetail || null;
|
|
401
|
+
}, [channelData]);
|
|
402
|
+
return React__default.createElement("div", {
|
|
403
|
+
className: "flex overflow-hidden",
|
|
404
|
+
style: {
|
|
405
|
+
height: `${windowHeight}px`,
|
|
406
|
+
maxHeight: '100vh'
|
|
407
|
+
}
|
|
408
|
+
}, React__default.createElement("div", {
|
|
409
|
+
className: "flex-1 flex flex-col min-w-0 overflow-hidden"
|
|
410
|
+
}, channelId && React__default.createElement("div", {
|
|
411
|
+
className: `border-b border-gray-200 bg-white flex-shrink-0 z-10 ${isSmallScreen ? 'px-3 py-3' : 'px-4 sm:px-6 py-4'}`
|
|
412
|
+
}, React__default.createElement("div", {
|
|
413
|
+
className: "flex items-center justify-between"
|
|
414
|
+
}, React__default.createElement("div", {
|
|
415
|
+
className: "flex items-center space-x-2 min-w-0 flex-1"
|
|
416
|
+
}, (isMobileView || isSmallTabletView) && React__default.createElement("button", {
|
|
417
|
+
className: "p-2 hover:bg-gray-100 rounded-full transition-colors flex-shrink-0",
|
|
418
|
+
onClick: () => window.history.back(),
|
|
419
|
+
"aria-label": "Go back"
|
|
420
|
+
}, React__default.createElement("svg", {
|
|
421
|
+
className: "w-5 h-5 text-gray-600",
|
|
422
|
+
fill: "none",
|
|
423
|
+
stroke: "currentColor",
|
|
424
|
+
viewBox: "0 0 24 24"
|
|
425
|
+
}, React__default.createElement("path", {
|
|
426
|
+
strokeLinecap: "round",
|
|
427
|
+
strokeLinejoin: "round",
|
|
428
|
+
strokeWidth: 2,
|
|
429
|
+
d: "M15 19l-7-7 7-7"
|
|
430
|
+
}))), React__default.createElement("h2", {
|
|
431
|
+
className: `font-semibold text-gray-800 truncate ${isSmallScreen ? 'text-base' : 'text-lg'}`
|
|
432
|
+
}, channelName)), (isMobileView || isSmallTabletView) && mobilePreviewState?.mobilePreviewVisibility && React__default.createElement("button", {
|
|
433
|
+
className: "text-sm px-3 py-1 bg-teal-500 hover:bg-teal-600 text-white rounded-md transition-colors flex-shrink-0",
|
|
434
|
+
onClick: () => setBottomDrawer(true)
|
|
435
|
+
}, mobilePreviewState?.mobilePreviewCTAText))), (isMobileView || isSmallTabletView) && channelId && mobilePreviewState?.mobilePreviewVisibility && React__default.createElement("div", {
|
|
436
|
+
className: `mt-4 ${isSmallScreen ? 'mx-3' : 'mx-4'}`
|
|
437
|
+
}, React__default.createElement("div", {
|
|
438
|
+
className: "mb-2"
|
|
439
|
+
}, React__default.createElement("div", {
|
|
440
|
+
className: "w-full flex justify-between items-center gap-2 mb-[5px]"
|
|
441
|
+
}, React__default.createElement("span", {
|
|
442
|
+
className: "truncate flex-1 text-sm"
|
|
443
|
+
}, mobilePreviewState?.mobilePreviewText), React__default.createElement("button", {
|
|
444
|
+
className: "text-sm px-3 py-2 bg-teal-500 hover:bg-teal-600 text-white rounded-md transition-colors flex-shrink-0",
|
|
445
|
+
onClick: () => setBottomDrawer(true)
|
|
446
|
+
}, mobilePreviewState?.mobilePreviewCTAText))), React__default.createElement("hr", {
|
|
447
|
+
className: "border-gray-200"
|
|
448
|
+
})), React__default.createElement("div", {
|
|
449
|
+
className: "flex-1 flex flex-col min-h-0 overflow-hidden"
|
|
450
|
+
}, channelId && React__default.createElement(React__default.Fragment, null, postId ? postId === '1' ? React__default.createElement(ThreadsInbox, {
|
|
451
|
+
channelId: channelId,
|
|
452
|
+
role: channelRole,
|
|
453
|
+
pathPrefix: pathPrefix,
|
|
454
|
+
setChannelId: () => {},
|
|
455
|
+
setPostId: () => {},
|
|
456
|
+
setGoBack: () => {}
|
|
457
|
+
}) : React__default.createElement(ThreadMessagesInbox, {
|
|
458
|
+
channelId: channelId,
|
|
459
|
+
postId: postId,
|
|
460
|
+
role: channelRole,
|
|
461
|
+
goBack: false,
|
|
462
|
+
pathPrefix: pathPrefix,
|
|
463
|
+
setPostId: () => {},
|
|
464
|
+
setChannelId: () => {},
|
|
465
|
+
onMessageClick: onMessageClick
|
|
466
|
+
}) : React__default.createElement(MessagesComponent, {
|
|
467
|
+
channelId: channelId,
|
|
468
|
+
MessagesLoaderQuery: MessagesLoaderQuery,
|
|
469
|
+
channelsDetail: channelsDetail,
|
|
470
|
+
channelLoading: channelLoading,
|
|
471
|
+
onMessageClick: onMessageClick,
|
|
472
|
+
isSmallScreen: isSmallScreen,
|
|
473
|
+
isDesktopView: isDesktopView,
|
|
474
|
+
windowHeight: windowHeight,
|
|
475
|
+
windowWidth: windowWidth
|
|
476
|
+
})))), (isMobileView || isSmallTabletView) && React__default.createElement(Drawer, {
|
|
477
|
+
isOpen: isBottomDrawerOpen,
|
|
478
|
+
onClose: () => setBottomDrawer(false),
|
|
479
|
+
title: mobilePreviewState.mobilePreviewText
|
|
480
|
+
}, React__default.createElement(RightSidebarWrapper, {
|
|
481
|
+
MessagesLoaderQuery: MessagesLoaderQuery,
|
|
482
|
+
selectedPost: selectedPost,
|
|
483
|
+
detailSidebarOptions: detailSidebarOptions
|
|
484
|
+
})));
|
|
485
|
+
});
|
|
486
|
+
const RightSidebarWrapper = React__default.memo(({
|
|
487
|
+
MessagesLoaderQuery,
|
|
488
|
+
selectedPost,
|
|
489
|
+
detailSidebarOptions
|
|
490
|
+
}) => {
|
|
491
|
+
const {
|
|
492
|
+
data
|
|
493
|
+
} = MessagesLoaderQuery || {};
|
|
494
|
+
const [activeTab, setActiveTab] = React__default.useState('preview');
|
|
495
|
+
const sortedMessages = useMemo(() => {
|
|
496
|
+
const messages = data?.messages?.data || [];
|
|
497
|
+
return orderBy(uniqBy(messages, 'id'), ['createdAt'], ['asc']);
|
|
498
|
+
}, [data?.messages?.data]);
|
|
499
|
+
const handleRefreshSandbox = useCallback(() => {
|
|
500
|
+
// Refresh sandbox functionality
|
|
501
|
+
console.log('Refreshing sandbox...');
|
|
502
|
+
// Add actual refresh logic here
|
|
503
|
+
}, []);
|
|
504
|
+
if (!sortedMessages.length) return null;
|
|
505
|
+
return React__default.createElement("div", {
|
|
506
|
+
className: "h-full flex flex-col overflow-hidden bg-white"
|
|
507
|
+
}, React__default.createElement("div", {
|
|
508
|
+
className: "flex-shrink-0 border-b border-gray-200"
|
|
509
|
+
}, React__default.createElement("div", {
|
|
510
|
+
className: "flex items-center justify-between px-4 py-3"
|
|
511
|
+
}, React__default.createElement("div", {
|
|
512
|
+
className: "flex items-center space-x-1"
|
|
513
|
+
}, React__default.createElement("button", {
|
|
514
|
+
onClick: () => setActiveTab('preview'),
|
|
515
|
+
className: `flex items-center space-x-2 px-3 py-2 text-sm font-medium rounded-lg transition-colors ${activeTab === 'preview' ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900 hover:bg-gray-50'}`
|
|
516
|
+
}, React__default.createElement("svg", {
|
|
517
|
+
className: "w-4 h-4",
|
|
518
|
+
fill: "none",
|
|
519
|
+
stroke: "currentColor",
|
|
520
|
+
viewBox: "0 0 24 24"
|
|
521
|
+
}, React__default.createElement("path", {
|
|
522
|
+
strokeLinecap: "round",
|
|
523
|
+
strokeLinejoin: "round",
|
|
524
|
+
strokeWidth: 2,
|
|
525
|
+
d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
|
526
|
+
}), React__default.createElement("path", {
|
|
527
|
+
strokeLinecap: "round",
|
|
528
|
+
strokeLinejoin: "round",
|
|
529
|
+
strokeWidth: 2,
|
|
530
|
+
d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
|
|
531
|
+
})), React__default.createElement("span", null, "Preview")), React__default.createElement("button", {
|
|
532
|
+
onClick: () => setActiveTab('code'),
|
|
533
|
+
className: `flex items-center space-x-2 px-3 py-2 text-sm font-medium rounded-lg transition-colors ${activeTab === 'code' ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900 hover:bg-gray-50'}`
|
|
534
|
+
}, React__default.createElement("svg", {
|
|
535
|
+
className: "w-4 h-4",
|
|
536
|
+
fill: "none",
|
|
537
|
+
stroke: "currentColor",
|
|
538
|
+
viewBox: "0 0 24 24"
|
|
539
|
+
}, React__default.createElement("path", {
|
|
540
|
+
strokeLinecap: "round",
|
|
541
|
+
strokeLinejoin: "round",
|
|
542
|
+
strokeWidth: 2,
|
|
543
|
+
d: "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
|
|
544
|
+
})), React__default.createElement("span", null, "Code"))), React__default.createElement("button", {
|
|
545
|
+
onClick: handleRefreshSandbox,
|
|
546
|
+
className: "p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-lg transition-colors",
|
|
547
|
+
title: "Refresh Sandbox"
|
|
548
|
+
}, React__default.createElement("svg", {
|
|
549
|
+
className: "w-4 h-4",
|
|
550
|
+
fill: "none",
|
|
551
|
+
stroke: "currentColor",
|
|
552
|
+
viewBox: "0 0 24 24"
|
|
553
|
+
}, React__default.createElement("path", {
|
|
554
|
+
strokeLinecap: "round",
|
|
555
|
+
strokeLinejoin: "round",
|
|
556
|
+
strokeWidth: 2,
|
|
557
|
+
d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
|
558
|
+
})))), React__default.createElement("hr", {
|
|
559
|
+
className: "border-gray-300 my-6"
|
|
560
|
+
}), React__default.createElement("div", {
|
|
561
|
+
className: "px-4 pb-3 flex justify-end"
|
|
562
|
+
}, React__default.createElement("button", {
|
|
563
|
+
onClick: handleRefreshSandbox,
|
|
564
|
+
className: "flex items-center space-x-2 px-4 py-2 text-sm font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-lg transition-colors border border-gray-200",
|
|
565
|
+
title: "Refresh Sandbox"
|
|
566
|
+
}, React__default.createElement("svg", {
|
|
567
|
+
className: "w-4 h-4",
|
|
568
|
+
fill: "none",
|
|
569
|
+
stroke: "currentColor",
|
|
570
|
+
viewBox: "0 0 24 24"
|
|
571
|
+
}, React__default.createElement("path", {
|
|
572
|
+
strokeLinecap: "round",
|
|
573
|
+
strokeLinejoin: "round",
|
|
574
|
+
strokeWidth: 2,
|
|
575
|
+
d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
|
576
|
+
})), React__default.createElement("span", null, "Refresh Sandbox")))), React__default.createElement("div", {
|
|
577
|
+
className: "flex-1 overflow-hidden"
|
|
578
|
+
}, activeTab === 'preview' ? React__default.createElement("div", {
|
|
579
|
+
className: "h-full flex items-center justify-center bg-gray-50"
|
|
580
|
+
}, React__default.createElement("div", {
|
|
581
|
+
className: "text-center"
|
|
582
|
+
}, React__default.createElement("div", {
|
|
583
|
+
className: "mb-8"
|
|
584
|
+
}, React__default.createElement("svg", {
|
|
585
|
+
className: "w-32 h-16 mx-auto text-black",
|
|
586
|
+
viewBox: "0 0 394 80",
|
|
587
|
+
fill: "currentColor"
|
|
588
|
+
}, React__default.createElement("path", {
|
|
589
|
+
d: "M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.4zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.7h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"
|
|
590
|
+
}), React__default.createElement("path", {
|
|
591
|
+
d: "M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.2 3.4 1 1.4 1.5 3 1.5 5h-5.8z"
|
|
592
|
+
}))), React__default.createElement("div", {
|
|
593
|
+
className: "space-y-4 text-gray-600"
|
|
594
|
+
}, React__default.createElement("h3", {
|
|
595
|
+
className: "text-lg font-semibold text-gray-900"
|
|
596
|
+
}, "Get started by editing"), React__default.createElement("p", {
|
|
597
|
+
className: "font-mono text-sm bg-gray-100 px-3 py-1 rounded"
|
|
598
|
+
}, "app/page.tsx"), React__default.createElement("p", null, "Save and see your changes instantly.")), React__default.createElement("div", {
|
|
599
|
+
className: "mt-8 space-y-4"
|
|
600
|
+
}, React__default.createElement("button", {
|
|
601
|
+
className: "bg-black text-white px-6 py-3 rounded-full hover:bg-gray-800 transition-colors flex items-center space-x-2 mx-auto"
|
|
602
|
+
}, React__default.createElement("svg", {
|
|
603
|
+
className: "w-4 h-4",
|
|
604
|
+
fill: "currentColor",
|
|
605
|
+
viewBox: "0 0 24 24"
|
|
606
|
+
}, React__default.createElement("path", {
|
|
607
|
+
d: "M12 2L2 7v10c0 5.55 3.84 9.739 9 11 5.16-1.261 9-5.45 9-11V7l-10-5z"
|
|
608
|
+
})), React__default.createElement("span", null, "Deploy now")), React__default.createElement("p", {
|
|
609
|
+
className: "text-sm text-gray-500 underline cursor-pointer hover:text-gray-700"
|
|
610
|
+
}, "Read our docs")))) : React__default.createElement("div", {
|
|
611
|
+
className: "h-full bg-gray-900 text-gray-300 p-4 overflow-auto"
|
|
612
|
+
}, React__default.createElement("div", {
|
|
613
|
+
className: "font-mono text-sm"
|
|
614
|
+
}, React__default.createElement("div", {
|
|
615
|
+
className: "mb-4"
|
|
616
|
+
}, React__default.createElement("div", {
|
|
617
|
+
className: "text-green-400"
|
|
618
|
+
}, "// app/page.tsx")), React__default.createElement("div", {
|
|
619
|
+
className: "space-y-2"
|
|
620
|
+
}, React__default.createElement("div", null, React__default.createElement("span", {
|
|
621
|
+
className: "text-purple-400"
|
|
622
|
+
}, "export"), ' ', React__default.createElement("span", {
|
|
623
|
+
className: "text-purple-400"
|
|
624
|
+
}, "default"), ' ', React__default.createElement("span", {
|
|
625
|
+
className: "text-blue-400"
|
|
626
|
+
}, "function"), ' ', React__default.createElement("span", {
|
|
627
|
+
className: "text-yellow-400"
|
|
628
|
+
}, "Home"), "() ", '{'), React__default.createElement("div", {
|
|
629
|
+
className: "ml-4"
|
|
630
|
+
}, React__default.createElement("span", {
|
|
631
|
+
className: "text-purple-400"
|
|
632
|
+
}, "return"), " ("), React__default.createElement("div", {
|
|
633
|
+
className: "ml-8"
|
|
634
|
+
}, '<', React__default.createElement("span", {
|
|
635
|
+
className: "text-red-400"
|
|
636
|
+
}, "main"), ' ', React__default.createElement("span", {
|
|
637
|
+
className: "text-green-400"
|
|
638
|
+
}, "className"), "=", React__default.createElement("span", {
|
|
639
|
+
className: "text-yellow-400"
|
|
640
|
+
}, "\"flex min-h-screen flex-col items-center justify-between p-24\""), '>'), React__default.createElement("div", {
|
|
641
|
+
className: "ml-12"
|
|
642
|
+
}, '<', React__default.createElement("span", {
|
|
643
|
+
className: "text-red-400"
|
|
644
|
+
}, "div"), ' ', React__default.createElement("span", {
|
|
645
|
+
className: "text-green-400"
|
|
646
|
+
}, "className"), "=", React__default.createElement("span", {
|
|
647
|
+
className: "text-yellow-400"
|
|
648
|
+
}, "\"z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex\""), '>'), React__default.createElement("div", {
|
|
649
|
+
className: "ml-16"
|
|
650
|
+
}, '<', React__default.createElement("span", {
|
|
651
|
+
className: "text-red-400"
|
|
652
|
+
}, "p"), ' ', React__default.createElement("span", {
|
|
653
|
+
className: "text-green-400"
|
|
654
|
+
}, "className"), "=", React__default.createElement("span", {
|
|
655
|
+
className: "text-yellow-400"
|
|
656
|
+
}, "\"fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30\""), '>'), React__default.createElement("div", {
|
|
657
|
+
className: "ml-20 text-gray-400"
|
|
658
|
+
}, "Get started by editing\u00A0"), React__default.createElement("div", {
|
|
659
|
+
className: "ml-20"
|
|
660
|
+
}, '<', React__default.createElement("span", {
|
|
661
|
+
className: "text-red-400"
|
|
662
|
+
}, "code"), ' ', React__default.createElement("span", {
|
|
663
|
+
className: "text-green-400"
|
|
664
|
+
}, "className"), "=", React__default.createElement("span", {
|
|
665
|
+
className: "text-yellow-400"
|
|
666
|
+
}, "\"font-mono font-bold\""), '>', "app/page.tsx", '</', React__default.createElement("span", {
|
|
667
|
+
className: "text-red-400"
|
|
668
|
+
}, "code"), '>'), React__default.createElement("div", {
|
|
669
|
+
className: "ml-16"
|
|
670
|
+
}, '</', React__default.createElement("span", {
|
|
671
|
+
className: "text-red-400"
|
|
672
|
+
}, "p"), '>'), React__default.createElement("div", {
|
|
673
|
+
className: "ml-12"
|
|
674
|
+
}, '</', React__default.createElement("span", {
|
|
675
|
+
className: "text-red-400"
|
|
676
|
+
}, "div"), '>'), React__default.createElement("div", {
|
|
677
|
+
className: "ml-8"
|
|
678
|
+
}, '</', React__default.createElement("span", {
|
|
679
|
+
className: "text-red-400"
|
|
680
|
+
}, "main"), '>'), React__default.createElement("div", {
|
|
681
|
+
className: "ml-4"
|
|
682
|
+
}, ");"), React__default.createElement("div", null, '}'))))));
|
|
683
|
+
});
|
|
684
|
+
const MessagesComponent = React__default.memo(props => {
|
|
685
|
+
const {
|
|
686
|
+
channelId,
|
|
687
|
+
MessagesLoaderQuery,
|
|
688
|
+
channelsDetail,
|
|
689
|
+
channelLoading,
|
|
690
|
+
onMessageClick,
|
|
691
|
+
isSmallScreen,
|
|
692
|
+
isDesktopView,
|
|
693
|
+
windowHeight = 768,
|
|
694
|
+
windowWidth = 1024
|
|
695
|
+
} = props;
|
|
696
|
+
const messageRootListRef = useRef(null);
|
|
697
|
+
const messageListRef = useRef(null);
|
|
698
|
+
useApolloClient();
|
|
699
|
+
const [isLoadingOlder, setIsLoadingOlder] = React__default.useState(false);
|
|
700
|
+
const isLoadingOlderRef = useRef(false);
|
|
701
|
+
const scrollTimeoutRef = useRef(null);
|
|
702
|
+
const auth = useSelector(userSelector);
|
|
703
|
+
const {
|
|
704
|
+
startUpload
|
|
705
|
+
} = useUploadFiles();
|
|
706
|
+
const [sendMsg] = useSendMessagesMutation();
|
|
707
|
+
const {
|
|
708
|
+
data,
|
|
709
|
+
loading: messageLoading,
|
|
710
|
+
fetchMore: fetchMoreMessages,
|
|
711
|
+
subscribeToMore
|
|
712
|
+
} = MessagesLoaderQuery || {};
|
|
713
|
+
// Get messages directly from Apollo cache
|
|
714
|
+
const messages = useMemo(() => {
|
|
715
|
+
const messagesData = data?.messages?.data || [];
|
|
716
|
+
return orderBy(uniqBy(messagesData, 'id'), ['createdAt'], ['asc']);
|
|
717
|
+
}, [data?.messages?.data]);
|
|
718
|
+
const totalCount = data?.messages?.totalCount || 0;
|
|
719
|
+
const scrollToBottom = useCallback(() => {
|
|
720
|
+
if (messageRootListRef?.current) {
|
|
721
|
+
messageRootListRef.current.scrollTop = messageRootListRef.current.scrollHeight;
|
|
722
|
+
}
|
|
723
|
+
}, []);
|
|
724
|
+
// Auto-scroll on new messages (but not when loading older messages)
|
|
725
|
+
useEffect(() => {
|
|
726
|
+
if (!isLoadingOlderRef.current) {
|
|
727
|
+
const timer = setTimeout(() => scrollToBottom(), 100);
|
|
728
|
+
return () => clearTimeout(timer);
|
|
729
|
+
}
|
|
730
|
+
}, [messages.length, scrollToBottom]);
|
|
731
|
+
const onFetchOld = useCallback(async skip => {
|
|
732
|
+
if (channelId && fetchMoreMessages && !isLoadingOlder) {
|
|
733
|
+
try {
|
|
734
|
+
setIsLoadingOlder(true);
|
|
735
|
+
isLoadingOlderRef.current = true;
|
|
736
|
+
// Capture current scroll height before fetching
|
|
737
|
+
const oldScrollHeight = messageRootListRef?.current?.scrollHeight || 0;
|
|
738
|
+
await fetchMoreMessages({
|
|
739
|
+
variables: {
|
|
740
|
+
channelId: channelId.toString(),
|
|
741
|
+
parentId: null,
|
|
742
|
+
skip
|
|
743
|
+
},
|
|
744
|
+
updateQuery: (prev, {
|
|
745
|
+
fetchMoreResult
|
|
746
|
+
}) => {
|
|
747
|
+
if (!fetchMoreResult) return prev;
|
|
748
|
+
const newMessages = fetchMoreResult.messages.data;
|
|
749
|
+
const existingMessages = prev.messages?.data || [];
|
|
750
|
+
return {
|
|
751
|
+
...prev,
|
|
752
|
+
messages: {
|
|
753
|
+
...fetchMoreResult.messages,
|
|
754
|
+
data: uniqBy([...newMessages, ...existingMessages], 'id')
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
});
|
|
759
|
+
// Maintain scroll position after loading older messages
|
|
760
|
+
setTimeout(() => {
|
|
761
|
+
if (messageRootListRef?.current) {
|
|
762
|
+
const newScrollHeight = messageRootListRef.current.scrollHeight;
|
|
763
|
+
const scrollDiff = newScrollHeight - oldScrollHeight;
|
|
764
|
+
// For normal flex layout, maintain position by adjusting scroll offset
|
|
765
|
+
messageRootListRef.current.scrollTop = scrollDiff;
|
|
766
|
+
}
|
|
767
|
+
// Reset the loading flag after position is maintained
|
|
768
|
+
setTimeout(() => {
|
|
769
|
+
isLoadingOlderRef.current = false;
|
|
770
|
+
}, 50);
|
|
771
|
+
}, 100);
|
|
772
|
+
} catch (error) {
|
|
773
|
+
console.error('Error fetching older messages:', error);
|
|
774
|
+
isLoadingOlderRef.current = false;
|
|
775
|
+
} finally {
|
|
776
|
+
setIsLoadingOlder(false);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}, [channelId, fetchMoreMessages, isLoadingOlder]);
|
|
780
|
+
// Scroll to bottom when channel changes
|
|
781
|
+
useEffect(() => {
|
|
782
|
+
if (channelId && messages.length > 0) {
|
|
783
|
+
isLoadingOlderRef.current = false; // Reset flag on channel change
|
|
784
|
+
const timer = setTimeout(() => scrollToBottom(), 200);
|
|
785
|
+
return () => clearTimeout(timer);
|
|
786
|
+
}
|
|
787
|
+
}, [channelId, scrollToBottom]);
|
|
788
|
+
// Alternative scroll detection for Firefox
|
|
789
|
+
useEffect(() => {
|
|
790
|
+
const element = messageRootListRef.current;
|
|
791
|
+
if (!element) return;
|
|
792
|
+
// Firefox-specific scroll detection using passive listeners
|
|
793
|
+
const handleScrollEnd = () => {
|
|
794
|
+
if (!isLoadingOlder && element) {
|
|
795
|
+
const {
|
|
796
|
+
scrollTop
|
|
797
|
+
} = element;
|
|
798
|
+
const isAtTop = Math.round(scrollTop) <= 30;
|
|
799
|
+
const hasMoreMessages = totalCount > messages.length;
|
|
800
|
+
if (isAtTop && hasMoreMessages) {
|
|
801
|
+
console.log('ScrollEnd triggered load more (Firefox):', {
|
|
802
|
+
scrollTop: Math.round(scrollTop),
|
|
803
|
+
totalCount,
|
|
804
|
+
messagesLength: messages.length
|
|
805
|
+
});
|
|
806
|
+
onFetchOld(messages.length);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
// Use scrollend event if available (modern Firefox/Chrome)
|
|
811
|
+
if ('onscrollend' in element) {
|
|
812
|
+
element.addEventListener('scrollend', handleScrollEnd, {
|
|
813
|
+
passive: true
|
|
814
|
+
});
|
|
815
|
+
return () => {
|
|
816
|
+
element.removeEventListener('scrollend', handleScrollEnd);
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
}, [totalCount, messages.length, onFetchOld, isLoadingOlder]);
|
|
820
|
+
// Cleanup scroll timeout on unmount
|
|
821
|
+
useEffect(() => {
|
|
822
|
+
return () => {
|
|
823
|
+
if (scrollTimeoutRef.current) {
|
|
824
|
+
clearTimeout(scrollTimeoutRef.current);
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
}, []);
|
|
828
|
+
const onMessagesScroll = useCallback(async e => {
|
|
829
|
+
// Throttle scroll events for better performance, especially in Firefox
|
|
830
|
+
if (scrollTimeoutRef.current) {
|
|
831
|
+
clearTimeout(scrollTimeoutRef.current);
|
|
832
|
+
}
|
|
833
|
+
scrollTimeoutRef.current = setTimeout(async () => {
|
|
834
|
+
if (messageRootListRef.current && !isLoadingOlder) {
|
|
835
|
+
const element = messageRootListRef.current;
|
|
836
|
+
const {
|
|
837
|
+
clientHeight,
|
|
838
|
+
scrollHeight,
|
|
839
|
+
scrollTop
|
|
840
|
+
} = element;
|
|
841
|
+
// Firefox-compatible scroll detection
|
|
842
|
+
// Use Math.ceil to handle Firefox's fractional scrollTop values
|
|
843
|
+
const isAtTop = Math.ceil(scrollTop) <= 25;
|
|
844
|
+
const hasMoreMessages = totalCount > messages.length;
|
|
845
|
+
// Additional Firefox-specific check
|
|
846
|
+
const isFirefox = navigator.userAgent.includes('Firefox');
|
|
847
|
+
const firefoxAdjustedTop = isFirefox ? Math.round(scrollTop) <= 30 : isAtTop;
|
|
848
|
+
if ((isAtTop || firefoxAdjustedTop) && hasMoreMessages) {
|
|
849
|
+
console.log('Triggering load more:', {
|
|
850
|
+
scrollTop: Math.ceil(scrollTop),
|
|
851
|
+
originalScrollTop: scrollTop,
|
|
852
|
+
totalCount,
|
|
853
|
+
messagesLength: messages.length,
|
|
854
|
+
scrollHeight,
|
|
855
|
+
clientHeight,
|
|
856
|
+
browser: isFirefox ? 'Firefox' : 'Other',
|
|
857
|
+
isAtTop,
|
|
858
|
+
firefoxAdjustedTop
|
|
859
|
+
});
|
|
860
|
+
await onFetchOld(messages.length);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}, 100);
|
|
864
|
+
}, [totalCount, messages.length, onFetchOld, isLoadingOlder]);
|
|
865
|
+
// Optimistic message sending with Apollo cache updates
|
|
866
|
+
const handleSend = useCallback(async (message, files = []) => {
|
|
867
|
+
// Allow sending if there's either a message or files
|
|
868
|
+
if ((!message || !message.trim()) && (!files || files.length === 0)) return;
|
|
869
|
+
if (!channelId) return;
|
|
870
|
+
try {
|
|
871
|
+
const postId = objectId();
|
|
872
|
+
const currentDate = new Date();
|
|
873
|
+
const createOptimisticMessage = files => ({
|
|
874
|
+
__typename: 'Post',
|
|
875
|
+
id: postId,
|
|
876
|
+
message,
|
|
877
|
+
createdAt: currentDate.toISOString(),
|
|
878
|
+
updatedAt: currentDate.toISOString(),
|
|
879
|
+
author: {
|
|
880
|
+
__typename: 'UserAccount',
|
|
881
|
+
id: auth?.id,
|
|
882
|
+
givenName: auth?.profile?.given_name || '',
|
|
883
|
+
familyName: auth?.profile?.family_name || '',
|
|
884
|
+
email: auth?.profile?.email || '',
|
|
885
|
+
username: auth?.profile?.nickname || '',
|
|
886
|
+
fullName: auth?.profile?.name || '',
|
|
887
|
+
picture: auth?.profile?.picture || '',
|
|
888
|
+
alias: [auth?.authUserId ?? ''],
|
|
889
|
+
tokens: []
|
|
890
|
+
},
|
|
891
|
+
isDelivered: false,
|
|
892
|
+
// Will be true once confirmed by server
|
|
893
|
+
isRead: false,
|
|
894
|
+
type: 'TEXT',
|
|
895
|
+
parentId: null,
|
|
896
|
+
fromServer: false,
|
|
897
|
+
channel: {
|
|
898
|
+
__typename: 'Channel',
|
|
899
|
+
id: channelId
|
|
900
|
+
},
|
|
901
|
+
propsConfiguration: {
|
|
902
|
+
__typename: 'MachineConfiguration',
|
|
903
|
+
id: null,
|
|
904
|
+
resource: '',
|
|
905
|
+
contents: null,
|
|
906
|
+
keys: null,
|
|
907
|
+
target: null,
|
|
908
|
+
overrides: null
|
|
909
|
+
},
|
|
910
|
+
props: {},
|
|
911
|
+
files: {
|
|
912
|
+
__typename: 'FilesInfo',
|
|
913
|
+
data: files || [],
|
|
914
|
+
totalCount: files?.length || 0
|
|
915
|
+
},
|
|
916
|
+
replies: {
|
|
917
|
+
__typename: 'Messages',
|
|
918
|
+
data: [],
|
|
919
|
+
totalCount: 0
|
|
920
|
+
}
|
|
921
|
+
});
|
|
922
|
+
const optimisticMessage = createOptimisticMessage(files);
|
|
923
|
+
if (files?.length > 0) {
|
|
924
|
+
const uploadResponse = await startUpload({
|
|
925
|
+
file: files,
|
|
926
|
+
saveUploadedFile: {
|
|
927
|
+
variables: {
|
|
928
|
+
postId
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
createUploadLink: {
|
|
932
|
+
variables: {
|
|
933
|
+
postId
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
const uploadedFiles = uploadResponse.data;
|
|
938
|
+
if (uploadedFiles) {
|
|
939
|
+
const fileIds = uploadedFiles.map(f => f.id);
|
|
940
|
+
await sendMsg({
|
|
941
|
+
variables: {
|
|
942
|
+
postId,
|
|
943
|
+
channelId,
|
|
944
|
+
content: message,
|
|
945
|
+
files: fileIds
|
|
946
|
+
},
|
|
947
|
+
optimisticResponse: {
|
|
948
|
+
__typename: 'Mutation',
|
|
949
|
+
sendMessage: createOptimisticMessage(uploadedFiles)
|
|
950
|
+
},
|
|
951
|
+
update: (cache, {
|
|
952
|
+
data: mutationData
|
|
953
|
+
}) => {
|
|
954
|
+
if (!mutationData?.sendMessage) return;
|
|
955
|
+
// Update messages cache optimistically
|
|
956
|
+
const messagesQuery = {
|
|
957
|
+
query: MessagesDocument,
|
|
958
|
+
variables: {
|
|
959
|
+
channelId: channelId.toString(),
|
|
960
|
+
parentId: null,
|
|
961
|
+
limit: MESSAGES_PER_PAGE
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
try {
|
|
965
|
+
const existingData = cache.readQuery(messagesQuery);
|
|
966
|
+
if (existingData?.messages) {
|
|
967
|
+
cache.writeQuery({
|
|
968
|
+
...messagesQuery,
|
|
969
|
+
data: {
|
|
970
|
+
messages: {
|
|
971
|
+
...existingData.messages,
|
|
972
|
+
data: [...(existingData.messages.data || []), mutationData.sendMessage],
|
|
973
|
+
totalCount: (existingData.messages.totalCount || 0) + 1
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
} catch (error) {
|
|
979
|
+
console.debug('Cache update failed (expected on first message):', error);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
} else {
|
|
985
|
+
await sendMsg({
|
|
986
|
+
variables: {
|
|
987
|
+
channelId,
|
|
988
|
+
content: message
|
|
989
|
+
},
|
|
990
|
+
optimisticResponse: {
|
|
991
|
+
__typename: 'Mutation',
|
|
992
|
+
sendMessage: optimisticMessage
|
|
993
|
+
},
|
|
994
|
+
update: (cache, {
|
|
995
|
+
data: mutationData
|
|
996
|
+
}) => {
|
|
997
|
+
if (!mutationData?.sendMessage) return;
|
|
998
|
+
// Update messages cache optimistically
|
|
999
|
+
const messagesQuery = {
|
|
1000
|
+
query: MessagesDocument,
|
|
1001
|
+
variables: {
|
|
1002
|
+
channelId: channelId.toString(),
|
|
1003
|
+
parentId: null,
|
|
1004
|
+
limit: MESSAGES_PER_PAGE
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1007
|
+
try {
|
|
1008
|
+
const existingData = cache.readQuery(messagesQuery);
|
|
1009
|
+
if (existingData?.messages) {
|
|
1010
|
+
cache.writeQuery({
|
|
1011
|
+
...messagesQuery,
|
|
1012
|
+
data: {
|
|
1013
|
+
messages: {
|
|
1014
|
+
...existingData.messages,
|
|
1015
|
+
data: [...(existingData.messages.data || []), mutationData.sendMessage],
|
|
1016
|
+
totalCount: (existingData.messages.totalCount || 0) + 1
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
} catch (error) {
|
|
1022
|
+
console.debug('Cache update failed (expected on first message):', error);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
} catch (error) {
|
|
1028
|
+
console.error('Error sending message:', error);
|
|
1029
|
+
}
|
|
1030
|
+
}, [channelId, auth, startUpload, sendMsg]);
|
|
1031
|
+
// Show loading spinner for initial load
|
|
1032
|
+
if ((messageLoading || channelLoading) && messages.length === 0) {
|
|
1033
|
+
return React__default.createElement("div", {
|
|
1034
|
+
className: "flex-1 flex justify-center items-center"
|
|
1035
|
+
}, React__default.createElement(Spinner, {
|
|
1036
|
+
className: "w-12 h-12"
|
|
1037
|
+
}));
|
|
1038
|
+
}
|
|
1039
|
+
return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
|
|
1040
|
+
ref: messageRootListRef,
|
|
1041
|
+
className: `overflow-y-scroll bg-gray-50 ${isSmallScreen ? 'p-2 px-3' : isDesktopView ? 'p-6 px-8' : 'p-4 px-6'}`,
|
|
1042
|
+
onScroll: onMessagesScroll,
|
|
1043
|
+
style: {
|
|
1044
|
+
height: `${windowHeight - 140}px`,
|
|
1045
|
+
// Subtract header + input height
|
|
1046
|
+
maxHeight: '100vh',
|
|
1047
|
+
scrollbarWidth: 'thin',
|
|
1048
|
+
scrollbarColor: '#cbd5e0 #f7fafc',
|
|
1049
|
+
overflowY: 'scroll',
|
|
1050
|
+
WebkitOverflowScrolling: 'touch'
|
|
1051
|
+
}
|
|
1052
|
+
}, React__default.createElement("div", {
|
|
1053
|
+
className: "min-h-full"
|
|
1054
|
+
}, messages.length > 0 ? React__default.createElement(React__default.Fragment, null, isLoadingOlder && React__default.createElement("div", {
|
|
1055
|
+
className: "flex justify-center py-4"
|
|
1056
|
+
}, React__default.createElement("div", {
|
|
1057
|
+
className: "flex items-center space-x-2 text-gray-500"
|
|
1058
|
+
}, React__default.createElement(Spinner, {
|
|
1059
|
+
className: "w-4 h-4"
|
|
1060
|
+
}), React__default.createElement("span", {
|
|
1061
|
+
className: "text-sm"
|
|
1062
|
+
}, "Loading older messages..."))), React__default.createElement(Messages, {
|
|
1063
|
+
innerRef: messageListRef,
|
|
1064
|
+
channelId: channelId,
|
|
1065
|
+
currentUser: auth,
|
|
1066
|
+
channelMessages: messages,
|
|
1067
|
+
totalCount: totalCount,
|
|
1068
|
+
onMessageClick: onMessageClick,
|
|
1069
|
+
isDesktopView: isDesktopView || false,
|
|
1070
|
+
isSmallScreen: isSmallScreen || false
|
|
1071
|
+
}), React__default.createElement(SubscriptionHandler, {
|
|
1072
|
+
subscribeToMore: subscribeToMore,
|
|
1073
|
+
document: OnChatMessageAddedDocument,
|
|
1074
|
+
variables: {
|
|
1075
|
+
channelId: channelId.toString()
|
|
1076
|
+
},
|
|
1077
|
+
enabled: !!channelId && !!subscribeToMore,
|
|
1078
|
+
updateQuery: (prev, {
|
|
1079
|
+
subscriptionData
|
|
1080
|
+
}) => {
|
|
1081
|
+
console.log('Subscription updateQuery called:', {
|
|
1082
|
+
prev,
|
|
1083
|
+
subscriptionData
|
|
1084
|
+
});
|
|
1085
|
+
if (!subscriptionData.data) {
|
|
1086
|
+
console.log('No subscription data, returning prev');
|
|
1087
|
+
return prev;
|
|
1088
|
+
}
|
|
1089
|
+
const newMessage = subscriptionData.data.chatMessageAdded;
|
|
1090
|
+
console.log('New message received via subscription:', newMessage);
|
|
1091
|
+
return {
|
|
1092
|
+
...prev,
|
|
1093
|
+
messages: {
|
|
1094
|
+
...prev?.messages,
|
|
1095
|
+
data: uniqBy([...(prev?.messages?.data || []), newMessage], 'id'),
|
|
1096
|
+
totalCount: (prev?.messages?.totalCount || 0) + 1
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
},
|
|
1100
|
+
onError: error => {
|
|
1101
|
+
console.error('Subscription error:', error);
|
|
1102
|
+
}
|
|
1103
|
+
})) : React__default.createElement("div", {
|
|
1104
|
+
className: "flex items-center justify-center text-gray-500 min-h-96"
|
|
1105
|
+
}, React__default.createElement("div", {
|
|
1106
|
+
className: "text-center max-w-sm mx-auto px-4"
|
|
1107
|
+
}, React__default.createElement("div", {
|
|
1108
|
+
className: "text-6xl mb-4 opacity-50"
|
|
1109
|
+
}, "\uD83D\uDCAC"), React__default.createElement("h3", {
|
|
1110
|
+
className: "text-lg font-semibold text-gray-600 mb-2"
|
|
1111
|
+
}, "No messages yet"), React__default.createElement("p", {
|
|
1112
|
+
className: "text-sm text-gray-500"
|
|
1113
|
+
}, "Start the conversation by sending a message below!"))))), React__default.createElement("div", {
|
|
1114
|
+
className: "flex-shrink-0 border-t border-gray-200 bg-white"
|
|
1115
|
+
}, React__default.createElement("div", {
|
|
1116
|
+
className: "px-4 py-3 border-b border-gray-100"
|
|
1117
|
+
}, React__default.createElement("div", {
|
|
1118
|
+
className: "flex gap-3"
|
|
1119
|
+
}, React__default.createElement("div", {
|
|
1120
|
+
className: "flex-1 relative"
|
|
1121
|
+
}, React__default.createElement("button", {
|
|
1122
|
+
type: "button",
|
|
1123
|
+
className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-md bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-left pr-10 flex items-center space-x-2",
|
|
1124
|
+
onClick: () => {
|
|
1125
|
+
const modal = document.getElementById('framework-modal');
|
|
1126
|
+
if (modal) {
|
|
1127
|
+
modal.classList.toggle('hidden');
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}, React__default.createElement("div", {
|
|
1131
|
+
className: "w-5 h-5 bg-purple-100 rounded flex items-center justify-center"
|
|
1132
|
+
}, "\u269B\uFE0F"), React__default.createElement("span", null, "Next.js")), React__default.createElement("div", {
|
|
1133
|
+
className: "absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"
|
|
1134
|
+
}, React__default.createElement("svg", {
|
|
1135
|
+
className: "w-4 h-4 text-gray-400",
|
|
1136
|
+
fill: "none",
|
|
1137
|
+
stroke: "currentColor",
|
|
1138
|
+
viewBox: "0 0 24 24"
|
|
1139
|
+
}, React__default.createElement("path", {
|
|
1140
|
+
strokeLinecap: "round",
|
|
1141
|
+
strokeLinejoin: "round",
|
|
1142
|
+
strokeWidth: 2,
|
|
1143
|
+
d: "M19 9l-7 7-7-7"
|
|
1144
|
+
}))), React__default.createElement("div", {
|
|
1145
|
+
id: "framework-modal",
|
|
1146
|
+
className: "hidden absolute bottom-full left-0 mb-1 w-80 bg-white border border-gray-200 rounded-lg shadow-lg z-50 p-4"
|
|
1147
|
+
}, React__default.createElement("div", {
|
|
1148
|
+
className: "space-y-2"
|
|
1149
|
+
}, React__default.createElement("div", {
|
|
1150
|
+
className: "flex items-center justify-between p-3 hover:bg-gray-50 rounded cursor-pointer border border-blue-300 bg-blue-50"
|
|
1151
|
+
}, React__default.createElement("div", {
|
|
1152
|
+
className: "flex items-center space-x-3"
|
|
1153
|
+
}, React__default.createElement("div", {
|
|
1154
|
+
className: "w-8 h-8 bg-purple-100 rounded flex items-center justify-center"
|
|
1155
|
+
}, "\u269B\uFE0F"), React__default.createElement("div", null, React__default.createElement("div", {
|
|
1156
|
+
className: "text-sm font-medium"
|
|
1157
|
+
}, "Next.js"), React__default.createElement("div", {
|
|
1158
|
+
className: "text-xs text-gray-500"
|
|
1159
|
+
}, "React + Next.js 15 with Shadcn UI"))), React__default.createElement("svg", {
|
|
1160
|
+
className: "w-4 h-4 text-blue-500",
|
|
1161
|
+
fill: "currentColor",
|
|
1162
|
+
viewBox: "0 0 20 20"
|
|
1163
|
+
}, React__default.createElement("path", {
|
|
1164
|
+
fillRule: "evenodd",
|
|
1165
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
1166
|
+
clipRule: "evenodd"
|
|
1167
|
+
}))), React__default.createElement("div", {
|
|
1168
|
+
className: "flex items-center p-3 hover:bg-gray-50 rounded cursor-pointer"
|
|
1169
|
+
}, React__default.createElement("div", {
|
|
1170
|
+
className: "flex items-center space-x-3"
|
|
1171
|
+
}, React__default.createElement("div", {
|
|
1172
|
+
className: "w-8 h-8 bg-green-100 rounded flex items-center justify-center"
|
|
1173
|
+
}, "\uD83D\uDC9A"), React__default.createElement("div", null, React__default.createElement("div", {
|
|
1174
|
+
className: "text-sm font-medium"
|
|
1175
|
+
}, "Vue.js"), React__default.createElement("div", {
|
|
1176
|
+
className: "text-xs text-gray-500"
|
|
1177
|
+
}, "Vue 3 + Nuxt 3 with Tailwind CSS")))), React__default.createElement("div", {
|
|
1178
|
+
className: "flex items-center p-3 hover:bg-gray-50 rounded cursor-pointer"
|
|
1179
|
+
}, React__default.createElement("div", {
|
|
1180
|
+
className: "flex items-center space-x-3"
|
|
1181
|
+
}, React__default.createElement("div", {
|
|
1182
|
+
className: "w-8 h-8 bg-blue-100 rounded flex items-center justify-center"
|
|
1183
|
+
}, "\u269B\uFE0F"), React__default.createElement("div", null, React__default.createElement("div", {
|
|
1184
|
+
className: "text-sm font-medium"
|
|
1185
|
+
}, "React"), React__default.createElement("div", {
|
|
1186
|
+
className: "text-xs text-gray-500"
|
|
1187
|
+
}, "React 18 + Vite with TypeScript")))), React__default.createElement("div", {
|
|
1188
|
+
className: "flex items-center p-3 hover:bg-gray-50 rounded cursor-pointer"
|
|
1189
|
+
}, React__default.createElement("div", {
|
|
1190
|
+
className: "flex items-center space-x-3"
|
|
1191
|
+
}, React__default.createElement("div", {
|
|
1192
|
+
className: "w-8 h-8 bg-red-100 rounded flex items-center justify-center"
|
|
1193
|
+
}, "\uD83C\uDD70\uFE0F"), React__default.createElement("div", null, React__default.createElement("div", {
|
|
1194
|
+
className: "text-sm font-medium"
|
|
1195
|
+
}, "Angular"), React__default.createElement("div", {
|
|
1196
|
+
className: "text-xs text-gray-500"
|
|
1197
|
+
}, "Angular 17 + Material Design")))), React__default.createElement("div", {
|
|
1198
|
+
className: "flex items-center p-3 hover:bg-gray-50 rounded cursor-pointer"
|
|
1199
|
+
}, React__default.createElement("div", {
|
|
1200
|
+
className: "flex items-center space-x-3"
|
|
1201
|
+
}, React__default.createElement("div", {
|
|
1202
|
+
className: "w-8 h-8 bg-orange-100 rounded flex items-center justify-center"
|
|
1203
|
+
}, "\uD83D\uDD25"), React__default.createElement("div", null, React__default.createElement("div", {
|
|
1204
|
+
className: "text-sm font-medium"
|
|
1205
|
+
}, "Svelte"), React__default.createElement("div", {
|
|
1206
|
+
className: "text-xs text-gray-500"
|
|
1207
|
+
}, "SvelteKit + TailwindCSS"))))))), React__default.createElement("div", {
|
|
1208
|
+
className: "flex-1 relative"
|
|
1209
|
+
}, React__default.createElement("button", {
|
|
1210
|
+
type: "button",
|
|
1211
|
+
className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-md bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-left pr-10",
|
|
1212
|
+
onClick: () => {
|
|
1213
|
+
const modal = document.getElementById('ai-model-modal');
|
|
1214
|
+
if (modal) {
|
|
1215
|
+
modal.classList.toggle('hidden');
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
}, "\uD83E\uDDE0 Claude 3.5 Sonnet"), React__default.createElement("div", {
|
|
1219
|
+
className: "absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"
|
|
1220
|
+
}, React__default.createElement("svg", {
|
|
1221
|
+
className: "w-4 h-4 text-gray-400",
|
|
1222
|
+
fill: "none",
|
|
1223
|
+
stroke: "currentColor",
|
|
1224
|
+
viewBox: "0 0 24 24"
|
|
1225
|
+
}, React__default.createElement("path", {
|
|
1226
|
+
strokeLinecap: "round",
|
|
1227
|
+
strokeLinejoin: "round",
|
|
1228
|
+
strokeWidth: 2,
|
|
1229
|
+
d: "M19 9l-7 7-7-7"
|
|
1230
|
+
}))), React__default.createElement("div", {
|
|
1231
|
+
id: "ai-model-modal",
|
|
1232
|
+
className: "hidden absolute bottom-full left-0 mb-1 w-72 bg-white border border-gray-200 rounded-lg shadow-lg z-50 p-4"
|
|
1233
|
+
}, React__default.createElement("div", {
|
|
1234
|
+
className: "space-y-3"
|
|
1235
|
+
}, React__default.createElement("div", {
|
|
1236
|
+
id: "claude-models",
|
|
1237
|
+
className: "space-y-2"
|
|
1238
|
+
}, React__default.createElement("div", {
|
|
1239
|
+
className: "flex items-center justify-between p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1240
|
+
}, React__default.createElement("div", {
|
|
1241
|
+
className: "flex items-center space-x-3"
|
|
1242
|
+
}, React__default.createElement("div", {
|
|
1243
|
+
className: "w-6 h-6 bg-orange-100 rounded flex items-center justify-center"
|
|
1244
|
+
}, "\uD83E\uDDE0"), React__default.createElement("span", {
|
|
1245
|
+
className: "text-sm font-medium"
|
|
1246
|
+
}, "Claude 3.5 Sonnet")), React__default.createElement("svg", {
|
|
1247
|
+
className: "w-4 h-4 text-blue-500",
|
|
1248
|
+
fill: "currentColor",
|
|
1249
|
+
viewBox: "0 0 20 20"
|
|
1250
|
+
}, React__default.createElement("path", {
|
|
1251
|
+
fillRule: "evenodd",
|
|
1252
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
1253
|
+
clipRule: "evenodd"
|
|
1254
|
+
}))), React__default.createElement("div", {
|
|
1255
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1256
|
+
}, React__default.createElement("div", {
|
|
1257
|
+
className: "flex items-center space-x-3"
|
|
1258
|
+
}, React__default.createElement("div", {
|
|
1259
|
+
className: "w-6 h-6 bg-orange-100 rounded flex items-center justify-center"
|
|
1260
|
+
}, "\uD83E\uDDE0"), React__default.createElement("span", {
|
|
1261
|
+
className: "text-sm"
|
|
1262
|
+
}, "Claude 3.5 Haiku"))), React__default.createElement("div", {
|
|
1263
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1264
|
+
}, React__default.createElement("div", {
|
|
1265
|
+
className: "flex items-center space-x-3"
|
|
1266
|
+
}, React__default.createElement("div", {
|
|
1267
|
+
className: "w-6 h-6 bg-orange-100 rounded flex items-center justify-center"
|
|
1268
|
+
}, "\uD83E\uDDE0"), React__default.createElement("span", {
|
|
1269
|
+
className: "text-sm"
|
|
1270
|
+
}, "Claude 3 Opus"))), React__default.createElement("div", {
|
|
1271
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1272
|
+
}, React__default.createElement("div", {
|
|
1273
|
+
className: "flex items-center space-x-3"
|
|
1274
|
+
}, React__default.createElement("div", {
|
|
1275
|
+
className: "w-6 h-6 bg-orange-100 rounded flex items-center justify-center"
|
|
1276
|
+
}, "\uD83E\uDDE0"), React__default.createElement("span", {
|
|
1277
|
+
className: "text-sm"
|
|
1278
|
+
}, "Claude 3 Sonnet"))), React__default.createElement("div", {
|
|
1279
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1280
|
+
}, React__default.createElement("div", {
|
|
1281
|
+
className: "flex items-center space-x-3"
|
|
1282
|
+
}, React__default.createElement("div", {
|
|
1283
|
+
className: "w-6 h-6 bg-orange-100 rounded flex items-center justify-center"
|
|
1284
|
+
}, "\uD83E\uDDE0"), React__default.createElement("span", {
|
|
1285
|
+
className: "text-sm"
|
|
1286
|
+
}, "Claude 3 Haiku")))), React__default.createElement("div", {
|
|
1287
|
+
id: "openai-models",
|
|
1288
|
+
className: "space-y-2 hidden"
|
|
1289
|
+
}, React__default.createElement("div", {
|
|
1290
|
+
className: "flex items-center justify-between p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1291
|
+
}, React__default.createElement("div", {
|
|
1292
|
+
className: "flex items-center space-x-3"
|
|
1293
|
+
}, React__default.createElement("div", {
|
|
1294
|
+
className: "w-6 h-6 bg-green-100 rounded flex items-center justify-center"
|
|
1295
|
+
}, "\uD83E\uDD16"), React__default.createElement("span", {
|
|
1296
|
+
className: "text-sm font-medium"
|
|
1297
|
+
}, "GPT-4o")), React__default.createElement("svg", {
|
|
1298
|
+
className: "w-4 h-4 text-blue-500",
|
|
1299
|
+
fill: "currentColor",
|
|
1300
|
+
viewBox: "0 0 20 20"
|
|
1301
|
+
}, React__default.createElement("path", {
|
|
1302
|
+
fillRule: "evenodd",
|
|
1303
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
1304
|
+
clipRule: "evenodd"
|
|
1305
|
+
}))), React__default.createElement("div", {
|
|
1306
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1307
|
+
}, React__default.createElement("div", {
|
|
1308
|
+
className: "flex items-center space-x-3"
|
|
1309
|
+
}, React__default.createElement("div", {
|
|
1310
|
+
className: "w-6 h-6 bg-green-100 rounded flex items-center justify-center"
|
|
1311
|
+
}, "\uD83E\uDD16"), React__default.createElement("span", {
|
|
1312
|
+
className: "text-sm"
|
|
1313
|
+
}, "GPT-4o mini"))), React__default.createElement("div", {
|
|
1314
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1315
|
+
}, React__default.createElement("div", {
|
|
1316
|
+
className: "flex items-center space-x-3"
|
|
1317
|
+
}, React__default.createElement("div", {
|
|
1318
|
+
className: "w-6 h-6 bg-green-100 rounded flex items-center justify-center"
|
|
1319
|
+
}, "\uD83E\uDD16"), React__default.createElement("span", {
|
|
1320
|
+
className: "text-sm"
|
|
1321
|
+
}, "GPT-4 Turbo"))), React__default.createElement("div", {
|
|
1322
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1323
|
+
}, React__default.createElement("div", {
|
|
1324
|
+
className: "flex items-center space-x-3"
|
|
1325
|
+
}, React__default.createElement("div", {
|
|
1326
|
+
className: "w-6 h-6 bg-green-100 rounded flex items-center justify-center"
|
|
1327
|
+
}, "\uD83E\uDD16"), React__default.createElement("span", {
|
|
1328
|
+
className: "text-sm"
|
|
1329
|
+
}, "GPT-4"))), React__default.createElement("div", {
|
|
1330
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1331
|
+
}, React__default.createElement("div", {
|
|
1332
|
+
className: "flex items-center space-x-3"
|
|
1333
|
+
}, React__default.createElement("div", {
|
|
1334
|
+
className: "w-6 h-6 bg-green-100 rounded flex items-center justify-center"
|
|
1335
|
+
}, "\uD83E\uDD16"), React__default.createElement("span", {
|
|
1336
|
+
className: "text-sm"
|
|
1337
|
+
}, "o1"))), React__default.createElement("div", {
|
|
1338
|
+
className: "flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"
|
|
1339
|
+
}, React__default.createElement("div", {
|
|
1340
|
+
className: "flex items-center space-x-3"
|
|
1341
|
+
}, React__default.createElement("div", {
|
|
1342
|
+
className: "w-6 h-6 bg-green-100 rounded flex items-center justify-center"
|
|
1343
|
+
}, "\uD83E\uDD16"), React__default.createElement("span", {
|
|
1344
|
+
className: "text-sm"
|
|
1345
|
+
}, "o1-mini")))), React__default.createElement("div", {
|
|
1346
|
+
className: "flex gap-2 pt-2 border-t border-gray-100"
|
|
1347
|
+
}, React__default.createElement("button", {
|
|
1348
|
+
id: "openai-btn",
|
|
1349
|
+
className: "flex-1 px-3 py-2 border border-gray-300 text-gray-700 text-sm rounded-md hover:bg-gray-50 transition-colors",
|
|
1350
|
+
onClick: () => {
|
|
1351
|
+
document.getElementById('claude-models')?.classList.add('hidden');
|
|
1352
|
+
document.getElementById('openai-models')?.classList.remove('hidden');
|
|
1353
|
+
document.getElementById('openai-btn')?.classList.add('bg-blue-500', 'text-white');
|
|
1354
|
+
document.getElementById('openai-btn')?.classList.remove('border-gray-300', 'text-gray-700');
|
|
1355
|
+
document.getElementById('anthropic-btn')?.classList.remove('bg-blue-500', 'text-white');
|
|
1356
|
+
document.getElementById('anthropic-btn')?.classList.add('border-gray-300', 'text-gray-700');
|
|
1357
|
+
}
|
|
1358
|
+
}, "OpenAI"), React__default.createElement("button", {
|
|
1359
|
+
id: "anthropic-btn",
|
|
1360
|
+
className: "flex-1 px-3 py-2 bg-blue-500 text-white text-sm rounded-md hover:bg-blue-600 transition-colors",
|
|
1361
|
+
onClick: () => {
|
|
1362
|
+
document.getElementById('openai-models')?.classList.add('hidden');
|
|
1363
|
+
document.getElementById('claude-models')?.classList.remove('hidden');
|
|
1364
|
+
document.getElementById('anthropic-btn')?.classList.add('bg-blue-500', 'text-white');
|
|
1365
|
+
document.getElementById('anthropic-btn')?.classList.remove('border-gray-300', 'text-gray-700');
|
|
1366
|
+
document.getElementById('openai-btn')?.classList.remove('bg-blue-500', 'text-white');
|
|
1367
|
+
document.getElementById('openai-btn')?.classList.add('border-gray-300', 'text-gray-700');
|
|
1368
|
+
}
|
|
1369
|
+
}, "Anthropic"))))), React__default.createElement("div", {
|
|
1370
|
+
className: "flex-1 relative"
|
|
1371
|
+
}, React__default.createElement("button", {
|
|
1372
|
+
type: "button",
|
|
1373
|
+
className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-md bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-left pr-10",
|
|
1374
|
+
onClick: () => {
|
|
1375
|
+
const modal = document.getElementById('api-key-modal');
|
|
1376
|
+
if (modal) {
|
|
1377
|
+
modal.classList.toggle('hidden');
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
}, "API Key \u2022\u2022\u2022\u2022"), React__default.createElement("div", {
|
|
1381
|
+
className: "absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"
|
|
1382
|
+
}, React__default.createElement("svg", {
|
|
1383
|
+
className: "w-4 h-4 text-gray-400",
|
|
1384
|
+
fill: "none",
|
|
1385
|
+
stroke: "currentColor",
|
|
1386
|
+
viewBox: "0 0 24 24"
|
|
1387
|
+
}, React__default.createElement("path", {
|
|
1388
|
+
strokeLinecap: "round",
|
|
1389
|
+
strokeLinejoin: "round",
|
|
1390
|
+
strokeWidth: 2,
|
|
1391
|
+
d: "M19 9l-7 7-7-7"
|
|
1392
|
+
}))), React__default.createElement("div", {
|
|
1393
|
+
id: "api-key-modal",
|
|
1394
|
+
className: "hidden"
|
|
1395
|
+
}, React__default.createElement("div", {
|
|
1396
|
+
className: "fixed inset-0 bg-opacity-50 z-[9998]",
|
|
1397
|
+
onClick: () => {
|
|
1398
|
+
const modal = document.getElementById('api-key-modal');
|
|
1399
|
+
if (modal) {
|
|
1400
|
+
modal.classList.add('hidden');
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
}), React__default.createElement("div", {
|
|
1404
|
+
className: "fixed w-80 bg-white border border-gray-200 rounded-lg shadow-lg z-[9999] p-4",
|
|
1405
|
+
style: {
|
|
1406
|
+
position: 'fixed',
|
|
1407
|
+
left: '50%',
|
|
1408
|
+
top: '50%',
|
|
1409
|
+
transform: 'translate(-50%, -50%)',
|
|
1410
|
+
zIndex: 9999
|
|
1411
|
+
}
|
|
1412
|
+
}, React__default.createElement("div", {
|
|
1413
|
+
className: "flex justify-between items-center mb-4"
|
|
1414
|
+
}, React__default.createElement("h3", {
|
|
1415
|
+
className: "text-lg font-semibold text-gray-900"
|
|
1416
|
+
}, "API Key Settings"), React__default.createElement("button", {
|
|
1417
|
+
type: "button",
|
|
1418
|
+
className: "text-gray-400 hover:text-gray-600 transition-colors",
|
|
1419
|
+
onClick: () => {
|
|
1420
|
+
const modal = document.getElementById('api-key-modal');
|
|
1421
|
+
if (modal) {
|
|
1422
|
+
modal.classList.add('hidden');
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
}, React__default.createElement("svg", {
|
|
1426
|
+
className: "w-5 h-5",
|
|
1427
|
+
fill: "none",
|
|
1428
|
+
stroke: "currentColor",
|
|
1429
|
+
viewBox: "0 0 24 24"
|
|
1430
|
+
}, React__default.createElement("path", {
|
|
1431
|
+
strokeLinecap: "round",
|
|
1432
|
+
strokeLinejoin: "round",
|
|
1433
|
+
strokeWidth: 2,
|
|
1434
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
1435
|
+
})))), React__default.createElement("div", {
|
|
1436
|
+
className: "space-y-4"
|
|
1437
|
+
}, React__default.createElement("div", null, React__default.createElement("label", {
|
|
1438
|
+
className: "block text-sm font-medium text-gray-700 mb-2"
|
|
1439
|
+
}, "API Key"), React__default.createElement("div", {
|
|
1440
|
+
className: "relative"
|
|
1441
|
+
}, React__default.createElement("input", {
|
|
1442
|
+
type: "password",
|
|
1443
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
1444
|
+
className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent pr-10"
|
|
1445
|
+
}), React__default.createElement("button", {
|
|
1446
|
+
type: "button",
|
|
1447
|
+
className: "absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600",
|
|
1448
|
+
onClick: e => {
|
|
1449
|
+
const input = e.currentTarget.previousElementSibling;
|
|
1450
|
+
if (input) {
|
|
1451
|
+
input.type = input.type === 'password' ? 'text' : 'password';
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
}, React__default.createElement("svg", {
|
|
1455
|
+
className: "w-4 h-4",
|
|
1456
|
+
fill: "none",
|
|
1457
|
+
stroke: "currentColor",
|
|
1458
|
+
viewBox: "0 0 24 24"
|
|
1459
|
+
}, React__default.createElement("path", {
|
|
1460
|
+
strokeLinecap: "round",
|
|
1461
|
+
strokeLinejoin: "round",
|
|
1462
|
+
strokeWidth: 2,
|
|
1463
|
+
d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
|
1464
|
+
}), React__default.createElement("path", {
|
|
1465
|
+
strokeLinecap: "round",
|
|
1466
|
+
strokeLinejoin: "round",
|
|
1467
|
+
strokeWidth: 2,
|
|
1468
|
+
d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
|
|
1469
|
+
}))))), React__default.createElement("div", null, React__default.createElement("h3", {
|
|
1470
|
+
className: "text-sm font-medium text-gray-700 mb-3"
|
|
1471
|
+
}, "Parameters"), React__default.createElement("div", {
|
|
1472
|
+
className: "space-y-2"
|
|
1473
|
+
}, React__default.createElement("div", {
|
|
1474
|
+
className: "flex justify-between items-center"
|
|
1475
|
+
}, React__default.createElement("span", {
|
|
1476
|
+
className: "text-sm text-gray-600"
|
|
1477
|
+
}, "Output tokens"), React__default.createElement("span", {
|
|
1478
|
+
className: "text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded"
|
|
1479
|
+
}, "Auto")), React__default.createElement("div", {
|
|
1480
|
+
className: "flex justify-between items-center"
|
|
1481
|
+
}, React__default.createElement("span", {
|
|
1482
|
+
className: "text-sm text-gray-600"
|
|
1483
|
+
}, "Temperature"), React__default.createElement("span", {
|
|
1484
|
+
className: "text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded"
|
|
1485
|
+
}, "Auto")), React__default.createElement("div", {
|
|
1486
|
+
className: "flex justify-between items-center"
|
|
1487
|
+
}, React__default.createElement("span", {
|
|
1488
|
+
className: "text-sm text-gray-600"
|
|
1489
|
+
}, "Top P"), React__default.createElement("span", {
|
|
1490
|
+
className: "text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded"
|
|
1491
|
+
}, "Auto")), React__default.createElement("div", {
|
|
1492
|
+
className: "flex justify-between items-center"
|
|
1493
|
+
}, React__default.createElement("span", {
|
|
1494
|
+
className: "text-sm text-gray-600"
|
|
1495
|
+
}, "Top K"), React__default.createElement("span", {
|
|
1496
|
+
className: "text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded"
|
|
1497
|
+
}, "Auto")), React__default.createElement("div", {
|
|
1498
|
+
className: "flex justify-between items-center"
|
|
1499
|
+
}, React__default.createElement("span", {
|
|
1500
|
+
className: "text-sm text-gray-600"
|
|
1501
|
+
}, "Frequence penalty"), React__default.createElement("span", {
|
|
1502
|
+
className: "text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded"
|
|
1503
|
+
}, "Auto")), React__default.createElement("div", {
|
|
1504
|
+
className: "flex justify-between items-center"
|
|
1505
|
+
}, React__default.createElement("span", {
|
|
1506
|
+
className: "text-sm text-gray-600"
|
|
1507
|
+
}, "Presence penalty"), React__default.createElement("span", {
|
|
1508
|
+
className: "text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded"
|
|
1509
|
+
}, "Auto")))))))))), React__default.createElement(MessageInputComponent, {
|
|
1510
|
+
channelId: channelId,
|
|
1511
|
+
handleSend: handleSend,
|
|
1512
|
+
placeholder: "Message"
|
|
1513
|
+
})));
|
|
1514
|
+
});
|
|
1515
|
+
// Display names for debugging
|
|
1516
|
+
Inbox.displayName = 'Inbox';
|
|
1517
|
+
ContentComponent.displayName = 'ContentComponent';
|
|
1518
|
+
MessagesComponent.displayName = 'MessagesComponent';
|
|
1519
|
+
RightSidebarWrapper.displayName = 'RightSidebarWrapper';
|
|
1520
|
+
var Inbox$1 = React__default.memo(Inbox);export{Inbox$1 as default};//# sourceMappingURL=AiInbox.js.map
|