WIP More Wifi setup
This commit is contained in:
parent
a6db96ef29
commit
0bb0e2f121
133
App.js
133
App.js
|
@ -6,7 +6,7 @@ import * as Font from 'expo-font';
|
||||||
// Redux + Storage
|
// Redux + Storage
|
||||||
import swimtrackerReducer from './state/Reducer';
|
import swimtrackerReducer from './state/Reducer';
|
||||||
import { createStore } from 'redux';
|
import { createStore } from 'redux';
|
||||||
import { DeviceReduxCoupling } from './state/DeviceReduxCoupling';
|
import { ConnState, WifiState, DeviceReduxCoupling } from './state/DeviceReduxCoupling';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import { persistStore, persistReducer } from 'redux-persist'
|
import { persistStore, persistReducer } from 'redux-persist'
|
||||||
|
@ -43,17 +43,32 @@ export default class App extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isReady: false,
|
isReady: false,
|
||||||
|
disconnected: true,
|
||||||
|
isProvisioning: false,
|
||||||
};
|
};
|
||||||
|
this.unsubscribe = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
componentDidMount() {
|
||||||
/*await Font.loadAsync({
|
|
||||||
Roboto: require('native-base/Fonts/Roboto.ttf'),
|
|
||||||
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
|
|
||||||
...Ionicons.font,
|
|
||||||
});*/
|
|
||||||
this.setState({ isReady: true });
|
this.setState({ isReady: true });
|
||||||
this.device = new DeviceReduxCoupling(store);
|
this.device = new DeviceReduxCoupling(store);
|
||||||
|
|
||||||
|
console.log("subscribing");
|
||||||
|
let theApp = this;
|
||||||
|
this.unsubscribe = store.subscribe(() => {
|
||||||
|
const state = store.getState();
|
||||||
|
theApp.setState({
|
||||||
|
disconnected: state.deviceState.connState == ConnState.DISCONNECTED,
|
||||||
|
isProvisioning: state.deviceState.wifiState == WifiState.AP_PROVISIONING || state.deviceState.wifiState == WifiState.UNKNOWN,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
if (this.unsubscribe) {
|
||||||
|
this.unsubscribe();
|
||||||
|
console.log("unsubscribe");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -64,61 +79,77 @@ export default class App extends React.Component {
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let disconnectedView = (
|
||||||
|
<>
|
||||||
|
<Stack.Screen
|
||||||
|
name="ConnectingView"
|
||||||
|
options={screenOptions}
|
||||||
|
component={ConnectingView} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
let provisioningView = (
|
||||||
|
<>
|
||||||
|
<Stack.Screen
|
||||||
|
name="WifiSelectionView"
|
||||||
|
options={screenOptions} >
|
||||||
|
{props => <WifiSelectionView {...props} device={this.device} />}
|
||||||
|
</Stack.Screen>
|
||||||
|
<Stack.Screen
|
||||||
|
name="WifiPasswordView"
|
||||||
|
options={screenOptions}
|
||||||
|
component={WifiPasswordView}
|
||||||
|
>
|
||||||
|
</Stack.Screen>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
let normalView = (
|
||||||
|
<>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Home"
|
||||||
|
component={MainMenuView}
|
||||||
|
options={screenOptions}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Settings"
|
||||||
|
component={SettingsView}
|
||||||
|
options={screenOptions}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Training"
|
||||||
|
component={TrainingView}
|
||||||
|
options={screenOptions}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="LastSessions"
|
||||||
|
component={LastSessionsView}
|
||||||
|
options={screenOptions}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
let activeView;
|
||||||
|
if (this.state.disconnected)
|
||||||
|
activeView = disconnectedView;
|
||||||
|
else if (this.state.isProvisioning)
|
||||||
|
activeView = provisioningView;
|
||||||
|
else
|
||||||
|
activeView = normalView;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PersistGate loading={<AppLoading />} persistor={persistor}>
|
<PersistGate loading={<AppLoading />} persistor={persistor}>
|
||||||
<NavigationContainer>
|
<NavigationContainer>
|
||||||
<Stack.Navigator initialRouteName="WifiSelectionView">
|
<Stack.Navigator >
|
||||||
<Stack.Screen
|
{activeView}
|
||||||
name="WifiSelectionView"
|
|
||||||
options={screenOptions} >
|
|
||||||
{props => <WifiSelectionView {...props} device={this.device} />}
|
|
||||||
</Stack.Screen>
|
|
||||||
<Stack.Screen
|
|
||||||
name="WifiPasswordView"
|
|
||||||
options={screenOptions}
|
|
||||||
component={WifiPasswordView}
|
|
||||||
>
|
|
||||||
</Stack.Screen>
|
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
</PersistGate>
|
</PersistGate>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
|
||||||
return (
|
|
||||||
<Provider store={store}>
|
|
||||||
<PersistGate loading={<AppLoading />} persistor={persistor}>
|
|
||||||
<NavigationContainer>
|
|
||||||
<Stack.Navigator initialRouteName="Home">
|
|
||||||
<Stack.Screen
|
|
||||||
name="Home"
|
|
||||||
component={MainMenuView}
|
|
||||||
options={screenOptions}
|
|
||||||
/>
|
|
||||||
<Stack.Screen
|
|
||||||
name="Settings"
|
|
||||||
component={SettingsView}
|
|
||||||
options={screenOptions}
|
|
||||||
/>
|
|
||||||
<Stack.Screen
|
|
||||||
name="Training"
|
|
||||||
component={TrainingView}
|
|
||||||
options={screenOptions}
|
|
||||||
/>
|
|
||||||
<Stack.Screen
|
|
||||||
name="LastSessions"
|
|
||||||
component={LastSessionsView}
|
|
||||||
options={screenOptions}
|
|
||||||
/>
|
|
||||||
</Stack.Navigator>
|
|
||||||
</NavigationContainer>
|
|
||||||
</PersistGate>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
app.json
5
app.json
|
@ -25,6 +25,9 @@
|
||||||
"ios": {
|
"ios": {
|
||||||
"supportsTablet": true
|
"supportsTablet": true
|
||||||
},
|
},
|
||||||
"description": ""
|
"description": "",
|
||||||
|
"android": {
|
||||||
|
"package": "tech.bauer.swimtracker"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,12 @@ function AdditionalOptionsBottomBar(props) {
|
||||||
return (
|
return (
|
||||||
<View style={bottomBarStyles.container}>
|
<View style={bottomBarStyles.container}>
|
||||||
{ props.leftText ?
|
{ props.leftText ?
|
||||||
<TouchableOpacity onPress={props.onLeftPress}>
|
<TouchableOpacity onPress={props.onLeftPress} style={bottomBarStyles.button}>
|
||||||
<Text style={bottomBarStyles.text}>{props.leftText} </Text>
|
<Text style={bottomBarStyles.text}>{props.leftText} </Text>
|
||||||
</TouchableOpacity> : <View></View>
|
</TouchableOpacity> : <View></View>
|
||||||
}
|
}
|
||||||
{props.rightText &&
|
{props.rightText &&
|
||||||
<TouchableOpacity onPress={props.onRightPress}>
|
<TouchableOpacity onPress={props.onRightPress} style={bottomBarStyles.button}>
|
||||||
<Text style={bottomBarStyles.text}>{props.rightText}</Text>
|
<Text style={bottomBarStyles.text}>{props.rightText}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,9 @@ const bottomBarStyles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
color: "rgba(255,255,255,0.5)",
|
color: "rgba(255,255,255,0.5)",
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
borderStyle: "dotted"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -55,7 +58,7 @@ function SetupView(props) {
|
||||||
<View style={setupViewStyles.container}>
|
<View style={setupViewStyles.container}>
|
||||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||||
{props.backButton &&
|
{props.backButton &&
|
||||||
<TouchableOpacity onPress={props.navigation.goBack}>
|
<TouchableOpacity onPress={() => props.navigation.goBack()}>
|
||||||
<EntypoIcon name="chevron-left" style={setupViewStyles.backButton}></EntypoIcon>
|
<EntypoIcon name="chevron-left" style={setupViewStyles.backButton}></EntypoIcon>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
}
|
}
|
||||||
|
@ -63,7 +66,9 @@ function SetupView(props) {
|
||||||
{props.headerText}
|
{props.headerText}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
{props.children}
|
<View style={{flex: 1, justifyContent: "center"}}>
|
||||||
|
{props.children}
|
||||||
|
</View>
|
||||||
<AdditionalOptionsBottomBar leftText={props.lowerLeftButtonText}
|
<AdditionalOptionsBottomBar leftText={props.lowerLeftButtonText}
|
||||||
onLeftPress={props.onLowerLeftButtonPress}
|
onLeftPress={props.onLowerLeftButtonPress}
|
||||||
rightText={props.lowerRightButtonText}
|
rightText={props.lowerRightButtonText}
|
||||||
|
@ -93,6 +98,7 @@ const setupViewStyles = StyleSheet.create({
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
lineHeight: 25,
|
lineHeight: 25,
|
||||||
width: "80%",
|
width: "80%",
|
||||||
|
marginBottom: 50,
|
||||||
},
|
},
|
||||||
backButton: {
|
backButton: {
|
||||||
color: "rgba(255,255,255,1)",
|
color: "rgba(255,255,255,1)",
|
||||||
|
|
|
@ -28,12 +28,13 @@ const OpCodes = {
|
||||||
|
|
||||||
|
|
||||||
export default class SwimTrackerWebsocketConnection {
|
export default class SwimTrackerWebsocketConnection {
|
||||||
constructor(swimTrackerHost, onData, onStarted, onStopped, onConnect, onDisconnect) {
|
constructor(swimTrackerHost, onData, onStarted, onStopped, onWifiStateInfo, onConnect, onDisconnect) {
|
||||||
this.swimTrackerHost = swimTrackerHost;
|
this.swimTrackerHost = swimTrackerHost;
|
||||||
|
|
||||||
this.onData = onData;
|
this.onData = onData;
|
||||||
this.onStarted = onStarted;
|
this.onStarted = onStarted;
|
||||||
this.onStopped = onStopped;
|
this.onStopped = onStopped;
|
||||||
|
this.onWifiStateInfo = onWifiStateInfo;
|
||||||
this.onConnect = onConnect;
|
this.onConnect = onConnect;
|
||||||
this.onDisconnect = onDisconnect;
|
this.onDisconnect = onDisconnect;
|
||||||
|
|
||||||
|
@ -54,48 +55,68 @@ export default class SwimTrackerWebsocketConnection {
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
this._wifiScanPromise = null;
|
this._wifiScanPromises = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
sendStartCommand() {
|
sendStartCommand() {
|
||||||
const data = new Uint8Array(1);
|
this._sendMsg(OpCodes.START_SESSION);
|
||||||
data[0] = OpCodes.START_SESSION;
|
|
||||||
this.ws.send(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendStopCommand() {
|
sendStopCommand() {
|
||||||
const data = new Uint8Array(1);
|
this._sendMsg(OpCodes.STOP_SESSION);
|
||||||
data[0] = OpCodes.STOP_SESSION;
|
|
||||||
this.ws.send(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendTareCommand() {
|
sendTareCommand() {
|
||||||
const data = new Uint8Array(1);
|
this._sendMsg(OpCodes.TARE);
|
||||||
data[0] = OpCodes.TARE;
|
|
||||||
this.ws.send(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scanWifiNetworks() {
|
scanWifiNetworks() {
|
||||||
// trigger scan
|
console.log("Trigger wifi scan");
|
||||||
const data = new Uint8Array(1);
|
this._sendMsg(OpCodes.WIFI_TRIGGER_SCAN);
|
||||||
data[0] = OpCodes.WIFI_TRIGGER_SCAN;
|
|
||||||
this.ws.send(data);
|
|
||||||
|
|
||||||
if (this._wifiScanPromise !== null) {
|
let conn = this;
|
||||||
return Promise.reject("Scan in progress");
|
return new Promise((resolve, reject) => {
|
||||||
}
|
conn._wifiScanPromises.push({ resolve: resolve, reject: reject });
|
||||||
else {
|
});
|
||||||
|
|
||||||
let conn = this;
|
}
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
conn._wifiScanPromise = { resolve: resolve, reject: reject };
|
wifiResetToProvisioning() {
|
||||||
});
|
this._sendMsg(OpCodes.WIFI_STATE_SET, {
|
||||||
|
"reset_to_provisioning": true,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
wifiSetModeAP(password) {
|
||||||
|
this._sendMsg(OpCodes.WIFI_STATE_SET, {
|
||||||
|
"ap_password": password,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
wifiSetModeSTA(ssid, password) {
|
||||||
|
this._sendMsg(OpCodes.WIFI_STATE_SET, {
|
||||||
|
"sta_ssid": ssid,
|
||||||
|
"sta_password": password,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendMsg(code, data) {
|
||||||
|
let msg = undefined;
|
||||||
|
if (data) {
|
||||||
|
const serializedData = msgpack.encode(data);
|
||||||
|
msg = new Uint8Array([code, ...serializedData]);
|
||||||
|
} else {
|
||||||
|
msg = new Uint8Array(1);
|
||||||
|
msg[0] = OpCodes.WIFI_TRIGGER_SCAN;
|
||||||
}
|
}
|
||||||
|
this.ws.send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMessage = (e) => {
|
_onMessage = (e) => {
|
||||||
const dv = new DataView(e.data);
|
const dv = new DataView(e.data);
|
||||||
const opCode = dv.getInt8(0);
|
const opCode = dv.getInt8(0);
|
||||||
|
const payload = new Uint8Array(e.data).slice(1);
|
||||||
|
|
||||||
if (opCode === OpCodes.INITIAL_INFO) {
|
if (opCode === OpCodes.INITIAL_INFO) {
|
||||||
const headerSize = 6;
|
const headerSize = 6;
|
||||||
|
@ -116,14 +137,15 @@ export default class SwimTrackerWebsocketConnection {
|
||||||
const data = new Uint16Array(e.data.slice(1));
|
const data = new Uint16Array(e.data.slice(1));
|
||||||
this.onData(data);
|
this.onData(data);
|
||||||
} else if (opCode === OpCodes.WIFI_SCAN_RESPONSE) {
|
} else if (opCode === OpCodes.WIFI_SCAN_RESPONSE) {
|
||||||
console.log("got data", e.data);
|
const scanResult = msgpack.decode(payload, { codec: this.msgpackCodec });
|
||||||
const scanResult = msgpack.decode(new Uint8Array(e.data).slice(1), { codec: this.msgpackCodec });
|
|
||||||
if (this._wifiScanPromise !== null) {
|
for (let i = 0; i < this._wifiScanPromises.length; ++i) {
|
||||||
this._wifiScanPromise.resolve(scanResult);
|
this._wifiScanPromises[i].resolve(scanResult);
|
||||||
this._wifiScanPromise = null;
|
|
||||||
} else {
|
|
||||||
console.log("Got unexpected WiFi scan result", scanResult);
|
|
||||||
}
|
}
|
||||||
|
this._wifiScanPromises.length = 0;
|
||||||
|
} else if (opCode === OpCodes.WIFI_STATE_RESPONSE) {
|
||||||
|
const wifiInfo = msgpack.decode(payload, { codec: this.msgpackCodec });
|
||||||
|
this.onWifiStateInfo(wifiInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ export class DeviceReduxCoupling {
|
||||||
this._onNewData,
|
this._onNewData,
|
||||||
(sessionId) => this.reduxStore.dispatch(reportSessionStarted(sessionId)),
|
(sessionId) => this.reduxStore.dispatch(reportSessionStarted(sessionId)),
|
||||||
() => this.reduxStore.dispatch(reportSessionStopped()),
|
() => this.reduxStore.dispatch(reportSessionStopped()),
|
||||||
|
(response) => this.reduxStore.dispatch(reportNewWifiState(response["state"])),
|
||||||
() => this.reduxStore.dispatch(reportDeviceConnect()),
|
() => this.reduxStore.dispatch(reportDeviceConnect()),
|
||||||
() => this.reduxStore.dispatch(reportDeviceDisconnect())
|
() => this.reduxStore.dispatch(reportDeviceDisconnect())
|
||||||
);
|
);
|
||||||
|
@ -152,15 +153,14 @@ export const deviceStateReducer = (state = INITIAL_DEVICE_STATE, action) => {
|
||||||
return state;
|
return state;
|
||||||
return { ...INITIAL_DEVICE_STATE, connState: ConnState.CONNECTED_STOPPING };
|
return { ...INITIAL_DEVICE_STATE, connState: ConnState.CONNECTED_STOPPING };
|
||||||
case WIFI_SET_STATE:
|
case WIFI_SET_STATE:
|
||||||
console.log("here");
|
|
||||||
let wifState = WifiState.UNKNOWN;
|
let wifState = WifiState.UNKNOWN;
|
||||||
if (action.data === "STATION_MODE") { wifState = WifiState.STA; }
|
if (action.newStateStr === "STATION_MODE") { wifState = WifiState.STA; }
|
||||||
else if (action.data === "AP_PROVISIONING") { wifState = WifiState.AP_PROVISIONING; }
|
else if (action.newStateStr === "AP_PROVISIONING") { wifState = WifiState.AP_PROVISIONING; }
|
||||||
else if (action.data === "AP_SECURE") { wifState = WifiState.AP_SECURE; }
|
else if (action.newStateStr === "AP_SECURE") { wifState = WifiState.AP_SECURE; }
|
||||||
return { ...state, wifiState: wifState };
|
return { ...state, wifiState: wifState };
|
||||||
default:
|
default:
|
||||||
console.log("Unhandled state in deviceStateReducer", action, action.type);
|
//console.log("Unhandled state in deviceStateReducer", action, action.type, "state", state);
|
||||||
return state
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,11 @@ import {
|
||||||
import themeColors from '../components/themeColors';
|
import themeColors from '../components/themeColors';
|
||||||
import MaterialIcon from "react-native-vector-icons/MaterialCommunityIcons";
|
import MaterialIcon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||||
import EntypoIcon from "react-native-vector-icons/Entypo";
|
import EntypoIcon from "react-native-vector-icons/Entypo";
|
||||||
|
import FeatherIcon from "react-native-vector-icons/Feather";
|
||||||
|
|
||||||
|
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import { ConnState, startSession } from '../state/DeviceReduxCoupling';
|
import { ConnState, startSession } from '../state/DeviceReduxCoupling';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
@ -83,7 +88,7 @@ function ButtonGrid(props) {
|
||||||
style={[{ backgroundColor: themeColors["MIDNIGHT BLUE"] }, buttonGridStyles.button]}
|
style={[{ backgroundColor: themeColors["MIDNIGHT BLUE"] }, buttonGridStyles.button]}
|
||||||
activeOpacity={0.6}
|
activeOpacity={0.6}
|
||||||
>
|
>
|
||||||
<MaterialIcon name="settings-outline" style={buttonGridStyles.icon}></MaterialIcon>
|
<MaterialCommunityIcons name="settings" style={buttonGridStyles.icon}></MaterialCommunityIcons>
|
||||||
<Text style={buttonGridStyles.buttonText}>EINSTELLUNGEN</Text>
|
<Text style={buttonGridStyles.buttonText}>EINSTELLUNGEN</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,33 +1,69 @@
|
||||||
import React from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import {
|
import {
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
TextInput,
|
TextInput,
|
||||||
|
Keyboard
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import SetupView from '../components/SetupView';
|
import SetupView from '../components/SetupView';
|
||||||
import EvilIcon from "react-native-vector-icons/EvilIcons";
|
import EvilIcon from "react-native-vector-icons/EvilIcons";
|
||||||
import MaterialIcon from "react-native-vector-icons/MaterialCommunityIcons";
|
import MaterialIcon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||||
import themeColors from '../components/themeColors';
|
import themeColors from '../components/themeColors';
|
||||||
|
|
||||||
|
|
||||||
function WifiPasswordView(props) {
|
function WifiPasswordView(props) {
|
||||||
props = {...props, ...props.route.params};
|
props = { ...props, ...props.route.params };
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
|
||||||
|
Keyboard.addListener("keyboardDidHide", _keyboardDidHide);
|
||||||
|
|
||||||
|
// cleanup function
|
||||||
|
return () => {
|
||||||
|
Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
|
||||||
|
Keyboard.removeListener("keyboardDidHide", _keyboardDidHide);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [keyboardStatus, setKeyboardStatus] = useState(undefined);
|
||||||
|
const [password1, setPassword1] = useState("");
|
||||||
|
const [password2, setPassword2] = useState("");
|
||||||
|
const [errorMsg, setErrorMsg] = useState("");
|
||||||
|
|
||||||
|
const _keyboardDidShow = () => setKeyboardStatus(true);
|
||||||
|
const _keyboardDidHide = () => setKeyboardStatus(false);
|
||||||
|
|
||||||
let iconName = "wifi-strength-" + props.strength;
|
let iconName = "wifi-strength-" + props.strength;
|
||||||
if (props.lock) {
|
if (props.lock) {
|
||||||
iconName += "-lock";
|
iconName += "-lock";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
|
||||||
|
if (props.confirmPwInput && password1 != password2)
|
||||||
|
setErrorMsg("Passwords don't match");
|
||||||
|
else if (password1.length < 8)
|
||||||
|
setErrorMsg("Password has to be at least 8 characters long")
|
||||||
|
else if (password1.length > 128)
|
||||||
|
setErrorMsg("Password too long");
|
||||||
|
else
|
||||||
|
setErrorMsg("");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SetupView
|
<SetupView
|
||||||
headerText="WiFi Password"
|
headerText="WiFi Password"
|
||||||
lowerRightButtonText="Need help?"
|
lowerRightButtonText="Need help?"
|
||||||
|
backButton={true}
|
||||||
|
navigation={props.navigation}
|
||||||
>
|
>
|
||||||
<Text style={styles.subtext}>
|
|
||||||
{props.subText}
|
{!keyboardStatus &&
|
||||||
</Text>
|
<Text style={styles.subtext}>
|
||||||
|
{props.subText}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
|
||||||
<View style={styles.formContainer}>
|
<View style={styles.formContainer}>
|
||||||
<View style={[styles.row, { backgroundColor: "rgba(155,155,155,0.8)" }]}>
|
<View style={[styles.row, { backgroundColor: "rgba(155,155,155,0.8)" }]}>
|
||||||
|
@ -38,6 +74,7 @@ function WifiPasswordView(props) {
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<EvilIcon name="lock" style={styles.ssidIcon}></EvilIcon>
|
<EvilIcon name="lock" style={styles.ssidIcon}></EvilIcon>
|
||||||
<TextInput style={styles.passwordInput}
|
<TextInput style={styles.passwordInput}
|
||||||
|
onChangeText={setPassword1}
|
||||||
autoCompleteType="password"
|
autoCompleteType="password"
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
placeholderTextColor="rgba(255,255,255,0.5)"
|
placeholderTextColor="rgba(255,255,255,0.5)"
|
||||||
|
@ -49,6 +86,7 @@ function WifiPasswordView(props) {
|
||||||
< View style={styles.row}>
|
< View style={styles.row}>
|
||||||
<EvilIcon name="lock" style={styles.ssidIcon}></EvilIcon>
|
<EvilIcon name="lock" style={styles.ssidIcon}></EvilIcon>
|
||||||
<TextInput style={styles.passwordInput}
|
<TextInput style={styles.passwordInput}
|
||||||
|
onChangeText={setPassword2}
|
||||||
autoCompleteType="password"
|
autoCompleteType="password"
|
||||||
placeholder="Repeat Password"
|
placeholder="Repeat Password"
|
||||||
placeholderTextColor="rgba(255,255,255,0.5)"
|
placeholderTextColor="rgba(255,255,255,0.5)"
|
||||||
|
@ -57,10 +95,15 @@ function WifiPasswordView(props) {
|
||||||
</View>
|
</View>
|
||||||
}
|
}
|
||||||
|
|
||||||
<TouchableOpacity style={[styles.row, styles.button]}>
|
{errorMsg.length > 0 &&
|
||||||
|
<View>
|
||||||
|
<Text style={{ color: "red", paddingTop: 10, paddingLeft: 55 }}>{errorMsg}</Text>
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
|
||||||
|
<TouchableOpacity style={[styles.row, styles.button]} onPress={onSubmit}>
|
||||||
<Text style={[styles.ssidLabel, { alignSelf: "center", textAlign: "center" }]}>{props.buttonText}</Text>
|
<Text style={[styles.ssidLabel, { alignSelf: "center", textAlign: "center" }]}>{props.buttonText}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
</SetupView >
|
</SetupView >
|
||||||
|
@ -91,9 +134,10 @@ const styles = StyleSheet.create({
|
||||||
subtext: {
|
subtext: {
|
||||||
color: "rgba(255,255,255,1)",
|
color: "rgba(255,255,255,1)",
|
||||||
textAlign: "left",
|
textAlign: "left",
|
||||||
fontSize: 18,
|
fontSize: 16,
|
||||||
lineHeight: 25,
|
lineHeight: 25,
|
||||||
width: "80%",
|
width: "80%",
|
||||||
|
paddingBottom: 30,
|
||||||
},
|
},
|
||||||
formContainer: {
|
formContainer: {
|
||||||
},
|
},
|
||||||
|
|
|
@ -56,6 +56,7 @@ class WifiSelectionView extends React.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.state = { wifiInfo: [] };
|
this.state = { wifiInfo: [] };
|
||||||
|
this.mounted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
processDeviceResponse(response) {
|
processDeviceResponse(response) {
|
||||||
|
@ -91,39 +92,56 @@ class WifiSelectionView extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
let component = this;
|
||||||
|
component.mounted = true;
|
||||||
this.props.device.conn.scanWifiNetworks().then(
|
this.props.device.conn.scanWifiNetworks().then(
|
||||||
(result) => {
|
(result) => {
|
||||||
this.setState({ wifiInfo: this.processDeviceResponse(result) })
|
if(component.mounted) {
|
||||||
|
this.setState({ wifiInfo: this.processDeviceResponse(result) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.mounted = false;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let inner;
|
let inner;
|
||||||
|
|
||||||
if (this.state.wifiInfo.length > 0) {
|
if (this.state.wifiInfo.length > 0) {
|
||||||
inner = (
|
inner = (
|
||||||
<ScrollView>
|
<View style={styles.listContainer}>
|
||||||
{this.state.wifiInfo.map(e => (
|
<ScrollView style={{backgroundColor: "red", centerContent: true, paddingTop: 20}}>
|
||||||
<WifiListElement
|
{this.state.wifiInfo.map(e => (
|
||||||
text={e.ssid}
|
<WifiListElement
|
||||||
strength={e.strength}
|
text={e.ssid}
|
||||||
lock={e.locked}
|
strength={e.strength}
|
||||||
key={e.ssid}
|
lock={e.locked}
|
||||||
onPress={() => { this.props.navigation.navigate("WifiPasswordView", {
|
key={e.ssid}
|
||||||
ssid: e.ssid,
|
onPress={() => {
|
||||||
lock: e.locked,
|
this.props.navigation.navigate("WifiPasswordView", {
|
||||||
strength: e.strength,
|
ssid: e.ssid,
|
||||||
buttonText: "Set Password",
|
lock: e.locked,
|
||||||
subText: "Please enter password for your home WiFi",
|
strength: e.strength,
|
||||||
}); }}>
|
confirmPwInput: false,
|
||||||
</WifiListElement>)
|
buttonText: "OK",
|
||||||
)}
|
subText: "Please enter the password for your home WiFi",
|
||||||
</ScrollView>)
|
});
|
||||||
|
}}>
|
||||||
|
</WifiListElement>)
|
||||||
|
)}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
inner = (<ActivityIndicator size="large" color="#ffffff" />
|
inner = (
|
||||||
|
<View style={{ alignItems: "center", justifyContent:"center", height: "100%" }}>
|
||||||
|
<View style={{ paddingBottom: 20 }}><Text style={{ fontSize: 16, color: "#fff"}}>Scanning WiFi networks</Text></View>
|
||||||
|
<ActivityIndicator size="large" color="#ffffff" />
|
||||||
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,11 +149,19 @@ class WifiSelectionView extends React.Component {
|
||||||
<SetupView
|
<SetupView
|
||||||
headerText="WiFi Connection"
|
headerText="WiFi Connection"
|
||||||
lowerLeftButtonText="My WiFi wasn't found"
|
lowerLeftButtonText="My WiFi wasn't found"
|
||||||
|
onLowerLeftButtonPress={() => {
|
||||||
|
this.props.navigation.navigate("WifiPasswordView", {
|
||||||
|
ssid: "swimtracker-E2842S", // todo real id here
|
||||||
|
lock: true,
|
||||||
|
strength: 4,
|
||||||
|
confirmPwInput: true,
|
||||||
|
buttonText: "Set Password",
|
||||||
|
subText: "Use this option only if you're home WiFi doesn't reach the SwimTracker. The SwimTracker creates its own WiFi with the password you set here.",
|
||||||
|
});
|
||||||
|
}}
|
||||||
lowerRightButtonText="Need help?"
|
lowerRightButtonText="Need help?"
|
||||||
>
|
>
|
||||||
<View style={styles.listContainer}>
|
{inner}
|
||||||
{inner}
|
|
||||||
</View>
|
|
||||||
</SetupView>
|
</SetupView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -145,7 +171,7 @@ class WifiSelectionView extends React.Component {
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
listContainer: {
|
listContainer: {
|
||||||
height: "75%",
|
height: "75%",
|
||||||
//backgroundColor: "red",
|
flex: 1,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue