@webinex/chatify 1.0.0-rc2 → 1.0.1-rc3

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.
Files changed (273) hide show
  1. package/dist/css/chatify.css +183 -141
  2. package/dist/esm/index.js +1 -1
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/types/core/action.d.ts +110 -42
  5. package/dist/esm/types/core/client.d.ts +2 -1
  6. package/dist/esm/types/core/index.d.ts +11 -8
  7. package/dist/esm/types/core/models.d.ts +10 -4
  8. package/dist/esm/types/core/state.d.ts +36 -7
  9. package/dist/esm/types/core/useAddChatMutation.d.ts +2 -0
  10. package/dist/esm/types/core/useAddMemberMutation.d.ts +2 -0
  11. package/dist/esm/types/core/useFetchNextMutation.d.ts +3 -0
  12. package/dist/esm/types/core/useGetAccountsQuery.d.ts +1 -0
  13. package/dist/esm/types/core/useGetChatListQuery.d.ts +1 -0
  14. package/dist/{cjs/types/core/useChat.d.ts → esm/types/core/useGetChatQuery.d.ts} +1 -1
  15. package/dist/esm/types/core/useGetMessagesQuery.d.ts +4 -0
  16. package/dist/esm/types/core/useRemoveMemberMutation.d.ts +2 -0
  17. package/dist/esm/types/core/useSendMutation.d.ts +2 -0
  18. package/dist/esm/types/core/useUpdateChatNameMutation.d.ts +2 -0
  19. package/dist/esm/types/ui/AddChatButton.d.ts +2 -2
  20. package/dist/esm/types/ui/Avatar.d.ts +2 -2
  21. package/dist/esm/types/ui/ChatList/ChatList.d.ts +2 -0
  22. package/dist/esm/types/ui/ChatList/ChatListItemBox.d.ts +6 -0
  23. package/dist/esm/types/ui/ChatList/ChatListItemLastMessage.d.ts +3 -0
  24. package/dist/esm/types/ui/ChatList/ChatListItemLastMessageAuthor.d.ts +3 -0
  25. package/dist/esm/types/ui/ChatList/ChatListItemLastMessageContent.d.ts +3 -0
  26. package/dist/esm/types/ui/ChatList/ChatListItemName.d.ts +3 -0
  27. package/dist/esm/types/ui/ChatList/ChatListItemUnreadCount.d.ts +3 -0
  28. package/dist/esm/types/ui/ChatList/index.d.ts +7 -0
  29. package/dist/esm/types/ui/ChatName.d.ts +2 -2
  30. package/dist/esm/types/ui/ChatPanel/ChatBody.d.ts +5 -0
  31. package/dist/esm/types/ui/ChatPanel/ChatHeader.d.ts +5 -0
  32. package/dist/esm/types/ui/ChatPanel/ChatHeaderMembers.d.ts +5 -0
  33. package/dist/esm/types/ui/ChatPanel/ChatHeaderName.d.ts +5 -0
  34. package/dist/esm/types/ui/ChatPanel/ChatMembersButton.d.ts +5 -0
  35. package/dist/esm/types/ui/ChatPanel/ChatMembersPanel.d.ts +5 -0
  36. package/dist/esm/types/ui/ChatPanel/ChatPanel.d.ts +5 -0
  37. package/dist/esm/types/ui/ChatPanel/index.d.ts +6 -0
  38. package/dist/esm/types/ui/Chatify.d.ts +45 -23
  39. package/dist/esm/types/ui/CreateChatPanel/CreateChatForm.d.ts +11 -0
  40. package/dist/esm/types/ui/CreateChatPanel/CreateChatMemberInput.d.ts +5 -0
  41. package/dist/esm/types/ui/CreateChatPanel/CreateChatNameInput.d.ts +5 -0
  42. package/dist/esm/types/ui/CreateChatPanel/CreateChatPanel.d.ts +2 -0
  43. package/dist/esm/types/ui/CreateChatPanel/index.d.ts +4 -0
  44. package/dist/esm/types/ui/Icon.d.ts +13 -4
  45. package/dist/esm/types/ui/InputBox/InputBox.d.ts +2 -0
  46. package/dist/esm/types/ui/InputBox/InputFilesBox.d.ts +2 -0
  47. package/dist/esm/types/ui/InputBox/InputSubmitButtonBox.d.ts +5 -0
  48. package/dist/esm/types/ui/InputBox/InputTextBox.d.ts +7 -0
  49. package/dist/esm/types/ui/InputBox/index.d.ts +4 -0
  50. package/dist/esm/types/ui/Layout/Aside.d.ts +2 -0
  51. package/dist/esm/types/ui/Layout/Body.d.ts +2 -0
  52. package/dist/esm/types/ui/Layout/Footer.d.ts +2 -0
  53. package/dist/esm/types/ui/Layout/Header.d.ts +2 -0
  54. package/dist/esm/types/ui/Layout/Main.d.ts +2 -0
  55. package/dist/esm/types/ui/Layout/index.d.ts +5 -0
  56. package/dist/esm/types/ui/Message/MessageAuthor.d.ts +3 -0
  57. package/dist/esm/types/ui/Message/MessageBox.d.ts +6 -0
  58. package/dist/esm/types/ui/Message/MessageContent.d.ts +3 -0
  59. package/dist/esm/types/ui/Message/MessageInfoBox.d.ts +3 -0
  60. package/dist/esm/types/ui/Message/MessageRow.d.ts +6 -0
  61. package/dist/esm/types/ui/Message/MessageText.d.ts +3 -0
  62. package/dist/esm/types/ui/Message/index.d.ts +6 -0
  63. package/dist/esm/types/ui/MessageReadObserver.d.ts +6 -0
  64. package/dist/esm/types/ui/Next.d.ts +4 -0
  65. package/dist/esm/types/ui/SendingMessage/SendingMessageBox.d.ts +7 -0
  66. package/dist/esm/types/ui/SendingMessage/SendingMessageContent.d.ts +3 -0
  67. package/dist/esm/types/ui/SendingMessage/SendingMessageInfoBox.d.ts +3 -0
  68. package/dist/esm/types/ui/SendingMessage/SendingMessageText.d.ts +3 -0
  69. package/dist/esm/types/ui/SendingMessage/index.d.ts +4 -0
  70. package/dist/esm/types/ui/SystemMessage/SystemMessageBox.d.ts +6 -0
  71. package/dist/esm/types/ui/SystemMessage/SystemMessageRow.d.ts +9 -0
  72. package/dist/esm/types/ui/SystemMessage/index.d.ts +2 -0
  73. package/dist/esm/types/{util → ui}/customize.d.ts +2 -3
  74. package/dist/esm/types/ui/index.d.ts +6 -6
  75. package/dist/esm/types/ui/localizer.d.ts +5 -0
  76. package/dist/esm/types/util/index.d.ts +0 -1
  77. package/dist/index.d.ts +353 -142
  78. package/package.json +92 -90
  79. package/src/ChatifyContext.tsx +41 -41
  80. package/src/core/action.tsx +405 -319
  81. package/src/core/client.ts +143 -137
  82. package/src/core/index.ts +17 -14
  83. package/src/core/models.tsx +82 -75
  84. package/src/core/reducer.tsx +87 -86
  85. package/src/core/state.ts +92 -38
  86. package/src/core/useAddChatMutation.tsx +22 -0
  87. package/src/core/useAddMemberMutation.tsx +25 -0
  88. package/src/core/useFetchNextMutation.tsx +28 -0
  89. package/src/core/useGetAccountsQuery.tsx +33 -0
  90. package/src/core/useGetChatListQuery.tsx +33 -0
  91. package/src/core/useGetChatQuery.tsx +34 -0
  92. package/src/core/useGetMessagesQuery.tsx +35 -0
  93. package/src/core/useReadMonitor.tsx +32 -31
  94. package/src/core/useRemoveMemberMutation.tsx +23 -0
  95. package/src/core/useSendMutation.tsx +24 -0
  96. package/src/core/useSignalRMonitor.tsx +66 -52
  97. package/src/core/useUpdateChatNameMutation.tsx +23 -0
  98. package/src/index.ts +3 -3
  99. package/src/{ui/styles → styles}/aside.scss +94 -94
  100. package/src/styles/chat.scss +222 -0
  101. package/src/styles/index.scss +79 -0
  102. package/src/{ui/styles → styles}/keyframes.scss +14 -14
  103. package/src/{ui/styles → styles}/mixins.scss +20 -20
  104. package/src/styles/settings.scss +5 -0
  105. package/src/{ui/styles → styles}/variables.scss +10 -10
  106. package/src/ui/AddChatButton.tsx +15 -19
  107. package/src/ui/Avatar.tsx +18 -18
  108. package/src/ui/ChatList/ChatList.tsx +42 -0
  109. package/src/ui/ChatList/ChatListItemBox.tsx +22 -0
  110. package/src/ui/ChatList/ChatListItemLastMessage.tsx +13 -0
  111. package/src/ui/ChatList/ChatListItemLastMessageAuthor.tsx +20 -0
  112. package/src/ui/ChatList/ChatListItemLastMessageContent.tsx +21 -0
  113. package/src/ui/ChatList/ChatListItemName.tsx +13 -0
  114. package/src/ui/ChatList/ChatListItemUnreadCount.tsx +12 -0
  115. package/src/ui/ChatList/index.ts +7 -0
  116. package/src/ui/ChatName.tsx +10 -15
  117. package/src/ui/ChatPanel/ChatBody.tsx +44 -0
  118. package/src/ui/ChatPanel/ChatHeader.tsx +33 -0
  119. package/src/ui/{ChatHeaderMembers.tsx → ChatPanel/ChatHeaderMembers.tsx} +26 -30
  120. package/src/ui/ChatPanel/ChatHeaderName.tsx +67 -0
  121. package/src/ui/ChatPanel/ChatMembersButton.tsx +21 -0
  122. package/src/ui/ChatPanel/ChatMembersPanel.tsx +117 -0
  123. package/src/ui/ChatPanel/ChatPanel.tsx +27 -0
  124. package/src/ui/ChatPanel/index.ts +6 -0
  125. package/src/ui/Chatify.tsx +148 -106
  126. package/src/ui/CreateChatPanel/CreateChatForm.tsx +36 -0
  127. package/src/ui/CreateChatPanel/CreateChatMemberInput.tsx +66 -0
  128. package/src/ui/CreateChatPanel/CreateChatNameInput.tsx +25 -0
  129. package/src/ui/CreateChatPanel/CreateChatPanel.tsx +33 -0
  130. package/src/ui/CreateChatPanel/index.ts +4 -0
  131. package/src/ui/Icon.tsx +33 -21
  132. package/src/ui/InputBox/InputBox.tsx +38 -0
  133. package/src/ui/InputBox/InputFilesBox.tsx +9 -0
  134. package/src/ui/InputBox/InputSubmitButtonBox.tsx +17 -0
  135. package/src/ui/InputBox/InputTextBox.tsx +50 -0
  136. package/src/ui/InputBox/index.ts +4 -0
  137. package/src/ui/Layout/Aside.tsx +10 -0
  138. package/src/ui/Layout/Body.tsx +10 -0
  139. package/src/ui/Layout/Footer.tsx +3 -0
  140. package/src/ui/Layout/Header.tsx +10 -0
  141. package/src/ui/Layout/Main.tsx +15 -0
  142. package/src/ui/Layout/index.ts +5 -0
  143. package/src/ui/Message/MessageAuthor.tsx +13 -0
  144. package/src/ui/Message/MessageBox.tsx +20 -0
  145. package/src/ui/Message/MessageContent.tsx +13 -0
  146. package/src/ui/Message/MessageInfoBox.tsx +25 -0
  147. package/src/ui/Message/MessageRow.tsx +24 -0
  148. package/src/ui/Message/MessageText.tsx +7 -0
  149. package/src/ui/Message/index.ts +6 -0
  150. package/src/ui/MessageReadObserver.tsx +45 -0
  151. package/src/ui/MessageSkeleton.tsx +19 -19
  152. package/src/ui/Next.tsx +48 -0
  153. package/src/ui/SendingMessage/SendingMessageBox.tsx +16 -0
  154. package/src/ui/SendingMessage/SendingMessageContent.tsx +13 -0
  155. package/src/ui/SendingMessage/SendingMessageInfoBox.tsx +13 -0
  156. package/src/ui/SendingMessage/SendingMessageText.tsx +7 -0
  157. package/src/ui/SendingMessage/index.ts +4 -0
  158. package/src/ui/SystemMessage/SystemMessageBox.tsx +20 -0
  159. package/src/ui/SystemMessage/SystemMessageRow.tsx +43 -0
  160. package/src/ui/SystemMessage/index.ts +2 -0
  161. package/src/{util → ui}/customize.tsx +45 -45
  162. package/src/ui/index.ts +11 -11
  163. package/src/ui/localizer.tsx +80 -68
  164. package/src/util/index.ts +2 -3
  165. package/src/util/uniqBy.tsx +17 -17
  166. package/src/util/uniqId.tsx +3 -3
  167. package/dist/cjs/index.js +0 -2
  168. package/dist/cjs/index.js.map +0 -1
  169. package/dist/cjs/types/ChatifyContext.d.ts +0 -11
  170. package/dist/cjs/types/core/action.d.ts +0 -76
  171. package/dist/cjs/types/core/client.d.ts +0 -35
  172. package/dist/cjs/types/core/index.d.ts +0 -14
  173. package/dist/cjs/types/core/models.d.ts +0 -64
  174. package/dist/cjs/types/core/reducer.d.ts +0 -11
  175. package/dist/cjs/types/core/state.d.ts +0 -25
  176. package/dist/cjs/types/core/useAccounts.d.ts +0 -1
  177. package/dist/cjs/types/core/useAddChat.d.ts +0 -2
  178. package/dist/cjs/types/core/useAddMember.d.ts +0 -2
  179. package/dist/cjs/types/core/useAddMessage.d.ts +0 -5
  180. package/dist/cjs/types/core/useChatList.d.ts +0 -1
  181. package/dist/cjs/types/core/useLoadMore.d.ts +0 -3
  182. package/dist/cjs/types/core/useMessages.d.ts +0 -15
  183. package/dist/cjs/types/core/useMutation.d.ts +0 -12
  184. package/dist/cjs/types/core/useQuery.d.ts +0 -7
  185. package/dist/cjs/types/core/useReadMonitor.d.ts +0 -1
  186. package/dist/cjs/types/core/useRemoveMember.d.ts +0 -2
  187. package/dist/cjs/types/core/useSignalRMonitor.d.ts +0 -2
  188. package/dist/cjs/types/index.d.ts +0 -3
  189. package/dist/cjs/types/ui/AddChat.d.ts +0 -1
  190. package/dist/cjs/types/ui/AddChatButton.d.ts +0 -2
  191. package/dist/cjs/types/ui/Aside.d.ts +0 -1
  192. package/dist/cjs/types/ui/Avatar.d.ts +0 -6
  193. package/dist/cjs/types/ui/Chat.d.ts +0 -4
  194. package/dist/cjs/types/ui/ChatBody.d.ts +0 -4
  195. package/dist/cjs/types/ui/ChatHeader.d.ts +0 -4
  196. package/dist/cjs/types/ui/ChatHeaderMembers.d.ts +0 -5
  197. package/dist/cjs/types/ui/ChatHeaderSettingsButton.d.ts +0 -5
  198. package/dist/cjs/types/ui/ChatListItem.d.ts +0 -11
  199. package/dist/cjs/types/ui/ChatName.d.ts +0 -5
  200. package/dist/cjs/types/ui/ChatSettings.d.ts +0 -1
  201. package/dist/cjs/types/ui/Chatify.d.ts +0 -49
  202. package/dist/cjs/types/ui/Footer.d.ts +0 -2
  203. package/dist/cjs/types/ui/Header.d.ts +0 -2
  204. package/dist/cjs/types/ui/Icon.d.ts +0 -7
  205. package/dist/cjs/types/ui/InputForm.d.ts +0 -1
  206. package/dist/cjs/types/ui/LoadMore.d.ts +0 -4
  207. package/dist/cjs/types/ui/Main.d.ts +0 -1
  208. package/dist/cjs/types/ui/Message.d.ts +0 -18
  209. package/dist/cjs/types/ui/MessageSkeleton.d.ts +0 -4
  210. package/dist/cjs/types/ui/SendingMessage.d.ts +0 -10
  211. package/dist/cjs/types/ui/SystemMessage.d.ts +0 -8
  212. package/dist/cjs/types/ui/index.d.ts +0 -11
  213. package/dist/cjs/types/ui/localizer.d.ts +0 -32
  214. package/dist/cjs/types/util/customize.d.ts +0 -12
  215. package/dist/cjs/types/util/index.d.ts +0 -3
  216. package/dist/cjs/types/util/uniqBy.d.ts +0 -1
  217. package/dist/cjs/types/util/uniqId.d.ts +0 -1
  218. package/dist/esm/types/core/useAccounts.d.ts +0 -1
  219. package/dist/esm/types/core/useAddChat.d.ts +0 -2
  220. package/dist/esm/types/core/useAddMember.d.ts +0 -2
  221. package/dist/esm/types/core/useAddMessage.d.ts +0 -5
  222. package/dist/esm/types/core/useChat.d.ts +0 -3
  223. package/dist/esm/types/core/useChatList.d.ts +0 -1
  224. package/dist/esm/types/core/useLoadMore.d.ts +0 -3
  225. package/dist/esm/types/core/useMessages.d.ts +0 -15
  226. package/dist/esm/types/core/useMutation.d.ts +0 -12
  227. package/dist/esm/types/core/useQuery.d.ts +0 -7
  228. package/dist/esm/types/core/useRemoveMember.d.ts +0 -2
  229. package/dist/esm/types/ui/AddChat.d.ts +0 -1
  230. package/dist/esm/types/ui/Aside.d.ts +0 -1
  231. package/dist/esm/types/ui/Chat.d.ts +0 -4
  232. package/dist/esm/types/ui/ChatBody.d.ts +0 -4
  233. package/dist/esm/types/ui/ChatHeader.d.ts +0 -4
  234. package/dist/esm/types/ui/ChatHeaderMembers.d.ts +0 -5
  235. package/dist/esm/types/ui/ChatHeaderSettingsButton.d.ts +0 -5
  236. package/dist/esm/types/ui/ChatListItem.d.ts +0 -11
  237. package/dist/esm/types/ui/ChatSettings.d.ts +0 -1
  238. package/dist/esm/types/ui/Footer.d.ts +0 -2
  239. package/dist/esm/types/ui/Header.d.ts +0 -2
  240. package/dist/esm/types/ui/InputForm.d.ts +0 -1
  241. package/dist/esm/types/ui/LoadMore.d.ts +0 -4
  242. package/dist/esm/types/ui/Main.d.ts +0 -1
  243. package/dist/esm/types/ui/Message.d.ts +0 -18
  244. package/dist/esm/types/ui/SendingMessage.d.ts +0 -10
  245. package/dist/esm/types/ui/SystemMessage.d.ts +0 -8
  246. package/src/core/useAccounts.tsx +0 -11
  247. package/src/core/useAddChat.tsx +0 -12
  248. package/src/core/useAddMember.tsx +0 -12
  249. package/src/core/useAddMessage.tsx +0 -40
  250. package/src/core/useChat.tsx +0 -12
  251. package/src/core/useChatList.tsx +0 -10
  252. package/src/core/useLoadMore.tsx +0 -42
  253. package/src/core/useMessages.tsx +0 -23
  254. package/src/core/useMutation.tsx +0 -48
  255. package/src/core/useQuery.tsx +0 -45
  256. package/src/core/useRemoveMember.tsx +0 -12
  257. package/src/ui/AddChat.tsx +0 -55
  258. package/src/ui/Aside.tsx +0 -41
  259. package/src/ui/Chat.tsx +0 -26
  260. package/src/ui/ChatBody.tsx +0 -43
  261. package/src/ui/ChatHeader.tsx +0 -33
  262. package/src/ui/ChatHeaderSettingsButton.tsx +0 -26
  263. package/src/ui/ChatListItem.tsx +0 -101
  264. package/src/ui/ChatSettings.tsx +0 -59
  265. package/src/ui/Footer.tsx +0 -7
  266. package/src/ui/Header.tsx +0 -14
  267. package/src/ui/InputForm.tsx +0 -51
  268. package/src/ui/LoadMore.tsx +0 -40
  269. package/src/ui/Main.tsx +0 -16
  270. package/src/ui/Message.tsx +0 -118
  271. package/src/ui/SendingMessage.tsx +0 -50
  272. package/src/ui/SystemMessage.tsx +0 -32
  273. package/src/ui/styles/index.scss +0 -248
@@ -1,48 +0,0 @@
1
- import { useCallback } from 'react';
2
- import { useDispatch, useSelect, useStateRef } from './reducer';
3
- import { MutationState, State } from './state';
4
-
5
- export interface MutationApi<TResult> {
6
- promise: Promise<TResult>;
7
- state: State;
8
- updateState: (mutation: (state: State) => State) => void;
9
- }
10
-
11
- export interface UseMutationArgs<TResult = unknown, TArgs = void> {
12
- key: string;
13
- queryFn: (args: TArgs) => Promise<TResult>;
14
- onQueryStarted?: (args: TArgs, api: MutationApi<TResult>) => void;
15
- }
16
-
17
- const INITIAL_MUTATION_STATE: MutationState = { isFetching: false, error: undefined };
18
-
19
- export function useMutation<TResult = unknown, TArgs = void>(args: UseMutationArgs<TResult, TArgs>) {
20
- const { key, queryFn, onQueryStarted } = args;
21
- const dispatch = useDispatch();
22
- const state = useStateRef();
23
- const mutationState = useSelect((x) => x.mutation[args.key], []);
24
-
25
- const invoke = useCallback((args: TArgs) => {
26
- dispatch({ type: 'mutation_fetch', data: { key } });
27
- const promise = queryFn(args);
28
-
29
- promise
30
- .then(() => {
31
- dispatch({ type: 'mutation_resolve', data: { key } });
32
- })
33
- .catch((error) => dispatch({ type: 'mutation_reject', data: { key, error } }));
34
-
35
- onQueryStarted &&
36
- onQueryStarted(args, {
37
- promise,
38
- state: state.current,
39
- updateState: (mutation: (state: State) => State) => {
40
- dispatch({ type: 'update', data: { mutation } });
41
- },
42
- });
43
-
44
- // eslint-disable-next-line react-hooks/exhaustive-deps
45
- }, []);
46
-
47
- return [invoke, mutationState ?? INITIAL_MUTATION_STATE] as const;
48
- }
@@ -1,45 +0,0 @@
1
- import { useEffect } from 'react';
2
- import { useDispatch, useSelect, useStateRef } from './reducer';
3
- import { QueryState, State } from './state';
4
-
5
- interface UseQueryArgs<TData> {
6
- key: string;
7
- queryFn: () => Promise<TData>;
8
- }
9
-
10
- const INITIAL_QUERY_STATE: QueryState<any> = {
11
- uninitialized: false,
12
- isFetching: true,
13
- data: undefined,
14
- error: undefined,
15
- };
16
-
17
- function select<TData>(state: State, key: string): QueryState<TData> | undefined {
18
- return (state.query as any)[key];
19
- }
20
-
21
- function useQueryState<TData>(key: string): QueryState<TData> | undefined {
22
- return useSelect((x) => select<TData>(x, key), []);
23
- }
24
-
25
- export function useQuery<TData>(args: UseQueryArgs<TData>): QueryState<TData> {
26
- const { key, queryFn } = args;
27
- const state = useStateRef();
28
- const dispatch = useDispatch();
29
- const queryState = useQueryState<TData>(args.key);
30
-
31
- useEffect(() => {
32
- if (select(state.current, key)) {
33
- return;
34
- }
35
-
36
- dispatch({ type: 'query_fetch', data: { key } });
37
- queryFn()
38
- .then((data) => dispatch({ type: 'query_resolve', data: { key, data: data as any } }))
39
- .catch((error) => dispatch({ type: 'query_reject', data: { key, error } }));
40
-
41
- // eslint-disable-next-line react-hooks/exhaustive-deps
42
- }, []);
43
-
44
- return queryState ?? INITIAL_QUERY_STATE;
45
- }
@@ -1,12 +0,0 @@
1
- import { useClient } from '../ChatifyContext';
2
- import { RemoveMemberRequest } from './models';
3
- import { useMutation } from './useMutation';
4
-
5
- export function useRemoveMember() {
6
- const client = useClient();
7
-
8
- return useMutation({
9
- key: 'remove-member',
10
- queryFn: (args: RemoveMemberRequest) => client.removeMember(args),
11
- });
12
- }
@@ -1,55 +0,0 @@
1
- import { Button, Form, Input, Select } from 'antd';
2
- import { useAccounts, useAddChat } from '../core';
3
- import { useCallback, useMemo } from 'react';
4
- import { uniqId } from '../util';
5
- import { useLocalizer } from './localizer';
6
-
7
- type FormValue = {
8
- name: string;
9
- members: string[];
10
- };
11
-
12
- export function AddChat() {
13
- const [add, { isFetching: adding }] = useAddChat();
14
- const { data: accounts, isFetching } = useAccounts();
15
- const localizer = useLocalizer();
16
- const options = useMemo(() => accounts?.map((x) => ({ value: x.id, label: x.name })), [accounts]);
17
-
18
- const onSubmit = useCallback(
19
- (value: FormValue) =>
20
- add({
21
- name: value.name,
22
- members: value.members,
23
- requestId: uniqId(),
24
- }),
25
- [add],
26
- );
27
-
28
- return (
29
- <div className="wxchtf-add-chat">
30
- <h3>{localizer.addChat.title()}</h3>
31
- <Form onFinish={onSubmit} layout="vertical" disabled={adding}>
32
- <Form.Item
33
- name="name"
34
- label={localizer.addChat.name.label()}
35
- rules={[
36
- { required: true, message: localizer.addChat.name.required() },
37
- { max: 250, message: localizer.addChat.name.max250() },
38
- ]}
39
- >
40
- <Input />
41
- </Form.Item>
42
- <Form.Item
43
- name="members"
44
- label={localizer.addChat.members.label()}
45
- rules={[{ required: true, message: localizer.addChat.members.required() }]}
46
- >
47
- <Select mode="multiple" loading={isFetching} options={options} />
48
- </Form.Item>
49
- <Button loading={adding} type="primary" block htmlType="submit">
50
- {localizer.addChat.submitBtn()}
51
- </Button>
52
- </Form>
53
- </div>
54
- );
55
- }
package/src/ui/Aside.tsx DELETED
@@ -1,41 +0,0 @@
1
- import { Menu, MenuProps } from 'antd';
2
- import { useCallback, useEffect, useMemo } from 'react';
3
- import type { MenuItemType } from 'antd/es/menu/hooks/useItems';
4
- import { useChatList, useDispatch, useSelect } from '../core';
5
- import { ChatListItemBox } from './ChatListItem';
6
-
7
- export function Aside() {
8
- const activeChatId = useSelect((x) => x.ui.chatId, []);
9
- const dispatch = useDispatch();
10
- const selected = useMemo(() => (activeChatId ? [activeChatId] : []), [activeChatId]);
11
-
12
- const onSelect = useCallback(
13
- (info: Parameters<NonNullable<MenuProps['onSelect']>>[0]) =>
14
- dispatch({ type: 'chat_open', data: { chatId: info.selectedKeys[0] } }),
15
- [dispatch],
16
- );
17
-
18
- const { data: chats } = useChatList();
19
-
20
- const items = useMemo<MenuItemType[]>(() => {
21
- if (!chats) {
22
- return [];
23
- }
24
-
25
- return chats.map((x) => ({ key: x.id, label: <ChatListItemBox chat={x} /> }));
26
- }, [chats]);
27
-
28
- useEffect(() => {
29
- if (!activeChatId && chats && chats.length > 0) {
30
- dispatch({ type: 'chat_open', data: { chatId: chats[0].id } });
31
- }
32
-
33
- // eslint-disable-next-line react-hooks/exhaustive-deps
34
- }, [chats, dispatch]);
35
-
36
- return (
37
- <div className="wxchtf-aside">
38
- {chats && <Menu className="wxchtf-chats" selectedKeys={selected} onSelect={onSelect} items={items} />}
39
- </div>
40
- );
41
- }
package/src/ui/Chat.tsx DELETED
@@ -1,26 +0,0 @@
1
- import { ChatHeader } from './ChatHeader';
2
- import { ChatBody } from './ChatBody';
3
- import { InputForm } from './InputForm';
4
- import { useChat } from '../core';
5
- import { useMe } from '../ChatifyContext';
6
-
7
- export interface ChatProps {
8
- id: string;
9
- }
10
-
11
- export function Chat(props: ChatProps) {
12
- const { id } = props;
13
- const me = useMe();
14
- const { data: chat } = useChat({ chatId: id });
15
- const isMember = chat?.members.map((x) => x.id).includes(me) === true;
16
-
17
- return (
18
- <>
19
- <div className="wxchtf-chat">
20
- <ChatHeader id={id} />
21
- <ChatBody id={id} />
22
- </div>
23
- {isMember && <InputForm />}
24
- </>
25
- );
26
- }
@@ -1,43 +0,0 @@
1
- import { MessageBox } from './Message';
2
- import { useMessages } from '../core';
3
- import { LoadMore } from './LoadMore';
4
- import { SendingMessage } from './SendingMessage';
5
- import { SystemMessage } from './SystemMessage';
6
- import { MessageSkeleton } from './MessageSkeleton';
7
-
8
- export interface ChatBodyProps {
9
- id: string;
10
- }
11
-
12
- export function ChatBody(props: ChatBodyProps) {
13
- const { id } = props;
14
- const { data: messages } = useMessages({ chatId: id });
15
-
16
- return (
17
- <div className="wxchtf-chat-body">
18
- {!messages && <MessageSkeleton count={5} />}
19
- {messages?.map((x, index) => {
20
- if (x.type === 'message' && x.sentBy.id === 'chatify::system') {
21
- return <SystemMessage text={x.text} sentAt={x.sentAt} />;
22
- }
23
-
24
- switch (x.type) {
25
- case 'message': {
26
- return <MessageBox message={x} key={x.id} />;
27
- }
28
-
29
- case 'sending': {
30
- return <SendingMessage key={x.requestId} text={x.text} files={x.files} />;
31
- }
32
-
33
- case 'more': {
34
- return <LoadMore key={index} chatId={id} />;
35
- }
36
-
37
- default:
38
- return null;
39
- }
40
- })}
41
- </div>
42
- );
43
- }
@@ -1,33 +0,0 @@
1
- import { useChat, useSelect, ChatListItem } from '../core';
2
- import { Col, Row, Space } from 'antd';
3
- import { ChatHeaderMembers } from './ChatHeaderMembers';
4
- import { ChatSettingsButton } from './ChatHeaderSettingsButton';
5
- import { ChatName } from './ChatName';
6
-
7
- export interface ChatHeaderProps {
8
- id: string;
9
- }
10
-
11
- export function ChatHeader(props: ChatHeaderProps) {
12
- const { id } = props;
13
- const { data: chat } = useChat({ chatId: id });
14
- const chatListItem = useSelect(
15
- (x) => x.query['chat-list'].data?.find((x: ChatListItem) => x.id === id),
16
- [id],
17
- );
18
- const name = chat?.name ?? chatListItem?.name;
19
-
20
- return (
21
- <div className="wxchtf-chat-header">
22
- <Row justify="space-between" align="middle">
23
- <Col className="wxchtf-chat-name">{name && <ChatName name={name} />}</Col>
24
- <Col className="wxchtf-chat-members">
25
- <Space align="center">
26
- <ChatHeaderMembers id={id} />
27
- <ChatSettingsButton id={id} />
28
- </Space>
29
- </Col>
30
- </Row>
31
- </div>
32
- );
33
- }
@@ -1,26 +0,0 @@
1
- import { useDispatch } from '../core';
2
- import { Button } from 'antd';
3
- import { SettingOutlined } from '@ant-design/icons';
4
- import { FC, useCallback } from 'react';
5
- import { customize } from '../util';
6
-
7
- export interface ChatSettingsButtonProps {
8
- id: string;
9
- }
10
-
11
- const _ChatSettingsButton: FC<ChatSettingsButtonProps> = (props) => {
12
- const { id } = props;
13
- const dispatch = useDispatch();
14
- const onSettingsClick = useCallback(
15
- () => dispatch({ type: 'chat_settings_open', data: { chatId: id } }),
16
-
17
- // eslint-disable-next-line react-hooks/exhaustive-deps
18
- [dispatch],
19
- );
20
-
21
- return <Button onClick={onSettingsClick} type="link" icon={<SettingOutlined />} />;
22
- };
23
-
24
- _ChatSettingsButton.displayName = 'ChatSettingsButton';
25
-
26
- export const ChatSettingsButton = customize('ChatSettingsButton', _ChatSettingsButton);
@@ -1,101 +0,0 @@
1
- import { useLocalizer } from './localizer';
2
- import { formatSystemMessage } from './SystemMessage';
3
- import { Avatar } from './Avatar';
4
- import { ChatName } from './ChatName';
5
- import { ChatListItem as ChatListItemModel } from '../core';
6
- import { FC } from 'react';
7
- import { customize } from '../util';
8
-
9
- export interface ChatListItemBoxProps {
10
- chat: ChatListItemModel;
11
- }
12
-
13
- const _ChatListItemName: FC<ChatListItemBoxProps> = (props) => {
14
- const { name } = props.chat;
15
-
16
- return (
17
- <div className="wxchtf-chat-name">
18
- <ChatName name={name} />
19
- </div>
20
- );
21
- };
22
-
23
- _ChatListItemName.displayName = 'ChatListItemName';
24
-
25
- export const ChatListItemName = customize('ChatListItemName', _ChatListItemName);
26
-
27
- const _ChatListItemUnreadCount: FC<ChatListItemBoxProps> = (props) => {
28
- const { unreadCount } = props.chat;
29
-
30
- if (unreadCount <= 0) {
31
- return null;
32
- }
33
-
34
- return <div className="wxchtf-unread-count">{unreadCount}</div>;
35
- };
36
-
37
- _ChatListItemUnreadCount.displayName = 'ChatListItemUnreadCount';
38
-
39
- export const ChatListItemUnreadCount = customize('ChatListItemUnreadCount', _ChatListItemUnreadCount);
40
-
41
- const _ChatListItemLastMessage: FC<ChatListItemBoxProps> = (props) => {
42
- return (
43
- <div className="wxchtf-chat-last">
44
- <ChatListItemLastMessageAuthor {...props} />
45
- <ChatListItemLastMessageContent {...props} />
46
- </div>
47
- );
48
- };
49
-
50
- _ChatListItemLastMessage.displayName = 'ChatListItemLastMessage';
51
-
52
- export const ChatListItemLastMessage = customize('ChatListItemLastMessage', _ChatListItemLastMessage);
53
-
54
- export const ChatListItemLastMessageAuthor = customize<FC<ChatListItemBoxProps>, string>(
55
- 'ChatListItemLastMessageAuthor',
56
- (props) => {
57
- const { message } = props.chat;
58
-
59
- if (message.sentBy.id === 'chatify::system') {
60
- return null;
61
- }
62
-
63
- return (
64
- <div className="wxchtf-chat-last-author">
65
- <Avatar account={message.sentBy} /> {message.sentBy.name}
66
- </div>
67
- );
68
- },
69
- );
70
-
71
- export const ChatListItemLastMessageContent = customize<FC<ChatListItemBoxProps>, string>(
72
- 'ChatListItemLastMessageContent',
73
- (props) => {
74
- const { message } = props.chat;
75
- const localizer = useLocalizer();
76
-
77
- return (
78
- <div className="wxchtf-chat-last-message">
79
- {message.sentBy.id === 'chatify::system'
80
- ? formatSystemMessage(localizer, message.text)
81
- : message.text}
82
- </div>
83
- );
84
- },
85
- );
86
-
87
- const _ChatListItemBox: FC<ChatListItemBoxProps> = (props) => {
88
- const { message } = props.chat;
89
-
90
- return (
91
- <div className={'wxchtf-chat' + (!message.read ? ' --unread' : '')}>
92
- <ChatListItemName {...props} />
93
- <ChatListItemUnreadCount {...props} />
94
- <ChatListItemLastMessage {...props} />
95
- </div>
96
- );
97
- };
98
-
99
- _ChatListItemBox.displayName = 'ChatListItemBox';
100
-
101
- export const ChatListItemBox = customize('ChatListItemBox', _ChatListItemBox);
@@ -1,59 +0,0 @@
1
- import { Button, Col, List, Row, Select } from 'antd';
2
- import { Account, useAccounts, useAddMember, useChat, useSelect } from '../core';
3
- import { CloseOutlined } from '@ant-design/icons';
4
- import { useRemoveMember } from '../core';
5
- import { useCallback, useMemo } from 'react';
6
-
7
- function Member(props: { account: Account; chatId: string }) {
8
- const { account, chatId } = props;
9
- const [remove] = useRemoveMember();
10
-
11
- const onRemoveClick = useCallback(
12
- () => remove({ chatId, accountId: account.id, deleteHistory: false }),
13
- [remove, chatId, account.id],
14
- );
15
-
16
- return (
17
- <List.Item>
18
- {account.name} <Button onClick={onRemoveClick} type="link" icon={<CloseOutlined />} />
19
- </List.Item>
20
- );
21
- }
22
-
23
- export function ChatSettings() {
24
- const [chatId] = useSelect((x) => [x.ui.chatId], []);
25
- const { data: chat } = useChat({ chatId: chatId! });
26
- const [add] = useAddMember();
27
- const { data: accounts } = useAccounts();
28
- const accountOptions = useMemo(() => accounts?.map((x) => ({ value: x.id, label: x.name })), [accounts]);
29
-
30
- const onAdd = useCallback(
31
- (id: string) => add({ chatId: chatId!, accountId: id, withHistory: true }),
32
- [add, chatId],
33
- );
34
-
35
- if (!chat) {
36
- return null;
37
- }
38
-
39
- return (
40
- <div className="wxchtf-chat-settings">
41
- <Row justify="space-between">
42
- <Col>
43
- <h3 className="wxchtf-title">{chat.name}</h3>
44
- </Col>
45
- <Col>
46
- <Button type="link" icon={<CloseOutlined />} />
47
- </Col>
48
- </Row>
49
- <h4>Members</h4>
50
- <List
51
- dataSource={chat.members}
52
- rowKey="id"
53
- renderItem={(account) => <Member account={account} chatId={chatId!} />}
54
- />
55
-
56
- <Select<string> style={{ width: '350px' }} options={accountOptions} value={null} onSelect={onAdd} />
57
- </div>
58
- );
59
- }
package/src/ui/Footer.tsx DELETED
@@ -1,7 +0,0 @@
1
- import { FC } from 'react';
2
- import { customize } from '../util';
3
-
4
- const _Footer: FC = () => <div className="wxchtf-footer"></div>;
5
- _Footer.displayName = 'Footer';
6
-
7
- export const Footer = customize('Footer', _Footer);
package/src/ui/Header.tsx DELETED
@@ -1,14 +0,0 @@
1
- import { FC } from 'react';
2
- import { AddChatButton } from './AddChatButton';
3
- import { customize } from '../util';
4
-
5
- const _Header: FC = () => {
6
- return (
7
- <div className="wxchtf-header">
8
- <AddChatButton />
9
- </div>
10
- );
11
- };
12
-
13
- _Header.displayName = 'Header';
14
- export const Header = customize('Header', _Header);
@@ -1,51 +0,0 @@
1
- import { Button, Input } from 'antd';
2
- import { useCallback, useState } from 'react';
3
- import isHotkey from 'is-hotkey';
4
- import { useAddMessage } from '../core/useAddMessage';
5
- import { uniqId } from '../util';
6
- import { useSelect } from '../core';
7
- import { useLocalizer } from './localizer';
8
- import { Icon } from './Icon';
9
-
10
- const isSend = isHotkey('ctrl+enter');
11
-
12
- export function InputForm() {
13
- const chatId = useSelect((x) => x.ui.chatId!, []);
14
- const [add] = useAddMessage({ chatId });
15
- const [text, setText] = useState('');
16
- const localizer = useLocalizer();
17
-
18
- const onSend = useCallback(() => {
19
- setText('');
20
- add({ text: text, files: [], requestId: uniqId() });
21
-
22
- // eslint-disable-next-line react-hooks/exhaustive-deps
23
- }, [chatId, text]);
24
-
25
- return (
26
- <div className="wxchtf-input-form">
27
- <div className="wxchtf-input-box">
28
- <div className="wxchtf-add-files-box">
29
- <Button type="link" icon={<Icon type="attach" />} className="wxchtf-add-files-btn" />
30
- </div>
31
- <div className="wxchtf-text-input-box">
32
- <Input.TextArea
33
- value={text}
34
- onChange={(e) => setText(e.target.value)}
35
- autoSize={{ maxRows: 5 }}
36
- className="wxchtf-text-input-textarea"
37
- placeholder={localizer.input.placeholder()}
38
- onKeyDown={(event) => {
39
- if (isSend(event)) {
40
- onSend();
41
- }
42
- }}
43
- />
44
- </div>
45
- <div className="wxchtf-submit-btn-box">
46
- <Button onClick={onSend} type="link" icon={<Icon type="send" />} className="wxchtf-submit-btn" />
47
- </div>
48
- </div>
49
- </div>
50
- );
51
- }
@@ -1,40 +0,0 @@
1
- import { useEffect, useMemo, useRef, useState } from 'react';
2
- import { useLoadMore } from '../core';
3
- import { MessageSkeleton } from './MessageSkeleton';
4
-
5
- export interface LoadMoreProps {
6
- chatId: string;
7
- }
8
-
9
- export function LoadMore(props: LoadMoreProps) {
10
- const { chatId } = props;
11
- const [loadMore, { isFetching }] = useLoadMore({ chatId });
12
- const [intersecting, setIntersecting] = useState(false);
13
- const ref = useRef<HTMLDivElement | null>(null);
14
-
15
- const observer = useMemo(
16
- () => new IntersectionObserver(([entry]) => setIntersecting((prev) => prev || entry.isIntersecting)),
17
- [],
18
- );
19
-
20
- useEffect(() => {
21
- observer.observe(ref.current!);
22
- return () => observer.disconnect();
23
- }, [observer]);
24
-
25
- useEffect(() => {
26
- if (!intersecting) {
27
- return;
28
- }
29
-
30
- loadMore();
31
-
32
- // eslint-disable-next-line react-hooks/exhaustive-deps
33
- }, [intersecting]);
34
-
35
- if (isFetching) {
36
- return <MessageSkeleton count={4} />;
37
- }
38
-
39
- return <div ref={ref} />;
40
- }
package/src/ui/Main.tsx DELETED
@@ -1,16 +0,0 @@
1
- import { useSelect } from '../core';
2
- import { AddChat } from './AddChat';
3
- import { Chat } from './Chat';
4
- import { ChatSettings } from './ChatSettings';
5
-
6
- export function Main() {
7
- const { view, chatId } = useSelect((x) => ({ view: x.ui.view, chatId: x.ui.chatId }), []);
8
-
9
- return (
10
- <div className="wxchtf-main">
11
- {view === 'chat' && chatId && <Chat id={chatId} key={chatId} />}
12
- {view === 'new-chat' && <AddChat />}
13
- {view === 'chat-settings' && <ChatSettings />}
14
- </div>
15
- );
16
- }