@ledvance/ui-biz-bundle 1.0.2 → 1.0.3

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 (35) hide show
  1. package/.babelrc +31 -31
  2. package/.eslintignore +5 -5
  3. package/.eslintrc.js +27 -27
  4. package/.prettierrc.js +1 -1
  5. package/.versionrc +5 -5
  6. package/package.json +72 -72
  7. package/rn-cli.config.js +8 -8
  8. package/src/modules/history/HistoryPage.d.ts +2 -2
  9. package/src/modules/history/HistoryPage.tsx +254 -254
  10. package/src/modules/history/SwitchHistoryPageActions.d.ts +13 -13
  11. package/src/modules/history/SwitchHistoryPageActions.ts +53 -53
  12. package/src/modules/hooks/DeviceDpStateHooks.ts +27 -0
  13. package/src/modules/mood/MixLightActions.ts +82 -0
  14. package/src/modules/mood/MixLightSceneActions.ts +259 -0
  15. package/src/modules/mood/MixMoodItem.tsx +138 -0
  16. package/src/modules/mood/MixScene.tsx +131 -0
  17. package/src/modules/mood/MixSceneBeans.ts +62 -0
  18. package/src/modules/mood/MoodAction.ts +222 -0
  19. package/src/modules/mood/MoodItem.tsx +113 -0
  20. package/src/modules/mood/SceneInfo.ts +319 -0
  21. package/src/modules/timeSchedule/DeviceState.tsx +54 -0
  22. package/src/modules/timeSchedule/LdvScheduleItem.tsx +125 -0
  23. package/src/modules/timeSchedule/ManualSetting.tsx +69 -0
  24. package/src/modules/timeSchedule/MoodSetting.tsx +66 -0
  25. package/src/modules/timeSchedule/ScheduleScene.tsx +138 -0
  26. package/src/modules/timeSchedule/SingleLightView.tsx +254 -0
  27. package/src/modules/timeSchedule/TimeScheduleEditpage.tsx +480 -0
  28. package/src/modules/timeSchedule/TimeSchedulePage.tsx +325 -0
  29. package/src/modules/timeSchedule/TimeSchedulePageEdit.tsx +0 -0
  30. package/src/modules/timeSchedule/mix/MixLightBean.ts +10 -0
  31. package/src/modules/timeSchedule/mix/MixLightView.tsx +221 -0
  32. package/src/modules/timeSchedule/utils.ts +7 -0
  33. package/src/modules/timer/TimerPage.tsx +409 -406
  34. package/src/modules/timer/{timerPageAction.ts → TimerPageAction.ts} +91 -91
  35. package/tsconfig.json +50 -50
@@ -0,0 +1,480 @@
1
+ import React, { useEffect, useCallback } from "react";
2
+ import { ScrollView, StyleSheet, Text, View, FlatList, TouchableOpacity, Image } from 'react-native'
3
+ import Page from '@ledvance/base/src/components/Page'
4
+ import TextField from '@ledvance/base/src/components/TextField'
5
+ import I18n from '@ledvance/base/src/i18n'
6
+ import { useNavigation, useRoute } from '@react-navigation/native'
7
+ import LdvTopName from "@ledvance/base/src/components/ldvTopName";
8
+ import LdvPickerView from '@ledvance/base/src/components/ldvPickerView'
9
+ import LdvWeekView from '@ledvance/base/src/components/weekSelect'
10
+ import { SwitchButton, Utils } from 'tuya-panel-kit'
11
+ import Spacer from '@ledvance/base/src/components/Spacer'
12
+ import DeleteButton from '@ledvance/base/src/components/DeleteButton'
13
+ import { toFixed, loopText } from '@ledvance/base/src/utils/common'
14
+ import { NativeApi } from '@ledvance/base/src/api/native'
15
+ import { useDeviceId } from '@ledvance/base/src/models/modules/NativePropsSlice'
16
+ // import dpCodes from "config/dpCodes";
17
+ import res from '@res'
18
+ import { useReactive } from 'ahooks';
19
+ import { dpItem } from "./TimeSchedulePage";
20
+ import { cloneDeep, differenceBy } from "lodash";
21
+ import DeviceState from "./DeviceState";
22
+
23
+ const { convertX: cx } = Utils.RatioUtils
24
+
25
+
26
+ export interface ScheduleItemDp extends dpItem {
27
+ enable: boolean
28
+ }
29
+
30
+ interface TimeScheduleEditPageParams {
31
+ scheduleItem: any,
32
+ dps: ScheduleItemDp[]
33
+ dpCodes: Record<any, any>
34
+ reloadData: () => void
35
+ deleteDialog: (item: any) => Promise<void>
36
+ }
37
+
38
+ const TimeScheduleEditPage = () => {
39
+ const navigation = useNavigation()
40
+ const devId = useDeviceId()
41
+ const route = useRoute()
42
+ const { scheduleItem, dps, reloadData, deleteDialog, dpCodes } = route.params as TimeScheduleEditPageParams
43
+ const state = useReactive({
44
+ hour: '00',
45
+ minute: '00',
46
+ loop: [0, 0, 0, 0, 0, 0, 0],
47
+ isNotification: false,
48
+ brightValue: 50,
49
+ name: '',
50
+ selectedSkill: [] as ScheduleItemDp[],
51
+ skillList: [] as ScheduleItemDp[],
52
+ isManual: true,
53
+ dpsValue: {} as Record<string,any>
54
+ })
55
+
56
+
57
+
58
+ useEffect(() => {
59
+ // 设置功能列表
60
+ if (scheduleItem) {
61
+ state.hour = scheduleItem.time.split(':')[0];
62
+ state.minute = scheduleItem.time.split(':')[1];
63
+ state.name = scheduleItem.aliasName;
64
+ state.isNotification = scheduleItem.isAppPush;
65
+ state.loop = scheduleItem.loops.split('').map(mItem => parseInt(mItem));
66
+ state.brightValue = parseInt(scheduleItem.dps[dpCodes.bright_value]) / 10 || 50
67
+ state.selectedSkill = dps.reduce((pre, cur) => {
68
+ if (scheduleItem.dps[cur.dpId] !== undefined) {
69
+ const result = { ...cur, enable: scheduleItem.dps[cur.dpId] }
70
+ pre.push(result)
71
+ }
72
+ return pre
73
+ }, [] as ScheduleItemDp[])
74
+ state.skillList = differenceBy(dps, state.selectedSkill, 'dpId')
75
+ } else {
76
+ const date = new Date();
77
+ state.hour = toFixed(date.getHours(), 2);
78
+ state.minute = toFixed(date.getMinutes(), 2);
79
+ state.skillList = dps.map(item => ({
80
+ ...item,
81
+ enable: true
82
+ }))
83
+ }
84
+ }, [])
85
+
86
+
87
+ const selectWeekAction = (idx: number) => {
88
+ const newLoop = state.loop.map((item, tempIndex) => {
89
+ if (tempIndex === idx - 1) {
90
+ return item > 0 ? 0 : 1;
91
+ }
92
+ return item;
93
+
94
+ });
95
+ state.loop = newLoop;
96
+ };
97
+
98
+ const saveEnable = () => {
99
+ return !!state.name.length && !!state.selectedSkill.length;
100
+ };
101
+
102
+ const saveAction = () => {
103
+ getSendDps()
104
+ if (!saveEnable()) {
105
+ return;
106
+ }
107
+ const params = {
108
+ time: [state.hour, state.minute].join(':'),
109
+ loops: state.loop.join(''),
110
+ dps: getSendDps(),
111
+ aliasName: state.name,
112
+ status: true,
113
+ notification: state.isNotification,
114
+ }
115
+ if (scheduleItem) {
116
+ NativeApi.editTimer(
117
+ devId,
118
+ {
119
+ ...params,
120
+ id: scheduleItem.id
121
+ },
122
+ res => {
123
+ if (res?.result) {
124
+ reloadData()
125
+ navigation.goBack();
126
+ }
127
+ }
128
+ );
129
+ } else {
130
+ NativeApi.addTimer(
131
+ devId,
132
+ params,
133
+ res => {
134
+ if (res?.result) {
135
+ reloadData()
136
+ navigation.goBack();
137
+ }
138
+ }
139
+ );
140
+ }
141
+ };
142
+
143
+ const getSendDps = () => {
144
+ let dp = cloneDeep(state.dpsValue)
145
+ state.selectedSkill.forEach(item => {
146
+ dp = {
147
+ ...dp,
148
+ [item.dpId]: item.enable
149
+ }
150
+ })
151
+ console.log(dp, '< --- dp')
152
+ return dp
153
+ }
154
+
155
+ const setSendDps = useCallback((dps: Record<string, any>) =>{
156
+ state.dpsValue = dps
157
+ }, [])
158
+
159
+ const renderItem = ({ item }) => {
160
+ return (
161
+ <View style={{
162
+ flexDirection: 'row',
163
+ justifyContent: 'space-between',
164
+ alignItems: 'center',
165
+ backgroundColor: '#fff',
166
+ marginBottom: cx(8)
167
+ }}>
168
+ <Text
169
+ style={{
170
+ color: '#000',
171
+ fontSize: 14,
172
+ marginHorizontal: cx(6),
173
+ marginVertical: cx(9),
174
+ }}
175
+ >
176
+ {item.label}
177
+ </Text>
178
+ <TouchableOpacity onPress={() => handelSkill('lower', item)}>
179
+ <Image style={{ width: cx(16), height: cx(16), marginRight: cx(5) }} source={res.ic_arrows_nav_clear} />
180
+ </TouchableOpacity>
181
+ </View>
182
+ );
183
+ };
184
+
185
+ const handelSkill = (handelType: string, skill: ScheduleItemDp) => {
186
+ if (handelType === 'add') {
187
+ state.selectedSkill = [...state.selectedSkill, skill]
188
+ state.skillList = state.skillList.filter(item => item.dpId !== skill.dpId)
189
+ } else {
190
+ state.skillList = [...state.skillList, skill]
191
+ state.selectedSkill = state.selectedSkill.filter(item => item.dpId !== skill.dpId)
192
+ }
193
+ }
194
+
195
+ const hasSelected = () => {
196
+ return !!state.selectedSkill.length
197
+ }
198
+
199
+
200
+ const changeSkillEnable = (enable: boolean, idx:number) =>{
201
+ state.selectedSkill = state.selectedSkill.map((skill, index) => {
202
+ if(idx === index){
203
+ skill.enable = enable
204
+ }
205
+ return skill
206
+ })
207
+ }
208
+
209
+ return (
210
+ <Page
211
+ backText={I18n.getLang('motion_detection_add_time_schedule_system_back_text')}
212
+ onBackClick={navigation.goBack}
213
+ rightButtonIcon={saveEnable() ? res.ic_check : res.ic_uncheck}
214
+ rightButtonIconClick={saveAction}
215
+ >
216
+ <ScrollView
217
+ nestedScrollEnabled={true}
218
+ showsHorizontalScrollIndicator={false}
219
+ showsVerticalScrollIndicator={false}
220
+ >
221
+ <LdvTopName title={I18n.getLang('motion_detection_add_time_schedule_headline_text')} />
222
+ <View style={styles.content}>
223
+ <TextField
224
+ value={state.name}
225
+ placeholder={I18n.getLang('motion_detection_add_time_schedule_selectionfield_text')}
226
+ onChangeText={(t: string) => {
227
+ state.name = t;
228
+ }}
229
+ />
230
+ {/* pick */}
231
+ <LdvPickerView
232
+ style={styles.picker}
233
+ hour={state.hour}
234
+ minute={state.minute}
235
+ setHour={v => (state.hour = v)}
236
+ setMinute={v => (state.minute = v)}
237
+ unit={['h', 'min']}
238
+ />
239
+ {/* week */}
240
+ <LdvWeekView
241
+ value={state.loop}
242
+ style={styles.zeroMarginHorizontal}
243
+ onSelect={selectWeekAction}
244
+ />
245
+ <Text style={styles.loopText}>{loopText(state.loop)}</Text>
246
+ {/* Apply for */}
247
+ <View>
248
+ <Text style={styles.itemTitle}>{I18n.getLang('timeschedule_add_schedule_subheadline_text')}</Text>
249
+ <View
250
+ style={{
251
+ backgroundColor: '#f6f6f6',
252
+ borderRadius: 4,
253
+ minHeight: cx(50),
254
+ flex: 1,
255
+ justifyContent: 'center',
256
+ }}
257
+ >
258
+ {!hasSelected() ? <Text style={{ marginLeft: cx(10) }}>{I18n.getLang('timer_ceiling_fan_selectionfield_no_components_text')}</Text> :
259
+ <View
260
+ style={{
261
+ marginHorizontal: cx(8),
262
+ marginTop: cx(8),
263
+ borderRadius: 4,
264
+ }}
265
+ >
266
+ <FlatList
267
+ data={state.selectedSkill}
268
+ renderItem={item => renderItem(item)}
269
+ keyExtractor={(item) => item.dpId + 'selected'}
270
+ />
271
+ </View>}
272
+ </View>
273
+ {state.skillList.map((item) => {
274
+ return (
275
+ <TouchableOpacity style={styles.skillListItem} key={item.dpId + 'skill'} onPress={() => handelSkill('add', item)}>
276
+ <Text style={{ color: '#000' }}>{item.label}</Text>
277
+ <Image style={{ width: cx(16), height: cx(16) }} source={res.device_panel_timer_add} />
278
+ </TouchableOpacity>
279
+ )
280
+ })}
281
+ </View>
282
+ {/* Device state */}
283
+ <View>
284
+ <Text style={styles.itemTitle}>{I18n.getLang('timeschedule_add_schedule_subheadline2_text')}</Text>
285
+ </View>
286
+ <DeviceState
287
+ dpCodes={dpCodes}
288
+ dps={state.selectedSkill}
289
+ scheduleItem={scheduleItem}
290
+ isManual={state.isManual}
291
+ setIsManual={(v) => state.isManual = v}
292
+ setSendDps={setSendDps}
293
+ changeSkillEnable={changeSkillEnable}
294
+ />
295
+ {!hasSelected() && <View style={{ flexDirection: 'row', alignItems: 'center' }}>
296
+ <Image style={{ width: cx(16), height: cx(16), tintColor: '#FF9500' }} source={res.ic_warning_amber} />
297
+ <Text style={{ color: '#FF9500', marginLeft: cx(5) }}>{I18n.getLang('timeschedule_add_schedule_no_device_warning_text')}</Text>
298
+ </View>}
299
+ {/* Settings */}
300
+ <Text style={styles.itemTitle}>{I18n.getLang('timeschedule_add_schedule_subheadline4_text')}</Text>
301
+ <View style={styles.switchButton}>
302
+ <Text style={styles.text}>{I18n.getLang('timeschedule_add_schedule_text2')}</Text>
303
+ <SwitchButton
304
+ value={state.isNotification}
305
+ onValueChange={value => {
306
+ state.isNotification = value;
307
+ }}
308
+ />
309
+ </View>
310
+ {/* Summary */}
311
+ <View>
312
+ <Text style={styles.itemTitle}>{I18n.getLang('add_randomtimecycle_subheadline_text')}</Text>
313
+ <View style={styles.summaryContainer}>
314
+ <View style={styles.summaryLeft}>
315
+ <Image
316
+ source={res.summary_icon1}
317
+ resizeMode="contain"
318
+ style={styles.summaryImg}
319
+ />
320
+ <View>
321
+ <Text style={styles.leftTitle}>{I18n.getLang('feature_summary_frequency_headline')}</Text>
322
+ </View>
323
+ </View>
324
+ <View style={styles.summaryRight}>
325
+ <Text style={styles.rightItem}>{loopText(state.loop)}</Text>
326
+ </View>
327
+ </View>
328
+ <View style={styles.summaryContainer}>
329
+ <View style={styles.summaryLeft}>
330
+ <Image
331
+ source={res.summary_icon2}
332
+ resizeMode="contain"
333
+ style={styles.summaryImg}
334
+ />
335
+ <View>
336
+ <Text style={styles.leftTitle}>{I18n.getLang('feature_summary_time_headline')}</Text>
337
+ </View>
338
+ </View>
339
+ <View style={styles.summaryRight}>
340
+ <Text style={styles.rightItem}>{[state.hour, state.minute].join(':')}</Text>
341
+ </View>
342
+ </View>
343
+ <View style={styles.summaryContainer}>
344
+ <View style={styles.summaryLeft}>
345
+ <Image
346
+ source={res.summary_icon3}
347
+ resizeMode="contain"
348
+ style={styles.summaryImg}
349
+ />
350
+ <View>
351
+ <Text style={styles.leftTitle}>{I18n.getLang('motion_detection_add_time_schedule_actions_text1')}</Text>
352
+ </View>
353
+ </View>
354
+ <View style={styles.summaryRight}>
355
+ {!!state.selectedSkill.length && <>
356
+ {(!!state.selectedSkill.filter(skill => skill.enable).length) && <>
357
+ <Text>{I18n.getLang('feature_summary_action_txt_1')}</Text>
358
+ <View style={{ flexDirection: 'row' }}>{
359
+ state.selectedSkill.filter(skill => skill.enable).map(item => (
360
+ <Text style={[styles.rightItem, { marginRight: cx(5), marginBottom: cx(5) }]} key={item.dpId}>{item.label}</Text>
361
+ ))
362
+ }</View>
363
+ </>}
364
+
365
+ {(!!state.selectedSkill.filter(skill => !skill.enable).length) && <>
366
+ <Text>{I18n.getLang('feature_summary_action_txt_2')}</Text>
367
+ <View style={{ flexDirection: 'row' }}>{
368
+ state.selectedSkill.filter(skill => !skill.enable).map(item => (
369
+ <Text style={[styles.rightItem, { marginRight: cx(5), marginBottom: cx(5) }]} key={item.dpId}>{item.label}</Text>
370
+ ))
371
+ }</View>
372
+ </>}
373
+ </>}
374
+ </View>
375
+ </View>
376
+ <Spacer height={cx(40)} />
377
+ {!!scheduleItem && <View style={{ marginBottom: cx(24) }}>
378
+ <DeleteButton
379
+ text={I18n.getLang('edit_timeschedule_bttn_text')}
380
+ onPress={() => {
381
+ deleteDialog(scheduleItem).then(() => {
382
+ navigation.goBack()
383
+ })
384
+ }}
385
+ />
386
+ </View>}
387
+ </View>
388
+ </View>
389
+ </ScrollView>
390
+ </Page>
391
+ )
392
+ }
393
+
394
+ const styles = StyleSheet.create({
395
+ content: {
396
+ marginHorizontal: cx(24)
397
+ },
398
+ picker: {
399
+ marginHorizontal: cx(24),
400
+ marginVertical: cx(15),
401
+ color: 'rgb(35,35,38)',
402
+ },
403
+ zeroMarginHorizontal: {
404
+ marginHorizontal: 0,
405
+ },
406
+ loopText: {
407
+ fontSize: cx(14),
408
+ fontFamily: 'PingFangSC-Medium',
409
+ color: '#999999',
410
+ marginTop: cx(10)
411
+ },
412
+ itemTitle: {
413
+ color: '#000',
414
+ fontSize: cx(16),
415
+ fontWeight: 'bold',
416
+ fontFamily: 'helvetica_neue_lt_std_bd',
417
+ marginTop: cx(30),
418
+ marginBottom: cx(10)
419
+ },
420
+ switchButton: {
421
+ flexDirection: 'row',
422
+ alignItems: 'center',
423
+ justifyContent: 'space-between',
424
+ marginBottom: cx(10)
425
+ },
426
+ text: {
427
+ color: '#000'
428
+ },
429
+ switchCard: {
430
+ paddingVertical: cx(16),
431
+ },
432
+ switchCardContent: {
433
+ flexDirection: 'row',
434
+ alignItems: 'center',
435
+ },
436
+ switchCardTitle: {
437
+ color: '#000',
438
+ fontSize: cx(16),
439
+ fontFamily: 'helvetica_neue_lt_std_bd',
440
+ },
441
+ skillListItem: {
442
+ flexDirection: 'row',
443
+ justifyContent: 'space-between',
444
+ height: cx(30),
445
+ alignItems: 'center',
446
+ marginVertical: cx(5)
447
+ },
448
+ summaryContainer: {
449
+ flexDirection: 'row',
450
+ justifyContent: 'flex-start',
451
+ alignItems: 'center',
452
+ marginBottom: cx(10)
453
+ },
454
+ summaryImg: {
455
+ height: cx(12),
456
+ width: cx(12),
457
+ marginRight: cx(6)
458
+ },
459
+ summaryLeft: {
460
+ flexDirection: 'row',
461
+ alignItems: 'center',
462
+ minWidth: cx(90),
463
+ },
464
+ leftTitle: {
465
+ fontSize: cx(14),
466
+ color: '#000',
467
+ },
468
+ summaryRight: {
469
+ flexDirection: 'column',
470
+ marginLeft: cx(21),
471
+ },
472
+ rightItem: {
473
+ paddingHorizontal: cx(12),
474
+ backgroundColor: '#cbcbcb',
475
+ borderRadius: cx(16),
476
+ color: '#000',
477
+ }
478
+ })
479
+
480
+ export default TimeScheduleEditPage