@ledvance/ui-biz-bundle 1.1.105 → 1.1.107
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/hooks/DeviceDpStateHooks.ts +156 -0
- package/src/modules/flags/FlagActions.ts +4 -1
- package/src/modules/flags/FlagPage.tsx +12 -42
- package/src/modules/music/MusicPage.tsx +13 -7
- package/src/modules/timer/TimerPage.tsx +4 -1
- package/src/modules/timer/TimerPageAction.ts +0 -1
- package/src/navigation/Routers.ts +3 -1
- package/src/newModules/biorhythm/BiorhythmBean.ts +1 -1
- package/src/newModules/biorhythm/BiorhythmPage.tsx +27 -4
- package/src/newModules/diyScene/DefaultScenes.ts +438 -0
- package/src/newModules/diyScene/DiySceneActions.ts +232 -0
- package/src/newModules/diyScene/DiySceneEditorPage.tsx +359 -0
- package/src/newModules/diyScene/DiyScenePage.tsx +297 -0
- package/src/newModules/diyScene/Router.ts +25 -0
- package/src/newModules/energyConsumption/EnergyConsumptionActions.ts +15 -2
- package/src/newModules/energyConsumption/EnergyConsumptionChart.tsx +31 -10
- package/src/newModules/energyConsumption/component/DateSwitch.tsx +111 -0
- package/src/newModules/energyConsumption/component/DateTypeItem.tsx +1 -0
- package/src/newModules/energyConsumption/component/NewBarChart.tsx +16 -3
- package/src/newModules/fixedTime/FixedTimeActions.ts +3 -3
- package/src/newModules/fixedTime/FixedTimePage.tsx +58 -6
- package/src/newModules/mood/MoodActions.ts +4 -1
- package/src/newModules/mood/MoodItem.tsx +2 -1
- package/src/newModules/mood/MoodPage.tsx +4 -3
- package/src/newModules/randomTime/RandomTimeActions.ts +3 -3
- package/src/newModules/randomTime/RandomTimePage.tsx +60 -7
- package/src/newModules/sleepWakeUp/SleepWakeUpActions.ts +21 -11
- package/src/newModules/sleepWakeUp/SleepWakeUpPage.tsx +108 -13
- package/src/newModules/switchGradient/SwitchGradientPage.tsx +7 -4
- package/src/newModules/swithInching/SwithInching.tsx +1 -0
- package/src/newModules/timeSchedule/Interface.ts +19 -7
- package/src/newModules/timeSchedule/TimeScheduleActions.ts +6 -0
- package/src/newModules/timeSchedule/TimeScheduleDetailPage.tsx +134 -57
- package/src/newModules/timeSchedule/TimeSchedulePage.tsx +23 -6
- package/src/newModules/timeSchedule/components/ManuaSettings.tsx +42 -9
- package/src/newModules/timeSchedule/components/ScheduleCard.tsx +5 -1
|
@@ -2,7 +2,12 @@ import {useDp} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
|
2
2
|
import {localeNumber, loopsText, monthFormat, monthFormatShort} from "@ledvance/base/src/utils/common";
|
|
3
3
|
import {EnergyData} from "./component/EnergyModal";
|
|
4
4
|
import {NativeApi} from "@ledvance/base/src/api/native";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
DpResultByMonthResData,
|
|
7
|
+
getDataWithSpecified,
|
|
8
|
+
getDpResultByHour,
|
|
9
|
+
getDpResultByMonth
|
|
10
|
+
} from "@ledvance/base/src/models/TuyaApi";
|
|
6
11
|
import {DateType} from "@ledvance/ui-biz-bundle/src/newModules/energyConsumption/co2Data";
|
|
7
12
|
import {OverviewItem} from "@ledvance/ui-biz-bundle/src/newModules/energyConsumption/EnergyConsumptionPage";
|
|
8
13
|
import {overDays} from "@ledvance/base/src/utils/index";
|
|
@@ -44,8 +49,13 @@ export async function getElectricity(devId: string, addEleDpCode: string, date:
|
|
|
44
49
|
return res
|
|
45
50
|
}
|
|
46
51
|
|
|
52
|
+
let dpResultByMonthCache: DpResultByMonthResData | undefined = undefined
|
|
47
53
|
const getDpResultByYear = async (devId: string, addEleDpCode: string, dateStr: string): Promise<OverviewItem[]> => {
|
|
48
|
-
|
|
54
|
+
let res: DpResultByMonthResData | undefined;
|
|
55
|
+
if (!dpResultByMonthCache) {
|
|
56
|
+
dpResultByMonthCache = await getDpResultByMonth(devId, addEleDpCode, 'sum')
|
|
57
|
+
}
|
|
58
|
+
res = dpResultByMonthCache;
|
|
49
59
|
if (!isEmpty(res)) {
|
|
50
60
|
if (!isEmpty(res.years)) {
|
|
51
61
|
const year = dateStr;
|
|
@@ -105,6 +115,9 @@ const getDpResultByDate = async (devId: string, addEleDpCode: string, date: stri
|
|
|
105
115
|
return []
|
|
106
116
|
}
|
|
107
117
|
const res = await getDpResultByHour(devId, addEleDpCode, date, 'sum')
|
|
118
|
+
if (!res) {
|
|
119
|
+
return []
|
|
120
|
+
}
|
|
108
121
|
const list: Array<OverviewItem> = []
|
|
109
122
|
const resData = Object.keys(res)?.map(val => {
|
|
110
123
|
return {key: Number(val?.slice(8, 10)), value: Number(res[val])}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback } from "react";
|
|
2
|
-
import {Image, Platform, StyleSheet, View, Text} from "react-native";
|
|
2
|
+
import {Image, Platform, StyleSheet, View, Text, TouchableOpacity} from "react-native";
|
|
3
3
|
import {useRoute} from '@react-navigation/core'
|
|
4
4
|
import Page from "@ledvance/base/src/components/Page";
|
|
5
5
|
import res from "@ledvance/base/src/res";
|
|
@@ -19,6 +19,7 @@ import DateSelectedItem from "@ledvance/ui-biz-bundle/src/newModules/energyConsu
|
|
|
19
19
|
import {useReactive, useUpdateEffect} from "ahooks";
|
|
20
20
|
import {getElectricity} from "@ledvance/ui-biz-bundle/src/newModules/energyConsumption/EnergyConsumptionActions";
|
|
21
21
|
import {useDeviceId} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
22
|
+
import DateSwitch from "@ledvance/ui-biz-bundle/src/newModules/energyConsumption/component/DateSwitch";
|
|
22
23
|
|
|
23
24
|
const {convertX: cx} = Utils.RatioUtils
|
|
24
25
|
const {withTheme} = Utils.ThemeUtils
|
|
@@ -50,6 +51,14 @@ const EnergyConsumptionChart = (props: { theme?: ThemeType }) => {
|
|
|
50
51
|
listEmptyText: {
|
|
51
52
|
flex: 0
|
|
52
53
|
},
|
|
54
|
+
downloadIcon: {
|
|
55
|
+
width: cx(24),
|
|
56
|
+
height: cx(24),
|
|
57
|
+
tintColor: props.theme?.global.brand,
|
|
58
|
+
position: 'absolute',
|
|
59
|
+
right: 0,
|
|
60
|
+
top: cx(10)
|
|
61
|
+
}
|
|
53
62
|
});
|
|
54
63
|
|
|
55
64
|
const getDateType = useCallback((date: string) => {
|
|
@@ -64,7 +73,7 @@ const EnergyConsumptionChart = (props: { theme?: ThemeType }) => {
|
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
return DateType.Day;
|
|
67
|
-
}, [])
|
|
76
|
+
}, []);
|
|
68
77
|
const dateType = getDateType(date);
|
|
69
78
|
const state = useReactive({
|
|
70
79
|
loading: false,
|
|
@@ -87,11 +96,13 @@ const EnergyConsumptionChart = (props: { theme?: ThemeType }) => {
|
|
|
87
96
|
getElectricity(devId, addEleDpCode, state.date, state.dateType).then((res) => {
|
|
88
97
|
state.chartData = res;
|
|
89
98
|
state.loading = false;
|
|
90
|
-
})
|
|
99
|
+
}).catch(()=>{
|
|
100
|
+
state.loading = false;
|
|
101
|
+
});
|
|
91
102
|
}, [state.date]);
|
|
92
103
|
|
|
93
104
|
const getEmptyDataTip = useCallback(() => {
|
|
94
|
-
if (state.over365Days) {
|
|
105
|
+
if (state.over365Days && state.dateType !== DateType.Day) {
|
|
95
106
|
return I18n.getLang('energyconsumption_Daylimit')
|
|
96
107
|
}
|
|
97
108
|
if (state.dateType === DateType.Day && state.over7Days) {
|
|
@@ -139,16 +150,26 @@ const EnergyConsumptionChart = (props: { theme?: ThemeType }) => {
|
|
|
139
150
|
return (
|
|
140
151
|
<Page
|
|
141
152
|
backText={I18n.getLang('consumption_data_annual_bar_chart_system_back_text')}
|
|
142
|
-
headlineIcon={state.chartData?.length ? res.download_icon : undefined}
|
|
143
|
-
onHeadlineIconClick={() => {
|
|
144
|
-
exportFile(state.chartData,params.price,params.unit)
|
|
145
|
-
}}
|
|
146
153
|
showGreenery={false}
|
|
147
154
|
loading={state.loading}
|
|
148
155
|
greeneryIcon={res.energy_consumption_greenery}
|
|
149
156
|
headlineContent={
|
|
150
|
-
<View style={{
|
|
151
|
-
<
|
|
157
|
+
<View style={{width: '100%',flexDirection:'row'}}>
|
|
158
|
+
<DateSwitch
|
|
159
|
+
style={{flex: 1}}
|
|
160
|
+
date={state.date}
|
|
161
|
+
dateType={state.dateType}
|
|
162
|
+
headlineText={state.headlineText}
|
|
163
|
+
onDateChange={(date) => {
|
|
164
|
+
state.date = date;
|
|
165
|
+
}}/>
|
|
166
|
+
<TouchableOpacity onPress={() => {
|
|
167
|
+
exportFile(state.chartData, params.price, params.unit)
|
|
168
|
+
}}>
|
|
169
|
+
<Image
|
|
170
|
+
style={styles.downloadIcon}
|
|
171
|
+
source={state.chartData?.length ? res.download_icon : undefined}/>
|
|
172
|
+
</TouchableOpacity>
|
|
152
173
|
</View>
|
|
153
174
|
}
|
|
154
175
|
>
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import ThemeType from "@ledvance/base/src/config/themeType";
|
|
2
|
+
import React, {PropsWithChildren, useCallback, useEffect} from "react";
|
|
3
|
+
import {Image, Text, TouchableOpacity, View, ViewProps} from "react-native";
|
|
4
|
+
import {Utils} from "tuya-panel-kit";
|
|
5
|
+
import {useReactive} from "ahooks";
|
|
6
|
+
import {DateType} from "@ledvance/ui-biz-bundle/src/newModules/energyConsumption/co2Data";
|
|
7
|
+
import res from "@ledvance/base/src/res";
|
|
8
|
+
import dayjs from "dayjs";
|
|
9
|
+
|
|
10
|
+
const cx = Utils.RatioUtils.convertX;
|
|
11
|
+
const {withTheme} = Utils.ThemeUtils
|
|
12
|
+
|
|
13
|
+
interface DateSwitchProps extends PropsWithChildren<ViewProps> {
|
|
14
|
+
theme?: ThemeType
|
|
15
|
+
headlineText: string,
|
|
16
|
+
date: string,
|
|
17
|
+
dateType: DateType,
|
|
18
|
+
onDateChange: (string) => void
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default withTheme(function DateSwitch(props: DateSwitchProps) {
|
|
22
|
+
const {dateType, date, onDateChange, theme, headlineText} = props;
|
|
23
|
+
const state = useReactive({
|
|
24
|
+
date: date,
|
|
25
|
+
dateType: dateType,
|
|
26
|
+
headlineText: headlineText,
|
|
27
|
+
disableArrowLeft: false,
|
|
28
|
+
disableArrowRight: false,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
state.date = date;
|
|
33
|
+
state.headlineText = headlineText;
|
|
34
|
+
state.dateType = dateType;
|
|
35
|
+
const {canPreChangeDate, canNextChangeDate} = canPreOrNextChangeDate(dayjs(date));
|
|
36
|
+
state.disableArrowRight = !canNextChangeDate;
|
|
37
|
+
state.disableArrowLeft = !canPreChangeDate;
|
|
38
|
+
}, [date, headlineText, dateType]);
|
|
39
|
+
|
|
40
|
+
const canPreOrNextChangeDate = useCallback((datejs: dayjs.Dayjs) => {
|
|
41
|
+
const minDatejs = dayjs('2000-1-1');
|
|
42
|
+
const nowDatejs = dayjs();
|
|
43
|
+
const year = datejs.year();
|
|
44
|
+
const month = (datejs.month() + 1).toString().padStart(2, '0');
|
|
45
|
+
const day = datejs.date().toString().padStart(2, '0');
|
|
46
|
+
const dateType = state.dateType;
|
|
47
|
+
const dateUnit = dateType === DateType.Year ? 'year' : (dateType === DateType.Month ? 'month' : 'day');
|
|
48
|
+
let canPreChangeDate = datejs.isAfter(minDatejs, dateUnit);
|
|
49
|
+
let canNextChangeDate = datejs.isBefore(nowDatejs, dateUnit);
|
|
50
|
+
let date: string | undefined = undefined;
|
|
51
|
+
if (datejs >= minDatejs && datejs <= nowDatejs) {
|
|
52
|
+
switch (state.dateType) {
|
|
53
|
+
case DateType.Day:
|
|
54
|
+
date = `${year}${month}${day}`;
|
|
55
|
+
break
|
|
56
|
+
case DateType.Month:
|
|
57
|
+
date = `${year}${month}`;
|
|
58
|
+
break
|
|
59
|
+
case DateType.Year:
|
|
60
|
+
date = `${year}`;
|
|
61
|
+
break
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return {date, canPreChangeDate, canNextChangeDate};
|
|
65
|
+
}, [state.dateType]);
|
|
66
|
+
|
|
67
|
+
const changeDate = useCallback((isNextDate: boolean) => {
|
|
68
|
+
const datejs = dayjs(state.date)
|
|
69
|
+
const dateType = state.dateType
|
|
70
|
+
const dateUnit = dateType === DateType.Year ? 'year' : (dateType === DateType.Month ? 'month' : 'day');
|
|
71
|
+
const newDatejs = datejs.add(isNextDate ? 1 : -1, dateUnit);
|
|
72
|
+
const {date, canPreChangeDate, canNextChangeDate} = canPreOrNextChangeDate(newDatejs);
|
|
73
|
+
state.disableArrowRight = !canNextChangeDate;
|
|
74
|
+
state.disableArrowLeft = !canPreChangeDate;
|
|
75
|
+
if (date) {
|
|
76
|
+
onDateChange(date);
|
|
77
|
+
}
|
|
78
|
+
}, [state.date, canPreOrNextChangeDate, state.disableArrowRight, state.disableArrowLeft, onDateChange]);
|
|
79
|
+
|
|
80
|
+
return (<View style={[props.style, {flexDirection: 'row', alignItems: 'center', justifyContent: 'center'}]}>
|
|
81
|
+
<TouchableOpacity
|
|
82
|
+
disabled={state.disableArrowLeft}
|
|
83
|
+
onPress={() => {
|
|
84
|
+
changeDate(false);
|
|
85
|
+
}}>
|
|
86
|
+
<Image
|
|
87
|
+
source={res.arrow_left}
|
|
88
|
+
style={{tintColor: state.disableArrowLeft ? theme?.global.disabledFontColor : theme?.global.brand}}
|
|
89
|
+
height={cx(36)}
|
|
90
|
+
width={cx(36)}/>
|
|
91
|
+
</TouchableOpacity>
|
|
92
|
+
<Text style={{
|
|
93
|
+
fontSize: cx(24),
|
|
94
|
+
minWidth: cx(200),
|
|
95
|
+
textAlign: 'center',
|
|
96
|
+
color: theme?.global.brand,
|
|
97
|
+
fontFamily: 'helvetica_neue_lt_std_roman',
|
|
98
|
+
}}>{state.headlineText}</Text>
|
|
99
|
+
<TouchableOpacity
|
|
100
|
+
disabled={state.disableArrowRight}
|
|
101
|
+
onPress={() => {
|
|
102
|
+
changeDate(true);
|
|
103
|
+
}}>
|
|
104
|
+
<Image
|
|
105
|
+
source={res.arrow_right}
|
|
106
|
+
style={{tintColor: state.disableArrowRight ? theme?.global.disabledFontColor : theme?.global.brand}}
|
|
107
|
+
height={cx(36)}
|
|
108
|
+
width={cx(36)}/>
|
|
109
|
+
</TouchableOpacity>
|
|
110
|
+
</View>)
|
|
111
|
+
})
|
|
@@ -91,6 +91,7 @@ export default withTheme(function DateTypeItem(props: DateTypeItemProps) {
|
|
|
91
91
|
state.showDateTypeModal = false;
|
|
92
92
|
}}
|
|
93
93
|
title={I18n.getLang('date_type')}
|
|
94
|
+
titleTextStyle={{fontWeight: 'bold', fontSize: cx(16)}}
|
|
94
95
|
cancelText={I18n.getLang('auto_scan_system_cancel')}
|
|
95
96
|
confirmText={I18n.getLang('auto_scan_system_wifi_confirm')}
|
|
96
97
|
onConfirm={(item: DateType) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {useRef} from 'react';
|
|
1
|
+
import React, {useMemo, useRef} from 'react';
|
|
2
2
|
import {View} from 'react-native';
|
|
3
3
|
import ECharts from '@ledvance/react-native-echarts-pro';
|
|
4
4
|
import I18n from "@ledvance/base/src/i18n";
|
|
@@ -28,7 +28,20 @@ const BarChartWithTouch = (props: BarChartProps) => {
|
|
|
28
28
|
const dataPriceY = data?.map(item => {
|
|
29
29
|
return ((isNaN(Number(item.value)) ? 0 : Number(item.value)) * price).toFixed(2);
|
|
30
30
|
});
|
|
31
|
-
const maxValue =
|
|
31
|
+
const maxValue = useMemo(() => {
|
|
32
|
+
let max = Math.max(...dataKwhY)
|
|
33
|
+
if (max < 0.1) {
|
|
34
|
+
max += 0.02
|
|
35
|
+
max = max - (max % 0.02)
|
|
36
|
+
} else if (max < 1) {
|
|
37
|
+
max += 0.2
|
|
38
|
+
max = max - (max % 0.2)
|
|
39
|
+
} else if (max < 10) {
|
|
40
|
+
max = Math.ceil(max) + 2
|
|
41
|
+
max = max - (max % 2)
|
|
42
|
+
}
|
|
43
|
+
return max
|
|
44
|
+
}, [dataKwhY]);
|
|
32
45
|
const option = {
|
|
33
46
|
tooltip: {
|
|
34
47
|
show: true,
|
|
@@ -56,7 +69,7 @@ const BarChartWithTouch = (props: BarChartProps) => {
|
|
|
56
69
|
yAxis: [{
|
|
57
70
|
type: 'value',
|
|
58
71
|
name: I18n.getLang('consumption_data_annual_bar_chart_text'),
|
|
59
|
-
max: Math.
|
|
72
|
+
max: Math.max(maxValue, 0.02),
|
|
60
73
|
min: 0,
|
|
61
74
|
position: 'left',
|
|
62
75
|
axisLabel: {
|
|
@@ -53,7 +53,7 @@ export interface PlugFixedTimer {
|
|
|
53
53
|
closeTime: number;
|
|
54
54
|
}
|
|
55
55
|
let fixedTimer
|
|
56
|
-
type UseFixedTimeType = (dpKey: string, isPlug?: boolean, disableFeature?: boolean) => [FixedTimerUiItem[], (fixedTimeList: FixedTimerUiItem[],
|
|
56
|
+
type UseFixedTimeType = (dpKey: string, isPlug?: boolean, disableFeature?: boolean) => [FixedTimerUiItem[], (fixedTimeList: FixedTimerUiItem[], pushFeature?: boolean) => Promise<{ success: boolean }>]
|
|
57
57
|
|
|
58
58
|
export const useFixedTime: UseFixedTimeType = (dpKey, isPlug, disableFeature) => {
|
|
59
59
|
const deviceId = useDeviceId()
|
|
@@ -107,7 +107,7 @@ export const useFixedTime: UseFixedTimeType = (dpKey, isPlug, disableFeature) =>
|
|
|
107
107
|
}, [fixedTimeDp])
|
|
108
108
|
|
|
109
109
|
|
|
110
|
-
const setFixedTimeFn = async (fixedTimeList: FixedTimerUiItem[]) => {
|
|
110
|
+
const setFixedTimeFn = async (fixedTimeList: FixedTimerUiItem[], pushFeature = true) => {
|
|
111
111
|
const fixedData = fixedTimeList.map(item => {
|
|
112
112
|
const fixedHex = fixedTimeToHex(item, isPlug)
|
|
113
113
|
return {
|
|
@@ -115,7 +115,7 @@ export const useFixedTime: UseFixedTimeType = (dpKey, isPlug, disableFeature) =>
|
|
|
115
115
|
v: isPlug ? JSON.stringify({dp: fixedHex}) : fixedHex
|
|
116
116
|
}
|
|
117
117
|
})
|
|
118
|
-
const cloudStatus = await putFeatureFn(deviceId, isPlug ? plug_fixedFeatureId : fixedFeatureId, JSON.stringify(fixedData))
|
|
118
|
+
const cloudStatus = pushFeature ? await putFeatureFn(deviceId, isPlug ? plug_fixedFeatureId : fixedFeatureId, JSON.stringify(fixedData)) : !pushFeature
|
|
119
119
|
if (cloudStatus) {
|
|
120
120
|
const fixedTimerData = {
|
|
121
121
|
version: 0,
|
|
@@ -9,10 +9,10 @@ import { ui_biz_routerKey } from "../../navigation/Routers";
|
|
|
9
9
|
import { useReactive, useUpdateEffect } from "ahooks";
|
|
10
10
|
import Spacer from "@ledvance/base/src/components/Spacer";
|
|
11
11
|
import TextButton from '@ledvance/base/src/components/TextButton'
|
|
12
|
-
import { SwitchButton, Utils } from "tuya-panel-kit";
|
|
12
|
+
import { Dialog, SwitchButton, Utils } from "tuya-panel-kit";
|
|
13
13
|
import { FixedTimerUiItem, useFixedTime } from "./FixedTimeActions";
|
|
14
14
|
import Card from "@ledvance/base/src/components/Card";
|
|
15
|
-
import { convertMinutesTo12HourFormat, loopText } from "@ledvance/base/src/utils/common";
|
|
15
|
+
import { convertMinutesTo12HourFormat, loopText, isConflictTask, showDialog } from "@ledvance/base/src/utils/common";
|
|
16
16
|
import { cloneDeep } from "lodash";
|
|
17
17
|
import dayjs from "dayjs";
|
|
18
18
|
import { ApplyForItem } from "@ledvance/base/src/utils/interface";
|
|
@@ -20,6 +20,7 @@ import { useParams } from "@ledvance/base/src/hooks/Hooks";
|
|
|
20
20
|
import Tag from "@ledvance/base/src/components/Tag";
|
|
21
21
|
import InfoText from "@ledvance/base/src/components/InfoText";
|
|
22
22
|
import ThemeType from '@ledvance/base/src/config/themeType'
|
|
23
|
+
import { useConflictTask } from "hooks/DeviceDpStateHooks";
|
|
23
24
|
|
|
24
25
|
const { convertX: cx } = Utils.RatioUtils
|
|
25
26
|
const { withTheme } = Utils.ThemeUtils
|
|
@@ -47,6 +48,7 @@ const FixedTimePage = (props: { theme?: ThemeType }) => {
|
|
|
47
48
|
const MAX_NUM = params.isPlug ? 10 : 4
|
|
48
49
|
const is24Hour = useSystemTimeFormate()
|
|
49
50
|
const [fixedTime, setFixedTime] = useFixedTime(params.fixedTimeDpCode, params.isPlug)
|
|
51
|
+
const [checkConflict, resolveConflict] = useConflictTask(params.conflictDps)
|
|
50
52
|
const state = useReactive({
|
|
51
53
|
loading: false,
|
|
52
54
|
originList: cloneDeep(fixedTime),
|
|
@@ -79,7 +81,7 @@ const FixedTimePage = (props: { theme?: ThemeType }) => {
|
|
|
79
81
|
return state.originList.length >= MAX_NUM
|
|
80
82
|
}, [state.originList.length])
|
|
81
83
|
|
|
82
|
-
const onPost =
|
|
84
|
+
const onPost = async (mode: 'add' | 'edit' | 'del', fixedTime: FixedTimerUiItem) => {
|
|
83
85
|
const cloneFixedTimeList = cloneDeep(state.originList)
|
|
84
86
|
const idx = state.originList.findIndex(f => f.index === fixedTime.index)
|
|
85
87
|
if (mode === 'edit') {
|
|
@@ -87,12 +89,48 @@ const FixedTimePage = (props: { theme?: ThemeType }) => {
|
|
|
87
89
|
}
|
|
88
90
|
if (mode === 'del') cloneFixedTimeList.splice(idx, 1)
|
|
89
91
|
const newFixedTimeList = mode === 'add' ? [...state.originList, fixedTime] : cloneFixedTimeList
|
|
92
|
+
if ((mode === 'edit' && fixedTime.enable) || mode === 'add'){
|
|
93
|
+
const cloneList = cloneDeep(newFixedTimeList)
|
|
94
|
+
let itselfConflict = false
|
|
95
|
+
cloneList.forEach((item, idx) => {
|
|
96
|
+
const itself = mode === 'add' ? (idx === cloneList.length - 1) : fixedTime.index === item.index
|
|
97
|
+
if (!itself && item.enable && isConflictTask(item, fixedTime)){
|
|
98
|
+
itselfConflict = true
|
|
99
|
+
item.enable = false
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
const isConflict = checkConflict(fixedTime) || itselfConflict
|
|
103
|
+
if (isConflict){
|
|
104
|
+
return new Promise((resolve) => {
|
|
105
|
+
showDialog({
|
|
106
|
+
method: 'confirm',
|
|
107
|
+
title: I18n.getLang('conflict_dialog_active_item_fixedtimecycle_titel'),
|
|
108
|
+
subTitle: I18n.getLang('conflict_dialog_active_item_fixedtimecycle_description'),
|
|
109
|
+
onConfirm: async (_, { close }) => {
|
|
110
|
+
close()
|
|
111
|
+
resolveConflict()
|
|
112
|
+
const res = await setFixedTime(cloneList)
|
|
113
|
+
if (res.success){
|
|
114
|
+
state.originList = cloneDeep(cloneList)
|
|
115
|
+
}
|
|
116
|
+
resolve(res)
|
|
117
|
+
},
|
|
118
|
+
onCancel: () => {
|
|
119
|
+
resolve({
|
|
120
|
+
success: false
|
|
121
|
+
})
|
|
122
|
+
Dialog.close()
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
}
|
|
90
128
|
const res = await setFixedTime(newFixedTimeList)
|
|
91
129
|
if (res.success) {
|
|
92
130
|
state.originList = cloneDeep(newFixedTimeList)
|
|
93
131
|
}
|
|
94
132
|
return res
|
|
95
|
-
}
|
|
133
|
+
}
|
|
96
134
|
|
|
97
135
|
|
|
98
136
|
const styles = StyleSheet.create({
|
|
@@ -207,6 +245,19 @@ const FixedTimePage = (props: { theme?: ThemeType }) => {
|
|
|
207
245
|
onPress={() => {
|
|
208
246
|
navigateToEdit('edit', item)
|
|
209
247
|
}}
|
|
248
|
+
onLongPress={() =>{
|
|
249
|
+
showDialog({
|
|
250
|
+
method: 'confirm',
|
|
251
|
+
title: I18n.getLang('cancel_dialog_delete_item_fixedtimecycle_titel'),
|
|
252
|
+
subTitle: I18n.getLang('cancel_dialog_delete_item_fixedtimecycle_description'),
|
|
253
|
+
onConfirm: async (_, { close }) => {
|
|
254
|
+
close()
|
|
255
|
+
state.loading = true
|
|
256
|
+
await onPost('del', item)
|
|
257
|
+
state.loading = false
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
}}
|
|
210
261
|
/>
|
|
211
262
|
)}
|
|
212
263
|
keyExtractor={(item: any) => `${item?.index}`}
|
|
@@ -253,11 +304,12 @@ const FixedTimeCard = memo((props: {
|
|
|
253
304
|
showTags?: boolean,
|
|
254
305
|
onSwitch: (enable: boolean) => void,
|
|
255
306
|
onPress: () => void
|
|
307
|
+
onLongPress?: () => void
|
|
256
308
|
styles: StyleSheet.NamedStyles<any>
|
|
257
309
|
}) => {
|
|
258
|
-
const { is24Hour, fixedTime, tags, showTags, onSwitch, onPress, styles } = props
|
|
310
|
+
const { is24Hour, fixedTime, tags, showTags, onSwitch, onPress, onLongPress, styles } = props
|
|
259
311
|
return (
|
|
260
|
-
<Card style={styles.randomTimingCard} onPress={onPress}>
|
|
312
|
+
<Card style={styles.randomTimingCard} onPress={onPress} onLongPress={onLongPress}>
|
|
261
313
|
<Spacer height={cx(16)} />
|
|
262
314
|
<View style={styles.switchLine}>
|
|
263
315
|
<Text style={styles.time}>
|
|
@@ -201,7 +201,10 @@ export const useMoodScene = (params: MoodPageParams): [MoodInfo, (moodInfo: Mood
|
|
|
201
201
|
}
|
|
202
202
|
mainLamp[params.switchLedDp] = true
|
|
203
203
|
}
|
|
204
|
-
return setDps(
|
|
204
|
+
return setDps({
|
|
205
|
+
...mainDps,
|
|
206
|
+
version: params.isStripLight ? 1 : 0
|
|
207
|
+
})
|
|
205
208
|
};
|
|
206
209
|
return [moodState, setMoodFn];
|
|
207
210
|
};
|
|
@@ -119,8 +119,9 @@ export default withTheme(MoodItem)
|
|
|
119
119
|
export function MixMoodColorsLine(props: { mixSubLight: MoodLampInfo; isMix: boolean, type: 'gradient' | 'separate' }) {
|
|
120
120
|
const { mixSubLight, isMix } = props;
|
|
121
121
|
const lightColors = !!(mixSubLight.enable && mixSubLight.nodes.length) ? mixSubLight.nodes?.map(n => {
|
|
122
|
+
const s = Math.round(mapFloatToRange(n.s / 100, 30, 100));
|
|
122
123
|
return n.isColorNode
|
|
123
|
-
? hsv2Hex(n.h,
|
|
124
|
+
? hsv2Hex(n.h, s, Math.round(mapFloatToRange(n.v / 100, 50, 100)))
|
|
124
125
|
: cctToColor(n.colorTemp.toFixed());
|
|
125
126
|
}) : ['#eee'];
|
|
126
127
|
|
|
@@ -23,7 +23,7 @@ import { getRemoteMoodList, useMoodScene } from './MoodActions';
|
|
|
23
23
|
import { useParams } from '@ledvance/base/src/hooks/Hooks';
|
|
24
24
|
import { ui_biz_routerKey } from '../../navigation/Routers'
|
|
25
25
|
import { cloneDeep, filter, map } from 'lodash';
|
|
26
|
-
import { saveFlagMode } from '
|
|
26
|
+
import { saveFlagMode } from '../../modules/flags/FlagActions';
|
|
27
27
|
import { SceneStatusType, WorkMode } from '@ledvance/base/src/utils/interface';
|
|
28
28
|
import { showDialog } from '@ledvance/base/src/utils/common';
|
|
29
29
|
import I18n from '@ledvance/base/src/i18n';
|
|
@@ -87,6 +87,7 @@ const MoodPage = (props: { theme?: ThemeType }) => {
|
|
|
87
87
|
state.loading = false
|
|
88
88
|
if (res.success && Array.isArray(res.data)) {
|
|
89
89
|
state.originMoods = cloneDeep(res.data);
|
|
90
|
+
setMoods(cloneDeep(res.data));
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
93
|
|
|
@@ -311,7 +312,7 @@ const MoodPage = (props: { theme?: ThemeType }) => {
|
|
|
311
312
|
right: cx(60),
|
|
312
313
|
top: Platform.OS === 'android' ? cx(90) : cx(130),
|
|
313
314
|
maxWidth: cx(200),
|
|
314
|
-
backgroundColor: props.theme
|
|
315
|
+
backgroundColor: props.theme?.card.background,
|
|
315
316
|
},
|
|
316
317
|
popoverItem: {
|
|
317
318
|
padding: cx(5),
|
|
@@ -365,7 +366,7 @@ const MoodPage = (props: { theme?: ThemeType }) => {
|
|
|
365
366
|
})
|
|
366
367
|
}}
|
|
367
368
|
>
|
|
368
|
-
<Image source={res.ic_refresh} style={{ width: cx(24), height: cx(24), tintColor: props.theme
|
|
369
|
+
<Image source={res.ic_refresh} style={{ width: cx(24), height: cx(24), tintColor: props.theme?.global.fontColor }} />
|
|
369
370
|
</TouchableOpacity>
|
|
370
371
|
<Spacer height={cx(10)} />
|
|
371
372
|
{state.originMoods.length >= MAX_MOOD_COUNT && (
|
|
@@ -52,7 +52,7 @@ export interface PlugRandomTimerItem extends PlugRandomTimer {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
let randomTimer
|
|
55
|
-
type UseFixedTimeType = (dpKey: string, isPlug?: boolean, disableFeature?: boolean) => [RandomTimerUiItem[], (randomTimeList: RandomTimerUiItem[],
|
|
55
|
+
type UseFixedTimeType = (dpKey: string, isPlug?: boolean, disableFeature?: boolean) => [RandomTimerUiItem[], (randomTimeList: RandomTimerUiItem[], pushFeature?: boolean) => Promise<{ success: boolean }>]
|
|
56
56
|
|
|
57
57
|
export const useRandomTime: UseFixedTimeType = (dpKey: string, isPlug?: boolean, disableFeature?: boolean) => {
|
|
58
58
|
const deviceId = useDeviceId()
|
|
@@ -107,7 +107,7 @@ export const useRandomTime: UseFixedTimeType = (dpKey: string, isPlug?: boolean,
|
|
|
107
107
|
return () => clearTimeout(randomTimer)
|
|
108
108
|
}, [randomTimeDp])
|
|
109
109
|
|
|
110
|
-
const setRandomTimeFn = async (randomTimeList: RandomTimerUiItem[]) => {
|
|
110
|
+
const setRandomTimeFn = async (randomTimeList: RandomTimerUiItem[], pushFeature = true) => {
|
|
111
111
|
const randomData = randomTimeList.map(item => {
|
|
112
112
|
const randomHex = randomTimeToHex(item, isPlug)
|
|
113
113
|
return {
|
|
@@ -115,7 +115,7 @@ export const useRandomTime: UseFixedTimeType = (dpKey: string, isPlug?: boolean,
|
|
|
115
115
|
v: isPlug ? JSON.stringify({dp: randomHex}) : randomHex
|
|
116
116
|
}
|
|
117
117
|
})
|
|
118
|
-
const cloudStatus = await putFeatureFn(deviceId, isPlug ? plug_randomFeatureId : randomFeatureId, JSON.stringify(randomData))
|
|
118
|
+
const cloudStatus = pushFeature ? await putFeatureFn(deviceId, isPlug ? plug_randomFeatureId : randomFeatureId, JSON.stringify(randomData)) : !pushFeature
|
|
119
119
|
if (cloudStatus) {
|
|
120
120
|
const randomTimerData = {
|
|
121
121
|
version: 0,
|
|
@@ -9,10 +9,10 @@ import { ui_biz_routerKey } from '../../navigation/Routers'
|
|
|
9
9
|
import { useReactive, useUpdateEffect } from 'ahooks'
|
|
10
10
|
import Spacer from '@ledvance/base/src/components/Spacer'
|
|
11
11
|
import TextButton from '@ledvance/base/src/components/TextButton'
|
|
12
|
-
import { SwitchButton, Utils } from 'tuya-panel-kit'
|
|
12
|
+
import { Dialog, SwitchButton, Utils } from 'tuya-panel-kit'
|
|
13
13
|
import { RandomTimerUiItem, useRandomTime } from './RandomTimeActions'
|
|
14
14
|
import Card from '@ledvance/base/src/components/Card'
|
|
15
|
-
import { convertMinutesTo12HourFormat, loopText } from '@ledvance/base/src/utils/common'
|
|
15
|
+
import { convertMinutesTo12HourFormat, loopText, isConflictTask, showDialog } from '@ledvance/base/src/utils/common'
|
|
16
16
|
import { cloneDeep } from 'lodash'
|
|
17
17
|
import dayjs from 'dayjs'
|
|
18
18
|
import { ApplyForItem } from '@ledvance/base/src/utils/interface'
|
|
@@ -20,6 +20,7 @@ import { useParams } from '@ledvance/base/src/hooks/Hooks'
|
|
|
20
20
|
import Tag from '@ledvance/base/src/components/Tag'
|
|
21
21
|
import InfoText from '@ledvance/base/src/components/InfoText'
|
|
22
22
|
import ThemeType from '@ledvance/base/src/config/themeType'
|
|
23
|
+
import { useConflictTask } from 'hooks/DeviceDpStateHooks'
|
|
23
24
|
|
|
24
25
|
const { convertX: cx } = Utils.RatioUtils
|
|
25
26
|
const { withTheme } = Utils.ThemeUtils
|
|
@@ -48,6 +49,7 @@ const RandomTimePage = (props: { theme?: ThemeType }) => {
|
|
|
48
49
|
const MAX_NUM = params.isPlug ? 16 : 4
|
|
49
50
|
const is24Hour = useSystemTimeFormate()
|
|
50
51
|
const [randomTime, setRandomTime] = useRandomTime(params.randomTimeDpCode, params.isPlug)
|
|
52
|
+
const [checkConflict, resolveConflict] = useConflictTask(params.conflictDps)
|
|
51
53
|
const state = useReactive({
|
|
52
54
|
loading: false,
|
|
53
55
|
originList: cloneDeep(randomTime),
|
|
@@ -80,7 +82,7 @@ const RandomTimePage = (props: { theme?: ThemeType }) => {
|
|
|
80
82
|
return state.originList.length >= MAX_NUM
|
|
81
83
|
}, [state.originList.length])
|
|
82
84
|
|
|
83
|
-
const onPost =
|
|
85
|
+
const onPost = async (mode: 'add' | 'edit' | 'del', randomTime: RandomTimerUiItem) => {
|
|
84
86
|
const cloneRandomTime = cloneDeep(state.originList)
|
|
85
87
|
const idx = state.originList.findIndex(f => f.index === randomTime.index)
|
|
86
88
|
if (mode === 'edit') {
|
|
@@ -88,12 +90,49 @@ const RandomTimePage = (props: { theme?: ThemeType }) => {
|
|
|
88
90
|
}
|
|
89
91
|
if (mode === 'del') cloneRandomTime.splice(idx, 1)
|
|
90
92
|
const newRandomTimeList = mode === 'add' ? [...state.originList, randomTime] : cloneRandomTime
|
|
93
|
+
if ((mode === 'edit' && randomTime.enable) || mode === 'add') {
|
|
94
|
+
const cloneList = cloneDeep(newRandomTimeList)
|
|
95
|
+
let itselfConflict = false
|
|
96
|
+
cloneList.forEach((item, idx) => {
|
|
97
|
+
const itself = mode === 'add' ? (idx === cloneList.length - 1) : randomTime.index === item.index
|
|
98
|
+
if (!itself && item.enable && isConflictTask(item, randomTime)){
|
|
99
|
+
itselfConflict = true
|
|
100
|
+
item.enable = false
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
const isConflict = checkConflict(randomTime) || itselfConflict
|
|
104
|
+
if (isConflict) {
|
|
105
|
+
return new Promise((resolve) => {
|
|
106
|
+
showDialog({
|
|
107
|
+
method: 'confirm',
|
|
108
|
+
title: I18n.getLang('conflict_dialog_active_item_randomtimecycle_titel'),
|
|
109
|
+
subTitle: I18n.getLang('conflict_dialog_active_item_randomtimecycle_description'),
|
|
110
|
+
onConfirm: async (_, { close }) => {
|
|
111
|
+
close()
|
|
112
|
+
resolveConflict()
|
|
113
|
+
const res = await setRandomTime(cloneList)
|
|
114
|
+
if (res.success) {
|
|
115
|
+
state.originList = cloneDeep(cloneList)
|
|
116
|
+
}
|
|
117
|
+
resolve(res)
|
|
118
|
+
},
|
|
119
|
+
onCancel: () => {
|
|
120
|
+
resolve({
|
|
121
|
+
success: false
|
|
122
|
+
})
|
|
123
|
+
Dialog.close()
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
91
130
|
const res = await setRandomTime(newRandomTimeList)
|
|
92
|
-
if(res.success){
|
|
131
|
+
if (res.success) {
|
|
93
132
|
state.originList = cloneDeep(newRandomTimeList)
|
|
94
133
|
}
|
|
95
134
|
return res
|
|
96
|
-
}
|
|
135
|
+
}
|
|
97
136
|
|
|
98
137
|
|
|
99
138
|
const styles = StyleSheet.create({
|
|
@@ -208,6 +247,19 @@ const RandomTimePage = (props: { theme?: ThemeType }) => {
|
|
|
208
247
|
onPress={() => {
|
|
209
248
|
navigateToEdit('edit', item)
|
|
210
249
|
}}
|
|
250
|
+
onLongPress={() =>{
|
|
251
|
+
showDialog({
|
|
252
|
+
method: 'confirm',
|
|
253
|
+
title: I18n.getLang('cancel_dialog_delete_item_randomtimecycle_titel'),
|
|
254
|
+
subTitle: I18n.getLang('cancel_dialog_delete_item_fixedtimecycle_description'),
|
|
255
|
+
onConfirm: async (_, { close }) => {
|
|
256
|
+
close()
|
|
257
|
+
state.loading = true
|
|
258
|
+
await onPost('del', item)
|
|
259
|
+
state.loading = false
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
}}
|
|
211
263
|
/>
|
|
212
264
|
)}
|
|
213
265
|
keyExtractor={(item: any) => `${item?.index}`}
|
|
@@ -254,10 +306,11 @@ const RandomTimeCard = (props: {
|
|
|
254
306
|
showTags?: boolean,
|
|
255
307
|
onSwitch: (enable: boolean) => void,
|
|
256
308
|
onPress: () => void
|
|
309
|
+
onLongPress?: () => void
|
|
257
310
|
}) => {
|
|
258
|
-
const { is24Hour, randomTime, tags, showTags, onSwitch, onPress, styles } = props
|
|
311
|
+
const { is24Hour, randomTime, tags, showTags, onSwitch, onPress, onLongPress, styles } = props
|
|
259
312
|
return (
|
|
260
|
-
<Card style={styles.randomTimingCard} onPress={onPress}>
|
|
313
|
+
<Card style={styles.randomTimingCard} onPress={onPress} onLongPress={onLongPress}>
|
|
261
314
|
<Spacer height={cx(16)} />
|
|
262
315
|
<View style={styles.switchLine}>
|
|
263
316
|
<Text style={styles.time}>
|