@ledvance/base 1.3.71 → 1.3.73
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 +10 -1
- package/package.json +1 -1
- package/src/api/native.ts +12 -11
- package/src/components/ColorAdjustView.tsx +77 -11
- package/src/components/ColorTempAdjustView.tsx +95 -6
- package/src/components/rect-color-and-bright-picker/ColourPicker.tsx +269 -0
- package/src/components/rect-color-and-bright-picker/RectPicker.tsx +448 -0
- package/src/components/rect-color-and-bright-picker/Slider.tsx +591 -0
- package/src/components/rect-color-and-bright-picker/Thumb.tsx +94 -0
- package/src/components/rect-color-and-bright-picker/WhitePicker.tsx +362 -0
- package/src/components/rect-color-and-bright-picker/brightness-icons/index.ts +8 -0
- package/src/components/rect-color-and-bright-picker/index.tsx +5 -0
- package/src/components/rect-color-and-bright-picker/res/index.ts +3 -0
- package/src/components/rect-color-and-bright-picker/res/thumb-mask@2x.png +0 -0
- package/src/components/rect-color-and-bright-picker/res/thumb-mask@3x.png +0 -0
- package/src/components/rect-color-and-bright-picker/utils/color.ts +73 -0
- package/src/components/weekSelect.tsx +7 -7
- package/src/composeLayout.tsx +4 -1
- package/src/hooks/Hooks.ts +46 -0
- package/src/i18n/strings.ts +1211 -959
- package/src/models/TuyaApi.ts +132 -0
- package/src/models/modules/NativePropsSlice.tsx +13 -2
- package/src/utils/common.ts +41 -9
- package/src/utils/index.ts +58 -0
- package/src/utils/interface.ts +20 -0
- package/translateKey.txt +9 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
import { View, ViewStyle } from 'react-native';
|
|
4
|
+
import RectPicker, {
|
|
5
|
+
ValidBound,
|
|
6
|
+
ILinear,
|
|
7
|
+
ILinearColors,
|
|
8
|
+
Point,
|
|
9
|
+
defaultProps as baseDefault,
|
|
10
|
+
} from './RectPicker';
|
|
11
|
+
import Slider, { IBrightOption } from './Slider';
|
|
12
|
+
import ColorUtils from './utils/color';
|
|
13
|
+
|
|
14
|
+
export interface IWhite {
|
|
15
|
+
brightness: number;
|
|
16
|
+
temperature: number;
|
|
17
|
+
}
|
|
18
|
+
const defaultProps = {
|
|
19
|
+
...baseDefault,
|
|
20
|
+
brightOption: {} as IBrightOption,
|
|
21
|
+
value: { brightness: 500, temperature: 500 } as IWhite,
|
|
22
|
+
lossSliderColor: 'rgba(255,255,255,0.4)',
|
|
23
|
+
hideBright: false,
|
|
24
|
+
/**
|
|
25
|
+
* 排布方向
|
|
26
|
+
* leftBottom 对角线, 0在左下角
|
|
27
|
+
* leftTop 对角线, 0在左上角
|
|
28
|
+
* rightBottom 反向对角线, 0在右下角
|
|
29
|
+
* rightTop 反向对角线, 0在右上角
|
|
30
|
+
* left 从左往右,0在左边
|
|
31
|
+
* right 从右往左,0在右边
|
|
32
|
+
* top 从上往下,0在上边
|
|
33
|
+
* bottom 从下往上,0在下边
|
|
34
|
+
* @version ^0.3.0
|
|
35
|
+
*/
|
|
36
|
+
direction: 'left' as
|
|
37
|
+
| 'leftBottom'
|
|
38
|
+
| 'leftTop'
|
|
39
|
+
| 'rightBottom'
|
|
40
|
+
| 'rightTop'
|
|
41
|
+
| 'left'
|
|
42
|
+
| 'right'
|
|
43
|
+
| 'top'
|
|
44
|
+
| 'bottom',
|
|
45
|
+
bgs: [
|
|
46
|
+
{ offset: '0%', stopColor: '#FFCA5C', stopOpacity: 1 },
|
|
47
|
+
{ offset: '60%', stopColor: '#FFFFFF', stopOpacity: 1 },
|
|
48
|
+
{ offset: '100%', stopColor: '#CDECFE', stopOpacity: 1 },
|
|
49
|
+
] as ILinearColors[],
|
|
50
|
+
onGrant(_v: any, _option?: { isChangeBright: boolean }) {},
|
|
51
|
+
onMove(_v: any, _option?: { isChangeBright: boolean }) {},
|
|
52
|
+
onRelease(_v: any, _option?: { isChangeBright: boolean }) {},
|
|
53
|
+
onPress(_v: any, _option?: { isChangeBright: boolean }) {},
|
|
54
|
+
};
|
|
55
|
+
type DefaultProps = {
|
|
56
|
+
style?: ViewStyle;
|
|
57
|
+
rectStyle?: ViewStyle;
|
|
58
|
+
} & Readonly<typeof defaultProps>;
|
|
59
|
+
|
|
60
|
+
type WhiteProps = DefaultProps;
|
|
61
|
+
|
|
62
|
+
export default class WhitePicker extends Component<WhiteProps, IWhite> {
|
|
63
|
+
static defaultProps = defaultProps;
|
|
64
|
+
|
|
65
|
+
constructor(props: WhiteProps) {
|
|
66
|
+
super(props);
|
|
67
|
+
const { value: { brightness, temperature }, } = this.props;
|
|
68
|
+
this.state = { brightness, temperature };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
componentDidUpdate(prevProps: WhiteProps) {
|
|
72
|
+
const {
|
|
73
|
+
value: { temperature, brightness },
|
|
74
|
+
} = this.props;
|
|
75
|
+
if (temperature !== prevProps.value.temperature) {
|
|
76
|
+
this.setState({ temperature });
|
|
77
|
+
this.thumbPosition = this.autoTemperaturePosition(temperature);
|
|
78
|
+
this.currentTemperature = temperature;
|
|
79
|
+
}
|
|
80
|
+
if (brightness !== prevProps.value.brightness && brightness !== this.state.brightness) {
|
|
81
|
+
this.setState({ brightness });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
componentWillUnmount() {
|
|
86
|
+
// 清理引用和状态
|
|
87
|
+
this.pickerRef = null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
shouldComponentUpdate(nextProps: WhiteProps, nextState: IWhite) {
|
|
91
|
+
return !_.isEqual(nextProps, this.props) || !_.isEqual(nextState, this.state);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
onBrightGrant = () => {
|
|
95
|
+
const { brightness, temperature } = this.state;
|
|
96
|
+
this.firPropsEvent(this.props.onGrant, { brightness, temperature }, { isChangeBright: true });
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
onBrightMove = (brightness: number) => {
|
|
100
|
+
const { temperature } = this.state;
|
|
101
|
+
this.firPropsEvent(this.props.onMove, { temperature, brightness }, { isChangeBright: true });
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
onBrightRelease = (brightness: number) => {
|
|
105
|
+
const { temperature } = this.state;
|
|
106
|
+
this.setState({ temperature, brightness });
|
|
107
|
+
this.firPropsEvent(this.props.onRelease, { temperature, brightness }, { isChangeBright: true });
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
onBrightPress = (brightness: number) => {
|
|
111
|
+
const { temperature } = this.state;
|
|
112
|
+
this.setState({ temperature, brightness });
|
|
113
|
+
this.firPropsEvent(this.props.onPress, { temperature, brightness }, { isChangeBright: true });
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
getBgs() {
|
|
117
|
+
const { direction, bgs } = this.props;
|
|
118
|
+
// left bottom
|
|
119
|
+
let x1 = '0%';
|
|
120
|
+
let y1 = '100%';
|
|
121
|
+
let x2 = '100%';
|
|
122
|
+
let y2 = '0%';
|
|
123
|
+
switch (direction) {
|
|
124
|
+
case 'leftTop':
|
|
125
|
+
x1 = '0%';
|
|
126
|
+
y1 = '0%';
|
|
127
|
+
x2 = '100%';
|
|
128
|
+
y2 = '100%';
|
|
129
|
+
break;
|
|
130
|
+
case 'rightBottom':
|
|
131
|
+
x1 = '100%';
|
|
132
|
+
y1 = '100%';
|
|
133
|
+
x2 = '0%';
|
|
134
|
+
y2 = '0%';
|
|
135
|
+
break;
|
|
136
|
+
case 'rightTop':
|
|
137
|
+
x1 = '100%';
|
|
138
|
+
y1 = '0%';
|
|
139
|
+
x2 = '0%';
|
|
140
|
+
y2 = '100%';
|
|
141
|
+
break;
|
|
142
|
+
case 'left':
|
|
143
|
+
x1 = '0%';
|
|
144
|
+
y1 = '0%';
|
|
145
|
+
x2 = '100%';
|
|
146
|
+
y2 = '0%';
|
|
147
|
+
break;
|
|
148
|
+
case 'right':
|
|
149
|
+
x1 = '100%';
|
|
150
|
+
y1 = '0%';
|
|
151
|
+
x2 = '0%';
|
|
152
|
+
y2 = '0%';
|
|
153
|
+
break;
|
|
154
|
+
case 'top':
|
|
155
|
+
x1 = '0%';
|
|
156
|
+
y1 = '0%';
|
|
157
|
+
x2 = '0%';
|
|
158
|
+
y2 = '100%';
|
|
159
|
+
break;
|
|
160
|
+
case 'bottom':
|
|
161
|
+
x1 = '0%';
|
|
162
|
+
y1 = '100%';
|
|
163
|
+
x2 = '0%';
|
|
164
|
+
y2 = '0%';
|
|
165
|
+
break;
|
|
166
|
+
|
|
167
|
+
default:
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return [{ x1, y1, x2, y2, colors: bgs }] as ILinear[];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
getNormalVector({ width, height, x, y }: ValidBound) {
|
|
175
|
+
switch (this.props.direction) {
|
|
176
|
+
case 'leftTop':
|
|
177
|
+
return { x: width, y: height, originX: x, originY: y };
|
|
178
|
+
case 'rightBottom':
|
|
179
|
+
return { x: -width, y: -height, originX: width + x, originY: height + y };
|
|
180
|
+
case 'rightTop':
|
|
181
|
+
return { x: -width, y: height, originX: width + x, originY: y };
|
|
182
|
+
case 'left':
|
|
183
|
+
return { x: width, y: 0, originX: x, originY: height / 2 + y };
|
|
184
|
+
case 'right':
|
|
185
|
+
return { x: -width, y: 0, originX: width + x, originY: height / 2 + y };
|
|
186
|
+
case 'top':
|
|
187
|
+
return { x: 0, y: height, originX: width / 2 + x, originY: y };
|
|
188
|
+
case 'bottom':
|
|
189
|
+
return { x: 0, y: -height, originX: width / 2 + x, originY: height + y };
|
|
190
|
+
default:
|
|
191
|
+
return { x: width, y: -height, originX: x, originY: height + y };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
setValue({ temperature, brightness }: IWhite) {
|
|
196
|
+
this.thumbPosition = this.autoTemperaturePosition(temperature);
|
|
197
|
+
this.currentTemperature = temperature;
|
|
198
|
+
this.setState({ temperature, brightness });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
initData = async (validBound: ValidBound) => {
|
|
202
|
+
const { temperature } = this.state;
|
|
203
|
+
// 根据色温计算位置
|
|
204
|
+
this.thumbPosition = this.autoTemperaturePosition(temperature, validBound);
|
|
205
|
+
this.currentTemperature = temperature;
|
|
206
|
+
this.pickerBound = validBound;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
autoTemperaturePosition(temperature: number, validBound: any = { width: 0, height: 0 }) {
|
|
210
|
+
let position;
|
|
211
|
+
if (this.pickerRef) {
|
|
212
|
+
position = this.pickerRef.valueToCoor({ temperature });
|
|
213
|
+
} else {
|
|
214
|
+
position = this.valueToCoor(
|
|
215
|
+
{ temperature, brightness: this.state.brightness },
|
|
216
|
+
null,
|
|
217
|
+
validBound
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
return position;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
coorToValue = ({ x, y }: Point, bound: ValidBound) => {
|
|
224
|
+
const { brightness } = this.state;
|
|
225
|
+
// 获取基准向量
|
|
226
|
+
const normalVector = this.getNormalVector(bound);
|
|
227
|
+
const vector1 = { x: x - normalVector.originX, y: y - normalVector.originY };
|
|
228
|
+
// 对角线的长度
|
|
229
|
+
const total = Math.sqrt(normalVector.x ** 2 + normalVector.y ** 2);
|
|
230
|
+
const diff = (vector1.x * normalVector.x + vector1.y * normalVector.y) / total;
|
|
231
|
+
const temperature = Math.round((diff / total) * 1000);
|
|
232
|
+
return { temperature, brightness };
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
handleTemperaturePosition(temperature: number, bound: ValidBound) {
|
|
236
|
+
// 获取基准向量
|
|
237
|
+
const normalVector = this.getNormalVector(bound);
|
|
238
|
+
const total = Math.sqrt(normalVector.x ** 2 + normalVector.y ** 2);
|
|
239
|
+
const normal = { x: normalVector.x / total, y: normalVector.y / total };
|
|
240
|
+
const length = total * (temperature / 1000);
|
|
241
|
+
const position = {
|
|
242
|
+
x: normal.x * length + normalVector.originX,
|
|
243
|
+
y: normal.y * length + normalVector.originY,
|
|
244
|
+
};
|
|
245
|
+
return position;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
valueToCoor = ({ temperature }: IWhite, origin: Point, validBound: ValidBound): Point => {
|
|
249
|
+
// origin 不存在时,不在滑动时候
|
|
250
|
+
if (!origin) {
|
|
251
|
+
let cacheEnabled = true;
|
|
252
|
+
if (!_.isEqual(validBound, this.pickerBound)) {
|
|
253
|
+
cacheEnabled = false;
|
|
254
|
+
}
|
|
255
|
+
if (this.currentTemperature === temperature && cacheEnabled) {
|
|
256
|
+
if (
|
|
257
|
+
this.thumbPosition &&
|
|
258
|
+
typeof this.thumbPosition.x === 'number' &&
|
|
259
|
+
this.thumbPosition.x >= 0
|
|
260
|
+
) {
|
|
261
|
+
return this.thumbPosition;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return this.handleTemperaturePosition(temperature, validBound);
|
|
265
|
+
}
|
|
266
|
+
this.currentTemperature = temperature;
|
|
267
|
+
this.thumbPosition = origin;
|
|
268
|
+
return origin;
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
valueToColor = (data: IWhite): string => {
|
|
272
|
+
const { temperature, brightness } = data;
|
|
273
|
+
return ColorUtils.brightKelvin2rgba(brightness, temperature);
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
firPropsEvent(cb: (params?: any) => void, ...args: any[]) {
|
|
277
|
+
typeof cb === 'function' && cb(...args);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private thumbPosition: Point;
|
|
281
|
+
private currentTemperature: number;
|
|
282
|
+
private pickerRef: RectPicker | null;
|
|
283
|
+
private pickerBound: ValidBound;
|
|
284
|
+
|
|
285
|
+
handlePickerGrant = () => {
|
|
286
|
+
const { temperature, brightness } = this.state;
|
|
287
|
+
this.firPropsEvent(this.props.onGrant, { temperature, brightness });
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
handlePickerMove = (white: IWhite) => {
|
|
291
|
+
this.firPropsEvent(this.props.onMove, white);
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
handlePickerRelease = (white: IWhite) => {
|
|
295
|
+
this.setState({ ...white });
|
|
296
|
+
this.firPropsEvent(this.props.onRelease, white);
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
handlePickerPress = (white: IWhite) => {
|
|
300
|
+
this.setState({ ...white });
|
|
301
|
+
this.firPropsEvent(this.props.onPress, white);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
render() {
|
|
305
|
+
const {
|
|
306
|
+
style,
|
|
307
|
+
rectStyle,
|
|
308
|
+
brightOption,
|
|
309
|
+
lossShow,
|
|
310
|
+
lossSliderColor,
|
|
311
|
+
clickEnabled,
|
|
312
|
+
hideBright,
|
|
313
|
+
opacityAnimationValue,
|
|
314
|
+
opacityAnimationDuration,
|
|
315
|
+
...pickerProps
|
|
316
|
+
} = this.props;
|
|
317
|
+
const { temperature, brightness } = this.state;
|
|
318
|
+
const sliderProps: any = {};
|
|
319
|
+
if (lossShow) {
|
|
320
|
+
sliderProps.activeColor = lossSliderColor;
|
|
321
|
+
}
|
|
322
|
+
return (
|
|
323
|
+
<View style={[{ flex: 1 }, style]}>
|
|
324
|
+
<RectPicker
|
|
325
|
+
ref={(ref: RectPicker) => {
|
|
326
|
+
this.pickerRef = ref;
|
|
327
|
+
}}
|
|
328
|
+
coorToValue={this.coorToValue}
|
|
329
|
+
valueToColor={this.valueToColor}
|
|
330
|
+
valueToCoor={this.valueToCoor}
|
|
331
|
+
value={{ temperature, brightness }}
|
|
332
|
+
lossShow={lossShow}
|
|
333
|
+
clickEnabled={clickEnabled}
|
|
334
|
+
opacityAnimationValue={opacityAnimationValue}
|
|
335
|
+
opacityAnimationDuration={opacityAnimationDuration}
|
|
336
|
+
{...pickerProps}
|
|
337
|
+
bgs={this.getBgs()}
|
|
338
|
+
style={rectStyle}
|
|
339
|
+
onGrant={this.handlePickerGrant}
|
|
340
|
+
onMove={this.handlePickerMove}
|
|
341
|
+
onRelease={this.handlePickerRelease}
|
|
342
|
+
onPress={this.handlePickerPress}
|
|
343
|
+
initData={this.initData}
|
|
344
|
+
/>
|
|
345
|
+
{!hideBright && (
|
|
346
|
+
<Slider
|
|
347
|
+
opacityAnimationValue={opacityAnimationValue}
|
|
348
|
+
opacityAnimationDuration={opacityAnimationDuration}
|
|
349
|
+
{...brightOption}
|
|
350
|
+
{...sliderProps}
|
|
351
|
+
clickEnabled={clickEnabled}
|
|
352
|
+
value={brightness}
|
|
353
|
+
onGrant={this.onBrightGrant}
|
|
354
|
+
onMove={this.onBrightMove}
|
|
355
|
+
onRelease={this.onBrightRelease}
|
|
356
|
+
onPress={this.onBrightPress}
|
|
357
|
+
/>
|
|
358
|
+
)}
|
|
359
|
+
</View>
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
brightLevel1:
|
|
3
|
+
'M512 736a32 32 0 1 1 0 64 32 32 0 0 1 0-64z m-158.4-65.6a32 32 0 1 1-45.248 45.248 32 32 0 0 1 45.248-45.248z m362.048 0a32 32 0 1 1-45.248 45.248 32 32 0 0 1 45.248-45.248zM512 352a160 160 0 1 1 0 320 160 160 0 0 1 0-320z m-256 128a32 32 0 1 1 0 64 32 32 0 0 1 0-64z m512 0a32 32 0 1 1 0 64 32 32 0 0 1 0-64z m-52.352-171.648a32 32 0 1 1-45.248 45.248 32 32 0 0 1 45.248-45.248z m-362.048 0a32 32 0 1 1-45.248 45.248 32 32 0 0 1 45.248-45.248zM512 224a32 32 0 1 1 0 64 32 32 0 0 1 0-64z',
|
|
4
|
+
brightLevel2:
|
|
5
|
+
'M512 736a32 32 0 0 1 32 32v32a32 32 0 0 1-64 0v-32a32 32 0 0 1 32-32z m-158.4-65.6a32 32 0 0 1 0 45.248l-22.624 22.624a32 32 0 0 1-45.248-45.248l22.624-22.624a32 32 0 0 1 45.248 0z m362.048 0l22.624 22.624a32 32 0 0 1-45.248 45.248l-22.624-22.624a32 32 0 1 1 45.248-45.248zM512 352a160 160 0 1 1 0 320 160 160 0 0 1 0-320z m-256 128a32 32 0 0 1 0 64H224a32 32 0 0 1 0-64h32z m544 0a32 32 0 0 1 0 64h-32a32 32 0 0 1 0-64h32z m-61.728-194.272a32 32 0 0 1 0 45.248l-22.624 22.624a32 32 0 1 1-45.248-45.248l22.624-22.624a32 32 0 0 1 45.248 0z m-407.296 0l22.624 22.624a32 32 0 1 1-45.248 45.248l-22.624-22.624a32 32 0 0 1 45.248-45.248zM512 192a32 32 0 0 1 32 32v32a32 32 0 0 1-64 0V224a32 32 0 0 1 32-32z',
|
|
6
|
+
brightLevel3:
|
|
7
|
+
'M512 736a32 32 0 0 1 32 32v64a32 32 0 0 1-64 0v-64a32 32 0 0 1 32-32z m-158.4-65.6a32 32 0 0 1 0 45.248l-45.248 45.248a32 32 0 1 1-45.248-45.248l45.248-45.248a32 32 0 0 1 45.248 0z m362.048 0l45.248 45.248a32 32 0 0 1-45.248 45.248l-45.248-45.248a32 32 0 1 1 45.248-45.248zM512 352a160 160 0 1 1 0 320 160 160 0 0 1 0-320z m320 128a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64h64zM256 480a32 32 0 0 1 0 64H192a32 32 0 0 1 0-64h64z m504.896-216.896a32 32 0 0 1 0 45.248l-45.248 45.248a32 32 0 1 1-45.248-45.248l45.248-45.248a32 32 0 0 1 45.248 0z m-452.544 0l45.248 45.248a32 32 0 1 1-45.248 45.248L263.104 308.352a32 32 0 0 1 45.248-45.248zM512 160a32 32 0 0 1 32 32v64a32 32 0 0 1-64 0V192a32 32 0 0 1 32-32z',
|
|
8
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/* eslint-disable func-names */
|
|
2
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
3
|
+
import { Utils } from 'tuya-panel-kit';
|
|
4
|
+
import ColorObj from 'color';
|
|
5
|
+
|
|
6
|
+
const { color: ColorUtils } = Utils.ColorUtils;
|
|
7
|
+
|
|
8
|
+
ColorUtils.temp2rgb = function (
|
|
9
|
+
kelvin: number,
|
|
10
|
+
{ temperatureMin = 4000, temperatureMax = 8000 } = {}
|
|
11
|
+
) {
|
|
12
|
+
let newKelvin = kelvin;
|
|
13
|
+
newKelvin /= 10; // 0 - 1000 范围
|
|
14
|
+
const temp = temperatureMin + ((temperatureMax - temperatureMin) * newKelvin) / 100;
|
|
15
|
+
const hsv = this.rgb2hsv(...this.kelvin2rgb(temp));
|
|
16
|
+
return this.hsv2RgbString(...hsv);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
ColorUtils.brightKelvin2rgb = function (
|
|
20
|
+
bright = 1000,
|
|
21
|
+
kelvin = 1000,
|
|
22
|
+
{ temperatureMin = 4000, temperatureMax = 8000 } = {}
|
|
23
|
+
) {
|
|
24
|
+
let newKelvin = kelvin;
|
|
25
|
+
let newBright = bright;
|
|
26
|
+
newBright /= 10;
|
|
27
|
+
newKelvin /= 10;
|
|
28
|
+
const temp = temperatureMin + ((temperatureMax - temperatureMin) * newKelvin) / 100;
|
|
29
|
+
const hsv = this.rgb2hsv(...this.kelvin2rgb(temp));
|
|
30
|
+
const brightV = newBright;
|
|
31
|
+
hsv[2] = brightV;
|
|
32
|
+
return this.hsv2RgbString(...hsv);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
ColorUtils.bright2Opacity = (
|
|
36
|
+
brightness: number,
|
|
37
|
+
option: { min: number; max: number } = { min: 0.2, max: 1 }
|
|
38
|
+
) => {
|
|
39
|
+
const { min = 0.2, max = 1 } = option;
|
|
40
|
+
return Math.round((min + ((brightness - 10) / (1000 - 10)) * (max - min)) * 100) / 100;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 格式化hsv
|
|
45
|
+
* 亮度将转化为透明度变化
|
|
46
|
+
*/
|
|
47
|
+
ColorUtils.hsv2rgba = function (hue: number, saturation: number, bright: number) {
|
|
48
|
+
try {
|
|
49
|
+
let color: string = ColorUtils.hsb2hex(hue, saturation / 10, 100);
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
color = new ColorObj(color as string).alpha(this.bright2Opacity(bright)).rgbString();
|
|
52
|
+
return color;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
console.warn(error);
|
|
56
|
+
return 'transparent';
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
ColorUtils.brightKelvin2rgba = function (bright: number, kelvin: number) {
|
|
61
|
+
try {
|
|
62
|
+
let color = ColorUtils.brightKelvin2rgb(1000, kelvin || 0);
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
color = new ColorObj(color).alpha(this.bright2Opacity(bright)).rgbString();
|
|
65
|
+
return color;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
// eslint-disable-next-line no-console
|
|
68
|
+
console.warn(error);
|
|
69
|
+
return 'transparent';
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default ColorUtils;
|
|
@@ -8,10 +8,6 @@ const { withTheme } = Utils.ThemeUtils
|
|
|
8
8
|
|
|
9
9
|
const repeatPeriod = [
|
|
10
10
|
{
|
|
11
|
-
index: 1,
|
|
12
|
-
title: I18n.getLang('timeschedule_add_schedule_weekday7_text'),
|
|
13
|
-
enabled: false,
|
|
14
|
-
}, {
|
|
15
11
|
index: 2,
|
|
16
12
|
title: I18n.getLang('timeschedule_add_schedule_weekday1_text'),
|
|
17
13
|
enabled: false,
|
|
@@ -35,14 +31,18 @@ const repeatPeriod = [
|
|
|
35
31
|
index: 7,
|
|
36
32
|
title: I18n.getLang('timeschedule_add_schedule_weekday6_text'),
|
|
37
33
|
enabled: false,
|
|
34
|
+
}, {
|
|
35
|
+
index: 1,
|
|
36
|
+
title: I18n.getLang('timeschedule_add_schedule_weekday7_text'),
|
|
37
|
+
enabled: false,
|
|
38
38
|
},
|
|
39
39
|
]
|
|
40
40
|
|
|
41
|
-
export const setDataSource = (loop) => {
|
|
42
|
-
return repeatPeriod.map(
|
|
41
|
+
export const setDataSource = (loop: number[] | string[] | string) => {
|
|
42
|
+
return repeatPeriod.map(item => {
|
|
43
43
|
return {
|
|
44
44
|
...item,
|
|
45
|
-
enabled: loop[index
|
|
45
|
+
enabled: [1, '1'].includes(loop[item.index - 1]),
|
|
46
46
|
}
|
|
47
47
|
})
|
|
48
48
|
}
|
package/src/composeLayout.tsx
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
NativeProps,
|
|
11
11
|
setGroupDevices,
|
|
12
12
|
setGroupNativeProps,
|
|
13
|
-
setNativeProps,
|
|
13
|
+
setNativeProps, setNewPalette,
|
|
14
14
|
setSystemTimeFormat,
|
|
15
15
|
setTimeZone,
|
|
16
16
|
UAGroupInfo,
|
|
@@ -26,6 +26,7 @@ interface Props {
|
|
|
26
26
|
ldvDevInfo: LdvDevInfo
|
|
27
27
|
uaGroupInfo: UAGroupInfoProps
|
|
28
28
|
colorScheme?: string
|
|
29
|
+
newPalette?: boolean
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
interface LdvDevInfo extends DeviceInfo {
|
|
@@ -130,6 +131,8 @@ const composeLayout = (component: React.ComponentType) => {
|
|
|
130
131
|
getTimeZone().then(timeZone => {
|
|
131
132
|
dispatch(setTimeZone(timeZone))
|
|
132
133
|
})
|
|
134
|
+
|
|
135
|
+
dispatch(setNewPalette(!!props.newPalette))
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
initReduxDeviceNativeProps(ldvDevInfo: LdvDevInfo) {
|
package/src/hooks/Hooks.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useRoute, useNavigation } from '@react-navigation/core'
|
|
2
|
+
import { useCallback, useEffect, useRef } from 'react'
|
|
2
3
|
|
|
3
4
|
export function createParams<T>(params: T): T {
|
|
4
5
|
return { ...params }
|
|
@@ -13,3 +14,48 @@ export function useCurrentPage(routeName: string): boolean {
|
|
|
13
14
|
const { index, routes} = navigation.getState()
|
|
14
15
|
return routeName === routes[index].name
|
|
15
16
|
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* dp 响应时间校验 hook
|
|
20
|
+
* 用于在指定时间内阻止长连接响应更新界面状态
|
|
21
|
+
*/
|
|
22
|
+
export function useDpResponseValidator(timeoutMs: number = 1000) {
|
|
23
|
+
const dpTimestamps = useRef<{[dpKey: string]: number}>({});
|
|
24
|
+
|
|
25
|
+
// dp 响应时间校验函数
|
|
26
|
+
const sendDpWithTimestamps = useCallback((dpKey: string, sendFunc: () => Promise<any>) => {
|
|
27
|
+
// 记录发送时间戳
|
|
28
|
+
const timestamp = Date.now();
|
|
29
|
+
dpTimestamps.current[dpKey] = timestamp;
|
|
30
|
+
|
|
31
|
+
// 发送命令
|
|
32
|
+
return sendFunc();
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
// 监听 dp 响应,比较时间戳
|
|
36
|
+
const onDpResponse = useCallback((dpKey: string) => {
|
|
37
|
+
const sendTimestamp = dpTimestamps.current[dpKey];
|
|
38
|
+
if (sendTimestamp) {
|
|
39
|
+
const responseTimestamp = Date.now();
|
|
40
|
+
const timeDiff = responseTimestamp - sendTimestamp;
|
|
41
|
+
|
|
42
|
+
if (timeDiff <= timeoutMs) {
|
|
43
|
+
// 指定时间内收到响应,不接收更新
|
|
44
|
+
return true; // 阻止更新
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return false; // 允许更新
|
|
48
|
+
}, [timeoutMs]);
|
|
49
|
+
|
|
50
|
+
// 组件卸载时清理所有记录
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
return () => {
|
|
53
|
+
dpTimestamps.current = {};
|
|
54
|
+
};
|
|
55
|
+
}, []);
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
sendDpWithTimestamps,
|
|
59
|
+
onDpResponse,
|
|
60
|
+
};
|
|
61
|
+
}
|