@ledvance/ui-biz-bundle 1.1.118 → 1.1.120
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/newModules/childLock/ChildLockPage.tsx +25 -34
- package/src/newModules/diyScene/DiySceneEditorPage.tsx +2 -2
- package/src/newModules/energyConsumption/EnergyConsumptionActions.ts +33 -0
- package/src/newModules/energyConsumption/EnergyConsumptionDetail.tsx +2 -2
- package/src/newModules/energyConsumption/EnergyConsumptionPage.tsx +304 -174
- package/src/newModules/energyConsumption/component/EnergyModal.tsx +60 -19
- package/src/newModules/overchargeSwitch/OverchargeSwitchPage.tsx +25 -44
package/package.json
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import {Utils} from "tuya-panel-kit";
|
|
3
3
|
import Page from "@ledvance/base/src/components/Page";
|
|
4
4
|
import I18n from "@ledvance/base/src/i18n/index";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import { Result } from "@ledvance/base/src/models/modules/Result";
|
|
5
|
+
import {useDeviceInfo, useDp} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
6
|
+
import {useReactive} from "ahooks";
|
|
7
|
+
import {View, Text, StyleSheet, Image} from "react-native";
|
|
8
|
+
import {Result} from "@ledvance/base/src/models/modules/Result";
|
|
10
9
|
import res from "@ledvance/base/src/res";
|
|
11
|
-
import {
|
|
10
|
+
import {useParams} from "@ledvance/base/src/hooks/Hooks";
|
|
12
11
|
import ThemeType from '@ledvance/base/src/config/themeType'
|
|
12
|
+
import Card from "@ledvance/base/src/components/Card";
|
|
13
|
+
import LdvSwitch from "@ledvance/base/src/components/ldvSwitch";
|
|
13
14
|
|
|
14
|
-
const {
|
|
15
|
-
const {
|
|
15
|
+
const {convertX: cx} = Utils.RatioUtils
|
|
16
|
+
const {withTheme} = Utils.ThemeUtils
|
|
16
17
|
|
|
17
18
|
export interface ChildLockPageParams {
|
|
18
19
|
childLockCode: string
|
|
@@ -44,18 +45,6 @@ const ChildLockPage = (props: { theme?: ThemeType }) => {
|
|
|
44
45
|
marginRight: cx(5),
|
|
45
46
|
tintColor: props.theme?.global.fontColor
|
|
46
47
|
},
|
|
47
|
-
titleBGView: {
|
|
48
|
-
flexDirection: 'row',
|
|
49
|
-
alignItems: 'center',
|
|
50
|
-
paddingHorizontal: cx(16),
|
|
51
|
-
marginHorizontal: cx(24),
|
|
52
|
-
},
|
|
53
|
-
colorBlock: {
|
|
54
|
-
width: cx(20),
|
|
55
|
-
height: cx(20),
|
|
56
|
-
marginStart: cx(12),
|
|
57
|
-
borderRadius: cx(4),
|
|
58
|
-
},
|
|
59
48
|
title: {
|
|
60
49
|
color: props.theme?.global.fontColor,
|
|
61
50
|
fontSize: cx(14),
|
|
@@ -81,22 +70,24 @@ const ChildLockPage = (props: { theme?: ThemeType }) => {
|
|
|
81
70
|
headlineText={I18n.getLang('sockets_specific_settings_child_lock')}
|
|
82
71
|
loading={state.loading}>
|
|
83
72
|
<View style={styles.tipInfoContainer}>
|
|
84
|
-
<Image style={styles.image} source={res.ic_info}
|
|
85
|
-
<Text style={{
|
|
73
|
+
<Image style={styles.image} source={res.ic_info}/>
|
|
74
|
+
<Text style={{color: props.theme?.global.fontColor}}>
|
|
86
75
|
{params.descriptionText ? params.descriptionText : I18n.getLang('childlock_overview_description_text')}
|
|
87
76
|
</Text>
|
|
88
77
|
</View>
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
78
|
+
<Card style={{marginHorizontal: cx(24)}}>
|
|
79
|
+
<LdvSwitch
|
|
80
|
+
title={I18n.getLang('sockets_specific_settings_child_lock')}
|
|
81
|
+
colorAlpha={0}
|
|
82
|
+
enable={childLock}
|
|
83
|
+
setEnable={async (v: boolean) => {
|
|
84
|
+
state.loading = true
|
|
85
|
+
await setChildLock(v)
|
|
86
|
+
params.switchTriggerEvent && params.switchTriggerEvent(v)
|
|
87
|
+
state.loading = false
|
|
88
|
+
}}
|
|
89
|
+
/>
|
|
90
|
+
</Card>
|
|
100
91
|
</Page>)
|
|
101
92
|
}
|
|
102
93
|
|
|
@@ -203,9 +203,9 @@ const DiySceneEditorPage = (props: { theme?: ThemeType }) => {
|
|
|
203
203
|
state.sceneInfo.type !== 'DIY' && <TouchableOpacity onPress={() => {
|
|
204
204
|
toggleLoveScene(state.sceneInfo.id)
|
|
205
205
|
}}>
|
|
206
|
-
{isLove ? <Image source={res.like} style={{width: cx(
|
|
206
|
+
{isLove ? <Image source={res.like} style={{width: cx(30), height: cx(26)}}/>
|
|
207
207
|
: <Image source={res.un_like}
|
|
208
|
-
style={{width: cx(
|
|
208
|
+
style={{width: cx(30), height: cx(26), tintColor: props.theme?.global.fontColor}}/>}
|
|
209
209
|
</TouchableOpacity>
|
|
210
210
|
}
|
|
211
211
|
rightButtonIcon={canSaveMoodData ? res.ic_check : res.ic_uncheck}
|
|
@@ -142,3 +142,36 @@ export const exportEnergyCsv = (values: any[][], unit: string) => {
|
|
|
142
142
|
const functionName = `${I18n.getLang('consumption_data_annual_bar_chart_system_back_text')}`
|
|
143
143
|
exportCsvFile(headers, values, functionName)
|
|
144
144
|
}
|
|
145
|
+
|
|
146
|
+
const EnergyGenerationId = 'EnergyGeneration'
|
|
147
|
+
|
|
148
|
+
export interface EnergyHistory {
|
|
149
|
+
time: number
|
|
150
|
+
generationMode: boolean
|
|
151
|
+
type: 'Consumption' | 'Generation'
|
|
152
|
+
value: number
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface EnergyGeneration {
|
|
156
|
+
generationMode: boolean
|
|
157
|
+
totalElectricity: number
|
|
158
|
+
history: EnergyHistory[]
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export async function setEnergyGenerationValue(devId: string, data: EnergyGeneration) {
|
|
162
|
+
const res = await NativeApi.putJson(devId, EnergyGenerationId, JSON.stringify(data))
|
|
163
|
+
if (!res.success) {
|
|
164
|
+
console.log('setEnergyGenerationValue failed', res)
|
|
165
|
+
}
|
|
166
|
+
return res.success
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export async function getEnergyGenerationValue(devId: string): Promise<EnergyGeneration | undefined> {
|
|
170
|
+
const res = await NativeApi.getJson(devId, EnergyGenerationId)
|
|
171
|
+
if (res.success && res.data) {
|
|
172
|
+
return JSON.parse(res.data)
|
|
173
|
+
} else {
|
|
174
|
+
console.log('getEnergyGenerationValue failed', res)
|
|
175
|
+
return undefined
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -10,7 +10,7 @@ import Card from "@ledvance/base/src/components/Card";
|
|
|
10
10
|
import OverView from "./component/Overview";
|
|
11
11
|
import {useReactive, useUpdateEffect} from "ahooks";
|
|
12
12
|
import {getDataWithSpecified, getDpResultByHour} from "@ledvance/base/src/models/TuyaApi";
|
|
13
|
-
import {useDeviceId,
|
|
13
|
+
import {useDeviceId, useSolarPlug, useTimeZoneCity} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
14
14
|
import {cloneDeep, isEmpty} from "lodash";
|
|
15
15
|
import {OverviewItem, PopupType} from "./EnergyConsumptionPage";
|
|
16
16
|
import {exchangeNumber, localeNumber, loopsText} from '@ledvance/base/src/utils/common'
|
|
@@ -37,7 +37,7 @@ export interface EnergyConsumptionDetailProps {
|
|
|
37
37
|
const EnergyConsumptionDetail = (props: {theme?: ThemeType}) => {
|
|
38
38
|
const params = useRoute().params as EnergyConsumptionDetailProps
|
|
39
39
|
const devId = useDeviceId()
|
|
40
|
-
const isSolarPlug =
|
|
40
|
+
const isSolarPlug = useSolarPlug()
|
|
41
41
|
const navigation = useNavigation()
|
|
42
42
|
const timeZoneCity = useTimeZoneCity()
|
|
43
43
|
const state = useReactive({
|
|
@@ -11,10 +11,17 @@ import Card from "@ledvance/base/src/components/Card";
|
|
|
11
11
|
import OverView from "./component/Overview";
|
|
12
12
|
import { useInterval, useReactive, useUpdateEffect } from "ahooks";
|
|
13
13
|
import { getDpResultByMonth } from "@ledvance/base/src/models/TuyaApi";
|
|
14
|
-
import {useDeviceId,
|
|
14
|
+
import {useDeviceId, useSolarPlug, useTimeZoneCity} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
15
15
|
import { flattenDeep, isEmpty } from "lodash";
|
|
16
|
-
import { exchangeNumber,
|
|
17
|
-
import {
|
|
16
|
+
import { exchangeNumber, localeNumber, monthFormat, monthFormatShort, showDialog } from "@ledvance/base/src/utils/common";
|
|
17
|
+
import {
|
|
18
|
+
EnergyGeneration, EnergyHistory,
|
|
19
|
+
exportEnergyCsv, getEnergyGenerationValue, setEnergyGenerationValue,
|
|
20
|
+
updatePrice,
|
|
21
|
+
useElectricCurrent,
|
|
22
|
+
usePower,
|
|
23
|
+
useVoltage
|
|
24
|
+
} from "./EnergyConsumptionActions";
|
|
18
25
|
import {ui_biz_routerKey} from "../../navigation/Routers";
|
|
19
26
|
import { EnergyConsumptionDetailProps } from "./EnergyConsumptionDetail";
|
|
20
27
|
import { EnergyConsumptionChartProps } from "./EnergyConsumptionChart";
|
|
@@ -22,6 +29,8 @@ import EnergyPopup, { EnergyData, UnitList } from "./component/EnergyModal";
|
|
|
22
29
|
import { NativeApi, queryDpIds } from "@ledvance/base/src/api/native";
|
|
23
30
|
import { carbonDioxideEmission, countryAndRegion } from "./co2Data";
|
|
24
31
|
import ThemeType from '@ledvance/base/src/config/themeType'
|
|
32
|
+
import LdvSwitch from "@ledvance/base/src/components/ldvSwitch";
|
|
33
|
+
import dayjs from "dayjs";
|
|
25
34
|
|
|
26
35
|
const { convertX: cx } = Utils.RatioUtils
|
|
27
36
|
const { withTheme } = Utils.ThemeUtils
|
|
@@ -39,7 +48,8 @@ export interface OverviewItem {
|
|
|
39
48
|
headlineText: string
|
|
40
49
|
chartTitle: string
|
|
41
50
|
}
|
|
42
|
-
|
|
51
|
+
|
|
52
|
+
export type PopupType = 'co2' | 'money' | 'unit' | 'history' | ''
|
|
43
53
|
|
|
44
54
|
interface EnergyConsumptionState {
|
|
45
55
|
todayElectricity: string
|
|
@@ -50,6 +60,9 @@ interface EnergyConsumptionState {
|
|
|
50
60
|
showPopup: boolean
|
|
51
61
|
popupType: PopupType
|
|
52
62
|
co2Saved: string
|
|
63
|
+
loading: boolean
|
|
64
|
+
generationMode: boolean
|
|
65
|
+
energyGeneration: EnergyGeneration
|
|
53
66
|
}
|
|
54
67
|
const EnergyConsumptionPage = (props: {theme?: ThemeType}) => {
|
|
55
68
|
const params = useRoute().params as EnergyConsumptionPageProps
|
|
@@ -60,7 +73,7 @@ const EnergyConsumptionPage = (props: {theme?: ThemeType}) => {
|
|
|
60
73
|
const power = usePower(params.powerDpCode)
|
|
61
74
|
const voltage = useVoltage(params.voltageDpCode)
|
|
62
75
|
const electric = useElectricCurrent(params.electricDpCode)
|
|
63
|
-
const isSolarPlug =
|
|
76
|
+
const isSolarPlug = useSolarPlug()
|
|
64
77
|
const state = useReactive<EnergyConsumptionState>({
|
|
65
78
|
todayElectricity: '0',
|
|
66
79
|
totalElectricity: '0',
|
|
@@ -69,7 +82,14 @@ const EnergyConsumptionPage = (props: {theme?: ThemeType}) => {
|
|
|
69
82
|
unit: UnitList[0],
|
|
70
83
|
showPopup: false,
|
|
71
84
|
popupType: '',
|
|
72
|
-
co2Saved: '0'
|
|
85
|
+
co2Saved: '0',
|
|
86
|
+
loading: false,
|
|
87
|
+
generationMode: false,
|
|
88
|
+
energyGeneration: {
|
|
89
|
+
generationMode: false,
|
|
90
|
+
totalElectricity: 0,
|
|
91
|
+
history: []
|
|
92
|
+
}
|
|
73
93
|
})
|
|
74
94
|
const chartHeadline = useMemo(() => {
|
|
75
95
|
const len = state.overviewList.length
|
|
@@ -89,21 +109,74 @@ const EnergyConsumptionPage = (props: {theme?: ThemeType}) => {
|
|
|
89
109
|
useEffect(() => {
|
|
90
110
|
getElectricity().then()
|
|
91
111
|
getInitPrice().then()
|
|
112
|
+
getEnergyGeneration().then()
|
|
92
113
|
}, [])
|
|
93
114
|
|
|
115
|
+
const isGeneration = useMemo(() => {
|
|
116
|
+
// 当 isSolarPlug 和 state.generationMode 不相等时返回 true
|
|
117
|
+
return isSolarPlug !== state.generationMode
|
|
118
|
+
}, [isSolarPlug, state.generationMode])
|
|
119
|
+
|
|
120
|
+
const totalElectricity = useMemo(() => {
|
|
121
|
+
return Math.max(Number(state.totalElectricity) - (state.energyGeneration.totalElectricity || 0), 0)
|
|
122
|
+
}, [state.totalElectricity, state.energyGeneration.totalElectricity])
|
|
123
|
+
|
|
94
124
|
useUpdateEffect(() =>{
|
|
95
|
-
if(
|
|
125
|
+
if(totalElectricity > 0 && timeZoneCity){
|
|
96
126
|
const letOut = carbonDioxideEmission(timeZoneCity, countryAndRegion) || 0
|
|
97
|
-
state.co2Saved = localeNumber((letOut *
|
|
127
|
+
state.co2Saved = localeNumber((letOut * totalElectricity) / 1000, 4)
|
|
128
|
+
}
|
|
129
|
+
}, [totalElectricity, timeZoneCity])
|
|
130
|
+
|
|
131
|
+
const getEnergyGeneration = async () => {
|
|
132
|
+
const data = await getEnergyGenerationValue(devId)
|
|
133
|
+
if (data) {
|
|
134
|
+
state.energyGeneration = data
|
|
135
|
+
state.generationMode = data.generationMode
|
|
136
|
+
} else {
|
|
137
|
+
state.energyGeneration = {
|
|
138
|
+
generationMode: false,
|
|
139
|
+
totalElectricity: 0,
|
|
140
|
+
history: []
|
|
141
|
+
}
|
|
98
142
|
}
|
|
99
|
-
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const setEnergyGeneration = async (value: boolean) => {
|
|
146
|
+
state.loading = true
|
|
147
|
+
await getElectricity()
|
|
148
|
+
const time = dayjs().startOf('day').valueOf()
|
|
149
|
+
const item: EnergyHistory = {
|
|
150
|
+
time,
|
|
151
|
+
generationMode: value,
|
|
152
|
+
value: Number(state.totalElectricity) || 0,
|
|
153
|
+
type: isSolarPlug ? (value ? 'Consumption' : 'Generation') : (value ? 'Generation' : 'Consumption')
|
|
154
|
+
}
|
|
155
|
+
const data: EnergyGeneration = {
|
|
156
|
+
generationMode: value,
|
|
157
|
+
totalElectricity: Number(state.totalElectricity) || 0,
|
|
158
|
+
history: [item, ...state.energyGeneration.history]
|
|
159
|
+
}
|
|
160
|
+
const res = await setEnergyGenerationValue(devId, data)
|
|
161
|
+
if (res) {
|
|
162
|
+
state.generationMode = value
|
|
163
|
+
state.energyGeneration = data
|
|
164
|
+
} else {
|
|
165
|
+
state.generationMode = !value
|
|
166
|
+
}
|
|
167
|
+
state.loading = false
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const onceByDay = () => {
|
|
171
|
+
const currentDay = dayjs().startOf('day').valueOf()
|
|
172
|
+
return !!state.energyGeneration.history.find(item => item.time === currentDay)
|
|
173
|
+
}
|
|
100
174
|
|
|
101
175
|
const getElectricity = async () => {
|
|
102
176
|
const res = await getDpResultByMonth(devId, params.addEleDpCode, 'sum')
|
|
103
177
|
if (!isEmpty(res)) {
|
|
104
178
|
state.todayElectricity = res.thisDay
|
|
105
179
|
state.totalElectricity = res.sum
|
|
106
|
-
console.log(res, '< --- res')
|
|
107
180
|
if (!isEmpty(res.years)) {
|
|
108
181
|
const yearsList = Object.keys(res.years)
|
|
109
182
|
yearsList.sort((a, b) => parseInt(b) - parseInt(a))
|
|
@@ -142,6 +215,13 @@ const EnergyConsumptionPage = (props: {theme?: ThemeType}) => {
|
|
|
142
215
|
state.unit = data.unit
|
|
143
216
|
}
|
|
144
217
|
|
|
218
|
+
const getEnergyModeTitle = (value: boolean) => {
|
|
219
|
+
const generationTitle = I18n.getLang('switchtitle_energygeneration', 'Do you really want to switch to energy generation?')
|
|
220
|
+
const consumptionTitle = I18n.getLang('switchtitle_energyconsumption', 'Do you really want to switch to energy consumption?')
|
|
221
|
+
const titleMapping = isSolarPlug ? [consumptionTitle, generationTitle] : [generationTitle, consumptionTitle]
|
|
222
|
+
return titleMapping[value ? 0 : 1]
|
|
223
|
+
}
|
|
224
|
+
|
|
145
225
|
const styles = StyleSheet.create({
|
|
146
226
|
showTip: {
|
|
147
227
|
marginHorizontal: cx(24)
|
|
@@ -222,190 +302,240 @@ const EnergyConsumptionPage = (props: {theme?: ThemeType}) => {
|
|
|
222
302
|
|
|
223
303
|
const ConsumedEnergyItem = (props: { value: number, unit: string }) => {
|
|
224
304
|
return (
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
305
|
+
<View style={styles.subContent}>
|
|
306
|
+
<Text style={styles.valueText}>{(props.value) || 0}</Text>
|
|
307
|
+
<Spacer height={cx(4)} />
|
|
308
|
+
<Text style={styles.titleText}>
|
|
309
|
+
{unitDivision(props.unit)[0]}
|
|
310
|
+
</Text>
|
|
311
|
+
<Text style={styles.titleText}>
|
|
312
|
+
{unitDivision(props.unit)[1]}
|
|
313
|
+
</Text>
|
|
314
|
+
</View>
|
|
235
315
|
)
|
|
236
316
|
}
|
|
237
317
|
|
|
238
318
|
return (
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
319
|
+
<Page
|
|
320
|
+
style={{ position: 'relative' }}
|
|
321
|
+
backText={I18n.getLang(isGeneration ? 'sockets_headline_power' : 'consumption_data_annual_bar_chart_system_back_text')}
|
|
322
|
+
headlineText={I18n.getLang(isGeneration ? 'sockets_headline_power' : 'consumption_data_annual_bar_chart_system_back_text')}
|
|
323
|
+
headlineIcon={state.overviewList.length ? res.download_icon : undefined}
|
|
324
|
+
onHeadlineIconClick={() => {
|
|
325
|
+
const values = state.overviewList.map(item => [item.key, item.value, (Number(state.price) * Number(item.value)).toFixed(2)])
|
|
326
|
+
exportEnergyCsv(values, state.unit)
|
|
327
|
+
}}
|
|
328
|
+
showGreenery={isGeneration}
|
|
329
|
+
greeneryIcon={res.energy_consumption_greenery}
|
|
330
|
+
loading={state.loading}
|
|
331
|
+
>
|
|
332
|
+
<ScrollView nestedScrollEnabled={true}>
|
|
333
|
+
<View>
|
|
334
|
+
{/* tip */}
|
|
335
|
+
<Spacer height={cx(15)} />
|
|
336
|
+
|
|
337
|
+
<View style={styles.showTip}>
|
|
338
|
+
<Text style={{ fontSize: cx(14), color: props.theme?.global.fontColor, }}>{I18n.getLang(isGeneration ? 'generation_data_description_text' : 'consumption_data_description_text')}</Text>
|
|
339
|
+
</View>
|
|
340
|
+
<Spacer />
|
|
341
|
+
{/* Today */}
|
|
342
|
+
<Card
|
|
343
|
+
style={styles.cardContainer}
|
|
344
|
+
>
|
|
345
|
+
<Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field1_headline_text')}</Text>
|
|
254
346
|
<Spacer height={cx(15)} />
|
|
255
|
-
<View style={
|
|
256
|
-
<Text style={{ fontSize: cx(
|
|
347
|
+
<View style={{ flexDirection: 'row', alignItems: 'flex-end' }}>
|
|
348
|
+
<Text style={[styles.consumptionNum, { fontSize: cx(38), marginRight: cx(8) }]}>{localeNumber(state.todayElectricity)}</Text>
|
|
349
|
+
<Text style={[styles.consumptionNum, { fontSize: cx(22), marginBottom: cx(4) }]}>kWh</Text>
|
|
257
350
|
</View>
|
|
258
|
-
<Spacer />
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
<ConsumedEnergyItem
|
|
285
|
-
value={voltage}
|
|
286
|
-
unit={I18n.getLang('consumption_data_field2_value_text3')} />
|
|
287
|
-
</View>
|
|
288
|
-
</Card>
|
|
289
|
-
<Spacer />
|
|
290
|
-
{/* 365 day */}
|
|
291
|
-
<Card
|
|
292
|
-
style={styles.cardContainer}
|
|
293
|
-
>
|
|
351
|
+
<Spacer height={cx(10)} />
|
|
352
|
+
</Card>
|
|
353
|
+
<Spacer />
|
|
354
|
+
<Card
|
|
355
|
+
style={styles.cardContainer}
|
|
356
|
+
>
|
|
357
|
+
<Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field2_headline_text')}</Text>
|
|
358
|
+
<Spacer height={cx(15)} />
|
|
359
|
+
<View style={styles.consumedEnergyContent}>
|
|
360
|
+
<ConsumedEnergyItem
|
|
361
|
+
value={power}
|
|
362
|
+
unit={I18n.getLang('consumption_data_field2_value_text1')} />
|
|
363
|
+
<ConsumedEnergyItem
|
|
364
|
+
value={electric}
|
|
365
|
+
unit={I18n.getLang('consumption_data_field2_value_text2')} />
|
|
366
|
+
<ConsumedEnergyItem
|
|
367
|
+
value={voltage}
|
|
368
|
+
unit={I18n.getLang('consumption_data_field2_value_text3')} />
|
|
369
|
+
</View>
|
|
370
|
+
</Card>
|
|
371
|
+
<Spacer />
|
|
372
|
+
{/* 365 day */}
|
|
373
|
+
<Card
|
|
374
|
+
style={styles.cardContainer}
|
|
375
|
+
>
|
|
376
|
+
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
294
377
|
<Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field3_headline_text')}</Text>
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
378
|
+
{ state.energyGeneration.history.length > 0 && <TouchableOpacity
|
|
379
|
+
onPress={() => {
|
|
380
|
+
state.showPopup = true
|
|
381
|
+
state.popupType = 'history'
|
|
382
|
+
}}
|
|
383
|
+
>
|
|
384
|
+
<Image
|
|
385
|
+
source={res.co2Icon}
|
|
386
|
+
resizeMode="contain"
|
|
387
|
+
style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
|
|
388
|
+
/>
|
|
389
|
+
</TouchableOpacity>}
|
|
390
|
+
</View>
|
|
391
|
+
<Spacer height={cx(15)} />
|
|
392
|
+
<View style={{ flexDirection: 'row', alignItems: 'flex-end' }}>
|
|
393
|
+
<Text style={[styles.consumptionNum, { fontSize: cx(38), marginRight: cx(8) }]}>{localeNumber(totalElectricity)}</Text>
|
|
394
|
+
<Text style={[styles.consumptionNum, { fontSize: cx(22), marginBottom: cx(4) }]}>kWh</Text>
|
|
395
|
+
</View>
|
|
396
|
+
<Spacer />
|
|
397
|
+
{/* CO2 */}
|
|
398
|
+
{isGeneration && <>
|
|
303
399
|
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
304
|
-
|
|
305
|
-
<Image
|
|
306
|
-
source={res.energy_consumption_cash}
|
|
307
|
-
resizeMode="contain"
|
|
308
|
-
style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
|
|
309
|
-
/>
|
|
310
|
-
</View>
|
|
311
|
-
<View style={styles.priceNum}>
|
|
312
|
-
<View style={{ flexDirection: 'row' }}>
|
|
313
|
-
<Text style={{ color: props.theme?.global.secondFontColor, marginRight: cx(5) }}>{I18n.getLang('consumption_data_field3_co2_topic_text')}</Text>
|
|
314
|
-
<TouchableOpacity
|
|
315
|
-
onPress={() => {
|
|
316
|
-
state.showPopup = true
|
|
317
|
-
state.popupType = 'co2'
|
|
318
|
-
}}
|
|
319
|
-
>
|
|
400
|
+
<View style={styles.priceBg}>
|
|
320
401
|
<Image
|
|
321
|
-
source={res.
|
|
402
|
+
source={res.energy_consumption_cash}
|
|
322
403
|
resizeMode="contain"
|
|
323
404
|
style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
|
|
324
405
|
/>
|
|
325
|
-
</TouchableOpacity>
|
|
326
406
|
</View>
|
|
327
|
-
<
|
|
328
|
-
|
|
407
|
+
<View style={styles.priceNum}>
|
|
408
|
+
<View style={{ flexDirection: 'row' }}>
|
|
409
|
+
<Text style={{ color: props.theme?.global.secondFontColor, marginRight: cx(5) }}>{I18n.getLang('consumption_data_field3_co2_topic_text')}</Text>
|
|
410
|
+
<TouchableOpacity
|
|
411
|
+
onPress={() => {
|
|
412
|
+
state.showPopup = true
|
|
413
|
+
state.popupType = 'co2'
|
|
414
|
+
}}
|
|
415
|
+
>
|
|
416
|
+
<Image
|
|
417
|
+
source={res.co2Icon}
|
|
418
|
+
resizeMode="contain"
|
|
419
|
+
style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
|
|
420
|
+
/>
|
|
421
|
+
</TouchableOpacity>
|
|
422
|
+
</View>
|
|
423
|
+
<Text style={{ color: props.theme?.global.fontColor, fontWeight: 'bold' }}>{`${state.co2Saved} kg`}</Text>
|
|
424
|
+
</View>
|
|
329
425
|
</View>
|
|
330
426
|
<Spacer height={cx(10)} />
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
427
|
+
</>}
|
|
428
|
+
{/* money */}
|
|
429
|
+
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
430
|
+
<View style={styles.priceBg}>
|
|
431
|
+
<Image
|
|
432
|
+
source={res.energy_consumption_cash}
|
|
433
|
+
resizeMode="contain"
|
|
434
|
+
style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
|
|
435
|
+
/>
|
|
436
|
+
</View>
|
|
437
|
+
<View>
|
|
438
|
+
<View style={styles.priceNum}>
|
|
439
|
+
<Text style={{ color: props.theme?.global.secondFontColor }}>{I18n.getLang(isGeneration ? 'consumption_data_monthly_overview_field1_text2' : 'consumption_data_field3_value_text2')}</Text>
|
|
440
|
+
<Text style={{ color: props.theme?.global.fontColor, fontWeight: 'bold' }}>{state.price ? `${localeNumber(Number(state.price ) * totalElectricity, 2)} ${state.unit}` : '-'}</Text>
|
|
340
441
|
</View>
|
|
341
|
-
<
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
442
|
+
<TouchableOpacity onPress={() => {
|
|
443
|
+
state.showPopup = true
|
|
444
|
+
state.popupType = 'money'
|
|
445
|
+
}}>
|
|
446
|
+
<View style={styles.priceButton}>
|
|
447
|
+
<Text style={{ color: props.theme?.button.fontColor }}>{I18n.getLang('consumption_data_field3_button_text')}</Text>
|
|
345
448
|
</View>
|
|
346
|
-
|
|
347
|
-
state.showPopup = true
|
|
348
|
-
state.popupType = 'money'
|
|
349
|
-
}}>
|
|
350
|
-
<View style={styles.priceButton}>
|
|
351
|
-
<Text style={{ color: props.theme?.button.fontColor }}>{I18n.getLang('consumption_data_field3_button_text')}</Text>
|
|
352
|
-
</View>
|
|
353
|
-
</TouchableOpacity>
|
|
354
|
-
</View>
|
|
449
|
+
</TouchableOpacity>
|
|
355
450
|
</View>
|
|
356
|
-
</
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
popupType={state.popupType || 'co2'}
|
|
387
|
-
title={state.popupType === 'co2' ? I18n.getLang('consumption_data_field3_co2_topic_text') : ''}
|
|
388
|
-
cancelText={state.popupType === 'co2' ? '' : I18n.getLang("auto_scan_system_cancel")}
|
|
389
|
-
confirmText={I18n.getLang(state.popupType === 'co2' ? 'home_screen_home_dialog_yes_con' : 'auto_scan_system_wifi_confirm')}
|
|
390
|
-
energyData={{ price: state.price, unit: state.unit }}
|
|
391
|
-
onConfirm={(energyData) => {
|
|
392
|
-
state.popupType = ''
|
|
393
|
-
state.showPopup = false
|
|
394
|
-
if(energyData){
|
|
395
|
-
updateEnergyData({
|
|
396
|
-
...energyData,
|
|
397
|
-
price: exchangeNumber(energyData.price)
|
|
398
|
-
})
|
|
451
|
+
</View>
|
|
452
|
+
</Card>
|
|
453
|
+
<Spacer />
|
|
454
|
+
<Card style={{marginHorizontal: cx(24)}}>
|
|
455
|
+
<LdvSwitch
|
|
456
|
+
title={isSolarPlug ? I18n.getLang('plug_energyconsumptionswitch', 'Switch to energy consumption mode') : I18n.getLang('plug_energygenerationswitch', 'Switch to energy generation mode')}
|
|
457
|
+
colorAlpha={0}
|
|
458
|
+
enable={state.generationMode}
|
|
459
|
+
setEnable={async (value: boolean) => {
|
|
460
|
+
if (state.loading) {
|
|
461
|
+
return
|
|
462
|
+
}
|
|
463
|
+
if (onceByDay()) {
|
|
464
|
+
showDialog({
|
|
465
|
+
method: 'alert',
|
|
466
|
+
title: I18n.getLang('switchonlyonce', 'Switching the mode is only allowed once a day.'),
|
|
467
|
+
confirmText: I18n.getLang('home_screen_home_dialog_yes_con'),
|
|
468
|
+
onConfirm: (_, {close}) => {
|
|
469
|
+
close()
|
|
470
|
+
}
|
|
471
|
+
})
|
|
472
|
+
return
|
|
473
|
+
}
|
|
474
|
+
showDialog({
|
|
475
|
+
method: 'confirm',
|
|
476
|
+
title: getEnergyModeTitle(value),
|
|
477
|
+
subTitle: I18n.getLang('switchdescription_energy', 'Note that the total energy data will be resetted and cannot be recovered again.'),
|
|
478
|
+
onConfirm: async (_, { close }) => {
|
|
479
|
+
close()
|
|
480
|
+
await setEnergyGeneration(value)
|
|
399
481
|
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
state.popupType = ''
|
|
403
|
-
state.showPopup = false
|
|
404
|
-
}}
|
|
482
|
+
})
|
|
483
|
+
}}
|
|
405
484
|
/>
|
|
406
|
-
</
|
|
407
|
-
|
|
408
|
-
|
|
485
|
+
</Card>
|
|
486
|
+
<Spacer />
|
|
487
|
+
{/* Annual overview */}
|
|
488
|
+
{!!state.price && <OverView
|
|
489
|
+
style={{marginHorizontal: cx(24)}}
|
|
490
|
+
headlineText={I18n.getLang('consumption_data_field4_headline_text')}
|
|
491
|
+
headlineClick={() => {
|
|
492
|
+
navigation.navigate(ui_biz_routerKey.ui_biz_energy_consumption_chart, {
|
|
493
|
+
headlineText: chartHeadline,
|
|
494
|
+
chartData: state.overviewList,
|
|
495
|
+
price: state.price,
|
|
496
|
+
unit: state.unit,
|
|
497
|
+
addEleDpCode: params.addEleDpCode,
|
|
498
|
+
date: (new Date()).getFullYear().toString(),
|
|
499
|
+
} as EnergyConsumptionChartProps)
|
|
500
|
+
}}
|
|
501
|
+
overviewItemClick={(item) => {
|
|
502
|
+
navigation.navigate(ui_biz_routerKey.ui_biz_energy_consumption_detail, {
|
|
503
|
+
addEleDpCode: params.addEleDpCode,
|
|
504
|
+
curMonth: item,
|
|
505
|
+
price: state.price,
|
|
506
|
+
unit: state.unit,
|
|
507
|
+
updateEnergyData
|
|
508
|
+
} as EnergyConsumptionDetailProps)
|
|
509
|
+
}}
|
|
510
|
+
overViewList={state.overviewList}
|
|
511
|
+
/>}
|
|
512
|
+
{/* modal */}
|
|
513
|
+
<EnergyPopup
|
|
514
|
+
visible={!!(state.popupType && state.showPopup)}
|
|
515
|
+
popupType={state.popupType || 'co2'}
|
|
516
|
+
title={state.popupType === 'co2' ? I18n.getLang('consumption_data_field3_co2_topic_text') : state.popupType === 'history' ? I18n.getLang('group_energytotal') : ''}
|
|
517
|
+
cancelText={['co2', 'history'].includes(state.popupType) ? '' : I18n.getLang("auto_scan_system_cancel")}
|
|
518
|
+
confirmText={I18n.getLang(['co2', 'history'].includes(state.popupType) ? 'home_screen_home_dialog_yes_con' : 'auto_scan_system_wifi_confirm')}
|
|
519
|
+
energyData={{ price: state.price, unit: state.unit }}
|
|
520
|
+
energyHistory={state.energyGeneration.history}
|
|
521
|
+
onConfirm={(energyData) => {
|
|
522
|
+
state.popupType = ''
|
|
523
|
+
state.showPopup = false
|
|
524
|
+
if(energyData){
|
|
525
|
+
updateEnergyData({
|
|
526
|
+
...energyData,
|
|
527
|
+
price: exchangeNumber(energyData.price)
|
|
528
|
+
})
|
|
529
|
+
}
|
|
530
|
+
}}
|
|
531
|
+
onCancel={() => {
|
|
532
|
+
state.popupType = ''
|
|
533
|
+
state.showPopup = false
|
|
534
|
+
}}
|
|
535
|
+
/>
|
|
536
|
+
</View>
|
|
537
|
+
</ScrollView>
|
|
538
|
+
</Page>
|
|
409
539
|
)
|
|
410
540
|
}
|
|
411
541
|
|
|
@@ -9,6 +9,8 @@ import { Utils, Modal, Popup } from "tuya-panel-kit";
|
|
|
9
9
|
import { useReactive, useUpdateEffect } from "ahooks";
|
|
10
10
|
import { cloneDeep } from "lodash";
|
|
11
11
|
import ThemeType from '@ledvance/base/src/config/themeType'
|
|
12
|
+
import dayjs from "dayjs";
|
|
13
|
+
import {EnergyHistory} from "../EnergyConsumptionActions";
|
|
12
14
|
|
|
13
15
|
const { convertX: cx, height } = Utils.RatioUtils
|
|
14
16
|
const { withTheme } = Utils.ThemeUtils
|
|
@@ -33,14 +35,16 @@ export interface EnergyData {
|
|
|
33
35
|
price: string
|
|
34
36
|
unit: string
|
|
35
37
|
}
|
|
38
|
+
|
|
36
39
|
interface EnergyModalProps {
|
|
37
40
|
theme?: ThemeType
|
|
38
41
|
visible: boolean
|
|
39
|
-
popupType: 'money' | 'co2' | 'unit'
|
|
42
|
+
popupType: 'money' | 'co2' | 'unit' | 'history'
|
|
40
43
|
title: string
|
|
41
44
|
confirmText?: string
|
|
42
45
|
cancelText?: string
|
|
43
46
|
energyData?: EnergyData
|
|
47
|
+
energyHistory?: EnergyHistory[]
|
|
44
48
|
motionType?: 'none'
|
|
45
49
|
onConfirm?: (data?: EnergyData) => void
|
|
46
50
|
onCancel?: () => void
|
|
@@ -51,29 +55,49 @@ const EnergyModal = (props: EnergyModalProps) => {
|
|
|
51
55
|
unitPopup: false
|
|
52
56
|
})
|
|
53
57
|
|
|
54
|
-
|
|
55
58
|
const openLink = (url: string) => {
|
|
56
59
|
Linking.openURL(url).catch((error) => console.error('无法打开链接:', error));
|
|
57
60
|
};
|
|
58
61
|
|
|
59
62
|
const getDescription = (string: string) => {
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
// 首先提取URL
|
|
64
|
+
const urlRegex = /(https?:\/\/[^\s]+)$/;
|
|
65
|
+
const urlMatch = string.match(urlRegex);
|
|
66
|
+
const url = urlMatch ? urlMatch[0] : '';
|
|
67
|
+
|
|
68
|
+
// 移除URL部分以处理正文文本
|
|
69
|
+
const textWithoutUrl = urlMatch
|
|
70
|
+
? string.slice(0, string.lastIndexOf(url)).trim()
|
|
71
|
+
: string;
|
|
72
|
+
|
|
73
|
+
// 分割文本但保留分隔符
|
|
74
|
+
const sentences:string[] = [];
|
|
75
|
+
const parts = textWithoutUrl.split(/([.:])/);
|
|
76
|
+
|
|
77
|
+
for (let i = 0; i < parts.length - 1; i += 2) {
|
|
78
|
+
if (i + 1 < parts.length) {
|
|
79
|
+
sentences.push(parts[i] + parts[i + 1]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<View>
|
|
85
|
+
{sentences.map((sentence, index) => (
|
|
86
|
+
<View key={index}>
|
|
87
|
+
<Text style={{ color: props.theme?.global.fontColor }}>{sentence.trim()}</Text>
|
|
88
|
+
<Spacer />
|
|
89
|
+
</View>
|
|
90
|
+
))}
|
|
91
|
+
{url && (
|
|
92
|
+
<Text
|
|
93
|
+
style={{ textDecorationLine: 'underline', color: props.theme?.button.primary }}
|
|
94
|
+
onPress={() => openLink(url)}
|
|
95
|
+
>
|
|
96
|
+
{url}
|
|
97
|
+
</Text>
|
|
98
|
+
)}
|
|
99
|
+
</View>
|
|
100
|
+
);
|
|
77
101
|
}
|
|
78
102
|
|
|
79
103
|
useUpdateEffect(() =>{
|
|
@@ -196,6 +220,23 @@ const EnergyModal = (props: EnergyModalProps) => {
|
|
|
196
220
|
</Card>
|
|
197
221
|
</View>
|
|
198
222
|
)
|
|
223
|
+
} else if (props.popupType === 'history') {
|
|
224
|
+
return (
|
|
225
|
+
<View>
|
|
226
|
+
<Spacer />
|
|
227
|
+
<Text style={styles.popupTip}>{I18n.getLang('infobutton_totalenergy', 'The total energy shows only the total consumption/generation data after the last reset.\n' +
|
|
228
|
+
'The data was switched on the following days:')}</Text>
|
|
229
|
+
<Spacer height={cx(20)} />
|
|
230
|
+
{
|
|
231
|
+
props.energyHistory?.map((item) => (
|
|
232
|
+
<View key={item.time} style={{ backgroundColor: props.theme?.card.background, alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', }}>
|
|
233
|
+
<Text style={{color: props.theme?.global.fontColor}}>{dayjs(item.time).format('DD/MM/YYYY')}</Text>
|
|
234
|
+
<Text style={{color: props.theme?.global.fontColor}}>{item.type === 'Generation' ? I18n.getLang('plug_energygenerationswitch', 'Switch to energy generation mode') : I18n.getLang('plug_energyconsumptionswitch', 'Switch to energy consumption mode')}</Text>
|
|
235
|
+
</View>
|
|
236
|
+
))
|
|
237
|
+
}
|
|
238
|
+
</View>
|
|
239
|
+
)
|
|
199
240
|
} else {
|
|
200
241
|
return (
|
|
201
242
|
<View>
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import {Utils} from "tuya-panel-kit";
|
|
3
3
|
import Page from "@ledvance/base/src/components/Page";
|
|
4
4
|
import I18n from "@ledvance/base/src/i18n/index";
|
|
5
5
|
import {useDeviceInfo, useDp} from "@ledvance/base/src/models/modules/NativePropsSlice";
|
|
6
6
|
import {useReactive} from "ahooks";
|
|
7
7
|
import Spacer from "@ledvance/base/src/components/Spacer";
|
|
8
|
-
import {StyleSheet, Text
|
|
8
|
+
import {StyleSheet, Text} from "react-native";
|
|
9
9
|
import {Result} from "@ledvance/base/src/models/modules/Result";
|
|
10
10
|
import {useParams} from "@ledvance/base/src/hooks/Hooks";
|
|
11
11
|
import ThemeType from '@ledvance/base/src/config/themeType'
|
|
12
|
+
import Card from "@ledvance/base/src/components/Card";
|
|
13
|
+
import LdvSwitch from "@ledvance/base/src/components/ldvSwitch";
|
|
12
14
|
|
|
13
|
-
const {
|
|
14
|
-
const {
|
|
15
|
+
const {convertX: cx} = Utils.RatioUtils
|
|
16
|
+
const {withTheme} = Utils.ThemeUtils
|
|
15
17
|
|
|
16
18
|
export interface OverchargeSwitchPageParams {
|
|
17
19
|
overchargeSwitchCode: string
|
|
@@ -30,55 +32,34 @@ const OverchargeSwitchPage = (props: { theme?: ThemeType }) => {
|
|
|
30
32
|
})
|
|
31
33
|
|
|
32
34
|
const styles = StyleSheet.create({
|
|
33
|
-
titleBGView: {
|
|
34
|
-
flexDirection: 'row',
|
|
35
|
-
alignItems: 'center',
|
|
36
|
-
paddingHorizontal: cx(16),
|
|
37
|
-
marginHorizontal: cx(24),
|
|
38
|
-
marginTop: cx(30)
|
|
39
|
-
},
|
|
40
35
|
title: {
|
|
41
36
|
color: props.theme?.global.fontColor,
|
|
42
|
-
fontSize: cx(
|
|
37
|
+
fontSize: cx(16),
|
|
38
|
+
fontWeight: 'bold',
|
|
43
39
|
fontFamily: 'helvetica_neue_lt_std_bd',
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
desc: {
|
|
47
|
-
color: props.theme?.global.fontColor,
|
|
48
|
-
},
|
|
49
|
-
shadow: {
|
|
50
|
-
shadowColor: props.theme?.card.shadowColor,
|
|
51
|
-
shadowOpacity: 0.2,
|
|
52
|
-
shadowRadius: 8,
|
|
53
|
-
elevation:8,
|
|
54
|
-
shadowOffset: {
|
|
55
|
-
width: 0,
|
|
56
|
-
height: 4,
|
|
57
|
-
},
|
|
58
|
-
backgroundColor: props.theme?.card.background,
|
|
59
|
-
borderRadius: 8,
|
|
40
|
+
paddingTop: cx(16),
|
|
41
|
+
paddingHorizontal: cx(16),
|
|
60
42
|
},
|
|
61
43
|
})
|
|
62
44
|
|
|
63
45
|
return (<Page
|
|
64
46
|
backText={devInfo.name}
|
|
65
47
|
loading={state.loading}>
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
</View>
|
|
48
|
+
<Spacer height={cx(24)}/>
|
|
49
|
+
<Card style={{marginHorizontal: cx(24)}}>
|
|
50
|
+
<Text style={styles.title}>{I18n.getLang('switch_overcharge_headline_text')}</Text>
|
|
51
|
+
<LdvSwitch
|
|
52
|
+
title={I18n.getLang('switch_overcharge_headline_description')}
|
|
53
|
+
titleStyle={{fontWeight: 'normal', fontSize: cx(14)}}
|
|
54
|
+
colorAlpha={1}
|
|
55
|
+
enable={overchargeSwitch}
|
|
56
|
+
setEnable={async (v) => {
|
|
57
|
+
state.loading = true
|
|
58
|
+
await setOverchargeSwitch(v)
|
|
59
|
+
state.loading = false
|
|
60
|
+
}}
|
|
61
|
+
/>
|
|
62
|
+
</Card>
|
|
82
63
|
</Page>)
|
|
83
64
|
}
|
|
84
65
|
|