@ledvance/base 1.3.26 → 1.3.28
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/localazy.json +35 -0
- package/package.json +1 -1
- package/src/api/nativeEventEmitter.ts +10 -0
- package/src/components/BallDirectionView.tsx +184 -0
- package/src/components/DiySceneItem.tsx +95 -0
- package/src/components/DiySceneNodeView.tsx +103 -0
- package/src/components/MoodStripAdjustView.tsx +128 -0
- package/src/components/TextField.tsx +3 -1
- package/src/hooks/Hooks.ts +8 -2
- package/src/i18n/strings.ts +7362 -6417
- package/src/models/TuyaApi.ts +61 -8
- package/src/models/modules/NativePropsSlice.tsx +35 -2
- package/src/res/index.ts +14 -2
- package/src/res/materialiconsOutlinedArrowsNavKeyboardArrowLeft.png +0 -0
- package/src/res/materialiconsOutlinedArrowsNavKeyboardArrowLeft@2x.png +0 -0
- package/src/res/materialiconsOutlinedArrowsNavKeyboardArrowLeft@3x.png +0 -0
- package/src/res/materialiconsOutlinedArrowsNavKeyboardArrowRight.png +0 -0
- package/src/res/materialiconsOutlinedArrowsNavKeyboardArrowRight@2x.png +0 -0
- package/src/res/materialiconsOutlinedArrowsNavKeyboardArrowRight@3x.png +0 -0
- package/src/res/src_res_all.png +0 -0
- package/src/res/src_res_colorring@2x.png +0 -0
- package/src/res/src_res_colorring@3x.png +0 -0
- package/src/res/src_res_cycle.png +0 -0
- package/src/res/src_res_half.png +0 -0
- package/src/res/src_res_halfborder.png +0 -0
- package/src/res/src_res_halfcircle@3x.png +0 -0
- package/src/res/src_res_like.png +0 -0
- package/src/res/src_res_minus.png +0 -0
- package/src/res/src_res_ringdown@2x.png +0 -0
- package/src/res/src_res_ringdown@3x.png +0 -0
- package/src/res/src_res_unlike.png +0 -0
- package/src/utils/common.ts +38 -0
- package/src/utils/interface.ts +37 -2
- package/translateKey.txt +36 -1
package/localazy.json
CHANGED
|
@@ -928,6 +928,41 @@
|
|
|
928
928
|
"MATCH:date_type",
|
|
929
929
|
"MATCH:cancel_dialog_leave_unsaved_vacation_note",
|
|
930
930
|
"MATCH:mood_string_mode_light_show",
|
|
931
|
+
"MATCH:mood_strip_mode_favorite",
|
|
932
|
+
"MATCH:mood_overview_field_chip_diy",
|
|
933
|
+
"MATCH:love_mood_alert_title",
|
|
934
|
+
"MATCH:love_mood_alert_content",
|
|
935
|
+
"MATCH:mood_strip_default_mood_focus",
|
|
936
|
+
"MATCH:mood_strip_default_mood_lavender",
|
|
937
|
+
"MATCH:mood_strip_default_mood_lavender_true_colors",
|
|
938
|
+
"MATCH:mood_strip_default_mood_night_light",
|
|
939
|
+
"MATCH:mood_strip_default_mood_cozy",
|
|
940
|
+
"MATCH:mood_strip_default_mood_atmosphere",
|
|
941
|
+
"MATCH:mood_strip_default_mood_relax",
|
|
942
|
+
"MATCH:mood_strip_default_mood_sky",
|
|
943
|
+
"MATCH:mood_strip_default_mood_ocean",
|
|
944
|
+
"MATCH:mood_strip_default_mood_warmth",
|
|
945
|
+
"MATCH:mood_strip_default_mood_romance",
|
|
946
|
+
"MATCH:mood_strip_default_mood_jungle",
|
|
947
|
+
"MATCH:mood_strip_default_mood_sunset",
|
|
948
|
+
"MATCH:mood_strip_default_mood_missing",
|
|
949
|
+
"MATCH:mood_strip_default_mood_party",
|
|
950
|
+
"MATCH:mood_strip_default_mood_rainbow",
|
|
951
|
+
"MATCH:mood_strip_default_mood_meditation",
|
|
952
|
+
"MATCH:mood_strip_default_mood_wake_time",
|
|
953
|
+
"MATCH:mood_strip_default_mood_spring",
|
|
954
|
+
"MATCH:mood_strip_default_mood_halloween",
|
|
955
|
+
"MATCH:mood_strip_default_mood_christmas",
|
|
956
|
+
"MATCH:mood_strip_default_mood_noble",
|
|
957
|
+
"MATCH:mood_strip_default_mood_energy",
|
|
958
|
+
"MATCH:mood_strip_default_mood_deep_dive",
|
|
959
|
+
"MATCH:mood_strip_default_mood_mojito",
|
|
960
|
+
"MATCH:mood_strip_default_mood_forest",
|
|
961
|
+
"MATCH:mood_strip_default_mood_cyberpunk",
|
|
962
|
+
"MATCH:mood_strip_default_mood_summer",
|
|
963
|
+
"MATCH:mood_strip_default_mood_fall",
|
|
964
|
+
"MATCH:mood_strip_default_mood_club",
|
|
965
|
+
"MATCH:mood_strip_default_mood_candlelight",
|
|
931
966
|
"MATCH:thermostat_scene",
|
|
932
967
|
"MATCH:thermostat_vacationplan",
|
|
933
968
|
"MATCH:thermostat_automatictab",
|
package/package.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {EmitterSubscription, NativeEventEmitter, NativeModules} from 'react-native'
|
|
2
2
|
import {
|
|
3
3
|
DeviceInfo,
|
|
4
|
+
GestureControlType,
|
|
4
5
|
NativeProps,
|
|
6
|
+
setGestrueControlValues,
|
|
5
7
|
setGroupDevices,
|
|
6
8
|
setGroupDps,
|
|
7
9
|
setGroupNativeProps,
|
|
@@ -21,6 +23,7 @@ let deviceDPListener: EmitterSubscription | null
|
|
|
21
23
|
let groupFeatureListener: EmitterSubscription | null
|
|
22
24
|
let groupDeviceListener: EmitterSubscription | null
|
|
23
25
|
let groupDpListener: EmitterSubscription | null
|
|
26
|
+
let gestrueControlListener: EmitterSubscription | null
|
|
24
27
|
|
|
25
28
|
interface GroupFeatureEvent {
|
|
26
29
|
tyGroupId: number
|
|
@@ -126,6 +129,10 @@ export const addListener = (store) => {
|
|
|
126
129
|
store.dispatch(setGroupDevices(groupDevices))
|
|
127
130
|
}
|
|
128
131
|
})
|
|
132
|
+
|
|
133
|
+
gestrueControlListener = nativeEventEmitter.addListener('LDV_GESTURE_CONTROL_COMMAND', (event: GestureControlType) => {
|
|
134
|
+
store.dispatch(setGestrueControlValues(event))
|
|
135
|
+
})
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
export const removeListener = () => {
|
|
@@ -140,4 +147,7 @@ export const removeListener = () => {
|
|
|
140
147
|
|
|
141
148
|
groupDpListener && groupDpListener.remove()
|
|
142
149
|
groupDpListener = null
|
|
150
|
+
|
|
151
|
+
gestrueControlListener && gestrueControlListener.remove()
|
|
152
|
+
gestrueControlListener = null
|
|
143
153
|
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import {Utils} from "tuya-panel-kit";
|
|
2
|
+
import React, {useEffect} from "react";
|
|
3
|
+
import {Image, StyleSheet, TouchableOpacity, View} from "react-native";
|
|
4
|
+
import res from "../res";
|
|
5
|
+
import {useReactive} from "ahooks";
|
|
6
|
+
import {hsv2Hex} from "../utils/index";
|
|
7
|
+
import {cctToColor} from "../utils/cctUtils";
|
|
8
|
+
import {AdjustType, HSV} from '../utils/interface'
|
|
9
|
+
|
|
10
|
+
const {withTheme} = Utils.ThemeUtils
|
|
11
|
+
const cx = Utils.RatioUtils.convertX;
|
|
12
|
+
|
|
13
|
+
export enum PaintMode {
|
|
14
|
+
Top,
|
|
15
|
+
Bottom,
|
|
16
|
+
ALL
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface BallDirectionProps {
|
|
20
|
+
theme?: any,
|
|
21
|
+
adjustType: AdjustType,
|
|
22
|
+
paintMode: PaintMode,
|
|
23
|
+
onPaintModeChanged: (paintMode: PaintMode) => void,
|
|
24
|
+
topColor: HSV,
|
|
25
|
+
bottomColor: HSV,
|
|
26
|
+
colorTemp: number,
|
|
27
|
+
brightness: number,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const BallDirectionView = (props: BallDirectionProps) => {
|
|
31
|
+
const {theme, adjustType, paintMode, onPaintModeChanged, topColor, bottomColor, colorTemp, brightness} = props;
|
|
32
|
+
const state = useReactive({
|
|
33
|
+
adjustType: adjustType,
|
|
34
|
+
paintMode: paintMode,
|
|
35
|
+
halfCircleTopColor: '#ff0000',
|
|
36
|
+
halfCircleBottomColor: '#00ff00',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
state.adjustType = adjustType;
|
|
41
|
+
state.paintMode = paintMode;
|
|
42
|
+
if (state.adjustType === AdjustType.COLOUR) {
|
|
43
|
+
state.halfCircleTopColor = hsv2Hex(topColor.h, Math.max(Math.round(topColor.s / 10), 10), 100);
|
|
44
|
+
state.halfCircleBottomColor = hsv2Hex(bottomColor.h, Math.max(Math.round(bottomColor.s / 10), 10), 100);
|
|
45
|
+
} else if (state.adjustType === AdjustType.WHITE) {
|
|
46
|
+
state.halfCircleTopColor = cctToColor(colorTemp, brightness);
|
|
47
|
+
state.halfCircleBottomColor = cctToColor(colorTemp, brightness);
|
|
48
|
+
} else {
|
|
49
|
+
state.halfCircleTopColor = '#ffffff';
|
|
50
|
+
state.halfCircleBottomColor = '#ffffff';
|
|
51
|
+
}
|
|
52
|
+
}, [adjustType, paintMode, JSON.stringify(topColor), JSON.stringify(bottomColor), colorTemp, brightness]);
|
|
53
|
+
|
|
54
|
+
const styles = StyleSheet.create({
|
|
55
|
+
root: {
|
|
56
|
+
flexDirection: 'row',
|
|
57
|
+
width: '100%',
|
|
58
|
+
alignItems: 'center',
|
|
59
|
+
justifyContent: 'center'
|
|
60
|
+
},
|
|
61
|
+
paintModeRoot: {
|
|
62
|
+
flexDirection: 'column',
|
|
63
|
+
position: 'absolute',
|
|
64
|
+
left: cx(24)
|
|
65
|
+
},
|
|
66
|
+
paintModeAll: {
|
|
67
|
+
resizeMode: 'contain',
|
|
68
|
+
width: '100%',
|
|
69
|
+
height: '100%',
|
|
70
|
+
tintColor: state.paintMode === PaintMode.ALL ? props.theme?.icon.primary : props.theme?.icon.normal
|
|
71
|
+
},
|
|
72
|
+
paintModeHalf: {
|
|
73
|
+
resizeMode: 'contain',
|
|
74
|
+
width: '100%',
|
|
75
|
+
height: '100%',
|
|
76
|
+
tintColor: state.paintMode !== PaintMode.ALL ? props.theme?.icon.primary : props.theme?.icon.normal
|
|
77
|
+
},
|
|
78
|
+
circleLayout: {
|
|
79
|
+
marginVertical: cx(10),
|
|
80
|
+
width: cx(180),
|
|
81
|
+
height: cx(180)
|
|
82
|
+
},
|
|
83
|
+
circleBorder: {
|
|
84
|
+
position: 'absolute',
|
|
85
|
+
width: '84%',
|
|
86
|
+
height: '84%',
|
|
87
|
+
borderColor: theme?.textInput.line,
|
|
88
|
+
borderRadius: 100,
|
|
89
|
+
borderWidth: 2,
|
|
90
|
+
bottom: '8%',
|
|
91
|
+
left: '8%',
|
|
92
|
+
right: '8%',
|
|
93
|
+
top: '8%',
|
|
94
|
+
},
|
|
95
|
+
coloring: {
|
|
96
|
+
width: '100%',
|
|
97
|
+
height: '100%',
|
|
98
|
+
resizeMode: 'contain',
|
|
99
|
+
},
|
|
100
|
+
ringUp: {
|
|
101
|
+
position: 'absolute',
|
|
102
|
+
width: '100%',
|
|
103
|
+
height: '56%',
|
|
104
|
+
resizeMode: 'contain',
|
|
105
|
+
transform: [{ rotate: '180deg' }]
|
|
106
|
+
},
|
|
107
|
+
ringDown: {
|
|
108
|
+
position: 'absolute',
|
|
109
|
+
width: '100%',
|
|
110
|
+
height: '56%',
|
|
111
|
+
resizeMode: 'contain',
|
|
112
|
+
bottom: 0
|
|
113
|
+
},
|
|
114
|
+
halfCircleDown: {
|
|
115
|
+
position: 'absolute',
|
|
116
|
+
width: '60%',
|
|
117
|
+
left: '20%',
|
|
118
|
+
right: '20%',
|
|
119
|
+
bottom: '11%',
|
|
120
|
+
},
|
|
121
|
+
halfCircleUp: {
|
|
122
|
+
position: 'absolute',
|
|
123
|
+
width: '60%',
|
|
124
|
+
left: '20%',
|
|
125
|
+
right: '20%',
|
|
126
|
+
top: '11%',
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return (<View style={styles.root}>
|
|
130
|
+
<View style={styles.paintModeRoot}>
|
|
131
|
+
{state.adjustType === AdjustType.COLOUR &&
|
|
132
|
+
<TouchableOpacity style={{width: cx(40), height: cx(40)}} onPress={() => {
|
|
133
|
+
onPaintModeChanged(PaintMode.Top);
|
|
134
|
+
}}>
|
|
135
|
+
<Image source={res.half} style={styles.paintModeHalf}/>
|
|
136
|
+
</TouchableOpacity>}
|
|
137
|
+
<TouchableOpacity
|
|
138
|
+
style={{width: cx(40), height: cx(40), marginTop: cx(10),}}
|
|
139
|
+
onPress={() => {
|
|
140
|
+
onPaintModeChanged(PaintMode.ALL);
|
|
141
|
+
}}>
|
|
142
|
+
<Image source={res.all} style={styles.paintModeAll}/>
|
|
143
|
+
</TouchableOpacity>
|
|
144
|
+
</View>
|
|
145
|
+
<View style={styles.circleLayout}>
|
|
146
|
+
<View style={styles.circleBorder}/>
|
|
147
|
+
{state.paintMode === PaintMode.ALL &&
|
|
148
|
+
<Image source={res.coloring} style={styles.coloring}/>}
|
|
149
|
+
{state.paintMode === PaintMode.Top &&
|
|
150
|
+
<Image source={res.ringdown} style={styles.ringUp}/>}
|
|
151
|
+
{state.paintMode === PaintMode.Bottom &&
|
|
152
|
+
<Image source={res.ringdown} style={styles.ringDown}/>}
|
|
153
|
+
<TouchableOpacity
|
|
154
|
+
style={styles.halfCircleUp}
|
|
155
|
+
disabled={state.paintMode === PaintMode.ALL}
|
|
156
|
+
onPress={() => {
|
|
157
|
+
onPaintModeChanged(PaintMode.Top);
|
|
158
|
+
}}>
|
|
159
|
+
<Image source={res.halfcircle} style={{
|
|
160
|
+
width: '100%',
|
|
161
|
+
resizeMode: 'contain',
|
|
162
|
+
tintColor: state.halfCircleTopColor
|
|
163
|
+
}}/>
|
|
164
|
+
|
|
165
|
+
</TouchableOpacity>
|
|
166
|
+
|
|
167
|
+
<TouchableOpacity
|
|
168
|
+
style={styles.halfCircleDown}
|
|
169
|
+
disabled={state.paintMode === PaintMode.ALL}
|
|
170
|
+
onPress={() => {
|
|
171
|
+
onPaintModeChanged(PaintMode.Bottom);
|
|
172
|
+
}}>
|
|
173
|
+
<Image source={res.halfcircle} style={{
|
|
174
|
+
width: '100%',
|
|
175
|
+
resizeMode: 'contain',
|
|
176
|
+
transform: [{rotate: '180deg'}],
|
|
177
|
+
tintColor: state.halfCircleBottomColor
|
|
178
|
+
}}/>
|
|
179
|
+
</TouchableOpacity>
|
|
180
|
+
</View>
|
|
181
|
+
</View>)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export default withTheme(BallDirectionView)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {StyleSheet, Text, View, ViewProps, ViewStyle} from 'react-native';
|
|
3
|
+
import {SwitchButton, Utils} from 'tuya-panel-kit';
|
|
4
|
+
import Card from './Card';
|
|
5
|
+
import Spacer from './Spacer';
|
|
6
|
+
import I18n from '../i18n';
|
|
7
|
+
import ThemeType from '../config/themeType'
|
|
8
|
+
|
|
9
|
+
const cx = Utils.RatioUtils.convertX;
|
|
10
|
+
const { withTheme } = Utils.ThemeUtils
|
|
11
|
+
|
|
12
|
+
const tagMap = {
|
|
13
|
+
'Static': I18n.getLang('mood_overview_field_chip_text'),
|
|
14
|
+
'Dynamic': I18n.getLang('mood_overview_field_chip_2'),
|
|
15
|
+
'DIY': I18n.getLang('mood_overview_field_chip_diy')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface DiySceneItemProps extends ViewProps {
|
|
19
|
+
theme?: ThemeType
|
|
20
|
+
enable: boolean
|
|
21
|
+
scene: {
|
|
22
|
+
name: string
|
|
23
|
+
type: 'Static' | 'Dynamic' | 'DIY'
|
|
24
|
+
[key: string]: any
|
|
25
|
+
}
|
|
26
|
+
style?: ViewStyle
|
|
27
|
+
onPress?: () => void
|
|
28
|
+
onSwitch: (enable: boolean) => void
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const DiySceneItem = (props: DiySceneItemProps) => {
|
|
32
|
+
const { scene } = props;
|
|
33
|
+
|
|
34
|
+
const styles = StyleSheet.create({
|
|
35
|
+
card: {
|
|
36
|
+
marginHorizontal: cx(24),
|
|
37
|
+
},
|
|
38
|
+
headline: {
|
|
39
|
+
flexDirection: 'row',
|
|
40
|
+
marginHorizontal: cx(16),
|
|
41
|
+
},
|
|
42
|
+
headText: {
|
|
43
|
+
flex: 1,
|
|
44
|
+
color: props.theme?.global.fontColor,
|
|
45
|
+
fontSize: cx(16),
|
|
46
|
+
fontFamily: 'helvetica_neue_lt_std_bd',
|
|
47
|
+
lineHeight: cx(20),
|
|
48
|
+
},
|
|
49
|
+
moodTypeItem: {
|
|
50
|
+
flexDirection: 'row',
|
|
51
|
+
},
|
|
52
|
+
moodTypeLabel: {
|
|
53
|
+
marginStart: cx(16),
|
|
54
|
+
paddingHorizontal: cx(12.5),
|
|
55
|
+
backgroundColor: props.theme?.tag.background,
|
|
56
|
+
borderRadius: cx(8),
|
|
57
|
+
},
|
|
58
|
+
moodTypeLabelText: {
|
|
59
|
+
height: cx(16),
|
|
60
|
+
color: props.theme?.tag.fontColor,
|
|
61
|
+
fontSize: cx(10),
|
|
62
|
+
textAlignVertical: 'center',
|
|
63
|
+
fontFamily: 'helvetica_neue_lt_std_roman',
|
|
64
|
+
lineHeight: cx(16),
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<Card style={[styles.card, props.style]} onPress={props.onPress}>
|
|
70
|
+
<View>
|
|
71
|
+
<Spacer height={cx(16)} />
|
|
72
|
+
<View style={styles.headline}>
|
|
73
|
+
<Text style={styles.headText}>{scene.name}</Text>
|
|
74
|
+
<SwitchButton
|
|
75
|
+
thumbStyle={{ elevation: 0 }}
|
|
76
|
+
value={props.enable}
|
|
77
|
+
onValueChange={props.onSwitch}
|
|
78
|
+
/>
|
|
79
|
+
</View>
|
|
80
|
+
<Spacer />
|
|
81
|
+
<Spacer height={cx(12)} />
|
|
82
|
+
<View style={styles.moodTypeItem}>
|
|
83
|
+
<View style={styles.moodTypeLabel}>
|
|
84
|
+
<Text style={styles.moodTypeLabelText}>
|
|
85
|
+
{tagMap[scene.type]}
|
|
86
|
+
</Text>
|
|
87
|
+
</View>
|
|
88
|
+
</View>
|
|
89
|
+
<Spacer height={cx(16)} />
|
|
90
|
+
</View>
|
|
91
|
+
</Card>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export default withTheme(DiySceneItem)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import {Utils} from "tuya-panel-kit";
|
|
2
|
+
import React, {useEffect} from "react";
|
|
3
|
+
import {Image, StyleSheet, TouchableOpacity, View} from "react-native";
|
|
4
|
+
import {useReactive} from "ahooks";
|
|
5
|
+
import {hsv2Hex} from "../utils/index";
|
|
6
|
+
import ThemeType from "../config/themeType";
|
|
7
|
+
import res from "../res";
|
|
8
|
+
import { HSV } from "../utils/interface";
|
|
9
|
+
|
|
10
|
+
const {withTheme} = Utils.ThemeUtils
|
|
11
|
+
const cx = Utils.RatioUtils.convertX;
|
|
12
|
+
|
|
13
|
+
interface DiySceneNodeProps {
|
|
14
|
+
theme?: ThemeType
|
|
15
|
+
isCurrent: boolean
|
|
16
|
+
position: 'Top' | 'Bottom'
|
|
17
|
+
topColor: HSV
|
|
18
|
+
bottomColor: HSV
|
|
19
|
+
onChangePosition: (position: 'Top' | 'Bottom') => void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DiySceneNodeView = (props: DiySceneNodeProps) => {
|
|
23
|
+
const {theme, topColor, bottomColor, isCurrent, position, onChangePosition} = props;
|
|
24
|
+
const state = useReactive({
|
|
25
|
+
halfCircleTopColor: hsv2Hex(topColor.h, Math.max(Math.round(topColor.s / 10), 10), 100),
|
|
26
|
+
halfCircleBottomColor: hsv2Hex(bottomColor.h, Math.max(Math.round(bottomColor.s / 10), 10), 100),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
state.halfCircleTopColor = hsv2Hex(topColor.h, Math.max(Math.round(topColor.s / 10), 10), 100);
|
|
31
|
+
state.halfCircleBottomColor = hsv2Hex(bottomColor.h, Math.max(Math.round(bottomColor.s / 10), 10), 100);
|
|
32
|
+
}, [JSON.stringify(topColor), JSON.stringify(bottomColor)]);
|
|
33
|
+
|
|
34
|
+
const styles = StyleSheet.create({
|
|
35
|
+
circleLayout: {
|
|
36
|
+
marginLeft: cx(10),
|
|
37
|
+
marginVertical: cx(10),
|
|
38
|
+
width: cx(60),
|
|
39
|
+
height: cx(60),
|
|
40
|
+
justifyContent:'space-between',
|
|
41
|
+
alignContent: 'center',
|
|
42
|
+
},
|
|
43
|
+
borderTop: {
|
|
44
|
+
position: 'absolute',
|
|
45
|
+
width: cx(60),
|
|
46
|
+
height: cx(28),
|
|
47
|
+
resizeMode: 'contain',
|
|
48
|
+
top: '-5%',
|
|
49
|
+
zIndex: 2,
|
|
50
|
+
tintColor: theme?.global.fontColor
|
|
51
|
+
},
|
|
52
|
+
borderBottom: {
|
|
53
|
+
position: 'absolute',
|
|
54
|
+
width: cx(60),
|
|
55
|
+
height: cx(28),
|
|
56
|
+
resizeMode: 'contain',
|
|
57
|
+
transform: [{rotate: '180deg'}],
|
|
58
|
+
bottom: '15%',
|
|
59
|
+
zIndex: 2,
|
|
60
|
+
tintColor: theme?.global.fontColor
|
|
61
|
+
},
|
|
62
|
+
halfCircleDown: {
|
|
63
|
+
width: '100%',
|
|
64
|
+
height: cx(30),
|
|
65
|
+
},
|
|
66
|
+
halfCircleUp: {
|
|
67
|
+
width: '100%',
|
|
68
|
+
height: cx(30)
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return (
|
|
72
|
+
<View style={styles.circleLayout}>
|
|
73
|
+
<TouchableOpacity
|
|
74
|
+
style={styles.halfCircleUp}
|
|
75
|
+
onPress={() => {
|
|
76
|
+
onChangePosition("Top")
|
|
77
|
+
}}>
|
|
78
|
+
<Image source={res.halfcircle} style={{
|
|
79
|
+
width: cx(60),
|
|
80
|
+
height: cx(25),
|
|
81
|
+
resizeMode: 'contain',
|
|
82
|
+
tintColor: state.halfCircleTopColor
|
|
83
|
+
}}/>
|
|
84
|
+
{ (isCurrent && position === 'Top') && <Image source={res.halfborder} style={styles.borderTop} />}
|
|
85
|
+
</TouchableOpacity>
|
|
86
|
+
<TouchableOpacity
|
|
87
|
+
style={styles.halfCircleDown}
|
|
88
|
+
onPress={() => {
|
|
89
|
+
onChangePosition("Bottom")
|
|
90
|
+
}}>
|
|
91
|
+
<Image source={res.halfcircle} style={{
|
|
92
|
+
width: cx(60),
|
|
93
|
+
height: cx(25),
|
|
94
|
+
resizeMode: 'contain',
|
|
95
|
+
transform: [{rotate: '180deg'}],
|
|
96
|
+
tintColor: state.halfCircleBottomColor
|
|
97
|
+
}}/>
|
|
98
|
+
{(isCurrent && position === 'Bottom') && <Image source={res.halfborder} style={styles.borderBottom} />}
|
|
99
|
+
</TouchableOpacity>
|
|
100
|
+
</View>)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default withTheme(DiySceneNodeView)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {Image, Text, TouchableOpacity, View} from "react-native";
|
|
3
|
+
import ColorAdjustView, {ColorAdjustViewProps} from "./ColorAdjustView";
|
|
4
|
+
import ColorTempAdjustView, {ColorTempAdjustViewProps} from "./ColorTempAdjustView";
|
|
5
|
+
import Spacer from "./Spacer";
|
|
6
|
+
import {TabBar, Utils} from "tuya-panel-kit";
|
|
7
|
+
import ThemeType from '../config/themeType'
|
|
8
|
+
import res from "../res";
|
|
9
|
+
import { AdjustType, DiySceneInfo } from "../utils/interface";
|
|
10
|
+
|
|
11
|
+
const {convertX: cx} = Utils.RatioUtils
|
|
12
|
+
const {withTheme} = Utils.ThemeUtils
|
|
13
|
+
|
|
14
|
+
type TabsNode = {
|
|
15
|
+
key: AdjustType
|
|
16
|
+
title: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface MoodStripAdjustViewProps extends ColorAdjustViewProps, ColorTempAdjustViewProps {
|
|
20
|
+
theme?: ThemeType
|
|
21
|
+
lampTabs: TabsNode[]
|
|
22
|
+
activeKey: AdjustType
|
|
23
|
+
onActiveKeyChange: (key: AdjustType) => void
|
|
24
|
+
favoriteScenes: DiySceneInfo[]
|
|
25
|
+
onFavoriteSceneChange: (sceneInfo: DiySceneInfo) => void
|
|
26
|
+
onFavoriteSceneRemove?: (sceneInfo: DiySceneInfo) => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const MoodStripAdjustView = (props: MoodStripAdjustViewProps) => {
|
|
30
|
+
return (
|
|
31
|
+
<View style={{width: '100%'}}>
|
|
32
|
+
<TabBar
|
|
33
|
+
type='radio'
|
|
34
|
+
tabs={props.lampTabs}
|
|
35
|
+
style={{
|
|
36
|
+
borderRadius: cx(8),
|
|
37
|
+
backgroundColor: props.theme?.segment.background,
|
|
38
|
+
height: cx(40),
|
|
39
|
+
marginHorizontal: cx(16)
|
|
40
|
+
}}
|
|
41
|
+
tabTextStyle={{color: props.theme?.segment.fontColor}}
|
|
42
|
+
tabActiveTextStyle={{color: props.theme?.segment.fontColor, fontWeight: 'bold'}}
|
|
43
|
+
activeColor={props.theme?.segment.active}
|
|
44
|
+
activeKey={props.activeKey}
|
|
45
|
+
onChange={props.onActiveKeyChange}
|
|
46
|
+
/>
|
|
47
|
+
{
|
|
48
|
+
props.activeKey === AdjustType.COLOUR &&
|
|
49
|
+
<>
|
|
50
|
+
<Spacer height={cx(10)}/>
|
|
51
|
+
<ColorAdjustView
|
|
52
|
+
h={props.h}
|
|
53
|
+
s={props.s}
|
|
54
|
+
v={props.v}
|
|
55
|
+
minSaturation={1}
|
|
56
|
+
reserveSV={true}
|
|
57
|
+
onHSVChange={props.onHSVChange}
|
|
58
|
+
onHSVChangeComplete={props.onHSVChangeComplete}/>
|
|
59
|
+
<Spacer/>
|
|
60
|
+
</>
|
|
61
|
+
}
|
|
62
|
+
{
|
|
63
|
+
props.activeKey === AdjustType.WHITE &&
|
|
64
|
+
<>
|
|
65
|
+
<Spacer height={cx(10)}/>
|
|
66
|
+
<ColorTempAdjustView
|
|
67
|
+
minBrightness={1}
|
|
68
|
+
isSupportTemperature={props.isSupportTemperature}
|
|
69
|
+
isSupportBrightness={props.isSupportBrightness}
|
|
70
|
+
colorTemp={props.colorTemp}
|
|
71
|
+
brightness={props.brightness}
|
|
72
|
+
onCCTChange={props.onCCTChange}
|
|
73
|
+
onCCTChangeComplete={props.onCCTChangeComplete}
|
|
74
|
+
onBrightnessChange={props.onBrightnessChange}
|
|
75
|
+
onBrightnessChangeComplete={props.onBrightnessChangeComplete}/>
|
|
76
|
+
<Spacer/>
|
|
77
|
+
</>
|
|
78
|
+
}
|
|
79
|
+
{
|
|
80
|
+
props.activeKey === AdjustType.LOVE &&
|
|
81
|
+
<View style={{marginVertical: cx(12), marginHorizontal: cx(16), flexDirection: 'row', flexWrap: 'wrap'}}>
|
|
82
|
+
{
|
|
83
|
+
props.favoriteScenes.map((sceneInfo: DiySceneInfo) => {
|
|
84
|
+
return (
|
|
85
|
+
<TouchableOpacity
|
|
86
|
+
key={sceneInfo.id}
|
|
87
|
+
onPress={() => {
|
|
88
|
+
props.onFavoriteSceneChange(sceneInfo)
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
<View style={{
|
|
92
|
+
width: cx(54),
|
|
93
|
+
height: cx(54),
|
|
94
|
+
borderRadius: cx(5),
|
|
95
|
+
marginHorizontal: cx(2),
|
|
96
|
+
marginVertical: cx(2),
|
|
97
|
+
justifyContent: 'center',
|
|
98
|
+
alignItems: 'center',
|
|
99
|
+
backgroundColor: props.theme?.container.background
|
|
100
|
+
}}>
|
|
101
|
+
{
|
|
102
|
+
sceneInfo.id === -1 ?
|
|
103
|
+
<Image source={res.cycle} style={{width: cx(50), height: cx(50)}}/> :
|
|
104
|
+
<View style={{justifyContent: 'center', alignItems: 'center', width: '100%', height: '100%'}}>
|
|
105
|
+
{props.favoriteScenes.length > 3 &&
|
|
106
|
+
<TouchableOpacity
|
|
107
|
+
style={{position: 'absolute', top: cx(5), right: cx(5)}}
|
|
108
|
+
onPress={() => {
|
|
109
|
+
props.onFavoriteSceneRemove && props.onFavoriteSceneRemove(sceneInfo)
|
|
110
|
+
}}>
|
|
111
|
+
<Image source={res.minus} style={{width: cx(10), height: cx(10), tintColor: props.theme?.icon.primary}}/>
|
|
112
|
+
</TouchableOpacity>
|
|
113
|
+
}
|
|
114
|
+
<Text style={{fontSize: cx(8), color: props.theme?.global.fontColor}}>{sceneInfo.name}</Text>
|
|
115
|
+
</View>
|
|
116
|
+
}
|
|
117
|
+
</View>
|
|
118
|
+
</TouchableOpacity>
|
|
119
|
+
)
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
</View>
|
|
123
|
+
}
|
|
124
|
+
</View>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default withTheme(MoodStripAdjustView)
|
|
@@ -13,11 +13,13 @@ interface TextFieldProps extends TextInputProps {
|
|
|
13
13
|
errorText?: string
|
|
14
14
|
tipIcon?: ImageSourcePropType
|
|
15
15
|
tipColor?: string
|
|
16
|
+
editable?: boolean
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
const TextField = (props: TextFieldProps) => {
|
|
19
20
|
const icon = props.tipIcon || res.ic_warning_amber
|
|
20
21
|
const color = props.tipColor || props.theme?.global.warning
|
|
22
|
+
const editable = props.editable ?? !props.editable
|
|
21
23
|
|
|
22
24
|
const styles = StyleSheet.create({
|
|
23
25
|
topTip: {
|
|
@@ -69,7 +71,7 @@ const TextField = (props: TextFieldProps) => {
|
|
|
69
71
|
<Text style={[styles.topTip, { opacity: (!!props.value) ? 1 : 0 }]}>{props.placeholder}</Text>
|
|
70
72
|
<View style={styles.textInputGroup}>
|
|
71
73
|
<TextInput{...props} style={styles.textInput} />
|
|
72
|
-
{!!props.value &&
|
|
74
|
+
{!!props.value && editable &&
|
|
73
75
|
<TouchableOpacity
|
|
74
76
|
style={styles.iconTouchable}
|
|
75
77
|
onPress={() => {
|
package/src/hooks/Hooks.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRoute } from '@react-navigation/core'
|
|
1
|
+
import { useRoute, useNavigation } from '@react-navigation/core'
|
|
2
2
|
|
|
3
3
|
export function createParams<T>(params: T): T {
|
|
4
4
|
return { ...params }
|
|
@@ -6,4 +6,10 @@ export function createParams<T>(params: T): T {
|
|
|
6
6
|
|
|
7
7
|
export function useParams<T extends any>(): T {
|
|
8
8
|
return useRoute().params as T
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function useCurrentPage(routeName: string): boolean {
|
|
12
|
+
const navigation = useNavigation()
|
|
13
|
+
const { index, routes} = navigation.getState()
|
|
14
|
+
return routeName === routes[index].name
|
|
15
|
+
}
|