diff --git a/app/api/gitter.js b/app/api/gitter.js
index b661e82..7c29572 100644
--- a/app/api/gitter.js
+++ b/app/api/gitter.js
@@ -50,6 +50,11 @@ export function getToken(code) {
/**
* Authed user stuff
*/
+
+export function me(token) {
+ return callApi('user/me', token)
+}
+
export function currentUser(token) {
return callApi('user', token)
}
diff --git a/app/components/Loading/index.js b/app/components/Loading/index.js
index f5ae856..3c04b7d 100644
--- a/app/components/Loading/index.js
+++ b/app/components/Loading/index.js
@@ -1,10 +1,10 @@
import PropTypes from 'prop-types'
import React from 'react'
-import {ActivityIndicator, View} from 'react-native';
+import {ActivityIndicator, View, Text} from 'react-native';
import {THEMES} from '../../constants'
const {colors} = THEMES.gitterDefault
-const Loading = ({size, height, color}) => (
+const Loading = ({size, height, color, text}) => (
(
animating
size={size}
color={color || colors.raspberry}/>
+ {text && (
+
+ {text}
+
+ )}
)
diff --git a/app/components/LoadingOverlay/index.js b/app/components/LoadingOverlay/index.js
new file mode 100644
index 0000000..149409c
--- /dev/null
+++ b/app/components/LoadingOverlay/index.js
@@ -0,0 +1,18 @@
+import React from 'react'
+import {View, Text} from 'react-native'
+import Loading from '../Loading'
+import s from './styles'
+
+const LoadingOverlay = ({text}) => (
+
+
+
+
+
+)
+
+LoadingOverlay.propTypes = {
+
+}
+
+export default LoadingOverlay
diff --git a/app/components/LoadingOverlay/styles.js b/app/components/LoadingOverlay/styles.js
new file mode 100644
index 0000000..8814e97
--- /dev/null
+++ b/app/components/LoadingOverlay/styles.js
@@ -0,0 +1,17 @@
+import {StyleSheet} from 'react-native'
+
+const styles = StyleSheet.create({
+ loadingContainer: {
+ flex: 1,
+ position: 'absolute',
+ bottom: 0,
+ top: 0,
+ left: 0,
+ right: 0,
+ backgroundColor: 'rgba(0,0,0,0.7)',
+ justifyContent: 'center',
+ alignItems: 'center'
+ }
+})
+
+export default styles
diff --git a/app/constants.js b/app/constants.js
index 6eb8c67..cc97130 100644
--- a/app/constants.js
+++ b/app/constants.js
@@ -53,5 +53,6 @@ export const icons = {
'info-outline': {icon: 'info-outline', color: 'white', size: 24},
'back': {icon: iOS ? 'chevron-left' : 'arrow-back', color: 'white', size: 24},
'forward': iOS ? {icon: 'chevron-right', color: 'white', size: 40} : {icon: 'arrow-forward', color: 'white', size: 24},
- 'expand-more': {icon: 'expand-more', color: 'white', size: 24}
+ 'expand-more': {icon: 'expand-more', color: 'white', size: 24},
+ 'checkmark': {icon: 'check', color: 'white', size: 24}
}
diff --git a/app/modules/auth.js b/app/modules/auth.js
index 7681fb0..6735bc7 100644
--- a/app/modules/auth.js
+++ b/app/modules/auth.js
@@ -8,17 +8,46 @@ import {setItem, removeItem} from '../utils/storage'
* Constants
*/
+const TOKEN_REGEX = /^[a-z\d]*$/i
+
export const LOGINING = 'auth/LOGINING'
export const LOGINED_IN_SUCCESS = 'auth/LOGINED_IN_SUCCESS'
export const LOGIN_USER = 'auth/LOGIN_USER'
export const LOGIN_USER_BY_TOKEN = 'auth/LOGIN_USER_BY_TOKEN'
export const UNEXPECTED_ERROR = 'auth/UNEXPECTED_ERROR'
export const LOGOUT = 'auth/LOGOUT'
+export const CHECK_TOKEN = 'auth/CHECK_TOKEN'
+export const CHECK_TOKEN_OK = 'auth/CHECK_TOKEN_OK'
+export const CHECK_TOKEN_ERROR = 'auth/CHECK_TOKEN_ERROR'
/**
* Action Creators
*/
+export function checkToken({token}) {
+ return async dispatch => {
+ try {
+ dispatch({type: CHECK_TOKEN})
+
+ if (!TOKEN_REGEX.test(token)) {
+ throw new Error('Bad token.')
+ }
+
+ const user = await Api.me(token)
+
+ if (!!user.error) {
+ throw new Error('Unable to authenticate. Please try again.')
+ }
+
+ dispatch({type: CHECK_TOKEN_OK})
+
+ await dispatch(loginByToken({token}))
+ } catch (err) {
+ dispatch({type: CHECK_TOKEN_ERROR, error: err.message})
+ }
+ }
+}
+
export function loginByToken({token, code}) {
return async dispatch => {
try {
@@ -37,9 +66,9 @@ export function loginByToken({token, code}) {
rootNavigator.startAppWithScreen({screen: 'gm.Launch'})
await dispatch(init())
- dispatch({LOGINED_IN_SUCCESS})
+ dispatch({type: LOGINED_IN_SUCCESS})
} catch (err) {
- dispatch({type: UNEXPECTED_ERROR, error: err})
+ dispatch({type: UNEXPECTED_ERROR, error: err.message})
}
}
}
@@ -66,7 +95,7 @@ const initialState = {
loginedIn: false,
token: '',
error: false,
- errors: {}
+ errors: ''
}
export default function auth(state = initialState, action) {
@@ -75,7 +104,8 @@ export default function auth(state = initialState, action) {
if (!!action.token) {
return {...state,
loginedIn: true,
- token: action.token
+ token: action.token,
+ error: false
}
} else {
return {...state,
@@ -84,12 +114,18 @@ export default function auth(state = initialState, action) {
}
}
}
+
+ case CHECK_TOKEN:
case LOGINING: {
return {...state,
- logining: true
+ logining: true,
+ error: false,
+ errors: ''
}
}
+
+ case CHECK_TOKEN_OK:
case LOGINED_IN_SUCCESS: {
return {...state,
logining: false
@@ -103,6 +139,14 @@ export default function auth(state = initialState, action) {
}
}
+ case CHECK_TOKEN_ERROR:
+ case UNEXPECTED_ERROR:
+ return {...state,
+ error: true,
+ logining: false,
+ errors: action.error
+ }
+
case LOGOUT: {
return initialState
}
diff --git a/app/screens/Drawer/ChannelListItem/index.js b/app/screens/Drawer/ChannelListItem/index.js
index fc16822..b6702fb 100644
--- a/app/screens/Drawer/ChannelListItem/index.js
+++ b/app/screens/Drawer/ChannelListItem/index.js
@@ -37,15 +37,20 @@ const ChannelListItem = ({
size={30} />
- {name}
+
+ {name}
+
-
-
- {(!!unreadItems || !!mentions || !!lurk) &&
- }
+
+
)
}
diff --git a/app/screens/Drawer/ChannelListItem/styles.js b/app/screens/Drawer/ChannelListItem/styles.js
index 60b3e8d..337f80f 100644
--- a/app/screens/Drawer/ChannelListItem/styles.js
+++ b/app/screens/Drawer/ChannelListItem/styles.js
@@ -11,7 +11,8 @@ const styles = StyleSheet.create({
backgroundColor: 'white'
},
headingContainer: {
- marginLeft: 10
+ marginLeft: 10,
+ flex: 1
},
heading: {
fontSize: 12,
diff --git a/app/screens/Home/HomeRoomItem/index.js b/app/screens/Home/HomeRoomItem/index.js
index c044ea1..dc2b63b 100644
--- a/app/screens/Home/HomeRoomItem/index.js
+++ b/app/screens/Home/HomeRoomItem/index.js
@@ -19,9 +19,13 @@ const HomeRoomItem = ({id, name, userCount, oneToOne, onPress, ...props}) => {
-
- {name}
+
+ {name}
+
{userCount} people
diff --git a/app/screens/Home/HomeRoomItem/styles.js b/app/screens/Home/HomeRoomItem/styles.js
index 1ca1541..cfdce69 100644
--- a/app/screens/Home/HomeRoomItem/styles.js
+++ b/app/screens/Home/HomeRoomItem/styles.js
@@ -2,6 +2,7 @@ import {StyleSheet} from 'react-native'
const styles = StyleSheet.create({
container: {
+ flex: 1,
height: 80,
padding: 20,
paddingLeft: 20,
@@ -11,6 +12,7 @@ const styles = StyleSheet.create({
alignItems: 'center'
},
infoContainer: {
+ flex: 1,
flexDirection: 'column',
marginLeft: 16
},
diff --git a/app/screens/Home/HomeRoomItemMy/index.js b/app/screens/Home/HomeRoomItemMy/index.js
index ba129e3..95c0295 100644
--- a/app/screens/Home/HomeRoomItemMy/index.js
+++ b/app/screens/Home/HomeRoomItemMy/index.js
@@ -26,17 +26,22 @@ const HomeRoomItemMy = ({
size={50} />
- {name}
+
+ {name}
+
{userCount} people
-
{(!!unreadItems || !!mentions || !!lurk) &&
-
- }
+
+ }
+
)
}
diff --git a/app/screens/Home/index.js b/app/screens/Home/index.js
index 1797ad6..051aac1 100644
--- a/app/screens/Home/index.js
+++ b/app/screens/Home/index.js
@@ -22,7 +22,7 @@ class HomeScreen extends Component {
homeNavigator = this.props.navigator
- this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
+ this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this))
this.props.navigator.setButtons({
leftButtons: [{
diff --git a/app/screens/Login/index.js b/app/screens/Login/index.js
index 87f35a0..58940fb 100644
--- a/app/screens/Login/index.js
+++ b/app/screens/Login/index.js
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types'
import React, { Component } from 'react'
-import {Text, Image, View, ToastAndroid} from 'react-native';
+import {Text, View} from 'react-native';
import Button from '../../components/Button'
import s from './styles'
import {connect} from 'react-redux'
@@ -12,35 +12,29 @@ class LoginScreen extends Component {
render() {
const {navigator} = this.props
return (
-
+
GitterMobile
-
- To start using Gitter mobile you should login first.
- You can login by oauth2 through WebView or just
- copy/paste authentication token.
-
-
+
)
}
}
diff --git a/app/screens/Login/styles.js b/app/screens/Login/styles.js
index e8691fd..106cad9 100644
--- a/app/screens/Login/styles.js
+++ b/app/screens/Login/styles.js
@@ -1,13 +1,13 @@
import {StyleSheet, Dimensions} from 'react-native'
-import backgroundImage from '../../styles/common/BackgroundImage'
import {THEMES} from '../../constants'
const {colors} = THEMES.gitterDefault
const styles = StyleSheet.create({
container: {
- ...backgroundImage,
- justifyContent: 'space-around',
- alignItems: 'center',
+ flex: 1,
+ backgroundColor: colors.raspberry,
+ justifyContent: 'center',
+ alignItems: 'center'
},
logo: {
fontSize: 40,
@@ -23,21 +23,22 @@ const styles = StyleSheet.create({
backgroundColor: 'transparent'
},
buttonGroup: {
- flexDirection: 'row'
+ position: 'absolute',
+ bottom: 20
},
buttonStyle: {
- margin: 10,
- backgroundColor: colors.primaryButton,
- width: 150,
- height: 40,
+ backgroundColor: 'white',
+ marginBottom: 16,
+ height: 35,
borderRadius: 2,
justifyContent: 'center',
alignItems: 'center',
- elevation: 2
+ elevation: 4
},
buttonText: {
- color: 'white',
- fontWeight: 'bold'
+ fontWeight: 'bold',
+ paddingHorizontal: 40,
+ color: colors.raspberry
}
})
diff --git a/app/screens/LoginByToken/index.js b/app/screens/LoginByToken/index.js
index 7edf3fc..7db1555 100644
--- a/app/screens/LoginByToken/index.js
+++ b/app/screens/LoginByToken/index.js
@@ -1,11 +1,12 @@
import PropTypes from 'prop-types'
import React, { Component } from 'react'
-import {TextInput, Text, Image} from 'react-native';
+import {TextInput, Text, View, Linking, ScrollView} from 'react-native';
import s from './styles'
import {connect} from 'react-redux'
-import {loginByToken} from '../../modules/auth'
+import {checkToken} from '../../modules/auth'
+import iconsMap from '../../utils/iconsMap'
-import Link from '../../components/Link'
+import LoadingOverlay from '../../components/LoadingOverlay'
import Button from '../../components/Button'
import {THEMES} from '../../constants'
const {colors} = THEMES.gitterDefault
@@ -14,48 +15,90 @@ class LoginByTokenScreen extends Component {
constructor(props) {
super(props)
this.handleLogin = this.handleLogin.bind(this)
+ this.handleChangeText = this.handleChangeText.bind(this)
+
+ this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this))
this.state = {
token: ''
}
}
+ onNavigatorEvent(event) {
+ if (event.type === 'NavBarButtonPress') {
+ if (event.id === 'submit') {
+ this.handleLogin()
+ }
+ }
+ }
+
handleLogin() {
const {dispatch, navigator} = this.props
const {token} = this.state
if (!token.trim()) {
return
}
- dispatch(loginByToken({token}, navigator))
+ dispatch(checkToken({token}, navigator))
}
- render() {
+ handleChangeText(e) {
+ let rightButtons = []
+ if (e.nativeEvent.text.trim().length) {
+ rightButtons = [{
+ title: 'Submit',
+ id: 'submit',
+ icon: iconsMap.checkmark,
+ showAsAction: 'always'
+ }]
+ }
+ this.props.navigator.setButtons({rightButtons})
+ this.setState({token: e.nativeEvent.text.trim()})
+ }
+
+ renderLoading() {
return (
-
-
- Sign in to Gitter
- to get your authentication token. Copy it and paste into the textinput below.
-
+
+ )
+ }
- this.setState({token: e.nativeEvent.text})} />
-
+
+
+
+
+
-
+ {logining && this.renderLoading()}
+
)
}
}
@@ -73,4 +116,14 @@ LoginByTokenScreen.propTypes = {
dispatch: PropTypes.func
}
-export default connect()(LoginByTokenScreen)
+function mapStateToProps(state) {
+ const {logining, errors, error} = state.auth
+
+ return {
+ logining,
+ errors,
+ error
+ }
+}
+
+export default connect(mapStateToProps)(LoginByTokenScreen)
diff --git a/app/screens/LoginByToken/styles.js b/app/screens/LoginByToken/styles.js
index 9be2221..0f0b75d 100644
--- a/app/screens/LoginByToken/styles.js
+++ b/app/screens/LoginByToken/styles.js
@@ -1,40 +1,23 @@
import {StyleSheet} from 'react-native'
-import backgroundImage from '../../styles/common/BackgroundImage'
import {THEMES} from '../../constants'
const {colors} = THEMES.gitterDefault
const styles = StyleSheet.create({
container: {
- ...backgroundImage,
flex: 1,
- // justifyContent: 'space-around',
- // alignItems: 'center',
- // padding: 16
- },
- logo: {
- marginTop: 40,
- fontSize: 40,
- color: 'white',
- textAlign: 'center'
- },
- hero: {
- marginTop: 40,
- marginHorizontal: 20,
- fontSize: 24,
- color: 'white',
- lineHeight: 40,
- backgroundColor: 'transparent'
+ backgroundColor: 'white',
+ paddingHorizontal: 16
},
- group: {
- // flexDirection: 'column'
+ buttonContainer: {
+ alignSelf: 'center'
},
buttonStyle: {
- margin: 10,
- backgroundColor: colors.primaryButton,
- width: 150,
- height: 40,
+ margin: 16,
+ backgroundColor: colors.raspberry,
+ paddingHorizontal: 40,
+ marginBottom: 40,
+ height: 35,
borderRadius: 2,
- alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
elevation: 2
@@ -44,13 +27,23 @@ const styles = StyleSheet.create({
fontWeight: 'bold'
},
textfield: {
- marginVertical: 10,
- marginHorizontal: 20,
- // width: 250,
height: 40,
backgroundColor: 'white',
- borderRadius: 5,
- paddingLeft: 8
+ paddingLeft: 0,
+ color: colors.raspberry
+ },
+ textfieldContainer: {
+ marginVertical: 16,
+ borderBottomWidth: 1,
+ borderBottomColor: colors.raspberry
+ },
+ hint: {
+ color: colors.secondaryFont
+ },
+ error: {
+ color: colors.red,
+ marginBottom: 16,
+ fontSize: 18
}
})
diff --git a/app/screens/LoginByWebView/index.js b/app/screens/LoginByWebView/index.js
index ee06262..6968b32 100644
--- a/app/screens/LoginByWebView/index.js
+++ b/app/screens/LoginByWebView/index.js
@@ -2,13 +2,11 @@ import PropTypes from 'prop-types'
import React, { Component } from 'react'
import {
WebView,
- Image,
- Text,
View
} from 'react-native'
import {connect} from 'react-redux'
-import Loading from '../../components/Loading'
+import LoadingOverlay from '../../components/LoadingOverlay'
import {THEMES} from '../../constants'
const {colors} = THEMES.gitterDefault
@@ -46,34 +44,23 @@ class LoginByWebView extends Component {
renderLoading() {
return (
-
-
-
- Signing in...
-
-
+
)
}
render() {
const {loading} = this.state
return (
-
- {loading
- ? (
- this.renderLoading()
- ) : (
-
- )
- }
-
+
+
+ {true && this.renderLoading()}
+
)
}
}
diff --git a/app/screens/User/UserInfo/styles.js b/app/screens/User/UserInfo/styles.js
index 6adbb9c..1267bfd 100644
--- a/app/screens/User/UserInfo/styles.js
+++ b/app/screens/User/UserInfo/styles.js
@@ -5,7 +5,8 @@ const {colors} = THEMES.gitterDefault
const styles = StyleSheet.create({
container: {
flex: 1,
- backgroundColor: 'white'
+ backgroundColor: 'white',
+ paddingBottom: 16
},
item: {
paddingHorizontal: 20,
diff --git a/app/screens/User/index.js b/app/screens/User/index.js
index 6cb22eb..3f94cf5 100644
--- a/app/screens/User/index.js
+++ b/app/screens/User/index.js
@@ -106,7 +106,7 @@ class UserScreen extends Component {
)
}
return (
-
+