| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- /**
- * 充电中的页面组件
- * @邠心vbe on 2021/04/13
- */
- import React, { useRef, useEffect, useState } from 'react';
- import { Animated, View, Easing, StyleSheet, Image, Text, ImageBackground, TextInput } from 'react-native';
- import { RadialGradient } from 'react-native-gradients';
- import Modal from 'react-native-modal';
- import { ModalProps } from '../../components/BottomModal';
- import ChargeItemSelect from '../../icons/ChargeItemSelect';
- import { DialogMaxWidth } from './InfoDialog';
- import { QRResult } from './QRScan';
- export const circleSize = $vw(50.66) < 300 ? $vw(50.66) : 300;
- const batterySize = 0.463 * circleSize;
- const batteryWidth = 0.659*batterySize;
- export const TypeImage = {
- AC: require('../../images/charge/ic-type-ac.png'),
- DC: require('../../images/charge/ic-type-dc.png'),
- CHADEMO: require('../../images/charge/ic-type-chademo.png')
- }
- export const TypeImageList = [
- {
- name: 'AC',
- key: 'AC',
- icon: require('../../images/charge/ic-type-ac.png')
- }, {
- name: 'DC',
- key: 'DC',
- icon: require('../../images/charge/ic-type-dc.png')
- }, /*{
- name: 'Chademo',
- key: 'CHADEMO',
- icon: require('../../images/charge/ic-type-chademo.png')
- }*/
- ]
- export const getConnectTypeByKey = (key) => {
- for (let item of TypeImageList) {
- if (item.key == key) {
- return item;
- }
- }
- }
- export const CircleAnimate = ({isStart = false}) => {
- var rotate = useRef(new Animated.Value(0)).current;
- const spins = () => {
- Animated.timing(rotate, {
- toValue: 1,
- duration: 10000,
- easing: Easing.linear,
- useNativeDriver: true
- }).start(() => {
- rotate.setValue(0);
- spins();
- });
- }
- useEffect(() => {
- if (isStart) {
- spins();
- }
- }, [rotate]);
- const spin = rotate.interpolate({
- inputRange: [0, 1],
- outputRange: ['0deg', '360deg']
- })
- return (
- <Animated.View
- style={[
- styles.chargeCircle, {
- transform: [{
- rotate: spin
- }]
- }
- ]}>
- { isStart &&
- <View style={{ width: 25, height: 25, marginTop: -11}}>
- <RadialGradient
- x="50%" y="50%" rx="50%" ry="50%"
- colorList={[
- {offset: '0%', color: '#FFF', opacity: .8},
- {offset: '40%', color: '#FFF', opacity: .5},
- {offset: '70%', color: '#FFF', opacity: .3},
- {offset: '100%', color: '#FFF',opacity: 0}
- ]}/>
- </View>
- }
- </Animated.View>
- );
- }
- export const BatteryView = ({soc, isPending, isCharging}) => {
- var [powerPercent, setPercent] = useState(-1);
- /*var [powerText, setText] = useState(0);
- const autoCharge = () => {
- setTimeout(() => {
- const p = powerPercent + 0.001
- setPercent(Number(p.toFixed(4)))
- setText((powerPercent * 100).toFixed(0))
- if (powerPercent >= 1) {
- onComplete();
- }
- }, 50 + powerPercent * 100);
- }
- useEffect(() => {
- if (run && powerPercent <= 1) {
- autoCharge();
- }
- }, [powerPercent])*/
- useEffect(() => {
- if (isCharging) {
- try {
- var s = '-1' + soc;
- var d = '' + parseInt(s);
- d = d.replace('-1', '');
- if (d) {
- setPercent(parseInt(d))
- } else {
- setPercent(-1);
- }
- } catch (e) {
- setPercent(-1);
- }
- }
- }, [soc]);
- const getOpacity = (unit) => {
- var op = 1 * (powerPercent + unit);
- return op < 1 ? op : 1;
- }
- const getHeight = () => {
- if (powerPercent > 1) {
- return batterySize * powerPercent / 100;
- } else if (powerPercent > 0) {
- return batterySize * powerPercent;
- } else {
- return 0
- }
- }
- return (
- isCharging
- ? <View style={ui.center}>
- <ImageBackground
- style={{
- width: circleSize,
- height: circleSize,
- margin: 32,
- padding: 32,
- alignItems: 'center',
- justifyContent: 'center'
- }}
- source={require('../../images/charge/ic-charge-circle.png')}>
- <View style={styles.chargingView}>
- <View style={styles.plusLeftView}>
- <Image
- style={[styles.plusMiddle, { opacity: getOpacity(0.5)}]}
- source={require('../../images/charge/ic-plus-middle.png')}/>
- <Image
- style={[styles.plusSmall, { opacity: getOpacity(0.4)}]}
- source={require('../../images/charge/ic-plus-small.png')}/>
- </View>
- <View style={styles.batteryView}>
- <View style={[styles.batteryIcon]}>
- <Image
- style={styles.batteryIcon}
- source={require('../../images/charge/ic-battery-0.png')}/>
- <View style={[styles.batteryLayer, { height: getHeight() }]}>
- <Image
- style={[styles.batteryIcon]}
- source={require('../../images/charge/ic-battery-1.png')}/>
- </View>
- </View>
- { isPending
- ? <Text style={styles.batterySoc}>Initiating...</Text>
- : powerPercent != -1
- ? <Text style={styles.batteryPercent}>{powerPercent}%</Text>
- : <Text style={styles.batterySoc}>{'In Charging'}</Text>
- }
- </View>
- <View style={styles.plusRightView}>
- <Image
- style={[styles.plusLarge, { opacity: getOpacity(0.6)}]}
- source={require('../../images/charge/ic-plus-large.png')}/>
- </View>
- </View>
- <CircleAnimate isStart={true}/>
- </ImageBackground>
- </View>
- : <View style={styles.completeView}>
- <Image
- style={styles.disconnectIcon}
- source={require('../../images/charge/charge-complete.png')}/>
- <Text style={styles.completeTip}>Please disconnect and return connector to charging station</Text>
- </View>
- );
- }
- export const EnterStationDialog = ({visible, stationId, onConfirm, onClose}) => {
- var [inputStationId, setInput] = useState('')
- const enterStatioinId= () => {
- console.log(inputStationId);
- if (inputStationId) {
- QRResult.applyInputStation(inputStationId, stationId, (success, err) => {
- setInput('')
- if (success) {
- if (onConfirm) onConfirm()
- } else if (err) {
- toastShort(err)
- }
- if (onClose) onClose()
- });
- } else {
- toastShort('Please input Station ID')
- }
- }
- return (
- <Modal
- isVisible={visible}
- {...ModalProps}
- onBackdropPress={() => onClose}
- onBackButtonPress={() => onClose}>
- <View style={styles.stationDialog}>
- <Text style={styles.stationInputTitle}>Enter Station ID</Text>
- <TextInput
- style={styles.stationInput}
- defaultValue={inputStationId}
- placeholder='e.g: EVCTD0002-1'
- onChangeText={text => setInput(text)}
- />
- <View style={styles.dialogButtons}>
- <Button
- textSize={17}
- style={styles.buttonCancel}
- text='Close'
- onClick={onClose}/>
- <Button
- textSize={17}
- style={styles.buttonOK}
- text='Confirm'
- onClick={() => enterStatioinId()}/>
- </View>
- </View>
- </Modal>
- )
- }
- const styles = StyleSheet.create({
- chargingView: {
- width: circleSize,
- height: circleSize,
- flexDirection: 'row',
- alignItems: 'center'
- },
- chargeCircle: {
- top: 0,
- left: 0,
- zIndex: 10,
- width: circleSize,
- height: circleSize,
- position: 'absolute',
- alignItems: 'center',
- borderRadius: circleSize
- },
- batteryView: {
- paddingTop: 8,
- paddingLeft: 12,
- paddingRight: 12,
- alignItems: 'center',
- justifyContent: 'center'
- },
- batteryIcon: {
- width: batteryWidth,
- height: batterySize,
- position: 'relative',
- justifyContent: 'flex-end',
- },
- batteryLayer: {
- left: 0,
- right: 0,
- height: 0,
- width: batteryWidth,
- overflow: 'hidden',
- position: 'absolute',
- justifyContent: 'flex-end',
- },
- batteryPercent: {
- color: '#333',
- fontSize: 22,
- textAlign: 'center',
- paddingTop: 10,
- paddingBottom: 8
- },
- batterySoc: {
- color: '#333',
- fontSize: 18,
- textAlign: 'center',
- paddingTop: 10,
- paddingBottom: 10
- },
- plusLeftView: {
- flex: 1,
- height: batterySize + 10,
- marginBottom: 12,
- alignItems: 'flex-end',
- justifyContent: 'space-around'
- },
- plusRightView: {
- flex: 1,
- justifyContent: 'center'
- },
- plusLarge: {
- width: 24,
- height: 24
- },
- plusMiddle: {
- width: 18,
- height: 18
- },
- plusSmall: {
- width: 12,
- height: 12,
- marginBottom: 8
- },
- selectView: {
- position: 'relative'
- },
- selectIcon: {
- width: 18,
- height: 18
- },
- selectIconAbs: {
- top: -2,
- right: -4,
- zIndex: 2,
- position: 'absolute'
- },
- completeView: {
- height: circleSize,
- marginBottom: 16,
- alignItems: 'center',
- justifyContent: 'center'
- },
- disconnectIcon: {
- width: 100,
- height: 100
- },
- completeTip: {
- width: circleSize,
- color: '#333',
- fontSize: 16,
- paddingLeft: 16,
- paddingRight: 16,
- textAlign: 'center'
- },
- stationDialog: {
- padding: 16,
- marginLeft: 'auto',
- marginRight: 'auto',
- borderRadius: isIOS ? 20 : 3,
- width: DialogMaxWidth,
- backgroundColor: 'white'
- },
- stationInput: {
- ...$padding(4, 10),
- minHeight: 40,
- borderRadius: 3,
- backgroundColor: '#F0F0F0'
- },
- stationInputTitle: {
- fontSize: 15,
- textAlign: 'center',
- paddingBottom: 16
- },
- dialogButtons: {
- paddingTop: 16,
- paddingBottom: 8,
- flexDirection: 'row'
- },
- buttonOK: {
- flex: 1,
- marginLeft: 4,
- },
- buttonCancel: {
- flex: 1,
- backgroundColor: '#eee'
- }
- });
- export const SelectableIcon = ({selected, children}) => {
- return (
- <View style={styles.selectView}>
- {selected &&
- <View style={[styles.selectIcon, children && styles.selectIconAbs]}>
- <ChargeItemSelect size={18} selected={true}/>
- </View>
- }
- {children}
- </View>
- );
- }
- export const ChargeStyle = StyleSheet.create({
- stationInfoView: {
- padding: 8,
- alignItems: 'center',
- flexDirection: 'row',
- justifyContent: 'space-between'
- },
- infoGroup: {
- ...$padding(4, 8),
- alignItems: 'center'
- },
- infoTitle: {
- color: '#999',
- fontSize: 12
- },
- infoText: {
- color: '#333',
- fontSize: 12,
- paddingTop: 4
- },
- infoBoldNumber: {
- color: '#333',
- fontSize: 14,
- paddingTop: 3,
- fontWeight: 'bold'
- },
- infoStatus: {
- fontSize: 12,
- borderRadius: 4,
- ...$padding(4, 10)
- },
- infoIcon: {
- width: 38,
- height: 38
- },
- itemDivide: {
- borderTopWidth: 1,
- borderTopColor: '#eee'
- },
- statusSelected: {
- color: '#333',
- ...$padding(4, 11),
- backgroundColor: colorAccent
- },
- statusAvailable: {
- color: 'white',
- backgroundColor: '#90DB0A'
- },
- statusUnavailable: {
- color: '#999',
- fontSize: 10,
- ...$padding(5, 8),
- backgroundColor: '#CCC'
- },
- statusWarning: {
- color: 'white',
- backgroundColor: colorAccent
- },
- rateText: {
- color: '#333',
- fontSize: 14,
- },
- ratePrice: {
- color: '#000',
- fontSize: 14,
- },
- authText: {
- color: '#000',
- fontSize: 12,
- paddingTop: 2
- }
- });
|