@ledvance/ui-biz-bundle 1.1.158 → 1.1.160

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
@@ -4,7 +4,7 @@
4
4
  "name": "@ledvance/ui-biz-bundle",
5
5
  "pid": [],
6
6
  "uiid": "",
7
- "version": "1.1.158",
7
+ "version": "1.1.160",
8
8
  "scripts": {},
9
9
  "dependencies": {
10
10
  "@ledvance/base": "^1.x",
@@ -59,7 +59,7 @@ export const useFlag: UseFlagType = (flagCode, extra) => {
59
59
  })
60
60
  const extraDps = {}
61
61
  if(extra.isCeilingLight){
62
- extraDps[extra.switchLedCode] = true,
62
+ extraDps[extra.switchLedCode] = true
63
63
  extraDps[extra.whiteSwitchCode!] = true
64
64
  extraDps[extra.rgbcSwitchLedCode!] = true
65
65
  extraDps[extra.rgbcWorkModeCode!] = WORK_MODE.COLOUR
@@ -2,13 +2,13 @@ import I18n from "@ledvance/base/src/i18n";
2
2
  import { SceneNodeTransitionMode } from "../scene/SceneInfo";
3
3
 
4
4
  type HSV = {
5
- h: number
6
- s: number
5
+ h: number
6
+ s: number
7
7
  v: number
8
8
  }
9
9
 
10
10
  type BT = {
11
- brightness: number
11
+ brightness: number
12
12
  colorTemp: number
13
13
  }
14
14
 
@@ -24,6 +24,7 @@ export interface FlagItemInfo {
24
24
 
25
25
  export interface FlagUiInfo extends FlagItemInfo{
26
26
  name: string
27
+ groupKey?: string
27
28
  }
28
29
 
29
30
  const defFlagConfig = {
@@ -45,36 +46,42 @@ export const defFlagList: FlagUiInfo[] = [
45
46
  {
46
47
  id: 255,
47
48
  name: I18n.getLang('country_DE'),
49
+ groupKey: 'latam_2026_e',
48
50
  ...defFlagConfig,
49
51
  colors: [{ h: 48, s: 100, v: 100 }, { h: 360, s: 100, v: 100 }, { h: 0, s: 0, v: 0 }],
50
52
  },
51
53
  {
52
54
  id: 254,
53
55
  name: I18n.getLang('country_BE'),
56
+ groupKey: 'latam_2026_g',
54
57
  ...defFlagConfig,
55
58
  colors: [{ h: 360, s: 100, v: 100 }, { h: 48, s: 100, v: 100 }, { h: 0, s: 0, v: 0 }]
56
59
  },
57
60
  {
58
61
  id: 253,
59
62
  name: I18n.getLang('country_FR'),
63
+ groupKey: 'latam_2026_i',
60
64
  ...defFlagConfig,
61
65
  colors: [{ h: 360, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 212, s: 100, v: 100 }]
62
66
  },
63
67
  {
64
68
  id: 252,
65
69
  name: I18n.getLang('country_PT'),
70
+ groupKey: 'latam_2026_k',
66
71
  ...defFlagConfig,
67
72
  colors: [{ h: 360, s: 100, v: 100 }, { h: 360, s: 100, v: 100 }, { h: 120, s: 100, v: 64 }]
68
73
  },
69
74
  {
70
75
  id: 251,
71
76
  name: I18n.getLang('country_scotland'),
77
+ groupKey: 'latam_2026_c',
72
78
  ...defFlagConfig,
73
79
  colors: [{ h: 209, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 209, s: 100, v: 100 }]
74
80
  },
75
81
  {
76
82
  id: 250,
77
83
  name: I18n.getLang('country_ES'),
84
+ groupKey: 'latam_2026_h',
78
85
  ...defFlagConfig,
79
86
  colors: [{ h: 360, s: 100, v: 100 }, { h: 47, s: 100, v: 100 }, { h: 360, s: 100, v: 100 }]
80
87
  },
@@ -87,12 +94,14 @@ export const defFlagList: FlagUiInfo[] = [
87
94
  {
88
95
  id: 248,
89
96
  name: I18n.getLang('country_AT'),
97
+ groupKey: 'latam_2026_j',
90
98
  ...defFlagConfig,
91
99
  colors: [{ h: 360, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 360, s: 100, v: 100 }]
92
100
  },
93
101
  {
94
102
  id: 247,
95
103
  name: I18n.getLang('country_england'),
104
+ groupKey: 'latam_2026_l',
96
105
  ...defFlagConfig,
97
106
  colors: [{ h: 0, s: 0, v: 100 }, { h: 360, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }]
98
107
  },
@@ -123,6 +132,7 @@ export const defFlagList: FlagUiInfo[] = [
123
132
  {
124
133
  id: 242,
125
134
  name: I18n.getLang('country_NL'),
135
+ groupKey: 'latam_2026_f',
126
136
  ...defFlagConfig,
127
137
  colors: [{ h: 217, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 360, s: 100, v: 100 }]
128
138
  },
@@ -135,6 +145,7 @@ export const defFlagList: FlagUiInfo[] = [
135
145
  {
136
146
  id: 240,
137
147
  name: I18n.getLang('country_CH'),
148
+ groupKey: 'latam_2026_b',
138
149
  ...defFlagConfig,
139
150
  colors: [{ h: 360, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 360, s: 100, v: 100 }]
140
151
  },
@@ -165,6 +176,7 @@ export const defFlagList: FlagUiInfo[] = [
165
176
  {
166
177
  id: 235,
167
178
  name: I18n.getLang('country_HR'),
179
+ groupKey: 'latam_2026_l',
168
180
  ...defFlagConfig,
169
181
  colors: [{ h: 220, s: 89, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 360, s: 100, v: 100 }]
170
182
  },
@@ -177,6 +189,7 @@ export const defFlagList: FlagUiInfo[] = [
177
189
  {
178
190
  id: 233,
179
191
  name: I18n.getLang('country_NO'),
192
+ groupKey: 'latam_2026_i',
180
193
  ...defFlagConfig,
181
194
  colors: [{ h: 218, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 360, s: 100, v: 100 }]
182
195
  },
@@ -215,24 +228,28 @@ export const defFlagList: FlagUiInfo[] = [
215
228
  {
216
229
  id: 226,
217
230
  name: I18n.getLang('country_US'),
231
+ groupKey: 'latam_2026_d',
218
232
  ...defFlagConfig,
219
233
  colors: [{ h: 210, s: 78, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 0, s: 100, v: 100 }],
220
234
  },
221
235
  {
222
236
  id: 225,
223
237
  name: I18n.getLang('country_CA'),
238
+ groupKey: 'latam_2026_b',
224
239
  ...defFlagConfig,
225
240
  colors: [{ h: 0, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 0, s: 100, v: 100 },],
226
241
  },
227
242
  {
228
243
  id: 224,
229
244
  name: I18n.getLang('country_MX'),
245
+ groupKey: 'latam_2026_a',
230
246
  ...defFlagConfig,
231
247
  colors: [{ h: 0, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 103, s: 73, v: 64 },],
232
248
  },
233
249
  {
234
250
  id: 223,
235
251
  name: I18n.getLang('country_SA'),
252
+ groupKey: 'latam_2026_h',
236
253
  ...defFlagConfig,
237
254
  colors: [{ h: 0, s: 0, v: 100 }, { h: 103, s: 73, v: 64 },],
238
255
  },
@@ -245,24 +262,28 @@ export const defFlagList: FlagUiInfo[] = [
245
262
  {
246
263
  id: 221,
247
264
  name: I18n.getLang('country_AU'),
265
+ groupKey: 'latam_2026_d',
248
266
  ...defFlagConfig,
249
267
  colors: [{ h: 0, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 199, s: 84, v: 100 },],
250
268
  },
251
269
  {
252
270
  id: 220,
253
271
  name: I18n.getLang('country_JP'),
272
+ groupKey: 'latam_2026_f',
254
273
  ...defFlagConfig,
255
274
  colors: [{ h: 360, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }],
256
275
  },
257
276
  {
258
277
  id: 219,
259
278
  name: I18n.getLang('country_BR'),
279
+ groupKey: 'latam_2026_c',
260
280
  ...defFlagConfig,
261
281
  colors: [{ h: 60, s: 100, v: 100 }, { h: 147, s: 100, v: 64 }, { h: 0, s: 0, v: 100 },],
262
282
  },
263
283
  {
264
284
  id: 218,
265
285
  name: I18n.getLang('country_AR'),
286
+ groupKey: 'latam_2026_j',
266
287
  ...defFlagConfig,
267
288
  colors: [{ h: 210, s: 65, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 210, s: 65, v: 100 },],
268
289
  },
@@ -275,6 +296,7 @@ export const defFlagList: FlagUiInfo[] = [
275
296
  {
276
297
  id: 216,
277
298
  name: I18n.getLang('country_EG'),
299
+ groupKey: 'latam_2026_g',
278
300
  ...defFlagConfig,
279
301
  colors: [{ h: 0, s: 0, v: 0 }, { h: 0, s: 0, v: 100 }, { h: 0, s: 100, v: 100 },],
280
302
  },
@@ -305,6 +327,7 @@ export const defFlagList: FlagUiInfo[] = [
305
327
  {
306
328
  id: 211,
307
329
  name: I18n.getLang('country_EC'),
330
+ groupKey: 'latam_2026_e',
308
331
  ...defFlagConfig,
309
332
  colors: [{ h: 0, s: 100, v: 100 }, { h: 210, s: 78, v: 100 }, { h: 60, s: 100, v: 100 },],
310
333
  },
@@ -317,12 +340,14 @@ export const defFlagList: FlagUiInfo[] = [
317
340
  {
318
341
  id: 209,
319
342
  name: I18n.getLang('country_CI'),
343
+ groupKey: 'latam_2026_e',
320
344
  ...defFlagConfig,
321
345
  colors: [{ h: 147, s: 100, v: 64 }, { h: 0, s: 0, v: 100 }, { h: 45, s: 100, v: 100 },],
322
346
  },
323
347
  {
324
348
  id: 208,
325
349
  name: I18n.getLang('country_GH'),
350
+ groupKey: 'latam_2026_l',
326
351
  ...defFlagConfig,
327
352
  colors: [{ h: 128, s: 77, v: 64 }, { h: 60, s: 100, v: 100 }, { h: 0, s: 100, v: 100 },],
328
353
  },
@@ -359,6 +384,7 @@ export const defFlagList: FlagUiInfo[] = [
359
384
  {
360
385
  id: 202,
361
386
  name: I18n.getLang('country_ir'),
387
+ groupKey: 'latam_2026_g',
362
388
  ...defFlagConfig,
363
389
  colors: [{ h: 0, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 147, s: 100, v: 64 },],
364
390
  },
@@ -383,6 +409,7 @@ export const defFlagList: FlagUiInfo[] = [
383
409
  {
384
410
  id: 198,
385
411
  name: I18n.getLang('country_QA'),
412
+ groupKey: 'latam_2026_b',
386
413
  ...defFlagConfig,
387
414
  colors: [{ h: 0, s: 100, v: 100 }, { h: 0, s: 0, v: 100 },],
388
415
  },
@@ -395,6 +422,7 @@ export const defFlagList: FlagUiInfo[] = [
395
422
  {
396
423
  id: 196,
397
424
  name: I18n.getLang('country_CO'),
425
+ groupKey: 'latam_2026_k',
398
426
  ...defFlagConfig,
399
427
  colors: [{ h: 0, s: 100, v: 100 }, { h: 210, s: 78, v: 100 }, { h: 60, s: 100, v: 100 },],
400
428
  },
@@ -449,6 +477,7 @@ export const defFlagList: FlagUiInfo[] = [
449
477
  {
450
478
  id: 187,
451
479
  name: I18n.getLang('country_MA'),
480
+ groupKey: 'latam_2026_c',
452
481
  ...defFlagConfig,
453
482
  colors: [{ h: 147, s: 100, v: 64 }, { h: 0, s: 100, v: 100 },],
454
483
  },
@@ -467,6 +496,7 @@ export const defFlagList: FlagUiInfo[] = [
467
496
  {
468
497
  id: 184,
469
498
  name: I18n.getLang('country_NZ'),
499
+ groupKey: 'latam_2026_g',
470
500
  ...defFlagConfig,
471
501
  colors: [{ h: 0, s: 0, v: 100 }, { h: 0, s: 100, v: 100 }, { h: 220, s: 100, v: 100 },],
472
502
  },
@@ -491,6 +521,7 @@ export const defFlagList: FlagUiInfo[] = [
491
521
  {
492
522
  id: 180,
493
523
  name: I18n.getLang('country_PY'),
524
+ groupKey: 'latam_2026_d',
494
525
  ...defFlagConfig,
495
526
  colors: [{ h: 205, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 0, s: 100, v: 100 },],
496
527
  },
@@ -521,6 +552,7 @@ export const defFlagList: FlagUiInfo[] = [
521
552
  {
522
553
  id: 175,
523
554
  name: I18n.getLang('country_ZA'),
555
+ groupKey: 'latam_2026_a',
524
556
  ...defFlagConfig,
525
557
  colors: [{ h: 0, s: 0, v: 0 },{ h: 60, s: 100, v: 100 },{ h: 205, s: 100, v: 100 }, { h: 147, s: 100, v: 64 }, { h: 0, s: 0, v: 100 }, { h: 0, s: 100, v: 100 },],
526
558
  },
@@ -539,6 +571,7 @@ export const defFlagList: FlagUiInfo[] = [
539
571
  {
540
572
  id: 172,
541
573
  name: I18n.getLang('country_TN'),
574
+ groupKey: 'latam_2026_f',
542
575
  ...defFlagConfig,
543
576
  colors: [{ h: 0, s: 0, v: 100 }, { h: 0, s: 100, v: 100 },],
544
577
  },
@@ -551,6 +584,7 @@ export const defFlagList: FlagUiInfo[] = [
551
584
  {
552
585
  id: 170,
553
586
  name: I18n.getLang('country_UY'),
587
+ groupKey: 'latam_2026_h',
554
588
  ...defFlagConfig,
555
589
  colors: [{ h: 20, s: 100, v: 100 }, { h: 60, s: 100, v: 100 }, { h: 0, s: 0, v: 100 }, { h: 205, s: 100, v: 100 },],
556
590
  },
@@ -563,18 +597,21 @@ export const defFlagList: FlagUiInfo[] = [
563
597
  {
564
598
  id: 168,
565
599
  name: I18n.getLang('country_JO'),
600
+ groupKey: 'latam_2026_j',
566
601
  ...defFlagConfig,
567
602
  colors: [{"h":150,"s":100,"v":48}, {"h":0,"s":0,"v":100}, {"h":0,"s":0,"v":0},{"h":353,"s":92,"v":81}],
568
603
  },
569
604
  {
570
605
  id: 167,
571
606
  name: I18n.getLang('country_CV'),
607
+ groupKey: 'latam_2026_h',
572
608
  ...defFlagConfig,
573
609
  colors: [{"h":49,"s":100,"v":100}, {"h":356,"s":79,"v":94}, {"h":0,"s":0,"v":100},{"h":218,"s":100,"v":65}],
574
610
  },
575
611
  {
576
612
  id: 166,
577
613
  name: I18n.getLang('country_PA'),
614
+ groupKey: 'latam_2026_l',
578
615
  ...defFlagConfig,
579
616
  colors: [{"h":219,"s":92,"v":34}, {"h":0,"s":0,"v":100}, {"h":358,"s":92,"v":85}],
580
617
  },
@@ -608,4 +645,46 @@ export const defFlagList: FlagUiInfo[] = [
608
645
  ...defFlagConfig,
609
646
  colors: [{"h":0,"s":0,"v":100}, {"h":160,"s":80,"v":34}],
610
647
  },
648
+ {
649
+ id: 160,
650
+ name: I18n.getLang('country_KR'),
651
+ groupKey: 'latam_2026_a',
652
+ ...defFlagConfig,
653
+ colors: [{"h":0,"s":0,"v":100}, {"h":355,"s":78,"v":80}, {"h":213,"s":93,"v":80}],
654
+ },
655
+ {
656
+ id: 159,
657
+ name: I18n.getLang('country_HT'),
658
+ groupKey: 'latam_2026_c',
659
+ ...defFlagConfig,
660
+ colors: [{"h":228,"s":100,"v":62}, {"h":349,"s":92,"v":82}, {"h":0,"s":0,"v":100}],
661
+ },
662
+ {
663
+ id: 158,
664
+ name: I18n.getLang('country_CW'),
665
+ groupKey: 'latam_2026_e',
666
+ ...defFlagConfig,
667
+ colors: [{"h":220,"s":100,"v":50}, {"h":56,"s":92,"v":98}, {"h":0,"s":0,"v":100}],
668
+ },
669
+ {
670
+ id: 157,
671
+ name: I18n.getLang('country_SN'),
672
+ groupKey: 'latam_2026_i',
673
+ ...defFlagConfig,
674
+ colors: [{"h":148,"s":100,"v":52}, {"h":56,"s":74,"v":99}, {"h":358,"s":88,"v":89}],
675
+ },
676
+ {
677
+ id: 156,
678
+ name: I18n.getLang('country_DZ'),
679
+ groupKey: 'latam_2026_j',
680
+ ...defFlagConfig,
681
+ colors: [{"h":150,"s":100,"v":40}, {"h":0,"s":0,"v":100}, {"h":349,"s":92,"v":82}],
682
+ },
683
+ {
684
+ id: 155,
685
+ name: I18n.getLang('country_UZ'),
686
+ groupKey: 'latam_2026_k',
687
+ ...defFlagConfig,
688
+ colors: [{"h":207,"s":100,"v":81}, {"h":0,"s":0,"v":100}, {"h":109,"s":76,"v":69}],
689
+ },
611
690
  ]
@@ -20,7 +20,7 @@ import { ColorUtils, WORK_MODE } from '@tuya/tuya-panel-lamp-sdk/lib/utils'
20
20
  import { useReactive, useUpdateEffect } from 'ahooks'
21
21
  import { cloneDeep, difference, isEqual, last, map, range } from 'lodash'
22
22
  import React, { useCallback, useEffect, useMemo, useState } from 'react'
23
- import { FlatList, Image, TouchableOpacity, View } from 'react-native'
23
+ import { FlatList, Image, LayoutChangeEvent, TouchableOpacity, View } from 'react-native'
24
24
  import { Utils } from 'tuya-panel-kit'
25
25
  import { ui_biz_routerKey } from '../../navigation/Routers'
26
26
  import { SceneNodeTransitionMode } from '../scene/SceneInfo'
@@ -42,6 +42,8 @@ export interface FlagPageProps {
42
42
  isSolarLight?: boolean
43
43
  isSupportMixScene?: boolean
44
44
  isSupportSceneStatus?: boolean
45
+ isLatamFlag?: boolean
46
+ groupKey?: string
45
47
  drawToolLight?: {
46
48
  drawToolCode: string
47
49
  drawToolObj2dp: (colors: any[]) => string[]
@@ -101,9 +103,10 @@ const FlagPage = (props: { theme?: ThemeType }) => {
101
103
  .catch(() => state.loading = false)
102
104
  }, [devInfo.devId])
103
105
 
104
- useUpdateEffect(() => {
105
- state.filterFlags = state.searchText !== '' ? cloneDeep(state.flags).filter(flag => (flag.name ?? '').toLowerCase().includes(state.searchText.toLowerCase())) : cloneDeep(state.flags)
106
- }, [state.searchText, state.flags])
106
+ useEffect(() => {
107
+ const newFlags = params.isLatamFlag ? state.flags.filter(item => item.groupKey === params.groupKey) : state.flags
108
+ state.filterFlags = state.searchText !== '' ? cloneDeep(newFlags).filter(flag => (flag.name ?? '').toLowerCase().includes(state.searchText.toLowerCase())) : cloneDeep(newFlags)
109
+ }, [params.groupKey, state.searchText, state.flags])
107
110
 
108
111
  // 3. 在父组件中创建 state 存储容器宽度
109
112
  const [listContainerWidth, setListContainerWidth] = useState(0)
@@ -138,6 +141,7 @@ const FlagPage = (props: { theme?: ThemeType }) => {
138
141
  const modDeleteFlag = async (mode: 'add' | 'edit' | 'del', currentMood: FlagUiInfo) => {
139
142
  const checkedMood: FlagUiInfo = {
140
143
  ...currentMood,
144
+ groupKey: params.groupKey
141
145
  }
142
146
 
143
147
  let newScene: FlagUiInfo[] = []
@@ -199,7 +203,7 @@ const FlagPage = (props: { theme?: ThemeType }) => {
199
203
  return (
200
204
  <Page
201
205
  headlineText={I18n.getLang('Feature_devicepanel_flags')}
202
- backText={devInfo.name}
206
+ backText={params.isLatamFlag ? I18n.getLang('latam_groups', 'Groups') : devInfo.name}
203
207
  headlineIcon={res.add}
204
208
  loading={state.loading}
205
209
  onHeadlineIconClick={() => {
@@ -0,0 +1,82 @@
1
+ import Card from '@ledvance/base/src/components/Card'
2
+ import Page from '@ledvance/base/src/components/Page'
3
+ import Spacer from '@ledvance/base/src/components/Spacer'
4
+ import ThemeType from '@ledvance/base/src/config/themeType'
5
+ import I18n from '@ledvance/base/src/i18n'
6
+ import { useDeviceInfo } from '@ledvance/base/src/models/modules/NativePropsSlice'
7
+ import { useNavigation, useRoute } from '@react-navigation/native'
8
+ import { useReactive } from 'ahooks'
9
+ import React, { useMemo } from 'react'
10
+ import { ScrollView, StyleSheet, Text, View } from 'react-native'
11
+ import { Utils } from 'tuya-panel-kit'
12
+ import { ui_biz_routerKey } from '../../navigation/Routers'
13
+ import { FlagPageProps } from './FlagPage'
14
+
15
+ const { convertX: cx } = Utils.RatioUtils
16
+ const { withTheme } = Utils.ThemeUtils
17
+
18
+ interface LatamFlagProps {
19
+ theme?: ThemeType
20
+ }
21
+
22
+ const LatamFlagPage = (props: LatamFlagProps) => {
23
+ const params = useRoute().params as FlagPageProps
24
+ const devInfo = useDeviceInfo()
25
+ const navigation = useNavigation()
26
+ const state = useReactive({
27
+ loading: false,
28
+ })
29
+
30
+ const groupList = useMemo(() => {
31
+ const groups = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
32
+ return groups.map((it) => ({
33
+ key: `latam_2026_${it}`,
34
+ name: I18n.formatValue('latam_group_format', it.toUpperCase())
35
+ }))
36
+ }, [])
37
+
38
+ const styles = useMemo(() => getStyles(props.theme), [props.theme])
39
+
40
+ return (
41
+ <Page
42
+ backText={devInfo.name}
43
+ headlineText={I18n.getLang('latam_groups', 'Groups')}
44
+ accessibilityHint={I18n.getLang('Feature_devicepanel_flags')}
45
+ loading={state.loading}
46
+ >
47
+ <ScrollView>
48
+ <Spacer/>
49
+ {groupList.map((item) => (
50
+ <View key={item.key} style={styles.container}>
51
+ <Card style={styles.card} onPress={() => navigation.navigate(ui_biz_routerKey.ui_biz_flag_page, {
52
+ ...params,
53
+ groupKey: item.key
54
+ })}>
55
+ <Text style={styles.title}>{item.name}</Text>
56
+ <Spacer />
57
+ </Card>
58
+ <Spacer/>
59
+ </View>
60
+ ))}
61
+ </ScrollView>
62
+ </Page>
63
+ )
64
+ }
65
+
66
+ const getStyles = (theme?: ThemeType) =>
67
+ StyleSheet.create({
68
+ container: {
69
+ marginHorizontal: cx(24),
70
+ },
71
+ card: {
72
+ padding: cx(20),
73
+ },
74
+ title: {
75
+ color: theme?.global.fontColor,
76
+ fontSize: cx(16),
77
+ fontWeight: 'bold',
78
+ marginBottom: cx(16),
79
+ },
80
+ })
81
+
82
+ export default withTheme(LatamFlagPage)
@@ -1,5 +1,6 @@
1
1
  import {NavigationRoute} from "tuya-panel-kit";
2
2
  import FlagPage from "./FlagPage";
3
+ import LatamFlagPage from "./LatamFlagPage";
3
4
  import FlagEditPage from "./FlagEditPage";
4
5
  import {ui_biz_routerKey} from "../../navigation/Routers";
5
6
 
@@ -20,6 +21,14 @@ const FlagPageRouters: NavigationRoute[] = [
20
21
  showOfflineView: false,
21
22
  }
22
23
  },
24
+ {
25
+ name: ui_biz_routerKey.ui_biz_latam_flag_page,
26
+ component: LatamFlagPage,
27
+ options: {
28
+ hideTopbar: true,
29
+ showOfflineView: false,
30
+ }
31
+ },
23
32
  ]
24
33
 
25
34
  export default FlagPageRouters
@@ -28,6 +28,7 @@ export const ui_biz_routerKey = {
28
28
  'ui_biz_history': 'ui_biz_history',
29
29
  'ui_biz_power_behavior': 'ui_biz_power_behavior',
30
30
  'ui_biz_flag_page': 'ui_biz_flag_page',
31
+ 'ui_biz_latam_flag_page': 'ui_biz_latam_flag_page',
31
32
  'ui_biz_flag_page_edit': 'ui_biz_flag_page_edit',
32
33
  'ui_biz_time_schedule_new': 'ui_biz_time_schedule_new',
33
34
  'ui_biz_time_schedule_add_new': 'ui_biz_time_schedule_add_new',
@@ -364,7 +364,7 @@ const EnergyConsumptionPage = (props: {theme?: ThemeType}) => {
364
364
  style={{ position: 'relative' }}
365
365
  backText={backTitle}
366
366
  headlineText={backTitle}
367
- headlineIcon={res.ic_refresh}
367
+ headlineIcon={res.ic_reset_energy}
368
368
  onHeadlineIconClick={() => {
369
369
  showDialog({
370
370
  method: 'confirm',
@@ -1,5 +1,5 @@
1
1
  import I18n from "@ledvance/base/src/i18n";
2
- import { AdjustType, ApplyForItem, DiySceneInfo } from "@ledvance/base/src/utils/interface";
2
+ import {AdjustType, AlarmState, ApplyForItem, DiySceneInfo} from "@ledvance/base/src/utils/interface";
3
3
  import { MoodInfo, MoodUIInfo } from "../mood/Interface";
4
4
 
5
5
  export interface Timer {
@@ -36,6 +36,7 @@ interface judgmentSupport {
36
36
  isFanLight?: boolean;
37
37
  isUVCFan?: boolean;
38
38
  isMoodStrip?: boolean;
39
+ isSiren?: boolean;
39
40
  }
40
41
 
41
42
  export interface ManualSettingProps extends judgmentSupport {
@@ -57,7 +58,8 @@ export enum DeviceType {
57
58
  FanLight = 'fanLight',
58
59
  MoodStrip = 'moodStrip',
59
60
  Shutter = 'shutter',
60
- OsramFanLight = 'osramFanLight'
61
+ OsramFanLight = 'osramFanLight',
62
+ Siren = 'Siren'
61
63
  }
62
64
  // export type DeviceType = 'LightSource' | 'CeilingLight' | 'StringLight' | 'StripLight' | 'MixLight';
63
65
 
@@ -106,6 +108,10 @@ export interface OsramFanLightData extends DeviceData {
106
108
  fanSpeed: number
107
109
  }
108
110
 
111
+ export interface SirenData extends DeviceData {
112
+ alarmState: AlarmState
113
+ }
114
+
109
115
  export type ComponentConfig =
110
116
  | { type: DeviceType.LightSource; deviceData: DeviceData }
111
117
  | { type: DeviceType.MixLight; deviceData: MixLightData }
@@ -116,6 +122,7 @@ export type ComponentConfig =
116
122
  | { type: DeviceType.MoodStrip; deviceData: MoodStripData}
117
123
  | { type: DeviceType.Shutter; deviceData: ShutterData}
118
124
  | { type: DeviceType.OsramFanLight; deviceData: OsramFanLightData}
125
+ | { type: DeviceType.Siren; deviceData: SirenData}
119
126
 
120
127
  export interface TimeScheduleDetailState {
121
128
  timeSchedule: Timer;
@@ -142,6 +149,11 @@ export interface DeviceStateType {
142
149
  isManual: boolean
143
150
  }
144
151
 
152
+ export interface SuggestItem {
153
+ name: string;
154
+ suggestValue: boolean | undefined;
155
+ }
156
+
145
157
  export const directOptions = [
146
158
  {label: I18n.getLang('ceiling_fan_tile_uvc_fan_direction_opt_1'), value: 'forward'},
147
159
  {label: I18n.getLang('ceiling_fan_tile_uvc_fan_direction_opt_2'), value: 'reverse'}
@@ -1,8 +1,8 @@
1
1
  import { NativeApi } from '@ledvance/base/src/api/native';
2
- import { Timer, TimerActions } from './Interface';
2
+ import { Timer, TimerActions} from './Interface';
3
3
  import { parseJSON } from '@tuya/tuya-panel-lamp-sdk/lib/utils';
4
4
  import { ColorList } from '@ledvance/base/src/components/StripAdjustView';
5
- import {AdjustType} from "@ledvance/base/src/utils/interface";
5
+ import {AdjustType, AlarmState} from "@ledvance/base/src/utils/interface";
6
6
  import { TimeScheduleDetailPageParams } from './TimeScheduleDetailPage'
7
7
 
8
8
  export const defDeviceData = {
@@ -45,6 +45,16 @@ export const defShutterDeviceData = (props: TimeScheduleDetailPageParams) => {
45
45
  }
46
46
  };
47
47
 
48
+ export const defSirenDeviceData = (props: TimeScheduleDetailPageParams) => {
49
+ return {
50
+ alarmState: props.suggestValue === undefined
51
+ ? AlarmState.AlarmSound
52
+ : props.suggestValue
53
+ ? AlarmState.AlarmLight
54
+ : AlarmState.AlarmSoundAndLight
55
+ }
56
+ };
57
+
48
58
  export const defOsramFanLightDeviceData = {
49
59
  ...defDeviceData,
50
60
  fanSpeed: 1,
@@ -14,6 +14,16 @@ import { TimeScheduleDetailPageParams } from './TimeScheduleDetailPage'
14
14
 
15
15
  const { convertX: cx } = Utils.RatioUtils
16
16
  const { withTheme } = Utils.ThemeUtils
17
+ const DEFAULT_SUGGEST_ITEMS = [
18
+ {
19
+ name: I18n.getLang('timeschedule_on'),
20
+ suggestValue: true,
21
+ },
22
+ {
23
+ name: I18n.getLang('timeschedule_off'),
24
+ suggestValue: false,
25
+ },
26
+ ]
17
27
 
18
28
  interface TimeScheduleAddProps {
19
29
  theme?: ThemeType
@@ -21,6 +31,8 @@ interface TimeScheduleAddProps {
21
31
 
22
32
  const TimeScheduleAddPage = (props: TimeScheduleAddProps) => {
23
33
  const params = useParams<TimeScheduleDetailPageParams>()
34
+ const suggestItems = params.suggestList ?? DEFAULT_SUGGEST_ITEMS
35
+
24
36
  const navigation = useNavigation()
25
37
  const state = useReactive({
26
38
  loading: false,
@@ -55,14 +67,16 @@ const TimeScheduleAddPage = (props: TimeScheduleAddProps) => {
55
67
  <Card style={styles.card} onPress={() => nextPage()}>
56
68
  <Text style={styles.text}>{I18n.getLang('timeschedule_own')}</Text>
57
69
  </Card>
58
- <Spacer/>
59
- <Card style={styles.card} onPress={() => nextPage(true)}>
60
- <Text style={styles.text}>{I18n.getLang('timeschedule_on')}</Text>
61
- </Card>
62
- <Spacer/>
63
- <Card style={styles.card} onPress={() => nextPage(false)}>
64
- <Text style={styles.text}>{I18n.getLang('timeschedule_off')}</Text>
65
- </Card>
70
+ {suggestItems.map((item) => {
71
+ return (
72
+ <View key={item.name}>
73
+ <Spacer/>
74
+ <Card style={styles.card} onPress={() => nextPage(item.suggestValue)}>
75
+ <Text style={styles.text}>{item.name}</Text>
76
+ </Card>
77
+ </View>
78
+ )
79
+ })}
66
80
  </View>
67
81
  </Page>
68
82
  )
@@ -15,7 +15,7 @@ import { useDeviceId, useMoods, useSystemTimeFormate, } from '@ledvance/base/src
15
15
  import { Result } from '@ledvance/base/src/models/modules/Result'
16
16
  import res from '@ledvance/base/src/res'
17
17
  import { convertTo12HourFormat, loopText, showDialog } from '@ledvance/base/src/utils/common'
18
- import { ApplyForItem, DiySceneInfo } from '@ledvance/base/src/utils/interface'
18
+ import {AlarmState, ApplyForItem, DiySceneInfo} from '@ledvance/base/src/utils/interface'
19
19
  import { ui_biz_routerKey } from '../../navigation/Routers'
20
20
  import { useNavigation } from '@react-navigation/core'
21
21
  import { useReactive } from 'ahooks'
@@ -27,14 +27,14 @@ import { MoodInfo, MoodUIInfo } from '../mood/Interface'
27
27
  import { getRemoteMoodList } from '../mood/MoodActions'
28
28
  import MoodItem from '../mood/MoodItem'
29
29
  import ManualSettings from './components/ManuaSettings'
30
- import { ComponentConfig, DeviceType, Timer, TimerActions, TimeScheduleDetailState, } from './Interface'
30
+ import {ComponentConfig, DeviceType, SirenData, Timer, TimerActions, TimeScheduleDetailState,} from './Interface'
31
31
  import {
32
32
  defDeviceData,
33
33
  defFanLightDeviceData,
34
34
  defMixDeviceData,
35
35
  defMoodStripDeviceData,
36
36
  defOsramFanLightDeviceData,
37
- defShutterDeviceData,
37
+ defShutterDeviceData, defSirenDeviceData,
38
38
  defStripDeviceData
39
39
  } from './TimeScheduleActions'
40
40
  import { TimeSchedulePageParams } from './TimeSchedulePage'
@@ -238,6 +238,14 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
238
238
  return params.isCeilingLight ? ((item.mainLamp.id === (state.mood as MoodInfo)?.mainLamp?.id) && (item.secondaryLamp.id === (state.mood as MoodInfo)?.secondaryLamp?.id)) : item.id === state.mood?.id
239
239
  }, [state.mood, params.isCeilingLight])
240
240
 
241
+ const alarmStateValueMap = useMemo(() => {
242
+ return {
243
+ [AlarmState.AlarmSound]: I18n.getLang('siren_alarm_type_sound'),
244
+ [AlarmState.AlarmLight]: I18n.getLang('siren_alarm_type_light'),
245
+ [AlarmState.AlarmSoundAndLight]: I18n.getLang('siren_alarm_type_sound_light'),
246
+ }
247
+ }, [])
248
+
241
249
  const renderSkillGroup = (skills: ApplyForItem[], i18nString: string) => {
242
250
  if (!skills.length) return null;
243
251
 
@@ -263,6 +271,31 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
263
271
  );
264
272
  };
265
273
 
274
+ const renderSirenSkillGroup = (skills: ApplyForItem[]) => {
275
+ if (!skills.length) return null;
276
+ return (
277
+ <>
278
+ {skills.map(item => (
279
+ <View key={item.dp}>
280
+ <Text style={{fontSize: cx(14), color: props.theme?.global.fontColor}}>
281
+ {item.key}
282
+ </Text>
283
+ <View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
284
+ <View
285
+ style={[
286
+ styles.summaryRight,
287
+ {marginRight: cx(5), marginBottom: cx(5)},
288
+ ]}
289
+ >
290
+ <Text
291
+ style={styles.rightItem}>{alarmStateValueMap[(state.manualData.deviceData as SirenData).alarmState]}</Text>
292
+ </View>
293
+ </View>
294
+ </View>))}
295
+ </>
296
+ );
297
+ };
298
+
266
299
  const styles = StyleSheet.create({
267
300
  cardContainer: {
268
301
  marginHorizontal: cx(24),
@@ -629,8 +662,9 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
629
662
  {state.isManual ? (
630
663
  state.selectedSkill.length ? (
631
664
  <>
632
- {renderSkillGroup(state.selectedSkill.filter(skill => skill.enable), I18n.getLang(params.isShutter ? 'curtain_summary_action_txt_1' : 'feature_summary_action_txt_1'))}
633
- {renderSkillGroup(state.selectedSkill.filter(skill => !skill.enable), I18n.getLang(params.isShutter ? 'curtain_summary_action_txt_2' : 'feature_summary_action_txt_2'))}
665
+ {!params.isSiren && renderSkillGroup(state.selectedSkill.filter(skill => skill.enable), I18n.getLang(params.isShutter ? 'curtain_summary_action_txt_1' : 'feature_summary_action_txt_1'))}
666
+ {!params.isSiren && renderSkillGroup(state.selectedSkill.filter(skill => !skill.enable), I18n.getLang(params.isShutter ? 'curtain_summary_action_txt_2' : 'feature_summary_action_txt_2'))}
667
+ {params.isSiren && renderSirenSkillGroup(state.selectedSkill)}
634
668
  </>
635
669
  ) : null
636
670
  ) : (
@@ -698,7 +732,8 @@ const getDefaultManual = (props: TimeScheduleDetailPageParams): ComponentConfig
698
732
  isCeilingLight: DeviceType.CeilingLight,
699
733
  isMoodStrip: DeviceType.MoodStrip,
700
734
  isShutter: DeviceType.Shutter,
701
- isOsramFanLight: DeviceType.OsramFanLight
735
+ isOsramFanLight: DeviceType.OsramFanLight,
736
+ isSiren: DeviceType.Siren
702
737
  };
703
738
 
704
739
  const deviceType = Object.entries(deviceTypeMap)
@@ -716,6 +751,7 @@ const getDefaultManual = (props: TimeScheduleDetailPageParams): ComponentConfig
716
751
  [DeviceType.PowerStrip]: defDeviceData,
717
752
  [DeviceType.LightSource]: defDeviceData,
718
753
  [DeviceType.Plug]: defDeviceData,
754
+ [DeviceType.Siren]: defSirenDeviceData(props),
719
755
  };
720
756
 
721
757
  return {
@@ -14,7 +14,7 @@ import Spacer from '@ledvance/base/src/components/Spacer';
14
14
  import InfoText from '@ledvance/base/src/components/InfoText';
15
15
  import DeleteButton from '@ledvance/base/src/components/DeleteButton';
16
16
  import { useReactive, useUpdateEffect } from 'ahooks';
17
- import { DeviceStateType, Timer, TimerActions } from './Interface';
17
+ import {DeviceStateType, SuggestItem, Timer, TimerActions} from './Interface';
18
18
  import { getTimeSchedule, manageTimeSchedule } from './TimeScheduleActions';
19
19
  import { useParams } from '@ledvance/base/src/hooks/Hooks';
20
20
  import ScheduleCard from './components/ScheduleCard';
@@ -46,8 +46,11 @@ export interface TimeSchedulePageParams {
46
46
  isMoodStrip?: boolean
47
47
  isShutter?: boolean
48
48
  isOsramFan?: boolean
49
+ isSiren?: boolean
50
+ showPresets?: boolean
49
51
  featureId?: string
50
52
  applyForList: ApplyForItem[];
53
+ suggestList?: SuggestItem[];
51
54
  applyForDisabled?: boolean; // 是否可以选择apply for
52
55
  manualDataDp2Obj: (dps: Record<string, any>) => DeviceStateType;
53
56
  manualDataObj2Dp: (deviceState: DeviceStateType, applyForList: ApplyForItem[]) => Record<string, any>;
@@ -130,7 +133,8 @@ const TimeSchedulePage = (props: { theme?: ThemeType }) => {
130
133
  };
131
134
 
132
135
  const navigateToEdit = useCallback((mode: 'add' | 'update', timeSchedule?: Timer) => {
133
- const path = mode === 'add' ? ui_biz_routerKey.ui_biz_time_schedule_add_new : ui_biz_routerKey.ui_biz_time_schedule_edit_new;
136
+ const {showPresets = true} = params;
137
+ const path = mode === 'add' && showPresets ? ui_biz_routerKey.ui_biz_time_schedule_add_new : ui_biz_routerKey.ui_biz_time_schedule_edit_new;
134
138
  navigation.navigate(path, {
135
139
  mode,
136
140
  name: path,
@@ -0,0 +1,54 @@
1
+ import React from "react";
2
+ import {Utils} from 'tuya-panel-kit';
3
+ import ThemeType from '@ledvance/base/src/config/themeType'
4
+ import OptionGroup from "@ledvance/base/src/components/OptionGroup";
5
+ import I18n from "@ledvance/base/src/i18n";
6
+ import {useReactive} from "ahooks";
7
+ import {AlarmState} from "@ledvance/base/src/utils/interface";
8
+
9
+ const {withTheme} = Utils.ThemeUtils
10
+
11
+ interface AlarmModeItemProps {
12
+ theme?: ThemeType
13
+ name: string
14
+ alarmState: AlarmState
15
+ onAlarmStateChange: (alarmState: AlarmState) => void
16
+ }
17
+
18
+ const AlarmModeItem = (props: AlarmModeItemProps) => {
19
+ const {name, alarmState, onAlarmStateChange} = props;
20
+ const state = useReactive({
21
+ alarmState: alarmState,
22
+ });
23
+ return (
24
+ <OptionGroup
25
+ tips={name}
26
+ selected={state.alarmState}
27
+ options={[{
28
+ title: I18n.getLang('siren_alarm_type_sound'),
29
+ value: AlarmState.AlarmSound,
30
+ onPress: (value) => {
31
+ state.alarmState = value
32
+ onAlarmStateChange(value)
33
+ }
34
+ }, {
35
+ title: I18n.getLang('siren_alarm_type_light'),
36
+ value: AlarmState.AlarmLight,
37
+ onPress: (value) => {
38
+ state.alarmState = value
39
+ onAlarmStateChange(value)
40
+ }
41
+ }, {
42
+ title: I18n.getLang('siren_alarm_type_sound_light'),
43
+ value: AlarmState.AlarmSoundAndLight,
44
+ onPress: (value) => {
45
+ state.alarmState = value
46
+ onAlarmStateChange(value)
47
+ }
48
+ }]}
49
+ />
50
+ )
51
+
52
+ }
53
+
54
+ export default withTheme(AlarmModeItem) as React.ComponentType<AlarmModeItemProps>
@@ -6,7 +6,7 @@ import {
6
6
  ManualSettingProps,
7
7
  modeOptions,
8
8
  OsramFanLightData,
9
- ShutterData,
9
+ ShutterData, SirenData,
10
10
  StripLightData
11
11
  } from '../Interface';
12
12
  import { View, Text, } from 'react-native';
@@ -28,6 +28,7 @@ import { hsv2Hex, mapFloatToRange } from '@ledvance/base/src/utils';
28
28
  import { AdjustType, ApplyForItem } from "@ledvance/base/src/utils/interface";
29
29
  import LdvSlider from '@ledvance/base/src/components/ldvSlider';
30
30
  import OsramFanAdjustView from '@ledvance/base/src/components/OsramFanAdjustView'
31
+ import AlarmModeItem from "./AlarmModeItem";
31
32
 
32
33
  const { convertX: cx } = Utils.RatioUtils;
33
34
  const { withTheme } = Utils.ThemeUtils
@@ -524,7 +525,7 @@ function ManualSettings(props: ManualSettingProps) {
524
525
  <Card style={{ marginHorizontal: cx(24) }}>
525
526
  <Spacer height={cx(16)} />
526
527
  <LdvSlider
527
- title={'Curtain'}
528
+ title={I18n.getLang('curtain_control_headline_text')}
528
529
  value={(state.deviceData as ShutterData).percentControl}
529
530
  min={0}
530
531
  max={100}
@@ -544,22 +545,37 @@ function ManualSettings(props: ManualSettingProps) {
544
545
  )
545
546
  }, [state.deviceData, state.applyForList, props.theme?.type])
546
547
 
547
- const componentRender = useMemo(() => {
548
- const component =
549
- props.manualData.type === DeviceType.MixLight
550
- ? mixLightCard
551
- : props.manualData.type === DeviceType.StripLight
552
- ? stripLightCard
553
- : props.manualData.type === DeviceType.CeilingLight
554
- ? ceilingLightCard
555
- : props.manualData.type === DeviceType.PowerStrip
556
- ? powerStripCard
557
- : props.manualData.type === DeviceType.Shutter
558
- ? shutterCard
559
- : lightSourceCard;
560
- return component;
561
- }, [props.manualData, state.applyForList, state.deviceData, props.theme?.type]);
548
+ const sirenCard = useMemo(() => {
549
+ return (
550
+ <View>
551
+ {state.applyForList.map((item, idx) => (
552
+ <View key={item.dp}>
553
+ <AlarmModeItem
554
+ name={item.name!}
555
+ alarmState={(state.deviceData as SirenData).alarmState}
556
+ onAlarmStateChange={async (alarmState) => {
557
+ (state.deviceData as SirenData).alarmState = alarmState
558
+ state.manualFlag = Symbol()
559
+ }}
560
+ />
561
+ <Spacer />
562
+ </View>
563
+ ))}
564
+ </View>
565
+ )
566
+ }, [state.deviceData, state.applyForList, props.theme?.type])
567
+
568
+ const componentMap = {
569
+ [DeviceType.MixLight]: mixLightCard,
570
+ [DeviceType.StripLight]: stripLightCard,
571
+ [DeviceType.CeilingLight]: ceilingLightCard,
572
+ [DeviceType.PowerStrip]: powerStripCard,
573
+ [DeviceType.Shutter]: shutterCard,
574
+ [DeviceType.Siren]: sirenCard,
575
+ };
562
576
 
577
+ const componentRender =
578
+ componentMap[props.manualData.type] ?? lightSourceCard;
563
579
 
564
580
  return <View>{componentRender}</View>;
565
581
  }