UNPKG

tuya-panel-kit

Version:

a functional component library for developing tuya device panels!

292 lines (278 loc) 8.41 kB
import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { ColorPropType, StyleSheet, Animated, ViewPropTypes, View, TouchableOpacity, Platform, Text, Image, Easing, } from 'react-native'; import { TYSdk } from '../../../TYNativeApi'; import Motion from '../../motion'; import RefText from '../../TYText'; import Strings from '../../i18n/strings'; import { RatioUtils, CoreUtils } from '../../../utils'; import IconFont from '../../iconfont/svg'; const { convert, winWidth, isIos, isIphoneX } = RatioUtils; const { get } = CoreUtils; const TYNative = TYSdk.native; export default class NewOfflineView extends PureComponent { static propTypes = { maskColor: ColorPropType, onClose: PropTypes.func, style: ViewPropTypes.style, animatedStyle: ViewPropTypes.style, showDeviceImg: PropTypes.bool, show: PropTypes.bool, onLinkPress: PropTypes.func, onHelpPress: PropTypes.func, /** * @description 判断App RN版本是否为3.21及以上,符合条件才可跳转至配网页面 */ isJumpToWifi: PropTypes.bool, // wifi 离线的时候用户不想要重新连接跳转 reconnectTextStyle: Text.propTypes.style, /** * 判断App RN版本是否为3.34.5及以上离线才能跳转知识库页面 */ isAllowJumpTo: PropTypes.bool, }; static defaultProps = { maskColor: 'rgba(0, 0, 0, 0.8)', onClose: null, style: null, animatedStyle: null, showDeviceImg: true, show: true, onLinkPress: () => {}, onHelpPress: () => {}, isJumpToWifi: false, reconnectTextStyle: null, }; constructor(props) { super(props); this.state = { value: new Animated.Value(0), show: props.show, }; } componentDidMount() { this.show(); } componentWillReceiveProps(nextProps) { if (this.props.show !== nextProps.show) { this.setState({ show: nextProps.show, }); } } show = () => { Animated.spring(this.state.value, { toValue: 1, useNativeDriver: true, showDuration: 250, easing: Easing.bezier(0, 0, 0.25, 1), }).start(); }; hide = () => { Animated.spring(this.state.value, { toValue: 0, useNativeDriver: true, hideDuration: 250, easing: Easing.bezier(0.42, 0, 1, 1), }).start(() => { typeof this.props.onClose === 'function' && this.props.onClose(); }); }; cropString = (str, newStrArr) => { if (!str) return; if (str.indexOf('\n') !== -1) { const idx = str.indexOf('\n'); const indexBefore = str.substring(0, idx); newStrArr.push(indexBefore); const strAfter = str.substring(idx + 1); this.cropString(strAfter, newStrArr); } else { newStrArr.push(str); } return newStrArr; }; render() { const { maskColor, style, animatedStyle, showDeviceImg, onLinkPress, onHelpPress, isJumpToWifi, reconnectTextStyle, isAllowJumpTo, } = this.props; const { value, show } = this.state; const textLineBefore = Strings.getLang('offline_textLinkBefore'); const textLink = Strings.getLang('offline_link'); const textLineAfter = Strings.getLang('offline_textLinkAfter'); const textLineMore = Strings.getLang('offline_textLinkMore'); const linkBeforeArr = this.cropString(textLineBefore, []); const imgUrl = Platform.OS === 'ios' ? get(TYSdk, 'devInfo.iconUrl') : get(TYSdk, 'devInfo.icon'); const topBarMoreIconName = get(TYSdk, 'devInfo.panelConfig.fun.topBarMoreIconName', 'pen'); return ( <View style={[show && styles.modal, style]}> <Animated.View style={[show && StyleSheet.absoluteFill, { backgroundColor: maskColor, opacity: value }]} /> <Motion.ScaleFadeIn show={show} style={{ flex: 1 }}> <Animated.View style={[{ opacity: this.state.value }, animatedStyle]}> <View style={[ styles.oldOfflineWrapper, { paddingTop: showDeviceImg && !!imgUrl ? convert(24) : convert(32), }, ]} > {showDeviceImg && !!imgUrl && ( <Image source={{ uri: imgUrl }} style={{ width: convert(95), height: convert(95) }} /> )} <RefText style={styles.offlineTitle}> {Strings.getLang('offline_alreadyOffline')} </RefText> <View style={{ paddingBottom: convert(32) }}> <RefText style={[styles.firstLine, { color: '#333', marginBottom: convert(8) }]}> {Strings.getLang('offline_pleaseCheck')} </RefText> {linkBeforeArr && linkBeforeArr.length && linkBeforeArr.map( item => !!item && <RefText key={item} style={styles.firstLine} text={item} /> )} {!!textLink && ( <View style={{ flexDirection: 'row' }}> <RefText style={styles.firstLine}> {Strings.getLang('offline_linkFront')} <Text style={[ styles.firstLine, isJumpToWifi && { color: '#FF4800', textDecorationLine: 'underline', }, reconnectTextStyle, ]} onPress={onLinkPress} > {textLink} </Text> </RefText> </View> )} {!!textLineAfter && ( <RefText style={[styles.firstLine, { marginBottom: 0 }]} text={textLineAfter} /> )} </View> {(isAllowJumpTo || !!textLineMore) && ( <TouchableOpacity style={styles.confirmTouchable} activeOpacity={0.8} onPress={onHelpPress} > <RefText style={styles.confirmText}> {Strings.getLang('offline_moreHelp')} </RefText> </TouchableOpacity> )} </View> </Animated.View> </Motion.ScaleFadeIn> <TouchableOpacity style={styles.circleBlack} activeOpacity={0.8} onPress={() => TYNative.back()} > <IconFont name="backIos" color="#fff" size={18} /> </TouchableOpacity> <TouchableOpacity style={styles.moreBlack} activeOpacity={0.8} onPress={() => TYNative.showDeviceMenu()} > <IconFont name={topBarMoreIconName} color="#fff" size={18} /> </TouchableOpacity> </View> ); } } const styles = StyleSheet.create({ modal: { position: 'absolute', top: 0, bottom: 0, left: 0, right: 0, zIndex: 10000, }, circleBlack: { width: convert(36), height: convert(36), borderRadius: convert(18), backgroundColor: '#000', position: 'absolute', top: isIos ? (isIphoneX ? 44 : 20) : 10, left: convert(6), justifyContent: 'center', paddingLeft: convert(9), }, firstLine: { fontSize: 12, color: '#999', marginBottom: 7, }, oldOfflineWrapper: { backgroundColor: '#fff', borderRadius: 16, paddingHorizontal: convert(20), justifyContent: 'center', alignItems: 'center', width: winWidth - convert(32), }, offlineTitle: { fontSize: 17, fontWeight: 'bold', marginBottom: 32, marginTop: 8, color: '#000', }, confirmTouchable: { justifyContent: 'center', alignItems: 'center', height: convert(54), width: winWidth - convert(32), borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: '#E5E5E5', }, confirmText: { fontSize: 16, color: '#FF4800', }, moreBlack: { width: convert(36), height: convert(36), borderRadius: convert(18), backgroundColor: '#000', position: 'absolute', top: isIos ? (isIphoneX ? 44 : 20) : 10, right: convert(6), justifyContent: 'center', alignItems: 'center', }, });