@ledvance/group-ui-biz-bundle 1.0.62 → 1.0.64

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/group-ui-biz-bundle",
5
5
  "pid": [],
6
6
  "uiid": "",
7
- "version": "1.0.62",
7
+ "version": "1.0.64",
8
8
  "scripts": {},
9
9
  "dependencies": {
10
10
  "@ledvance/base": "^1.x",
@@ -0,0 +1,25 @@
1
+ import {NavigationRoute} from "tuya-panel-kit";
2
+ import SleepWakeUpPage from "./SleepWakeUpPage";
3
+ import SleepWakeUpDetailPage from "./SleepWakeUpDetailPage";
4
+ import {ui_biz_routerKey} from "../../navigation/Routers";
5
+
6
+ const SleepWakeUpPageRouters: NavigationRoute[] = [
7
+ {
8
+ name: ui_biz_routerKey.group_ui_biz_sleep_wakeUp,
9
+ component: SleepWakeUpPage,
10
+ options: {
11
+ hideTopbar: true,
12
+ showOfflineView: false,
13
+ },
14
+ },
15
+ {
16
+ name: ui_biz_routerKey.group_ui_biz_sleep_wakeUp_detail,
17
+ component: SleepWakeUpDetailPage,
18
+ options: {
19
+ hideTopbar: true,
20
+ showOfflineView: false,
21
+ },
22
+ },
23
+ ]
24
+
25
+ export default SleepWakeUpPageRouters
@@ -0,0 +1,83 @@
1
+ import {useFeatureHook} from "@ledvance/base/src/models/modules/NativePropsSlice"
2
+
3
+ export interface SleepWakeUpItem {
4
+ isSleep: boolean
5
+ enable: boolean
6
+ weeks: number[]
7
+ fade: number
8
+ time: number
9
+ hue: number
10
+ sat: number
11
+ value: number
12
+ brightness: number
13
+ temperature: number
14
+ duration: number
15
+ name: string
16
+ index: number
17
+ isColorMode: boolean
18
+ settingTime: number
19
+ }
20
+
21
+ interface LightConfig {
22
+ sleepMode: SleepWakeUpItem[]
23
+ wakeupMode: SleepWakeUpItem[]
24
+ }
25
+
26
+ export function useSleepPlan() {
27
+ return useFeatureHook<LightConfig, SleepWakeUpItem[]>('sleepMode', [], (val) => encodeSleepOrWakeUp(val))
28
+ }
29
+
30
+ export function useWakeUpPlan() {
31
+ return useFeatureHook<LightConfig, SleepWakeUpItem[]>('wakeupMode', [], (val) => encodeSleepOrWakeUp(val))
32
+ }
33
+
34
+ export function getStartTime(item: SleepWakeUpItem) {
35
+ const time = item.time - (item.isSleep ? 0 : item.fade * 5)
36
+ return time < 0 ? time + 1440 : time
37
+ }
38
+
39
+ export function getEndTime(item: SleepWakeUpItem) {
40
+ const time = item.time + (item.isSleep ? item.fade * 5 : item.duration * 5)
41
+ return time > 1440 ? time - 1440 : time
42
+ }
43
+
44
+ const encodeSleepOrWakeUp = (items: SleepWakeUpItem[]) => {
45
+ const bytes: number[] = []
46
+ bytes.push(numToByte(0))
47
+ bytes.push(numToByte(items.length))
48
+ for (const item of items) {
49
+ bytes.push(numToByte(item.enable ? 1 : 0))
50
+ bytes.push(weeksToByte(item.weeks))
51
+ bytes.push(numToByte(item.fade))
52
+ const hour = Math.trunc(item.time / 60)
53
+ const minute = item.time % 60
54
+ bytes.push(numToByte(hour))
55
+ bytes.push(numToByte(minute))
56
+ bytes.push(...numToTwoBytes(item.hue))
57
+ bytes.push(numToByte(item.sat))
58
+ bytes.push(numToByte(item.value))
59
+ bytes.push(numToByte(item.brightness))
60
+ bytes.push(numToByte(item.temperature))
61
+ if (!item.isSleep) {
62
+ bytes.push(numToByte(item.duration || 0))
63
+ }
64
+ }
65
+
66
+ return bytesToHex(bytes)
67
+ }
68
+
69
+ const numToByte = (num: number) => {
70
+ return num & 0xFF
71
+ }
72
+
73
+ const numToTwoBytes = (num: number) => {
74
+ return [numToByte(num >> 8), numToByte(num)]
75
+ }
76
+
77
+ const weeksToByte = (weeks: number[]) => {
78
+ return weeks.reduce((byte, week, index) => byte | (week << index), 0)
79
+ }
80
+
81
+ const bytesToHex = (bytes: number[]) => {
82
+ return bytes.map(byte => byte.toString(16).padStart(2, '0')).join('')
83
+ }
@@ -0,0 +1,662 @@
1
+ import React, { useCallback, useEffect, useMemo } from 'react';
2
+ import { ScrollView, StyleSheet, Text, View } from 'react-native';
3
+ import { useNavigation } from '@react-navigation/native';
4
+ import Page from '@ledvance/base/src/components/Page';
5
+ import I18n from '@ledvance/base/src/i18n';
6
+ import res from '@ledvance/base/src/res';
7
+ import { TimerPicker, Utils } from 'tuya-panel-kit';
8
+ import { useReactive, useUpdateEffect } from 'ahooks';
9
+ import TextField from '@ledvance/base/src/components/TextField';
10
+ import LdvPickerView from '@ledvance/base/src/components/ldvPickerView';
11
+ import LdvWeekView from '@ledvance/base/src/components/weekSelect';
12
+ import {
13
+ convertMinutesTo12HourFormat,
14
+ loopText,
15
+ showDialog,
16
+ } from '@ledvance/base/src/utils/common';
17
+ import Spacer from '@ledvance/base/src/components/Spacer';
18
+ import DeleteButton from '@ledvance/base/src/components/DeleteButton';
19
+ import { SleepWakeUpPageRouteParams } from './SleepWakeUpPage';
20
+ import LdvSwitch from '@ledvance/base/src/components/ldvSwitch';
21
+ import {cloneDeep, isEqual, omit} from 'lodash';
22
+ import { useSystemTimeFormate } from '@ledvance/base/src/models/modules/NativePropsSlice';
23
+ import { Result } from '@ledvance/base/src/models/modules/Result';
24
+ import InfoText from '@ledvance/base/src/components/InfoText';
25
+ import LampAdjustView from '@ledvance/base/src/components/LampAdjustView';
26
+ import Card from '@ledvance/base/src/components/Card';
27
+ import { hsv2Hex, mapFloatToRange } from '@ledvance/base/src/utils';
28
+ import { cctToColor } from '@ledvance/base/src/utils/cctUtils';
29
+ import { useParams } from '@ledvance/base/src/hooks/Hooks';
30
+ import ColorTempAdjustView from '@ledvance/base/src/components/ColorTempAdjustView';
31
+ import ColorAdjustView from '@ledvance/base/src/components/ColorAdjustView';
32
+ import {getEndTime, getStartTime, SleepWakeUpItem} from "./SleepWakeUpActions";
33
+
34
+ const { convertX: cx } = Utils.RatioUtils;
35
+ const { toFixedString } = Utils.NumberUtils;
36
+ const { withTheme } = Utils.ThemeUtils
37
+
38
+ interface SleepWakeUpDetailPageProps extends SleepWakeUpPageRouteParams {
39
+ mode: 'add' | 'edit';
40
+ isSleep: boolean;
41
+ scheduleItem: any;
42
+ modDeleteTimeSchedule: (
43
+ mode: 'add' | 'edit' | 'del',
44
+ isSleep: boolean,
45
+ sleepWakeUp: SleepWakeUpItem
46
+ ) => Promise<Result<any>>;
47
+ }
48
+
49
+ const SleepWakeUpDetailPage = (props: {theme?: any}) => {
50
+ const navigation = useNavigation();
51
+ const params = useParams<SleepWakeUpDetailPageProps>();
52
+ const is24HourClock = useSystemTimeFormate();
53
+ const state = useReactive({
54
+ sleepWakeUp: cloneDeep(params.scheduleItem) as SleepWakeUpItem,
55
+ loading: false,
56
+ });
57
+
58
+ useEffect(() => {
59
+ if (params.mode !== 'edit') return;
60
+ if (state.sleepWakeUp.isColorMode) {
61
+ state.sleepWakeUp.brightness = 100;
62
+ } else {
63
+ state.sleepWakeUp.sat = 100;
64
+ state.sleepWakeUp.value = 100;
65
+ }
66
+ }, []);
67
+
68
+ useUpdateEffect(() => {
69
+ if (state.sleepWakeUp.fade === 0) {
70
+ state.sleepWakeUp.fade = 1;
71
+ }
72
+ if (state.sleepWakeUp.fade > 24) {
73
+ state.sleepWakeUp.fade = 24;
74
+ }
75
+ }, [state.sleepWakeUp.fade]);
76
+
77
+ useUpdateEffect(() => {
78
+ if (state.sleepWakeUp.duration > 24) {
79
+ state.sleepWakeUp.duration = 24;
80
+ }
81
+ }, [state.sleepWakeUp.duration]);
82
+
83
+ const getBlockColor = useCallback(() => {
84
+ if (state.sleepWakeUp.isColorMode) {
85
+ const sat = Math.round(mapFloatToRange(state.sleepWakeUp.sat / 100, 30, 100));
86
+ return hsv2Hex(state.sleepWakeUp.hue, sat, 100);
87
+ }
88
+ return cctToColor(state.sleepWakeUp.temperature);
89
+ }, [state.sleepWakeUp]);
90
+
91
+ const showBackDialog = () => {
92
+ const excludeKeys: string[] = []
93
+ if (state.sleepWakeUp.isColorMode) {
94
+ excludeKeys.push('brightness', 'temperature')
95
+ } else {
96
+ excludeKeys.push('hue', 'sat', 'value')
97
+ }
98
+ return !isEqual(omit(params.scheduleItem, excludeKeys), omit(state.sleepWakeUp, excludeKeys))
99
+ };
100
+
101
+ const caSubmit = useMemo(() => {
102
+ return state.sleepWakeUp.name?.length > 0 && state.sleepWakeUp.name?.length < 33;
103
+ }, [state.sleepWakeUp.name]);
104
+
105
+ const mixLightCard = useMemo(() => {
106
+ const applyList = params.applyForList.map(item => {
107
+ if (item.type === 'mainLight' && state.sleepWakeUp.isColorMode) {
108
+ return {
109
+ ...item,
110
+ enable: false,
111
+ };
112
+ }
113
+ if (item.type === 'secondaryLight' && !state.sleepWakeUp.isColorMode) {
114
+ return {
115
+ ...item,
116
+ enable: false,
117
+ };
118
+ }
119
+ return item;
120
+ });
121
+ return (
122
+ <View>
123
+ {applyList.map(item => (
124
+ <View key={`${item.dp}-key`}>
125
+ <Card style={{ marginHorizontal: cx(24) }}>
126
+ <LdvSwitch
127
+ title={item.key}
128
+ color={props.theme.card.background}
129
+ colorAlpha={1}
130
+ enable={
131
+ item.type === 'mainLight'
132
+ ? !state.sleepWakeUp.isColorMode
133
+ : state.sleepWakeUp.isColorMode
134
+ }
135
+ setEnable={(enable: boolean) => {
136
+ state.sleepWakeUp.isColorMode = item.type === 'mainLight' ? !enable : enable;
137
+ }}
138
+ />
139
+ {item.type === 'mainLight' && !state.sleepWakeUp.isColorMode ? (
140
+ <View>
141
+ <ColorTempAdjustView
142
+ isSupportBrightness={!!params.isSupportBrightness}
143
+ isSupportTemperature={!!params.isSupportTemperature}
144
+ colorTemp={state.sleepWakeUp.temperature}
145
+ brightness={state.sleepWakeUp.brightness}
146
+ onBrightnessChangeComplete={bright => {
147
+ state.sleepWakeUp.brightness = bright;
148
+ }}
149
+ onCCTChangeComplete={cct => {
150
+ state.sleepWakeUp.temperature = cct;
151
+ }}
152
+ />
153
+ <Spacer height={cx(16)} />
154
+ </View>
155
+ ) : item.type === 'secondaryLight' && state.sleepWakeUp.isColorMode ? (
156
+ <View>
157
+ <ColorAdjustView
158
+ h={state.sleepWakeUp.hue}
159
+ s={state.sleepWakeUp.sat}
160
+ v={state.sleepWakeUp.value}
161
+ reserveSV={true}
162
+ minSaturation={1}
163
+ onHSVChangeComplete={(h, s, v) => {
164
+ state.sleepWakeUp.hue = h;
165
+ state.sleepWakeUp.sat = s;
166
+ state.sleepWakeUp.value = v;
167
+ }}
168
+ />
169
+ <Spacer />
170
+ </View>
171
+ ) : null}
172
+ </Card>
173
+ <Spacer />
174
+ </View>
175
+ ))}
176
+ </View>
177
+ );
178
+ }, [params.applyForList, JSON.stringify(state.sleepWakeUp)]);
179
+
180
+
181
+ const styles = StyleSheet.create({
182
+ cardContainer: {
183
+ marginHorizontal: cx(24),
184
+ },
185
+ textField: {
186
+ marginHorizontal: cx(24),
187
+ },
188
+ picker: {
189
+ marginHorizontal: cx(24),
190
+ marginVertical: cx(15),
191
+ color: props.theme.global.backgournd,
192
+ },
193
+ week: {},
194
+ itemTitle: {
195
+ color: props.theme.global.fontColor,
196
+ fontSize: cx(16),
197
+ fontWeight: 'bold',
198
+ fontFamily: 'helvetica_neue_lt_std_bd',
199
+ marginBottom: cx(10),
200
+ },
201
+ skillListItem: {
202
+ flexDirection: 'row',
203
+ justifyContent: 'space-between',
204
+ height: cx(30),
205
+ alignItems: 'center',
206
+ marginVertical: cx(5),
207
+ },
208
+ summaryContainer: {
209
+ flexDirection: 'row',
210
+ justifyContent: 'flex-start',
211
+ marginBottom: cx(10),
212
+ marginHorizontal: cx(24),
213
+ },
214
+ summaryImg: {
215
+ height: cx(12),
216
+ width: cx(12),
217
+ tintColor: props.theme.global.fontColor,
218
+ },
219
+ summaryLeft: {
220
+ flexDirection: 'row',
221
+ alignItems: 'center',
222
+ minWidth: cx(90),
223
+ },
224
+ leftTitle: {
225
+ fontSize: cx(14),
226
+ color: props.theme.global.fontColor,
227
+ },
228
+ summaryRight: {
229
+ flexDirection: 'column',
230
+ marginLeft: cx(21),
231
+ borderRadius: cx(16),
232
+ backgroundColor: '#cbcbcb',
233
+ },
234
+ rightItem: {
235
+ paddingHorizontal: cx(12),
236
+ color: props.theme.global.fontColor,
237
+ },
238
+ rightTitle: {
239
+ paddingLeft: cx(12),
240
+ paddingRight: cx(12),
241
+ fontSize: cx(10),
242
+ textAlign: 'center',
243
+ alignSelf: 'flex-start',
244
+ },
245
+ filletCorner: {
246
+ flexDirection: 'row',
247
+ backgroundColor: '#cbcbcb',
248
+ borderRadius: cx(16),
249
+ alignSelf: 'flex-start',
250
+ },
251
+ })
252
+
253
+ return (
254
+ <Page
255
+ backText={I18n.getLang('add_sleepschedule_one_source_system_back_text')}
256
+ showBackDialog={showBackDialog() && caSubmit}
257
+ loading={state.loading}
258
+ backDialogTitle={I18n.getLang('cancel_dialog_leave_unsaved_titel')}
259
+ backDialogContent={I18n.getLang(
260
+ params.isSleep
261
+ ? 'cancel_dialog_leave_unsaved_sleepschedule_note'
262
+ : 'cancel_dialog_leave_unsaved_wakeupschedule_note'
263
+ )}
264
+ rightButtonIcon={showBackDialog() && caSubmit ? res.ic_check : res.ic_uncheck}
265
+ rightButtonIconClick={async () => {
266
+ if (!showBackDialog() || !caSubmit || state.loading) return;
267
+ state.loading = true;
268
+ if (state.sleepWakeUp.isColorMode) {
269
+ state.sleepWakeUp.brightness = 0;
270
+ state.sleepWakeUp.temperature = 0;
271
+ } else {
272
+ state.sleepWakeUp.hue = 0;
273
+ state.sleepWakeUp.sat = 0;
274
+ state.sleepWakeUp.value = 0;
275
+ }
276
+ state.sleepWakeUp.enable = true
277
+ const res = await params.modDeleteTimeSchedule(
278
+ params.mode,
279
+ state.sleepWakeUp.isSleep,
280
+ {...state.sleepWakeUp, settingTime: new Date().getTime()}
281
+ );
282
+ state.loading = false;
283
+ if (res.success) {
284
+ navigation.goBack();
285
+ }
286
+ }}
287
+ headlineText={I18n.getLang(
288
+ params.isSleep
289
+ ? params.mode === 'add'
290
+ ? 'add_sleepschedule_one_source_headline_text'
291
+ : 'edit_sleepschedule_headline_text'
292
+ : params.mode === 'add'
293
+ ? 'add_wakeupschedule_one_source_headline_text'
294
+ : 'edit_wakeupschedule_headline_text'
295
+ )}
296
+ >
297
+ <ScrollView
298
+ nestedScrollEnabled={true}
299
+ showsHorizontalScrollIndicator={false}
300
+ showsVerticalScrollIndicator={false}
301
+ >
302
+ <TextField
303
+ style={styles.cardContainer}
304
+ value={state.sleepWakeUp.name}
305
+ showError={state.sleepWakeUp.name.length > 32}
306
+ maxLength={33}
307
+ errorText={I18n.getLang('add_new_dynamic_mood_alert_text')}
308
+ placeholder={I18n.getLang('add_new_trigger_time_inputfield_value_text')}
309
+ onChangeText={(t: string) => {
310
+ state.sleepWakeUp.name = t;
311
+ }}
312
+ />
313
+ {/* pick */}
314
+ <TimerPicker
315
+ itemTextColor={props.theme.global.fontColor}
316
+ style={{ paddingVertical: cx(0), marginVertical: cx(0), backgroundColor: props.theme.global.background }}
317
+ is12Hours={!is24HourClock}
318
+ singlePicker={true}
319
+ amText={I18n.getLang('manage_user_calendar_label_am')}
320
+ pmText={I18n.getLang('manage_user_calendar_label_pm')}
321
+ startTime={state.sleepWakeUp.time}
322
+ symbol={''}
323
+ onTimerChange={time => {
324
+ state.sleepWakeUp.time = time
325
+ }}
326
+ />
327
+
328
+ {/* week */}
329
+ <View style={styles.week}>
330
+ <LdvWeekView
331
+ value={state.sleepWakeUp.weeks}
332
+ onSelect={(weekIdx: number) => {
333
+ state.sleepWakeUp.weeks = state.sleepWakeUp.weeks.map((week, idx) => {
334
+ if (idx === weekIdx - 1) {
335
+ return week === 1 ? 0 : 1;
336
+ }
337
+ return week;
338
+ });
339
+ }}
340
+ />
341
+ <Spacer />
342
+ <Text style={{ marginHorizontal: cx(24), color: props.theme.global.fontColor }}>{loopText(state.sleepWakeUp.weeks)}</Text>
343
+ <Spacer />
344
+ </View>
345
+
346
+ {/* Apply for */}
347
+ <View style={styles.cardContainer}>
348
+ <Text style={styles.itemTitle}>
349
+ {I18n.getLang('timeschedule_add_schedule_subheadline_text')}
350
+ </Text>
351
+ <View
352
+ style={{
353
+ backgroundColor: props.theme.card.board,
354
+ borderRadius: 4,
355
+ minHeight: cx(50),
356
+ flex: 1,
357
+ justifyContent: 'center',
358
+ }}
359
+ >
360
+ <View
361
+ style={{
362
+ marginHorizontal: cx(8),
363
+ marginTop: cx(8),
364
+ borderRadius: 4,
365
+ }}
366
+ >
367
+ {params.applyForList.map(apply => (
368
+ <View
369
+ key={`${apply.dp}-key`}
370
+ style={{
371
+ flexDirection: 'row',
372
+ justifyContent: 'space-between',
373
+ alignItems: 'center',
374
+ backgroundColor: props.theme.global.background,
375
+ marginBottom: cx(8),
376
+ }}
377
+ >
378
+ <Text
379
+ style={{
380
+ color: props.theme.global.fontColor,
381
+ fontSize: cx(14),
382
+ marginHorizontal: cx(6),
383
+ marginVertical: cx(9),
384
+ }}
385
+ >
386
+ {apply.key}
387
+ </Text>
388
+ </View>
389
+ ))}
390
+ </View>
391
+ </View>
392
+ <Spacer />
393
+ </View>
394
+
395
+ {/* Device state */}
396
+ <View>
397
+ <Text style={[styles.itemTitle, styles.cardContainer]}>
398
+ {I18n.getLang('timeschedule_add_schedule_subheadline2_text')}
399
+ </Text>
400
+ {params.isMixLight ? (
401
+ mixLightCard
402
+ ) : (
403
+ <Card style={styles.cardContainer}>
404
+ <LdvSwitch
405
+ title={I18n.getLang('light_sources_tile_tw_lighting_headline')}
406
+ color={getBlockColor()}
407
+ colorAlpha={1}
408
+ enable={false}
409
+ showSwitch={false}
410
+ setEnable={() => {}}
411
+ />
412
+ <LampAdjustView
413
+ isSupportColor={!!params.isSupportColor}
414
+ isSupportTemperature={!!params.isSupportTemperature}
415
+ isSupportBrightness={!!params.isSupportBrightness}
416
+ isColorMode={state.sleepWakeUp.isColorMode}
417
+ reserveSV={true}
418
+ setIsColorMode={() => {
419
+ state.sleepWakeUp.isColorMode = !state.sleepWakeUp.isColorMode;
420
+ }}
421
+ h={state.sleepWakeUp.hue}
422
+ s={state.sleepWakeUp.sat}
423
+ v={state.sleepWakeUp.value}
424
+ onHSVChange={(h, s, v) => {
425
+ state.sleepWakeUp.hue = h;
426
+ state.sleepWakeUp.sat = s;
427
+ state.sleepWakeUp.value = v;
428
+ }}
429
+ onHSVChangeComplete={(h, s, v) => {
430
+ state.sleepWakeUp.hue = h;
431
+ state.sleepWakeUp.sat = s;
432
+ state.sleepWakeUp.value = v;
433
+ }}
434
+ colorTemp={state.sleepWakeUp.temperature}
435
+ brightness={state.sleepWakeUp.brightness}
436
+ onCCTChange={cct => {
437
+ state.sleepWakeUp.temperature = cct;
438
+ }}
439
+ onCCTChangeComplete={cct => {
440
+ state.sleepWakeUp.temperature = cct;
441
+ }}
442
+ onBrightnessChange={brightness => {
443
+ state.sleepWakeUp.brightness = brightness;
444
+ }}
445
+ onBrightnessChangeComplete={brightness => {
446
+ state.sleepWakeUp.brightness = brightness;
447
+ }}
448
+ />
449
+ </Card>
450
+ )}
451
+ </View>
452
+ <Spacer />
453
+ {/* Settings */}
454
+ <View style={styles.cardContainer}>
455
+ <Text style={styles.itemTitle}>
456
+ {I18n.getLang('timeschedule_add_schedule_subheadline4_text')}
457
+ </Text>
458
+ <Spacer />
459
+ <Text style={{color: props.theme.global.secondFontColor}}>
460
+ {I18n.getLang(
461
+ params.isSleep
462
+ ? 'add_sleepschedule_one_source_settings_text'
463
+ : 'add_wakeupschedule_settings_text'
464
+ )}
465
+ </Text>
466
+ <LdvPickerView
467
+ style={styles.picker}
468
+ hour={toFixedString(Math.trunc((state.sleepWakeUp.fade * 5) / 60), 2)}
469
+ minute={toFixedString((state.sleepWakeUp.fade * 5) % 60, 2)}
470
+ minutesStep={5}
471
+ setHour={v => {
472
+ const m = (state.sleepWakeUp.fade * 5) % 60;
473
+ state.sleepWakeUp.fade = (Number(v) * 60 + m) / 5;
474
+ }}
475
+ setMinute={v => {
476
+ const h = Math.trunc((state.sleepWakeUp.fade * 5) / 60);
477
+ state.sleepWakeUp.fade = (h * 60 + Number(v)) / 5;
478
+ }}
479
+ unit={['h', 'min']}
480
+ maxHour={3}
481
+ />
482
+ <Text style={{color: props.theme.global.secondFontColor}}>
483
+ {I18n.formatValue(
484
+ params.isSleep
485
+ ? 'add_sleepschedule_one_source_settings_text2'
486
+ : 'add_wakeupschedule_settings_text2',
487
+ `${convertMinutesTo12HourFormat(params.isSleep ? getEndTime(state.sleepWakeUp) : getStartTime(state.sleepWakeUp), is24HourClock)}`
488
+ )}
489
+ </Text>
490
+ <Spacer />
491
+ {!params.isSleep && (
492
+ <View style={{ marginHorizontal: -cx(16), marginTop: -cx(20) }}>
493
+ <LdvSwitch
494
+ title={I18n.getLang('add_wakeupschedule_settings_text3')}
495
+ enable={state.sleepWakeUp.duration > 0}
496
+ color={props.theme.global.background}
497
+ colorAlpha={1}
498
+ setEnable={v => {
499
+ state.sleepWakeUp.duration = v ? 1 : 0;
500
+ }}
501
+ />
502
+ </View>
503
+ )}
504
+ {state.sleepWakeUp.duration > 0 && (
505
+ <>
506
+ <Text style={{ fontSize: cx(14), color: props.theme.global.secondFontColor }}>
507
+ {I18n.getLang('add_wakeupschedule_settings_text4')}
508
+ </Text>
509
+ <LdvPickerView
510
+ style={styles.picker}
511
+ hour={toFixedString(Math.trunc((state.sleepWakeUp.duration * 5) / 60), 2)}
512
+ minute={toFixedString((state.sleepWakeUp.duration * 5) % 60, 2)}
513
+ minutesStep={5}
514
+ setHour={v => {
515
+ const m = (state.sleepWakeUp.duration * 5) % 60;
516
+ if (Number(v) === 0 && m === 0) {
517
+ state.sleepWakeUp.duration = 1;
518
+ } else {
519
+ state.sleepWakeUp.duration = (Number(v) * 60 + m) / 5;
520
+ }
521
+ }}
522
+ setMinute={v => {
523
+ const h = Math.trunc((state.sleepWakeUp.duration * 5) / 60);
524
+ if (Number(v) === 0 && h === 0) {
525
+ state.sleepWakeUp.duration = 1;
526
+ } else {
527
+ state.sleepWakeUp.duration = (h * 60 + Number(v)) / 5;
528
+ }
529
+ }}
530
+ unit={['h', 'min']}
531
+ maxHour={3}
532
+ />
533
+ <Text style={{color: props.theme.global.secondFontColor}}>
534
+ {I18n.formatValue(
535
+ 'add_wakeupschedule_settings_text5',
536
+ `${convertMinutesTo12HourFormat(
537
+ getEndTime(state.sleepWakeUp),
538
+ is24HourClock
539
+ )}`
540
+ )}
541
+ </Text>
542
+ <Spacer />
543
+ </>
544
+ )}
545
+ </View>
546
+ {/* Summary */}
547
+ <Text style={[styles.itemTitle, styles.cardContainer]}>
548
+ {I18n.getLang('add_sleepschedule_one_source_subheadline4_text')}
549
+ </Text>
550
+ <View style={styles.summaryContainer}>
551
+ <InfoText
552
+ icon={res.summary_icon1}
553
+ text={I18n.getLang('feature_summary_frequency_headline')}
554
+ iconStyle={styles.summaryImg}
555
+ textStyle={styles.leftTitle}
556
+ style={styles.summaryLeft}
557
+ />
558
+ <View style={styles.summaryRight}>
559
+ <Text style={styles.rightItem}>{loopText(state.sleepWakeUp.weeks)}</Text>
560
+ </View>
561
+ </View>
562
+ <View style={styles.summaryContainer}>
563
+ <InfoText
564
+ icon={res.summary_icon2}
565
+ text={I18n.getLang('feature_summary_time_headline')}
566
+ iconStyle={styles.summaryImg}
567
+ textStyle={styles.leftTitle}
568
+ style={styles.summaryLeft}
569
+ />
570
+ <View style={styles.summaryRight}>
571
+ <Text style={styles.rightItem}>
572
+ {`${convertMinutesTo12HourFormat(getStartTime(state.sleepWakeUp), is24HourClock)} - ${convertMinutesTo12HourFormat(getEndTime(state.sleepWakeUp), is24HourClock)}`}
573
+ </Text>
574
+ </View>
575
+ </View>
576
+ <View style={[styles.summaryContainer, { alignItems: 'flex-start' }]}>
577
+ <InfoText
578
+ icon={res.summary_icon3}
579
+ text={I18n.getLang('motion_detection_add_time_schedule_actions_text1')}
580
+ iconStyle={styles.summaryImg}
581
+ textStyle={styles.leftTitle}
582
+ style={styles.summaryLeft}
583
+ />
584
+ <View style={{ marginLeft: cx(24), flex: 1 }}>
585
+ <Text style={{ fontSize: cx(12), color: props.theme.global.fontColor }}>
586
+ {I18n.getLang(
587
+ !params.isSleep ? 'feature_summary_action_txt_11' : 'feature_summary_action_txt_10'
588
+ )}
589
+ </Text>
590
+ <View style={styles.filletCorner}>
591
+ <Text style={styles.rightTitle}>
592
+ {params.isMixLight ? (state.sleepWakeUp.isColorMode ? params.applyForList[1].key : params.applyForList[0].key) : params.applyForList[0].key}
593
+ </Text>
594
+ </View>
595
+ <Spacer height={cx(10)}/>
596
+ <Text style={{ fontSize: cx(12), color: props.theme.global.fontColor }}>
597
+ {I18n.getLang(
598
+ params.isSleep
599
+ ? 'feature_summary_action_txt_2'
600
+ : state.sleepWakeUp.duration
601
+ ? 'feature_summary_action_txt_12'
602
+ : 'feature_summary_action_txt_1'
603
+ )}
604
+ </Text>
605
+ <View style={styles.filletCorner}>
606
+ <Text style={styles.rightTitle}>
607
+ {convertMinutesTo12HourFormat(
608
+ params.isSleep
609
+ ? getEndTime(state.sleepWakeUp)
610
+ : getEndTime(state.sleepWakeUp),
611
+ is24HourClock
612
+ )}
613
+ </Text>
614
+ </View>
615
+ </View>
616
+ </View>
617
+ <Spacer />
618
+ {/* Delete btn */}
619
+ {params.mode === 'edit' && (
620
+ <View style={styles.cardContainer}>
621
+ <DeleteButton
622
+ text={I18n.getLang('edit_timeschedule_bttn_text')}
623
+ onPress={async () => {
624
+ showDialog({
625
+ method: 'confirm',
626
+ title: I18n.getLang(
627
+ params.isSleep
628
+ ? 'cancel_dialog_delete_item_sleepschedule_titel'
629
+ : 'cancel_dialog_delete_item_wakeupschedule_titel'
630
+ ),
631
+ subTitle: I18n.getLang(
632
+ params.isSleep
633
+ ? 'cancel_dialog_delete_item_sleepschedule_description'
634
+ : 'cancel_dialog_delete_item_wakeupschedule_description'
635
+ ),
636
+ onConfirm: async (_, { close }) => {
637
+ close();
638
+ if (state.loading) return;
639
+ state.loading = true;
640
+ const res = await params.modDeleteTimeSchedule(
641
+ 'del',
642
+ state.sleepWakeUp.isSleep,
643
+ state.sleepWakeUp
644
+ );
645
+ state.loading = false;
646
+ if (res.success) {
647
+ navigation.goBack();
648
+ }
649
+ },
650
+ });
651
+ }}
652
+ />
653
+ </View>
654
+ )}
655
+ <Spacer />
656
+ </ScrollView>
657
+ </Page>
658
+ );
659
+ };
660
+
661
+
662
+ export default withTheme(SleepWakeUpDetailPage)
@@ -0,0 +1,430 @@
1
+ import React, {useCallback, useEffect, useMemo} from "react";
2
+ import {FlatList, Image, StyleSheet, Text, View} from 'react-native'
3
+ import Page from '@ledvance/base/src/components/Page'
4
+ import Tag from '@ledvance/base/src/components/Tag'
5
+ import Spacer from '@ledvance/base/src/components/Spacer'
6
+ import {useNavigation} from '@react-navigation/native'
7
+ import I18n from '@ledvance/base/src/i18n'
8
+ import res from '@ledvance/base/src/res'
9
+ import {useDeviceInfo, useSystemTimeFormate} from "@ledvance/base/src/models/modules/NativePropsSlice";
10
+ import {useReactive, useUpdateEffect} from "ahooks";
11
+ import CustomListDialog from "@ledvance/base/src/components/CustomListDialog";
12
+ import {SwitchButton, Utils} from "tuya-panel-kit";
13
+ import {convertMinutesTo12HourFormat, getIsClosed, loopText} from "@ledvance/base/src/utils/common";
14
+ import TextButton from "@ledvance/base/src/components/TextButton";
15
+ import {ui_biz_routerKey} from "../../navigation/Routers";
16
+ import {cloneDeep} from "lodash";
17
+ import Card from "@ledvance/base/src/components/Card";
18
+ import {useParams} from "@ledvance/base/src/hooks/Hooks";
19
+ import {ApplyForItem} from "@ledvance/base/src/utils/interface";
20
+ import {getEndTime, getStartTime, SleepWakeUpItem, useSleepPlan, useWakeUpPlan} from "./SleepWakeUpActions";
21
+
22
+ const cx = Utils.RatioUtils.convertX
23
+ const {parseTimer} = Utils.TimeUtils
24
+ const { withTheme } = Utils.ThemeUtils
25
+
26
+ export interface SleepWakeUpPageRouteParams {
27
+ isSupportColor?: boolean
28
+ isSupportTemperature?: boolean
29
+ isSupportBrightness?: boolean
30
+ isMixLight?: boolean
31
+ sleepModeDpCode: string
32
+ wakeUpDpCode: string
33
+ applyForList: ApplyForItem[];
34
+ }
35
+
36
+ const MAX_SCHEDULE = 4
37
+ const SleepWakeUpPage = (props: {theme?: any}) => {
38
+ const deviceInfo = useDeviceInfo()
39
+ const navigation = useNavigation()
40
+ const is24HourClock = useSystemTimeFormate()
41
+ const params = useParams<SleepWakeUpPageRouteParams>()
42
+ const [wakeUpList, setWakeUpList] = useWakeUpPlan()
43
+ const [sleepList, setSleepList] = useSleepPlan()
44
+ const state = useReactive({
45
+ showAddSchedulePopover: false,
46
+ sleepTagChecked: false,
47
+ wakeUpTagChecked: false,
48
+ sleepScheduleList: cloneDeep(sleepList),
49
+ wakeUpScheduleList: cloneDeep(wakeUpList),
50
+ filteredScheduleList: [] as any[],
51
+ })
52
+
53
+ const isMaxNum = useMemo(() => {
54
+ return state.sleepScheduleList.length >= MAX_SCHEDULE && state.wakeUpScheduleList.length >= MAX_SCHEDULE
55
+ }, [state.sleepScheduleList, state.wakeUpScheduleList])
56
+
57
+ useUpdateEffect(() =>{
58
+ state.sleepScheduleList = cloneDeep(sleepList)
59
+ }, [sleepList])
60
+
61
+ useUpdateEffect(() =>{
62
+ state.wakeUpScheduleList = cloneDeep(wakeUpList)
63
+ }, [wakeUpList])
64
+
65
+
66
+ const onAddScheduleDialogItemClick = useCallback((isSleep: boolean, mode: 'add' | 'edit', scheduleItem: SleepWakeUpItem) => {
67
+ if (mode === 'add' && isSleep && state.sleepScheduleList.length === MAX_SCHEDULE) return
68
+ if (mode === 'add' && !isSleep && state.wakeUpScheduleList.length === MAX_SCHEDULE) return
69
+ navigateToEdit({
70
+ ...params,
71
+ mode,
72
+ isSleep,
73
+ scheduleItem: cloneDeep(scheduleItem),
74
+ modDeleteTimeSchedule
75
+ })
76
+ state.showAddSchedulePopover = false
77
+ }, [state.filteredScheduleList])
78
+
79
+ const modDeleteTimeSchedule = async (mode: 'add' | 'edit' | 'del', isSleep: boolean, sleepWakeUp: SleepWakeUpItem) => {
80
+ let cloneSleepWakeUp: SleepWakeUpItem[] = isSleep ? cloneDeep(state.sleepScheduleList) : cloneDeep(state.wakeUpScheduleList)
81
+ if (mode === 'add') {
82
+ cloneSleepWakeUp = [
83
+ ...cloneSleepWakeUp,
84
+ {
85
+ ...sleepWakeUp,
86
+ index: cloneSleepWakeUp.length,
87
+ }
88
+ ]
89
+ }
90
+ if (mode === 'del') {
91
+ cloneSleepWakeUp = cloneSleepWakeUp.filter(item => sleepWakeUp.index !== item.index)
92
+ }
93
+ if (mode === 'edit') {
94
+ cloneSleepWakeUp = cloneSleepWakeUp.map(item => {
95
+ if (item.index === sleepWakeUp.index) {
96
+ return sleepWakeUp
97
+ }
98
+ return item
99
+ })
100
+ }
101
+
102
+ const res = isSleep ? await setSleepList(cloneSleepWakeUp) : await setWakeUpList(cloneSleepWakeUp)
103
+ if(res.success){
104
+ if(isSleep){
105
+ state.sleepScheduleList = cloneDeep(cloneSleepWakeUp)
106
+ }else{
107
+ state.wakeUpScheduleList = cloneDeep(cloneSleepWakeUp)
108
+ }
109
+ return {
110
+ success: true
111
+ }
112
+ }else{
113
+ return {
114
+ success: false
115
+ }
116
+ }
117
+ }
118
+
119
+ useEffect(() => {
120
+ if (state.sleepTagChecked === state.wakeUpTagChecked) {
121
+ state.filteredScheduleList = [...state.sleepScheduleList, ...state.wakeUpScheduleList]
122
+ } else if (state.sleepTagChecked) {
123
+ state.filteredScheduleList = state.sleepScheduleList
124
+ } else {
125
+ state.filteredScheduleList = state.wakeUpScheduleList
126
+ }
127
+ }, [state.sleepTagChecked, state.wakeUpTagChecked, state.sleepScheduleList, state.wakeUpScheduleList])
128
+
129
+ const getTipText = useCallback(() => {
130
+ if (state.sleepScheduleList.length >= MAX_SCHEDULE && state.wakeUpScheduleList.length >= MAX_SCHEDULE) return "both"
131
+ if (state.sleepScheduleList.length >= MAX_SCHEDULE) return "sleep"
132
+ if (state.wakeUpScheduleList.length >= MAX_SCHEDULE) return "wakeup"
133
+ }, [state.sleepScheduleList, state.wakeUpScheduleList])
134
+
135
+ const hasScheduleList = useCallback(() => {
136
+ return !!(state.sleepScheduleList.length && state.wakeUpScheduleList.length)
137
+ }, [state.sleepScheduleList, state.wakeUpScheduleList])
138
+
139
+ const navigateToEdit = (params) => {
140
+ navigation.navigate(ui_biz_routerKey.group_ui_biz_sleep_wakeUp_detail, params)
141
+ }
142
+
143
+ const isSleepMax = useMemo(() => {
144
+ return state.sleepScheduleList.length >= MAX_SCHEDULE
145
+ }, [state.sleepScheduleList])
146
+
147
+ const isWakeUpMax = useMemo(() => {
148
+ return state.wakeUpScheduleList.length >= MAX_SCHEDULE
149
+ }, [state.wakeUpScheduleList])
150
+
151
+ const styles = StyleSheet.create({
152
+ tagLine: {
153
+ flexDirection: 'row',
154
+ marginHorizontal: cx(24),
155
+ },
156
+ infoLine: {
157
+ marginHorizontal: cx(24),
158
+ },
159
+ addMoodPopover: {
160
+ width: cx(210),
161
+ height: cx(90.5),
162
+ marginStart: cx(115),
163
+ marginTop: cx(100),
164
+ backgroundColor: props.theme.card.background,
165
+ },
166
+ popoverItem: {
167
+ width: cx(210),
168
+ height: cx(45),
169
+ alignItems: 'flex-start',
170
+ },
171
+ emptyListCon: {
172
+ flex: 1,
173
+ alignItems: 'center',
174
+ },
175
+ emptyImage: {
176
+ width: cx(225),
177
+ height: cx(198),
178
+ },
179
+ emptyText: {
180
+ flexDirection: 'row',
181
+ alignItems: 'center'
182
+ },
183
+ emptyNoTime: {
184
+ fontSize: cx(14),
185
+ lineHeight: cx(20),
186
+ textAlign: 'center',
187
+ fontFamily: 'helvetica_neue_lt_std_roman',
188
+ color: props.theme.global.fontColor
189
+ },
190
+ emptyBtnView: {
191
+ alignItems: 'center'
192
+ },
193
+ emptyBtn: {
194
+ backgroundColor: props.theme.button.active,
195
+ borderRadius: cx(5),
196
+ paddingHorizontal: cx(15),
197
+ paddingVertical: cx(10)
198
+ },
199
+ addTimer: {
200
+ justifyContent: 'center',
201
+ alignItems: 'center',
202
+ // width,
203
+ marginVertical: cx(20),
204
+ },
205
+ disableItemText: {
206
+ color: '#CBCBCB',
207
+ fontSize: cx(16),
208
+ },
209
+ randomTimingCard: {
210
+ marginHorizontal: cx(24),
211
+ paddingHorizontal: cx(16),
212
+ },
213
+ switchLine: {
214
+ flexDirection: 'row',
215
+ alignItems: 'center',
216
+ },
217
+ time: {
218
+ flex: 1,
219
+ color: props.theme.global.fontColor,
220
+ fontSize: cx(16),
221
+ fontWeight: 'bold',
222
+ fontFamily: 'helvetica_neue_lt_std_bd',
223
+ },
224
+ switchBtn: {},
225
+ loopText: {
226
+ color: props.theme.global.fontColor,
227
+ fontSize: cx(14),
228
+ fontFamily: 'helvetica_neue_lt_std_roman',
229
+ height: cx(20)
230
+ },
231
+ tag: {
232
+ alignSelf: 'flex-start',
233
+ borderRadius: cx(16),
234
+ height: cx(16),
235
+ backgroundColor: props.theme.tag.background,
236
+ paddingHorizontal: cx(10),
237
+ },
238
+ tagTitle: {
239
+ fontSize: cx(10),
240
+ textAlign: 'center',
241
+ fontFamily: 'PingFangSC-Medium',
242
+ color: props.theme.tag.fontColor
243
+ },
244
+ })
245
+
246
+
247
+ return (
248
+ <>
249
+ <Page
250
+ backText={deviceInfo.name}
251
+ onBackClick={navigation.goBack}
252
+ headlineText={I18n.getLang('add_sleepschedule_one_source_system_back_text')}
253
+ headlineIcon={isMaxNum ? undefined : res.device_panel_schedule_add}
254
+ onHeadlineIconClick={() => {
255
+ state.showAddSchedulePopover = !state.showAddSchedulePopover
256
+ }}
257
+ >
258
+ <View style={{ marginHorizontal: cx(24) }}>
259
+ <Text style={{ color: props.theme.global.fontColor, fontSize: cx(12) }}>
260
+ {I18n.getLang('timeschedule_overview_description_text')}
261
+ </Text>
262
+ </View>
263
+ <Spacer />
264
+ {!!getTipText() && <View style={{ marginHorizontal: cx(24), marginVertical: cx(10), flexDirection: 'row', alignItems: 'center' }}>
265
+ <Image style={{ width: cx(16), height: cx(16), tintColor: props.theme.global.warning }} source={res.ic_warning_amber} />
266
+ {getTipText() === "sleep" && <Text style={{fontSize: cx(12), color: props.theme.global.secondFontColor}}>{I18n.getLang('sleepwakeschedule_warning_max_number_sleep_text')}</Text>}
267
+ {getTipText() === "wakeup" && <Text style={{fontSize: cx(12), color: props.theme.global.secondFontColor}}>{I18n.getLang('sleepwakeschedule_warning_max_number_wakeup_text')}</Text>}
268
+ {getTipText() === "both" && <Text style={{fontSize: cx(12), color: props.theme.global.secondFontColor}}>{I18n.getLang('sleepwakeschedule_warning_max_number_both_text')}</Text>}
269
+ <Spacer />
270
+ </View>}
271
+ {hasScheduleList() && <View style={styles.tagLine}>
272
+ <Tag
273
+ checked={state.sleepTagChecked}
274
+ text={I18n.getLang('sleepwakeschedule_field_3_Times_chips2_text')}
275
+ onCheckedChange={checked => {
276
+ state.sleepTagChecked = checked
277
+ }} />
278
+ <Spacer width={cx(8)} height={0} />
279
+ <Tag
280
+ checked={state.wakeUpTagChecked}
281
+ text={I18n.getLang('sleepwakeschedule_field_3_Times_chips_text')}
282
+ onCheckedChange={checked => {
283
+ state.wakeUpTagChecked = checked
284
+ }} />
285
+ </View>}
286
+ {state.filteredScheduleList.length ?
287
+ <FlatList
288
+ data={state.filteredScheduleList}
289
+ renderItem={({ item }) => (
290
+ <SleepWakeUpCard
291
+ is24HourClock={is24HourClock}
292
+ styles={styles}
293
+ sleepWakeUp={item}
294
+ onPress={() => {
295
+ onAddScheduleDialogItemClick(item.isSleep, 'edit', item)
296
+ }}
297
+ onSwitch={async (v) => {
298
+ await modDeleteTimeSchedule('edit', item.isSleep, {
299
+ ...item,
300
+ enable: v,
301
+ settingTime: new Date().getTime()
302
+ })
303
+ }}
304
+ />
305
+ )}
306
+ ListHeaderComponent={() => (<Spacer height={cx(10)} />)}
307
+ ItemSeparatorComponent={() => (<Spacer />)}
308
+ ListFooterComponent={() => (<Spacer />)}
309
+ keyExtractor={(item, idx) => `${item.isSleep ? 'sleep' : 'wakeUp'}_${idx}`}
310
+ /> :
311
+ <View style={styles.emptyListCon}>
312
+ <Spacer height={cx(70)} />
313
+ <Image
314
+ style={styles.emptyImage}
315
+ source={res.scheduleEmpty}
316
+ resizeMode="contain" />
317
+ <Spacer height={cx(20)} />
318
+ <View style={styles.emptyText}>
319
+ <Image
320
+ source={{ uri: res.device_panel_schedule_alert }}
321
+ style={{ width: cx(16), height: cx(16), tintColor: props.theme.global.fontColor }}
322
+ />
323
+ <Text style={styles.emptyNoTime}>
324
+ {
325
+ !hasScheduleList() ?
326
+ I18n.getLang('sleepwakeschedule_empty_information_text') :
327
+ I18n.getLang('sleepwakeschedule_empty_filtering_information_text')
328
+ }
329
+ </Text>
330
+ </View>
331
+ {!hasScheduleList() &&
332
+ <View style={styles.emptyBtnView}>
333
+ <Spacer />
334
+ <TextButton
335
+ style={styles.emptyBtn}
336
+ textStyle={isSleepMax ? styles.disableItemText : { color: props.theme.button.fontColor }}
337
+ text={I18n.getLang('sleepwakeschedule_add_button_text1')}
338
+ onPress={() => onAddScheduleDialogItemClick(true, 'add', getNewSleepWakeUp(true, params))}
339
+ />
340
+ <Spacer />
341
+ <TextButton
342
+ style={styles.emptyBtn}
343
+ textStyle={isWakeUpMax ? styles.disableItemText : { color: props.theme.button.fontColor }}
344
+ text={I18n.getLang('sleepwakeschedule_add_button_text2')}
345
+ onPress={() => onAddScheduleDialogItemClick(false, 'add', getNewSleepWakeUp(false, params))}
346
+ />
347
+ </View>}
348
+ </View>
349
+ }
350
+ </Page>
351
+ <CustomListDialog
352
+ show={state.showAddSchedulePopover}
353
+ style={styles.addMoodPopover}
354
+ itemStyle={styles.popoverItem}
355
+ onDismiss={() => {
356
+ state.showAddSchedulePopover = false
357
+ }}
358
+ data={[
359
+ {
360
+ text: I18n.getLang('sleepwakeschedule_add_button_text1'),
361
+ value: true,
362
+ isMax: isSleepMax
363
+ },
364
+ {
365
+ text: I18n.getLang('sleepwakeschedule_add_button_text2'),
366
+ value: false,
367
+ isMax: isWakeUpMax
368
+ },
369
+ ]}
370
+ onItemPress={(isSleep) => onAddScheduleDialogItemClick(isSleep, 'add', getNewSleepWakeUp(isSleep, params))}
371
+ />
372
+ </>
373
+ )
374
+ }
375
+
376
+ const SleepWakeUpCard = ({ sleepWakeUp, is24HourClock, onSwitch, onPress, styles }: {
377
+ sleepWakeUp: SleepWakeUpItem,
378
+ onSwitch: (enable: boolean) => void,
379
+ onPress: () => void
380
+ is24HourClock: boolean
381
+ styles: StyleSheet.NamedStyles<any>
382
+ }) => {
383
+ const closed = getIsClosed({weeks: sleepWakeUp.weeks, settingTime: sleepWakeUp.settingTime, endTime: getEndTime(sleepWakeUp)})
384
+ return (
385
+ <Card style={styles.randomTimingCard} onPress={onPress}>
386
+ <Spacer height={cx(16)} />
387
+ <View style={styles.switchLine}>
388
+ <Text style={styles.time}>
389
+ {`${convertMinutesTo12HourFormat(getStartTime(sleepWakeUp), is24HourClock)} - ${convertMinutesTo12HourFormat(getEndTime(sleepWakeUp), is24HourClock)}`}</Text>
390
+ <SwitchButton
391
+ value={sleepWakeUp.enable && closed}
392
+ thumbStyle={{ elevation: 0 }}
393
+ onValueChange={onSwitch} />
394
+ </View>
395
+ <Text style={styles.loopText}>{loopText(sleepWakeUp.weeks, parseTimer(getStartTime(sleepWakeUp) * 60))}</Text>
396
+ <Spacer height={cx(5)} />
397
+ <Text style={styles.loopText}>{sleepWakeUp.name}</Text>
398
+ <Spacer height={cx(10)} />
399
+ <View style={styles.tag}>
400
+ <Text style={styles.tagTitle}>
401
+ {I18n.getLang(sleepWakeUp.isSleep ? 'sleepwakeschedule_field_3_Times_chips2_text' : 'sleepwakeschedule_field_3_Times_chips_text')}
402
+ </Text>
403
+ </View>
404
+ <Spacer />
405
+ </Card>
406
+ )
407
+ }
408
+
409
+
410
+ const getNewSleepWakeUp = (isSleep: boolean, params: SleepWakeUpPageRouteParams) => {
411
+ const hour = isSleep ? 23 : 7
412
+ return {
413
+ enable: true,
414
+ name: '',
415
+ weeks: [0, 0, 0, 0, 0, 0, 0],
416
+ fade: 6,
417
+ time: hour * 60,
418
+ hue: 0,
419
+ sat: 100,
420
+ value: 100,
421
+ brightness: 100,
422
+ temperature: 0,
423
+ duration: 0,
424
+ isColorMode: !!params.isSupportColor,
425
+ isSleep,
426
+ settingTime: new Date().getTime()
427
+ } as SleepWakeUpItem
428
+ }
429
+
430
+ export default withTheme(SleepWakeUpPage)
@@ -24,4 +24,6 @@ export const ui_biz_routerKey = {
24
24
  'group_ui_biz_fixed_time_plug_detail': 'group_ui_biz_fixed_time_plug_detail',
25
25
  'group_ui_biz_fixed_timing_light': 'group_ui_biz_fixed_timing_light',
26
26
  'group_ui_biz_fixed_timing_light_detail': 'group_ui_biz_fixed_timing_light_detail',
27
+ 'group_ui_biz_sleep_wakeUp': 'group_ui_biz_sleep_wakeUp',
28
+ 'group_ui_biz_sleep_wakeUp_detail': 'group_ui_biz_sleep_wakeUp_detail',
27
29
  }