Răsfoiți Sursa

Enhancement UI with skeleton screen

vbea 1 an în urmă
părinte
comite
e16012ed65

+ 44 - 1
Strides-APP/app/pages/alert/ListCampaign.js

@@ -9,13 +9,16 @@
  import { PageList } from '../Router';
  import AlertUtil from './AlertUtil';
 import ItemCampaign from './ItemCampaign';
+import VbeSkeleton from '../../components/VbeSkeleton';
 
 export default class ListCampaign extends Component {
   constructor(props) {
     super(props);
     this.state = {
       dataList: [],
-      refreshing: false
+      loading: true,
+      refreshing: false,
+      loadingList: ["", "", "", ""]
     };
   }
 
@@ -52,6 +55,7 @@ export default class ListCampaign extends Component {
       toastShort(err)
     }).finally(() => {
       this.setState({
+        loading: false,
         refreshing: false
       })
     })
@@ -93,6 +97,34 @@ export default class ListCampaign extends Component {
   }
 
   render() {
+    if (this.state.loading) {
+      return (
+        <View style={styles.listView}>
+          { this.state.loadingList.map((item, index) =>
+            <View style={styles.loadingView} key={index}>
+              <VbeSkeleton
+                style={styles.iconImage}
+                layout={[
+                  {width: 85, height: 85, borderRadius: 6},
+                  {width: 35, height: 12, marginTop: 4, marginLeft: 25},
+                ]}
+                animationDirection={"horizontalRight"}
+              />
+              <VbeSkeleton
+                style={ui.flex1}
+                layout={[
+                  {width: '100%', height: 20},
+                  {width: '80%', height: 12, marginTop: 6},
+                  {width: '100%', height: 15, marginTop: 12},
+                  {width: '60%', height: 15, marginTop: 6}
+                ]}
+                animationDirection={"horizontalRight"}
+              />
+            </View>
+          )}
+        </View>
+      )
+    }
     return (
       <FlatList
         style={styles.listView}
@@ -124,5 +156,16 @@ const styles = StyleSheet.create({
     fontSize: 14,
     padding: 20,
     textAlign: 'center'
+  },
+  loadingView: {
+    padding: 16,
+    flexDirection: 'row'
+  },
+  iconImage: {
+    width: 85,
+    height: 85,
+    borderRadius: 6,
+    marginRight: 16,
+    marginBottom: 8
   }
 })

+ 44 - 1
Strides-APP/app/pages/alert/ListNews.js

@@ -9,13 +9,16 @@ import { MyRefreshProps } from '../../components/ThemesConfig';
 import { PageList } from '../Router';
 import AlertUtil from './AlertUtil';
 import ItemArticle from './ItemArticle';
+import VbeSkeleton from '../../components/VbeSkeleton';
 
 export default class ListNews extends Component {
   constructor(props) {
     super(props);
     this.state = {
       dataList: [],
-      refreshing: false
+      loading: true,
+      refreshing: false,
+      loadingList: ["", "", "", ""]
     };
   }
 
@@ -53,6 +56,7 @@ export default class ListNews extends Component {
       toastShort(err)
     }).finally(() => {
       this.setState({
+        loading: false,
         refreshing: false
       })
     })
@@ -94,6 +98,34 @@ export default class ListNews extends Component {
   }
 
   render() {
+    if (this.state.loading) {
+      return (
+        <View style={styles.listView}>
+          { this.state.loadingList.map((item, index) =>
+            <View style={styles.loadingView} key={index}>
+              <VbeSkeleton
+                style={styles.iconImage}
+                layout={[
+                  {width: 85, height: 85, borderRadius: 6},
+                  {width: 35, height: 12, marginTop: 4, marginLeft: 25},
+                ]}
+                animationDirection={"horizontalRight"}
+              />
+              <VbeSkeleton
+                style={ui.flex1}
+                layout={[
+                  {width: '100%', height: 20},
+                  {width: '80%', height: 12, marginTop: 6},
+                  {width: '100%', height: 15, marginTop: 12},
+                  {width: '60%', height: 15, marginTop: 6}
+                ]}
+                animationDirection={"horizontalRight"}
+              />
+            </View>
+          )}
+        </View>
+      )
+    }
     return (
       <FlatList
         style={styles.listView}
@@ -125,5 +157,16 @@ const styles = StyleSheet.create({
     fontSize: 14,
     padding: 20,
     textAlign: 'center'
+  },
+  loadingView: {
+    padding: 16,
+    flexDirection: 'row'
+  },
+  iconImage: {
+    width: 85,
+    height: 85,
+    borderRadius: 6,
+    marginRight: 16,
+    marginBottom: 8
   }
 })

+ 1 - 1
Strides-APP/app/pages/alert/ViewArticle.js

@@ -6,7 +6,6 @@ import React, { Component } from 'react';
 import { View,  StyleSheet, Image, ScrollView, Linking } from 'react-native';
 import Swiper from 'react-native-swiper';
 import apiArticle from '../../api/apiArticle';
-import { ElevationObject } from '../../components/Button';
 import HeaderTitle from '../../components/HeaderTitle';
 import TextView from '../../components/TextView';
 import VbeSkeleton from '../../components/VbeSkeleton';
@@ -72,6 +71,7 @@ export default class ViewArticle extends Component {
       return (
         <View style={styles.container}>
           <VbeSkeleton
+            style={{width: $width, height: $width}}
             layout={[
               {width: $width, height: $width}
             ]}

+ 38 - 4
Strides-APP/app/pages/alert/ViewCampaign.js

@@ -11,12 +11,14 @@ import { ElevationObject } from '../../components/Button';
  import TextView from '../../components/TextView';
  import utils from '../../utils/utils';
 import { PagerView } from './ViewUtil';
+import VbeSkeleton from '../../components/VbeSkeleton';
 
 export default class ViewCampaign extends Component {
   constructor(props) {
     super(props);
     this.state = {
       id: "",
+      loading: true,
       messageInfo: {
         articleTypeName: "",
         articleTitle: "",
@@ -36,7 +38,6 @@ export default class ViewCampaign extends Component {
   }
 
   readMessage() {
-    Dialog.showProgressDialog();
     apiArticle.readMessage(this.state.id).then(res => {
       if (res.data) {
         this.setState({
@@ -46,9 +47,7 @@ export default class ViewCampaign extends Component {
       }
     }).catch(err => {
       toastShort(err);
-    }).finally(() => {
-      Dialog.dismissLoading();
-    })
+    });
   }
 
   setPageTitle() {
@@ -56,6 +55,11 @@ export default class ViewCampaign extends Component {
       this.props.navigation.setOptions({
         headerTitle: () => (<HeaderTitle title={this.state.messageInfo.articleTitle}/>)
       })
+      setTimeout(() => {
+        this.setState({
+          loading: false
+        });
+      }, 300);
     }
   }
 
@@ -77,6 +81,30 @@ export default class ViewCampaign extends Component {
   }
 
   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}
+            ]}
+            animationDirection={"horizontalRight"}/>
+        </View>
+      )
+    }
     return (
       <ScrollView
         style={styles.container}
@@ -180,6 +208,12 @@ const styles = StyleSheet.create({
     flex: 1,
     backgroundColor: pageBackground
   },
+  loadingView: {
+    flex: 1,
+    padding: 16,
+    justifyContent: 'flex-start',
+    backgroundColor: pageBackground
+  },
   textTitle: {
     color: textPrimary,
     fontSize: 18,

+ 1 - 1
Strides-APP/app/pages/chargingV2/DialogPayPerUse.js

@@ -42,7 +42,7 @@ const styles = StyleSheet.create({
     flex: 1,
     alignItems: 'center',
     justifyContent: 'center',
-    backgroundColor: 'rgba(0,0,0,.1)'
+    backgroundColor: 'rgba(0,0,0,.3)'
   },
   content: {
     width: Dialog.dialogWidth,

+ 1 - 1
Strides-APP/app/pages/home/maps/BottomSiteInfo.js

@@ -143,7 +143,7 @@ export default BottomSiteInfo = ({
           <EndView/>
         </View>
       );
-    } else {
+    } else if (stationInfo.id) {
       return (
         <Pressable
           style={({pressed}) => [style, pressed ? styles.stationBarPresed : {}]}

+ 114 - 51
Strides-APP/app/pages/member/MembersList.js

@@ -9,20 +9,27 @@ import { ElevationObject } from '../../components/Button';
 import Dialog from '../../components/Dialog';
 import TextView from '../../components/TextView';
 import utils from '../../utils/utils';
+import VbeSkeleton from '../../components/VbeSkeleton';
 
 export default class MembersList extends Component {
   constructor(props) {
     super(props);
     this.state = {
-      memberList: []
+      loading: true,
+      memberList: [],
+      loadingList: ["", "", "", ""]
     };
   }
 
   componentDidMount() {
-    this.getMyMemberList();
     this.props.navigation.addListener('focus', () => {
-      this.getMyMemberList();
+      if (!this.state.loading) {
+        this.getMyMemberList();
+      }
     })
+    setTimeout(() => {
+      this.getMyMemberList();
+    }, 500);
   }
 
   getMyMemberList() {
@@ -31,12 +38,20 @@ export default class MembersList extends Component {
         this.setState({
           memberList: res.data
         });
+      } else {
+        this.setState({
+          memberList: []
+        });
       }
     }).catch(err => {
       this.setState({
         memberList: []
       });
       toastShort(err)
+    }).finally(() => {
+      this.setState({
+        loading: false
+      });
     });
   }
 
@@ -80,60 +95,103 @@ export default class MembersList extends Component {
   }
 
   render() {
+    if (this.state.loading) {
+      return (
+        <View style={styles.container}>
+          { this.state.loadingList.map((item, index) =>
+            <View style={styles.loadingView} key={index}>
+              <VbeSkeleton
+                style={ui.flex1}
+                layout={[
+                  {width: '50%', height: 20},
+                  {width: '100%', height: 15, marginTop: 6},
+                  {width: '60%', height: 15, marginTop: 6}
+                ]}
+                animationDirection={"horizontalRight"}
+              />
+              <VbeSkeleton
+                style={styles.loadingIcon}
+                layout={[
+                  {width: 48, height: 48, borderRadius: 6}
+                ]}
+                animationDirection={"horizontalRight"}
+              />
+            </View>
+          )}
+        </View>
+      )
+    }
     return (
-      this.state.memberList.length > 0
-      ? this.state.memberList.map((item, index) => (
-        <Pressable
-          key={index}
-          style={styles.memberView}
-          onPress={() => {
-            if (item.membershipStatus == "Rejected") {
-              this.onDeleteMember(item)
-            }
-            //startPage(PageList.editVehicle, {id: item.vehiclePk});
-          }}>
-          <View style={styles.itemBackground}>
-            { utils.isNotEmpty(item.groupLogo)
-            ? <Image
-                source={{uri: utils.getImageUrl(item.groupLogo)}}
-                resizeMode="contain"
-                style={styles.groupLogo}/>
-            : <MaterialIcons
-                name="card-membership"
-                color={colorAccent}
-                style={styles.groupIcon}
-                size={52}/>
-            }
-          </View>
-          <View style={styles.memberItem}>
-            { utils.isEmpty(item.groupType)
-            ? <TextView style={styles.textLabel2}>{$t('members.membership')}:</TextView>
-            : <TextView style={styles.textType}>{item.groupType}</TextView>
-            }
-            <TextView
-              style={styles.textValue2}
-              numberOfLines={1}>{item.membership}</TextView>
-          </View>
-          <View style={styles.memberItem}>
-            <TextView style={styles.textLabel}>{$t('members.membershipNo')}:</TextView>
-            <TextView style={styles.textValue}>{item.membershipNo}</TextView>
-          </View>
-          <View style={styles.memberItem}>
-            <TextView style={styles.textLabel}>{$t('members.status')}:</TextView>
-            { item.membershipStatus == "Rejected"
-              ? <TextView style={[styles.textValue, styles.statusRed]}>{this.getMembershipStatus(item.membershipStatus)}</TextView>
-              : <TextView style={styles.textValue}>{this.getMembershipStatus(item.membershipStatus)}</TextView>
-            }
-            
-          </View>
-        </Pressable>
-      ))
-      : <Text style={ui.noData}>{$t('members.noData')}</Text>
+      <View style={styles.container}>
+        { this.state.memberList.length > 0
+        ? this.state.memberList.map((item, index) => (
+          <Pressable
+            key={index}
+            style={styles.memberView}
+            onPress={() => {
+              if (item.membershipStatus == "Rejected") {
+                this.onDeleteMember(item)
+              }
+              //startPage(PageList.editVehicle, {id: item.vehiclePk});
+            }}>
+            <View style={styles.itemBackground}>
+              { utils.isNotEmpty(item.groupLogo)
+              ? <Image
+                  source={{uri: utils.getImageUrl(item.groupLogo)}}
+                  resizeMode="contain"
+                  style={styles.groupLogo}/>
+              : <MaterialIcons
+                  name="card-membership"
+                  color={colorAccent}
+                  style={styles.groupIcon}
+                  size={52}/>
+              }
+            </View>
+            <View style={styles.memberItem}>
+              { utils.isEmpty(item.groupType)
+              ? <TextView style={styles.textLabel2}>{$t('members.membership')}:</TextView>
+              : <TextView style={styles.textType}>{item.groupType}</TextView>
+              }
+              <TextView
+                style={styles.textValue2}
+                numberOfLines={1}>{item.membership}</TextView>
+            </View>
+            <View style={styles.memberItem}>
+              <TextView style={styles.textLabel}>{$t('members.membershipNo')}:</TextView>
+              <TextView style={styles.textValue}>{item.membershipNo}</TextView>
+            </View>
+            <View style={styles.memberItem}>
+              <TextView style={styles.textLabel}>{$t('members.status')}:</TextView>
+              { item.membershipStatus == "Rejected"
+                ? <TextView style={[styles.textValue, styles.statusRed]}>{this.getMembershipStatus(item.membershipStatus)}</TextView>
+                : <TextView style={styles.textValue}>{this.getMembershipStatus(item.membershipStatus)}</TextView>
+              }
+              
+            </View>
+          </Pressable>
+        ))
+        : <Text style={ui.noData}>{$t('members.noData')}</Text>
+      }
+      </View>
     );
   }
 }
 
 const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+    backgroundColor: pageBackground
+  },
+  loadingView: {
+    padding: 16,
+    borderRadius: 8,
+    borderColor: '#F0F0F0',
+    borderWidth: 1,
+    alignItems: 'flex-end',
+    backgroundColor: colorLight,
+    flexDirection: 'row',
+    ...$margin(16, 16, 0)
+  },
   memberView: {
     borderRadius: 8,
     overflow: 'hidden',
@@ -199,5 +257,10 @@ const styles = StyleSheet.create({
     margin: 8,
     opacity: .8,
     borderRadius: 6
+  },
+  loadingIcon: {
+    width: 48,
+    height: 48,
+    marginLeft: 16
   }
 })