|
@@ -0,0 +1,363 @@
|
|
|
|
|
+/**
|
|
|
|
|
+ * 活动详情
|
|
|
|
|
+ * @邠心vbe on 2023/08/17
|
|
|
|
|
+ */
|
|
|
|
|
+import React, { Component } from 'react';
|
|
|
|
|
+import { View, StyleSheet, Image, ScrollView, Linking, Animated, Easing } from 'react-native';
|
|
|
|
|
+import Swiper from 'react-native-swiper';
|
|
|
|
|
+import apiArticle from '../../api/apiArticle';
|
|
|
|
|
+import TextView from '../../components/TextView';
|
|
|
|
|
+import VbeSkeleton from '../../components/VbeSkeleton';
|
|
|
|
|
+import utils from '../../utils/utils';
|
|
|
|
|
+import { PagerView } from './ViewUtil';
|
|
|
|
|
+import MyStatusBar from '../../components/MyStatusBar';
|
|
|
|
|
+import Toolbar, { BackButton } from '../../components/Toolbar';
|
|
|
|
|
+
|
|
|
|
|
+export default class ViewCampaign extends Component {
|
|
|
|
|
+ constructor(props) {
|
|
|
|
|
+ super(props);
|
|
|
|
|
+ this.state = {
|
|
|
|
|
+ id: "",
|
|
|
|
|
+ loading: true,
|
|
|
|
|
+ showTitleBar: false,
|
|
|
|
|
+ messageInfo: {
|
|
|
|
|
+ articleTypeName: "",
|
|
|
|
|
+ articleTitle: "",
|
|
|
|
|
+ articleContent: ""
|
|
|
|
|
+ },
|
|
|
|
|
+ opacity: new Animated.Value(0)
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ componentDidMount() {
|
|
|
|
|
+ if (this.props.route?.params?.id) {
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ id: this.props.route?.params?.id
|
|
|
|
|
+ }, () => {
|
|
|
|
|
+ this.readMessage();
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ MyStatusBar.setStatusBarTheme(MyStatusBar.LIGHT_STYLE);
|
|
|
|
|
+ this.props.navigation.addListener('beforeRemove', (e) => {
|
|
|
|
|
+ MyStatusBar.setStatusBarTheme(MyStatusBar.DEFAULT_STYLE);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ readMessage() {
|
|
|
|
|
+ apiArticle.readMessage(this.state.id).then(res => {
|
|
|
|
|
+ if (res.data) {
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ loading: false,
|
|
|
|
|
+ messageInfo: res.data
|
|
|
|
|
+ });
|
|
|
|
|
+ //this.setPageTitle();
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(err => {
|
|
|
|
|
+ toastShort(err);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ setPageTitle() {
|
|
|
|
|
+ if (this.state.messageInfo.articleTitle) {
|
|
|
|
|
+ /*this.props.navigation.setOptions({
|
|
|
|
|
+ headerTitle: () => (<HeaderTitle title={this.state.messageInfo.articleTitle}/>)
|
|
|
|
|
+ })*/
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ loading: false
|
|
|
|
|
+ });
|
|
|
|
|
+ }, 300);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ accessLink(url) {
|
|
|
|
|
+ Linking.openURL(utils.getImageUrl(url))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ getColorByType(type) {
|
|
|
|
|
+ switch (type) {
|
|
|
|
|
+ case "Ended":
|
|
|
|
|
+ return {
|
|
|
|
|
+ backgroundColor: "#E11919"
|
|
|
|
|
+ }
|
|
|
|
|
+ case "Upcoming":
|
|
|
|
|
+ return {
|
|
|
|
|
+ backgroundColor: "#FFAA2C"
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ onScrollView(e) {
|
|
|
|
|
+ if (e.nativeEvent.contentOffset) {
|
|
|
|
|
+ const isR = e.nativeEvent.contentOffset.y >= $vw(95);
|
|
|
|
|
+ if (isR != this.state.showTitleBar) {
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ showTitleBar: isR
|
|
|
|
|
+ });
|
|
|
|
|
+ if (isR) {
|
|
|
|
|
+ this.startTitleAnimate();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.hideTitleAnimate();
|
|
|
|
|
+ }
|
|
|
|
|
+ MyStatusBar.setStatusBarTheme(isR ? MyStatusBar.DEFAULT_STYLE : MyStatusBar.LIGHT_STYLE);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ startTitleAnimate() {
|
|
|
|
|
+ Animated.timing(this.state.opacity, {
|
|
|
|
|
+ toValue: 1,
|
|
|
|
|
+ duration: 250,
|
|
|
|
|
+ easing: Easing.linear,
|
|
|
|
|
+ useNativeDriver: true
|
|
|
|
|
+ }).start(() => {
|
|
|
|
|
+
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ hideTitleAnimate() {
|
|
|
|
|
+ Animated.timing(this.state.opacity, {
|
|
|
|
|
+ toValue: 0,
|
|
|
|
|
+ duration: 250,
|
|
|
|
|
+ easing: Easing.linear,
|
|
|
|
|
+ useNativeDriver: true
|
|
|
|
|
+ }).start(() => {
|
|
|
|
|
+
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ render() {
|
|
|
|
|
+ if (this.state.loading) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <View style={styles.container}>
|
|
|
|
|
+ <VbeSkeleton
|
|
|
|
|
+ style={{width: $width, height: $width}}
|
|
|
|
|
+ layout={[
|
|
|
|
|
+ {width: $width, height: $width}
|
|
|
|
|
+ ]}
|
|
|
|
|
+ animationDirection={"horizontalRight"}/>
|
|
|
|
|
+ <VbeSkeleton
|
|
|
|
|
+ style={styles.loadingView}
|
|
|
|
|
+ layout={[
|
|
|
|
|
+ {width: '90%', height: 20, marginTop: 8},
|
|
|
|
|
+ {width: '50%', height: 12, marginTop: 8},
|
|
|
|
|
+ {width: '100%', height: 15, marginTop: 24},
|
|
|
|
|
+ {width: '100%', height: 15, marginTop: 8},
|
|
|
|
|
+ {width: '100%', height: 15, marginTop: 8},
|
|
|
|
|
+ {width: '100%', height: 15, marginTop: 8},
|
|
|
|
|
+ {width: '30%', height: 15, marginTop: 8},
|
|
|
|
|
+ {width: '100%', height: 15, marginTop: 24},
|
|
|
|
|
+ {width: '100%', height: 15, marginTop: 8},
|
|
|
|
|
+ {width: '100%', height: 15, marginTop: 8},
|
|
|
|
|
+ {width: '100%', height: 15, marginTop: 8},
|
|
|
|
|
+ {width: '30%', height: 15, marginTop: 8}
|
|
|
|
|
+ ]}
|
|
|
|
|
+ animationDirection={"horizontalRight"}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ return (
|
|
|
|
|
+ <>
|
|
|
|
|
+ <ScrollView
|
|
|
|
|
+ style={styles.container}
|
|
|
|
|
+ onScroll={e => this.onScrollView(e)}
|
|
|
|
|
+ scrollEventThrottle={16}
|
|
|
|
|
+ contentContainerStyle={$padding(0,0,32)}>
|
|
|
|
|
+ { utils.isNotEmpty(this.state.messageInfo.articleImages) &&
|
|
|
|
|
+ <Swiper
|
|
|
|
|
+ style={{height: $width}}
|
|
|
|
|
+ autoplay={true}
|
|
|
|
|
+ autoplayTimeout={5}
|
|
|
|
|
+ renderPagination={(index,total) => <PagerView index={index+1} total={total}/> }
|
|
|
|
|
+ removeClippedSubviews={false}>
|
|
|
|
|
+ { this.state.messageInfo.articleImages.map((item, index) => {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <Image
|
|
|
|
|
+ key={index}
|
|
|
|
|
+ style={{width: $width, height: $width}}
|
|
|
|
|
+ source={{uri: utils.getImageUrl(item.articleImagePath)}}/>
|
|
|
|
|
+ );
|
|
|
|
|
+ })}
|
|
|
|
|
+ </Swiper>
|
|
|
|
|
+ }
|
|
|
|
|
+ <View style={styles.header}>
|
|
|
|
|
+ <View>
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={[styles.labelTypeText, this.getColorByType(this.state.messageInfo.campaignMark)]}
|
|
|
|
|
+ numberOfLines={1}>
|
|
|
|
|
+ {this.state.messageInfo.campaignMark}
|
|
|
|
|
+ </TextView>
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={styles.textTitle}
|
|
|
|
|
+ numberOfLines={2}
|
|
|
|
|
+ ellipsizeMode="tail">
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={styles.hideText}
|
|
|
|
|
+ numberOfLines={1}>
|
|
|
|
|
+ {this.state.messageInfo.campaignMark}
|
|
|
|
|
+ </TextView>
|
|
|
|
|
+ {this.state.messageInfo.articleTitle}
|
|
|
|
|
+ </TextView>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View style={ui.flexc}>
|
|
|
|
|
+ <MaterialCommunityIcons
|
|
|
|
|
+ name="clock-time-four-outline"
|
|
|
|
|
+ color={textSecondary}
|
|
|
|
|
+ size={12}/>
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={styles.textDate}
|
|
|
|
|
+ numberOfLines={1}>
|
|
|
|
|
+ {this.state.messageInfo.createTime}
|
|
|
|
|
+ </TextView>
|
|
|
|
|
+ <MaterialCommunityIcons
|
|
|
|
|
+ name="eye-check-outline"
|
|
|
|
|
+ size={12}
|
|
|
|
|
+ color={textPrimary}/>
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={styles.textView}
|
|
|
|
|
+ numberOfLines={1}>
|
|
|
|
|
+ {this.state.messageInfo.articleViews}
|
|
|
|
|
+ </TextView>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <TextView style={styles.textLinkTitle}>{$t("notification.labelSummary")}</TextView>
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={styles.textSummary}>
|
|
|
|
|
+ {$t("notification.startTime")}
|
|
|
|
|
+ {this.state.messageInfo.startTime}
|
|
|
|
|
+ </TextView>
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={styles.textSummary}>
|
|
|
|
|
+ {$t("notification.endTime")}
|
|
|
|
|
+ {this.state.messageInfo.endTime}
|
|
|
|
|
+ </TextView>
|
|
|
|
|
+ <TextView style={styles.textLinkTitle}>{$t("notification.labelDetails")}</TextView>
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={styles.textMessage}
|
|
|
|
|
+ selectable={true}>
|
|
|
|
|
+ {this.state.messageInfo.articleContent}
|
|
|
|
|
+ </TextView>
|
|
|
|
|
+ { utils.isNotEmpty(this.state.messageInfo.articleLinks) &&
|
|
|
|
|
+ <>
|
|
|
|
|
+ <TextView style={styles.textLinkTitle}>{$t("notification.labelLinks")}</TextView>
|
|
|
|
|
+ { this.state.messageInfo.articleLinks.map((item, index) =>
|
|
|
|
|
+ <View style={styles.itemLink} key={index}>
|
|
|
|
|
+ <TextView style={styles.linkIndex}>{index + 1}.</TextView>
|
|
|
|
|
+ <TextView
|
|
|
|
|
+ style={styles.linkHyper}
|
|
|
|
|
+ onPress={() => this.accessLink(item.articleLink)}>{item.articleLinkName}</TextView>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </>
|
|
|
|
|
+ }
|
|
|
|
|
+ <EndView/>
|
|
|
|
|
+ </ScrollView>
|
|
|
|
|
+ { !this.state.showTitleBar &&
|
|
|
|
|
+ <View style={[styles.toolbar, {top: statusHeight}]}>
|
|
|
|
|
+ <BackButton style={styles.backIcon} color={"#F0F0F0"}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ }
|
|
|
|
|
+ <Animated.View style={[styles.toolbar, {opacity: this.state.opacity}]}>
|
|
|
|
|
+ <Toolbar title={this.state.messageInfo.articleTitle}/>
|
|
|
|
|
+ </Animated.View>
|
|
|
|
|
+ </>
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const styles = StyleSheet.create({
|
|
|
|
|
+ container: {
|
|
|
|
|
+ flex: 1,
|
|
|
|
|
+ backgroundColor: pageBackground
|
|
|
|
|
+ },
|
|
|
|
|
+ toolbar: {
|
|
|
|
|
+ top: 0,
|
|
|
|
|
+ left: 0,
|
|
|
|
|
+ right: 0,
|
|
|
|
|
+ zIndex: 2,
|
|
|
|
|
+ position: 'absolute'
|
|
|
|
|
+ },
|
|
|
|
|
+ backIcon: {
|
|
|
|
|
+ width: 48,
|
|
|
|
|
+ height: toolbarSize,
|
|
|
|
|
+ zIndex: 2,
|
|
|
|
|
+ marginLeft: isIOS ? 0 : 2,
|
|
|
|
|
+ alignItems: 'center',
|
|
|
|
|
+ justifyContent: 'center'
|
|
|
|
|
+ },
|
|
|
|
|
+ loadingView: {
|
|
|
|
|
+ flex: 1,
|
|
|
|
|
+ padding: 16,
|
|
|
|
|
+ justifyContent: 'flex-start',
|
|
|
|
|
+ backgroundColor: pageBackground
|
|
|
|
|
+ },
|
|
|
|
|
+ textTitle: {
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 18,
|
|
|
|
|
+ fontWeight: 'bold',
|
|
|
|
|
+ paddingBottom: 2
|
|
|
|
|
+ },
|
|
|
|
|
+ textDate: {
|
|
|
|
|
+ flex: 1,
|
|
|
|
|
+ color: textSecondary,
|
|
|
|
|
+ fontSize: 10,
|
|
|
|
|
+ paddingLeft: 2
|
|
|
|
|
+ },
|
|
|
|
|
+ textView: {
|
|
|
|
|
+ color: textSecondary,
|
|
|
|
|
+ fontSize: 10,
|
|
|
|
|
+ paddingLeft: 4
|
|
|
|
|
+ },
|
|
|
|
|
+ header: {
|
|
|
|
|
+ padding: 16,
|
|
|
|
|
+ backgroundColor: pageBackground
|
|
|
|
|
+ },
|
|
|
|
|
+ textSummary: {
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ ...$padding(0, 16, 8)
|
|
|
|
|
+ },
|
|
|
|
|
+ textMessage: {
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ ...$padding(0, 16, 16)
|
|
|
|
|
+ },
|
|
|
|
|
+ labelTypeText: {
|
|
|
|
|
+ color: textLight,
|
|
|
|
|
+ height: 16,
|
|
|
|
|
+ fontSize: 10,
|
|
|
|
|
+ borderRadius: 4,
|
|
|
|
|
+ marginTop: 3,
|
|
|
|
|
+ ...$padding(0, 6),
|
|
|
|
|
+ position: 'absolute',
|
|
|
|
|
+ backgroundColor: "#1ABD00"
|
|
|
|
|
+ },
|
|
|
|
|
+ hideText: {
|
|
|
|
|
+ height: 16,
|
|
|
|
|
+ opacity: 0,
|
|
|
|
|
+ fontSize: 10,
|
|
|
|
|
+ ...$padding(2, 8),
|
|
|
|
|
+ },
|
|
|
|
|
+ textLinkTitle: {
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 16,
|
|
|
|
|
+ fontWeight: 'bold',
|
|
|
|
|
+ padding: 16
|
|
|
|
|
+ },
|
|
|
|
|
+ itemLink: {
|
|
|
|
|
+ ...$padding(0, 16, 8),
|
|
|
|
|
+ flexDirection: 'row'
|
|
|
|
|
+ },
|
|
|
|
|
+ linkIndex: {
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ paddingRight: 2
|
|
|
|
|
+ },
|
|
|
|
|
+ linkHyper: {
|
|
|
|
|
+ ...ui.link,
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ textDecorationLine: 'underline'
|
|
|
|
|
+ },
|
|
|
|
|
+ linkActive: {
|
|
|
|
|
+ color: "#FF3B30"
|
|
|
|
|
+ }
|
|
|
|
|
+})
|