stream-chat-react-native-core 5.12.1 → 5.13.0-beta.1

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 (33) hide show
  1. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +1 -1
  2. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  3. package/lib/commonjs/components/Chat/Chat.js +1 -4
  4. package/lib/commonjs/components/Chat/Chat.js.map +1 -1
  5. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js +1 -4
  6. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js.map +1 -1
  7. package/lib/commonjs/hooks/useStreami18n.js +17 -8
  8. package/lib/commonjs/hooks/useStreami18n.js.map +1 -1
  9. package/lib/commonjs/utils/Streami18n.js +78 -27
  10. package/lib/commonjs/utils/Streami18n.js.map +1 -1
  11. package/lib/commonjs/version.json +1 -1
  12. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +1 -1
  13. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  14. package/lib/module/components/Chat/Chat.js +1 -4
  15. package/lib/module/components/Chat/Chat.js.map +1 -1
  16. package/lib/module/contexts/overlayContext/OverlayProvider.js +1 -4
  17. package/lib/module/contexts/overlayContext/OverlayProvider.js.map +1 -1
  18. package/lib/module/hooks/useStreami18n.js +17 -8
  19. package/lib/module/hooks/useStreami18n.js.map +1 -1
  20. package/lib/module/utils/Streami18n.js +78 -27
  21. package/lib/module/utils/Streami18n.js.map +1 -1
  22. package/lib/module/version.json +1 -1
  23. package/lib/typescript/hooks/useStreami18n.d.ts +1 -4
  24. package/lib/typescript/utils/Streami18n.d.ts +13 -6
  25. package/package.json +1 -1
  26. package/src/__tests__/optimistic-update.test.js +2 -1
  27. package/src/components/ChannelList/__tests__/ChannelList.test.js +4 -2
  28. package/src/components/ChannelList/hooks/usePaginatedChannels.ts +6 -4
  29. package/src/components/Chat/Chat.tsx +1 -1
  30. package/src/contexts/overlayContext/OverlayProvider.tsx +1 -1
  31. package/src/hooks/useStreami18n.ts +21 -12
  32. package/src/utils/Streami18n.ts +66 -18
  33. package/src/version.json +1 -1
@@ -5,16 +5,12 @@ import { useIsMountedRef } from './useIsMountedRef';
5
5
  import type { TranslatorFunctions } from '../contexts/translationContext/TranslationContext';
6
6
  import { Streami18n } from '../utils/Streami18n';
7
7
 
8
- export const useStreami18n = ({
9
- i18nInstance,
10
- setTranslators,
11
- }: {
12
- setTranslators: React.Dispatch<React.SetStateAction<TranslatorFunctions>>;
13
- i18nInstance?: Streami18n;
14
- }) => {
8
+ export const useStreami18n = (
9
+ setTranslators: React.Dispatch<React.SetStateAction<TranslatorFunctions>>,
10
+ i18nInstance?: Streami18n,
11
+ ) => {
15
12
  const [loadingTranslators, setLoadingTranslators] = useState(true);
16
13
  const isMounted = useIsMountedRef();
17
- const i18nInstanceExists = !!i18nInstance;
18
14
  useEffect(() => {
19
15
  let streami18n: Streami18n;
20
16
 
@@ -24,15 +20,28 @@ export const useStreami18n = ({
24
20
  streami18n = new Streami18n({ language: 'en' });
25
21
  }
26
22
 
27
- streami18n.registerSetLanguageCallback((t: (key: string) => string) =>
28
- setTranslators((prevTranslator) => ({ ...prevTranslator, t })),
29
- );
23
+ const updateTFunction = (t: TranslatorFunctions['t']) => {
24
+ setTranslators((prevTranslator) => ({ ...prevTranslator, t }));
25
+ };
26
+
27
+ const { unsubscribe: unsubscribeOnLanguageChangeListener } =
28
+ streami18n.addOnLanguageChangeListener((t) => {
29
+ updateTFunction(t);
30
+ });
31
+ const { unsubscribe: unsubscribeOnTFuncOverrideListener } =
32
+ streami18n.addOnTFunctionOverrideListener((t) => {
33
+ updateTFunction(t);
34
+ });
30
35
  streami18n.getTranslators().then((translator) => {
31
36
  if (translator && isMounted.current) setTranslators(translator);
32
37
  });
33
38
 
34
39
  setLoadingTranslators(false);
35
- }, [i18nInstanceExists, i18nInstance]);
40
+ return () => {
41
+ unsubscribeOnTFuncOverrideListener();
42
+ unsubscribeOnLanguageChangeListener();
43
+ };
44
+ }, [i18nInstance]);
36
45
 
37
46
  return loadingTranslators;
38
47
  };
@@ -346,8 +346,20 @@ const defaultStreami18nOptions = {
346
346
  export class Streami18n {
347
347
  i18nInstance = i18n.createInstance();
348
348
  Dayjs = null;
349
- setLanguageCallback: (t: TFunction) => void = () => null;
350
349
  initialized = false;
350
+ /* this promise is used to prevent simultaneous calls to init (happens in Overlay and Chat) */
351
+ private waitForInitializing: Promise<void> | undefined;
352
+ /* This is the callback to be fired when the language is changed */
353
+ private onLanguageChangeListeners: ((t: TFunction) => void)[] = [];
354
+ /* This is the callback to be fired when the tFunc is overridden
355
+ * This is useful when a different i18n library needs to be used
356
+ * The SDK uses this in useStreami18n hook to set the tFunc in the context
357
+ */
358
+ private onTFunctionOverrideListeners: ((t: TFunction) => void)[] = [];
359
+ /* We need to queue the overridden tFunction
360
+ * if the tFunction is overridden before the SDK has initialized the translations
361
+ */
362
+ private queuedTFunctionOverride: TFunction | undefined;
351
363
 
352
364
  t: TFunction = (key: string) => key;
353
365
  tDateTimeParser: TDateTimeParser;
@@ -518,7 +530,7 @@ export class Streami18n {
518
530
  /**
519
531
  * Initializes the i18next instance with configuration (which enables natural language as default keys)
520
532
  */
521
- async init() {
533
+ private async init() {
522
534
  this.validateCurrentLanguage();
523
535
 
524
536
  try {
@@ -527,15 +539,17 @@ export class Streami18n {
527
539
  lng: this.currentLanguage,
528
540
  resources: this.translations,
529
541
  });
542
+ if (this.queuedTFunctionOverride) {
543
+ // special case where we have a override for tFunc before initialization
544
+ this.t = this.queuedTFunctionOverride;
545
+ this.queuedTFunctionOverride = undefined;
546
+ this.onTFunctionOverrideListeners.forEach((listener) => listener(this.t));
547
+ }
530
548
  this.initialized = true;
531
549
  } catch (error) {
532
550
  this.logger(`Something went wrong with init: ${JSON.stringify(error)}`);
533
551
  }
534
-
535
- return {
536
- t: this.t,
537
- tDateTimeParser: this.tDateTimeParser,
538
- };
552
+ this.waitForInitializing = undefined;
539
553
  }
540
554
 
541
555
  localeExists = (language: string) => {
@@ -571,16 +585,21 @@ export class Streami18n {
571
585
  */
572
586
  async getTranslators() {
573
587
  if (!this.initialized) {
574
- if (this.dayjsLocales[this.currentLanguage]) {
575
- this.addOrUpdateLocale(this.currentLanguage, this.dayjsLocales[this.currentLanguage]);
588
+ if (this.waitForInitializing) {
589
+ await this.waitForInitializing;
590
+ } else {
591
+ if (this.dayjsLocales[this.currentLanguage]) {
592
+ this.addOrUpdateLocale(this.currentLanguage, this.dayjsLocales[this.currentLanguage]);
593
+ }
594
+ const initPromise = this.init();
595
+ this.waitForInitializing = initPromise;
596
+ await initPromise;
576
597
  }
577
- return await this.init();
578
- } else {
579
- return {
580
- t: this.t,
581
- tDateTimeParser: this.tDateTimeParser,
582
- };
583
598
  }
599
+ return {
600
+ t: this.t,
601
+ tDateTimeParser: this.tDateTimeParser,
602
+ };
584
603
  }
585
604
 
586
605
  /**
@@ -631,6 +650,7 @@ export class Streami18n {
631
650
 
632
651
  /**
633
652
  * Changes the language.
653
+ * Note: if you are using overrideTFunction, you will need to call the override again after changing the language.
634
654
  */
635
655
  async setLanguage(language: string) {
636
656
  this.currentLanguage = language;
@@ -642,7 +662,8 @@ export class Streami18n {
642
662
  if (this.dayjsLocales[language]) {
643
663
  this.addOrUpdateLocale(this.currentLanguage, this.dayjsLocales[this.currentLanguage]);
644
664
  }
645
- this.setLanguageCallback(t);
665
+ this.t = t;
666
+ this.onLanguageChangeListeners.forEach((listener) => listener(t));
646
667
 
647
668
  return t;
648
669
  } catch (error) {
@@ -651,7 +672,34 @@ export class Streami18n {
651
672
  }
652
673
  }
653
674
 
654
- registerSetLanguageCallback(callback: (t: TFunction) => void) {
655
- this.setLanguageCallback = callback;
675
+ addOnLanguageChangeListener(callback: (t: TFunction) => void) {
676
+ this.onLanguageChangeListeners.push(callback);
677
+ return {
678
+ unsubscribe: () => {
679
+ this.onLanguageChangeListeners = this.onLanguageChangeListeners.filter(
680
+ (listener) => listener !== callback,
681
+ );
682
+ },
683
+ };
684
+ }
685
+
686
+ addOnTFunctionOverrideListener(callback: (t: TFunction) => void) {
687
+ this.onTFunctionOverrideListeners.push(callback);
688
+ return {
689
+ unsubscribe: () => {
690
+ this.onTFunctionOverrideListeners = this.onTFunctionOverrideListeners.filter(
691
+ (listener) => listener !== callback,
692
+ );
693
+ },
694
+ };
695
+ }
696
+
697
+ overrideTFunction(tFunction: TFunction) {
698
+ if (!this.initialized) {
699
+ this.queuedTFunctionOverride = tFunction;
700
+ } else {
701
+ this.t = tFunction;
702
+ this.onTFunctionOverrideListeners.forEach((listener) => listener(tFunction));
703
+ }
656
704
  }
657
705
  }
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "5.12.1"
2
+ "version": "5.13.0-beta.1"
3
3
  }