@ledvance/group-ui-biz-bundle 1.0.91 → 1.0.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/package.json +1 -1
  2. package/src/modules/biorhythm/BiorhythmBean.ts +1 -1
  3. package/src/modules/diyScene/DefaultScenes.ts +439 -0
  4. package/src/modules/diyScene/DiySceneActions.ts +206 -0
  5. package/src/modules/diyScene/DiySceneEditorPage.tsx +356 -0
  6. package/src/modules/diyScene/DiyScenePage.tsx +281 -0
  7. package/src/modules/diyScene/Router.ts +25 -0
  8. package/src/modules/energyConsumption/EnergyConsumptionActions.ts +134 -119
  9. package/src/modules/energyConsumption/EnergyConsumptionChart.tsx +30 -9
  10. package/src/modules/energyConsumption/component/DateSwitch.tsx +111 -0
  11. package/src/modules/energyConsumption/component/NewBarChart.tsx +16 -3
  12. package/src/modules/fixedTimeForPlug/FixedTimeForPlugPage.tsx +14 -0
  13. package/src/modules/fixedTimeForPlug/ItemCard.tsx +3 -2
  14. package/src/modules/fixedTimingForLight/FixedTimingForLightPage.tsx +14 -0
  15. package/src/modules/fixedTimingForLight/ItemCard.tsx +3 -2
  16. package/src/modules/flags/FlagActions.ts +3 -1
  17. package/src/modules/flags/FlagPage.tsx +4 -3
  18. package/src/modules/mood_new/Interface.ts +1 -0
  19. package/src/modules/mood_new/MoodActions.ts +12 -1
  20. package/src/modules/mood_new/MoodItem.tsx +2 -1
  21. package/src/modules/mood_new/MoodPage.tsx +34 -12
  22. package/src/modules/randomTimeForPlug/ItemCard.tsx +3 -2
  23. package/src/modules/randomTimeForPlug/RandomTimeForPlugPage.tsx +14 -0
  24. package/src/modules/randomTimingForLight/RandomTimingForLightPage.tsx +14 -0
  25. package/src/modules/sleepWakeUp/SleepWakeUpPage.tsx +34 -5
  26. package/src/modules/timeSchedule/Interface.ts +19 -10
  27. package/src/modules/timeSchedule/TimeScheduleActions.ts +7 -1
  28. package/src/modules/timeSchedule/TimeScheduleDetailPage.tsx +116 -26
  29. package/src/modules/timeSchedule/TimeSchedulePage.tsx +1 -0
  30. package/src/modules/timeSchedule/components/ManuaSettings.tsx +35 -3
  31. package/src/modules/timeSchedule/components/ScheduleCard.tsx +5 -6
  32. package/src/modules/timer/TimerAction.ts +1 -1
  33. package/src/navigation/Routers.ts +3 -1
@@ -1,5 +1,10 @@
1
1
  import {useGroupEzvizConfig} from "@ledvance/base/src/models/modules/NativePropsSlice";
2
- import {getDataWithSpecified, getDpResultByHour, getDpResultByMonth} from "@ledvance/base/src/models/TuyaApi";
2
+ import {
3
+ DpResultByMonthResData,
4
+ getDataWithSpecified,
5
+ getDpResultByHour,
6
+ getDpResultByMonth
7
+ } from "@ledvance/base/src/models/TuyaApi";
3
8
  import {overDays} from "@ledvance/base/src/utils";
4
9
  import {loopsText, monthFormat, monthFormatShort} from "@ledvance/base/src/utils/common";
5
10
  import {DateType} from "@ledvance/group-ui-biz-bundle/src/modules/energyConsumption/co2Data";
@@ -9,150 +14,160 @@ import {isNumber} from "lodash";
9
14
  import {EnergyData, UnitList} from "./component/EnergyModal";
10
15
 
11
16
  interface LightConfig {
12
- energyConsumption?: EnergyData
17
+ energyConsumption?: EnergyData
13
18
  }
14
19
 
15
- export const useEnergyConsumption = () =>{
16
- return useGroupEzvizConfig<LightConfig, EnergyData>('energyConsumption', {unit: UnitList[0], price: ''})
20
+ export const useEnergyConsumption = () => {
21
+ return useGroupEzvizConfig<LightConfig, EnergyData>('energyConsumption', {unit: UnitList[0], price: ''})
17
22
  }
18
23
 
19
24
  export const unitDivision = (str: string) => {
20
- if (!str) { return ['', ''] }
21
- const strIndex = str.indexOf('(' || '')
22
- const unit = str.substring(strIndex)
23
- const name = str.split(unit)[0]
24
- return [name, unit]
25
+ if (!str) {
26
+ return ['', '']
27
+ }
28
+ const strIndex = str.indexOf('(' || '(')
29
+ const unit = str.substring(strIndex)
30
+ const name = str.split(unit)[0]
31
+ return [name, unit]
25
32
  }
26
33
 
27
34
 
28
35
  export async function getElectricity(devIdGroup: string[], addEleDpCode: string, date: string, dateType: DateType): Promise<OverviewItem[]> {
29
- let res: OverviewItem[] = []
30
- switch (dateType) {
31
- case DateType.Year:
32
- res = await getDpResultByYear(devIdGroup, addEleDpCode, date)
33
- break
34
- case DateType.Month:
35
- res = await getDpResultByYearMonth(devIdGroup, addEleDpCode, date)
36
- break
37
- case DateType.Day:
38
- res = await getDpResultByDate(devIdGroup, addEleDpCode, date);
39
- break
40
- }
41
- return res
36
+ let res: OverviewItem[] = []
37
+ switch (dateType) {
38
+ case DateType.Year:
39
+ res = await getDpResultByYear(devIdGroup, addEleDpCode, date)
40
+ break
41
+ case DateType.Month:
42
+ res = await getDpResultByYearMonth(devIdGroup, addEleDpCode, date)
43
+ break
44
+ case DateType.Day:
45
+ res = await getDpResultByDate(devIdGroup, addEleDpCode, date);
46
+ break
47
+ }
48
+ return res
42
49
  }
43
50
 
51
+ let dpResultByMonthCache: DpResultByMonthResData[] | undefined
44
52
  const getDpResultByYear = async (devIdGroup: string[], addEleDpCode: string, dateStr: string): Promise<OverviewItem[]> => {
45
- const year = dateStr;
46
- const promiseGroup = devIdGroup.map(devId =>
47
- getDpResultByMonth(devId, addEleDpCode, 'sum').catch(error => ({error}))
48
- );
49
- const res = await Promise.all(promiseGroup);
50
- // @ts-ignore
51
- const successGroup: DpResultByMonthResData[] = res.filter(v => !v.error);
52
- const mergedData = {}
53
- successGroup.forEach(item => {
54
- const monthData = item.years[year];
55
- if (monthData) {
56
- Object.keys(monthData).forEach(month => {
57
- if (mergedData[month] === undefined) {
58
- mergedData[month] = 0
59
- }
60
- const monthNum = Number(monthData[month])
61
- mergedData[month] += Number(isNumber(monthNum) ? monthNum : 0)
62
- })
53
+ const year = dateStr;
54
+ let successGroup = dpResultByMonthCache;
55
+ if (!successGroup) {
56
+ const promiseGroup = devIdGroup.map(devId =>
57
+ getDpResultByMonth(devId, addEleDpCode, 'sum').catch(error => ({error}))
58
+ );
59
+ // @ts-ignore
60
+ dpResultByMonthCache = (await Promise.all(promiseGroup)).filter(v => !v.error);
61
+ successGroup = dpResultByMonthCache
63
62
  }
64
- })
65
- const curMonthList = Object.keys(mergedData).sort((a, b) => parseInt(b) - parseInt(a));
66
- return curMonthList.map(month => {
67
- return {
68
- key: `${monthFormat(month)} ${year}`,
69
- value: (Number(mergedData[month]) || 0).toFixed(2),
70
- headlineText: `${year}${month}`,
71
- chartTitle: `${monthFormatShort(month)}\n${year}`
63
+ if (!successGroup) {
64
+ return []
72
65
  }
73
- })
66
+ // @ts-ignore
67
+ const mergedData = {}
68
+ successGroup.forEach(item => {
69
+ const monthData = item.years[year];
70
+ if (monthData) {
71
+ Object.keys(monthData).forEach(month => {
72
+ if (mergedData[month] === undefined) {
73
+ mergedData[month] = 0
74
+ }
75
+ const monthNum = Number(monthData[month])
76
+ mergedData[month] += Number(isNumber(monthNum) ? monthNum : 0)
77
+ })
78
+ }
79
+ })
80
+ const curMonthList = Object.keys(mergedData).sort((a, b) => parseInt(b) - parseInt(a));
81
+ return curMonthList.map(month => {
82
+ return {
83
+ key: `${monthFormat(month)} ${year}`,
84
+ value: (Number(mergedData[month]) || 0).toFixed(2),
85
+ headlineText: `${year}${month}`,
86
+ chartTitle: `${monthFormatShort(month)}\n${year}`
87
+ }
88
+ })
74
89
  }
75
90
 
76
91
 
77
92
  const getDpResultByYearMonth = async (deviceIdGroup: string[], addEleDpCode: string, dateStr: string): Promise<OverviewItem[]> => {
78
- const date = dayjs(dateStr)
79
- const startDay = date.startOf('month').format('YYYYMMDD')
80
- const endDay = date.endOf('month').format('YYYYMMDD')
81
- const promiseGroup = deviceIdGroup.map(devId => getDataWithSpecified(devId, addEleDpCode, startDay, endDay, 'sum').catch(error => ({error})))
82
- const res = await Promise.all(promiseGroup);
83
- // @ts-ignore
84
- const successGroup: DpResultByDataWithSpecifiedResData[] = res.filter(v => !v.error);
85
- const mergedData = {}
86
- successGroup.forEach(item => {
87
- if (item.result) {
88
- Object.keys(item.result).forEach(day => {
89
- if (mergedData[day] === undefined) {
90
- mergedData[day] = 0
93
+ const date = dayjs(dateStr)
94
+ const startDay = date.startOf('month').format('YYYYMMDD')
95
+ const endDay = date.endOf('month').format('YYYYMMDD')
96
+ const promiseGroup = deviceIdGroup.map(devId => getDataWithSpecified(devId, addEleDpCode, startDay, endDay, 'sum').catch(error => ({error})))
97
+ const res = await Promise.all(promiseGroup);
98
+ // @ts-ignore
99
+ const successGroup: DpResultByDataWithSpecifiedResData[] = res.filter(v => !v.error);
100
+ const mergedData = {}
101
+ successGroup.forEach(item => {
102
+ if (item.result) {
103
+ Object.keys(item.result).forEach(day => {
104
+ if (mergedData[day] === undefined) {
105
+ mergedData[day] = 0
106
+ }
107
+ const dayNum = Number(item.result[day])
108
+ mergedData[day] += Number(isNumber(dayNum) ? dayNum : 0)
109
+ })
91
110
  }
92
- const dayNum = Number(item.result[day])
93
- mergedData[day] += Number(isNumber(dayNum) ? dayNum : 0)
94
- })
95
- }
96
- })
97
- return Object.keys(mergedData).filter(v => Number(mergedData[v]) > 0).map(time => {
98
- // 提取年、月和日
99
- const year = time.slice(0, 4);
100
- const month = time.slice(4, 6);
101
- const day = time.slice(6, 8);
111
+ })
112
+ return Object.keys(mergedData).filter(v => Number(mergedData[v]) > 0).map(time => {
113
+ // 提取年、月和日
114
+ const year = time.slice(0, 4);
115
+ const month = time.slice(4, 6);
116
+ const day = time.slice(6, 8);
102
117
 
103
- // 格式化为 'YYYY/MM/DD' 格式
104
- const formattedDate = `${year}/${month}/${day}`
105
- const dateStr = `${day}/${month}/${year}`
106
- const dateObj = dayjs(formattedDate, "YYYY/MM/DD");
107
- const dayOfWeek = dateObj.day() % 7;
108
- const key = `${dateStr} (${loopsText[dayOfWeek]})`
109
- return {
110
- key,
111
- value: Number(mergedData[time] || 0).toFixed(2),
112
- headlineText: formattedDate,
113
- chartTitle: `${Number(key?.split('/')[0])}\n${loopsText[dayOfWeek]}`
114
- }
115
- })
118
+ // 格式化为 'YYYY/MM/DD' 格式
119
+ const formattedDate = `${year}/${month}/${day}`
120
+ const dateStr = `${day}/${month}/${year}`
121
+ const dateObj = dayjs(formattedDate, "YYYY/MM/DD");
122
+ const dayOfWeek = dateObj.day() % 7;
123
+ const key = `${dateStr} (${loopsText[dayOfWeek]})`
124
+ return {
125
+ key,
126
+ value: Number(mergedData[time] || 0).toFixed(2),
127
+ headlineText: formattedDate,
128
+ chartTitle: `${Number(key?.split('/')[0])}\n${loopsText[dayOfWeek]}`
129
+ }
130
+ })
116
131
  }
117
132
 
118
133
 
119
134
  const getDpResultByDate = async (deviceIdGroup: string[], addEleDpCode: string, date: string): Promise<OverviewItem[]> => {
120
- if (overDays(date, 7)) {
121
- console.log("getDpResultByDate overDays true")
122
- return []
123
- }
124
- const promiseGroup = deviceIdGroup.map(devId => getDpResultByHour(devId, addEleDpCode, date, 'sum').catch(error => ({error})))
125
- const res = await Promise.all(promiseGroup);
126
- // @ts-ignore
127
- const successGroup: DpResultByDataWithSpecifiedResData[] = res.filter(v => !v.error);
128
- const mergedData = {}
129
- successGroup.forEach(item => {
130
- if (item) {
131
- Object.keys(item).forEach(day => {
132
- if (mergedData[day] === undefined) {
133
- mergedData[day] = 0
134
- }
135
- const dayNum = Number(item[day])
136
- mergedData[day] += Number(isNumber(dayNum) ? dayNum : 0)
137
- })
135
+ if (overDays(date, 7)) {
136
+ console.log("getDpResultByDate overDays true")
137
+ return []
138
138
  }
139
- });
139
+ const promiseGroup = deviceIdGroup.map(devId => getDpResultByHour(devId, addEleDpCode, date, 'sum').catch(error => ({error})))
140
+ const res = await Promise.all(promiseGroup);
141
+ // @ts-ignore
142
+ const successGroup: DpResultByDataWithSpecifiedResData[] = res.filter(v => !v.error);
143
+ const mergedData = {}
144
+ successGroup.forEach(item => {
145
+ if (item) {
146
+ Object.keys(item).forEach(day => {
147
+ if (mergedData[day] === undefined) {
148
+ mergedData[day] = 0
149
+ }
150
+ const dayNum = Number(item[day])
151
+ mergedData[day] += Number(isNumber(dayNum) ? dayNum : 0)
152
+ })
153
+ }
154
+ });
140
155
 
141
156
 
142
- const list: Array<OverviewItem> = []
143
- const resData = Object.keys(mergedData)?.map(val => {
144
- return {key: Number(val?.slice(8, 10)), value: Number(mergedData[val])}
145
- })
146
- for (let i = 0; i <= 23; i++) {
147
- const hourData = resData?.find(val => val?.key === i)
148
- const hourKey = hourData?.key || i
149
- const hourValue = Number(hourData?.value) || 0
150
- list.push({
151
- key: `${hourKey.toString().padStart(2, '0')}:00`,
152
- value: hourValue,
153
- chartTitle: `${hourKey}:00`,
154
- headlineText: `${hourKey}:00`
157
+ const list: Array<OverviewItem> = []
158
+ const resData = Object.keys(mergedData)?.map(val => {
159
+ return {key: Number(val?.slice(8, 10)), value: Number(mergedData[val])}
155
160
  })
156
- }
157
- return list
161
+ for (let i = 0; i <= 23; i++) {
162
+ const hourData = resData?.find(val => val?.key === i)
163
+ const hourKey = hourData?.key || i
164
+ const hourValue = Number(hourData?.value) || 0
165
+ list.push({
166
+ key: `${hourKey.toString().padStart(2, '0')}:00`,
167
+ value: hourValue,
168
+ chartTitle: `${hourKey}:00`,
169
+ headlineText: `${hourKey}:00`
170
+ })
171
+ }
172
+ return list
158
173
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useCallback } from "react";
2
- import { Platform, View, StyleSheet, Image, Text} from "react-native";
2
+ import { Platform, View, StyleSheet, Image, 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";
@@ -18,6 +18,7 @@ import DateTypeItem from "@ledvance/group-ui-biz-bundle/src/modules/energyConsum
18
18
  import DateSelectedItem from "@ledvance/group-ui-biz-bundle/src/modules/energyConsumption/component/DateSelectedItem";
19
19
  import NewBarChart from "@ledvance/group-ui-biz-bundle/src/modules/energyConsumption/component/NewBarChart";
20
20
  import { getElectricity } from "@ledvance/group-ui-biz-bundle/src/modules/energyConsumption/EnergyConsumptionActions";
21
+ import DateSwitch from "./component/DateSwitch";
21
22
 
22
23
  const { convertX: cx, height, width } = Utils.RatioUtils
23
24
  const { withTheme } = Utils.ThemeUtils
@@ -49,6 +50,14 @@ const EnergyConsumptionChart = (props: { theme?: ThemeType }) => {
49
50
  listEmptyText: {
50
51
  flex: 0
51
52
  },
53
+ downloadIcon: {
54
+ width: cx(24),
55
+ height: cx(24),
56
+ tintColor: props.theme?.global.brand,
57
+ position: 'absolute',
58
+ right: 0,
59
+ top: cx(10)
60
+ }
52
61
  });
53
62
 
54
63
  const getDateType = useCallback((date: string) => {
@@ -87,7 +96,9 @@ const EnergyConsumptionChart = (props: { theme?: ThemeType }) => {
87
96
  getElectricity(deviceIdGroup, 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
  useUpdateEffect(() => {
@@ -127,7 +138,7 @@ const EnergyConsumptionChart = (props: { theme?: ThemeType }) => {
127
138
  }, [state.dateType, state.headlineText]);
128
139
 
129
140
  const getEmptyDataTip = useCallback(() => {
130
- if (state.over365Days) {
141
+ if (state.over365Days && state.dateType !== DateType.Day) {
131
142
  return I18n.getLang('energyconsumption_Daylimit')
132
143
  }
133
144
  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
  greeneryIcon={res.energy_consumption_greenery}
148
155
  loading={state.loading}
149
156
  headlineContent={
150
- <View style={{alignItems: 'center', justifyContent: 'center', flex: 1, marginStart: cx(24)}}>
151
- <Text style={{fontSize: cx(24), color: props.theme?.global.brand}}>{state.headlineText}</Text>
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 res from "@ledvance/base/src/res";
7
+ import dayjs from "dayjs";
8
+ import {DateType} from "../co2Data";
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
+ })
@@ -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";
@@ -29,7 +29,20 @@ const BarChartWithTouch = (props: BarChartProps) => {
29
29
  const dataPriceY = data?.map(item => {
30
30
  return ((isNaN(Number(item.value)) ? 0 : Number(item.value)) * price).toFixed(2);
31
31
  });
32
- const maxValue = Math.max(...dataKwhY);
32
+ const maxValue = useMemo(() => {
33
+ let max = Math.max(...dataKwhY)
34
+ if (max < 0.1) {
35
+ max += 0.02
36
+ max = max - (max % 0.02)
37
+ } else if (max < 1) {
38
+ max += 0.2
39
+ max = max - (max % 0.2)
40
+ } else if (max < 10) {
41
+ max = Math.ceil(max) + 2
42
+ max = max - (max % 2)
43
+ }
44
+ return max
45
+ }, [dataKwhY]);
33
46
  const option = {
34
47
  tooltip: {
35
48
  show: true,
@@ -57,7 +70,7 @@ const BarChartWithTouch = (props: BarChartProps) => {
57
70
  yAxis: [{
58
71
  type: 'value',
59
72
  name: I18n.getLang('consumption_data_annual_bar_chart_text'),
60
- max: Math.ceil(maxValue),
73
+ max: Math.max(maxValue, 0.02),
61
74
  min: 0,
62
75
  position: 'left',
63
76
  axisLabel: {
@@ -14,6 +14,7 @@ import {Utils} from "tuya-panel-kit";
14
14
  import ItemCard from "./ItemCard";
15
15
  import InfoText from "@ledvance/base/src/components/InfoText";
16
16
  import ThemeType from '@ledvance/base/src/config/themeType'
17
+ import { showDialog } from "@ledvance/base/src/utils/common";
17
18
 
18
19
  const {convertX: cx, topBarHeight} = Utils.RatioUtils;
19
20
  const { withTheme } = Utils.ThemeUtils
@@ -114,6 +115,19 @@ const FixedTimeForPlugPage = (props: { theme?: ThemeType}) => {
114
115
  onPress={() => {
115
116
  onAddOrEditItem('edit', item)
116
117
  }}
118
+ onLongPress={async () =>{
119
+ showDialog({
120
+ method: 'confirm',
121
+ title: I18n.getLang('cancel_dialog_delete_item_fixedtimecycle_titel'),
122
+ subTitle: I18n.getLang('cancel_dialog_delete_item_fixedtimecycle_description'),
123
+ onConfirm: async (_, {close}) => {
124
+ close()
125
+ state.loading = true
126
+ await onPost('del', item)
127
+ state.loading = false
128
+ }
129
+ })
130
+ }}
117
131
  />
118
132
  )}
119
133
  keyExtractor={(item: any) => `${item?.index}`}
@@ -18,10 +18,11 @@ export interface ItemCardProps {
18
18
  is24Hour?: boolean,
19
19
  onSwitch: (enable: boolean) => void
20
20
  onPress: () => void
21
+ onLongPress: () => void
21
22
  }
22
23
 
23
24
  const ItemCard = (props: ItemCardProps) => {
24
- const {item, is24Hour, onSwitch, onPress} = props
25
+ const {item, is24Hour, onSwitch, onPress, onLongPress} = props
25
26
  // 判断是否关闭
26
27
  const closed = getIsClosed(item)
27
28
 
@@ -50,7 +51,7 @@ const ItemCard = (props: ItemCardProps) => {
50
51
  })
51
52
 
52
53
  return (
53
- <Card style={styles.itemCard} onPress={onPress}>
54
+ <Card style={styles.itemCard} onPress={onPress} onLongPress={onLongPress}>
54
55
  <Spacer height={cx(16)}/>
55
56
  <View style={styles.switchLine}>
56
57
  <Text style={styles.time}>
@@ -14,6 +14,7 @@ import ItemCard from "./ItemCard";
14
14
  import {cloneDeep} from "lodash";
15
15
  import InfoText from "@ledvance/base/src/components/InfoText";
16
16
  import ThemeType from '@ledvance/base/src/config/themeType'
17
+ import { showDialog } from "@ledvance/base/src/utils/common";
17
18
 
18
19
  const {convertX: cx, topBarHeight} = Utils.RatioUtils;
19
20
  const { withTheme } = Utils.ThemeUtils
@@ -119,6 +120,19 @@ const FixedTimeForLightPage = (props: { theme?: ThemeType}) => {
119
120
  onPress={() => {
120
121
  onAddOrEditItem('edit', item)
121
122
  }}
123
+ onLongPress={async () =>{
124
+ showDialog({
125
+ method: 'confirm',
126
+ title: I18n.getLang('cancel_dialog_delete_item_fixedtimecycle_titel'),
127
+ subTitle: I18n.getLang('cancel_dialog_delete_item_fixedtimecycle_description'),
128
+ onConfirm: async (_, {close}) => {
129
+ close()
130
+ state.loading = true
131
+ await onPost('del', item)
132
+ state.loading = false
133
+ }
134
+ })
135
+ }}
122
136
  />
123
137
  )}
124
138
  keyExtractor={(item: any) => `${item?.index}`}
@@ -18,10 +18,11 @@ export interface ItemCardProps {
18
18
  is24Hour?: boolean,
19
19
  onSwitch: (enable: boolean) => void
20
20
  onPress: () => void
21
+ onLongPress: () => void
21
22
  }
22
23
 
23
24
  const ItemCard = (props: ItemCardProps) => {
24
- const {item, is24Hour, onSwitch, onPress} = props
25
+ const {item, is24Hour, onSwitch, onPress, onLongPress} = props
25
26
  // 判断是否关闭
26
27
  const closed = getIsClosed(item)
27
28
 
@@ -50,7 +51,7 @@ const ItemCard = (props: ItemCardProps) => {
50
51
  })
51
52
 
52
53
  return (
53
- <Card style={styles.itemCard} onPress={onPress}>
54
+ <Card style={styles.itemCard} onPress={onPress} onLongPress={onLongPress}>
54
55
  <Spacer height={cx(16)}/>
55
56
  <View style={styles.switchLine}>
56
57
  <Text style={styles.time}>
@@ -71,7 +71,9 @@ export const useFlag: UseFlagType = (params) => {
71
71
  const dps = {}
72
72
  const { flag } = flagData
73
73
  if (!(params.isStripLight || params.isCeilingLight)){
74
- const moodDp = obj2Dp(flag, params)
74
+ const cloneFlag = cloneDeep(flag)
75
+ cloneFlag.colors = cloneFlag.colors.reverse()
76
+ const moodDp = obj2Dp(cloneFlag, params)
75
77
  if (params.isStringLight){
76
78
  dps[getGlobalParamsDp('rgbic_linerlight_scene')] = moodDp
77
79
  }else{
@@ -49,6 +49,7 @@ const FlagPage = (props: { theme?: ThemeType }) => {
49
49
  const state = useReactive({
50
50
  loading: false,
51
51
  flags: cloneDeep(flags) as FlagUiInfo[],
52
+ filterFlags: cloneDeep(flags) as FlagUiInfo[],
52
53
  searchText: ''
53
54
  })
54
55
 
@@ -57,8 +58,8 @@ const FlagPage = (props: { theme?: ThemeType }) => {
57
58
  }, [])
58
59
 
59
60
  useUpdateEffect(() => {
60
- state.flags = state.searchText !== '' ? cloneDeep(flags).filter(flag => (flag.name ?? '').toLowerCase().includes(state.searchText.toLowerCase())) : cloneDeep(flags)
61
- }, [state.searchText, flags])
61
+ state.filterFlags = state.searchText !== '' ? cloneDeep(state.flags).filter(flag => (flag.name ?? '').toLowerCase().includes(state.searchText.toLowerCase())) : cloneDeep(state.flags)
62
+ }, [state.searchText, state.flags])
62
63
 
63
64
  const getRemoteFlagInfo = async (isRefresh?: boolean) => {
64
65
  const defNum = uaGroupInfo.groupDevices.filter(device => !(def2Pids.includes(device.tyPid) || def3Pids.includes(device.tyPid))).length
@@ -177,7 +178,7 @@ const FlagPage = (props: { theme?: ThemeType }) => {
177
178
  </TouchableOpacity>
178
179
  </View>
179
180
  <FlatList
180
- data={state.flags}
181
+ data={state.filterFlags}
181
182
  renderItem={({ item }) => <FlagItem
182
183
  enable={flagMode?.flagId === item.id && flagMode?.flagMode && switch_led}
183
184
  title={item.name}