@ethora/chat-component-rn 26.5.16 → 26.5.17

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 (50) hide show
  1. package/lib/commonjs/components/MainComponents/ReduxWrapper.js +4 -0
  2. package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
  3. package/lib/commonjs/context/xmppProvider.js +4 -0
  4. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  5. package/lib/commonjs/helpers/historyPreloadScheduler.js +118 -113
  6. package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
  7. package/lib/commonjs/hooks/useChatFonts.js +137 -0
  8. package/lib/commonjs/hooks/useChatFonts.js.map +1 -0
  9. package/lib/commonjs/hooks/useUnreadMessagesCounter.js +4 -2
  10. package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
  11. package/lib/commonjs/main.js +7 -0
  12. package/lib/commonjs/main.js.map +1 -1
  13. package/lib/commonjs/roomStore/roomsSlice.js +9 -1
  14. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  15. package/lib/module/components/MainComponents/ReduxWrapper.js +4 -0
  16. package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
  17. package/lib/module/context/xmppProvider.js +5 -1
  18. package/lib/module/context/xmppProvider.js.map +1 -1
  19. package/lib/module/helpers/historyPreloadScheduler.js +119 -114
  20. package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
  21. package/lib/module/hooks/useChatFonts.js +132 -0
  22. package/lib/module/hooks/useChatFonts.js.map +1 -0
  23. package/lib/module/hooks/useUnreadMessagesCounter.js +4 -2
  24. package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
  25. package/lib/module/main.js +2 -0
  26. package/lib/module/main.js.map +1 -1
  27. package/lib/module/roomStore/roomsSlice.js +7 -0
  28. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  29. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
  30. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  31. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  32. package/lib/typescript/hooks/useChatFonts.d.ts +23 -0
  33. package/lib/typescript/hooks/useChatFonts.d.ts.map +1 -0
  34. package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts +1 -0
  35. package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts.map +1 -1
  36. package/lib/typescript/main.d.ts +2 -1
  37. package/lib/typescript/main.d.ts.map +1 -1
  38. package/lib/typescript/roomStore/roomsSlice.d.ts +3 -1
  39. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  40. package/lib/typescript/types/types.d.ts +39 -0
  41. package/lib/typescript/types/types.d.ts.map +1 -1
  42. package/package.json +5 -1
  43. package/src/components/MainComponents/ReduxWrapper.tsx +4 -0
  44. package/src/context/xmppProvider.tsx +5 -0
  45. package/src/helpers/historyPreloadScheduler.ts +7 -1
  46. package/src/hooks/useChatFonts.ts +153 -0
  47. package/src/hooks/useUnreadMessagesCounter.ts +5 -2
  48. package/src/main.ts +4 -0
  49. package/src/roomStore/roomsSlice.ts +11 -0
  50. package/src/types/types.ts +41 -0
@@ -10,6 +10,7 @@ interface UnreadMessagesStats {
10
10
  hasUnread: boolean;
11
11
  totalCount: number;
12
12
  unreadByRoom: UnreadMessagesMap;
13
+ isLoading: boolean;
13
14
  }
14
15
 
15
16
  export const useUnreadMessagesCounter = (): UnreadMessagesStats => {
@@ -26,11 +27,12 @@ export const useUnreadMessagesCounter = (): UnreadMessagesStats => {
26
27
  // so non-rooms dispatches still don't trigger a re-render.)
27
28
  const subscribe = (callback: () => void) => store.subscribe(callback);
28
29
 
29
- const rooms = useSyncExternalStore(
30
+ const roomsState = useSyncExternalStore(
30
31
  subscribe,
31
- () => store.getState().rooms.rooms
32
+ () => store.getState().rooms
32
33
  );
33
34
 
35
+ const rooms = roomsState.rooms;
34
36
  const unreadByRoom: UnreadMessagesMap = {};
35
37
  let totalCount = 0;
36
38
 
@@ -46,6 +48,7 @@ export const useUnreadMessagesCounter = (): UnreadMessagesStats => {
46
48
  hasUnread: totalCount > 0,
47
49
  totalCount,
48
50
  unreadByRoom,
51
+ isLoading: !!roomsState.isUnreadSyncing || !!roomsState.isLoading,
49
52
  };
50
53
  };
51
54
 
package/src/main.ts CHANGED
@@ -32,6 +32,8 @@ export { useChatRoomFocus } from './hooks/useChatRoomFocus';
32
32
  export { logoutService } from './hooks/useLogout';
33
33
  export { useQRCodeChat, handleQRChatId } from './hooks/useQRCodeChatHandler';
34
34
  export { resendMessage } from './utils/resendMessage';
35
+ // Font loader — exposed so hosts can also load the font outside <Chat> if needed.
36
+ export { useChatFonts } from './hooks/useChatFonts';
35
37
 
36
38
  // Public types — needed so consumers can type their `config` prop and
37
39
  // any event handlers they pass in.
@@ -43,4 +45,6 @@ export type {
43
45
  User,
44
46
  ConfigUser,
45
47
  MessageProps,
48
+ TypographyConfig,
49
+ RNFontSource,
46
50
  } from './types/types';
@@ -96,6 +96,7 @@ export interface RoomMessagesState {
96
96
  editAction?: EditAction;
97
97
  isLoading: boolean;
98
98
  loadingText?: string;
99
+ isUnreadSyncing?: boolean;
99
100
  usersSet?: Record<string, any>;
100
101
  pendingNotificationJid?: string | null;
101
102
  // Server-side read markers fetched from the XMPP private store
@@ -111,6 +112,7 @@ const initialState: RoomMessagesState = {
111
112
  activeRoomJID: null,
112
113
  visibleRoomJID: null,
113
114
  isLoading: false,
115
+ isUnreadSyncing: false,
114
116
  editAction: {
115
117
  isEdit: false,
116
118
  roomJid: '',
@@ -362,6 +364,7 @@ const reducers = {
362
364
  state.rooms = {};
363
365
  state.visibleRoomJID = null;
364
366
  state.privateStoreMarkers = {};
367
+ state.isUnreadSyncing = false;
365
368
  },
366
369
  setComposing(
367
370
  state: WritableDraft<RoomMessagesState>,
@@ -386,6 +389,12 @@ const reducers = {
386
389
  state.isLoading = loading;
387
390
  state.loadingText = loadingText;
388
391
  },
392
+ setUnreadSyncing: (
393
+ state: WritableDraft<RoomMessagesState>,
394
+ action: PayloadAction<boolean>
395
+ ) => {
396
+ state.isUnreadSyncing = action.payload;
397
+ },
389
398
  setLastViewedTimestamp: (
390
399
  state: WritableDraft<RoomMessagesState>,
391
400
  action: PayloadAction<{ chatJID: string; timestamp: number }>
@@ -538,6 +547,7 @@ const reducers = {
538
547
  state.activeRoomJID = null;
539
548
  state.visibleRoomJID = null;
540
549
  state.isLoading = false;
550
+ state.isUnreadSyncing = false;
541
551
  state.privateStoreMarkers = {};
542
552
  },
543
553
  setActiveMessage: (
@@ -729,6 +739,7 @@ export const {
729
739
  editRoomMessage,
730
740
  setComposing,
731
741
  setIsLoading,
742
+ setUnreadSyncing,
732
743
  setLastViewedTimestamp,
733
744
  applyPrivateStoreMarkers,
734
745
  setRoomNoMessages,
@@ -223,6 +223,45 @@ export interface PartialRoomWithMandatoryKeys {
223
223
  pinned?: boolean;
224
224
  }
225
225
 
226
+ /**
227
+ * A custom font to register at runtime via `expo-font`. On React Native a
228
+ * font must be loaded before it can be referenced by name — there is no
229
+ * web-style runtime `@font-face`. Each weight is typically its own file and
230
+ * its own family name (RN does not synthesise weights reliably).
231
+ *
232
+ * `source` accepts what `Font.loadAsync` accepts: a remote URL string (e.g. a
233
+ * hosted e-Ukraine `.ttf`), or a bundled asset via `require('./e-Ukraine.ttf')`.
234
+ */
235
+ export interface RNFontSource {
236
+ /** Family name used in text styles, e.g. "e-Ukraine" or "e-Ukraine-Medium". */
237
+ family: string;
238
+ /** Remote URL string or `require(...)` module for the font file. */
239
+ source: string | number;
240
+ }
241
+
242
+ /**
243
+ * Font configuration for the chat UI. When omitted, the component keeps the
244
+ * platform's default system font, so existing integrations are unaffected.
245
+ *
246
+ * Provide `fonts` for the SDK to load via expo-font, then set `fontFamily` to
247
+ * the family the chat should render in. If the host already loaded the font
248
+ * itself (e.g. via `@expo-google-fonts/*` or its own `useFonts`), pass only
249
+ * `fontFamily` and leave `fonts` empty.
250
+ */
251
+ export interface TypographyConfig {
252
+ /** Family applied across the chat UI. Must be loaded (via `fonts` or by the host). */
253
+ fontFamily?: string;
254
+ /** Optional per-weight families, used where the chat renders bolder text. */
255
+ weightFamilies?: {
256
+ regular?: string;
257
+ medium?: string;
258
+ semibold?: string;
259
+ bold?: string;
260
+ };
261
+ /** Fonts for the SDK to load with expo-font before applying `fontFamily`. */
262
+ fonts?: RNFontSource[];
263
+ }
264
+
226
265
  export interface IConfig {
227
266
  // ----- identity / network -----
228
267
  appId?: string;
@@ -232,6 +271,8 @@ export interface IConfig {
232
271
 
233
272
  // ----- theming -----
234
273
  colors?: { primary: string; secondary: string };
274
+ /** Configurable font family / weights for the chat UI. See TypographyConfig. */
275
+ typography?: TypographyConfig;
235
276
  messageColor?: {
236
277
  backgroundMessage: string;
237
278
  backgroundMessageUser: string;