@ledvance/group-ui-biz-bundle 1.0.45 → 1.0.47

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