@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,653 @@
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 } 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 LampAdjustView from '@ledvance/base/src/components/LampAdjustView';
25
+ import LdvSlider from '@ledvance/base/src/components/ldvSlider';
26
+ import { useFanMaxSpeed } from '@ledvance/base/src/models/modules/NativePropsSlice';
27
+ import TextButton from '@ledvance/base/src/components/TextButton';
28
+ import {
29
+ MoodNodeTransitionMode,
30
+ stripLightMoodMode,
31
+ stringLightMoodMode,
32
+ lightMoodMode,
33
+ StripLightMoodMode,
34
+ MoodUIInfo,
35
+ } from './Interface';
36
+ import TextFieldStyleButton from '@ledvance/base/src/components/TextFieldStyleButton';
37
+ import FanAdjustView from '@ledvance/base/src/components/FanAdjustView';
38
+ import { RouterKey } from 'navigation/Router';
39
+ import { SelectPageParams } from '@ledvance/ui-biz-bundle/src/modules/select/SelectPage';
40
+ import I18n from '@ledvance/base/src/i18n';
41
+ import Segmented from '@ledvance/base/src/components/Segmented';
42
+ import { MoodNodeInfo } from './Interface';
43
+ import { showDialog } from '@ledvance/base/src/utils/common';
44
+
45
+ const cx = Utils.RatioUtils.convertX;
46
+ interface DynamicMoodEditorPageState {
47
+ headline: string;
48
+ mood: MoodUIInfo;
49
+ mainNode: MoodNodeInfo;
50
+ mainBucketSelected: boolean;
51
+ sceneMode: StripLightMoodMode;
52
+ loading: boolean;
53
+ }
54
+ const DynamicMoodEditorPage = () => {
55
+ const navigation = useNavigation();
56
+ const routeParams = useRoute().params as StaticMoodEditorPageParams;
57
+ const params = cloneDeep(routeParams);
58
+ const moduleParams = params.moduleParams;
59
+ const state = useReactive<DynamicMoodEditorPageState>({
60
+ headline: '',
61
+ mood: params.currentMood,
62
+ mainNode: params.currentMood.mainLamp.nodes[params.currentMood.mainLamp.nodes.length - 1],
63
+ mainBucketSelected: false,
64
+ loading: false,
65
+ sceneMode: moduleParams.isStringLight
66
+ ? stringLightMoodMode
67
+ : moduleParams.isStripLight
68
+ ? stripLightMoodMode
69
+ : lightMoodMode,
70
+ });
71
+
72
+ useEffect(() => {
73
+ state.headline = Strings.getLang(
74
+ params.mode === 'add'
75
+ ? 'add_new_dynamic_mood_headline_text'
76
+ : 'edit_static_mood_headline_text'
77
+ );
78
+ }, [params.mode]);
79
+
80
+ const getColorBlockColor = useCallback((node: MoodNodeInfo) => {
81
+ const s = Math.round(mapFloatToRange(node.s / 100, 30, 100));
82
+ if (node.isColorNode) {
83
+ return hsv2Hex(node.h, s, 100);
84
+ } else {
85
+ return cctToColor(node.colorTemp.toFixed());
86
+ }
87
+ }, []);
88
+
89
+ const getNodeColor = useCallback((node: MoodNodeInfo) => {
90
+ if (node.isColorNode) {
91
+ const s = Math.round(mapFloatToRange(node.s / 100, 30, 100));
92
+ return hsv2Hex(node.h, s, 100);
93
+ }
94
+ return cctToColor(node.colorTemp.toFixed());
95
+ }, []);
96
+
97
+ const getButtonStatus = () => {
98
+ return (
99
+ (params.mode === 'edit' && isEqual(state.mood, routeParams.currentMood)) ||
100
+ !!!state.mood.name ||
101
+ nameRepeat ||
102
+ state.mood.name.length > 32
103
+ );
104
+ };
105
+
106
+ const createSelectModeData = useCallback(
107
+ (mode: number, moodMode?: StripLightMoodMode) => {
108
+ return Object.values(moodMode ? moodMode : state.sceneMode).map(scene => {
109
+ return {
110
+ text: scene.title,
111
+ selected: scene.mode === mode,
112
+ value: scene.mode,
113
+ };
114
+ });
115
+ },
116
+ [state.sceneMode]
117
+ );
118
+
119
+ const createSelectOtherData = useCallback((otherData, expand) => {
120
+ return otherData.map(other => {
121
+ return {
122
+ text: other.label,
123
+ selected: other.value === expand,
124
+ value: other.value,
125
+ };
126
+ });
127
+ }, []);
128
+
129
+ const getSelectOther = useCallback((otherData, expand) => {
130
+ const currentOther = otherData.find(other => other.value === expand);
131
+ return currentOther.label;
132
+ }, []);
133
+
134
+ const nameRepeat = useMemo(() => {
135
+ return !!find(params.moods, m => m.id !== state.mood.id && m.name === state.mood.name);
136
+ }, [state.mood.name]);
137
+
138
+
139
+ return (
140
+ <Page
141
+ backText={Strings.getLang('mesh_device_detail_mode')}
142
+ showBackDialog={true}
143
+ backDialogTitle={Strings.getLang(
144
+ params.mode === 'add'
145
+ ? 'string_light_pp_dialog_sm_add_headline_c'
146
+ : 'manage_user_unsaved_changes_dialog_headline'
147
+ )}
148
+ backDialogContent={Strings.getLang(
149
+ params.mode === 'add'
150
+ ? 'strip_light_static_mood_add_step_2_dialog_text'
151
+ : 'strip_light_static_mood_editor_step_2_dialog_text'
152
+ )}
153
+ headlineText={state.headline}
154
+ rightButtonIcon={getButtonStatus() ? res.ic_uncheck : res.ic_check}
155
+ rightButtonDisabled={getButtonStatus()}
156
+ rightButtonIconClick={async () => {
157
+ if (state.loading) return;
158
+ state.loading = true;
159
+ const res = await params.modDeleteMood(params.mode, cloneDeep(state.mood));
160
+ if (res.success) {
161
+ navigation.navigate(RouterKey.ui_biz_mood);
162
+ }
163
+ state.loading = false;
164
+ }}
165
+ loading={state.loading}
166
+ >
167
+ <ScrollView style={{ flex: 1 }} nestedScrollEnabled={true}>
168
+ <View style={styles.root}>
169
+ <TextField
170
+ style={styles.name}
171
+ value={state.mood.name}
172
+ placeholder={Strings.getLang('edit_static_mood_inputfield_topic_text')}
173
+ onChangeText={text => {
174
+ state.mood.name = text;
175
+ }}
176
+ maxLength={33}
177
+ showError={state.mood.name.length > 32 || nameRepeat}
178
+ tipColor={nameRepeat ? '#f00' : undefined}
179
+ tipIcon={nameRepeat ? res.ic_text_field_input_error : undefined}
180
+ errorText={Strings.getLang(
181
+ nameRepeat ? 'string_light_pp_field_sm_add_error1' : 'add_new_dynamic_mood_alert_text'
182
+ )}
183
+ />
184
+ <Card style={styles.adjustCard}>
185
+ <Spacer height={cx(16)} />
186
+ <View style={styles.lightLine}>
187
+ <Text style={styles.light}>
188
+ {Strings.getLang('light_sources_tile_tw_lighting_headline')}
189
+ </Text>
190
+ </View>
191
+ <Spacer height={cx(18)} />
192
+ <TextFieldStyleButton
193
+ style={styles.transitionMode}
194
+ text={state.sceneMode[state.mood.mainLamp.mode]?.title}
195
+ placeholder={Strings.getLang('add_new_dynamic_mood_color_changing_mode_headline')}
196
+ onPress={() => {
197
+ const paramsSelect: SelectPageParams<number> = {
198
+ title: I18n.getLang('add_new_dynamic_mood_color_changing_mode_headline'),
199
+ data: createSelectModeData(state.mood.mainLamp.mode),
200
+ onSelect: selectPageData => {
201
+ state.mood.mainLamp.mode = selectPageData.value;
202
+ },
203
+ };
204
+ navigation.navigate(RouterKey.ui_biz_select_page, paramsSelect);
205
+ }}
206
+ />
207
+ <Spacer height={cx(10)} />
208
+ <LdvSlider
209
+ title={Strings.getLang('add_new_dynamic_mood_lights_field_speed_topic_text')}
210
+ value={state.mood.mainLamp.speed}
211
+ onValueChange={() => {}}
212
+ onSlidingComplete={value => {
213
+ state.mood.mainLamp.speed = value;
214
+ }}
215
+ />
216
+ <Spacer height={cx(16)} />
217
+ {state.sceneMode[state.mood.mainLamp.mode]?.turnOn && (
218
+ <View style={styles.transitionMode}>
219
+ <Segmented
220
+ value={state.mood.mainLamp.direction}
221
+ options={[
222
+ {
223
+ label: I18n.getLang('add_new_dynamic_mood_strip_lights_switch_tab_text1'),
224
+ value: 0,
225
+ },
226
+ {
227
+ label: I18n.getLang('add_new_dynamic_mood_strip_lights_switch_tab_text2'),
228
+ value: 1,
229
+ },
230
+ ]}
231
+ onChange={v => (state.mood.mainLamp.direction = Number(v))}
232
+ />
233
+ <Spacer />
234
+ </View>
235
+ )}
236
+ {state.sceneMode[state.mood.mainLamp.mode]?.paragraph && (
237
+ <View style={styles.transitionMode}>
238
+ <Segmented
239
+ value={state.mood.mainLamp.segmented}
240
+ options={[
241
+ {
242
+ label: I18n.getLang('add_new_dynamic_mood_strip_lights_switch_tab_text3'),
243
+ value: 0,
244
+ },
245
+ {
246
+ label: I18n.getLang('add_new_dynamic_mood_strip_lights_switch_tab_text4'),
247
+ value: 1,
248
+ },
249
+ ]}
250
+ onChange={v => (state.mood.mainLamp.segmented = Number(v))}
251
+ />
252
+ <Spacer />
253
+ </View>
254
+ )}
255
+ {state.sceneMode[state.mood.mainLamp.mode]?.other && (
256
+ <>
257
+ <TextFieldStyleButton
258
+ style={styles.transitionMode}
259
+ text={getSelectOther(
260
+ state.sceneMode[state.mood.mainLamp.mode]?.other,
261
+ state.mood.mainLamp.expand
262
+ )}
263
+ placeholder={I18n.getLang(
264
+ 'add_new_dynamic_mood_strip_lights_selectionfield2_topic_text'
265
+ )}
266
+ onPress={() => {
267
+ const paramsSelect: SelectPageParams<number> = {
268
+ title: I18n.getLang(
269
+ 'add_new_dynamic_mood_strip_lights_selectionfield2_topic_text'
270
+ ),
271
+ data: createSelectOtherData(
272
+ state.sceneMode[state.mood.mainLamp.mode]?.other,
273
+ state.mood.mainLamp.expand
274
+ ),
275
+ onSelect: selectPageData => {
276
+ state.mood.mainLamp.expand = selectPageData.value;
277
+ },
278
+ };
279
+ navigation.navigate(RouterKey.ui_biz_select_page, paramsSelect);
280
+ }}
281
+ />
282
+ <Spacer />
283
+ </>
284
+ )}
285
+ <View style={styles.nodesAdjust}>
286
+ <View style={styles.adjustButtons}>
287
+ <TouchableOpacity
288
+ onPress={() => {
289
+ state.mainBucketSelected = true;
290
+ }}
291
+ >
292
+ <Image
293
+ style={[
294
+ styles.adjustButton,
295
+ { tintColor: state.mainBucketSelected ? '#f60' : '#666' },
296
+ ]}
297
+ source={res.ic_paint_bucket}
298
+ />
299
+ </TouchableOpacity>
300
+ <TouchableOpacity
301
+ onPress={() => {
302
+ state.mainBucketSelected = false;
303
+ }}
304
+ >
305
+ <Image
306
+ style={[
307
+ styles.adjustButton,
308
+ { tintColor: state.mainBucketSelected ? '#666' : '#f60' },
309
+ ]}
310
+ source={res.ic_colorize}
311
+ />
312
+ </TouchableOpacity>
313
+ </View>
314
+ <FlatList
315
+ data={state.mood.mainLamp.nodes}
316
+ style={styles.nodeList}
317
+ renderItem={({ item, index }) => {
318
+ return (
319
+ <View style={styles.nodeItem}>
320
+ <TouchableOpacity
321
+ style={[
322
+ styles.nodeBlock,
323
+ {
324
+ backgroundColor: getNodeColor(item),
325
+ },
326
+ ]}
327
+ onPress={() => {
328
+ state.mainNode = item;
329
+ }}
330
+ />
331
+ <TouchableOpacity
332
+ style={styles.nodeDeleteBtn}
333
+ disabled={state.mood.mainLamp.nodes.length < 3}
334
+ onPress={() => {
335
+ state.mood.mainLamp.nodes.splice(index, 1);
336
+ state.mainNode = state.mood.mainLamp.nodes[state.mood.mainLamp.nodes.length - 1];
337
+ }}
338
+ >
339
+ <Image
340
+ style={[
341
+ styles.nodeDeleteIcon,
342
+ {
343
+ tintColor: state.mood.mainLamp.nodes.length < 3 ? '#ccc' : '#666',
344
+ },
345
+ ]}
346
+ source={res.ic_mood_del}
347
+ />
348
+ </TouchableOpacity>
349
+ </View>
350
+ );
351
+ }}
352
+ keyExtractor={(_, index) => `${index}`}
353
+ ItemSeparatorComponent={() => <Spacer height={cx(12)} />}
354
+ ListFooterComponent={() => {
355
+ if (state.mood.mainLamp.nodes.length >= 8) {
356
+ return <></>;
357
+ }
358
+ return (
359
+ <View>
360
+ <Spacer height={cx(12)} />
361
+ <TouchableOpacity
362
+ style={styles.nodeAddBtn}
363
+ onPress={() => {
364
+ const node = {
365
+ ...state.mainNode,
366
+ };
367
+ state.mood.mainLamp.nodes.push(node);
368
+ state.mainNode = node;
369
+ }}
370
+ >
371
+ <Image
372
+ style={{
373
+ width: cx(18),
374
+ height: cx(18),
375
+ tintColor: '#000',
376
+ }}
377
+ source={{ uri: res.add }}
378
+ />
379
+ </TouchableOpacity>
380
+ </View>
381
+ );
382
+ }}
383
+ />
384
+ </View>
385
+ <Spacer />
386
+ <View style={styles.lightLine}>
387
+ <Text style={styles.light}>
388
+ {Strings.getLang('add_new_dynamic_mood_lights_field_headline2_text')}
389
+ </Text>
390
+ <View
391
+ style={[styles.preview, { backgroundColor: getColorBlockColor(state.mainNode) }]}
392
+ />
393
+ </View>
394
+ <Spacer />
395
+ <LampAdjustView
396
+ isSupportColor={moduleParams.isSupportColor}
397
+ isSupportBrightness={moduleParams.isSupportBrightness}
398
+ isSupportTemperature={moduleParams.isSupportTemperature}
399
+ isColorMode={state.mainNode.isColorNode}
400
+ reserveSV={true}
401
+ setIsColorMode={isColorMode => {
402
+ if (state.mainBucketSelected) {
403
+ state.mood.mainLamp.nodes.forEach(node => {
404
+ node.isColorNode = isColorMode;
405
+ if (isColorMode && node.h === 0 && node.s === 0 && node.v === 0) {
406
+ node.s = 100;
407
+ node.v = 100;
408
+ } else {
409
+ if (node.brightness === 0 && node.colorTemp === 0) {
410
+ node.brightness = 100;
411
+ }
412
+ }
413
+ });
414
+ } else {
415
+ state.mainNode.isColorNode = isColorMode;
416
+ if (
417
+ isColorMode &&
418
+ state.mainNode.h === 0 &&
419
+ state.mainNode.s === 0 &&
420
+ state.mainNode.v === 0
421
+ ) {
422
+ state.mainNode.s = 100;
423
+ state.mainNode.v = 100;
424
+ } else {
425
+ if (state.mainNode.brightness === 0 && state.mainNode.colorTemp === 0) {
426
+ state.mainNode.brightness = 100;
427
+ }
428
+ }
429
+ }
430
+ }}
431
+ h={state.mainNode.h}
432
+ s={state.mainNode.s}
433
+ v={state.mainNode.v}
434
+ onHSVChange={(h, s, v) => {
435
+ if (state.mainBucketSelected) {
436
+ state.mood.mainLamp.nodes.forEach(node => {
437
+ node.isColorNode = true;
438
+ node.h = h;
439
+ node.s = s;
440
+ node.v = v;
441
+ });
442
+ } else {
443
+ state.mainNode.h = h;
444
+ state.mainNode.s = s;
445
+ state.mainNode.v = v;
446
+ }
447
+ }}
448
+ onHSVChangeComplete={(h, s, v) => {
449
+ if (state.mainBucketSelected) {
450
+ state.mood.mainLamp.nodes.forEach(node => {
451
+ node.isColorNode = true;
452
+ node.h = h;
453
+ node.s = s;
454
+ node.v = v;
455
+ });
456
+ } else {
457
+ state.mainNode.h = h;
458
+ state.mainNode.s = s || 1;
459
+ state.mainNode.v = v;
460
+ }
461
+ }}
462
+ colorTemp={state.mainNode.colorTemp}
463
+ brightness={state.mainNode.brightness}
464
+ onCCTChange={cct => {
465
+ if (state.mainBucketSelected) {
466
+ state.mood.mainLamp.nodes.forEach(node => {
467
+ node.isColorNode = false;
468
+ node.colorTemp = cct;
469
+ });
470
+ } else {
471
+ state.mainNode.colorTemp = cct;
472
+ }
473
+ }}
474
+ onCCTChangeComplete={cct => {
475
+ if (state.mainBucketSelected) {
476
+ state.mood.mainLamp.nodes.forEach(node => {
477
+ node.isColorNode = false;
478
+ node.colorTemp = cct;
479
+ });
480
+ } else {
481
+ state.mainNode.colorTemp = cct;
482
+ }
483
+ }}
484
+ onBrightnessChange={brightness => {
485
+ if (state.mainBucketSelected) {
486
+ state.mood.mainLamp.nodes.forEach(node => {
487
+ node.isColorNode = false;
488
+ node.brightness = brightness;
489
+ });
490
+ } else {
491
+ state.mainNode.brightness = brightness;
492
+ }
493
+ }}
494
+ onBrightnessChangeComplete={brightness => {
495
+ if (state.mainBucketSelected) {
496
+ state.mood.mainLamp.nodes.forEach(node => {
497
+ node.isColorNode = false;
498
+ node.brightness = brightness;
499
+ });
500
+ } else {
501
+ state.mainNode.brightness = brightness;
502
+ }
503
+ }}
504
+ />
505
+ </Card>
506
+ <Spacer />
507
+ {(moduleParams.isFanLight || moduleParams.isUVCFan) && (
508
+ <FanAdjustView
509
+ fanEnable={!!state.mood.mainLamp.fanEnable}
510
+ fanSpeed={state.mood.mainLamp.fanSpeed || 1}
511
+ maxFanSpeed={useFanMaxSpeed()}
512
+ onFanSwitch={fanEnable => {
513
+ state.mood.mainLamp.fanEnable = fanEnable;
514
+ }}
515
+ onFanSpeedChange={fanSpeed => {
516
+ state.mood.mainLamp.fanSpeed = fanSpeed;
517
+ }}
518
+ onFanSpeedChangeComplete={fanSpeed => {
519
+ state.mood.mainLamp.fanSpeed = fanSpeed;
520
+ }}
521
+ style={styles.fanAdjustCard}
522
+ />
523
+ )}
524
+ {params.mode === 'edit' && (
525
+ <View style={{ marginTop: cx(20), marginHorizontal: cx(24) }}>
526
+ <TextButton
527
+ style={styles.deleteBtn}
528
+ textStyle={styles.deleteBtnText}
529
+ text={Strings.getLang('edit_static_mood_button_delete_text')}
530
+ onPress={() => {
531
+ showDialog({
532
+ method: 'confirm',
533
+ title: I18n.getLang('string_light_pp_dialog_sm_ed_headline_d'),
534
+ subTitle: I18n.getLang('strip_light_static_mood_edit_dialog_text'),
535
+ onConfirm: async (_, { close }) => {
536
+ close()
537
+ if (state.loading) return
538
+ state.loading = true
539
+ const res = await params.modDeleteMood('del', state.mood);
540
+ state.loading = false
541
+ if (res.success) {
542
+ navigation.navigate(RouterKey.ui_biz_mood);
543
+ }
544
+ }
545
+ })
546
+ }}
547
+ />
548
+ </View>
549
+ )}
550
+ <Spacer />
551
+ </View>
552
+ </ScrollView>
553
+ </Page>
554
+ );
555
+ };
556
+ const styles = StyleSheet.create({
557
+ root: {
558
+ flex: 1,
559
+ flexDirection: 'column',
560
+ },
561
+ name: {
562
+ marginHorizontal: cx(24),
563
+ },
564
+ adjustCard: {
565
+ marginVertical: cx(12),
566
+ marginHorizontal: cx(24),
567
+ },
568
+ fanAdjustCard: {
569
+ marginHorizontal: cx(24),
570
+ },
571
+ lightLine: {
572
+ flexDirection: 'row',
573
+ marginHorizontal: cx(16),
574
+ },
575
+ light: {
576
+ color: '#000',
577
+ fontSize: cx(18),
578
+ fontFamily: 'helvetica_neue_lt_std_bd',
579
+ },
580
+ transitionMode: {
581
+ marginHorizontal: cx(16),
582
+ },
583
+ preview: {
584
+ width: cx(20),
585
+ height: cx(20),
586
+ marginStart: cx(12),
587
+ borderRadius: cx(4),
588
+ },
589
+ nodesAdjust: {
590
+ flexDirection: 'row',
591
+ alignItems: 'center',
592
+ },
593
+ adjustButtons: {
594
+ width: cx(44),
595
+ marginStart: cx(16),
596
+ },
597
+ adjustButton: {
598
+ width: cx(44),
599
+ height: cx(44),
600
+ },
601
+ nodeList: {
602
+ flex: 1,
603
+ marginHorizontal: cx(16),
604
+ },
605
+ nodeItem: {
606
+ flexDirection: 'row',
607
+ alignItems: 'center',
608
+ },
609
+ nodeBlock: {
610
+ flex: 1,
611
+ height: cx(40),
612
+ borderRadius: cx(8),
613
+ },
614
+ nodeDeleteBtn: {
615
+ width: cx(24),
616
+ height: cx(30),
617
+ justifyContent: 'center',
618
+ alignItems: 'center',
619
+ },
620
+ nodeDeleteIcon: {
621
+ width: cx(16),
622
+ height: cx(16),
623
+ },
624
+ nodeAddBtn: {
625
+ height: cx(40),
626
+ justifyContent: 'center',
627
+ alignItems: 'center',
628
+ marginEnd: cx(26),
629
+ borderRadius: cx(8),
630
+ borderWidth: cx(1),
631
+ borderStyle: 'dashed',
632
+ borderColor: '#666',
633
+ backgroundColor: '#f6f6f6',
634
+ },
635
+ deleteBtn: {
636
+ width: '100%',
637
+ height: cx(50),
638
+ backgroundColor: '#666',
639
+ borderRadius: cx(8),
640
+ },
641
+ deleteBtnText: {
642
+ color: '#fff',
643
+ fontSize: cx(16),
644
+ fontFamily: 'helvetica_neue_lt_std_bd',
645
+ },
646
+ });
647
+ export default DynamicMoodEditorPage;
648
+ export function getTransitionModeString(transitionMode: MoodNodeTransitionMode): string {
649
+ if (transitionMode === MoodNodeTransitionMode.Jump) {
650
+ return Strings.getLang('other_lights_modes_jump_text');
651
+ }
652
+ return Strings.getLang('other_lights_modes_gradient_text');
653
+ }