Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation for new Bot UI #1437

Merged
merged 9 commits into from
Oct 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions index.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const {AppRegistry} = React;
import App from './src/App';

AppRegistry.registerComponent('Chat', () => App);

//
// in case isolated work, comment line above and uncomment lines below
// import React from 'react';
// import botFactory from './src/factory/botFactory';
Expand All @@ -13,12 +13,20 @@ AppRegistry.registerComponent('Chat', () => App);
// import BotDetails from './src/components/BotDetails';
// import {Text, AppRegistry, View} from 'react-native';
// import locationStore from './src/store/locationStore';
// import {Router, Scene, Stack} from 'react-native-router-flux';
//
// const owner = new Profile('123');
// owner.handle = 'aksonov';
// owner.image = { source: require('./images/iconBotAdded.png')};
// locationStore.location = new Location({latitude: 12, longitude: 12});
// const bot = botFactory.create({id: '123', owner, followersSize: 123, description: '123123123fsd fsd fsdf sdf',
// title: 'Wow my test bot rules!', location: {latitude: 10, longitude: 10}, visibility: 100});
// const App = () => <BotDetails item='123' isNew />;
// const bot = botFactory.create({id: '123', owner, address: 'Los Angeles, US', followersSize: 123, description: '123123123fsd fsd fsdf sdf',
// title: 'Wow my test bot rules!', location: {latitude: 45.547289, longitude: 13.7333244}, visibility: 100});
// bot.image = {source: require('./images/iconAddcover.png')};
// const App = () => <Router>
// <Stack>
// <Scene item='123' isNew component={BotDetails} scale={0.5} />
// </Stack>
// </Router>;
//
// AppRegistry.registerComponent('App', () => App);
//
12 changes: 5 additions & 7 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,17 @@ import ChatsScreen from './components/ChatsScreen';
import ChatScreen from './components/ChatScreen';
import BotNoteScene from './components/BotNote';
import BotCompose from './components/BotCompose';
import BotCreate from './components/BotCreate';
import BotCreate from './components/map/BotCreate';
import BotDetails from './components/BotDetails';
import BotMap from './components/BotMap';
import BotsScreen from './components/BotsScreen';
import BotShareSelectFriends from './components/BotShareSelectFriends';
import BotShareCompleted from './components/BotShareCompleted';
import ExploreNearBy from './components/ExploreNearBy';
import ExploreNearBy from './components/map/ExploreNearBy';
import TestRegister from './components/TestRegister';
import CodePushScene from './components/CodePushScene';
import OnboardingSlideshow from './components/OnboardingSlideshowScene';
import LocationWarning from './components/LocationWarning';
import BotAddressScene from './components/BotAddressScene';
import BotAddressScene from './components/map/BotAddressScene';
import * as peopleLists from './components/people-lists';
import ReportUser from './components/report-modals/ReportUser';
import ReportBot from './components/report-modals/ReportBot';
Expand Down Expand Up @@ -174,7 +173,7 @@ when(
() => model.connected && model.profile && model.profile.handle,
() => {
setTimeout(() => {
// Actions.botDetails({item: 'a8bde3a6-9eff-11e7-8a33-0a580a020198'});
// Actions.botDetails({item: '8bfee86e-9d1a-11e7-bd78-0a580a020377'});
// Actions.subscribers({item: 'd1b08da4-3429-11e7-93e4-0e78520e044a'});
// Actions.botShareSelectFriends({item: '9b2a4590-8e7e-11e7-8720-0eea5386eb69'});
// setTimeout(() => Actions.botPhotoSwiper({item: 'aa567e14-5795-11e7-9926-0e78520e044a', index: 1}), 1000);
Expand Down Expand Up @@ -284,14 +283,13 @@ const App = () => (
<Scene key='camera' component={Camera} clone hideNavBar />
<Scene key='botEdit' component={BotCompose} clone back edit navTransparent right={() => null} />
<Scene key='codePush' component={CodePushScene} title='CodePush' clone back />
<Scene key='botDetails' component={BotDetails} clone back right={() => null} />
<Scene key='botDetails' component={BotDetails} scale={0.5} clone back right={() => null} />
<Scene key='botShareSelectFriends' component={BotShareSelectFriends} title='Share' clone back right={() => null} />
<Scene key='subscribers' component={peopleLists.BotSubscriberList} clone back right={() => null} navTransparent={false} title='Saves' />
<Scene key='botNote' component={BotNoteScene} clone leftTitle={'Cancel'} onLeft={Actions.pop} navTransparent={false} />
<Scene key='botAddress' component={BotAddressScene} clone hideNavBar back />
<Scene key='profileDetails' component={ProfileDetail} clone back navTransparent={false} />
<Scene key='myAccount' component={MyAccount} editMode clone back />
<Scene key='botMap' component={BotMap} map clone back navigationBarStyle={{backgroundColor: 'white', height: 100}} />
<Scene key='followers' component={peopleLists.FollowersList} clone title='Followers' back />
<Scene key='following' component={peopleLists.FollowingList} clone title='Following' back />
<Scene key='blocked' component={peopleLists.BlockedList} clone title='Blocked Users' back right={() => null} />
Expand Down
80 changes: 42 additions & 38 deletions src/components/BotDetails/BotDetailsHeader.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
// @flow

import React from 'react';
import {View, Text, Animated, Alert, TouchableWithoutFeedback, Image, StyleSheet} from 'react-native';
import {View, Text, Animated, Alert, TouchableOpacity, TouchableWithoutFeedback, Image, StyleSheet} from 'react-native';
import {observable} from 'mobx';
import Popover from 'react-native-popover';
import {observer} from 'mobx-react/native';
import botFactory from '../../factory/botFactory';
import {k, width, defaultCover} from '../Global';
import {k, width, height, defaultCover} from '../Global';
import botStore from '../../store/botStore';
import locationStore from '../../store/locationStore';
import {colors} from '../../constants';
import BotButtons from './BotButtons';
import UserInfoRow from './UserInfoRow';
import Bot from '../../model/Bot';
import {RText} from '../common';
import BotDetailsMap from '../map/BotDetailsMap';
import {Actions} from 'react-native-router-flux';

type Props = {
botId: string,
flashPopover: Function,
scale: number,
};

type State = {
Expand Down Expand Up @@ -105,48 +108,49 @@ class BotDetailsHeader extends React.Component {
const isOwn = !owner || owner.isOwn;
return (
<View style={{flex: 1}}>
<View style={{height: width, backgroundColor: 'white'}}>
<TouchableWithoutFeedback onPress={this.handleImagePress}>
{bot.image && bot.image.source ? (
<Image style={{height: width, width}} resizeMode='contain' source={bot.image.source} />
) : (
<Image style={{height: width, width}} source={defaultCover[bot.coverColor % 4]} resizeMode='contain' />
)}
</TouchableWithoutFeedback>
<View style={{height: this.props.scale === 0 ? height - (70 * k) : width, backgroundColor: 'white'}}>
<BotDetailsMap
bot={bot}
onMapPress={() => Actions.refresh({scale: 0})}
onImagePress={() => Actions.refresh({scale: this.props.scale === 1 ? 0.5 : this.props.scale + 0.5})}
scale={this.props.scale}
/>
<Animated.View pointerEvents='none' style={[{opacity: this.state.fadeAnim}, styles.botAddedContainer]}>
<Image source={require('../../../images/iconBotAdded.png')} />
</Animated.View>
</View>
<BotButtons isOwn={isOwn} bot={bot} subscribe={this.subscribe} unsubscribe={this.unsubscribe} isSubscribed={bot.isSubscribed} afterCopy={this.showPopover} />
<UserInfoRow flashPopover={this.props.flashPopover} bot={bot} owner={owner} ref={r => (this.userInfo = r)} />
{!!bot.description && (
<View style={styles.descriptionContainer}>
<RText numberOfLines={0} size={16} weight='Light' color={locationStore.isDay ? colors.DARK_PURPLE : colors.WHITE}>
{bot.description}
{this.props.scale > 0 && <View>
<BotButtons isOwn={isOwn} bot={bot} subscribe={this.subscribe} unsubscribe={this.unsubscribe} isSubscribed={bot.isSubscribed} afterCopy={this.showPopover} />
<UserInfoRow flashPopover={this.props.flashPopover} bot={bot} owner={owner} ref={r => (this.userInfo = r)} />
{!!bot.description && (
<View style={styles.descriptionContainer}>
<RText numberOfLines={0} size={16} weight='Light' color={locationStore.isDay ? colors.DARK_PURPLE : colors.WHITE}>
{bot.description}
</RText>
</View>
)}
<View style={{height: 8.5, width}} />
<View style={{height: 45, width, flexDirection: 'row', alignItems: 'center', backgroundColor: 'white'}}>
<Image style={{marginLeft: 14, width: 14, height: 14}} source={require('../../../images/postsIcon.png')} />
<RText size={15} color={colors.DARK_PURPLE} style={{marginLeft: 7, letterSpacing: 0.3}}>
Posts
</RText>

<RText size={12} color={colors.DARK_GREY} style={{marginLeft: 7}}>
{bot.totalItems}
</RText>
</View>
)}
<View style={{height: 8.5, width}} />
<View style={{height: 45, width, flexDirection: 'row', alignItems: 'center', backgroundColor: 'white'}}>
<Image style={{marginLeft: 14, width: 14, height: 14}} source={require('../../../images/postsIcon.png')} />
<RText size={15} color={colors.DARK_PURPLE} style={{marginLeft: 7, letterSpacing: 0.3}}>
Posts
</RText>

<RText size={12} color={colors.DARK_GREY} style={{marginLeft: 7}}>
{bot.totalItems}
</RText>
</View>
<View style={{height: 1, width}} />
<Popover
isVisible={this.state.isVisible}
fromRect={this.state.buttonRect}
contentStyle={{backgroundColor: colors.DARK_PURPLE}}
placement='bottom'
// onClose={this.closePopover}
>
<Text style={styles.popoverText}>Address copied to clipboard</Text>
</Popover>
<View style={{height: 1, width}} />
<Popover
isVisible={this.state.isVisible}
fromRect={this.state.buttonRect}
contentStyle={{backgroundColor: colors.DARK_PURPLE}}
placement='bottom'
// onClose={this.closePopover}
>
<Text style={styles.popoverText}>Address copied to clipboard</Text>
</Popover>
</View>}
</View>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/BotDetails/UserInfoRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class UserInfoRow extends React.Component {
{locationStore.location &&
bot.location && (
<View>
<TouchableOpacity onLongPress={this.showPopover} ref={r => (this.button = r)} onPress={() => Actions.botMap({item: bot.id})} style={styles.botLocationButton}>
<TouchableOpacity onLongPress={this.showPopover} ref={r => (this.button = r)} onPress={() => Actions.refresh({scale: 0})} style={styles.botLocationButton}>
<View style={{paddingRight: 2 * k, paddingLeft: 5 * k}}>
<Image style={{width: 11 * k, height: 14 * k}} source={require('../../../images/iconBotLocation2.png')} />
</View>
Expand Down
16 changes: 8 additions & 8 deletions src/components/BotDetails/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ class BotDetails extends BotNavBarMixin(React.Component) {
};
}

_headerComponent = () => <BotDetailsHeader botId={this.bot && this.bot.id} flashPopover={this.flashPopover} />;
_headerComponent = () => <BotDetailsHeader botId={this.bot && this.bot.id} scale={this.props.scale} flashPopover={this.flashPopover} {...this.props} />;

_footerComponent = () =>
(this.bot.posts.length > 0 ? <ListFooter footerImage={require('../../../images/graphicEndPosts.png')} finished={this.bot.posts.length === this.bot.totalItems} /> : null);
// workaround: we need footer to be shown to unhide last posts hidden by add post input box
_footerComponent = () => <View style={{height: 60}} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did the marginBottom style on FlatList not work for this?

// (this.bot.posts.length > 0 ? <ListFooter footerImage={require('../../../images/graphicEndPosts.png')} finished={this.bot.posts.length === this.bot.totalItems} /> : null);

componentWillMount() {
this.loadBot();
Expand All @@ -75,7 +76,7 @@ class BotDetails extends BotNavBarMixin(React.Component) {
);
};

getData = () => (this.bot ? this.bot.posts.filter(post => post.content || (post.image && post.image.loaded)) : []);
getData = () => (this.bot && this.props.scale > 0 ? this.bot.posts.filter(post => post.content || (post.image && post.image.loaded)) : []);

scrollToEnd = () => {
this.setState({numToRender: this.getData().length});
Expand All @@ -93,19 +94,18 @@ class BotDetails extends BotNavBarMixin(React.Component) {
return (
<View style={styles.container}>
<FlatList
style={{marginBottom: 50 * k}}
data={this.getData()}
ref={r => (this.list = r)}
contentContainerStyle={{flexGrow: 1, paddingBottom: this.post ? this.post.imgContainerHeight : 0}}
// NOTE: below not necessary if we load all posts
// onEndReachedThreshold={0.5}
// onEndReached={this.loadMore}
// ListFooterComponent={this._footerComponent}
ListFooterComponent={this._footerComponent}
initialNumToRender={this.state.numToRender}
ListEmptyComponent={this.renderEmpty}
ListHeaderComponent={this._headerComponent}
ItemSeparatorComponent={() => <View style={{height: SEPARATOR_HEIGHT, width, backgroundColor: colors.LIGHT_GREY}} />}
renderItem={({item}) => <BotPostCard item={item} bot={bot} />}
renderItem={({item}) => <BotPostCard item={item} bot={bot} />}
keyExtractor={item => item.id}
// getItemLayout={(data, index) => {
// // console.log('& getItemLayout', index, data);
Expand All @@ -116,7 +116,7 @@ class BotDetails extends BotNavBarMixin(React.Component) {
// };
// }}
/>
<AddBotPost bot={bot} ref={a => (this.post = a)} scrollToEnd={this.scrollToEnd} />
{this.props.scale > 0 && <AddBotPost bot={bot} ref={a => (this.post = a)} scrollToEnd={this.scrollToEnd} /> }
</View>
);
}
Expand Down
83 changes: 0 additions & 83 deletions src/components/BotMap.js

This file was deleted.

11 changes: 6 additions & 5 deletions src/components/BotNavBarMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ import ButtonWithPopover from './ButtonWithPopover';
// http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/
const BotNavBarMixin = superclass =>
class extends superclass {
static renderTitle = ({item, map}) => {
static renderTitle = ({item, scale}) => {
const bot = botFactory.create({id: item});
const map = scale === 0;
return (
<ButtonWithPopover
contentStyle={{backgroundColor: colors.DARK_PURPLE}}
placement='bottom'
onLongPress={() => Clipboard.setString(bot.address)}
// @TODO: need a way to call scrollToEnd on a ref in the mixin implementer
// onPress={this.list.scrollToEnd}
onPress={() => scale === 0 && Actions.refresh({scale: 0.5})}
popover={<Text style={{fontFamily: 'Roboto-Regular', color: 'white', fontSize: 14}}>Address copied to clipboard</Text>}
>
<Text
numberOfLines={2}
numberOfLines={map ? 1 : 2}
adjustsFontSizeToFit
minimumFontScale={0.9}
minimumFontScale={0.8}
style={{
fontFamily: 'Roboto-Medium',
fontSize: 18,
Expand All @@ -36,7 +37,7 @@ const BotNavBarMixin = superclass =>
{bot.title}
</Text>
{map &&
<Text adjustsFontSizeToFit minimumFontScale={0.9} numberOfLines={2} style={styles.address}>
<Text adjustsFontSizeToFit minimumFontScale={0.6} numberOfLines={1} style={styles.address}>
{bot.address}
</Text>}
</ButtonWithPopover>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ButtonWithPopover.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default class extends React.Component {
render() {
return (
<View>
<TouchableOpacity ref={ref => (this.button = ref)} onLongPress={this.showPopover}>
<TouchableOpacity ref={ref => (this.button = ref)} onLongPress={this.showPopover} onPress={this.props.onPress}>
{this.props.children}
</TouchableOpacity>
<Popover
Expand Down
Loading