diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..8be70af39 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "editor.defaultFormatter": "esbenp.prettier-vscode", + "files.autoSave": "onFocusChange", + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/MobileApp/android/app/build.gradle b/MobileApp/android/app/build.gradle index 1d41efeea..93decc6a3 100644 --- a/MobileApp/android/app/build.gradle +++ b/MobileApp/android/app/build.gradle @@ -190,6 +190,8 @@ android { } dependencies { + implementation project(':@react-native-community_netinfo') + implementation project(':react-native-smart-splash-screen') implementation project(':react-native-fbsdk') implementation project(':react-native-maps') implementation project(':@react-native-firebase_storage') diff --git a/MobileApp/android/app/src/main/java/com/dwc/MainActivity.java b/MobileApp/android/app/src/main/java/com/dwc/MainActivity.java index 60507b204..a354fd087 100644 --- a/MobileApp/android/app/src/main/java/com/dwc/MainActivity.java +++ b/MobileApp/android/app/src/main/java/com/dwc/MainActivity.java @@ -1,9 +1,10 @@ package com.dwc; - +import android.os.Bundle; import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; import com.facebook.react.ReactRootView; import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; +import com.reactnativecomponent.splashscreen.RCTSplashScreen; public class MainActivity extends ReactActivity { @@ -11,6 +12,14 @@ public class MainActivity extends ReactActivity { * Returns the name of the main component registered from JavaScript. This is used to schedule * rendering of the component. */ +@Override +protected void onCreate(Bundle savedInstanceState) { + RCTSplashScreen.openSplashScreen(this); //open splashscreen + //RCTSplashScreen.openSplashScreen(this, true, ImageView.ScaleType.FIT_XY); //open splashscreen fullscreen + super.onCreate(savedInstanceState); +} + + @Override protected String getMainComponentName() { return "DWC"; diff --git a/MobileApp/android/app/src/main/java/com/dwc/MainApplication.java b/MobileApp/android/app/src/main/java/com/dwc/MainApplication.java index 5c3156046..c65fea4f5 100644 --- a/MobileApp/android/app/src/main/java/com/dwc/MainApplication.java +++ b/MobileApp/android/app/src/main/java/com/dwc/MainApplication.java @@ -1,9 +1,10 @@ package com.dwc; - +import com.reactnativecomponent.splashscreen.RCTSplashScreenPackage; import android.app.Application; import android.content.Context; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; +import com.reactnativecommunity.netinfo.NetInfoPackage; import com.oblador.vectoricons.VectorIconsPackage; import com.swmansion.rnscreens.RNScreensPackage; import com.swmansion.reanimated.ReanimatedPackage; diff --git a/MobileApp/android/app/src/main/res/drawable/splash.png b/MobileApp/android/app/src/main/res/drawable/splash.png new file mode 100644 index 000000000..d94ed7455 Binary files /dev/null and b/MobileApp/android/app/src/main/res/drawable/splash.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index b25e05c69..59c62e821 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index b25e05c69..59c62e821 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 69376f6b0..da5aee820 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 69376f6b0..da5aee820 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 6cd44a240..1e09900d6 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 6cd44a240..1e09900d6 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index a24815145..dad28334d 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index a24815145..dad28334d 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index db29fcd01..47702480a 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index db29fcd01..47702480a 100644 Binary files a/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/MobileApp/android/app/src/main/res/values/styles.xml b/MobileApp/android/app/src/main/res/values/styles.xml index 62fe59fa4..b7137d553 100644 --- a/MobileApp/android/app/src/main/res/values/styles.xml +++ b/MobileApp/android/app/src/main/res/values/styles.xml @@ -4,6 +4,7 @@ diff --git a/MobileApp/android/settings.gradle b/MobileApp/android/settings.gradle index 35d0c8b9d..6dc780fa1 100644 --- a/MobileApp/android/settings.gradle +++ b/MobileApp/android/settings.gradle @@ -1,4 +1,8 @@ rootProject.name = 'DWC' +include ':@react-native-community_netinfo' +project(':@react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android') +include ':react-native-smart-splash-screen' +project(':react-native-smart-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-smart-splash-screen/android') include ':react-native-vector-icons' project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') include ':react-native-screens' diff --git a/MobileApp/ios/DWC.xcodeproj/project.pbxproj b/MobileApp/ios/DWC.xcodeproj/project.pbxproj index 4e661e330..418fd4f30 100644 --- a/MobileApp/ios/DWC.xcodeproj/project.pbxproj +++ b/MobileApp/ios/DWC.xcodeproj/project.pbxproj @@ -39,6 +39,7 @@ 71B447F91CF743669AB55D00 /* Proxima Nova Extrabold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 4D8481A618E040FC9D4C7C18 /* Proxima Nova Extrabold.otf */; }; 7EE6E5C20C4F48F08EDA9524 /* Proxima Nova Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = B6DF844CF2FB4D52AD5812D1 /* Proxima Nova Thin.otf */; }; AA9389E3E3BB4DE4BBFB808A /* ProximaNova-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = F31DDC677E6245298E1AB266 /* ProximaNova-Regular.otf */; }; + ABA5D3E47B7F4DF1A96017DD /* libRCTSplashScreen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B36960B5C6E4837AB98A95A /* libRCTSplashScreen.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -98,6 +99,8 @@ 4D8481A618E040FC9D4C7C18 /* Proxima Nova Extrabold.otf */ = {isa = PBXFileReference; name = "Proxima Nova Extrabold.otf"; path = "../fonts/Proxima Nova Extrabold.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; B6DF844CF2FB4D52AD5812D1 /* Proxima Nova Thin.otf */ = {isa = PBXFileReference; name = "Proxima Nova Thin.otf"; path = "../fonts/Proxima Nova Thin.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; F31DDC677E6245298E1AB266 /* ProximaNova-Regular.otf */ = {isa = PBXFileReference; name = "ProximaNova-Regular.otf"; path = "../fonts/ProximaNova-Regular.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + AF5C8B556083499B9AB80896 /* RCTSplashScreen.xcodeproj */ = {isa = PBXFileReference; name = "RCTSplashScreen.xcodeproj"; path = "../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; + 1B36960B5C6E4837AB98A95A /* libRCTSplashScreen.a */ = {isa = PBXFileReference; name = "libRCTSplashScreen.a"; path = "libRCTSplashScreen.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -112,6 +115,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + ABA5D3E47B7F4DF1A96017DD /* libRCTSplashScreen.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -175,6 +179,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( + AF5C8B556083499B9AB80896 /* RCTSplashScreen.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -568,6 +573,14 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DWC.app/DWC"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen", + ); }; name = Debug; }; @@ -587,6 +600,14 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DWC.app/DWC"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen", + ); }; name = Release; }; @@ -606,6 +627,10 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = DWC; VERSIONING_SYSTEM = "apple-generic"; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen", + ); }; name = Debug; }; @@ -624,6 +649,10 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = DWC; VERSIONING_SYSTEM = "apple-generic"; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen", + ); }; name = Release; }; @@ -651,6 +680,14 @@ SDKROOT = appletvos; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.2; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen", + ); }; name = Debug; }; @@ -678,6 +715,14 @@ SDKROOT = appletvos; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.2; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen", + ); }; name = Release; }; @@ -704,6 +749,14 @@ SDKROOT = appletvos; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DWC-tvOS.app/DWC-tvOS"; TVOS_DEPLOYMENT_TARGET = 10.1; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen", + ); }; name = Debug; }; @@ -730,6 +783,14 @@ SDKROOT = appletvos; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DWC-tvOS.app/DWC-tvOS"; TVOS_DEPLOYMENT_TARGET = 10.1; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen", + ); }; name = Release; }; diff --git a/MobileApp/ios/Podfile b/MobileApp/ios/Podfile index 9b7252e5a..2de24fb13 100644 --- a/MobileApp/ios/Podfile +++ b/MobileApp/ios/Podfile @@ -62,6 +62,9 @@ target 'DWC' do pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons' + + pod 'react-native-netinfo', :path => '../node_modules/@react-native-community/netinfo' + target 'DWCTests' do inherit! :search_paths # Pods for testing diff --git a/MobileApp/package.json b/MobileApp/package.json index 086078c82..6d07157c9 100644 --- a/MobileApp/package.json +++ b/MobileApp/package.json @@ -13,6 +13,7 @@ "@react-native-community/cameraroll": "1.3.0", "@react-native-community/geolocation": "2.0.2", "@react-native-community/google-signin": "3.0.3", + "@react-native-community/netinfo": "5.5.0", "@react-native-firebase/app": "6.0.3", "@react-native-firebase/auth": "6.0.3", "@react-native-firebase/database": "6.0.3", @@ -27,6 +28,7 @@ "react-native-reanimated": "1.3.2", "react-native-responsive-screen": "1.3.0", "react-native-screens": "1.0.0-alpha.23", + "react-native-smart-splash-screen": "2.3.5", "react-native-vector-icons": "6.6.0", "react-navigation": "4.0.10", "react-navigation-drawer": "2.3.3", diff --git a/MobileApp/src/components/CardComponent/CardComponent.js b/MobileApp/src/components/CardComponent/CardComponent.js index 97c56f3ea..baab3c2f3 100644 --- a/MobileApp/src/components/CardComponent/CardComponent.js +++ b/MobileApp/src/components/CardComponent/CardComponent.js @@ -1,92 +1,109 @@ import * as React from 'react'; -import { View, StyleSheet, Dimensions, TouchableOpacity } from 'react-native' -import { Card, Text, Avatar } from 'react-native-paper'; - +import {View, StyleSheet, Dimensions, TouchableOpacity} from 'react-native'; +import {Card, Text, Avatar} from 'react-native-paper'; class CardComponent extends React.Component { + constructor(props) { + super(props); + } - constructor(props) { - super(props); - } - - render() { - return ( - - - } - right={() => } - /> - {this.props.isNavigate ? - this.props.showPhoto.navigate('showDetailedPhoto', - { - img: this.props.image, - title: this.props.title, - subtitle: this.props.subtitle, - user: this.props.user, - content: this.props.result, - showPhoto: this.props.navigation - } - ) - } - > - - - : - - - - } - - - {this.props.content.map((val, i) => { - - return ( - val[0] === 'map-marker' ? - this.props.showPhoto.navigate('showLocationScreen', { location: val[1] })} - > - - View location - - : - - - {val[1]} - - ) - - })} - - - - - - + render() { + return ( + + + ( + + )} + right={() => ( + + )} + /> + {this.props.isNavigate ? ( + + this.props.showPhoto.navigate('showDetailedPhoto', { + img: this.props.image, + title: this.props.title, + subtitle: this.props.subtitle, + user: this.props.user, + content: this.props.result, + showPhoto: this.props.navigation, + }) + }> + + + ) : ( + + + + )} - ); - } + + {this.props.content.map((val, i) => { + return val[0] === 'map-marker' ? ( + + this.props.showPhoto.navigate('showLocationScreen', { + location: val[1], + }) + }> + + View location + + ) : ( + + + {val[1]} + + ); + })} + + + + + ); + } } const styles = StyleSheet.create({ - container: { - marginTop: 2, - width: Dimensions.get('window').width - }, - cover: { - height: 300, - width: Dimensions.get('window').width - }, - content: { - marginTop: 5, - flexDirection: 'row', - flexWrap: 'wrap', - alignItems: 'center' - }, -}) + container: { + marginTop: 2, + width: Dimensions.get('window').width, + }, + cover: { + height: 300, + width: Dimensions.get('window').width - 10, + borderRadius: 15, + }, + content: { + marginTop: 5, + flexDirection: 'row', + flexWrap: 'wrap', + alignItems: 'center', + fontSize: 15, + }, +}); -export { CardComponent }; \ No newline at end of file +export {CardComponent}; diff --git a/MobileApp/src/components/NetInfo/NetInfo.js b/MobileApp/src/components/NetInfo/NetInfo.js new file mode 100644 index 000000000..5f8b7b5a8 --- /dev/null +++ b/MobileApp/src/components/NetInfo/NetInfo.js @@ -0,0 +1,6 @@ +import NetInfo from '@react-native-community/netinfo'; +export async function checkNet() { + let state = await NetInfo.fetch(); + //state.isConnected + return state.isInternetReachable; +} diff --git a/MobileApp/src/components/TileCompoent/TileComponent.js b/MobileApp/src/components/TileCompoent/TileComponent.js index 35be4bd2c..8539309fa 100644 --- a/MobileApp/src/components/TileCompoent/TileComponent.js +++ b/MobileApp/src/components/TileCompoent/TileComponent.js @@ -1,66 +1,67 @@ import * as React from 'react'; -import { View, StyleSheet, Dimensions, TouchableNativeFeedback } from 'react-native' -import { Card, Text, Avatar } from 'react-native-paper'; -import { TouchableOpacity } from 'react-native-gesture-handler'; -import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'; +import {StyleSheet, TouchableNativeFeedback} from 'react-native'; +import {Card} from 'react-native-paper'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import { + widthPercentageToDP as wp, + heightPercentageToDP as hp, +} from 'react-native-responsive-screen'; class TileComponent extends React.Component { + constructor(props) { + super(props); + } - constructor(props) { - super(props); - } + render() { + return ( + + this.props.next.navigate('ParkDetails', { + img: this.props.img, + title: this.props.title, + subtitle: this.props.subtitle, + code: this.props.code, + }) + }> + + + + - render() { - return ( - this.props.next.navigate('ParkDetails', - { - img: this.props.img, - title: this.props.title, - subtitle: this.props.subtitle, - code: this.props.code - } - ) - } - > - - - - - - - - } - /> - - - ); - } + } + /> + + + ); + } } const styles = StyleSheet.create({ - container: { - margin: 5, - borderRadius: 5, - backgroundColor: '#F0FFFF' - }, - cover: { - height: 180 - }, - content: { - marginTop: 5, - flexDirection: 'row', - flexWrap: 'wrap', - alignItems: 'center' - }, - title: { - flexWrap: 'wrap' - } -}) - -export { TileComponent }; + container: { + margin: 5, + borderRadius: 5, + backgroundColor: '#F0FFFF', + borderRadius: 10, + }, + cover: { + height: 180, + backgroundColor: '#F0FFFF', + borderTopRightRadius: 10, + borderTopLeftRadius: 10, + }, + content: { + marginTop: 5, + flexDirection: 'row', + flexWrap: 'wrap', + alignItems: 'center', + }, + title: { + flexWrap: 'wrap', + }, +}); +export {TileComponent}; diff --git a/MobileApp/src/components/UserDataHandling/UserDataHandling.js b/MobileApp/src/components/UserDataHandling/UserDataHandling.js index e75f4582d..2f61b54ca 100644 --- a/MobileApp/src/components/UserDataHandling/UserDataHandling.js +++ b/MobileApp/src/components/UserDataHandling/UserDataHandling.js @@ -1,112 +1,49 @@ - export function generateResult(data) { - let result = [] - // result.push(['map-marker', data.location.toString()]) - let time = new Date(data.time) - time = time.toString().split(" ") - time = time.splice(0, time.length - 1) - time = time.toString().replace(/,/g, ' ') - result.push(['clock', time.toString()]) - data.notes !== '' ? result.push(['note-text', data.notes]) : null - if (data.isAlive === 1) { - result.push(['cards-heart', "Alive"]) - if (data.isSingle === 0) { - result.push(['comment-question', "Single"]) - // if (data.haveTusks === 0) { - // result.push(['comment-question', "Have tusks"]) - // } else if (data.haveTusks === 1) { - // result.push(['comment-question', "No tusks"]) - // } else { - // result.push(['comment-question', "Can't see tusks"]) - // } - } else if (data.isSingle === 1) { - if (data.isSingle === 1) { - result.push(['comment-question', "Group with calves"]) - } else { - result.push(['comment-question', "Group without calves"]) - } - - if (data.noOfIndividuals === 0) { - result.push(['comment-question', "2 to 5 individuals"]) - } else if (data.noOfIndividuals === 1) { - result.push(['comment-question', "6 to 10 individuals"]) - } else { - result.push(['comment-question', "More than 10 individuals"]) - } - - // if (data.howManyTuskers === 0) { - // result.push(['comment-question', "No any tuskers"]) - // } else if (data.howManyTuskers === 1) { - // result.push(['comment-question', "1 to 5 individual tuskers"]) - // } else if (data.howManyTuskers === 1) { - // result.push(['comment-question', "6 to 10 individual tuskers"]) - // } else { - // result.push(['comment-question', "More than 10 individual tuskers"]) - // } + let result = []; + result.push(['map-marker', data.location.toString()]); + let time = new Date(data.time); + time = time.toString().split(' '); + time = time.splice(0, time.length - 1); + time = time.toString().replace(/,/g, ' '); + result.push(['clock', time.toString()]); + if (data.isAlive === 1) { + result.push(['cards-heart', 'Alive']); - } - - if (data.sex === 0) { - result.push(['gender-male-female', "Male"]) - } else if (data.sex === 0) { - result.push(['gender-male-female', "Female"]) - } else if (data.sex === 0) { - result.push(['gender-male-female', "Both male and female"]) - } else { - result.push(['gender-male-female', "Don't know the gender"]) - } + if (data.sex === 0) { + result.push(['gender-male-female', 'Male']); + } else if (data.sex === 0) { + result.push(['gender-male-female', 'Female']); + } else if (data.sex === 0) { + result.push(['gender-male-female', 'Both male and female']); } else { - if (data.cause === 0) { - result.push(['comment-question', "By Accident"]) - if (data.accidentKind === 0) { - result.push(['comment-question', "A Vehicle strike"]) - } else if (data.accidentKind === 1) { - result.push(['comment-question', "A Train strike"]) - } else if (data.accidentKind === 2) { - result.push(['comment-question', "Has Fell into well"]) - } else if (data.accidentKind === 3) { - result.push(['comment-question', "A Electrocution"]) - } else { - result.push(['comment-question', data.accidentOther]) - } - } else if (data.cause === 1) { - result.push(['comment-question', "Intentional Death."]) - if (data.intentionalKind === 0) { - result.push(['comment-question', "Conflict related"]) - } else if (data.intentionalKind === 1) { - result.push(['comment-question', "Hunting related"]) - } else if (data.intentionalKind === 2) { - result.push(['comment-question', data.intentionalOther]) - } else { - result.push(['comment-question', "Don’t know how it died."]) - } - } else { - result.push(['comment-question', "Don't know how the death happened."]) - } - result.push(['comment-question', data.noOfDeaths + " died."]) - // result.push(['comment-question', data.noOfTusks + " tuskers."]) - // if (data.tusksStatus === 0) { - // result.push(['comment-question', "Tusks naturally absent"]) - // } else if (data.tusksStatus === 1) { - // result.push(['comment-question', "Tusks present"]) - // } else if (data.tusksStatus === 2) { - // result.push(['comment-question', "Tusks removed"]) - // } else { - // result.push(['comment-question', "Don’t know what happened to tusks."]) - // } + result.push(['gender-male-female', "Don't know the gender"]); } - - //console.log(result) - return result + } else { + result.push(['cards-heart', 'Died']); + } + if (data.type !== '') { + result.push(['elephant', data.type]); + } else { + result.push(['elephant', 'Un-Identified']); + } + result.push(['shield-check', data.verified]); + if (data.notes !== '') { + result.push(['note-text', data.notes]); + } else { + result.push(['note-text', 'Notes unavailable']); + } + return result; } export function generateUUID() { - let dt = new Date().getTime(); - let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - let r = (dt + Math.random() * 16) % 16 | 0; - dt = Math.floor(dt / 16); - return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); - }); - //console.log(uuid) - return uuid + let dt = new Date().getTime(); + let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function( + c, + ) { + let r = (dt + Math.random() * 16) % 16 | 0; + dt = Math.floor(dt / 16); + return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16); + }); + //console.log(uuid) + return uuid; } diff --git a/MobileApp/src/images/cover.jpg b/MobileApp/src/images/cover.jpg deleted file mode 100644 index 67d751ae7..000000000 Binary files a/MobileApp/src/images/cover.jpg and /dev/null differ diff --git a/MobileApp/src/images/defaultLogo/appLogo.png b/MobileApp/src/images/defaultLogo/appLogo.png new file mode 100644 index 000000000..8e4ac8704 Binary files /dev/null and b/MobileApp/src/images/defaultLogo/appLogo.png differ diff --git a/MobileApp/src/images/logos/logosAny/5172278581526528_1579180619_PARK.PNG b/MobileApp/src/images/logos/logosAny/5172278581526528_1579180619_PARK.PNG new file mode 100644 index 000000000..be6473e7f Binary files /dev/null and b/MobileApp/src/images/logos/logosAny/5172278581526528_1579180619_PARK.PNG differ diff --git a/MobileApp/src/images/logos/logosAny/5859688990638080_1579622048_New_Project_7.png b/MobileApp/src/images/logos/logosAny/5859688990638080_1579622048_New_Project_7.png new file mode 100644 index 000000000..736cb4920 Binary files /dev/null and b/MobileApp/src/images/logos/logosAny/5859688990638080_1579622048_New_Project_7.png differ diff --git a/MobileApp/src/images/logos/logosAny/6051626893180928_1579684224_PARK.png b/MobileApp/src/images/logos/logosAny/6051626893180928_1579684224_PARK.png new file mode 100644 index 000000000..dafc8883e Binary files /dev/null and b/MobileApp/src/images/logos/logosAny/6051626893180928_1579684224_PARK.png differ diff --git a/MobileApp/src/images/logos/logosAny/6051626893180928_1579684250_PARK.svg b/MobileApp/src/images/logos/logosAny/6051626893180928_1579684250_PARK.svg new file mode 100644 index 000000000..b87a26ebf --- /dev/null +++ b/MobileApp/src/images/logos/logosAny/6051626893180928_1579684250_PARK.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + diff --git a/MobileApp/src/screens/AboutScreen/AboutScreen.js b/MobileApp/src/screens/AboutScreen/AboutScreen.js index 6a9b935f0..8e08c1fb6 100644 --- a/MobileApp/src/screens/AboutScreen/AboutScreen.js +++ b/MobileApp/src/screens/AboutScreen/AboutScreen.js @@ -1,100 +1,115 @@ import * as React from 'react'; -import { View, Image, Text, Dimensions, StyleSheet, Linking,ImageBackground } from 'react-native' -import { Divider } from 'react-native-paper'; -import {SLOGO, COVER, LOGO} from '../../images/index' +import { + View, + Image, + Text, + Dimensions, + StyleSheet, + Linking, + ImageBackground, +} from 'react-native'; +import {Divider} from 'react-native-paper'; +import {SLOGO, COVER, LOGO} from '../../images/index'; class AboutScreen extends React.Component { + constructor(props) { + super(props); + } - constructor(props) { - super(props) - } + static navigationOptions = ({navigation}) => { + return { + headerTitle: 'About Sri Lankan Wild Life Park App', + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: 'white', + }; + }; - static navigationOptions = ({ navigation }) => { - return { - headerTitle: "About Sri Lankan National Park App", - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: 'white', - - } - } - - render() { - return ( - - - - Developed By - - - - - - This app is developed by - ScoreLab origanization with the collaboration of Department of Wild Life Conservation-Sri Lanka for animal conservation purposes.{'\n'}{'\n'} - For more information contact us: - Linking.openURL('https://mail.google.com')}> elly@scorelab.org{'\n'}{'\n'} - Linking.openURL('http://www.scorelab.org/')}>Visits http://www.scorelab.org/ - {'\n'} - - - - - - - - ); - } + render() { + return ( + + + + Developed By + + + + + + + This app is developed by ScoreLab origanization with the + collaboration of Department of Wild Life Conservation-Sri Lanka + for animal conservation purposes.{'\n'} + {'\n'} + For more information contact us: + Linking.openURL('https://mail.google.com')}> + {' '} + elly@scorelab.org + + {'\n'} + {'\n'} + Linking.openURL('http://www.scorelab.org/')}> + Visits http://www.scorelab.org/ + + {'\n'} + + + + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'flex-start', - alignItems: 'center', - alignSelf: 'stretch', - width: Dimensions.get('window').width - }, - logo: { - width: 90, - height: 90, - margin: 10, - resizeMode: 'stretch' - }, - bigText: { - textAlign: 'center', - color: 'black', - fontSize: 20 - }, - companyLogos: { - width: 200, - height: 100, - resizeMode: 'stretch', - borderRadius: 20 - }, - cmpLogoCntner: { - margin: 10, - flexDirection: 'row', - justifyContent: 'center', - alignItems: 'center' - }, - info: { - marginTop: 20, - padding: 0 - }, - paragraph: { - textAlign: 'justify', - color: 'black', - fontSize: 17, - margin: 5, - fontWeight: '100', - padding: 10 - }, - imgConatiner: { - width: Dimensions.get('window').width, - alignItems: 'center', - height: Dimensions.get('window').height, - } -}) -export default AboutScreen; \ No newline at end of file + container: { + flex: 1, + justifyContent: 'flex-start', + alignItems: 'center', + alignSelf: 'stretch', + width: Dimensions.get('window').width, + }, + logo: { + width: 90, + height: 90, + margin: 10, + resizeMode: 'stretch', + }, + bigText: { + textAlign: 'center', + color: 'black', + fontSize: 20, + }, + companyLogos: { + width: 200, + height: 100, + resizeMode: 'stretch', + borderRadius: 20, + }, + cmpLogoCntner: { + margin: 10, + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + }, + info: { + marginTop: 20, + padding: 0, + }, + paragraph: { + textAlign: 'justify', + color: 'black', + fontSize: 17, + margin: 5, + fontWeight: '100', + padding: 10, + }, + imgConatiner: { + width: Dimensions.get('window').width, + alignItems: 'center', + height: Dimensions.get('window').height, + }, +}); +export default AboutScreen; diff --git a/MobileApp/src/screens/DiscoverScreen/DiscoverScreen.js b/MobileApp/src/screens/DiscoverScreen/DiscoverScreen.js index 13ea8c904..71fe11be3 100644 --- a/MobileApp/src/screens/DiscoverScreen/DiscoverScreen.js +++ b/MobileApp/src/screens/DiscoverScreen/DiscoverScreen.js @@ -1,178 +1,208 @@ import * as React from 'react'; -import { View, StyleSheet, PermissionsAndroid, Image} from 'react-native' +import {View, StyleSheet, PermissionsAndroid, Alert} from 'react-native'; import MapView from 'react-native-maps'; -import { Marker } from 'react-native-maps'; +import {Marker} from 'react-native-maps'; import Geolocation from '@react-native-community/geolocation'; -import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator' -import { NavigationEvents } from 'react-navigation' +import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator'; +import {NavigationEvents} from 'react-navigation'; import database from '@react-native-firebase/database'; -import { generateResult } from '../../components/UserDataHandling/UserDataHandling'; -import {MAPMARKER} from '../../images/index' -var MapStyle = require('../../config/map.json') +import {generateResult} from '../../components/UserDataHandling/UserDataHandling'; +import {MAPMARKER} from '../../images/index'; +var MapStyle = require('../../config/map.json'); class DiscoverScreen extends React.Component { + static navigationOptions = ({navigation}) => { + return { + headerTitle: 'Explore Near By', + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: 'white', + }; + }; - static navigationOptions = ({ navigation }) => { - return { - headerTitle: 'Explore Near By', - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: 'white', - } - } - - constructor(props) { - super(props) - - this.state = { - observations: [], - location: [82.0, 6.8], - activityIndicator: true - } - } + constructor(props) { + super(props); - componentDidMount() { - this.findCoordinates() - this.getObservations() - } + this.state = { + observations: [], + location: [82.0, 6.8], + activityIndicator: true, + }; + } - getObservations = async function () { - // Fetch the data snapshot - const data = await database().ref(`/usersObservations/`).once('value') - // console.log(data) - const val = data.val() + componentDidMount() { + this.findCoordinates(); + this.getObservations(); + } - let observations = [] - for (let i in val) { - let name = val[i].uname - let photo = val[i].uimg - let userNick = name.toLowerCase().replace(/ /g, '') - let time = new Date(val[i].time) - let crntTime = new Date().getTime() - let dif = crntTime - time - if (dif <= 604800000) { continue } - let photUrl = val[i].photoURL - let location = val[i].location - time = time.toString().split(" ") - time = time.splice(0, time.length - 1) - time = time.toString().replace(/,/g, ' ') - let result = generateResult(val[i]) - let address = val[i].address - let marker = - { - title: time, - cordinates: - { - latitude: parseFloat(location[1]), - longitude: parseFloat(location[0]) - }, - description: address.toString() + getObservations = async function() { + // Fetch the data snapshot + const data = await database() + .ref(`/usersObservations/`) + .once('value'); + // console.log(data); + const val = data.val(); - } - observations.push([name, photo, photUrl, location, time, userNick, result, marker, address]) - await this.setState({ - observations: observations, - }) - } + let observations = []; + for (let i in val) { + let name = val[i].uname; + let photo = val[i].uimg; + let userNick = name.toLowerCase().replace(/ /g, ''); + let time = new Date(val[i].time); + let crntTime = new Date().getTime(); + let dif = crntTime - time; + if (dif <= 604800000) { + continue; + } + let photUrl = val[i].photoURL; + let location = val[i].location; + time = time.toString().split(' '); + time = time.splice(0, time.length - 1); + time = time.toString().replace(/,/g, ' '); + let result = generateResult(val[i]); + let address = val[i].address; + let marker = { + title: time, + cordinates: { + latitude: parseFloat(location[1]), + longitude: parseFloat(location[0]), + }, + description: address.toString(), + }; + observations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + marker, + address, + ]); + await this.setState({ + observations: observations, + }); } + }; - findCoordinates = async () => { - try { - const granted = await PermissionsAndroid.request( - PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, + findCoordinates = async () => { + try { + const granted = await PermissionsAndroid.request( + PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, + ); + if (granted === PermissionsAndroid.RESULTS.GRANTED) { + // console.log('Location'); + await Geolocation.getCurrentPosition( + async position => { + const initialPosition = position; + const lon = parseFloat(initialPosition['coords']['longitude']); + const lat = parseFloat(initialPosition['coords']['latitude']); + await this.setState({ + location: [lon, lat], + activityIndicator: false, + }); + }, + error => { + console.log('Error', JSON.stringify(error)); + this.setState({ + activityIndicator: false, + }); + // this.props.navigation.navigate('CameraViewScreen'); + return Alert.alert( + 'Location Error', + 'Please turn on the location access.', ); - if (granted === PermissionsAndroid.RESULTS.GRANTED) { - console.log("Location") - await Geolocation.getCurrentPosition( - async position => { - const initialPosition = position; - const lon = parseFloat(initialPosition['coords']['longitude']) - const lat = parseFloat(initialPosition['coords']['latitude']) - await this.setState({ location: [lon, lat], activityIndicator: false }); - }, - error => console.log('Error', JSON.stringify(error)), - { enableHighAccuracy: false }, - ); - } else { - await this.setState({ - activityIndicator: false - }) - - } - } catch (err) { - console.log(err.message) - } - }; - - render() { - return ( - - - {this.state.activityIndicator ? - - - - : - - {this.state.observations.map((val, i) => ( - this.props.navigation.navigate('showDetailedPhoto', - { - img: val[2], - title: val[0], - subtitle: val[5], - user: val[1], - content: val[6], - showPhoto: this.props.navigation - } - )} - // image={'map'} - /> - ))} - - } - - + }, + {enableHighAccuracy: false}, ); + } else { + await this.setState({ + activityIndicator: false, + }); + } + } catch (err) { + console.log(err.message); } + }; + + render() { + return ( + + + {this.state.activityIndicator ? ( + + + + ) : ( + + {this.state.observations.map((val, i) => ( + + this.props.navigation.navigate('showDetailedPhoto', { + img: val[2], + title: val[0], + subtitle: val[5], + user: val[1], + content: val[6], + showPhoto: this.props.navigation, + }) + } + // image={'map'} + /> + ))} + + )} + + ); + } } const styles = StyleSheet.create({ - MainContainer: { - position: 'absolute', - top: 0, - left: 0, - right: 0, - bottom: 0, - alignItems: 'center', - justifyContent: 'flex-end', - }, - mapStyle: { - position: 'absolute', - top: 0, - left: 0, - right: 0, - bottom: 0, - }, - indicator: { - width: "100%", - backgroundColor: 'grey' - } + MainContainer: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + alignItems: 'center', + justifyContent: 'flex-end', + }, + mapStyle: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + }, + indicator: { + width: '100%', + backgroundColor: 'grey', + }, }); -export default DiscoverScreen; \ No newline at end of file +export default DiscoverScreen; diff --git a/MobileApp/src/screens/EmailAuthScreen/EmailAuthSignInScreen.js b/MobileApp/src/screens/EmailAuthScreen/EmailAuthSignInScreen.js index a08c8b405..e82b20413 100644 --- a/MobileApp/src/screens/EmailAuthScreen/EmailAuthSignInScreen.js +++ b/MobileApp/src/screens/EmailAuthScreen/EmailAuthSignInScreen.js @@ -112,9 +112,7 @@ export default class EmailAuthScreen extends React.Component { - - Email - + Email this.setState({email: text})} @@ -204,7 +202,7 @@ export default class EmailAuthScreen extends React.Component { const styles = StyleSheet.create({ fieldText: { fontFamily: 'ProximaNova-Regular', - fontWeight: '600' + fontWeight: '600', }, container: { flex: 1, @@ -222,7 +220,7 @@ const styles = StyleSheet.create({ height: 50, justifyContent: 'center', borderRadius: 10, - backgroundColor: '#2ecc71' + backgroundColor: '#2ecc71', }, logoIconContainer: { flexDirection: 'row', @@ -245,7 +243,7 @@ const styles = StyleSheet.create({ width: Dimensions.get('window').width, justifyContent: 'center', alignItems: 'center', - height: Dimensions.get('window').height + height: Dimensions.get('window').height, }, logoBtnCntner: { flex: 1, diff --git a/MobileApp/src/screens/FeedScreen/FeedScreen.js b/MobileApp/src/screens/FeedScreen/FeedScreen.js index 4734a20ed..eca6246a5 100644 --- a/MobileApp/src/screens/FeedScreen/FeedScreen.js +++ b/MobileApp/src/screens/FeedScreen/FeedScreen.js @@ -1,245 +1,301 @@ import * as React from 'react'; -import { View, StyleSheet,FlatList,Text,SafeAreaView, TouchableOpacity } from 'react-native' -import { Avatar} from 'react-native-paper'; -import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator' -import { CardComponent } from '../../components/CardComponent/CardComponent' +import { + View, + StyleSheet, + FlatList, + Text, + SafeAreaView, + TouchableOpacity, + Alert, +} from 'react-native'; +import {Avatar} from 'react-native-paper'; +import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator'; +import {CardComponent} from '../../components/CardComponent/CardComponent'; import auth from '@react-native-firebase/auth'; import database from '@react-native-firebase/database'; -import { generateResult } from '../../components/UserDataHandling/UserDataHandling'; +import {generateResult} from '../../components/UserDataHandling/UserDataHandling'; +import {checkNet} from '../../components/NetInfo/NetInfo'; class FeedScreen extends React.Component { + static navigationOptions = ({navigation}) => { + const {params = []} = navigation.state; + return { + headerTitle: 'Home', + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: '#fff', - static navigationOptions = ({ navigation }) => { - const { params = [] } = navigation.state - return { - headerTitle: 'Home', - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: '#fff', - - headerRight: () => navigation.navigate("Profile")} - > - {params.userPhoto!==''? - - : - - } - - , - } - } + headerRight: () => ( + navigation.navigate('Profile')}> + {params.userPhoto !== '' ? ( + + ) : ( + + )} + + ), + }; + }; - constructor(props) { - super(props) - this.state = { - observations: [], - activityIndicator: true, - refreshing: false, - } - } + constructor(props) { + super(props); + this.state = { + observations: [], + activityIndicator: true, + refreshing: false, + }; + } - componentDidMount() { - this.getUserData() - this.getObservations() - } + componentDidMount() { + this.getUserData(); + this.getObservations(); + } - getUserData = async function () { - const user = auth().currentUser; - // console.log(user) - const uid = user.uid - const ref = await database().ref('/users/').child(uid).once('value'); - const data = ref.val() - await this.props.navigation.setParams({ - userPhoto: data.photo, - userName: data.name - }) + getUserData = async function() { + let hasNet = await checkNet(); + if (hasNet !== true) { + Alert.alert( + 'Connectivity Error', + 'Please check your internet connectivity', + ); } + const user = auth().currentUser; + // console.log(user) + const uid = user.uid; + const ref = await database() + .ref('/users/') + .child(uid) + .once('value'); + const data = ref.val(); + await this.props.navigation.setParams({ + userPhoto: data.photo, + userName: data.name, + }); + }; + + getObservations = async () => { + // Fetch the data snapshot + const data = await database() + .ref(`/usersObservations/`) + .orderByKey() + .limitToLast(7) + .once('value'); + + const val = data.val(); - getObservations = async() =>{ - // Fetch the data snapshot - const data = await database().ref(`/usersObservations/`).orderByKey().limitToLast(10).once('value') - - const val = data.val() - - let observations = [] - let lastVisible = '' - for (let i in val) { - let name = val[i].uname - let photo = val[i].uimg - let userNick = name.toLowerCase().replace(/ /g, '') - let time = new Date(val[i].time) - let crntTime = new Date().getTime() - let dif = crntTime - time - if (dif <= 604800000) { continue } - let photUrl = val[i].photoURL - let location = val[i].location - time = time.toString().split(" ") - time = time.splice(0, time.length - 1) - time = time.toString().replace(/,/g, ' ') - let result = generateResult(val[i]) - let address = val[i].address - - observations.push([name, photo, photUrl, location, time, userNick, result, address]) - this.setState({ - observations: observations, - activityIndicator: false - }) - - lastVisible = i - } - if(observations.length>2){ - observations.pop() - } - - await this.setState({ - activityIndicator: false, - lastVisible: lastVisible - }) - // console.log("Get "+lastVisible) + let observations = []; + let lastVisible = ''; + for (let i in val) { + let name = val[i].uname; + let photo = val[i].uimg; + let userNick = name.toLowerCase().replace(/ /g, ''); + let time = new Date(val[i].time); + let crntTime = new Date().getTime(); + let dif = crntTime - time; + if (dif <= 604800000) { + continue; + } else if (val[i].verified !== 'verified') { + continue; + } + let photUrl = val[i].photoURL; + let location = val[i].location; + time = time.toString().split(' '); + time = time.splice(0, time.length - 1); + time = time.toString().replace(/,/g, ' '); + let result = generateResult(val[i]); + let address = val[i].address; + + observations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + address, + ]); + this.setState({ + observations: observations, + activityIndicator: false, + }); + + lastVisible = i; + } + if (observations.length > 2) { + observations.pop(); } - getMoreObservation= async () => { - // console.log("hello") - let lastVisible = this.state.lastVisible - - const data = await database().ref(`/usersObservations/`).orderByKey().endAt(lastVisible).limitToLast(10).once('value') - - const val = data.val() - // console.log(val) - let observations = [] - for (let i in val) { - // console.log(i) - let name = val[i].uname - let photo = val[i].uimg - let userNick = name.toLowerCase().replace(/ /g, '') - let time = new Date(val[i].time) - let crntTime = new Date().getTime() - let dif = crntTime - time - if (dif <= 604800000) { continue } - let photUrl = val[i].photoURL - let location = val[i].location - time = time.toString().split(" ") - time = time.splice(0, time.length - 1) - time = time.toString().replace(/,/g, ' ') - let result = generateResult(val[i]) - let address = val[i].address - // console.log(result) - observations.push([name, photo, photUrl, location, time, userNick, result, address]) - lastVisible = i - } - observations.pop() - await this.setState({ - observations: [...this.state.observations,...observations], - activityIndicator: false, - lastVisible: lastVisible - }) - // console.log("Get more"+lastVisible) + await this.setState({ + activityIndicator: false, + lastVisible: lastVisible, + }); + // console.log("Get "+lastVisible) + }; + + getMoreObservation = async () => { + // console.log("hello") + let lastVisible = this.state.lastVisible; + + const data = await database() + .ref(`/usersObservations/`) + .orderByKey() + .endAt(lastVisible) + .limitToLast(7) + .once('value'); + + const val = data.val(); + // console.log(val) + let observations = []; + for (let i in val) { + // console.log(i) + let name = val[i].uname; + let photo = val[i].uimg; + let userNick = name.toLowerCase().replace(/ /g, ''); + let time = new Date(val[i].time); + let crntTime = new Date().getTime(); + let dif = crntTime - time; + if (dif <= 604800000) { + continue; + } else if (val[i].verified !== 'verified') { + continue; + } + let photUrl = val[i].photoURL; + let location = val[i].location; + time = time.toString().split(' '); + time = time.splice(0, time.length - 1); + time = time.toString().replace(/,/g, ' '); + let result = generateResult(val[i]); + let address = val[i].address; + // console.log(result) + observations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + address, + ]); + lastVisible = i; } - renderHeader = () => { - try { - return ( - Items - ) - } - catch (error) { - console.log(error); - } - }; // Render Footer - renderFooter = () => { + observations.pop(); + await this.setState({ + observations: [...this.state.observations, ...observations], + activityIndicator: false, + lastVisible: lastVisible, + }); + // console.log("Get more"+lastVisible) + }; + renderHeader = () => { try { - // Check If Loading - if (this.state.activityIndicator) { + return Items; + } catch (error) { + console.log(error); + } + }; // Render Footer + renderFooter = () => { + try { + // Check If Loading + if (this.state.activityIndicator) { return ( - - ) - } - else { + + ); + } else { return null; - } + } + } catch (error) { + console.log(error); } - catch (error) { - console.log(error); - } - }; - - render() { - return ( - - - {this.state.activityIndicator ? - - - - : - - - - {this.state.observations.length > 0? - - ( - - )} - // Item Key - keyExtractor={(item, index) => String(index)} - // Header (Title) - // On End Reached (Takes a function) - - // ListHeaderComponent={this.renderHeader} - // Footer (Activity Indicator) - ListFooterComponent={()=>} - onEndReached={this.getMoreObservation} - // How Close To The End Of List Until Next Data Request Is Made - onEndReachedThreshold={0.1} - // Refreshing (Set To True When End Reached) - refreshing={this.state.activityIndicator} - /> - - : - - } - - - - } + }; + render() { + return ( + + {this.state.activityIndicator ? ( + + + + ) : ( + + + {this.state.observations.length > 0 ? ( + + ( + + )} + // Item Key + keyExtractor={(item, index) => String(index)} + // Header (Title) + // On End Reached (Takes a function) + // ListHeaderComponent={this.renderHeader} + // Footer (Activity Indicator) + ListFooterComponent={() => ( + + )} + onEndReached={this.getMoreObservation} + // How Close To The End Of List Until Next Data Request Is Made + onEndReachedThreshold={0.1} + // Refreshing (Set To True When End Reached) + refreshing={this.state.activityIndicator} + /> + + ) : ( + + )} - - ); - } + + )} + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'flex-start', - alignItems: 'center', - alignSelf: 'stretch', - }, - welcome: { - fontSize: 25 - } -}) -export default FeedScreen; \ No newline at end of file + container: { + flex: 1, + justifyContent: 'flex-start', + alignItems: 'center', + alignSelf: 'stretch', + }, + welcome: { + fontSize: 25, + }, +}); +export default FeedScreen; diff --git a/MobileApp/src/screens/FormScreen/FormScreen.js b/MobileApp/src/screens/FormScreen/FormScreen.js index a5e828165..b81cd646f 100644 --- a/MobileApp/src/screens/FormScreen/FormScreen.js +++ b/MobileApp/src/screens/FormScreen/FormScreen.js @@ -1,263 +1,327 @@ import * as React from 'react'; -import { View, StyleSheet, Image, ScrollView, TouchableOpacity,Alert, ImageBackground } from 'react-native' -import CameraRoll from "@react-native-community/cameraroll"; -import { ToggleButtonGroupHorizontal, TextInputGroupHorizontal, UneditableComponent } from '../../components/FormComponents/FormComponents' +import { + View, + StyleSheet, + Image, + ScrollView, + TouchableOpacity, + Alert, + ImageBackground, +} from 'react-native'; +import { + ToggleButtonGroupHorizontal, + TextInputGroupHorizontal, + UneditableComponent, +} from '../../components/FormComponents/FormComponents'; import Geolocation from '@react-native-community/geolocation'; import auth from '@react-native-firebase/auth'; import database from '@react-native-firebase/database'; import storage from '@react-native-firebase/storage'; -import { Button } from 'react-native-paper' -import { generateUUID } from '../../components/UserDataHandling/UserDataHandling' -import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator' -import { googleMapAPIKey } from '../../config/config' -import {SmallDialog} from '../../components/SmallDialog/SmallDialog' - +import {Button} from 'react-native-paper'; +import {generateUUID} from '../../components/UserDataHandling/UserDataHandling'; +import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator'; +import {googleMapAPIKey} from '../../config/config'; +import {SmallDialog} from '../../components/SmallDialog/SmallDialog'; class FormScreen extends React.Component { + static navigationOptions = ({navigation}) => { + const {params = {}} = navigation.state; + return { + headerTitle: 'Observation', + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: 'white', + headerRight: () => ( + + ), + }; + }; - static navigationOptions = ({ navigation }) => { - const { params = {} } = navigation.state; - return { - headerTitle: 'Observation', - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: 'white', - headerRight: () => - } - } - - constructor(props) { - super(props); - let date = new Date() - let time = date.getTime() - date = date.toString().split(" ") - date = date.splice(0, date.length - 2) - this.state = { - photos: this.props.navigation.getParam('dataUri'), - location: ['', ''], - activityIndicator: false, - address: [], - date: date, - isAlive: 1, - verified: false, - notes: '', - park: '', - uid: '', - uname: '', - uimg: '', - type: '', - time: time, - sDialogVisible: false - }; + constructor(props) { + super(props); + let date = new Date(); + let time = date.getTime(); + date = date.toString().split(' '); + date = date.splice(0, date.length - 2); + this.state = { + photos: this.props.navigation.getParam('dataUri'), + location: ['', ''], + activityIndicator: false, + address: [], + date: date, + isAlive: 1, + verified: 'pending', + notes: '', + park: '', + uid: '', + uname: '', + uimg: '', + type: '', + time: time, + sDialogVisible: false, + leave: false, + }; + } - } + componentDidMount() { + this.findCoordinates(); + this.getUserData(); + this.props.navigation.setParams({ + handlePress: () => this.uploadData(), + }); + } - componentDidMount() { - this.findCoordinates() - this.getUserData() - this.props.navigation.setParams({ - handlePress: () => this.uploadData(), - }); + componentDidUpdate() { + if (this.state.leave) { + this.props.navigation.navigate('CameraViewScreen'); } + } - getUserData = async function () { - const uid =await auth().currentUser.uid; - const user = await database().ref(`/users/${uid}`).once('value') - const uname = user.val().name - const uimg = user.val().photo - await this.setState({ - uid: uid, - uname: uname, - uimg: uimg - }) - } + getUserData = async function() { + const uid = await auth().currentUser.uid; + const user = await database() + .ref(`/users/${uid}`) + .once('value'); + const uname = user.val().name; + const uimg = user.val().photo; + await this.setState({ + uid: uid, + uname: uname, + uimg: uimg, + }); + }; - uploadData = async function () { - this.setState({ - activityIndicator: true - }) - - const ref = database().ref(`/usersObservations`); - const randomID = generateUUID() - const storageRef = storage().ref('/observations/' + randomID + '.jpeg') - await storageRef.putFile(this.state.photos) - const url = await storageRef.getDownloadURL() + uploadData = async function() { + this.setState({ + activityIndicator: true, + }); - await ref.push({ - photoURL: url, - isAlive: this.state.isAlive, - location: this.state.location, - time: this.state.time, - isAlive: this.state.isAlive, - address: this.state.address, - verified: this.state.verified, - notes: this.state.notes, - park: this.state.park, - uid: this.state.uid, - uname: this.state.uname, - uimg: this.state.uimg, - type: this.state.type, - address: this.state.address.toString() - }); + const ref = database().ref(`/usersObservations`); + const randomID = generateUUID(); + const storageRef = storage().ref( + '/observations/original/' + randomID + '.jpeg', + ); + await storageRef.putFile(this.state.photos); + const url = await storageRef.getDownloadURL(); - await this.setState({ - activityIndicator: false, - sDialogVisible: true - }) + await ref.push({ + photoURL: url, + isAlive: this.state.isAlive, + location: this.state.location, + time: this.state.time, + isAlive: this.state.isAlive, + address: this.state.address, + verified: this.state.verified, + notes: this.state.notes, + park: this.state.park, + uid: this.state.uid, + uname: this.state.uname, + uimg: this.state.uimg, + type: this.state.type, + address: this.state.address.toString(), + }); - } + await this.setState({ + activityIndicator: false, + sDialogVisible: true, + }); + }; - requestLocationPermission = async function () { - try { - const granted = await PermissionsAndroid.request( - PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, - ); - if (granted === PermissionsAndroid.RESULTS.GRANTED) { - return true - } else { - return false - } - } catch (err) { - return false - } + requestLocationPermission = async function() { + try { + const granted = await PermissionsAndroid.request( + PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, + ); + if (granted === PermissionsAndroid.RESULTS.GRANTED) { + return true; + } else { + return false; + } + } catch (err) { + return false; } + }; - findCoordinates = () => { - if (this.requestLocationPermission) { - Geolocation.getCurrentPosition( - position => { - const initialPosition = position; - console.log(initialPosition) - const lon = initialPosition['coords']['longitude'] - const lat = initialPosition['coords']['latitude'] - console.log(lon, lat, googleMapAPIKey) - fetch('https://maps.googleapis.com/maps/api/geocode/json?address=' + lat + ',' + lon + '&key=' + googleMapAPIKey) - .then((response) => response.json()) - .then((responseJson) => { - this.setState({ - address: responseJson.results.length > 0 ? responseJson.results[0].formatted_address.split(",") : "Unnamed location" - }) - console.log('ADDRESS GEOCODE: => ' + JSON.stringify(responseJson.results[0].formatted_address)); - }) - this.setState({ location: [initialPosition['coords']['longitude'], initialPosition['coords']['latitude']] }); - }, - error => console.log('Error', JSON.stringify(error)), - { enableHighAccuracy: false }, - ); - } - - }; - - FormComponentCallbackFunction = (childData) => { - let type = childData[1] - let obj = {} - obj[type] = childData[0] - this.setState(obj) - console.log(childData) + findCoordinates = () => { + if (this.requestLocationPermission) { + Geolocation.getCurrentPosition( + position => { + const initialPosition = position; + const lon = initialPosition['coords']['longitude']; + const lat = initialPosition['coords']['latitude']; + fetch( + 'https://maps.googleapis.com/maps/api/geocode/json?address=' + + lat + + ',' + + lon + + '&key=' + + googleMapAPIKey, + ) + .then(response => response.json()) + .then(responseJson => { + this.setState({ + address: + responseJson.results.length > 0 + ? responseJson.results[0].formatted_address.split(',') + : 'Unnamed location', + }); + console.log( + 'ADDRESS GEOCODE: => ' + + JSON.stringify(responseJson.results[0].formatted_address), + ); + }); + this.setState({ + location: [ + initialPosition['coords']['longitude'], + initialPosition['coords']['latitude'], + ], + }); + }, + error => { + console.log('Error', JSON.stringify(error)); + this.props.navigation.navigate('CameraViewScreen'); + return Alert.alert( + 'Location Error', + 'Please turn on the location access.', + ); + }, + {enableHighAccuracy: false}, + ); + } else { + this.props.navigation.navigate('CameraViewScreen'); + return Alert.alert( + 'Permission Denied', + 'Please allow the location permission.', + ); } + }; - smallDialogCallback =(child) => { - this.setState({ - sDialogVisible: child - }) - if(!child){ - this.props.navigation.navigate('CameraViewScreen') - } - } + FormComponentCallbackFunction = childData => { + let type = childData[1]; + let obj = {}; + obj[type] = childData[0]; + this.setState(obj); + }; - render() { - const { navigate } = this.props.navigation; - return ( - - - navigate('showPhoto', { img: this.state.photos })} - > - - - + smallDialogCallback = child => { + console.log(child); + this.setState({ + sDialogVisible: child, + leave: !child, + }); + }; - - - - - - + render() { + const {navigate} = this.props.navigation; + return ( + + + navigate('showPhoto', {img: this.state.photos})}> + + + - - - - - - - - - + + + + + + - - ); - } + + + + + + + + + + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'flex-start', - alignSelf: 'stretch', - //backgroundColor: getRandomColor(), - }, - welcome: { - fontSize: 25 - }, - imgHolder: { - marginLeft: 10, - marginTop: 10, - marginBottom: 10, - width: "100%", - justifyContent: 'center', - - }, - bottom: { - flex: 1, - justifyContent: 'flex-end', - marginBottom: 10, - marginLeft: 0, - alignItems: 'center' - } -}) + container: { + flex: 1, + justifyContent: 'flex-start', + alignSelf: 'stretch', + }, + welcome: { + fontSize: 25, + }, + imgHolder: { + marginLeft: 10, + marginTop: 10, + marginBottom: 10, + width: '100%', + justifyContent: 'center', + }, + bottom: { + flex: 1, + justifyContent: 'flex-end', + marginBottom: 10, + marginLeft: 0, + alignItems: 'center', + }, +}); export default FormScreen; - diff --git a/MobileApp/src/screens/LandingScreen/LandingScreen.js b/MobileApp/src/screens/LandingScreen/LandingScreen.js index 90235715e..3ae7be781 100644 --- a/MobileApp/src/screens/LandingScreen/LandingScreen.js +++ b/MobileApp/src/screens/LandingScreen/LandingScreen.js @@ -1,44 +1,49 @@ import * as React from 'react'; -import { View, StyleSheet, Image, Dimensions } from 'react-native' +import {View, StyleSheet, Image, Dimensions, Alert} from 'react-native'; import auth from '@react-native-firebase/auth'; -import {LOGO} from '../../images/index' +import {LOGO} from '../../images/index'; +import SplashScreen from 'react-native-smart-splash-screen'; class LandingScreen extends React.Component { - componentDidMount(){ - auth().onAuthStateChanged( user => { - if (user!==null) { - this.props.navigation.navigate('App') - }else { - this.props.navigation.navigate('SignIn') - } - }) - } + componentDidMount() { + SplashScreen.close({ + animationType: SplashScreen.animationType.fade, + duration: 850, + delay: 500, + }); + auth().onAuthStateChanged(user => { + if (user !== null) { + this.props.navigation.navigate('App'); + } else { + this.props.navigation.navigate('SignIn'); + } + }); + } - render() { - return ( - - - - - ); - } + render() { + return ( + + + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '#F0FFFF', - width: Dimensions.get('window').width - }, - img: { - width: 100, - height: 100, - resizeMode: 'stretch' - }, - welcome: { - fontSize: 25 - } -}) -export default LandingScreen; \ No newline at end of file + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#F0FFFF', + width: Dimensions.get('window').width, + }, + img: { + width: 100, + height: 100, + resizeMode: 'stretch', + }, + welcome: { + fontSize: 25, + }, +}); +export default LandingScreen; diff --git a/MobileApp/src/screens/ParkDetails/ParkDetails.js b/MobileApp/src/screens/ParkDetails/ParkDetails.js index f7b644b77..c400ca020 100644 --- a/MobileApp/src/screens/ParkDetails/ParkDetails.js +++ b/MobileApp/src/screens/ParkDetails/ParkDetails.js @@ -1,131 +1,181 @@ import * as React from 'react'; -import { View, Text, Dimensions,ImageBackground,ScrollView, StyleSheet } from 'react-native' -import { Button,List, Avatar, Divider } from 'react-native-paper' -import { TouchableOpacity } from 'react-native-gesture-handler'; +import { + View, + Text, + Dimensions, + ImageBackground, + ScrollView, + StyleSheet, + Alert, +} from 'react-native'; +import {List, Avatar} from 'react-native-paper'; +import {TouchableOpacity} from 'react-native-gesture-handler'; import database from '@react-native-firebase/database'; +import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator'; +import {checkNet} from '../../components/NetInfo/NetInfo'; class ParkDetails extends React.Component { + constructor(props) { + super(props); + this.state = { + species: [], + activityIndicator: true, + }; + } - constructor(props) { - super(props) - this.state={ - species: [] - } - } - - static navigationOptions = ({ navigation }) => { - const { params = [] } = navigation.state - return { - headerTitle: params.title, - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: 'white', + static navigationOptions = ({navigation}) => { + const {params = []} = navigation.state; + return { + headerTitle: params.title, + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: 'white', + }; + }; - } - } + componentDidMount() { + this.getParkDetails(); + } - componentDidMount(){ - this.getParkDetails() - } + // updateParkDetails = async function() { + // const data = await database().ref(`/parks/anp`) + // data.push({ + // name: 'Sri Lankan sambar deer', + // sname: 'Rusa unicolor unicolor', + // description: '', + // img: 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Sambar_%28Cervus_unicolor_unicolor%29_male.jpg/1920px-Sambar_%28Cervus_unicolor_unicolor%29_male.jpg' - // updateParkDetails = async function() { - // const data = await database().ref(`/parks/anp`) - // data.push({ - // name: 'Sri Lankan sambar deer', - // sname: 'Rusa unicolor unicolor', - // description: '', - // img: 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Sambar_%28Cervus_unicolor_unicolor%29_male.jpg/1920px-Sambar_%28Cervus_unicolor_unicolor%29_male.jpg' + // }) + // } - // }) - // } - - getParkDetails = async function () { - // console.log(this.props.navigation.getParam('code')) - const data = await database().ref(`/parks/${this.props.navigation.getParam('code')}`).orderByKey().once('value') - const snapshot = data.val() - // console.log(snapshot) - let species = [] - for(let i in snapshot){ - species.push([snapshot[i].name, snapshot[i].sname, snapshot[i].img, snapshot[i].description]) - } + getParkDetails = async function() { + let hasNet = await checkNet(); + if (hasNet !== true) { + Alert.alert( + 'Connectivity Error', + 'Please check your internet connectivity', + ); + } - await this.setState({ - species: species - }) - // console.log(species) + const data = await database() + .ref(`/parks/${this.props.navigation.getParam('code')}`) + .orderByKey() + .once('value'); + const snapshot = data.val(); + // console.log(snapshot) + let species = []; + for (let i in snapshot) { + species.push([ + snapshot[i].name, + snapshot[i].sname, + snapshot[i].img, + snapshot[i].description, + ]); } - render() { - return ( - - - {this.props.navigation.getParam('title')} - {this.props.navigation.getParam('subtitle')} - - - {this.state.species.length>0? - - {this.state.species.map((val,i)=>{ - return( - this.props.navigation.navigate('SpeciesDetailsScreen', {content: val})} - key={i} - style={{backgroundColor: '#014421', marginLeft: 5, marginRight: 5, marginBottom: 2, borderRadius: 10 }} - > - } - /> - - ) - })} - - : - null - - } - + await this.setState({ + species: species, + activityIndicator: false, + }); + // console.log(species) + }; - ); - } + render() { + return ( + + + + {this.props.navigation.getParam('title')} + + + {this.props.navigation.getParam('subtitle')} + + + {this.state.activityIndicator ? ( + + + + ) : ( + + {this.state.species.map((val, i) => { + return ( + + this.props.navigation.navigate('SpeciesDetailsScreen', { + content: val, + }) + } + key={i} + style={{ + backgroundColor: '#014421', + marginLeft: 5, + marginRight: 5, + marginBottom: 2, + borderRadius: 10, + }}> + ( + + )} + /> + + ); + })} + + )} + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'flex-start', - alignItems: 'center', - alignSelf: 'stretch', - width: Dimensions.get('window').width - }, - profileConatiner: { - width: Dimensions.get('window').width, - justifyContent: 'center', - alignItems: 'center', - padding: 10, - height: 270, - marginBottom: 5 - }, - title: { - color: 'white', - fontSize: 40, - textAlign: 'center', - }, - subtitle: { - color: 'white', - fontSize: 20, - }, - userPhoto: { - width: 100, - height: 100, - borderRadius: 100, - borderWidth: 1, - borderColor: 'white' - }, -}) -export default ParkDetails; \ No newline at end of file + container: { + flex: 1, + justifyContent: 'flex-start', + alignItems: 'center', + alignSelf: 'stretch', + width: Dimensions.get('window').width, + }, + profileConatiner: { + width: Dimensions.get('window').width, + justifyContent: 'center', + alignItems: 'center', + padding: 10, + height: 270, + marginBottom: 5, + }, + title: { + color: 'white', + fontSize: 40, + textAlign: 'center', + }, + subtitle: { + color: 'white', + fontSize: 20, + }, + userPhoto: { + width: 100, + height: 100, + borderRadius: 100, + borderWidth: 1, + borderColor: 'white', + }, +}); +export default ParkDetails; diff --git a/MobileApp/src/screens/ParkScreen/ParkScreen.js b/MobileApp/src/screens/ParkScreen/ParkScreen.js index 9c129964d..1b34ce790 100644 --- a/MobileApp/src/screens/ParkScreen/ParkScreen.js +++ b/MobileApp/src/screens/ParkScreen/ParkScreen.js @@ -1,113 +1,135 @@ import * as React from 'react'; -import { View, Text, Dimensions, StyleSheet } from 'react-native' -import {TileComponent} from '../../components/TileCompoent/TileComponent' -import {ScrollView} from 'react-native-gesture-handler' -import { Avatar, Button} from 'react-native-paper'; +import {View, Text, Dimensions, StyleSheet} from 'react-native'; +import {TileComponent} from '../../components/TileCompoent/TileComponent'; +import {ScrollView} from 'react-native-gesture-handler'; +import {Avatar, Button} from 'react-native-paper'; class ParkScreen extends React.Component { + constructor(props) { + super(props); + } - constructor(props) { - super(props) - } + static navigationOptions = ({navigation}) => { + return { + headerTitle: 'Sri Lankan Wild Life Parks', + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: 'white', + headerRight: () => ( + + ), + }; + }; - static navigationOptions = ({ navigation }) => { - return { - headerTitle: "Sri Lankan National Parks", - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: 'white', - headerRight: () => - } - } - - render() { - return ( - - - - - - - - - - - - - - - - - - - - ); - } + render() { + return ( + + + + + + + + + + + + + + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'flex-start', - alignItems: 'center', - alignSelf: 'stretch', - width: Dimensions.get('window').width, - }, -}) -export default ParkScreen; \ No newline at end of file + container: { + flex: 1, + justifyContent: 'flex-start', + alignItems: 'center', + alignSelf: 'stretch', + width: Dimensions.get('window').width, + }, +}); +export default ParkScreen; diff --git a/MobileApp/src/screens/ProfileScreen/ProfileScreen.js b/MobileApp/src/screens/ProfileScreen/ProfileScreen.js index 6635a5d78..cf476653f 100644 --- a/MobileApp/src/screens/ProfileScreen/ProfileScreen.js +++ b/MobileApp/src/screens/ProfileScreen/ProfileScreen.js @@ -1,339 +1,434 @@ import * as React from 'react'; -import { View, StyleSheet,FlatList, ImageBackground, Text, Image, Dimensions } from 'react-native' -import { Button, Menu, Avatar } from 'react-native-paper' -import { TouchableOpacity } from 'react-native-gesture-handler'; -import { generateResult } from '../../components/UserDataHandling/UserDataHandling' -import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator' +import { + View, + StyleSheet, + FlatList, + ImageBackground, + Text, + Image, + Dimensions, +} from 'react-native'; +import {Button, Menu, Avatar} from 'react-native-paper'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import {generateResult} from '../../components/UserDataHandling/UserDataHandling'; +import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator'; import auth from '@react-native-firebase/auth'; import database from '@react-native-firebase/database'; import Icon from 'react-native-vector-icons/dist/MaterialCommunityIcons'; class ProfileScreen extends React.Component { + static navigationOptions = ({navigation}) => { + const {params = []} = navigation.state; + return { + headerTitle: 'My Profile', + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: '#fff', + headerRight: () => ( + params.closeMenu()} + anchor={ + params.openMenu()}> + + + }> + params.onPressMenuLogout()} + title="LOGOUT" + /> + params.onPressMenuAbout()} + title="ABOUT App" + /> + + ), + }; + }; - static navigationOptions = ({ navigation }) => { - const { params = [] } = navigation.state - return { - headerTitle: 'My Profile', - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: '#fff', - headerRight: () => - params.closeMenu()} - anchor={ - params.openMenu()}> - - - } - > - params.onPressMenuLogout()} title="LOGOUT" /> - params.onPressMenuAbout()} title="ABOUT App" /> - - } - } + constructor(props) { + super(props); + this.state = { + userName: '', + userPhoto: '', + userNick: '', + uid: '', + userObservations: [], + noObs: 0, + activityIndicator: true, + refreshing: false, + showMenu: false, + }; + } - constructor(props) { - super(props) - this.state = { - userName: '', - userPhoto: '', - userNick: '', - uid: '', - userObservations: [], - noObs: 0, - activityIndicator: true, - refreshing: false, - showMenu: false - } - } + componentDidMount() { + this.getUserProfile(); + this.props.navigation.setParams({ + onPressMenuAbout: () => { + this.props.navigation.navigate('AboutScreen'); + this.closeMenu(); + }, + onPressMenuLogout: () => this.logutHandler(), + showMenu: false, + openMenu: () => this.openMenu(), + closeMenu: () => this.closeMenu(), + }); + database() + .ref('/usersObservations/') + .child(this.state.uid) + .on('child_added', () => { + this.getUserData(); + }); + } - componentDidMount() { - this.getUserProfile() - this.props.navigation.setParams({ - onPressMenuAbout: () => { - this.props.navigation.navigate("AboutScreen") - this.closeMenu() - }, - onPressMenuLogout: () => this.logutHandler(), - showMenu: false, - openMenu: ()=>this.openMenu(), - closeMenu: ()=> this.closeMenu() + componentDidUpdate() {} - }) - this.getUserData() - } + logutHandler = async () => { + await this.closeMenu(); + let result = await auth() + .signOut() + .then(() => console.log('Log out')); + }; - logutHandler = async () => { - this.closeMenu() - let result = await auth().signOut().then( - ()=>console.log("Log out") - ) - } + openMenu() { + this.props.navigation.setParams({ + showMenu: true, + }); + } - openMenu(){ - console.log("opened") - this.props.navigation.setParams({ - showMenu: true - }) - } + closeMenu() { + this.props.navigation.setParams({ + showMenu: false, + }); + } - closeMenu(){ - console.log("closed") - this.props.navigation.setParams({ - showMenu: false - }) - } + _onRefresh() { + this.setState({refreshing: true}); + this.getUserData().then(() => { + this.setState({refreshing: false}); + }); + } - _onRefresh() { - this.setState({ refreshing: true }); - this.getUserData().then(() => { - this.setState({ refreshing: false }); - }); - } + getUserProfile = async () => { + const user = auth().currentUser; + const uid = user.uid; + const ref = await database() + .ref('/users/') + .child(uid) + .once('value'); + const data = ref.val(); + console.log(data); + await this.setState({ + userName: data.name, + userNick: data.name.toLowerCase().replace(/ /g, ''), + userPhoto: data.photo, + uid: uid, + }); + }; - getUserProfile = async () =>{ - const user = auth().currentUser; - const uid = user.uid - const ref = await database().ref('/users/').child(uid).once('value'); - const data = ref.val() - console.log(data) - await this.setState({ - userName: data.name, - userNick: data.name.toLowerCase().replace(/ /g, ''), - userPhoto: data.photo, - uid: uid - }) - } + getUserData = async () => { + // Fetch the data snapshot + const data = await database() + .ref(`/usersObservations/`) + .orderByValue('uid') + .limitToLast(10) + .once('value'); - getUserData = async() =>{ - // Fetch the data snapshot - const data = await database().ref(`/usersObservations/`).orderByValue('uid').limitToLast(10).once('value') - - const val = data.val() + const val = data.val(); - let userObservations = [] - let lastVisible = '' - for (let i in val) { - let time = new Date(val[i].time) - let crntTime = new Date().getTime() - let dif = crntTime - time - if(val[i].uid!==this.state.uid){continue} - if(dif <= 604800000){continue} - let name = val[i].uname - let photo = val[i].uimg - let userNick = name.toLowerCase().replace(/ /g, '') - - let photUrl = val[i].photoURL - let location = val[i].location - time = time.toString().split(" ") - time = time.splice(0, time.length - 1) - time = time.toString().replace(/,/g, ' ') - let result = generateResult(val[i]) - let address = val[i].address - - userObservations.push([name, photo, photUrl, location, time, userNick, result, address]) - this.setState({ - userObservations: userObservations, - activityIndicator: false - }) - - lastVisible = i - } - if(userObservations.length>2){ - userObservations.pop() - } - // console.log(userObservations) - await this.setState({ - activityIndicator: false, - lastVisible: lastVisible, - noObs: userObservations.length - }) - } + let userObservations = []; + let lastVisible = ''; + for (let i in val) { + let time = new Date(val[i].time); + let crntTime = new Date().getTime(); + let dif = crntTime - time; + if (val[i].uid !== this.state.uid) { + continue; + } + let name = val[i].uname; + let photo = val[i].uimg; + let userNick = name.toLowerCase().replace(/ /g, ''); - getMoreUserData= async () => { - let lastVisible = this.state.lastVisible - - const data = await database().ref(`/usersObservations/`).orderByValue('uid').endAt(lastVisible).limitToLast(10).once('value') - - const val = data.val() - // console.log(val) - let userObservations = [] - for (let i in val) { - let name = val[i].uname - let photo = val[i].uimg - let userNick = name.toLowerCase().replace(/ /g, '') - let time = new Date(val[i].time) - let crntTime = new Date().getTime() - let dif = crntTime - time - if(val[i].uid!==this.state.uid){continue} - if(dif <= 604800000){continue} - let photUrl = val[i].photoURL - let location = val[i].location - time = time.toString().split(" ") - time = time.splice(0, time.length - 1) - time = time.toString().replace(/,/g, ' ') - let result = generateResult(val[i]) - let address = val[i].address - userObservations.push([name, photo, photUrl, location, time, userNick, result, address]) - lastVisible = i - } - if(userObservations.length>2){ - userObservations.pop() - } - await this.setState({ - userObservations: [...this.state.userObservations,...userObservations], - activityIndicator: false, - lastVisible: lastVisible, - noObs: this.state.userObservations.length - }) + let photUrl = val[i].photoURL; + let location = val[i].location; + time = time.toString().split(' '); + time = time.splice(0, time.length - 1); + time = time.toString().replace(/,/g, ' '); + let result = generateResult(val[i]); + let address = val[i].address; + let verified = val[i].verified; + userObservations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + address, + verified, + ]); + this.setState({ + userObservations: userObservations, + activityIndicator: false, + }); + + lastVisible = i; + } + if (userObservations.length > 2) { + userObservations.pop(); } + // console.log(userObservations) + await this.setState({ + activityIndicator: false, + lastVisible: lastVisible, + noObs: userObservations.length, + }); + }; - render() { - return ( - - {this.state.activityIndicator ? - - - - : - - {this.state.userPhoto!==''? - - {this.state.userNick} - - - {this.state.userName} - - {this.state.noObs} - - : - - {this.state.userNick} - - {this.state.userName} - - {this.state.noObs} - - } - - {this.state.userObservations.length > 0 - ? - ( - this.props.navigation.navigate('showDetailedPhoto', - { - img: item[2], - title: this.state.userName, - subtitle: this.state.userNick, - user: this.state.userPhoto, - content: item[6], - showPhoto: this.props.navigation - } - )} - style={{justifyContent: 'center'}} - > - - - )} - // Item Key - keyExtractor={(item, index) => String(index)} - // Header (Title) - // On End Reached (Takes a function) + getMoreUserData = async () => { + let lastVisible = this.state.lastVisible; - // ListHeaderComponent={Hello} - // Footer (Activity Indicator) - ListFooterComponent={()=>} - onEndReached={this.getMoreUserData} - // How Close To The End Of List Until Next Data Request Is Made - onEndReachedThreshold={0.1} - // Refreshing (Set To True When End Reached) - refreshing={this.state.activityIndicator} - /> - : - - } - - } - - ); + const data = await database() + .ref(`/usersObservations/`) + .orderByValue('uid') + .endAt(lastVisible) + .limitToLast(10) + .once('value'); + + const val = data.val(); + // console.log(val) + let userObservations = []; + for (let i in val) { + let name = val[i].uname; + let photo = val[i].uimg; + let userNick = name.toLowerCase().replace(/ /g, ''); + let time = new Date(val[i].time); + let crntTime = new Date().getTime(); + let dif = crntTime - time; + if (val[i].uid !== this.state.uid) { + continue; + } + let photUrl = val[i].photoURL; + let location = val[i].location; + time = time.toString().split(' '); + time = time.splice(0, time.length - 1); + time = time.toString().replace(/,/g, ' '); + let result = generateResult(val[i]); + let address = val[i].address; + let verified = val[i].verified; + userObservations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + address, + verified, + ]); + lastVisible = i; + } + if (userObservations.length > 2) { + userObservations.pop(); } + await this.setState({ + userObservations: [...this.state.userObservations, ...userObservations], + activityIndicator: false, + lastVisible: lastVisible, + noObs: this.state.userObservations.length, + }); + }; + + render() { + return ( + + {this.state.activityIndicator ? ( + + + + ) : ( + + {this.state.userPhoto !== '' ? ( + + {this.state.userNick} + + + {this.state.userName} + + {this.state.noObs} + + ) : ( + + {this.state.userNick} + + {this.state.userName} + + {this.state.noObs} + + )} + + {this.state.userObservations.length > 0 ? ( + ( + + this.props.navigation.navigate('showDetailedPhoto', { + img: item[2], + title: this.state.userName, + subtitle: this.state.userNick, + user: this.state.userPhoto, + content: item[6], + showPhoto: this.props.navigation, + }) + } + style={{justifyContent: 'center'}}> + + + + {item[8][0].toUpperCase()} + + + + + )} + // Item Key + keyExtractor={(item, index) => String(index)} + // Header (Title) + // On End Reached (Takes a function) + + // ListHeaderComponent={Hello} + // Footer (Activity Indicator) + ListFooterComponent={() => ( + + )} + onEndReached={this.getMoreUserData} + // How Close To The End Of List Until Next Data Request Is Made + onEndReachedThreshold={0.1} + // Refreshing (Set To True When End Reached) + refreshing={this.state.activityIndicator} + /> + ) : ( + + )} + + )} + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'flex-start', - alignItems: 'center', - alignSelf: 'stretch', - width: '100%' - }, - profileConatiner: { - width: Dimensions.get('window').width, - justifyContent: 'center', - alignItems: 'center', - padding: 10, - backgroundColor: 'green' - }, - observationConatiner: { - width: '100%', - }, - userNick: { - color: 'white' - }, - observationTxt: { - color: 'white', - fontSize: 20 - }, - userName: { - fontWeight: 'bold', - color: 'white', - margin:5 - }, - obCount: { - color: 'white', - fontSize: 35 - }, - userPhoto: { - width: 100, - height: 100, - borderRadius: 100, - borderWidth: 1, - borderColor: 'white' - }, - img: { - width: Dimensions.get('window').width / 3.085, - height: Dimensions.get('window').width / 3.5, - margin: 2, - justifyContent: 'center', - borderRadius: 5 - }, - imgConatiner: { - justifyContent: 'center', - alignItems: 'center', - marginTop: 5, - width: Dimensions.get('window').width - }, - scrollView: { - width: Dimensions.get('window').width, - marginBottom: 10, - - }, -}) -export default ProfileScreen; \ No newline at end of file + container: { + flex: 1, + justifyContent: 'flex-start', + alignItems: 'center', + alignSelf: 'stretch', + width: '100%', + }, + profileConatiner: { + width: Dimensions.get('window').width, + justifyContent: 'center', + alignItems: 'center', + padding: 10, + backgroundColor: 'green', + }, + observationConatiner: { + width: '100%', + }, + userNick: { + color: 'white', + }, + observationTxt: { + color: 'white', + fontSize: 20, + }, + userName: { + fontWeight: 'bold', + color: 'white', + margin: 5, + }, + obCount: { + color: 'white', + fontSize: 35, + }, + userPhoto: { + width: 100, + height: 100, + borderRadius: 100, + borderWidth: 1, + borderColor: 'white', + }, + img: { + width: Dimensions.get('window').width / 3.085, + height: Dimensions.get('window').width / 3.5, + margin: 2, + borderRadius: 5, + flexDirection: 'row-reverse', + }, + imgConatiner: { + justifyContent: 'center', + alignItems: 'center', + marginTop: 5, + width: Dimensions.get('window').width, + }, + scrollView: { + width: Dimensions.get('window').width, + marginBottom: 10, + }, +}); +export default ProfileScreen; diff --git a/MobileApp/src/screens/SearchScreen/SearchScreen.js b/MobileApp/src/screens/SearchScreen/SearchScreen.js index fc9a0134a..4f06422f7 100644 --- a/MobileApp/src/screens/SearchScreen/SearchScreen.js +++ b/MobileApp/src/screens/SearchScreen/SearchScreen.js @@ -1,277 +1,349 @@ import * as React from 'react'; -import { View, StyleSheet, FlatList, TouchableOpacity, Image, Dimensions } from 'react-native' -import { Searchbar, Chip } from 'react-native-paper'; -import { generateResult } from '../../components/UserDataHandling/UserDataHandling' -import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator' +import { + View, + StyleSheet, + FlatList, + TouchableOpacity, + Image, + Dimensions, +} from 'react-native'; +import {Searchbar, Chip} from 'react-native-paper'; +import {generateResult} from '../../components/UserDataHandling/UserDataHandling'; +import ActivityIndicator from '../../components/ActivityIndicator/ActivityIndicator'; import database from '@react-native-firebase/database'; class SearchScreen extends React.Component { + constructor(props) { + super(props); + this.state = { + firstQuery: '', + observations: [], + type: 'all', + }; + } - constructor(props) { - super(props) - this.state = { - firstQuery: '', - observations: [], - type: 'all' - } - } + static navigationOptions = ({navigation}) => { + const {params = {}} = navigation.state; + return { + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: 'white', + headerRight: () => ( + params.handleText(query)} + value={params.query} + /> + ), + }; + }; - static navigationOptions = ({ navigation }) => { - const { params = {} } = navigation.state; - return { + componentDidMount() { + this.props.navigation.setParams({ + handleText: text => this.onTextChangeHandler(text), + query: this.state.firstQuery, + }); + // database().ref('/users/').on("value", snapshot=>{ + // this.getObservations('all') + // }) + this.getObservations(this.state.type); + } - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: 'white', - headerRight: () => params.handleText(query)} - value={params.query} - />, + onTextChangeHandler = text => { + this.setState({ + firstQuery: text, + }); + this.getObservations(text.toLowerCase()); + this.props.navigation.setParams({ + query: text, + }); + }; - } - } + getObservations = async type => { + // Fetch the data snapshot + const data = await database() + .ref(`/usersObservations/`) + .orderByValue(type) + .limitToLast(10) + .once('value'); - componentDidMount() { - this.props.navigation.setParams({ - handleText: (text) => this.onTextChangeHandler(text), - query: this.state.firstQuery - }); - // database().ref('/users/').on("value", snapshot=>{ - // this.getObservations('all') - // }) - this.getObservations(this.state.type) - } + const val = data.val(); - onTextChangeHandler = (text) => { - this.setState({ - firstQuery: text - }) - this.getObservations(text.toLowerCase()) - this.props.navigation.setParams({ - query: text + let userObservations = []; + let lastVisible = ''; + for (let i in val) { + let time = new Date(val[i].time); + let crntTime = new Date().getTime(); + let dif = crntTime - time; + if (dif <= 604800000) { + continue; + } else if (val[i].verified !== 'verified') { + continue; + } + let name = val[i].uname; + let photo = val[i].uimg; + let userNick = name.toLowerCase().replace(/ /g, ''); + + let photUrl = val[i].photoURL; + let location = val[i].location; + time = time.toString().split(' '); + time = time.splice(0, time.length - 1); + time = time.toString().replace(/,/g, ' '); + let result = generateResult(val[i]); + let address = val[i].address; + type.split(' ').map(keywd => { + let found = result.map(val => { + return val[1].toLowerCase().includes(keywd); }); + if (found.includes(true)) { + userObservations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + address, + ]); + lastVisible = i; + } else if (type === 'all') { + userObservations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + address, + ]); + lastVisible = i; + } + }); + this.setState({ + userObservations: userObservations, + activityIndicator: false, + }); + } + if (userObservations.length > 2) { + userObservations.pop(); } - getObservations = async(type) =>{ - // Fetch the data snapshot - const data = await database().ref(`/usersObservations/`).orderByValue(type).limitToLast(10).once('value') - - const val = data.val() + await this.setState({ + activityIndicator: false, + lastVisible: lastVisible, + noObs: userObservations.length, + }); + console.log('Get ' + lastVisible); + }; - let userObservations = [] - let lastVisible = '' - for (let i in val) { - let time = new Date(val[i].time) - let crntTime = new Date().getTime() - let dif = crntTime - time - if(dif <= 604800000){continue} - let name = val[i].uname - let photo = val[i].uimg - let userNick = name.toLowerCase().replace(/ /g, '') - - let photUrl = val[i].photoURL - let location = val[i].location - time = time.toString().split(" ") - time = time.splice(0, time.length - 1) - time = time.toString().replace(/,/g, ' ') - let result = generateResult(val[i]) - let address = val[i].address - type.split(" ").map((keywd) => { - let found = result.map((val) => { - return val[1].toLowerCase().includes(keywd) - }) - if (found.includes(true)) { + getMoreObservations = async type => { + console.log('hello'); + let lastVisible = this.state.lastVisible; - userObservations.push([name, photo, photUrl, location, time, userNick, result, address]) - lastVisible = i - } else if (type === 'all') { - userObservations.push([name, photo, photUrl, location, time, userNick, result, address]) - lastVisible = i - } - }) - this.setState({ - userObservations: userObservations, - activityIndicator: false - }) - - } - if(userObservations.length>2){ - userObservations.pop() - } - - await this.setState({ - activityIndicator: false, - lastVisible: lastVisible, - noObs: userObservations.length - }) - console.log("Get "+lastVisible) - } + const data = await database() + .ref(`/usersObservations/`) + .orderByValue(type) + .endAt(lastVisible) + .limitToLast(10) + .once('value'); - getMoreObservations= async (type) => { - console.log("hello") - let lastVisible = this.state.lastVisible - - const data = await database().ref(`/usersObservations/`).orderByValue(type).endAt(lastVisible).limitToLast(10).once('value') - - const val = data.val() - // console.log(val) - let userObservations = [] - for (let i in val) { - console.log(i) - let name = val[i].uname - let photo = val[i].uimg - let userNick = name.toLowerCase().replace(/ /g, '') - let time = new Date(val[i].time) - let crntTime = new Date().getTime() - let dif = crntTime - time - if (dif <= 604800000) { continue } - let photUrl = val[i].photoURL - let location = val[i].location - time = time.toString().split(" ") - time = time.splice(0, time.length - 1) - time = time.toString().replace(/,/g, ' ') - let result = generateResult(val[i]) - let address = val[i].address - - type.split(" ").map((keywd) => { - let found = result.map((val) => { - return val[1].toLowerCase().includes(keywd) - }) - if (found.includes(true)) { + const val = data.val(); + // console.log(val) + let userObservations = []; + for (let i in val) { + console.log(i); + let name = val[i].uname; + let photo = val[i].uimg; + let userNick = name.toLowerCase().replace(/ /g, ''); + let time = new Date(val[i].time); + let crntTime = new Date().getTime(); + let dif = crntTime - time; + if (dif <= 604800000) { + continue; + } else if (val[i].verified !== 'verified') { + continue; + } + let photUrl = val[i].photoURL; + let location = val[i].location; + time = time.toString().split(' '); + time = time.splice(0, time.length - 1); + time = time.toString().replace(/,/g, ' '); + let result = generateResult(val[i]); + let address = val[i].address; - userObservations.push([name, photo, photUrl, location, time, userNick, result, address]) - lastVisible = i - } else if (type === 'all') { - userObservations.push([name, photo, photUrl, location, time, userNick, result, address]) - lastVisible = i - } - }) - - } - if(userObservations.length>2){ - userObservations.pop() + type.split(' ').map(keywd => { + let found = result.map(val => { + return val[1].toLowerCase().includes(keywd); + }); + if (found.includes(true)) { + userObservations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + address, + ]); + lastVisible = i; + } else if (type === 'all') { + userObservations.push([ + name, + photo, + photUrl, + location, + time, + userNick, + result, + address, + ]); + lastVisible = i; } - await this.setState({ - userObservations: [...this.state.userObservations,...userObservations], - activityIndicator: false, - lastVisible: lastVisible, - noObs: this.state.userObservations.length - }) - console.log("Get more"+lastVisible) + }); } - - _onRefresh() { - this.setState({ refreshing: true }); - this.getObservations('all').then(() => { - this.setState({ refreshing: false }); - }); + if (userObservations.length > 2) { + userObservations.pop(); } + await this.setState({ + userObservations: [...this.state.userObservations, ...userObservations], + activityIndicator: false, + lastVisible: lastVisible, + noObs: this.state.userObservations.length, + }); + console.log('Get more' + lastVisible); + }; - render() { - return ( - - {this.state.activityIndicator ? - - - - : - - - this.getObservations('all')}>All - this.getObservations('male')}>Male - this.getObservations('female')}>Female - this.getObservations('die')}>Dead - - - ( - this.props.navigation.navigate('showDetailedPhoto', - { - img: item[2], - title: item[0], - subtitle: item[5], - user: item[1], - content: item[6], - showPhoto: this.props.navigation - } - )} - style={{justifyContent: 'center'}} - > - - - )} - // Item Key - keyExtractor={(item, index) => String(index)} - // Header (Title) - // On End Reached (Takes a function) - - // ListHeaderComponent={Hello} - // Footer (Activity Indicator) - ListFooterComponent={()=>} - onEndReached={this.getMoreObservations} - // How Close To The End Of List Until Next Data Request Is Made - onEndReachedThreshold={0.1} - // Refreshing (Set To True When End Reached) - refreshing={this.state.activityIndicator} - /> - - } + _onRefresh() { + this.setState({refreshing: true}); + this.getObservations('all').then(() => { + this.setState({refreshing: false}); + }); + } + render() { + return ( + + {this.state.activityIndicator ? ( + + + + ) : ( + + + this.getObservations('all')}> + All + + this.getObservations('alive')}> + Alive + + this.getObservations('die')}> + Dead + + ( + + this.props.navigation.navigate('showDetailedPhoto', { + img: item[2], + title: item[0], + subtitle: item[5], + user: item[1], + content: item[6], + showPhoto: this.props.navigation, + }) + } + style={{justifyContent: 'center'}}> + + + )} + // Item Key + keyExtractor={(item, index) => String(index)} + // Header (Title) + // On End Reached (Takes a function) - ); - } + // ListHeaderComponent={Hello} + // Footer (Activity Indicator) + ListFooterComponent={() => ( + + )} + onEndReached={this.getMoreObservations} + // How Close To The End Of List Until Next Data Request Is Made + onEndReachedThreshold={0.1} + // Refreshing (Set To True When End Reached) + refreshing={this.state.activityIndicator} + /> + + )} + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'flex-start', - alignItems: 'center', - alignSelf: 'stretch', - marginTop: 10, - width: Dimensions.get('window').width - }, - chipContainer: { - flexDirection: 'row', - flexWrap: 'wrap', - justifyContent: 'center', - alignItems: 'center', - }, - chip: { - margin: 2 - }, - img: { - width: Dimensions.get('window').width / 3.085, - height: Dimensions.get('window').width / 3.5, - margin: 2, - justifyContent: 'center', - borderRadius: 2 - }, - imgConatiner: { - flexDirection: 'row', - flexWrap: 'wrap', - justifyContent: 'center', - alignItems: 'center', - marginTop: 20, - width: Dimensions.get('window').width - }, - scrollView: { - width: Dimensions.get('window').width, - marginTop: 5 - }, - welcome: { - fontSize: 25 - } -}) + container: { + flex: 1, + justifyContent: 'flex-start', + alignItems: 'center', + alignSelf: 'stretch', + marginTop: 10, + width: Dimensions.get('window').width, + }, + chipContainer: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'center', + alignItems: 'center', + }, + chip: { + margin: 2, + }, + img: { + width: Dimensions.get('window').width / 3.085, + height: Dimensions.get('window').width / 3.5, + margin: 2, + justifyContent: 'center', + borderRadius: 0, + }, + imgConatiner: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'center', + alignItems: 'center', + marginTop: 20, + width: Dimensions.get('window').width, + }, + scrollView: { + width: Dimensions.get('window').width, + marginTop: 5, + }, + welcome: { + fontSize: 25, + }, +}); export default SearchScreen; - diff --git a/MobileApp/src/screens/ShowPhotoScreen/ShowPhotoScreen.js b/MobileApp/src/screens/ShowPhotoScreen/ShowPhotoScreen.js index 03804a395..6a14136fb 100644 --- a/MobileApp/src/screens/ShowPhotoScreen/ShowPhotoScreen.js +++ b/MobileApp/src/screens/ShowPhotoScreen/ShowPhotoScreen.js @@ -1,71 +1,75 @@ import * as React from 'react'; -import { View, StyleSheet, PermissionsAndroid, Dimensions, Image } from 'react-native' +import { + View, + StyleSheet, + PermissionsAndroid, + Dimensions, + Image, +} from 'react-native'; class ShowPhotoScreen extends React.Component { - constructor(props) { - super(props); - this.state = { photos: [] }; - } - - static navigationOptions = ({ navigation }) => { - const { params = [] } = navigation.state - return { - headerTitle: 'Snapshot', - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: 'white', - } - } + constructor(props) { + super(props); + this.state = {photos: []}; + } - requestStoragePermission = async function () { - try { - const granted = await PermissionsAndroid.request( - PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE, - ); - if (granted === PermissionsAndroid.RESULTS.GRANTED) { - return true + static navigationOptions = ({navigation}) => { + const {params = []} = navigation.state; + return { + headerTitle: 'Snapshot', + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: 'white', + }; + }; - } else { - return false - } - } catch (err) { - //console.warn(err); - return false - } + requestStoragePermission = async function() { + try { + const granted = await PermissionsAndroid.request( + PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE, + ); + if (granted === PermissionsAndroid.RESULTS.GRANTED) { + return true; + } else { + return false; + } + } catch (err) { + //console.warn(err); + return false; } + }; - render() { - return ( - - {this.state.photos !== "" ? - - - - : - - } - - - ); - } + render() { + return ( + + {this.state.photos !== '' ? ( + + + + ) : ( + + )} + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - alignSelf: 'stretch', - width: "100%" - }, -}) -export default ShowPhotoScreen; \ No newline at end of file + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + alignSelf: 'stretch', + width: '100%', + backgroundColor: '#014421', + }, +}); +export default ShowPhotoScreen; diff --git a/MobileApp/src/screens/SpeciesDetailsScreen/SpeciesDetailsScreen.js b/MobileApp/src/screens/SpeciesDetailsScreen/SpeciesDetailsScreen.js index 9e6bbcd5f..fd99db620 100644 --- a/MobileApp/src/screens/SpeciesDetailsScreen/SpeciesDetailsScreen.js +++ b/MobileApp/src/screens/SpeciesDetailsScreen/SpeciesDetailsScreen.js @@ -1,77 +1,100 @@ import * as React from 'react'; -import { View, StyleSheet, Dimensions, ImageBackground, Text } from 'react-native' -import { CardComponent } from '../../components/CardComponent/CardComponent' -import { ScrollView } from 'react-native-gesture-handler'; +import { + View, + StyleSheet, + Dimensions, + ImageBackground, + Text, +} from 'react-native'; +import {CardComponent} from '../../components/CardComponent/CardComponent'; +import {ScrollView} from 'react-native-gesture-handler'; class SpeciesDetailsScreen extends React.Component { - constructor(props) { - super(props); - this.state = { photos: [] }; - } + constructor(props) { + super(props); + this.state = {photos: []}; + } - static navigationOptions = ({ navigation }) => { - const { params = [] } = navigation.state - return { - headerTitle: params.content[0], - headerStyle: { - backgroundColor: '#014421', - }, - headerTintColor: 'white', - } - } + static navigationOptions = ({navigation}) => { + const {params = []} = navigation.state; + return { + headerTitle: params.content[0], + headerStyle: { + backgroundColor: '#014421', + }, + headerTintColor: 'white', + }; + }; - - render() { - return ( - - - {this.props.navigation.getParam('content')[0]} - {this.props.navigation.getParam('content')[1]} - - - - - {this.props.navigation.getParam('content')[3]} - - - - - - ); - } + render() { + return ( + + + + {this.props.navigation.getParam('content')[0]} + + + {this.props.navigation.getParam('content')[1]} + + + + + {this.props.navigation.getParam('content')[3]} + + + source: www.wikipedia.org + + + + ); + } } const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'flex-start', - alignItems: 'center', - alignSelf: 'stretch', - width: Dimensions.get('window').width - }, - profileConatiner: { - width: Dimensions.get('window').width, - justifyContent: 'center', - alignItems: 'center', - padding: 10, - height: 270, - resizeMode: 'stretch' - }, - title: { - color: 'white', - fontSize: 40, - textAlign: 'center', - }, - subtitle: { - color: 'white', - fontSize: 20, - }, - userPhoto: { - width: 100, - height: 100, - borderRadius: 100, - borderWidth: 1, - borderColor: 'white' - }, -}) -export default SpeciesDetailsScreen; \ No newline at end of file + container: { + flex: 1, + justifyContent: 'flex-start', + alignItems: 'center', + width: Dimensions.get('window').width, + backgroundColor: '#014421', + }, + profileConatiner: { + width: Dimensions.get('window').width, + justifyContent: 'center', + alignItems: 'center', + padding: 10, + height: 270, + resizeMode: 'contain', + }, + title: { + color: 'white', + fontSize: 40, + textAlign: 'center', + }, + subtitle: { + color: 'white', + fontSize: 20, + }, + userPhoto: { + width: 100, + height: 100, + borderRadius: 100, + borderWidth: 1, + borderColor: 'white', + }, +}); +export default SpeciesDetailsScreen;