@ledvance/ui-biz-bundle 1.1.55 → 1.1.57

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 (70) hide show
  1. package/package.json +2 -1
  2. package/src/modules/biorhythm/Router.ts +34 -0
  3. package/src/modules/fixedTime/Router.ts +26 -0
  4. package/src/modules/flags/FlagActions.ts +12 -4
  5. package/src/modules/flags/FlagPage.tsx +31 -11
  6. package/src/modules/flags/Router.ts +25 -0
  7. package/src/modules/history/Router.ts +16 -0
  8. package/src/modules/mood/FantasyRouter.ts +35 -0
  9. package/src/modules/mood/MixMood/Router.ts +44 -0
  10. package/src/modules/mood/Router.ts +53 -0
  11. package/src/modules/music/Router.ts +16 -0
  12. package/src/modules/powerOnBehavior/Router.ts +16 -0
  13. package/src/modules/randomTime/Router.ts +25 -0
  14. package/src/modules/sleepWakeup/Router.ts +25 -0
  15. package/src/modules/timeSchedule/Router.ts +25 -0
  16. package/src/modules/timer/Router.ts +16 -0
  17. package/src/navigation/Routers.d.ts +0 -7
  18. package/src/navigation/Routers.ts +15 -304
  19. package/src/newModules/childLock/ChildLockPage.tsx +97 -0
  20. package/src/newModules/childLock/Router.ts +16 -0
  21. package/src/newModules/energyConsumption/EnergyConsumptionActions.ts +23 -0
  22. package/src/newModules/energyConsumption/EnergyConsumptionChart.tsx +84 -0
  23. package/src/newModules/energyConsumption/EnergyConsumptionDetail.tsx +321 -0
  24. package/src/newModules/energyConsumption/EnergyConsumptionPage.tsx +392 -0
  25. package/src/newModules/energyConsumption/Router.ts +34 -0
  26. package/src/newModules/energyConsumption/co2Data.ts +23655 -0
  27. package/src/newModules/energyConsumption/component/BarChart.tsx +93 -0
  28. package/src/newModules/energyConsumption/component/EnergyModal.tsx +282 -0
  29. package/src/newModules/energyConsumption/component/Overview.tsx +116 -0
  30. package/src/newModules/fixedTime/FixedTimeActions.ts +234 -0
  31. package/src/newModules/fixedTime/FixedTimeDetailPage.tsx +341 -0
  32. package/src/newModules/fixedTime/FixedTimePage.tsx +231 -0
  33. package/src/newModules/fixedTime/Router.ts +25 -0
  34. package/src/newModules/lightMode/LightModePage.tsx +204 -0
  35. package/src/newModules/lightMode/Router.ts +16 -0
  36. package/src/newModules/mood/AddMoodPage.tsx +178 -0
  37. package/src/newModules/mood/DynamicMoodEditorPage.tsx +653 -0
  38. package/src/newModules/mood/Interface.ts +219 -0
  39. package/src/newModules/mood/MixDynamicMoodEditor.tsx +781 -0
  40. package/src/newModules/mood/MoodActions.ts +235 -0
  41. package/src/newModules/mood/MoodInfo.ts +2151 -0
  42. package/src/newModules/mood/MoodItem.tsx +148 -0
  43. package/src/newModules/mood/MoodPage.tsx +385 -0
  44. package/src/newModules/mood/MoodParse.ts +442 -0
  45. package/src/newModules/mood/RecommendMoodItem.tsx +68 -0
  46. package/src/newModules/mood/Router.ts +53 -0
  47. package/src/newModules/mood/StaticMoodEditorPage.tsx +343 -0
  48. package/src/newModules/mood/tools.ts +12 -0
  49. package/src/newModules/overchargeSwitch/OverchargeSwitchPage.tsx +96 -0
  50. package/src/newModules/overchargeSwitch/Router.ts +16 -0
  51. package/src/newModules/powerOnBehavior/LightBehaviorPage.tsx +266 -0
  52. package/src/newModules/powerOnBehavior/PlugBehaviorPage.tsx +173 -0
  53. package/src/newModules/powerOnBehavior/PowerOnBehaviorActions.ts +106 -0
  54. package/src/newModules/powerOnBehavior/Router.ts +16 -0
  55. package/src/newModules/randomTime/RandomTimeActions.ts +232 -0
  56. package/src/newModules/randomTime/RandomTimeDetailPage.tsx +322 -0
  57. package/src/newModules/randomTime/RandomTimePage.tsx +230 -0
  58. package/src/newModules/randomTime/Router.ts +25 -0
  59. package/src/newModules/randomTime/Summary.tsx +116 -0
  60. package/src/newModules/swithInching/Router.ts +16 -0
  61. package/src/newModules/swithInching/SwithInching.tsx +231 -0
  62. package/src/newModules/swithInching/SwithInchingAction.ts +55 -0
  63. package/src/newModules/swithInching/pickerView.tsx +91 -0
  64. package/src/newModules/timeSchedule/Interface.ts +111 -0
  65. package/src/newModules/timeSchedule/Router.ts +25 -0
  66. package/src/newModules/timeSchedule/TimeScheduleActions.ts +53 -0
  67. package/src/newModules/timeSchedule/TimeScheduleDetailPage.tsx +662 -0
  68. package/src/newModules/timeSchedule/TimeSchedulePage.tsx +222 -0
  69. package/src/newModules/timeSchedule/components/ManuaSettings.tsx +259 -0
  70. package/src/newModules/timeSchedule/components/ScheduleCard.tsx +109 -0
@@ -0,0 +1,781 @@
1
+ import React, { useCallback, useEffect, useMemo } from 'react';
2
+ import {
3
+ FlatList,
4
+ Image,
5
+ ScrollView,
6
+ StyleSheet,
7
+ Text,
8
+ TouchableOpacity,
9
+ View,
10
+ } from 'react-native';
11
+ import { Utils } from 'tuya-panel-kit';
12
+ import { useReactive } from 'ahooks';
13
+ import { cloneDeep, find, isEqual } from 'lodash';
14
+ import Page from '@ledvance/base/src/components/Page';
15
+ import Strings from '@ledvance/base/src/i18n';
16
+ import { StaticMoodEditorPageParams, StaticMoodEditorPageState } from './StaticMoodEditorPage';
17
+ import { useNavigation, useRoute } from '@react-navigation/native';
18
+ import { hsv2Hex, mapFloatToRange } from '@ledvance/base/src/utils';
19
+ import { cctToColor } from '@ledvance/base/src/utils/cctUtils';
20
+ import res from '@ledvance/base/src/res';
21
+ import TextField from '@ledvance/base/src/components/TextField';
22
+ import Card from '@ledvance/base/src/components/Card';
23
+ import Spacer from '@ledvance/base/src/components/Spacer';
24
+ import LdvSlider from '@ledvance/base/src/components/ldvSlider';
25
+ import TextButton from '@ledvance/base/src/components/TextButton';
26
+ import {
27
+ MoodNodeTransitionMode,
28
+ stripLightMoodMode,
29
+ lightMoodMode,
30
+ StripLightMoodMode,
31
+ } from './Interface';
32
+ import TextFieldStyleButton from '@ledvance/base/src/components/TextFieldStyleButton';
33
+ import { showDeleteMoodDialog } from './tools';
34
+ import { RouterKey } from 'navigation/Router';
35
+ import { SelectPageParams } from '@ledvance/ui-biz-bundle/src/modules/select/SelectPage';
36
+ import I18n from '@ledvance/base/src/i18n';
37
+ import Segmented from '@ledvance/base/src/components/Segmented';
38
+ import { MoodNodeInfo } from './Interface';
39
+ import ColorAdjustView from '@ledvance/base/src/components/ColorAdjustView';
40
+ import LdvSwitch from '@ledvance/base/src/components/ldvSwitch';
41
+ import ColorTempAdjustView from '@ledvance/base/src/components/ColorTempAdjustView';
42
+
43
+ const cx = Utils.RatioUtils.convertX;
44
+ interface MixDynamicMoodEditorPageState extends StaticMoodEditorPageState {
45
+ mainBucketSelected: boolean;
46
+ secondaryBucketSelected: boolean;
47
+ mainNodeIdx: number;
48
+ secondaryIdx: number;
49
+ sceneMode: StripLightMoodMode;
50
+ }
51
+ const MixDynamicMoodEditorPage = () => {
52
+ const navigation = useNavigation();
53
+ const routeParams = useRoute().params as StaticMoodEditorPageParams;
54
+ const params = cloneDeep(routeParams);
55
+ const moduleParams = params.moduleParams;
56
+ const state = useReactive<MixDynamicMoodEditorPageState>({
57
+ headline: '',
58
+ mood: params.currentMood,
59
+ mainNode: params.currentMood.mainLamp.nodes[params.currentMood.mainLamp.nodes.length - 1],
60
+ secondaryNode:
61
+ params.currentMood.secondaryLamp.nodes[params.currentMood.secondaryLamp.nodes.length - 1],
62
+ mainNodeIdx: params.currentMood.mainLamp.nodes.length - 1,
63
+ secondaryIdx: params.currentMood.secondaryLamp.nodes.length - 1,
64
+ mainBucketSelected: false,
65
+ secondaryBucketSelected: false,
66
+ loading: false,
67
+ sceneMode: moduleParams.isCeilingLight ? stripLightMoodMode : lightMoodMode,
68
+ });
69
+ useEffect(() => {
70
+ state.headline = Strings.getLang(
71
+ params.mode === 'add'
72
+ ? 'add_new_dynamic_mood_headline_text'
73
+ : 'edit_static_mood_headline_text'
74
+ );
75
+ }, [params.mode]);
76
+
77
+ const getColorBlockColor = useCallback((node: MoodNodeInfo) => {
78
+ const s = Math.round(mapFloatToRange(node.s / 100, 30, 100));
79
+ if (node.isColorNode) {
80
+ return hsv2Hex(node.h, s, 100);
81
+ } else {
82
+ return cctToColor(node.colorTemp.toFixed());
83
+ }
84
+ }, []);
85
+
86
+ const getNodeColor = useCallback((node: MoodNodeInfo) => {
87
+ if (node.isColorNode) {
88
+ const s = Math.round(mapFloatToRange(node.s / 100, 30, 100));
89
+ return hsv2Hex(node.h, s, 100);
90
+ }
91
+ return cctToColor(node.colorTemp.toFixed());
92
+ }, []);
93
+
94
+ const getButtonStatus = () => {
95
+ return (
96
+ (params.mode === 'edit' && isEqual(state.mood, routeParams.currentMood)) ||
97
+ !!!state.mood.name ||
98
+ nameRepeat ||
99
+ state.mood.name.length > 32
100
+ );
101
+ };
102
+
103
+ const createSelectModeData = useCallback(
104
+ (mode: number, moodMode: StripLightMoodMode) => {
105
+ return Object.values(moodMode).map(scene => {
106
+ return {
107
+ text: scene.title,
108
+ selected: scene.mode === mode,
109
+ value: scene.mode,
110
+ };
111
+ });
112
+ },
113
+ []
114
+ );
115
+
116
+ const createSelectOtherData = useCallback((otherData, expand) => {
117
+ return otherData.map(other => {
118
+ return {
119
+ text: other.label,
120
+ selected: other.value === expand,
121
+ value: other.value,
122
+ };
123
+ });
124
+ }, []);
125
+
126
+ const getSelectOther = useCallback((otherData, expand) => {
127
+ const currentOther = otherData.find(other => other.value === expand);
128
+ return currentOther.label;
129
+ }, []);
130
+
131
+ const nameRepeat = useMemo(() => {
132
+ return !!find(params.moods, m => m.id !== state.mood.id && m.name === state.mood.name);
133
+ }, [state.mood.name]);
134
+
135
+ return (
136
+ <Page
137
+ backText={Strings.getLang('mesh_device_detail_mode')}
138
+ showBackDialog={true}
139
+ backDialogTitle={Strings.getLang(
140
+ params.mode === 'add'
141
+ ? 'string_light_pp_dialog_sm_add_headline_c'
142
+ : 'manage_user_unsaved_changes_dialog_headline'
143
+ )}
144
+ backDialogContent={Strings.getLang(
145
+ params.mode === 'add'
146
+ ? 'strip_light_static_mood_add_step_2_dialog_text'
147
+ : 'strip_light_static_mood_editor_step_2_dialog_text'
148
+ )}
149
+ headlineText={state.headline}
150
+ rightButtonIcon={getButtonStatus() ? res.ic_uncheck : res.ic_check}
151
+ rightButtonDisabled={getButtonStatus()}
152
+ rightButtonIconClick={async () => {
153
+ if (state.loading) return;
154
+ state.loading = true;
155
+ const newMood = cloneDeep(state.mood)
156
+ if(moduleParams.isSupportBrightness){
157
+ newMood.mainLamp.type = 1
158
+ }
159
+ if(moduleParams.isSupportBrightness && moduleParams.isSupportTemperature){
160
+ newMood.mainLamp.type = 2
161
+ }
162
+ if(moduleParams.isSupportColor){
163
+ newMood.secondaryLamp.type = 3
164
+ }
165
+ const res = await params.modDeleteMood(params.mode, newMood);
166
+ if (res.success) {
167
+ navigation.navigate(RouterKey.ui_biz_mood);
168
+ }
169
+ state.loading = false;
170
+ }}
171
+ loading={state.loading}
172
+ >
173
+ <ScrollView style={{ flex: 1 }} nestedScrollEnabled={true}>
174
+ <View style={styles.root}>
175
+ <TextField
176
+ style={styles.name}
177
+ value={state.mood.name}
178
+ placeholder={Strings.getLang('edit_static_mood_inputfield_topic_text')}
179
+ onChangeText={text => {
180
+ state.mood.name = text;
181
+ }}
182
+ maxLength={33}
183
+ showError={state.mood.name.length > 32 || nameRepeat}
184
+ tipColor={nameRepeat ? '#f00' : undefined}
185
+ tipIcon={nameRepeat ? res.ic_text_field_input_error : undefined}
186
+ errorText={Strings.getLang(
187
+ nameRepeat ? 'string_light_pp_field_sm_add_error1' : 'add_new_dynamic_mood_alert_text'
188
+ )}
189
+ />
190
+ <Card style={styles.adjustCard}>
191
+ <LdvSwitch
192
+ title={I18n.getLang('light_sources_tile_main_lighting_headline')}
193
+ color="#fff"
194
+ colorAlpha={1}
195
+ enable={!!state.mood.mainLamp.enable}
196
+ setEnable={v => {
197
+ if (v && !state.mood.mainLamp.nodes.length) {
198
+ state.mood.mainLamp.nodes.push(
199
+ {
200
+ h: 0,
201
+ s: 0,
202
+ v: 0,
203
+ brightness: 100,
204
+ colorTemp: 0,
205
+ isColorNode: false,
206
+ },
207
+ {
208
+ h: 0,
209
+ s: 0,
210
+ v: 0,
211
+ brightness: 100,
212
+ colorTemp: 0,
213
+ isColorNode: false,
214
+ }
215
+ );
216
+ state.mood.mainLamp.mode = MoodNodeTransitionMode.Gradient;
217
+ state.mood.mainLamp.speed = 75;
218
+ state.mainNodeIdx = 1;
219
+ state.mainNode = state.mood.mainLamp.nodes[1];
220
+ }
221
+
222
+ state.mood.mainLamp.enable = v;
223
+ }}
224
+ showSwitch={!!moduleParams.isMixLight}
225
+ />
226
+ {(!moduleParams.isMixLight || state.mood.mainLamp.enable) && (
227
+ <>
228
+ <TextFieldStyleButton
229
+ style={styles.transitionMode}
230
+ text={lightMoodMode[state.mood.mainLamp.mode]?.title}
231
+ placeholder={I18n.getLang('add_new_dynamic_mood_color_changing_mode_headline')}
232
+ onPress={() => {
233
+ const paramsSelect: SelectPageParams<number> = {
234
+ title: I18n.getLang('add_new_dynamic_mood_color_changing_mode_headline'),
235
+ data: createSelectModeData(state.mood.mainLamp.mode, lightMoodMode),
236
+ onSelect: selectPageData => {
237
+ state.mood.mainLamp.mode = selectPageData.value;
238
+ },
239
+ };
240
+ navigation.navigate(RouterKey.ui_biz_select_page, paramsSelect);
241
+ }}
242
+ />
243
+ <Spacer height={cx(10)} />
244
+ <LdvSlider
245
+ title={I18n.getLang('add_new_dynamic_mood_lights_field_speed_topic_text')}
246
+ value={state.mood.mainLamp.speed}
247
+ onValueChange={() => {}}
248
+ onSlidingComplete={value => {
249
+ state.mood.mainLamp.speed = value;
250
+ }}
251
+ />
252
+ <Spacer height={cx(16)} />
253
+ <View style={styles.nodesAdjust}>
254
+ <View style={styles.adjustButtons}>
255
+ <TouchableOpacity
256
+ onPress={() => {
257
+ state.mainBucketSelected = true;
258
+ }}
259
+ >
260
+ <Image
261
+ style={[
262
+ styles.adjustButton,
263
+ { tintColor: state.mainBucketSelected ? '#f60' : '#666' },
264
+ ]}
265
+ source={res.ic_paint_bucket}
266
+ />
267
+ </TouchableOpacity>
268
+ <TouchableOpacity
269
+ onPress={() => {
270
+ state.mainBucketSelected = false;
271
+ }}
272
+ >
273
+ <Image
274
+ style={[
275
+ styles.adjustButton,
276
+ { tintColor: state.mainBucketSelected ? '#666' : '#f60' },
277
+ ]}
278
+ source={res.ic_colorize}
279
+ />
280
+ </TouchableOpacity>
281
+ </View>
282
+ <FlatList
283
+ data={state.mood.mainLamp.nodes}
284
+ style={styles.nodeList}
285
+ renderItem={({ item, index }) => {
286
+ return (
287
+ <View style={styles.nodeItem}>
288
+ <TouchableOpacity
289
+ style={[
290
+ styles.nodeBlock,
291
+ {
292
+ backgroundColor: getNodeColor(item),
293
+ },
294
+ ]}
295
+ onPress={() => {
296
+ state.mainNodeIdx = index;
297
+ state.mainNode = state.mood.mainLamp.nodes[index];
298
+ }}
299
+ />
300
+ <TouchableOpacity
301
+ style={styles.nodeDeleteBtn}
302
+ disabled={state.mood.mainLamp.nodes.length < 3}
303
+ onPress={() => {
304
+ state.mood.mainLamp.nodes.splice(index, 1);
305
+ state.mainNodeIdx = state.mood.mainLamp.nodes.length - 1;
306
+ }}
307
+ >
308
+ <Image
309
+ style={[
310
+ styles.nodeDeleteIcon,
311
+ {
312
+ tintColor: state.mood.mainLamp.nodes.length < 3 ? '#ccc' : '#666',
313
+ },
314
+ ]}
315
+ source={res.ic_mood_del}
316
+ />
317
+ </TouchableOpacity>
318
+ </View>
319
+ );
320
+ }}
321
+ keyExtractor={(_, index) => `${index}`}
322
+ ItemSeparatorComponent={() => <Spacer height={cx(12)} />}
323
+ ListFooterComponent={() => {
324
+ if (state.mood.mainLamp.nodes.length >= 8) {
325
+ return <></>;
326
+ }
327
+ return (
328
+ <View>
329
+ <Spacer height={cx(12)} />
330
+ <TouchableOpacity
331
+ style={styles.nodeAddBtn}
332
+ onPress={() => {
333
+ const node = {
334
+ ...state.mood.mainLamp.nodes[state.mainNodeIdx],
335
+ };
336
+ state.mood.mainLamp.nodes.push(node);
337
+ state.mainNodeIdx = state.mood.mainLamp.nodes.length - 1;
338
+ }}
339
+ >
340
+ <Image
341
+ style={{
342
+ width: cx(18),
343
+ height: cx(18),
344
+ tintColor: '#000',
345
+ }}
346
+ source={{ uri: res.add }}
347
+ />
348
+ </TouchableOpacity>
349
+ </View>
350
+ );
351
+ }}
352
+ />
353
+ </View>
354
+ <Spacer />
355
+ <ColorTempAdjustView
356
+ isSupportBrightness={moduleParams.isSupportBrightness}
357
+ isSupportTemperature={moduleParams.isSupportTemperature}
358
+ colorTemp={state.mood.mainLamp.nodes[state.mainNodeIdx].colorTemp}
359
+ brightness={state.mood.mainLamp.nodes[state.mainNodeIdx].brightness}
360
+ onBrightnessChangeComplete={bright => {
361
+ state.mood.mainLamp.nodes.forEach((node, idx) => {
362
+ if (state.mainBucketSelected) {
363
+ node.brightness = bright;
364
+ }
365
+ if (state.mainNodeIdx === idx) {
366
+ node.brightness = bright;
367
+ }
368
+ });
369
+ }}
370
+ onCCTChangeComplete={cct => {
371
+ state.mood.mainLamp.nodes.forEach((node, idx) => {
372
+ if (state.mainBucketSelected) {
373
+ node.colorTemp = cct;
374
+ }
375
+ if (state.mainNodeIdx === idx) {
376
+ node.colorTemp = cct;
377
+ }
378
+ });
379
+ }}
380
+ />
381
+ <Spacer height={cx(10)} />
382
+ </>
383
+ )}
384
+ </Card>
385
+ <Card style={styles.adjustCard}>
386
+ <LdvSwitch
387
+ title={I18n.getLang('light_sources_tile_sec_lighting_headline')}
388
+ color={'#fff'}
389
+ colorAlpha={1}
390
+ enable={!!state.mood.secondaryLamp.enable}
391
+ setEnable={v => {
392
+ state.mood.secondaryLamp.enable = v;
393
+ if (v && !state.mood.secondaryLamp.nodes.length) {
394
+ state.mood.secondaryLamp.nodes.push(
395
+ {
396
+ h: 0,
397
+ s: 100,
398
+ v: 100,
399
+ brightness: 0,
400
+ colorTemp: 0,
401
+ isColorNode: true,
402
+ },
403
+ {
404
+ h: 0,
405
+ s: 100,
406
+ v: 100,
407
+ brightness: 0,
408
+ colorTemp: 0,
409
+ isColorNode: true,
410
+ }
411
+ );
412
+ state.mood.secondaryLamp.mode = MoodNodeTransitionMode.Gradient;
413
+ state.mood.secondaryLamp.speed = 75;
414
+ state.secondaryIdx = 1;
415
+ state.secondaryNode = state.mood.secondaryLamp.nodes[1];
416
+ }
417
+ }}
418
+ showSwitch={!!moduleParams.isMixLight}
419
+ />
420
+ {(!moduleParams.isMixLight || state.mood.secondaryLamp.enable) && (
421
+ <>
422
+ <TextFieldStyleButton
423
+ style={styles.transitionMode}
424
+ text={state.sceneMode[state.mood.secondaryLamp.mode]?.title}
425
+ placeholder={I18n.getLang('add_new_dynamic_mood_color_changing_mode_headline')}
426
+ onPress={() => {
427
+ const paramsSelect: SelectPageParams<number> = {
428
+ title: I18n.getLang('add_new_dynamic_mood_color_changing_mode_headline'),
429
+ data: createSelectModeData(
430
+ state.mood.secondaryLamp.mode,
431
+ state.sceneMode
432
+ ),
433
+ onSelect: selectPageData => {
434
+ state.mood.secondaryLamp.mode = selectPageData.value;
435
+ },
436
+ };
437
+ navigation.navigate(RouterKey.ui_biz_select_page, paramsSelect);
438
+ }}
439
+ />
440
+ <Spacer height={cx(10)} />
441
+ <LdvSlider
442
+ title={I18n.getLang('add_new_dynamic_mood_lights_field_speed_topic_text')}
443
+ value={state.mood.secondaryLamp.speed}
444
+ onValueChange={() => {}}
445
+ onSlidingComplete={value => {
446
+ state.mood.secondaryLamp.speed = value;
447
+ }}
448
+ />
449
+ <Spacer height={cx(16)} />
450
+ {state.sceneMode[state.mood.secondaryLamp.mode]?.turnOn && (
451
+ <View style={styles.transitionMode}>
452
+ <Segmented
453
+ value={state.mood.secondaryLamp.direction}
454
+ options={[
455
+ {
456
+ label: I18n.getLang('add_new_dynamic_mood_strip_lights_switch_tab_text1'),
457
+ value: 0,
458
+ },
459
+ {
460
+ label: I18n.getLang('add_new_dynamic_mood_strip_lights_switch_tab_text2'),
461
+ value: 1,
462
+ },
463
+ ]}
464
+ onChange={v => (state.mood.secondaryLamp.direction = Number(v))}
465
+ />
466
+ <Spacer />
467
+ </View>
468
+ )}
469
+ {state.sceneMode[state.mood.secondaryLamp.mode]?.paragraph && (
470
+ <View style={styles.transitionMode}>
471
+ <Segmented
472
+ value={state.mood.secondaryLamp.segmented}
473
+ options={[
474
+ {
475
+ label: I18n.getLang('add_new_dynamic_mood_strip_lights_switch_tab_text3'),
476
+ value: 0,
477
+ },
478
+ {
479
+ label: I18n.getLang('add_new_dynamic_mood_strip_lights_switch_tab_text4'),
480
+ value: 1,
481
+ },
482
+ ]}
483
+ onChange={v => (state.mood.secondaryLamp.segmented = Number(v))}
484
+ />
485
+ <Spacer />
486
+ </View>
487
+ )}
488
+ {state.sceneMode[state.mood.secondaryLamp.mode]?.other && (
489
+ <>
490
+ <TextFieldStyleButton
491
+ style={styles.transitionMode}
492
+ text={getSelectOther(
493
+ state.sceneMode[state.mood.secondaryLamp.mode]?.other,
494
+ state.mood.secondaryLamp.expand
495
+ )}
496
+ placeholder={I18n.getLang(
497
+ 'add_new_dynamic_mood_strip_lights_selectionfield2_topic_text'
498
+ )}
499
+ onPress={() => {
500
+ const paramsSelect: SelectPageParams<number> = {
501
+ title: I18n.getLang(
502
+ 'add_new_dynamic_mood_strip_lights_selectionfield2_topic_text'
503
+ ),
504
+ data: createSelectOtherData(
505
+ state.sceneMode[state.mood.secondaryLamp.mode]?.other,
506
+ state.mood.secondaryLamp.expand
507
+ ),
508
+ onSelect: selectPageData => {
509
+ state.mood.secondaryLamp.expand = selectPageData.value;
510
+ },
511
+ };
512
+ navigation.navigate(RouterKey.ui_biz_select_page, paramsSelect);
513
+ }}
514
+ />
515
+ <Spacer />
516
+ </>
517
+ )}
518
+ <View style={styles.nodesAdjust}>
519
+ <View style={styles.adjustButtons}>
520
+ <TouchableOpacity
521
+ onPress={() => {
522
+ state.secondaryBucketSelected = true;
523
+ }}
524
+ >
525
+ <Image
526
+ style={[
527
+ styles.adjustButton,
528
+ { tintColor: state.secondaryBucketSelected ? '#f60' : '#666' },
529
+ ]}
530
+ source={res.ic_paint_bucket}
531
+ />
532
+ </TouchableOpacity>
533
+ <TouchableOpacity
534
+ onPress={() => {
535
+ state.secondaryBucketSelected = false;
536
+ }}
537
+ >
538
+ <Image
539
+ style={[
540
+ styles.adjustButton,
541
+ { tintColor: state.secondaryBucketSelected ? '#666' : '#f60' },
542
+ ]}
543
+ source={res.ic_colorize}
544
+ />
545
+ </TouchableOpacity>
546
+ </View>
547
+ <FlatList
548
+ data={state.mood.secondaryLamp.nodes}
549
+ style={styles.nodeList}
550
+ renderItem={({ item, index }) => {
551
+ return (
552
+ <View style={styles.nodeItem}>
553
+ <TouchableOpacity
554
+ style={[
555
+ styles.nodeBlock,
556
+ {
557
+ backgroundColor: getNodeColor(item),
558
+ },
559
+ ]}
560
+ onPress={() => {
561
+ state.secondaryIdx = index;
562
+ }}
563
+ />
564
+ <TouchableOpacity
565
+ style={styles.nodeDeleteBtn}
566
+ disabled={state.mood.secondaryLamp.nodes.length < 3}
567
+ onPress={() => {
568
+ state.mood.secondaryLamp.nodes.splice(index, 1);
569
+ state.secondaryIdx = state.mood.secondaryLamp.nodes.length - 1;
570
+ }}
571
+ >
572
+ <Image
573
+ style={[
574
+ styles.nodeDeleteIcon,
575
+ {
576
+ tintColor:
577
+ state.mood.secondaryLamp.nodes.length < 3 ? '#ccc' : '#666',
578
+ },
579
+ ]}
580
+ source={res.ic_mood_del}
581
+ />
582
+ </TouchableOpacity>
583
+ </View>
584
+ );
585
+ }}
586
+ keyExtractor={(_, index) => `${index}`}
587
+ ItemSeparatorComponent={() => <Spacer height={cx(12)} />}
588
+ ListFooterComponent={() => {
589
+ if (state.mood.secondaryLamp.nodes.length >= 8) {
590
+ return <></>;
591
+ }
592
+ return (
593
+ <View>
594
+ <Spacer height={cx(12)} />
595
+ <TouchableOpacity
596
+ style={styles.nodeAddBtn}
597
+ onPress={() => {
598
+ const node = {
599
+ ...state.mood.secondaryLamp.nodes[state.secondaryIdx],
600
+ };
601
+ state.mood.secondaryLamp.nodes.push(node);
602
+ state.secondaryIdx = state.mood.secondaryLamp.nodes.length - 1;
603
+ }}
604
+ >
605
+ <Image
606
+ style={{
607
+ width: cx(18),
608
+ height: cx(18),
609
+ tintColor: '#000',
610
+ }}
611
+ source={{ uri: res.add }}
612
+ />
613
+ </TouchableOpacity>
614
+ </View>
615
+ );
616
+ }}
617
+ />
618
+ </View>
619
+ <Spacer />
620
+ <View style={styles.lightLine}>
621
+ <Text style={styles.light}>
622
+ {I18n.getLang('add_new_dynamic_mood_lights_field_headline2_text')}
623
+ </Text>
624
+ <View
625
+ style={[
626
+ styles.preview,
627
+ { backgroundColor: getColorBlockColor(state.secondaryNode) },
628
+ ]}
629
+ />
630
+ </View>
631
+ <Spacer />
632
+ <ColorAdjustView
633
+ h={state.secondaryNode.h}
634
+ s={state.secondaryNode.s}
635
+ v={state.secondaryNode.v}
636
+ reserveSV={true}
637
+ onHSVChange={() => {}}
638
+ onHSVChangeComplete={(h, s, v) => {
639
+ state.mood.secondaryLamp.nodes.forEach((node, idx) => {
640
+ if (state.secondaryBucketSelected) {
641
+ node.h = h;
642
+ node.s = s;
643
+ node.v = v;
644
+ }
645
+ if (state.secondaryIdx === idx) {
646
+ node.h = h;
647
+ node.s = s;
648
+ node.v = v;
649
+ }
650
+ });
651
+ }}
652
+ />
653
+ <Spacer height={cx(10)} />
654
+ </>
655
+ )}
656
+ </Card>
657
+
658
+ {params.mode === 'edit' && (
659
+ <View style={{ marginTop: cx(20), marginHorizontal: cx(24) }}>
660
+ <TextButton
661
+ style={styles.deleteBtn}
662
+ textStyle={styles.deleteBtnText}
663
+ text={Strings.getLang('edit_static_mood_button_delete_text')}
664
+ onPress={() => {
665
+ showDeleteMoodDialog(async (_, { close }) => {
666
+ state.loading = true;
667
+ close();
668
+ const res = await params.modDeleteMood('del', state.mood);
669
+ if (res.success) {
670
+ navigation.navigate(RouterKey.ui_biz_mood);
671
+ }
672
+ state.loading = false;
673
+ });
674
+ }}
675
+ />
676
+ </View>
677
+ )}
678
+ <Spacer />
679
+ </View>
680
+ </ScrollView>
681
+ </Page>
682
+ );
683
+ };
684
+ const styles = StyleSheet.create({
685
+ root: {
686
+ flex: 1,
687
+ flexDirection: 'column',
688
+ },
689
+ name: {
690
+ marginHorizontal: cx(24),
691
+ },
692
+ adjustCard: {
693
+ marginVertical: cx(12),
694
+ marginHorizontal: cx(24),
695
+ },
696
+ fanAdjustCard: {
697
+ marginHorizontal: cx(24),
698
+ },
699
+ lightLine: {
700
+ flexDirection: 'row',
701
+ marginHorizontal: cx(16),
702
+ },
703
+ light: {
704
+ color: '#000',
705
+ fontSize: cx(18),
706
+ fontFamily: 'helvetica_neue_lt_std_bd',
707
+ },
708
+ transitionMode: {
709
+ marginHorizontal: cx(16),
710
+ },
711
+ preview: {
712
+ width: cx(20),
713
+ height: cx(20),
714
+ marginStart: cx(12),
715
+ borderRadius: cx(4),
716
+ },
717
+ nodesAdjust: {
718
+ flexDirection: 'row',
719
+ alignItems: 'center',
720
+ },
721
+ adjustButtons: {
722
+ width: cx(44),
723
+ marginStart: cx(16),
724
+ },
725
+ adjustButton: {
726
+ width: cx(44),
727
+ height: cx(44),
728
+ },
729
+ nodeList: {
730
+ flex: 1,
731
+ marginHorizontal: cx(16),
732
+ },
733
+ nodeItem: {
734
+ flexDirection: 'row',
735
+ alignItems: 'center',
736
+ },
737
+ nodeBlock: {
738
+ flex: 1,
739
+ height: cx(40),
740
+ borderRadius: cx(8),
741
+ },
742
+ nodeDeleteBtn: {
743
+ width: cx(24),
744
+ height: cx(30),
745
+ justifyContent: 'center',
746
+ alignItems: 'center',
747
+ },
748
+ nodeDeleteIcon: {
749
+ width: cx(16),
750
+ height: cx(16),
751
+ },
752
+ nodeAddBtn: {
753
+ height: cx(40),
754
+ justifyContent: 'center',
755
+ alignItems: 'center',
756
+ marginEnd: cx(26),
757
+ borderRadius: cx(8),
758
+ borderWidth: cx(1),
759
+ borderStyle: 'dashed',
760
+ borderColor: '#666',
761
+ backgroundColor: '#f6f6f6',
762
+ },
763
+ deleteBtn: {
764
+ width: '100%',
765
+ height: cx(50),
766
+ backgroundColor: '#666',
767
+ borderRadius: cx(8),
768
+ },
769
+ deleteBtnText: {
770
+ color: '#fff',
771
+ fontSize: cx(16),
772
+ fontFamily: 'helvetica_neue_lt_std_bd',
773
+ },
774
+ });
775
+ export default MixDynamicMoodEditorPage;
776
+ export function getTransitionModeString(transitionMode: MoodNodeTransitionMode): string {
777
+ if (transitionMode === MoodNodeTransitionMode.Jump) {
778
+ return Strings.getLang('other_lights_modes_jump_text');
779
+ }
780
+ return Strings.getLang('other_lights_modes_gradient_text');
781
+ }