@applicaster/zapp-react-native-ui-components 15.0.0-rc.92 → 15.0.0-rc.94

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.
@@ -1,9 +1,15 @@
1
- import { getPluginIdentifier } from "..";
1
+ import { getPluginIdentifier, memoizedGetPluginIdentifier } from "..";
2
2
 
3
3
  describe("getPluginIdentifier", () => {
4
4
  const prefix = "tv_buttons";
5
5
 
6
+ beforeAll(() => {
7
+ memoizedGetPluginIdentifier.clear();
8
+ });
9
+
6
10
  it("returns the first valid plugin identifier", () => {
11
+ expect.assertions(2);
12
+
7
13
  const configuration = {
8
14
  tv_buttons_button_1_other: "value",
9
15
  tv_buttons_button_1_assign_action:
@@ -15,10 +21,19 @@ describe("getPluginIdentifier", () => {
15
21
  const index = 0;
16
22
  const result = getPluginIdentifier(configuration, prefix, index);
17
23
 
24
+ const memoizedResult = memoizedGetPluginIdentifier(
25
+ configuration,
26
+ prefix,
27
+ index
28
+ );
29
+
18
30
  expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
31
+ expect(memoizedResult).toEqual(result);
19
32
  });
20
33
 
21
34
  it("returns the second valid plugin identifier", () => {
35
+ expect.assertions(2);
36
+
22
37
  const configuration = {
23
38
  tv_buttons_button_1_other: "value_1",
24
39
  tv_buttons_button_1_assign_action:
@@ -31,19 +46,37 @@ describe("getPluginIdentifier", () => {
31
46
  const index = 1;
32
47
  const result = getPluginIdentifier(configuration, prefix, index);
33
48
 
49
+ const memoizedResult = memoizedGetPluginIdentifier(
50
+ configuration,
51
+ prefix,
52
+ index
53
+ );
54
+
34
55
  expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
56
+ expect(memoizedResult).toEqual(result);
35
57
  });
36
58
 
37
59
  it("returns undefined when there are no assign_action keys", () => {
60
+ expect.assertions(2);
61
+
38
62
  const configuration = {};
39
63
  const index = 0;
40
64
 
41
65
  const result = getPluginIdentifier(configuration, prefix, index);
42
66
 
67
+ const memoizedResult = memoizedGetPluginIdentifier(
68
+ configuration,
69
+ prefix,
70
+ index
71
+ );
72
+
43
73
  expect(result).toBeUndefined();
74
+ expect(memoizedResult).toBeUndefined();
44
75
  });
45
76
 
46
77
  it("skips undefined values and returns the correct plugin identifier", () => {
78
+ expect.assertions(2);
79
+
47
80
  const configuration = {
48
81
  tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
49
82
  tv_buttons_button_2_assign_action: undefined,
@@ -53,10 +86,19 @@ describe("getPluginIdentifier", () => {
53
86
  const index = 1;
54
87
  const result = getPluginIdentifier(configuration, prefix, index);
55
88
 
89
+ const memoizedResult = memoizedGetPluginIdentifier(
90
+ configuration,
91
+ prefix,
92
+ index
93
+ );
94
+
56
95
  expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
96
+ expect(memoizedResult).toEqual(result);
57
97
  });
58
98
 
59
99
  it("handles missing intermediate keys and returns the correct plugin identifier", () => {
100
+ expect.assertions(2);
101
+
60
102
  const configuration = {
61
103
  tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
62
104
  tv_buttons_button_3_assign_action: "tv_buttons_button_3_assign_action",
@@ -65,10 +107,19 @@ describe("getPluginIdentifier", () => {
65
107
  const index = 1;
66
108
  const result = getPluginIdentifier(configuration, prefix, index);
67
109
 
110
+ const memoizedResult = memoizedGetPluginIdentifier(
111
+ configuration,
112
+ prefix,
113
+ index
114
+ );
115
+
68
116
  expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
117
+ expect(memoizedResult).toEqual(result);
69
118
  });
70
119
 
71
120
  it("skips empty string values and returns the first non-empty assign_action", () => {
121
+ expect.assertions(2);
122
+
72
123
  const configuration = {
73
124
  tv_buttons_button_1_assign_action: "",
74
125
  tv_buttons_button_2_assign_action: "tv_buttons_button_2_assign_action",
@@ -77,10 +128,19 @@ describe("getPluginIdentifier", () => {
77
128
  const index = 0;
78
129
  const result = getPluginIdentifier(configuration, prefix, index);
79
130
 
131
+ const memoizedResult = memoizedGetPluginIdentifier(
132
+ configuration,
133
+ prefix,
134
+ index
135
+ );
136
+
80
137
  expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
138
+ expect(memoizedResult).toEqual(result);
81
139
  });
82
140
 
83
141
  it("returns undefined for negative index", () => {
142
+ expect.assertions(2);
143
+
84
144
  const configuration = {
85
145
  tv_buttons_button_1_assign_action: "a",
86
146
  tv_buttons_button_2_assign_action: "b",
@@ -89,10 +149,19 @@ describe("getPluginIdentifier", () => {
89
149
  const index = -1;
90
150
  const result = getPluginIdentifier(configuration, prefix, index);
91
151
 
152
+ const memoizedResult = memoizedGetPluginIdentifier(
153
+ configuration,
154
+ prefix,
155
+ index
156
+ );
157
+
92
158
  expect(result).toBeUndefined();
159
+ expect(memoizedResult).toBeUndefined();
93
160
  });
94
161
 
95
162
  it("returns undefined for out-of-bounds index", () => {
163
+ expect.assertions(2);
164
+
96
165
  const configuration = {
97
166
  tv_buttons_button_1_assign_action: "a",
98
167
  tv_buttons_button_2_assign_action: "b",
@@ -101,10 +170,19 @@ describe("getPluginIdentifier", () => {
101
170
  const index = 5;
102
171
  const result = getPluginIdentifier(configuration, prefix, index);
103
172
 
173
+ const memoizedResult = memoizedGetPluginIdentifier(
174
+ configuration,
175
+ prefix,
176
+ index
177
+ );
178
+
104
179
  expect(result).toBeUndefined();
180
+ expect(memoizedResult).toBeUndefined();
105
181
  });
106
182
 
107
183
  it("ignores keys with wrong prefix or format", () => {
184
+ expect.assertions(2);
185
+
108
186
  const configuration = {
109
187
  tv_buttons_button_1_assign_action: "a",
110
188
  tv_buttons_wrongprefix_2_assign_action: "b",
@@ -114,10 +192,19 @@ describe("getPluginIdentifier", () => {
114
192
  const index = 1;
115
193
  const result = getPluginIdentifier(configuration, prefix, index);
116
194
 
195
+ const memoizedResult = memoizedGetPluginIdentifier(
196
+ configuration,
197
+ prefix,
198
+ index
199
+ );
200
+
117
201
  expect(result).toBeUndefined();
202
+ expect(memoizedResult).toBeUndefined();
118
203
  });
119
204
 
120
205
  it("returns undefined if all assign_actions are null or empty", () => {
206
+ expect.assertions(2);
207
+
121
208
  const configuration = {
122
209
  tv_buttons_button_1_assign_action: null,
123
210
  tv_buttons_button_2_assign_action: undefined,
@@ -127,10 +214,19 @@ describe("getPluginIdentifier", () => {
127
214
  const index = 0;
128
215
  const result = getPluginIdentifier(configuration, prefix, index);
129
216
 
217
+ const memoizedResult = memoizedGetPluginIdentifier(
218
+ configuration,
219
+ prefix,
220
+ index
221
+ );
222
+
130
223
  expect(result).toBeUndefined();
224
+ expect(memoizedResult).toBeUndefined();
131
225
  });
132
226
 
133
227
  it("handles non-string values correctly", () => {
228
+ expect.assertions(6);
229
+
134
230
  const configuration = {
135
231
  tv_buttons_button_1_assign_action: 123,
136
232
  tv_buttons_button_2_assign_action: true,
@@ -143,10 +239,21 @@ describe("getPluginIdentifier", () => {
143
239
  expect(getPluginIdentifier(configuration, prefix, 2)).toEqual({
144
240
  nested: "value",
145
241
  });
242
+
243
+ expect(memoizedGetPluginIdentifier(configuration, prefix, 0)).toEqual(123);
244
+ expect(memoizedGetPluginIdentifier(configuration, prefix, 1)).toEqual(true);
245
+
246
+ expect(memoizedGetPluginIdentifier(configuration, prefix, 2)).toEqual({
247
+ nested: "value",
248
+ });
146
249
  });
147
250
  });
148
251
 
149
252
  describe("getPluginIdentifier - when configuration has duplicate values", () => {
253
+ beforeAll(() => {
254
+ memoizedGetPluginIdentifier.clear();
255
+ });
256
+
150
257
  const prefix = "tv_buttons";
151
258
 
152
259
  const configuration = {
@@ -155,16 +262,34 @@ describe("getPluginIdentifier - when configuration has duplicate values", () =>
155
262
  };
156
263
 
157
264
  it("returns the first plugin identifier when values are identical", () => {
265
+ expect.assertions(2);
266
+
158
267
  const index = 0;
159
268
  const result = getPluginIdentifier(configuration, prefix, index);
160
269
 
270
+ const memoizedResult = memoizedGetPluginIdentifier(
271
+ configuration,
272
+ prefix,
273
+ index
274
+ );
275
+
161
276
  expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
277
+ expect(memoizedResult).toEqual(result);
162
278
  });
163
279
 
164
280
  it("returns the second plugin identifier when values are identical", () => {
281
+ expect.assertions(2);
282
+
165
283
  const index = 1;
166
284
  const result = getPluginIdentifier(configuration, prefix, index);
167
285
 
286
+ const memoizedResult = memoizedGetPluginIdentifier(
287
+ configuration,
288
+ prefix,
289
+ index
290
+ );
291
+
168
292
  expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
293
+ expect(memoizedResult).toEqual(result);
169
294
  });
170
295
  });
@@ -40,9 +40,7 @@ export const getPluginIdentifier = (
40
40
  return undefined;
41
41
  };
42
42
 
43
- export const memoizedGetPluginIdentifier = memoizee(getPluginIdentifier, {
44
- primitive: true,
45
- });
43
+ export const memoizedGetPluginIdentifier = memoizee(getPluginIdentifier);
46
44
 
47
45
  type Label = {
48
46
  name: string;
@@ -1,4 +1,6 @@
1
1
  import * as React from "react";
2
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
3
+ import { useNetworkStatusLocalizations } from "./utils";
2
4
 
3
5
  type Props = {
4
6
  children?: React.ReactNode;
@@ -10,13 +12,6 @@ type Props = {
10
12
 
11
13
  const NOTIF_DURATION = 4500;
12
14
 
13
- export const ONLINE_MSG = "You are back online";
14
-
15
- export const OFFLINE_MSG = "No internet connection";
16
-
17
- const EXTRA_OFFLINE_MSG = "Please check your connection";
18
- const EXTRA_ONLINE_MSG = "Feel free to continue where you left off";
19
-
20
15
  const styles: Record<any, React.CSSProperties> = {
21
16
  body: {
22
17
  position: "absolute",
@@ -47,6 +42,9 @@ const styles: Record<any, React.CSSProperties> = {
47
42
  export const NotificationView = (props: Props) => {
48
43
  const { children, hidden, dismiss, previousOnline, online } = props;
49
44
 
45
+ const theme = useTheme<BaseThemePropertiesTV>();
46
+ const storedLocalizations = useNetworkStatusLocalizations();
47
+
50
48
  const [open, setOpen] = React.useState<boolean | null>(null);
51
49
 
52
50
  const timeout = React.useRef<NodeJS.Timeout>();
@@ -84,8 +82,18 @@ export const NotificationView = (props: Props) => {
84
82
  }, [hidden, online]);
85
83
 
86
84
  const showOnlineMsg = wentOnline || online;
87
- const MSG = showOnlineMsg ? ONLINE_MSG : OFFLINE_MSG;
88
- const EXTRA_MSG = showOnlineMsg ? EXTRA_ONLINE_MSG : EXTRA_OFFLINE_MSG;
85
+
86
+ const MSG = showOnlineMsg
87
+ ? (theme?.online_notification_title ??
88
+ storedLocalizations?.online_notification_title)
89
+ : (theme?.offline_notification_title ??
90
+ storedLocalizations?.offline_notification_title);
91
+
92
+ const EXTRA_MSG = showOnlineMsg
93
+ ? (theme?.online_notification_subtitle ??
94
+ storedLocalizations?.online_notification_subtitle)
95
+ : (theme?.offline_notification_subtitle ??
96
+ storedLocalizations?.offline_notification_subtitle);
89
97
 
90
98
  return (
91
99
  <div onClick={onClose}>
@@ -1,4 +1,6 @@
1
1
  import * as React from "react";
2
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
3
+ import { useNetworkStatusLocalizations } from "./utils";
2
4
 
3
5
  type Props = {
4
6
  children?: React.ReactNode;
@@ -9,12 +11,6 @@ type Props = {
9
11
 
10
12
  const DURATION_TO_HIDE_AFTER_BACK_TO_ONLINE = 4500; // ms
11
13
 
12
- const ONLINE_TITLE = "You are back online";
13
- const ONLINE_SUBTITLE = "Feel free to continue where you left off";
14
-
15
- const OFFLINE_TITLE = "No internet connection";
16
- const OFFLINE_SUBTITLE = "Please check your connection";
17
-
18
14
  const styles: Record<any, React.CSSProperties> = {
19
15
  body: {
20
16
  position: "absolute",
@@ -47,6 +43,9 @@ let timer: NodeJS.Timeout;
47
43
  export const NotificationView = (props: Props) => {
48
44
  const { children, dismiss, previousOnline = true, online } = props;
49
45
 
46
+ const theme = useTheme<BaseThemePropertiesTV>();
47
+ const storedLocalizations = useNetworkStatusLocalizations();
48
+
50
49
  const [shown, setShown] = React.useState<boolean>(false);
51
50
 
52
51
  const onClose = () => {
@@ -79,8 +78,17 @@ export const NotificationView = (props: Props) => {
79
78
  }
80
79
  }, [online, previousOnline]);
81
80
 
82
- const title = online ? ONLINE_TITLE : OFFLINE_TITLE;
83
- const subtitle = online ? ONLINE_SUBTITLE : OFFLINE_SUBTITLE;
81
+ const title = online
82
+ ? (theme?.online_notification_title ??
83
+ storedLocalizations?.online_notification_title)
84
+ : (theme?.offline_notification_title ??
85
+ storedLocalizations?.offline_notification_title);
86
+
87
+ const subtitle = online
88
+ ? (theme?.online_notification_subtitle ??
89
+ storedLocalizations?.online_notification_subtitle)
90
+ : (theme?.offline_notification_subtitle ??
91
+ storedLocalizations?.offline_notification_subtitle);
84
92
 
85
93
  return (
86
94
  <div onClick={onClose}>
@@ -0,0 +1,34 @@
1
+ import * as React from "react";
2
+ import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
3
+
4
+ export const NETWORK_STATUS_LOCALIZATIONS_KEY = "network_status_localizations";
5
+
6
+ export const THEME_STORAGE_NAMESPACE = "quick-brick-theme";
7
+
8
+ export function useNetworkStatusLocalizations() {
9
+ const [storedLocalizations, setStoredLocalizations] = React.useState<Record<
10
+ string,
11
+ string
12
+ > | null>(null);
13
+
14
+ React.useEffect(() => {
15
+ async function loadStoredLocalizations() {
16
+ try {
17
+ const stored = await sessionStorage.getItem(
18
+ NETWORK_STATUS_LOCALIZATIONS_KEY,
19
+ THEME_STORAGE_NAMESPACE
20
+ );
21
+
22
+ if (stored) {
23
+ setStoredLocalizations(stored);
24
+ }
25
+ } catch (error) {
26
+ console.error("Error loading network status localizations", error);
27
+ }
28
+ }
29
+
30
+ loadStoredLocalizations();
31
+ }, []);
32
+
33
+ return storedLocalizations;
34
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "15.0.0-rc.92",
3
+ "version": "15.0.0-rc.94",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "15.0.0-rc.92",
32
- "@applicaster/zapp-react-native-bridge": "15.0.0-rc.92",
33
- "@applicaster/zapp-react-native-redux": "15.0.0-rc.92",
34
- "@applicaster/zapp-react-native-utils": "15.0.0-rc.92",
31
+ "@applicaster/applicaster-types": "15.0.0-rc.94",
32
+ "@applicaster/zapp-react-native-bridge": "15.0.0-rc.94",
33
+ "@applicaster/zapp-react-native-redux": "15.0.0-rc.94",
34
+ "@applicaster/zapp-react-native-utils": "15.0.0-rc.94",
35
35
  "fast-json-stable-stringify": "^2.1.0",
36
36
  "promise": "^8.3.0",
37
37
  "url": "^0.11.0",