commit 61c834f66ff079d8036962855a39a90f729856e9
parent 1aa1b5f32490101c77c6e8a512b90a8fc4cb14ef
Author: Johan Lindskogen <johan.lindskogen@gmail.com>
Date:   Mon,  2 Apr 2018 21:44:13 +0200
Add loginform
Diffstat:
3 files changed, 171 insertions(+), 19 deletions(-)
diff --git a/src/usecase/ConnectionGate.ts b/src/usecase/ConnectionGate.ts
@@ -1,19 +0,0 @@
-import { connect } from "react-redux";
-
-interface Props {
-  connected: boolean;
-  children: React.ReactChild;
-}
-
-const ConnectionGate = (props: Props) => {
-  console.log("connection gate", props.connected);
-  if (props.connected) {
-    return props.children;
-  } else {
-    return null;
-  }
-};
-
-export default connect(state => ({
-  connected: state.app.connected
-}))(ConnectionGate);
diff --git a/src/usecase/ConnectionGate.tsx b/src/usecase/ConnectionGate.tsx
@@ -0,0 +1,24 @@
+import * as React from "react";
+import { connect } from "react-redux";
+import LoginForm from "./login/LoginForm";
+
+interface Props {
+  connecting: boolean;
+  connected: boolean;
+  onConnect: (hostname: string, password: string) => void;
+}
+
+class ConnectionGate extends React.Component<Props> {
+  render() {
+    const { connecting, connected, children, onConnect } = this.props;
+    if (connected) {
+      return children;
+    } else {
+      return <LoginForm connecting={connecting} onConnect={onConnect} />;
+    }
+  }
+}
+
+export default connect(state => ({
+  connected: state.app.connected
+}))(ConnectionGate);
diff --git a/src/usecase/login/LoginForm.tsx b/src/usecase/login/LoginForm.tsx
@@ -0,0 +1,147 @@
+import * as React from "react";
+import {
+  View,
+  Text,
+  TextInput,
+  ActivityIndicator,
+  StyleSheet,
+  Switch,
+  StatusBar,
+  TouchableOpacity
+} from "react-native";
+import { connect } from "react-redux";
+
+interface Props {
+  onConnect: (hostname: string, password: string) => void;
+  connecting: boolean;
+}
+interface State {
+  hostname: string;
+  password: string;
+  ssl: boolean;
+}
+
+export default class LoginForm extends React.Component<Props, State> {
+  state: State = {
+    hostname: "",
+    password: "",
+    ssl: true
+  };
+
+  onPress = () => {
+    const { hostname, password, ssl } = this.state;
+    this.props.onConnect(this.getFullWebsocketUrl(hostname, ssl), password);
+  };
+
+  getFullWebsocketUrl = (hostname: string, ssl: boolean) =>
+    `${ssl ? "wss" : "ws"}://${hostname}/weechat`;
+
+  setHostname = (hostname: string) => {
+    this.setState({ hostname });
+  };
+
+  setPassword = (password: string) => {
+    this.setState({ password });
+  };
+
+  setSSL = (ssl: boolean) => {
+    this.setState({ ssl });
+  };
+
+  render() {
+    const { children, connecting } = this.props;
+    const { hostname, password, ssl } = this.state;
+
+    return (
+      <View style={styles.container}>
+        <StatusBar barStyle="light-content" />
+        <Text style={styles.header}>
+          Connect to Weechat relay via websocket
+        </Text>
+        <TextInput
+          style={styles.input}
+          placeholderTextColor="#4157af"
+          autoCapitalize="none"
+          placeholder="Hostname"
+          onChangeText={this.setHostname}
+          value={hostname}
+        />
+        <TextInput
+          style={styles.input}
+          placeholderTextColor="#4157af"
+          autoCapitalize="none"
+          placeholder="Password"
+          secureTextEntry
+          onChangeText={this.setPassword}
+          value={password}
+        />
+        <View style={{ flexDirection: "row", justifyContent: "space-between" }}>
+          <Text style={styles.text}>SSL</Text>
+          <Switch
+            style={{ margin: 10 }}
+            value={ssl}
+            onValueChange={this.setSSL}
+          />
+        </View>
+        <View style={styles.centeredButton}>
+          <TouchableOpacity
+            disabled={connecting}
+            style={styles.button}
+            onPress={this.onPress}
+          >
+            {connecting ? (
+              <ActivityIndicator color="#4157af" animating={connecting} />
+            ) : (
+              <Text style={styles.buttonText}>CONNECT</Text>
+            )}
+          </TouchableOpacity>
+        </View>
+      </View>
+    );
+  }
+}
+
+const styles = StyleSheet.create({
+  container: {
+    backgroundColor: "#f8f8f8",
+    flex: 1,
+    padding: 20
+  },
+  header: {
+    textAlign: "center",
+    color: "#4157af",
+    fontSize: 20
+  },
+  text: {
+    padding: 10,
+    color: "#4157af",
+    fontSize: 18
+  },
+  input: {
+    marginVertical: 10,
+    padding: 10,
+    borderBottomWidth: 2,
+    fontSize: 18,
+    borderColor: "#4157af",
+    color: "#4157af"
+  },
+  centeredButton: {
+    flexDirection: "row",
+    justifyContent: "center"
+  },
+  button: {
+    borderWidth: 2,
+    borderColor: "#4157af",
+    width: 200,
+    backgroundColor: "#f8f8f8",
+    paddingHorizontal: 20,
+    paddingVertical: 10,
+    borderRadius: 20
+  },
+  buttonText: {
+    textAlign: "center",
+    color: "#4157af",
+    fontWeight: "400",
+    fontSize: 18
+  }
+});