This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community. Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it. https://www.freifunk-altdorf.de
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

459 lines
14 KiB

/**
* Freifunk Altdorf
*/
import MapScreen from './MapScreen';
import NodeInfo from './NodeInfNavigation';
import FetchData from './components/fetchData';
import styles from './style'
import React, { Component } from 'react';
import { Div, StyleSheet, Text, View, ScrollView, Alert, Button, TouchableHighlight, TouchableOpacity, Image, Collapsile, AppRegistry } from 'react-native';
import wifi from 'react-native-android-wifi';
import MapView from 'react-native-maps';
import { createStackNavigator } from 'react-navigation';
import { YellowBox } from 'react-native';
import MapScreenFreifunk from './MapScreenFreifunk';
import Speedtest from './Speedtest';
import Information from './Information';
import SwichExample from './components/SwitchExample';
import NodeInformation from './components/NodeInformation';
YellowBox.ignoreWarnings(['Warning: isMounted(...) is deprecated', 'Module RCTImageLoader']); //Silence Bug in React-Navigation
import SplashScreen from 'react-native-splash-screen';
import { PermissionsAndroid } from 'react-native';
import { Icon } from 'react-native-elements';
import { PricingCard } from 'react-native-elements';
import { Grid, Col, Row } from 'react-native-elements';
import email from 'react-native-email';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
header: null //hide Bar at HomeScreen
};
constructor(props) {
super(props);
this.state = {
security: null,
security2: null,
ssid: null,
bssid: null,
data: [],
hostName: '',
dataATT: [],
data2: [],
isLoad: false,
mySSID: 'Wadenspanner2',
SSIDJson: [],
bssidShort: null,
ipv6Address: null,
communityData: [],
community: null,
communityContact: null,
latitude: null,
longitude: null,
error: null,
};
}
async requestLocationPermission() {
const chckLocationPermission = PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);
if (chckLocationPermission === PermissionsAndroid.RESULTS.GRANTED) {
alert("You've access for the location");
} else {
try {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
'title': 'Cool Location App required Location permission',
'message': 'We required Location permission in order to get device location ' +
'Please grant us.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
alert("You've access for the location");
} else {
alert("You don't have access for the location");
}
} catch (err) {
alert(err)
}
}
};
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchId);
}
async componentDidMount() {
// do stuff while splash screen is shown
// After having done stuff (such as async tasks) hide the splash screen
this.json_funcion();
this.getGeolocationData();
SplashScreen.hide();
}
getGeolocationData() {
this.watchId = navigator.geolocation.watchPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: false, timeout: 20000, maximumAge: 1000, distanceFilter: 10 },
);
}
ShowAlertWithDelay = () => {
setTimeout(function () {
//Put All Your Code Here, Which You Want To Execute After Some Delay Time.
Alert.alert("Alert Shows After 5 Seconds of Delay.")
}, 5000);
}
json_funcionCommunity = async () => {
await this.setState({
communityData: require('./config/FreifunkAltdorfConfig')
});
await this.setState({
community: this.state.communityData.community,
jsonAdr: this.state.communityData.jsonAdr,
communityContact: this.state.communityContact
});
// return fetch('/config/FreifunkAltdorf.json')
// .then((response) => response.json())
// .then((responseJson) => {
// this.setState({
// communityData: responseJson
// });
// this.setState({
// // dataATT: this.state.data.nodes.map(user => user.nodeinfo),
// community: this.state.communityData.community,
// jsonAdr: this.state.communityData.jsonAdr,
// communityContact: this.state.communityContact
// });
// })
// .catch((error) => {
// console.error(error);
// });
}
//Fetching Data from JSON File
json_funcion = async () => {
await Promise.all([this.json_funcionCommunity()]);
return fetch(this.state.jsonAdr)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
data: responseJson
});
this.setState({
// dataATT: this.state.data.nodes.map(user => user.nodeinfo),
dataATT: this.state.data.nodes,
isLoad: true
});
})
.catch((error) => {
console.error(error);
});
}
json_funcion2 = (addr) => {
console.log("9. checkSecurity was called");
console.log(addr);
return fetch(String(addr))
.then((response) => response.json())
.then((responseJson) => {
this.setState({
data2: responseJson
});
// this.setState({
console.log(this.state.data2.node_id);
// // dataATT: this.state.data.nodes.map(user => user.nodeinfo),
// dataATT: this.state.data.nodes,
// isLoad: true
// });
})
.catch((error) => {
console.error(error);
});
}
getSSIDOnPress() {
wifi.getSSID((ssid) => {
this.setState({ currentSSID: 'Your SSID is ' + ssid });
});
}
getBSSIDOnPress() {
console.log("2. getBSSID was called");
wifi.getBSSID((bssid) => {
console.log(bssid);
var res = bssid.substring(0, 16);
this.setState({ currentBSSID: bssid });
this.setState({ currentBSSIDText: 'Your BSSID is ' + bssid });
this.setState({ bssidShort: res });
console.log("3. gleich wird findOutComminity aufgerufen");
this.findOutCommunity();
});
}
async checkSecurity() {
Promise.all([this.getBSSIDOnPress(), this.getSSIDOnPress()]);
this.setState({ security: 'not reliable' });
//ĀRWYB
}
displayReliabilty = () => {
if (this.state.security != null || this.state.currentSSID != null) {
return <View>
<Text style={styles.simpleText}>{this.state.currentSSID}</Text>
<Text style={styles.simpleText}>{this.state.currentBSSIDText}</Text>
<Text style={styles.simpleText}>{this.state.hostName}</Text>
<Text style={styles.simpleText}>{'Your connection is ' + this.state.security}</Text>
</View>
}
}
findOutCommunity = () => {
var data = this.state.dataATT;
var aa1 = String(this.state.bssidShort).toLocaleLowerCase();
for (var k3 in data) {
if (data.hasOwnProperty(k3)) {
if (String(data[k3].nodeinfo.network.mesh.bat0.interfaces.other).toLowerCase().includes(aa1)) {
this.setState({ hostName: data[k3].nodeinfo.hostname });
if (String(data[k3].nodeinfo.network.addresses[0]).includes("fdef")) {
this.setState({ ipv6Address: data[k3].nodeinfo.network.addresses[0] });
} else if (String(data[k3].nodeinfo.network.addresses[1]).includes("fdef")) {
this.setState({ ipv6Address: data[k3].nodeinfo.network.addresses[1] });
} else {
this.setState({ ipv6Address: data[k3].nodeinfo.network.addresses[2] });
}
console.log("6. gleich wird compareJSONwithJSON aufgerufen");
this.compareJSONwithJSON(data[k3].nodeinfo.node_id);
}
}
}
}
compareJSONwithJSON = async (nodeid) => {
var addr = "http://[";
addr += String(this.state.ipv6Address);
addr += "]/cgi-bin/nodeinfo";
await Promise.all([this.json_funcion2(addr)]);
console.log(nodeid);
console.log(this.state.data2.node_id);
if (nodeid == this.state.data2.node_id) {
console.log("found");
this.setState({ security: 'reliable' });
}
}
render() {
//console.log(this.state.dataATT.map(us => us.hostname))
return (
<ScrollView style={styles.wholeBackground}>
<View style={styles.header}>
{/* Logo */}
<View style={styles.img}>
<Image
style={{
width: 102,
height: 85,
}}
source={require('./src/img/Logo.png')}
/>
</View>
</View>
<View style={styles.container}>
<View>
<Text style={styles.headlineText}>Reliability Check</Text>
<View style={styles.testCenter}>
<TouchableHighlight onPress={this.checkSecurity.bind(this)}>
<Text style={styles.button}>Measure Security</Text>
</TouchableHighlight>
<View style={styles.testCenter}>
{this.displayReliabilty()}
</View>
</View>
</View>
</View>
<View style={styles.breakLine}></View>
<View style={styles.container}>
<View style={styles.testCenter}>
<Text style={styles.headlineText}>Node Information</Text>
<NodeInformation dataATT={this.state.dataATT} />
<TouchableHighlight onPress={() => {
/* 1. Navigate to the Details route with params */
this.checkSecurity();
console.log('lets see : ' + this.currentBSSID); // ISSUE currentBSSID is not set as fast as nav gets open
this.props.navigation.navigate('NodeInfoO', {
dataATT: this.state.dataATT,
currentBSSID: this.state.currentBSSID,
hostName: this.state.hostName,
});
}}>
<Text style={styles.button}>More Node Info</Text>
</TouchableHighlight>
</View>
</View>
<View style={styles.breakLine}></View>
<View style={styles.container}>
<View>
<Text style={styles.headlineText}>Speedtest</Text>
<TouchableHighlight onPress={() => {
/* 1. Navigate to the Details route with params */
this.props.navigation.navigate('SpeedtestO', {
});
}}>
<Text style={styles.button}>Start Speedtest</Text>
</TouchableHighlight>
</View>
</View>
<View style={styles.breakLine}></View>
<View style={styles.container}>
<View>
<Text style={styles.headlineText}>Map Info</Text>
<View>
<TouchableHighlight onPress={() => {
/* 1. Navigate to the Details route with params */
this.props.navigation.navigate('MapScreenG', {
dataATT: this.state.dataATT,
latitude: this.state.latitude,
longitude: this.state.longitude,
});
}}>
<Text style={styles.button}>Maps (Google)</Text>
</TouchableHighlight>
<TouchableHighlight onPress={() => {
/* 1. Navigate to the Details route with params */
this.props.navigation.navigate('MapScreenF', {
itemId: 86,
dataATT: this.state.dataATT,
});
}}>
<Text style={styles.button}>Maps (Freifunk)</Text>
</TouchableHighlight>
</View>
</View>
</View>
<View style={styles.breakLine}></View>
<View style={styles.container}>
<View>
<Text style={styles.headlineText}>Info</Text>
{/* Latitude Longitude */}
{/* <Text
onPress={() => this.requestLocationPermission()}>
Request Location Permission
</Text>
<Text>Latitude: {this.state.latitude}</Text>
<Text style={{ paddingBottom: 10 }}>Longitude: {this.state.longitude}</Text>
{this.state.error ? <Text>Error: {this.state.error}</Text> : null}
<Text></Text> */}
<TouchableHighlight onPress={() => {
/* 1. Navigate to the Details route with params */
this.props.navigation.navigate('InformationO', {
itemId: 86,
dataATT: this.state.dataATT,
});
}}>
<Text style={styles.button}>Information</Text>
</TouchableHighlight>
</View>
</View>
<View style={styles.breakLine}></View>
<View style={styles.container}>
<View style={{ paddingBottom: 10 }}>
<Text style={styles.headlineText}>Report</Text>
<TouchableOpacity
style={styles.button2}
onPress={this.handleEmail}
>
<Text> Send Report </Text>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
}
handleEmail = () => {
const to = ['orhan.sari.1993@gmail.com'] // string or array of email addresses
email(to, {
// Optional additional arguments
// cc: ['bazzy@moo.com', 'doooo@daaa.com'], // string or array of email addresses
// bcc: 'mee@mee.com', // string or array of email addresses
subject: 'From Freifunk App',
body:
'Hostname: ' + this.state.hostName + //If not connected with Freifunk then null
'\n SSID: ' + this.state.currentSSID +
'\n BSSID: ' + this.state.currentBSSID +
'\n IPv6 Address: ' + this.state.ipv6Address + //If not connected with Freifunk then null
'\n Latitude: ' + this.state.latitude +
'\n Longitude: ' + this.state.longitude
// TODO:
// + Information returned by Node Information
// e.g. Gateway Hops, Clients, ..
}).catch(console.error)
}
}
const RootStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
},
MapScreenG: {
screen: MapScreen,
},
MapScreenF: {
screen: MapScreenFreifunk,
},
NodeInfoO: {
screen: NodeInfo,
},
SpeedtestO: {
screen: Speedtest,
},
InformationO: {
screen: Information,
}
},
{
initialRouteName: 'Home',
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}