Last active
August 10, 2016 10:42
-
-
Save SamSaffron/e9866eaa6e5ee2e0cfdfaf40758664bf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sample React Native App | |
* https://github.com/facebook/react-native | |
* @flow | |
*/ | |
import React, { | |
Component, | |
PropTypes | |
} from 'react'; | |
import { | |
AppRegistry, | |
StyleSheet, | |
Text, | |
View, | |
TextInput, | |
Image, | |
AsyncStorage, | |
TouchableHighlight, | |
Navigator, | |
ListView, | |
WebView | |
} from 'react-native'; | |
var CookieManager = require('react-native-cookies'); | |
class SiteManager extends Component { | |
static propTypes = { | |
onChange: PropTypes.func.isRequired, | |
} | |
constructor(props) { | |
super(props); | |
this.sites = []; | |
this.load(); | |
} | |
add(site) { | |
this.sites.push(site); | |
save(); | |
} | |
save() { | |
AsyncStorage.setItem('@Discourse.sites', JSON.stringify(this.sites)); | |
} | |
load() { | |
AsyncStorage.getItem('@Discourse.sites').then((json) => { | |
if (json) { | |
this.sites = JSON.parse(json); | |
this.props.onChange() | |
} | |
}); | |
} | |
} | |
class Site { | |
save(){ | |
this._siteManager.save(); | |
} | |
updateAuthCookie(){ | |
CookieManager.get(this.url, (err, res) => { | |
console.log('Got cookies for url', res); | |
}); | |
} | |
refreshNotificationCounts(){ | |
} | |
} | |
class SiteNav extends Component { | |
onChangeSites(){ | |
} | |
constructor(props) { | |
super(props); | |
this._siteManager = new SiteManager({onChange: onChangeSites}); | |
} | |
openUrl(navigator, site) { | |
navigator.push({title: site.url, index: 1, site: site}); | |
} | |
checkAuth(navigator, site) { | |
} | |
render() { | |
return ( | |
<Navigator | |
initialRoute={{ title: 'Discourse', index: 0 }} | |
renderScene={(route, navigator) => { | |
if(route.index == 0) { | |
return <HomePage title={route.title} | |
siteManager={this._siteManager} | |
onVisitSite={(site)=> this.openUrl(navigator, site)} | |
/> | |
} else if(route.index == 1) { | |
return <WebView source={{uri: route.site.url}} | |
onLoadEnd={() => | |
this.checkAuth(navigator, route.site)} | |
/> | |
} | |
} | |
} | |
style={{paddingTop: 20}} | |
/> | |
); | |
} | |
} | |
class HomePage extends Component { | |
static propTypes = { | |
onVisitSite: PropTypes.func.isRequired, | |
siteManager: PropTypes.object.isRequired, | |
} | |
constructor(props) { | |
super(props); | |
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); | |
this.onChangeSites(); | |
} | |
onChangeSites() { | |
this.setState({ | |
dataSource: this.state.dataSource.cloneWithRows(this.props.siteManager.sites) | |
}) | |
} | |
parseSite(body,url) { | |
var titleRegex = /<title>(.*)<\/title>/gi; | |
var title = titleRegex.exec(body)[1]; | |
var descriptionRegex = /<meta name="description" content="([^"]*)">/; | |
var description = descriptionRegex.exec(body)[1]; | |
var iconRegex = /<link rel="apple-touch-icon"[^>]*href="([^"]*)">/; | |
var icon = iconRegex.exec(body)[1]; | |
this.siteManager.add({title, description, icon, url}); | |
} | |
doSearch(term) { | |
fetch(term) | |
.then((resp)=>resp.blob()) | |
.then((blob)=>{ | |
var partial = blob.slice(0,5000); | |
var reader = new FileReader(); | |
reader.onloadend = () => { | |
this.parseSite(reader.result,term); | |
} | |
reader.readAsText(partial); | |
}) | |
.catch((e)=>alert(term + " not found! " + e)) | |
} | |
render() { | |
return ( | |
<View> | |
<TextInput | |
style={styles.term} | |
placeholder="Add Site" | |
returnKeyType="search" | |
keyboardType="url" | |
autoCapitalize="none" | |
onChangeText={(search) => this.setState({search})} | |
onSubmitEditing={()=>this.doSearch(this.state.search)} | |
/> | |
<ListView | |
dataSource={this.state.dataSource} | |
renderRow={(rowData) => | |
<TouchableHighlight | |
onPress={()=>this.props.onVisitSite(rowData)}> | |
<View accessibilityTraits="link" style={styles.row}> | |
<Image style={styles.icon} source={{uri: rowData.icon}} style={{width: 40, height: 40}} /> | |
<View style={styles.info}> | |
<Text> | |
{rowData.description} | |
</Text> | |
<Text> | |
{rowData.url} | |
</Text> | |
</View> | |
</View> | |
</TouchableHighlight> | |
} | |
/> | |
</View> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
term: { | |
height: 40, | |
paddingLeft: 10 | |
}, | |
icon: { | |
}, | |
info: { | |
paddingLeft: 10, | |
}, | |
row: { | |
flex: 1, | |
flexDirection: 'row', | |
paddingLeft: 10, | |
paddingBottom: 20 | |
}, | |
container: { | |
paddingTop: 22, | |
flex: 1, | |
justifyContent: 'flex-start', | |
alignItems: 'center', | |
backgroundColor: '#FFFAFF', | |
}, | |
welcome: { | |
fontSize: 20, | |
textAlign: 'center', | |
margin: 10, | |
}, | |
instructions: { | |
textAlign: 'center', | |
color: '#333333', | |
marginBottom: 5, | |
}, | |
}); | |
AppRegistry.registerComponent('discourse_react_native', () => SiteNav); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment