diff options
Diffstat (limited to 'client/src/lib/timeline/timelineFull.js')
| -rw-r--r-- | client/src/lib/timeline/timelineFull.js | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/client/src/lib/timeline/timelineFull.js b/client/src/lib/timeline/timelineFull.js new file mode 100644 index 0000000..a004987 --- /dev/null +++ b/client/src/lib/timeline/timelineFull.js @@ -0,0 +1,227 @@ +import React, { Component } from 'react'; +import { + ScrollView, + StyleSheet, + TouchableOpacity, + Image, + View, + RefreshControl, +} from 'react-native'; + +import HTMLView from 'react-native-htmlview' +import htmlStyles from '../components/htmlStyles' + +import ClearText from '../components/text' +import Heading from '../components/heading' +import Definition from '../components/definition' +import Close from '../components/close' + +export default class TimelineFull extends Component { + constructor() { + super() + this.onRefresh = this.onRefresh.bind(this) + this.onPickTag = this.onPickTag.bind(this) + } + onRefresh() { + this.props.onClose() + } + onPickTag(tag) { + this.props.onFilter(tag) + } + render() { + const item = this.props.item + let image, links; + if (! item) { + return ( <View></View> ) + } + + if (item.image) { + const caption = item.credit ? ( + <ClearText style={styles.caption}>{item.credit}</ClearText> + ) : ( + <View></View> + ) + const originalWidth = Number(item.image.width) + const originalHeight = Number(item.image.height) + const height = originalHeight > 450 ? 450 : originalHeight + const width = originalWidth * height / originalHeight + image = ( + <View style={styles.imageContainer}> + <View style={styles.imageWrapper}> + <img src={item.image.uri} + style={[styles.image, { + width: width, + height: height, + }]} /> + </View> + {caption} + </View> + ) + } else { + image = ( <View></View> ) + } + + if (item.links.length) { + const linkItems = item.links.map((link, i) => { + const url = link.uri + let name = link.text + if (! name || name.match(/Link Text/i)) { + name = linkTextFromUrl(url) + } + return ( + <TouchableOpacity key={'link_' + i} onPress={() => this.props.onLinkPress(url)}> + <ClearText style={styles.link}>{name}</ClearText> + </TouchableOpacity> + ) + }) + links = ( + <Definition label='Links' contentIsView={true}>{linkItems}</Definition> + ) + } + + const tags = item.keywords.map((tag, i) => { + return `<a href='${tag}'>${tag}</a>` + }).join(', ') + + const description = '<p>' + item.description + '</p>' + + return ( + <View style={styles.container}> + <ScrollView + contentContainerStyle={styles.item} + horizontal={false} + showsHorizontalScrollIndicator={false} + > + {image} + <Heading style={styles.title}>{item.title}</Heading> + <View style={styles.contentContainer}> + <View style={styles.bodyContainer}> + <HTMLView value={description} style={styles.description} stylesheet={htmlStyles} onLinkPress={this.props.onLinkPress} /> + </View> + <View style={styles.metadataContainer}> + <Definition label='Date'>{item.date}</Definition> + <Definition label='Medium'>{item.medium}</Definition> + <Definition label='Category' contentIsView={true}> + <TouchableOpacity onPress={() => this.onPickTag(item.category)}> + <ClearText style={styles.link}>{item.category}</ClearText> + </TouchableOpacity> + </Definition> + <Definition label='Tags' contentIsView={true}> + <HTMLView value={'<p>' + tags + '</p>'} stylesheet={tagHTMLStyles} onLinkPress={this.onPickTag} /> + </Definition> + {links} + </View> + </View> + </ScrollView> + <Close onPress={this.props.onClose} /> + </View> + ) + } +} + + +function linkTextFromUrl (url) { + const url_parts = url.split('/') + const domain = url_parts[2] + const terms = domain.split('.') + const len = terms.length + let term = (len > 2 && terms[len-1].length == 2) ? terms[len-3] : terms[len-2] + if (term == 'wikipedia') { + term += url_parts[4].replace(/\#.*/,'').replace('_', ' ') + } + return capitalize(term) +} +function capitalize (s){ + return s.charAt(0).toUpperCase() + s.slice(1) +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + scrollView: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'black', + }, + item: { + maxWidth: 1000, + padding: 40, + }, + imageContainer: { + width: '100%', + marginBottom: 10, + alignItems: 'center', + }, + imageWrapper: { + width: '100%', + marginBottom: 5, + alignItems: 'center', + }, + caption: { + fontSize: 12, + }, + + bodyContainer: { + left: '0%', + width: '60%', + paddingRight: 50, + }, + metadataContainer: { + position: 'absolute', + left: '60%', + width: '40%', + }, + title: { + textAlign: 'left', + fontWeight: 'bold', + fontSize: 18, + }, + date: { + textAlign: 'left', + }, + description: { + flex: 1, + flexDirection: 'column', + }, + link: { + textDecorationLine: 'underline', + textAlign: 'left', + }, + tag: { + marginRight: 5, + }, +}) + +const tagHTMLStyles = StyleSheet.create({ + p: { + color: 'white', + fontFamily: 'Futura-Medium', + textAlign: 'justify', + fontSize: 16, + lineHeight: 30, + }, + b: { + fontFamily: 'Futura-MediumItalic', + color: 'white', + fontSize: 16, + lineHeight: 30, + }, + i: { + fontFamily: 'Futura-MediumItalic', + color: 'white', + fontSize: 16, + lineHeight: 30, + }, + a: { + color: 'white', + fontFamily: 'Futura-Medium', + textDecorationLine: 'underline', + fontSize: 16, + lineHeight: 30, + }, +}) + |
