@ledvance/ui-biz-bundle 1.1.66 → 1.1.67
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 +1 -1
- package/src/newModules/biorhythm/BiorhythmPage.tsx +11 -7
- package/src/newModules/fixedTime/FixedTimePage.tsx +4 -3
- package/src/newModules/randomTime/RandomTimePage.tsx +4 -3
- package/src/newModules/remoteControl/RemoteControlActions.ts +6 -0
- package/src/newModules/remoteControl/RemoteControlPage.tsx +51 -0
- package/src/newModules/remoteControl/Router.ts +16 -0
- package/src/newModules/sleepWakeUp/Interface.ts +70 -0
- package/src/newModules/sleepWakeUp/Router.ts +25 -0
- package/src/newModules/sleepWakeUp/SleepWakeUpActions.ts +317 -0
- package/src/newModules/sleepWakeUp/SleepWakeUpDetailPage.tsx +661 -0
- package/src/newModules/sleepWakeUp/SleepWakeUpPage.tsx +456 -0
- package/src/newModules/sleepWakeUp/utils.ts +254 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo } from "react";
|
|
2
|
+
import { StyleSheet, View, Text, Image, FlatList } 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, 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 { sleepNode2Dp, useSleepMode, useWakeUp, wakeUpNode2Dp } from "./SleepWakeUpActions";
|
|
18
|
+
import { SleepUIItem, WakeUpUIItem } from "./Interface";
|
|
19
|
+
import Card from "@ledvance/base/src/components/Card";
|
|
20
|
+
import { useParams } from "@ledvance/base/src/hooks/Hooks";
|
|
21
|
+
import { ApplyForItem } from "../timeSchedule/Interface";
|
|
22
|
+
import InfoText from "@ledvance/base/src/components/InfoText";
|
|
23
|
+
|
|
24
|
+
const cx = Utils.RatioUtils.convertX
|
|
25
|
+
|
|
26
|
+
export interface SleepWakeUpPageRouteParams {
|
|
27
|
+
isSupportColor?: boolean
|
|
28
|
+
isSupportTemperature?: boolean
|
|
29
|
+
isSupportBrightness?: boolean
|
|
30
|
+
isMixLight?: boolean
|
|
31
|
+
sleepModeDpCode: string
|
|
32
|
+
wakeUpDpCode: string
|
|
33
|
+
conflictDps: {
|
|
34
|
+
randomTimeDpCode?: string
|
|
35
|
+
fixedTimeDpCode?: string
|
|
36
|
+
biorhythmDpCode?: string
|
|
37
|
+
}
|
|
38
|
+
applyForList: ApplyForItem[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const MAX_SCHEDULE = 4
|
|
42
|
+
const SleepWakeUpPage = () => {
|
|
43
|
+
const deviceInfo = useDeviceInfo()
|
|
44
|
+
const navigation = useNavigation()
|
|
45
|
+
const is24HourClock = useSystemTimeFormate()
|
|
46
|
+
const params = useParams<SleepWakeUpPageRouteParams>()
|
|
47
|
+
const [wakeUpList, setWakeUpList, wakeupComplete] = useWakeUp(params.wakeUpDpCode)
|
|
48
|
+
const [sleepList, setSleepList, sleepComplete] = useSleepMode(params.sleepModeDpCode)
|
|
49
|
+
const state = useReactive({
|
|
50
|
+
showAddSchedulePopover: false,
|
|
51
|
+
sleepTagChecked: false,
|
|
52
|
+
wakeUpTagChecked: false,
|
|
53
|
+
sleepScheduleList: cloneDeep(sleepList),
|
|
54
|
+
wakeUpScheduleList: cloneDeep(wakeUpList),
|
|
55
|
+
filteredScheduleList: [] as any[],
|
|
56
|
+
flag: Symbol(),
|
|
57
|
+
loading: true
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const isMaxNum = useMemo(() => {
|
|
61
|
+
return state.sleepScheduleList.length >= MAX_SCHEDULE && state.wakeUpScheduleList.length >= MAX_SCHEDULE
|
|
62
|
+
}, [state.sleepScheduleList, state.wakeUpScheduleList])
|
|
63
|
+
|
|
64
|
+
useUpdateEffect(() => {
|
|
65
|
+
console.log(sleepList, '< --- sleepList')
|
|
66
|
+
state.sleepScheduleList = cloneDeep(sleepList)
|
|
67
|
+
}, [JSON.stringify(sleepList)])
|
|
68
|
+
|
|
69
|
+
useUpdateEffect(() => {
|
|
70
|
+
console.log(wakeUpList, '< --- wakeUpList')
|
|
71
|
+
state.wakeUpScheduleList = cloneDeep(wakeUpList)
|
|
72
|
+
}, [JSON.stringify(wakeUpList)])
|
|
73
|
+
|
|
74
|
+
useUpdateEffect(() => {
|
|
75
|
+
state.loading = !wakeupComplete && !sleepComplete
|
|
76
|
+
}, [wakeupComplete, sleepComplete])
|
|
77
|
+
|
|
78
|
+
const onAddScheduleDialogItemClick = useCallback((isSleep: boolean, mode: 'add' | 'edit', scheduleItem?: any) => {
|
|
79
|
+
if (mode === 'add' && isSleep && state.sleepScheduleList.length === MAX_SCHEDULE) return
|
|
80
|
+
if (mode === 'add' && !isSleep && state.wakeUpScheduleList.length === MAX_SCHEDULE) return
|
|
81
|
+
navigateToEdit({
|
|
82
|
+
...params,
|
|
83
|
+
mode,
|
|
84
|
+
isSleep,
|
|
85
|
+
scheduleItem: cloneDeep(scheduleItem),
|
|
86
|
+
modDeleteTimeSchedule
|
|
87
|
+
})
|
|
88
|
+
state.showAddSchedulePopover = false
|
|
89
|
+
}, [state.filteredScheduleList])
|
|
90
|
+
|
|
91
|
+
const modDeleteTimeSchedule = async (mode: 'add' | 'edit' | 'del', isSleep: boolean, sleepWakeUp: SleepUIItem | WakeUpUIItem) => {
|
|
92
|
+
let cloneSleepWakeUp: any[] = isSleep ? cloneDeep(state.sleepScheduleList) : cloneDeep(state.wakeUpScheduleList)
|
|
93
|
+
if (mode === 'add') {
|
|
94
|
+
cloneSleepWakeUp = [
|
|
95
|
+
...cloneSleepWakeUp,
|
|
96
|
+
{
|
|
97
|
+
...sleepWakeUp,
|
|
98
|
+
id: cloneSleepWakeUp.length,
|
|
99
|
+
nodeHex: isSleep ? sleepNode2Dp(sleepWakeUp) : wakeUpNode2Dp(sleepWakeUp as WakeUpUIItem)
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
if (mode === 'del') {
|
|
104
|
+
cloneSleepWakeUp = cloneSleepWakeUp.filter(item => sleepWakeUp.id !== item.id)
|
|
105
|
+
}
|
|
106
|
+
if (mode === 'edit') {
|
|
107
|
+
cloneSleepWakeUp = cloneSleepWakeUp.map(item => {
|
|
108
|
+
if (item.id === sleepWakeUp.id) {
|
|
109
|
+
return sleepWakeUp
|
|
110
|
+
}
|
|
111
|
+
return item
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
const def = {
|
|
115
|
+
version: 0,
|
|
116
|
+
num: cloneSleepWakeUp.length,
|
|
117
|
+
nodes: cloneDeep(cloneSleepWakeUp)
|
|
118
|
+
}
|
|
119
|
+
const res = isSleep ? await setSleepList(def) : await setWakeUpList(def)
|
|
120
|
+
if (res.success) {
|
|
121
|
+
if (isSleep) {
|
|
122
|
+
state.sleepScheduleList = cloneDeep(cloneSleepWakeUp)
|
|
123
|
+
} else {
|
|
124
|
+
state.wakeUpScheduleList = cloneDeep(cloneSleepWakeUp)
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
success: true
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
return {
|
|
131
|
+
success: false
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
if (state.sleepTagChecked === state.wakeUpTagChecked) {
|
|
138
|
+
state.filteredScheduleList = [...state.sleepScheduleList, ...state.wakeUpScheduleList]
|
|
139
|
+
} else if (state.sleepTagChecked) {
|
|
140
|
+
state.filteredScheduleList = state.sleepScheduleList
|
|
141
|
+
} else {
|
|
142
|
+
state.filteredScheduleList = state.wakeUpScheduleList
|
|
143
|
+
}
|
|
144
|
+
}, [state.sleepTagChecked, state.wakeUpTagChecked, state.sleepScheduleList, state.wakeUpScheduleList])
|
|
145
|
+
|
|
146
|
+
const getTipText = useCallback(() => {
|
|
147
|
+
if (state.sleepScheduleList.length >= MAX_SCHEDULE && state.wakeUpScheduleList.length >= MAX_SCHEDULE) return "both"
|
|
148
|
+
if (state.sleepScheduleList.length >= MAX_SCHEDULE) return "sleep"
|
|
149
|
+
if (state.wakeUpScheduleList.length >= MAX_SCHEDULE) return "wakeup"
|
|
150
|
+
}, [state.sleepScheduleList, state.wakeUpScheduleList])
|
|
151
|
+
|
|
152
|
+
const hasScheduleList = useCallback(() => {
|
|
153
|
+
return !!(state.sleepScheduleList.length && state.wakeUpScheduleList.length)
|
|
154
|
+
}, [state.sleepScheduleList, state.wakeUpScheduleList])
|
|
155
|
+
|
|
156
|
+
const navigateToEdit = (params) => {
|
|
157
|
+
navigation.navigate(ui_biz_routerKey.ui_biz_sleep_wakeUp_edit_new, params)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const isSleepMax = useMemo(() => {
|
|
161
|
+
return state.sleepScheduleList.length >= MAX_SCHEDULE
|
|
162
|
+
}, [state.sleepScheduleList.length])
|
|
163
|
+
|
|
164
|
+
const isWakeUpMax = useMemo(() => {
|
|
165
|
+
return state.wakeUpScheduleList.length >= MAX_SCHEDULE
|
|
166
|
+
}, [state.wakeUpScheduleList.length])
|
|
167
|
+
|
|
168
|
+
const tipText = useMemo(() => {
|
|
169
|
+
const tip = getTipText()
|
|
170
|
+
if (tip === 'sleep') return I18n.getLang('sleepwakeschedule_warning_max_number_sleep_text')
|
|
171
|
+
if (tip === 'wakeup') return I18n.getLang('sleepwakeschedule_warning_max_number_wakeup_text')
|
|
172
|
+
if (tip === 'both') return I18n.getLang('sleepwakeschedule_warning_max_number_both_text')
|
|
173
|
+
return ''
|
|
174
|
+
}, [getTipText()])
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<>
|
|
178
|
+
<Page
|
|
179
|
+
backText={deviceInfo.name}
|
|
180
|
+
onBackClick={navigation.goBack}
|
|
181
|
+
headlineText={I18n.getLang('add_sleepschedule_one_source_system_back_text')}
|
|
182
|
+
headlineIcon={isMaxNum ? undefined : res.device_panel_schedule_add}
|
|
183
|
+
onHeadlineIconClick={() => {
|
|
184
|
+
state.showAddSchedulePopover = !state.showAddSchedulePopover
|
|
185
|
+
}}
|
|
186
|
+
loading={state.loading}
|
|
187
|
+
>
|
|
188
|
+
<View style={{ marginHorizontal: cx(24) }}>
|
|
189
|
+
<Text style={{ color: '#000', fontSize: cx(12) }}>
|
|
190
|
+
{I18n.getLang('timeschedule_overview_description_text')}
|
|
191
|
+
</Text>
|
|
192
|
+
</View>
|
|
193
|
+
<Spacer height={cx(5)} />
|
|
194
|
+
{!!getTipText() && <InfoText
|
|
195
|
+
style={{ marginHorizontal: cx(24), marginBottom: cx(5) }}
|
|
196
|
+
icon={res.ic_warning_amber}
|
|
197
|
+
iconStyle={{ width: cx(16), height: cx(16) }}
|
|
198
|
+
contentColor="#FF9500"
|
|
199
|
+
text={tipText}
|
|
200
|
+
textStyle={{ fontSize: cx(12) }}
|
|
201
|
+
/>}
|
|
202
|
+
{hasScheduleList() && <>
|
|
203
|
+
<View style={styles.tagLine}>
|
|
204
|
+
<Tag
|
|
205
|
+
checked={state.sleepTagChecked}
|
|
206
|
+
text={I18n.getLang('sleepwakeschedule_field_3_Times_chips2_text')}
|
|
207
|
+
onCheckedChange={checked => {
|
|
208
|
+
state.sleepTagChecked = checked
|
|
209
|
+
}} />
|
|
210
|
+
<Spacer width={cx(8)} height={0} />
|
|
211
|
+
<Tag
|
|
212
|
+
checked={state.wakeUpTagChecked}
|
|
213
|
+
text={I18n.getLang('sleepwakeschedule_field_3_Times_chips_text')}
|
|
214
|
+
onCheckedChange={checked => {
|
|
215
|
+
state.wakeUpTagChecked = checked
|
|
216
|
+
}} />
|
|
217
|
+
</View>
|
|
218
|
+
<Spacer height={cx(5)} />
|
|
219
|
+
</>}
|
|
220
|
+
{state.filteredScheduleList.length ?
|
|
221
|
+
<FlatList
|
|
222
|
+
data={state.filteredScheduleList}
|
|
223
|
+
renderItem={({ item }) => (
|
|
224
|
+
<SleepWakeUpCard
|
|
225
|
+
is24HourClock={is24HourClock}
|
|
226
|
+
sleepWakeUp={item}
|
|
227
|
+
onPress={() => {
|
|
228
|
+
onAddScheduleDialogItemClick(item.isSleep, 'edit', item)
|
|
229
|
+
}}
|
|
230
|
+
onSwitch={async (v) => {
|
|
231
|
+
await modDeleteTimeSchedule('edit', item.isSleep, {
|
|
232
|
+
...item,
|
|
233
|
+
enable: v ? 1 : 0
|
|
234
|
+
})
|
|
235
|
+
}}
|
|
236
|
+
/>
|
|
237
|
+
)}
|
|
238
|
+
ListHeaderComponent={() => (<Spacer height={cx(10)} />)}
|
|
239
|
+
ItemSeparatorComponent={() => (<Spacer />)}
|
|
240
|
+
ListFooterComponent={() => (<Spacer />)}
|
|
241
|
+
keyExtractor={(item, idx) => `${item.isSleep ? 'sleep' : 'wakeUp'}_${idx}`}
|
|
242
|
+
/> :
|
|
243
|
+
<View style={styles.emptyListCon}>
|
|
244
|
+
<Spacer height={cx(70)} />
|
|
245
|
+
<Image
|
|
246
|
+
style={styles.emptyImage}
|
|
247
|
+
source={res.scheduleEmpty}
|
|
248
|
+
resizeMode="contain" />
|
|
249
|
+
<Spacer height={cx(20)} />
|
|
250
|
+
<View style={styles.emptyText}>
|
|
251
|
+
<Image
|
|
252
|
+
source={{ uri: res.device_panel_schedule_alert }}
|
|
253
|
+
style={{ width: cx(16), height: cx(16) }}
|
|
254
|
+
/>
|
|
255
|
+
<Text style={styles.emptyNoTime}>
|
|
256
|
+
{
|
|
257
|
+
!hasScheduleList() ?
|
|
258
|
+
I18n.getLang('sleepwakeschedule_empty_information_text') :
|
|
259
|
+
I18n.getLang('sleepwakeschedule_empty_filtering_information_text')
|
|
260
|
+
}
|
|
261
|
+
</Text>
|
|
262
|
+
</View>
|
|
263
|
+
{!hasScheduleList() &&
|
|
264
|
+
<View style={styles.emptyBtnView}>
|
|
265
|
+
<Spacer />
|
|
266
|
+
<TextButton
|
|
267
|
+
style={styles.emptyBtn}
|
|
268
|
+
textStyle={isSleepMax ? styles.disableItemText : { color: '#fff' }}
|
|
269
|
+
text={I18n.getLang('sleepwakeschedule_add_button_text1')}
|
|
270
|
+
onPress={() => onAddScheduleDialogItemClick(true, 'add', getNewSleepWakeUp(true, params))}
|
|
271
|
+
/>
|
|
272
|
+
<Spacer />
|
|
273
|
+
<TextButton
|
|
274
|
+
style={styles.emptyBtn}
|
|
275
|
+
textStyle={isWakeUpMax ? styles.disableItemText : { color: '#fff' }}
|
|
276
|
+
text={I18n.getLang('sleepwakeschedule_add_button_text2')}
|
|
277
|
+
onPress={() => onAddScheduleDialogItemClick(false, 'add', getNewSleepWakeUp(false, params))}
|
|
278
|
+
/>
|
|
279
|
+
</View>}
|
|
280
|
+
</View>
|
|
281
|
+
}
|
|
282
|
+
</Page>
|
|
283
|
+
<CustomListDialog
|
|
284
|
+
show={state.showAddSchedulePopover}
|
|
285
|
+
style={styles.addMoodPopover}
|
|
286
|
+
itemStyle={styles.popoverItem}
|
|
287
|
+
onDismiss={() => {
|
|
288
|
+
state.showAddSchedulePopover = false
|
|
289
|
+
}}
|
|
290
|
+
data={[
|
|
291
|
+
{
|
|
292
|
+
text: I18n.getLang('sleepwakeschedule_add_button_text1'),
|
|
293
|
+
value: true,
|
|
294
|
+
isMax: isSleepMax
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
text: I18n.getLang('sleepwakeschedule_add_button_text2'),
|
|
298
|
+
value: false,
|
|
299
|
+
isMax: isWakeUpMax
|
|
300
|
+
},
|
|
301
|
+
]}
|
|
302
|
+
onItemPress={(isSleep) => onAddScheduleDialogItemClick(isSleep, 'add', getNewSleepWakeUp(isSleep, params))}
|
|
303
|
+
/>
|
|
304
|
+
</>
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const SleepWakeUpCard = (props: {
|
|
309
|
+
sleepWakeUp: SleepUIItem | WakeUpUIItem,
|
|
310
|
+
onSwitch: (enable: boolean) => void,
|
|
311
|
+
onPress: () => void
|
|
312
|
+
is24HourClock: boolean
|
|
313
|
+
}) => {
|
|
314
|
+
const { sleepWakeUp, is24HourClock, onSwitch, onPress } = props
|
|
315
|
+
return (
|
|
316
|
+
<Card style={styles.randomTimingCard} onPress={onPress}>
|
|
317
|
+
<Spacer height={cx(16)} />
|
|
318
|
+
<View style={styles.switchLine}>
|
|
319
|
+
<Text style={styles.time}>
|
|
320
|
+
{`${convertMinutesTo12HourFormat(sleepWakeUp.startTime, is24HourClock)} - ${convertMinutesTo12HourFormat(sleepWakeUp.endTime, is24HourClock)}`}</Text>
|
|
321
|
+
<SwitchButton
|
|
322
|
+
value={sleepWakeUp.enable}
|
|
323
|
+
thumbStyle={{ elevation: 0 }}
|
|
324
|
+
onValueChange={onSwitch} />
|
|
325
|
+
</View>
|
|
326
|
+
<Text style={styles.loopText}>{loopText(sleepWakeUp.weeks)}</Text>
|
|
327
|
+
<Spacer height={cx(5)} />
|
|
328
|
+
<Text style={styles.loopText}>{sleepWakeUp.name}</Text>
|
|
329
|
+
<Spacer height={cx(10)} />
|
|
330
|
+
<View style={styles.tag}>
|
|
331
|
+
<Text style={styles.tagTitle}>
|
|
332
|
+
{I18n.getLang(sleepWakeUp.isSleep ? 'sleepwakeschedule_field_3_Times_chips2_text' : 'sleepwakeschedule_field_3_Times_chips_text')}
|
|
333
|
+
</Text>
|
|
334
|
+
</View>
|
|
335
|
+
<Spacer />
|
|
336
|
+
</Card>
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const getNewSleepWakeUp = (isSleep: boolean, params: SleepWakeUpPageRouteParams) => {
|
|
341
|
+
const def = {
|
|
342
|
+
name: '',
|
|
343
|
+
weeks: [0, 0, 0, 0, 0, 0, 0],
|
|
344
|
+
delay: 6,
|
|
345
|
+
hour: isSleep ? 23 : 7,
|
|
346
|
+
minute: 0,
|
|
347
|
+
h: 0,
|
|
348
|
+
s: 100,
|
|
349
|
+
v: 100,
|
|
350
|
+
brightness: 100,
|
|
351
|
+
temperature: 0,
|
|
352
|
+
last: 0,
|
|
353
|
+
startTime: isSleep ? 1380 : 390,
|
|
354
|
+
endTime: isSleep ? 1410 : 420,
|
|
355
|
+
isColorMode: params.isSupportColor ? true : false,
|
|
356
|
+
isSleep
|
|
357
|
+
}
|
|
358
|
+
return def
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const styles = StyleSheet.create({
|
|
362
|
+
tagLine: {
|
|
363
|
+
flexDirection: 'row',
|
|
364
|
+
marginHorizontal: cx(24),
|
|
365
|
+
},
|
|
366
|
+
infoLine: {
|
|
367
|
+
marginHorizontal: cx(24),
|
|
368
|
+
},
|
|
369
|
+
addMoodPopover: {
|
|
370
|
+
width: cx(210),
|
|
371
|
+
height: cx(90.5),
|
|
372
|
+
marginStart: cx(115),
|
|
373
|
+
marginTop: cx(100),
|
|
374
|
+
backgroundColor: '#fff',
|
|
375
|
+
},
|
|
376
|
+
popoverItem: {
|
|
377
|
+
width: cx(210),
|
|
378
|
+
height: cx(45),
|
|
379
|
+
alignItems: 'flex-start',
|
|
380
|
+
},
|
|
381
|
+
emptyListCon: {
|
|
382
|
+
flex: 1,
|
|
383
|
+
alignItems: 'center',
|
|
384
|
+
},
|
|
385
|
+
emptyImage: {
|
|
386
|
+
width: cx(225),
|
|
387
|
+
height: cx(198),
|
|
388
|
+
},
|
|
389
|
+
emptyText: {
|
|
390
|
+
flexDirection: 'row',
|
|
391
|
+
alignItems: 'center'
|
|
392
|
+
},
|
|
393
|
+
emptyNoTime: {
|
|
394
|
+
fontSize: cx(12),
|
|
395
|
+
lineHeight: cx(20),
|
|
396
|
+
textAlign: 'center',
|
|
397
|
+
fontFamily: 'helvetica_neue_lt_std_roman',
|
|
398
|
+
color: '#000'
|
|
399
|
+
},
|
|
400
|
+
emptyBtnView: {
|
|
401
|
+
alignItems: 'center'
|
|
402
|
+
},
|
|
403
|
+
emptyBtn: {
|
|
404
|
+
backgroundColor: '#f60',
|
|
405
|
+
borderRadius: cx(5),
|
|
406
|
+
paddingHorizontal: cx(15),
|
|
407
|
+
paddingVertical: cx(10)
|
|
408
|
+
},
|
|
409
|
+
addTimer: {
|
|
410
|
+
justifyContent: 'center',
|
|
411
|
+
alignItems: 'center',
|
|
412
|
+
// width,
|
|
413
|
+
marginVertical: cx(20),
|
|
414
|
+
},
|
|
415
|
+
disableItemText: {
|
|
416
|
+
color: '#CBCBCB',
|
|
417
|
+
fontSize: cx(16),
|
|
418
|
+
},
|
|
419
|
+
randomTimingCard: {
|
|
420
|
+
marginHorizontal: cx(24),
|
|
421
|
+
paddingHorizontal: cx(16),
|
|
422
|
+
},
|
|
423
|
+
switchLine: {
|
|
424
|
+
flexDirection: 'row',
|
|
425
|
+
alignItems: 'center',
|
|
426
|
+
},
|
|
427
|
+
time: {
|
|
428
|
+
flex: 1,
|
|
429
|
+
color: '#000',
|
|
430
|
+
fontSize: cx(16),
|
|
431
|
+
fontWeight: 'bold',
|
|
432
|
+
fontFamily: 'helvetica_neue_lt_std_bd',
|
|
433
|
+
},
|
|
434
|
+
switchBtn: {},
|
|
435
|
+
loopText: {
|
|
436
|
+
color: '#000',
|
|
437
|
+
fontSize: cx(14),
|
|
438
|
+
fontFamily: 'helvetica_neue_lt_std_roman',
|
|
439
|
+
height: cx(20)
|
|
440
|
+
},
|
|
441
|
+
tag: {
|
|
442
|
+
alignSelf: 'flex-start',
|
|
443
|
+
borderRadius: cx(16),
|
|
444
|
+
height: cx(16),
|
|
445
|
+
backgroundColor: 'rgb(230,231,232)',
|
|
446
|
+
paddingHorizontal: cx(10),
|
|
447
|
+
},
|
|
448
|
+
tagTitle: {
|
|
449
|
+
fontSize: cx(10),
|
|
450
|
+
textAlign: 'center',
|
|
451
|
+
fontFamily: 'PingFangSC-Medium',
|
|
452
|
+
color: '#000'
|
|
453
|
+
},
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
export default SleepWakeUpPage
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { Utils } from "tuya-panel-kit";
|
|
2
|
+
import { getArray, getWeek } from '@ledvance/base/src/utils/common';
|
|
3
|
+
import { cloneDeep } from "lodash";
|
|
4
|
+
const { hexStringToNumber } = Utils.StringUtils;
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
//// 入睡计划
|
|
8
|
+
export function decodeSleepString(allSleep: string) {
|
|
9
|
+
if (!allSleep || allSleep === '') {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
const version = allSleep.substring(0, 2)
|
|
13
|
+
const count = parseInt(allSleep.substring(2, 4))
|
|
14
|
+
if (count === 0 || version !== '00') {
|
|
15
|
+
return []
|
|
16
|
+
}
|
|
17
|
+
const contentString = allSleep.substring(4)
|
|
18
|
+
const list = getArray(contentString, 11 * 2)
|
|
19
|
+
const sleepList = list.map((item, index) => {
|
|
20
|
+
return {
|
|
21
|
+
...decodeSingleSleepString(item),
|
|
22
|
+
index: index,
|
|
23
|
+
name: `sleepPlan ${index + 1}`
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
return sleepList
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 通过云端获取数据并渲染 sleep
|
|
31
|
+
export function highInTheCloudsSleepString(featureList) {
|
|
32
|
+
if (!!!featureList) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
const sleepList = featureList.map((item, index) => {
|
|
36
|
+
const data = decodeSingleSleepString(item?.startTime)
|
|
37
|
+
return {
|
|
38
|
+
...data,
|
|
39
|
+
loops: data?.loops?.reverse(),
|
|
40
|
+
index: index,
|
|
41
|
+
name: item?.name || `sleepPlan ${index}`
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
return sleepList
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function decodeSingleSleepString(sleep: string) {
|
|
48
|
+
const numbers = hexStringToNumber(sleep)
|
|
49
|
+
const enable = numbers[0]
|
|
50
|
+
const week = getWeek(sleep.substring(2, 4))
|
|
51
|
+
const fade = numbers[2] * 5
|
|
52
|
+
const time = numbers.slice(3, 5)
|
|
53
|
+
const hue = numbers[5] * 100 + numbers[6]
|
|
54
|
+
const sat = numbers[7]
|
|
55
|
+
const value = numbers[8]
|
|
56
|
+
const brightness = numbers[9]
|
|
57
|
+
const temperature = numbers[10]
|
|
58
|
+
const name = numbers[11]
|
|
59
|
+
|
|
60
|
+
const result = {
|
|
61
|
+
isSleep: true,
|
|
62
|
+
enable,
|
|
63
|
+
loops: week,
|
|
64
|
+
fade,
|
|
65
|
+
time,
|
|
66
|
+
hue,
|
|
67
|
+
sat,
|
|
68
|
+
value,
|
|
69
|
+
brightness,
|
|
70
|
+
temperature,
|
|
71
|
+
name
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
return result
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function encodeSleep(sleepList: any) {
|
|
79
|
+
const targetList = sleepList
|
|
80
|
+
let allHex = ''
|
|
81
|
+
allHex = allHex + '00' + targetList.length.toString().padStart(2, '0')
|
|
82
|
+
targetList.forEach(item => {
|
|
83
|
+
allHex = allHex + encodeSingleSleepPlan(item)
|
|
84
|
+
})
|
|
85
|
+
return allHex
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export function encodeSingleSleepPlan(item) {
|
|
90
|
+
const enableHex = getEnableHex(item.enable)
|
|
91
|
+
const loopHex = getLoopHex(item.loops)
|
|
92
|
+
const fadeHex = getFadeHex(item.fade)
|
|
93
|
+
const timeHex = getTimeHex(item.time)
|
|
94
|
+
|
|
95
|
+
const colorHex = getHueHex(item.hue)
|
|
96
|
+
const satHex = getSatHex(item.sat)
|
|
97
|
+
const valueHex = getValueHex(item.value)
|
|
98
|
+
|
|
99
|
+
const brightnessHex = getBrightnessHex(item.brightness)
|
|
100
|
+
const temperatureHex = getTemperatureHex(item.temperature)
|
|
101
|
+
let hex = enableHex + loopHex + fadeHex + timeHex + colorHex + satHex + valueHex + brightnessHex + temperatureHex
|
|
102
|
+
|
|
103
|
+
return hex
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function getEnableHex(enable) {
|
|
107
|
+
const enableNumber = enable ? 1 : 0
|
|
108
|
+
return enableNumber.toString().padStart(2, '0')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function getLoopHex(loop) {
|
|
112
|
+
const cloneLoop = cloneDeep(loop)
|
|
113
|
+
return parseInt(cloneLoop.reverse().join('').padStart(8, '0'), 2).toString(16).padStart(2, '0')
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function getFadeHex(fade) {
|
|
117
|
+
return (fade / 5).toString(16).padStart(2, '0')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function getTimeHex(time) {
|
|
121
|
+
return time[0].toString(16).padStart(2, '0') + time[1].toString(16).padStart(2, '0')
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function getBrightnessHex(b: number) {
|
|
125
|
+
return b.toString(16).padStart(2, '0')
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function getTemperatureHex(t: number) {
|
|
129
|
+
return t.toString(16).padStart(2, '0')
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function getHueHex(h: number) {
|
|
133
|
+
return Math.trunc(h / 100).toString(16).padStart(2, '0') + (h % 100).toString(16).padStart(2, '0')
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function getSatHex(s: number) {
|
|
137
|
+
return s.toString(16).padStart(2, '0')
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function getValueHex(v: number) {
|
|
141
|
+
return v.toString(16).padStart(2, '0')
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
//// 唤醒计划
|
|
145
|
+
export function decodeWakeUpString(allString: string) {
|
|
146
|
+
if (!allString || allString === '') {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const version = allString.substring(0, 2)
|
|
151
|
+
const count = parseInt(allString.substring(2, 4))
|
|
152
|
+
if (count === 0 || version !== '00') {
|
|
153
|
+
return []
|
|
154
|
+
}
|
|
155
|
+
const contentString = allString.substring(4)
|
|
156
|
+
const list = getArray(contentString, 12 * 2)
|
|
157
|
+
|
|
158
|
+
const weekList = list.map((item, index) => {
|
|
159
|
+
return {
|
|
160
|
+
...decodeSingleWakeUpString(item),
|
|
161
|
+
index: index,
|
|
162
|
+
name: `wakeUpPlan ${index + 1}`
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
return weekList
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 通过云端获取数据并渲染 wakeUp
|
|
170
|
+
export function highInTheCloudsWakeString(featureList) {
|
|
171
|
+
if (!!!featureList) {
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
const wakeUpList = featureList.map((item, index) => {
|
|
175
|
+
const data = decodeSingleWakeUpString(item?.startTime)
|
|
176
|
+
return {
|
|
177
|
+
...data,
|
|
178
|
+
loops: data?.loops?.reverse(),
|
|
179
|
+
index: index,
|
|
180
|
+
name: item?.name || `wakeUpPlan ${index}`
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
return wakeUpList
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function decodeSingleWakeUpString(string: string) {
|
|
187
|
+
const numbers = hexStringToNumber(string)
|
|
188
|
+
const enable = numbers[0]
|
|
189
|
+
const week = getWeek(string.substring(2, 4))
|
|
190
|
+
const fade: number = numbers[2] * 5
|
|
191
|
+
const time = numbers.slice(3, 5)
|
|
192
|
+
const hue = numbers[5] * 100 + numbers[6]
|
|
193
|
+
const sat = numbers[7]
|
|
194
|
+
const value = numbers[8]
|
|
195
|
+
const brightness = numbers[9]
|
|
196
|
+
const temperature = numbers[10]
|
|
197
|
+
const duration = numbers[11] * 5
|
|
198
|
+
|
|
199
|
+
const result = {
|
|
200
|
+
isSleep: false,
|
|
201
|
+
enable,
|
|
202
|
+
loops: week,
|
|
203
|
+
fade,
|
|
204
|
+
time,
|
|
205
|
+
hue,
|
|
206
|
+
sat,
|
|
207
|
+
value,
|
|
208
|
+
brightness,
|
|
209
|
+
temperature,
|
|
210
|
+
duration,
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
return result
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function encodeWakeUp(wakeUpList: any) {
|
|
218
|
+
const targetList = wakeUpList
|
|
219
|
+
|
|
220
|
+
let allHex = ''
|
|
221
|
+
allHex = allHex + '00' + targetList.length.toString().padStart(2, '0')
|
|
222
|
+
|
|
223
|
+
targetList.forEach(item => {
|
|
224
|
+
allHex = allHex + encodeSingleWakeUpPlan(item)
|
|
225
|
+
})
|
|
226
|
+
// return allHex;
|
|
227
|
+
return allHex
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
export function encodeSingleWakeUpPlan(item) {
|
|
232
|
+
|
|
233
|
+
const enableHex = getEnableHex(item.enable)
|
|
234
|
+
const loopHex = getLoopHex(item.loops)
|
|
235
|
+
const fadeHex = getFadeHex(item.fade)
|
|
236
|
+
const timeHex = getTimeHex(item.time)
|
|
237
|
+
|
|
238
|
+
const hueHex = getHueHex(item.hue)
|
|
239
|
+
const satHex = getSatHex(item.sat)
|
|
240
|
+
const valueHex = getValueHex(item.value)
|
|
241
|
+
|
|
242
|
+
const brightnessHex = getBrightnessHex(item.brightness)
|
|
243
|
+
const temperatureHex = getTemperatureHex(item.temperature)
|
|
244
|
+
const durationHex = getDurationHex(item.duration)
|
|
245
|
+
|
|
246
|
+
let hex = enableHex + loopHex + fadeHex + timeHex + hueHex + satHex + valueHex + brightnessHex + temperatureHex + durationHex
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
return hex
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function getDurationHex(d) {
|
|
253
|
+
return (d / 5).toString(16).padStart(2, '0')
|
|
254
|
+
}
|