@ledvance/group-ui-biz-bundle 1.0.69 → 1.0.70
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/modules/childLock/ChildLockPage.tsx +97 -0
- package/src/modules/childLock/Router.ts +16 -0
- package/src/modules/lightMode/LightModePage.tsx +210 -0
- package/src/modules/lightMode/Router.ts +16 -0
- package/src/modules/overchargeSwitch/OverchargeSwitchPage.tsx +96 -0
- package/src/modules/overchargeSwitch/Router.ts +16 -0
- package/src/modules/swithInching/Router.ts +16 -0
- package/src/modules/swithInching/SwithInching.tsx +170 -0
- package/src/modules/swithInching/SwithInchingAction.ts +32 -0
- package/src/modules/swithInching/pickerView.tsx +91 -0
- package/src/modules/timeSchedule/TimeScheduleActions.ts +2 -2
- package/src/navigation/Routers.ts +4 -0
package/package.json
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {SwitchButton, Utils} from "tuya-panel-kit";
|
|
3
|
+
import Page from "@ledvance/base/src/components/Page";
|
|
4
|
+
import I18n from "@ledvance/base/src/i18n/index";
|
|
5
|
+
import {useDeviceInfo, useFeatureHook} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
6
|
+
import {useReactive} from "ahooks";
|
|
7
|
+
import Spacer from "@ledvance/base/src/components/Spacer";
|
|
8
|
+
import {View, Text, StyleSheet, Image} from "react-native";
|
|
9
|
+
import {Result} from "@ledvance/base/src/models/modules/Result";
|
|
10
|
+
import res from "@ledvance/base/src/res";
|
|
11
|
+
|
|
12
|
+
const { convertX: cx } = Utils.RatioUtils
|
|
13
|
+
const { withTheme } = Utils.ThemeUtils
|
|
14
|
+
|
|
15
|
+
interface ChildLockConfig {
|
|
16
|
+
childLock: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function useChildLock(): [boolean, (v: boolean) => Promise<Result<any>>] {
|
|
20
|
+
return useFeatureHook<ChildLockConfig, boolean>('childLock', false)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const ChildLockPage = (props: { theme?: any }) => {
|
|
24
|
+
const devInfo = useDeviceInfo()
|
|
25
|
+
const [childLock, setChildLock] = useChildLock()
|
|
26
|
+
const state = useReactive({
|
|
27
|
+
loading: false
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const styles = StyleSheet.create({
|
|
31
|
+
tipInfoContainer: {
|
|
32
|
+
flexDirection: 'row',
|
|
33
|
+
marginHorizontal: cx(24),
|
|
34
|
+
marginVertical: cx(10)
|
|
35
|
+
},
|
|
36
|
+
image: {
|
|
37
|
+
width: cx(16),
|
|
38
|
+
height: cx(16),
|
|
39
|
+
marginRight: cx(5),
|
|
40
|
+
tintColor: props.theme.global.fontColor
|
|
41
|
+
},
|
|
42
|
+
titleBGView: {
|
|
43
|
+
flexDirection: 'row',
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
paddingHorizontal: cx(16),
|
|
46
|
+
marginHorizontal: cx(24),
|
|
47
|
+
},
|
|
48
|
+
colorBlock: {
|
|
49
|
+
width: cx(20),
|
|
50
|
+
height: cx(20),
|
|
51
|
+
marginStart: cx(12),
|
|
52
|
+
borderRadius: cx(4),
|
|
53
|
+
},
|
|
54
|
+
title: {
|
|
55
|
+
color: props.theme.global.fontColor,
|
|
56
|
+
fontSize: cx(14),
|
|
57
|
+
fontFamily: 'helvetica_neue_lt_std_bd',
|
|
58
|
+
paddingVertical: cx(16),
|
|
59
|
+
},
|
|
60
|
+
shadow: {
|
|
61
|
+
shadowColor: props.theme.global.fontColor,
|
|
62
|
+
shadowOpacity: 0.2,
|
|
63
|
+
shadowRadius: 8,
|
|
64
|
+
elevation:8,
|
|
65
|
+
shadowOffset: {
|
|
66
|
+
width: 0,
|
|
67
|
+
height: 4,
|
|
68
|
+
},
|
|
69
|
+
backgroundColor: props.theme.global.background,
|
|
70
|
+
borderRadius: 8,
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
return (<Page
|
|
75
|
+
backText={devInfo.name}
|
|
76
|
+
headlineText={I18n.getLang('sockets_specific_settings_child_lock')}
|
|
77
|
+
loading={state.loading}>
|
|
78
|
+
<View style={styles.tipInfoContainer}>
|
|
79
|
+
<Image style={styles.image} source={res.ic_info} />
|
|
80
|
+
<Text style={{ color: props.theme.global.fontColor }}>
|
|
81
|
+
{I18n.getLang('childlock_overview_description_text')}
|
|
82
|
+
</Text>
|
|
83
|
+
</View>
|
|
84
|
+
<View style={[styles.titleBGView, styles.shadow]}>
|
|
85
|
+
<Text style={styles.title}>{I18n.getLang('sockets_specific_settings_child_lock')}</Text>
|
|
86
|
+
<View style={[styles.colorBlock, { backgroundColor: 'red', opacity: 0 }]} />
|
|
87
|
+
<Spacer style={{ flex: 1 }} height={0} width={0} />
|
|
88
|
+
<SwitchButton value={childLock} onValueChange={async v => {
|
|
89
|
+
state.loading = true
|
|
90
|
+
await setChildLock(v)
|
|
91
|
+
state.loading = false
|
|
92
|
+
} } />
|
|
93
|
+
</View>
|
|
94
|
+
</Page>)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export default withTheme(ChildLockPage)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {NavigationRoute} from "tuya-panel-kit";
|
|
2
|
+
import {ui_biz_routerKey} from "../../navigation/Routers";
|
|
3
|
+
import ChildLockPage from "./ChildLockPage";
|
|
4
|
+
|
|
5
|
+
const ChildLockRouters: NavigationRoute[] = [
|
|
6
|
+
{
|
|
7
|
+
name: ui_biz_routerKey.group_ui_biz_child_lock,
|
|
8
|
+
component: ChildLockPage,
|
|
9
|
+
options:{
|
|
10
|
+
hideTopbar: true,
|
|
11
|
+
showOfflineView: false,
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
export default ChildLockRouters
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import React, {PropsWithChildren} from 'react'
|
|
2
|
+
import {Image, ScrollView, StyleSheet, Text, TouchableOpacity, View, ViewProps} from 'react-native'
|
|
3
|
+
import Page from '@ledvance/base/src/components/Page'
|
|
4
|
+
import {useDeviceInfo, useFeatureHook} from '@ledvance/base/src/models/modules/NativePropsSlice'
|
|
5
|
+
import I18n from '@ledvance/base/src/i18n'
|
|
6
|
+
import {Utils} from 'tuya-panel-kit'
|
|
7
|
+
import Spacer from '@ledvance/base/src/components/Spacer'
|
|
8
|
+
import Card from '@ledvance/base/src/components/Card'
|
|
9
|
+
import res from '@ledvance/base/src/res'
|
|
10
|
+
import {useReactive, useUpdateEffect} from 'ahooks'
|
|
11
|
+
import {Result} from "@ledvance/base/src/models/modules/Result";
|
|
12
|
+
|
|
13
|
+
const { convertX: cx } = Utils.RatioUtils
|
|
14
|
+
const { withTheme } = Utils.ThemeUtils
|
|
15
|
+
|
|
16
|
+
const LIGHT_MODE_RELAY = 'relay'
|
|
17
|
+
const LIGHT_MODE_POS = 'pos'
|
|
18
|
+
const LIGHT_MODE_OFF = 'off'
|
|
19
|
+
const LIGHT_MODE_ON = 'on'
|
|
20
|
+
|
|
21
|
+
export type LightMode = 'relay' | 'pos' | 'off' | 'on'
|
|
22
|
+
|
|
23
|
+
interface LightModeConfig {
|
|
24
|
+
lightMode: LightMode
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function useLightMode(): [LightMode, (v: LightMode) => Promise<Result<any>>] {
|
|
28
|
+
return useFeatureHook<LightModeConfig, LightMode>('lightMode', 'relay')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const LightModePage = (props: { theme?: any }) => {
|
|
32
|
+
const deviceInfo = useDeviceInfo()
|
|
33
|
+
const [lightMode, setLightMode] = useLightMode()
|
|
34
|
+
|
|
35
|
+
const state = useReactive({
|
|
36
|
+
lightMode: lightMode,
|
|
37
|
+
loading: false,
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
useUpdateEffect(() => {
|
|
41
|
+
state.lightMode = lightMode
|
|
42
|
+
}, [lightMode])
|
|
43
|
+
|
|
44
|
+
const styles = StyleSheet.create({
|
|
45
|
+
root: {
|
|
46
|
+
flex: 1,
|
|
47
|
+
},
|
|
48
|
+
desc: {
|
|
49
|
+
marginHorizontal: cx(24),
|
|
50
|
+
color: props.theme.global.fontColor,
|
|
51
|
+
fontSize: cx(14),
|
|
52
|
+
fontWeight: 'bold',
|
|
53
|
+
fontFamily: 'helvetica_neue_lt_std_bd',
|
|
54
|
+
},
|
|
55
|
+
tipText: {
|
|
56
|
+
marginHorizontal: cx(24),
|
|
57
|
+
color: props.theme.global.fontColor,
|
|
58
|
+
fontSize: cx(14),
|
|
59
|
+
fontFamily: 'helvetica_neue_lt_std_roman',
|
|
60
|
+
},
|
|
61
|
+
modeSelectGroup: {
|
|
62
|
+
marginHorizontal: cx(24),
|
|
63
|
+
backgroundColor: props.theme.card.board,
|
|
64
|
+
borderRadius: cx(4),
|
|
65
|
+
},
|
|
66
|
+
modeTip: {
|
|
67
|
+
marginHorizontal: cx(8),
|
|
68
|
+
color: props.theme.global.fontColor,
|
|
69
|
+
fontSize: cx(14),
|
|
70
|
+
fontWeight: 'bold',
|
|
71
|
+
fontFamily: 'helvetica_neue_lt_std_bd',
|
|
72
|
+
},
|
|
73
|
+
modeSelectCard: {
|
|
74
|
+
marginHorizontal: cx(8),
|
|
75
|
+
},
|
|
76
|
+
line: {
|
|
77
|
+
height: cx(1),
|
|
78
|
+
marginHorizontal: cx(12),
|
|
79
|
+
backgroundColor: '#3C3C435B',
|
|
80
|
+
},
|
|
81
|
+
itemRoot: {
|
|
82
|
+
flexDirection: 'row',
|
|
83
|
+
alignItems: 'center',
|
|
84
|
+
paddingHorizontal: cx(12),
|
|
85
|
+
paddingBottom: cx(8),
|
|
86
|
+
},
|
|
87
|
+
itemTextGroup: {
|
|
88
|
+
flex: 1,
|
|
89
|
+
marginEnd: cx(12),
|
|
90
|
+
justifyContent: 'center',
|
|
91
|
+
},
|
|
92
|
+
itemTitle: {
|
|
93
|
+
color: props.theme.global.fontColor,
|
|
94
|
+
fontSize: cx(14),
|
|
95
|
+
fontFamily: 'helvetica_neue_lt_std_roman',
|
|
96
|
+
},
|
|
97
|
+
itemContent: {
|
|
98
|
+
color: props.theme.global.secondFontColor,
|
|
99
|
+
fontSize: cx(14),
|
|
100
|
+
fontFamily: 'helvetica_neue_lt_std_roman',
|
|
101
|
+
},
|
|
102
|
+
itemCheckedIcon: {
|
|
103
|
+
width: cx(32),
|
|
104
|
+
height: cx(32),
|
|
105
|
+
marginEnd: cx(4),
|
|
106
|
+
},
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<Page
|
|
112
|
+
backText={deviceInfo.name}
|
|
113
|
+
headlineText={I18n.getLang('matterplug_LED')}
|
|
114
|
+
loading={state.loading}>
|
|
115
|
+
<ScrollView style={styles.root} nestedScrollEnabled={true}>
|
|
116
|
+
<Text style={styles.desc}>
|
|
117
|
+
{I18n.getLang('matterplug_description')}
|
|
118
|
+
</Text>
|
|
119
|
+
<Spacer />
|
|
120
|
+
<View style={styles.modeSelectGroup}>
|
|
121
|
+
<Spacer height={cx(8)} />
|
|
122
|
+
<Text style={styles.modeTip}>
|
|
123
|
+
{I18n.getLang('matterplug_heading')}
|
|
124
|
+
</Text>
|
|
125
|
+
<Spacer height={cx(8)} />
|
|
126
|
+
<Card style={styles.modeSelectCard}>
|
|
127
|
+
<Spacer height={cx(12)} />
|
|
128
|
+
<LightModeItem
|
|
129
|
+
styles={styles}
|
|
130
|
+
enable={state.lightMode === LIGHT_MODE_RELAY}
|
|
131
|
+
title={I18n.getLang('matterplug_option1title')}
|
|
132
|
+
content={I18n.getLang('matterplug_option1description')}
|
|
133
|
+
onPress={async () => {
|
|
134
|
+
state.lightMode = LIGHT_MODE_RELAY
|
|
135
|
+
await setLightMode(state.lightMode)
|
|
136
|
+
}} />
|
|
137
|
+
<View style={styles.line} />
|
|
138
|
+
<Spacer height={cx(8)} />
|
|
139
|
+
<LightModeItem
|
|
140
|
+
styles={styles}
|
|
141
|
+
enable={state.lightMode === LIGHT_MODE_POS}
|
|
142
|
+
title={I18n.getLang('matterplug_option2title')}
|
|
143
|
+
content={I18n.getLang('matterplug_option2description')}
|
|
144
|
+
onPress={async () => {
|
|
145
|
+
state.lightMode = LIGHT_MODE_POS
|
|
146
|
+
await setLightMode(state.lightMode)
|
|
147
|
+
}} />
|
|
148
|
+
<View style={styles.line} />
|
|
149
|
+
<Spacer height={cx(8)} />
|
|
150
|
+
<LightModeItem
|
|
151
|
+
styles={styles}
|
|
152
|
+
enable={state.lightMode === LIGHT_MODE_OFF}
|
|
153
|
+
title={I18n.getLang('matterplug_option3title')}
|
|
154
|
+
content={I18n.getLang('matterplug_option3description')}
|
|
155
|
+
onPress={async () => {
|
|
156
|
+
state.lightMode = LIGHT_MODE_OFF
|
|
157
|
+
await setLightMode(state.lightMode)
|
|
158
|
+
}} />
|
|
159
|
+
<Spacer height={cx(8)} />
|
|
160
|
+
<View style={styles.line} />
|
|
161
|
+
<LightModeItem
|
|
162
|
+
styles={styles}
|
|
163
|
+
enable={state.lightMode === LIGHT_MODE_ON}
|
|
164
|
+
title={I18n.getLang('matterplug_option4title')}
|
|
165
|
+
content={I18n.getLang('matterplug_option4description')}
|
|
166
|
+
onPress={async () => {
|
|
167
|
+
state.lightMode = LIGHT_MODE_ON
|
|
168
|
+
await setLightMode(state.lightMode)
|
|
169
|
+
}} />
|
|
170
|
+
<Spacer height={cx(4)} />
|
|
171
|
+
</Card>
|
|
172
|
+
<Spacer height={cx(8)} />
|
|
173
|
+
</View>
|
|
174
|
+
</ScrollView>
|
|
175
|
+
</Page>
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
interface LightModeItemProps extends PropsWithChildren<ViewProps> {
|
|
180
|
+
onPress: () => void
|
|
181
|
+
title: string
|
|
182
|
+
content: string
|
|
183
|
+
enable: boolean
|
|
184
|
+
styles: any
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function LightModeItem(props: LightModeItemProps) {
|
|
188
|
+
const { styles } = props
|
|
189
|
+
return (
|
|
190
|
+
<TouchableOpacity onPress={props.onPress}>
|
|
191
|
+
<View style={styles.itemRoot}>
|
|
192
|
+
<View style={styles.itemTextGroup}>
|
|
193
|
+
<Text style={styles.itemTitle}>{props.title}</Text>
|
|
194
|
+
<Spacer height={cx(4)} />
|
|
195
|
+
<Text style={styles.itemContent}>{props.content}</Text>
|
|
196
|
+
</View>
|
|
197
|
+
<Image
|
|
198
|
+
source={{ uri: res.ic_check }}
|
|
199
|
+
style={[
|
|
200
|
+
styles.itemCheckedIcon,
|
|
201
|
+
{
|
|
202
|
+
display: props.enable ? 'flex' : 'none',
|
|
203
|
+
},
|
|
204
|
+
]} />
|
|
205
|
+
</View>
|
|
206
|
+
</TouchableOpacity>
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export default withTheme(LightModePage)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {NavigationRoute} from "tuya-panel-kit";
|
|
2
|
+
import LightModePage from "./LightModePage";
|
|
3
|
+
import {ui_biz_routerKey} from "../../navigation/Routers";
|
|
4
|
+
|
|
5
|
+
const LightModeRouters: NavigationRoute[] = [
|
|
6
|
+
{
|
|
7
|
+
name: ui_biz_routerKey.group_ui_biz_light_mode,
|
|
8
|
+
component: LightModePage,
|
|
9
|
+
options:{
|
|
10
|
+
hideTopbar: true,
|
|
11
|
+
showOfflineView: false,
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
export default LightModeRouters
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {SwitchButton, Utils} from "tuya-panel-kit";
|
|
3
|
+
import Page from "@ledvance/base/src/components/Page";
|
|
4
|
+
import I18n from "@ledvance/base/src/i18n/index";
|
|
5
|
+
import {useDeviceInfo, useFeatureHook} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
6
|
+
import {useReactive} from "ahooks";
|
|
7
|
+
import Spacer from "@ledvance/base/src/components/Spacer";
|
|
8
|
+
import {StyleSheet, Text, View} from "react-native";
|
|
9
|
+
import {Result} from "@ledvance/base/src/models/modules/Result";
|
|
10
|
+
|
|
11
|
+
const { convertX: cx } = Utils.RatioUtils
|
|
12
|
+
const { withTheme } = Utils.ThemeUtils
|
|
13
|
+
|
|
14
|
+
interface OverchargeSwitchConfig {
|
|
15
|
+
overchargeSwitch: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function useOverchargeSwitch(): [boolean, (v: boolean) => Promise<Result<any>>] {
|
|
19
|
+
return useFeatureHook<OverchargeSwitchConfig, boolean>('overchargeSwitch', false)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const OverchargeSwitchPage = (props: { theme?: any }) => {
|
|
23
|
+
const devInfo = useDeviceInfo()
|
|
24
|
+
const [overchargeSwitch, setOverchargeSwitch] = useOverchargeSwitch()
|
|
25
|
+
const state = useReactive({
|
|
26
|
+
loading: false
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const styles = StyleSheet.create({
|
|
30
|
+
tipInfoContainer: {
|
|
31
|
+
flexDirection: 'row',
|
|
32
|
+
marginHorizontal: cx(24),
|
|
33
|
+
marginVertical: cx(10)
|
|
34
|
+
},
|
|
35
|
+
image: {
|
|
36
|
+
width: cx(16),
|
|
37
|
+
height: cx(16),
|
|
38
|
+
marginRight: cx(5),
|
|
39
|
+
tintColor: props.theme.global.fontColor
|
|
40
|
+
},
|
|
41
|
+
titleBGView: {
|
|
42
|
+
flexDirection: 'row',
|
|
43
|
+
alignItems: 'center',
|
|
44
|
+
paddingHorizontal: cx(16),
|
|
45
|
+
marginHorizontal: cx(24),
|
|
46
|
+
marginTop: cx(30)
|
|
47
|
+
},
|
|
48
|
+
colorBlock: {
|
|
49
|
+
width: cx(20),
|
|
50
|
+
height: cx(20),
|
|
51
|
+
marginStart: cx(12),
|
|
52
|
+
borderRadius: cx(4),
|
|
53
|
+
},
|
|
54
|
+
title: {
|
|
55
|
+
color: props.theme.global.fontColor,
|
|
56
|
+
fontSize: cx(14),
|
|
57
|
+
fontFamily: 'helvetica_neue_lt_std_bd',
|
|
58
|
+
paddingVertical: cx(16),
|
|
59
|
+
},
|
|
60
|
+
shadow: {
|
|
61
|
+
shadowColor: props.theme.card.shadowColor,
|
|
62
|
+
shadowOpacity: 0.2,
|
|
63
|
+
shadowRadius: 8,
|
|
64
|
+
elevation:8,
|
|
65
|
+
shadowOffset: {
|
|
66
|
+
width: 0,
|
|
67
|
+
height: 4,
|
|
68
|
+
},
|
|
69
|
+
backgroundColor: props.theme.global.background,
|
|
70
|
+
borderRadius: 8,
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
return (<Page
|
|
75
|
+
backText={devInfo.name}
|
|
76
|
+
loading={state.loading}>
|
|
77
|
+
<View style={[styles.titleBGView, styles.shadow]}>
|
|
78
|
+
<View style={{ flex: 7 }}>
|
|
79
|
+
<View>
|
|
80
|
+
<Text style={styles.title}>{I18n.getLang('switch_overcharge_headline_text')}</Text>
|
|
81
|
+
</View>
|
|
82
|
+
<View style={{ paddingBottom: cx(16) }}>
|
|
83
|
+
<Text>{I18n.getLang('switch_overcharge_headline_description')}</Text>
|
|
84
|
+
</View>
|
|
85
|
+
</View>
|
|
86
|
+
<Spacer style={{ flex: 1 }} height={0} width={0} />
|
|
87
|
+
<SwitchButton value={overchargeSwitch} onValueChange={async v => {
|
|
88
|
+
state.loading = true
|
|
89
|
+
await setOverchargeSwitch(v)
|
|
90
|
+
state.loading = false
|
|
91
|
+
} } />
|
|
92
|
+
</View>
|
|
93
|
+
</Page>)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export default withTheme(OverchargeSwitchPage)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {NavigationRoute} from "tuya-panel-kit";
|
|
2
|
+
import OverchargeSwitchPage from "./OverchargeSwitchPage";
|
|
3
|
+
import {ui_biz_routerKey} from "../../navigation/Routers";
|
|
4
|
+
|
|
5
|
+
const OverchargeSwitchRouters: NavigationRoute[] = [
|
|
6
|
+
{
|
|
7
|
+
name: ui_biz_routerKey.group_ui_biz_overcharge_switch,
|
|
8
|
+
component: OverchargeSwitchPage,
|
|
9
|
+
options:{
|
|
10
|
+
hideTopbar: true,
|
|
11
|
+
showOfflineView: false,
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
export default OverchargeSwitchRouters
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {NavigationRoute} from "tuya-panel-kit";
|
|
2
|
+
import SwitchInching from "./SwithInching";
|
|
3
|
+
import {ui_biz_routerKey} from "../../navigation/Routers";
|
|
4
|
+
|
|
5
|
+
const SwitchInchingRouters: NavigationRoute[] = [
|
|
6
|
+
{
|
|
7
|
+
name: ui_biz_routerKey.group_ui_biz_switch_inching,
|
|
8
|
+
component: SwitchInching,
|
|
9
|
+
options:{
|
|
10
|
+
hideTopbar: true,
|
|
11
|
+
showOfflineView: false,
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
export default SwitchInchingRouters
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import React, {useEffect} from "react";
|
|
2
|
+
import {StyleSheet, Text, View} from "react-native";
|
|
3
|
+
import Page from "@ledvance/base/src/components/Page";
|
|
4
|
+
import {useDeviceInfo} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
5
|
+
import {useNavigation} from '@react-navigation/native'
|
|
6
|
+
import {SwitchButton, Utils} from "tuya-panel-kit";
|
|
7
|
+
import LdvPickerView from "./pickerView";
|
|
8
|
+
import I18n from '@ledvance/base/src/i18n'
|
|
9
|
+
import {useReactive, useUpdateEffect} from "ahooks";
|
|
10
|
+
import {useSwitchInching} from "./SwithInchingAction";
|
|
11
|
+
|
|
12
|
+
const {convertX: cx} = Utils.RatioUtils
|
|
13
|
+
const { withTheme } = Utils.ThemeUtils
|
|
14
|
+
|
|
15
|
+
interface SwitchInchingState {
|
|
16
|
+
enable: boolean,
|
|
17
|
+
minute: string,
|
|
18
|
+
second: string,
|
|
19
|
+
flag: Symbol | number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const SwitchInching = (props: { theme?: any }) => {
|
|
23
|
+
const deviceInfo = useDeviceInfo()
|
|
24
|
+
const navigation = useNavigation()
|
|
25
|
+
const [switchInching, setSwitchInching] = useSwitchInching()
|
|
26
|
+
|
|
27
|
+
const state = useReactive<SwitchInchingState>({
|
|
28
|
+
enable: false,
|
|
29
|
+
minute: '00',
|
|
30
|
+
second: '00',
|
|
31
|
+
flag: 1
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
state.enable = switchInching.enable
|
|
36
|
+
state.minute = formatValue('minute')
|
|
37
|
+
state.second = formatValue('second')
|
|
38
|
+
}, [JSON.stringify(switchInching)])
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
const requestSwitchInching = () => {
|
|
42
|
+
const enable = state.enable
|
|
43
|
+
const time = Number(state.minute) * 60 + Number(state.second)
|
|
44
|
+
setSwitchInching({enable, time}).then(_r => {})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (state.flag !== 1) {
|
|
49
|
+
requestSwitchInching()
|
|
50
|
+
}
|
|
51
|
+
}, [state.flag])
|
|
52
|
+
|
|
53
|
+
useUpdateEffect(() => {
|
|
54
|
+
if (!Number(state.minute) && Number(state.second) < 2) {
|
|
55
|
+
state.second = '02'
|
|
56
|
+
}
|
|
57
|
+
if (Number(state.minute) === 60) {
|
|
58
|
+
state.second = '00'
|
|
59
|
+
}
|
|
60
|
+
}, [state.minute, state.second])
|
|
61
|
+
|
|
62
|
+
const formatValue = (type: string) => {
|
|
63
|
+
const m = parseInt(String((switchInching?.time || 0) / 60))
|
|
64
|
+
if (type === 'minute') {
|
|
65
|
+
return m.toString().padStart(2, '0')
|
|
66
|
+
} else {
|
|
67
|
+
const s = switchInching.time - 60 * m
|
|
68
|
+
return s === 0 ? '00' : s < 10 ? '0' + s : String(s)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const styles = StyleSheet.create({
|
|
73
|
+
switchContainer: {
|
|
74
|
+
backgroundColor: props.theme.card.board,
|
|
75
|
+
marginHorizontal: cx(24),
|
|
76
|
+
padding: cx(10),
|
|
77
|
+
borderRadius: cx(6),
|
|
78
|
+
flexDirection: 'column',
|
|
79
|
+
},
|
|
80
|
+
switchCardContainer: {
|
|
81
|
+
paddingVertical: cx(4),
|
|
82
|
+
paddingHorizontal: cx(10),
|
|
83
|
+
backgroundColor: props.theme.global.background,
|
|
84
|
+
flexDirection: 'row',
|
|
85
|
+
justifyContent: 'center',
|
|
86
|
+
alignItems: 'center',
|
|
87
|
+
borderRadius: cx(6),
|
|
88
|
+
},
|
|
89
|
+
switchCardTitle: {
|
|
90
|
+
color: props.theme.global.fontColor,
|
|
91
|
+
fontSize: cx(14),
|
|
92
|
+
flex: 1,
|
|
93
|
+
fontWeight: '400',
|
|
94
|
+
},
|
|
95
|
+
switchDescription: {
|
|
96
|
+
color: props.theme.global.fontColor,
|
|
97
|
+
flexWrap: 'wrap',
|
|
98
|
+
fontSize: cx(12),
|
|
99
|
+
marginTop: cx(4),
|
|
100
|
+
},
|
|
101
|
+
secondTopic: {
|
|
102
|
+
color: props.theme.global.fontColor,
|
|
103
|
+
flexWrap: 'wrap',
|
|
104
|
+
fontSize: cx(14),
|
|
105
|
+
marginTop: cx(30),
|
|
106
|
+
marginHorizontal: cx(24),
|
|
107
|
+
},
|
|
108
|
+
pickContainer: {
|
|
109
|
+
position: 'relative',
|
|
110
|
+
marginVertical: cx(24),
|
|
111
|
+
marginHorizontal: cx(24),
|
|
112
|
+
},
|
|
113
|
+
disabledCover: {
|
|
114
|
+
position: 'absolute',
|
|
115
|
+
width: '100%',
|
|
116
|
+
height: '100%',
|
|
117
|
+
left: 0,
|
|
118
|
+
top: 0,
|
|
119
|
+
zIndex: 999,
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<Page
|
|
125
|
+
backText={deviceInfo.name}
|
|
126
|
+
onBackClick={navigation.goBack}
|
|
127
|
+
headlineText={I18n.getLang('socket_settings_switch_off_firstbox_text')}
|
|
128
|
+
>
|
|
129
|
+
<View style={styles.switchContainer}>
|
|
130
|
+
<View style={styles.switchCardContainer}>
|
|
131
|
+
<Text style={styles.switchCardTitle}>
|
|
132
|
+
{I18n.getLang('socket_settings_switch_off_firstbox_text')}
|
|
133
|
+
</Text>
|
|
134
|
+
<SwitchButton
|
|
135
|
+
value={switchInching.enable}
|
|
136
|
+
onValueChange={v => {
|
|
137
|
+
state.enable = v
|
|
138
|
+
state.flag = Symbol()
|
|
139
|
+
}}
|
|
140
|
+
/>
|
|
141
|
+
</View>
|
|
142
|
+
<Text style={styles.switchDescription}>
|
|
143
|
+
{I18n.getLang('switchinching_overview_description_text')}
|
|
144
|
+
</Text>
|
|
145
|
+
</View>
|
|
146
|
+
<Text style={styles.secondTopic}>
|
|
147
|
+
{I18n.getLang('socket_settings_switch_off_secondtopic')}
|
|
148
|
+
</Text>
|
|
149
|
+
<View style={styles.pickContainer}>
|
|
150
|
+
{switchInching.enable && <View style={styles.disabledCover}/>}
|
|
151
|
+
<LdvPickerView
|
|
152
|
+
hour={state.minute}
|
|
153
|
+
minute={state.second}
|
|
154
|
+
unit={[
|
|
155
|
+
I18n.getLang('socket_settings_switch_off_min'),
|
|
156
|
+
I18n.getLang('socket_settings_switch_off_s'),
|
|
157
|
+
]}
|
|
158
|
+
setHour={m => {
|
|
159
|
+
state.minute = m
|
|
160
|
+
}}
|
|
161
|
+
setMinute={s => {
|
|
162
|
+
state.second = s
|
|
163
|
+
}}
|
|
164
|
+
/>
|
|
165
|
+
</View>
|
|
166
|
+
</Page>
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export default withTheme(SwitchInching)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {Buffer} from 'buffer'
|
|
2
|
+
import {Result} from "@ledvance/base/src/models/modules/Result"
|
|
3
|
+
import {useFeatureHook} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
4
|
+
|
|
5
|
+
interface SwitchInchingConfig {
|
|
6
|
+
switchInching: SwitchInchingModel
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface SwitchInchingModel {
|
|
10
|
+
enable: boolean
|
|
11
|
+
channel?: number
|
|
12
|
+
time: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const useSwitchInching = (): [SwitchInchingModel, (v: SwitchInchingModel) => Promise<Result<any>>] => {
|
|
16
|
+
return useFeatureHook<SwitchInchingConfig, SwitchInchingModel>('switchInching', {enable: false, channel: 0, time: 1}, mode => {
|
|
17
|
+
const buffer = new Uint8Array(3)
|
|
18
|
+
// 第1个字节:开/关+通道号
|
|
19
|
+
buffer[0] = packOnOffChannel(mode.enable, mode.channel)
|
|
20
|
+
// 第2、3个字节:点动时间
|
|
21
|
+
buffer[1] = (mode.time >> 8) & 0xff
|
|
22
|
+
buffer[2] = mode.time & 0xff
|
|
23
|
+
return Buffer.from(buffer).toString('base64')
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 工具函数:将开/关和通道号打包为一个字节
|
|
28
|
+
function packOnOffChannel(enable: boolean, channel: number = 0): number {
|
|
29
|
+
const enableBit = enable ? 1 : 0;
|
|
30
|
+
const channelBits = (channel << 1) & 0b11111110;
|
|
31
|
+
return enableBit | channelBits;
|
|
32
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleProp, StyleSheet, View, ViewStyle, Text } from 'react-native'
|
|
3
|
+
import { Picker, Utils } from 'tuya-panel-kit'
|
|
4
|
+
import _ from 'lodash'
|
|
5
|
+
|
|
6
|
+
const { convertX } = Utils.RatioUtils
|
|
7
|
+
|
|
8
|
+
const hours = _.times(61, (n) => _.padStart(n.toString(), 2, '0'))
|
|
9
|
+
const minutes = _.times(61, (n) => _.padStart(n.toString(), 2, '0'))
|
|
10
|
+
const pickerTheme = {
|
|
11
|
+
fontSize: 20,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface LdvPickerViewProps {
|
|
15
|
+
hour: string,
|
|
16
|
+
minute: string,
|
|
17
|
+
setHour: (string) => void,
|
|
18
|
+
setMinute: (string) => void,
|
|
19
|
+
style?: StyleProp<ViewStyle> | undefined,
|
|
20
|
+
unit?:string[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const LdvPickerView = (props: LdvPickerViewProps) => {
|
|
24
|
+
|
|
25
|
+
const { hour, minute, unit, setHour, setMinute } = props
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<View style={[styles.pickerContainer, props.style]}>
|
|
29
|
+
<View style={styles.picContainer}>
|
|
30
|
+
<Picker
|
|
31
|
+
style={[styles.picker, styles.pickerLeft]}
|
|
32
|
+
theme={pickerTheme}
|
|
33
|
+
itemStyle={styles.pickerItem}
|
|
34
|
+
textSize={convertX(14)}
|
|
35
|
+
selectedValue={hour}
|
|
36
|
+
itemAlign={'center'}
|
|
37
|
+
onValueChange={value => setHour(value as string)}>
|
|
38
|
+
{hours.map((value) => (
|
|
39
|
+
<Picker.Item key={value} value={value} label={value} />
|
|
40
|
+
))}
|
|
41
|
+
</Picker>
|
|
42
|
+
{unit ? <View style={styles.pickerUnit}>
|
|
43
|
+
<Text style={{ color: '#000', fontSize: convertX(18) }}>
|
|
44
|
+
{unit[0]}
|
|
45
|
+
</Text>
|
|
46
|
+
</View> : null}
|
|
47
|
+
</View>
|
|
48
|
+
<View style={styles.picContainer}>
|
|
49
|
+
<Picker
|
|
50
|
+
style={[styles.picker, styles.pickerLeft]}
|
|
51
|
+
theme={pickerTheme}
|
|
52
|
+
itemStyle={styles.pickerItem}
|
|
53
|
+
textSize={convertX(14)}
|
|
54
|
+
selectedValue={minute}
|
|
55
|
+
onValueChange={value => setMinute(value as string)}>
|
|
56
|
+
{minutes.map((value) => (
|
|
57
|
+
<Picker.Item key={value} value={value} label={value} />
|
|
58
|
+
))}
|
|
59
|
+
</Picker>
|
|
60
|
+
{unit ? <View style={styles.pickerUnit}>
|
|
61
|
+
<Text style={{ color: '#000', fontSize: convertX(18) }}>
|
|
62
|
+
{unit[1]}
|
|
63
|
+
</Text>
|
|
64
|
+
</View> : null}
|
|
65
|
+
</View>
|
|
66
|
+
</View>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const styles = StyleSheet.create({
|
|
71
|
+
pickerContainer: {
|
|
72
|
+
flexDirection: 'row',
|
|
73
|
+
alignItems: 'center',
|
|
74
|
+
},
|
|
75
|
+
picker: {
|
|
76
|
+
flex: 1,
|
|
77
|
+
},
|
|
78
|
+
pickerLeft: {},
|
|
79
|
+
pickerItem: {},
|
|
80
|
+
picContainer: {
|
|
81
|
+
flex: 1,
|
|
82
|
+
alignItems: 'center',
|
|
83
|
+
flexDirection: 'row',
|
|
84
|
+
},
|
|
85
|
+
pickerUnit: {
|
|
86
|
+
position: 'absolute',
|
|
87
|
+
right: convertX(20),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export default LdvPickerView
|
|
@@ -73,7 +73,7 @@ export const getTimeSchedule = async (props: IQueryTimerTasks) => {
|
|
|
73
73
|
return {
|
|
74
74
|
success: true,
|
|
75
75
|
data: flatMapDeep(res.timers).map(time => ({
|
|
76
|
-
...time,
|
|
76
|
+
...time,
|
|
77
77
|
dps: parseJSON(time.dps)
|
|
78
78
|
}))
|
|
79
79
|
}
|
|
@@ -109,7 +109,7 @@ export const modDelTimeSchedule = async (props: IModDeleteTaskByIds) => {
|
|
|
109
109
|
const status = await commonApi.timerApi.modDeleteTaskByIds({
|
|
110
110
|
...props,
|
|
111
111
|
bizType: '1',
|
|
112
|
-
status: 2
|
|
112
|
+
status: props.status ?? 2
|
|
113
113
|
})
|
|
114
114
|
return {
|
|
115
115
|
success: status
|
|
@@ -26,4 +26,8 @@ export const ui_biz_routerKey = {
|
|
|
26
26
|
'group_ui_biz_fixed_timing_light_detail': 'group_ui_biz_fixed_timing_light_detail',
|
|
27
27
|
'group_ui_biz_sleep_wakeUp': 'group_ui_biz_sleep_wakeUp',
|
|
28
28
|
'group_ui_biz_sleep_wakeUp_detail': 'group_ui_biz_sleep_wakeUp_detail',
|
|
29
|
+
'group_ui_biz_child_lock': 'group_ui_biz_child_lock',
|
|
30
|
+
'group_ui_biz_light_mode': 'group_ui_biz_light_mode',
|
|
31
|
+
'group_ui_biz_overcharge_switch': 'group_ui_biz_overcharge_switch',
|
|
32
|
+
'group_ui_biz_switch_inching': 'group_ui_biz_switch_inching',
|
|
29
33
|
}
|