@umituz/react-native-settings 5.2.26 → 5.2.28

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-settings",
3
- "version": "5.2.26",
3
+ "version": "5.2.28",
4
4
  "description": "Complete settings hub for React Native apps - consolidated package with settings, localization, about, legal, appearance, feedback, FAQs, rating, and gamification",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * Translation Hook
3
3
  *
4
- * Provides translation function with proper language change reactivity
5
- * - React i18next integration for automatic language change detection
6
- * - Auto-namespace detection from dot notation
7
- * - Type-safe translation function
4
+ * Provides translation function with proper language change reactivity.
5
+ * Keys use dot notation only: "namespace.key.subkey"
6
+ * The first segment before the dot is the i18next namespace.
8
7
  */
9
8
 
10
9
  import { useCallback } from 'react';
11
10
  import { useTranslation } from 'react-i18next';
12
11
  import i18n from '../config/i18n';
12
+ import { devWarn } from '../../../../utils/devUtils';
13
13
 
14
14
  export interface TranslationOptions {
15
15
  count?: number;
@@ -19,12 +19,11 @@ export interface TranslationOptions {
19
19
  }
20
20
 
21
21
  /**
22
- * Hook for translation functionality
23
- * Uses react-i18next for automatic language change reactivity
22
+ * Hook for translation functionality.
23
+ * Uses react-i18next for automatic language change reactivity.
24
24
  *
25
- * Supports both formats:
26
- * - t('namespace:key.subkey') - explicit namespace
27
- * - t('namespace.key.subkey') - auto-detected namespace (first segment before dot)
25
+ * Keys must use dot notation: t('namespace.key.subkey')
26
+ * The first segment is the i18next namespace: t('common.ok'), t('settings.title')
28
27
  */
29
28
  export const useTranslationFunction = () => {
30
29
  const { t: i18nextT, ready } = useTranslation(undefined, { i18n });
@@ -38,50 +37,20 @@ export const useTranslationFunction = () => {
38
37
  return options.defaultValue || key;
39
38
  }
40
39
 
41
- let finalResult: string;
42
- let translationFound = false;
40
+ // Convert dot notation to i18next namespace:key format
41
+ // "namespace.key.subkey" i18next "namespace:key.subkey"
42
+ const firstDotIndex = key.indexOf('.');
43
+ const i18nextKey = firstDotIndex > 0
44
+ ? `${key.substring(0, firstDotIndex)}:${key.substring(firstDotIndex + 1)}`
45
+ : key;
43
46
 
44
- // If key already has namespace separator (:), use as-is
45
- if (key.includes(':')) {
46
- const result = i18nextT(key, options);
47
- finalResult = typeof result === 'string' ? result : key;
48
- translationFound = finalResult !== key && finalResult !== options.defaultValue;
49
- } else {
50
- // Auto-detect namespace from first dot segment
51
- const firstDotIndex = key.indexOf('.');
52
- if (firstDotIndex > 0) {
53
- const potentialNamespace = key.substring(0, firstDotIndex);
54
- const restOfKey = key.substring(firstDotIndex + 1);
55
- const hasNamespace = i18n.hasResourceBundle(i18n.language, potentialNamespace);
56
-
57
- if (hasNamespace) {
58
- const namespacedKey = `${potentialNamespace}:${restOfKey}`;
59
- const namespacedResult = i18nextT(namespacedKey, options);
60
-
61
- if (namespacedResult !== namespacedKey && namespacedResult !== restOfKey) {
62
- finalResult = typeof namespacedResult === 'string' ? namespacedResult : key;
63
- translationFound = true;
64
- } else {
65
- // Fallback to original key
66
- const result = i18nextT(key, options);
67
- finalResult = typeof result === 'string' ? result : key;
68
- translationFound = finalResult !== key && finalResult !== options.defaultValue;
69
- }
70
- } else {
71
- // Fallback to original key
72
- const result = i18nextT(key, options);
73
- finalResult = typeof result === 'string' ? result : key;
74
- translationFound = finalResult !== key && finalResult !== options.defaultValue;
75
- }
76
- } else {
77
- // Fallback to original key
78
- const result = i18nextT(key, options);
79
- finalResult = typeof result === 'string' ? result : key;
80
- translationFound = finalResult !== key && finalResult !== options.defaultValue;
81
- }
47
+ // Missing translation is a critical issue warn in development
48
+ if (!i18n.exists(i18nextKey)) {
49
+ devWarn(`[i18n] Missing translation: "${key}"`);
82
50
  }
83
51
 
84
- return finalResult;
52
+ const result = i18nextT(i18nextKey, options);
53
+ return typeof result === 'string' ? result : (options.defaultValue ?? key);
85
54
  }, [i18nextT, ready]);
86
55
 
87
56
  return {
@@ -11,7 +11,6 @@
11
11
 
12
12
  import { useMemo } from 'react';
13
13
  import { createStore, storageService } from '@umituz/react-native-design-system';
14
- import { excludeTransientState } from '../../../../infrastructure/storage/storeConfig';
15
14
  import type { Reminder, QuietHoursConfig, NotificationPreferences } from '../services/types';
16
15
 
17
16
  // ============================================================================
@@ -86,7 +86,7 @@ export interface BaseStoreState {
86
86
  export const excludeTransientState = <T extends BaseStoreState>(
87
87
  state: T
88
88
  ): Partial<T> => {
89
- const { isLoading, isInitialized, ...persistedState } = state;
89
+ const { isLoading: _isLoading, isInitialized: _isInitialized, ...persistedState } = state;
90
90
  return persistedState as Partial<T>;
91
91
  };
92
92