Channel page redesign (#528)
* channel page redesign changes * add constants. change publisher thumbnail resize mode.
This commit is contained in:
parent
7a7e96388b
commit
07f23ba927
11 changed files with 234 additions and 39 deletions
BIN
app/src/assets/default_avatar.jpg
Normal file
BIN
app/src/assets/default_avatar.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
app/src/assets/default_channel_cover.png
Normal file
BIN
app/src/assets/default_channel_cover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 354 KiB |
|
@ -4,6 +4,9 @@ const Constants = {
|
|||
FIRST_RUN_PAGE_WALLET: "wallet",
|
||||
FIRST_RUN_PAGE_SKIP_ACCOUNT: "skip-account",
|
||||
|
||||
CONTENT_TAB: "content",
|
||||
ABOUT_TAB: "about",
|
||||
|
||||
KEY_FIRST_RUN_EMAIL: "firstRunEmail",
|
||||
KEY_FIRST_RUN_PASSWORD: "firstRunPassword",
|
||||
KEY_SHOULD_VERIFY_EMAIL: "shouldVerifyEmail",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { connect } from 'react-redux';
|
||||
import {
|
||||
doFetchClaimsByChannel,
|
||||
doFetchClaimCountByChannel,
|
||||
makeSelectClaimForUri,
|
||||
makeSelectClaimsInChannelForCurrentPageState,
|
||||
makeSelectFetchingChannelClaims,
|
||||
|
@ -21,7 +20,6 @@ const select = (state, props) => ({
|
|||
|
||||
const perform = dispatch => ({
|
||||
fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)),
|
||||
fetchClaimCount: uri => dispatch(doFetchClaimCountByChannel(uri)),
|
||||
popDrawerStack: () => dispatch(doPopDrawerStack())
|
||||
});
|
||||
|
||||
|
|
|
@ -1,9 +1,20 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { ActivityIndicator, Text, View } from 'react-native';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Dimensions,
|
||||
Image,
|
||||
ScrollView,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { TabView, SceneMap } from 'react-native-tab-view';
|
||||
import { navigateBack } from 'utils/helper';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants';
|
||||
import Button from 'component/button';
|
||||
import Link from 'component/link';
|
||||
import FileList from 'component/fileList';
|
||||
import PageHeader from 'component/pageHeader';
|
||||
import SubscribeButton from 'component/subscribeButton';
|
||||
|
@ -13,7 +24,8 @@ import channelPageStyle from 'styles/channelPage';
|
|||
class ChannelPage extends React.PureComponent {
|
||||
state = {
|
||||
page: 1,
|
||||
showPageButtons: false
|
||||
showPageButtons: false,
|
||||
activeTab: Constants.CONTENT_TAB
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -21,7 +33,6 @@ class ChannelPage extends React.PureComponent {
|
|||
|
||||
if (!claimsInChannel || !claimsInChannel.length) {
|
||||
fetchClaims(uri, page || this.state.page);
|
||||
fetchClaimCount(uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,18 +54,8 @@ class ChannelPage extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
fetching,
|
||||
claimsInChannel,
|
||||
claim,
|
||||
navigation,
|
||||
totalPages,
|
||||
uri,
|
||||
drawerStack,
|
||||
popDrawerStack
|
||||
} = this.props;
|
||||
const { name, permanent_url: permanentUrl } = claim;
|
||||
renderContent = () => {
|
||||
const { fetching, claimsInChannel, totalPages, navigation } = this.props;
|
||||
|
||||
let contentList;
|
||||
if (fetching) {
|
||||
|
@ -81,15 +82,9 @@ class ChannelPage extends React.PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={channelPageStyle.container}>
|
||||
<UriBar value={uri} navigation={navigation} />
|
||||
<View style={channelPageStyle.channelHeader}>
|
||||
<Text style={channelPageStyle.channelName}>{name}</Text>
|
||||
<SubscribeButton style={channelPageStyle.subscribeButton} uri={uri} name={name} />
|
||||
</View>
|
||||
{contentList}
|
||||
{(totalPages > 1) && this.state.showPageButtons &&
|
||||
let pageButtons;
|
||||
if (totalPages > 1 && this.state.showPageButtons) {
|
||||
pageButtons = (
|
||||
<View style={channelPageStyle.pageButtons}>
|
||||
<View>
|
||||
{(this.state.page > 1) && <Button
|
||||
|
@ -103,7 +98,127 @@ class ChannelPage extends React.PureComponent {
|
|||
text={"Next"}
|
||||
disabled={!!fetching}
|
||||
onPress={this.handleNextPage} />}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={channelPageStyle.contentTab}>
|
||||
{contentList}
|
||||
{pageButtons}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
renderAbout = () => {
|
||||
const { claim } = this.props;
|
||||
|
||||
if (!claim) {
|
||||
return (
|
||||
<View style={channelPageStyle.aboutTab}>
|
||||
<View style={channelPageStyle.busyContainer}>
|
||||
<Text style={channelPageStyle.infoText}>No information to display.</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const { cover, description, thumbnail, email, website_url, title } = claim.value;
|
||||
return (
|
||||
<View style={channelPageStyle.aboutTab}>
|
||||
{(!website_url && !email && !description) &&
|
||||
<View style={channelPageStyle.busyContainer}>
|
||||
<Text style={channelPageStyle.infoText}>Nothing here yet. Please check back later.</Text>
|
||||
</View>}
|
||||
|
||||
{(website_url || email || description) &&
|
||||
<ScrollView style={channelPageStyle.aboutScroll} contentContainerStyle={channelPageStyle.aboutScrollContent}>
|
||||
{(website_url && website_url.trim().length > 0) &&
|
||||
<View style={channelPageStyle.aboutItem}>
|
||||
<Text style={channelPageStyle.aboutTitle}>Website</Text>
|
||||
<Link style={channelPageStyle.aboutText} text={website_url} href={website_url} />
|
||||
</View>}
|
||||
|
||||
{(email && email.trim().length > 0) &&
|
||||
<View style={channelPageStyle.aboutItem}>
|
||||
<Text style={channelPageStyle.aboutTitle}>Email</Text>
|
||||
<Link style={channelPageStyle.aboutText} text={email} href={`mailto:${email}`} />
|
||||
</View>}
|
||||
|
||||
{(description && description.trim().length > 0) &&
|
||||
<View style={channelPageStyle.aboutItem}>
|
||||
<Text style={channelPageStyle.aboutText}>{description}</Text>
|
||||
</View>}
|
||||
</ScrollView>}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
fetching,
|
||||
claimsInChannel,
|
||||
claim,
|
||||
navigation,
|
||||
totalPages,
|
||||
uri,
|
||||
drawerStack,
|
||||
popDrawerStack
|
||||
} = this.props;
|
||||
const { name, permanent_url: permanentUrl } = claim;
|
||||
|
||||
let thumbnailUrl, coverUrl, title;
|
||||
if (claim && claim.value) {
|
||||
title = claim.value.title;
|
||||
if (claim.value.cover) {
|
||||
coverUrl = claim.value.cover.url;
|
||||
}
|
||||
if (claim.value.thumbnail) {
|
||||
thumbnailUrl = claim.value.thumbnail.url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<View style={channelPageStyle.container}>
|
||||
<UriBar value={uri} navigation={navigation} />
|
||||
|
||||
|
||||
<View style={channelPageStyle.viewContainer}>
|
||||
<View style={channelPageStyle.cover}>
|
||||
<Image
|
||||
style={channelPageStyle.coverImage}
|
||||
resizeMode={'cover'}
|
||||
source={(coverUrl && coverUrl.trim().length > 0) ? { uri: coverUrl } : require('../../assets/default_channel_cover.png')} />
|
||||
|
||||
<View style={channelPageStyle.channelHeader}>
|
||||
<Text style={channelPageStyle.channelName}>{(title && title.trim().length > 0) ? title : name}</Text>
|
||||
</View>
|
||||
|
||||
<View style={channelPageStyle.avatarImageContainer}>
|
||||
<Image
|
||||
style={channelPageStyle.avatarImage}
|
||||
resizeMode={'cover'}
|
||||
source={(thumbnailUrl && thumbnailUrl.trim().length > 0) ? { uri: thumbnailUrl } : require('../../assets/default_avatar.jpg')} />
|
||||
</View>
|
||||
|
||||
<SubscribeButton style={channelPageStyle.subscribeButton} uri={uri} name={name} />
|
||||
</View>
|
||||
|
||||
<View style={channelPageStyle.tabBar}>
|
||||
<TouchableOpacity style={channelPageStyle.tab} onPress={() => this.setState({ activeTab: Constants.CONTENT_TAB })}>
|
||||
<Text style={channelPageStyle.tabTitle}>CONTENT</Text>
|
||||
{Constants.CONTENT_TAB === this.state.activeTab && <View style={channelPageStyle.activeTabHint} />}
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={channelPageStyle.tab} onPress={() => this.setState({ activeTab: Constants.ABOUT_TAB })}>
|
||||
<Text style={channelPageStyle.tabTitle}>ABOUT</Text>
|
||||
{Constants.ABOUT_TAB === this.state.activeTab && <View style={channelPageStyle.activeTabHint} />}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{Constants.CONTENT_TAB === this.state.activeTab && this.renderContent()}
|
||||
{Constants.ABOUT_TAB === this.state.activeTab && this.renderAbout()}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
TouchableWithoutFeedback,
|
||||
View,
|
||||
WebView
|
||||
} from 'react-native';
|
||||
|
@ -444,7 +444,7 @@ class FilePage extends React.PureComponent {
|
|||
const { height, channel_name: channelName, value } = claim;
|
||||
const showActions = !this.state.fullscreenMode && !this.state.showImageViewer && !this.state.showWebView;
|
||||
const showFileActions = (completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
|
||||
const channelClaimId = value && value.publisherSignature && value.publisherSignature.certificateId;
|
||||
const channelClaimId = claim && claim.signing_channel && claim.signing_channel.claim_id;
|
||||
const canSendTip = this.state.tipAmount > 0;
|
||||
const fullChannelUri = channelClaimId && channelClaimId.trim().length > 0 ? `${channelName}#${channelClaimId}` : channelName;
|
||||
|
||||
|
@ -582,10 +582,10 @@ class FilePage extends React.PureComponent {
|
|||
ref={(ref) => { this.scrollView = ref; }}>
|
||||
<View style={filePageStyle.titleRow}>
|
||||
<Text style={filePageStyle.title} selectable={true}>{title}</Text>
|
||||
<TouchableOpacity style={filePageStyle.descriptionToggle}
|
||||
<TouchableWithoutFeedback style={filePageStyle.descriptionToggle}
|
||||
onPress={() => this.setState({ showDescription: !this.state.showDescription })}>
|
||||
<Icon name={this.state.showDescription ? "caret-up" : "caret-down"} size={24} />
|
||||
</TouchableOpacity>
|
||||
</TouchableWithoutFeedback>
|
||||
</View>
|
||||
{channelName &&
|
||||
<View style={filePageStyle.channelRow}>
|
||||
|
|
|
@ -10,6 +10,10 @@ const channelPageStyle = StyleSheet.create({
|
|||
content: {
|
||||
flex: 1
|
||||
},
|
||||
viewContainer: {
|
||||
flex: 1,
|
||||
marginTop: 60
|
||||
},
|
||||
fileList: {
|
||||
flex: 1,
|
||||
paddingTop: 30
|
||||
|
@ -53,22 +57,95 @@ const channelPageStyle = StyleSheet.create({
|
|||
alignSelf: 'flex-end'
|
||||
},
|
||||
channelHeader: {
|
||||
marginTop: 60,
|
||||
marginLeft: 16,
|
||||
marginRight: 16
|
||||
position: 'absolute',
|
||||
left: 120,
|
||||
bottom: 4
|
||||
},
|
||||
channelName: {
|
||||
fontFamily: 'Inter-UI-SemiBold',
|
||||
fontSize: 24,
|
||||
marginTop: 16,
|
||||
marginBottom: 8
|
||||
color: Colors.White,
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 18
|
||||
},
|
||||
subscribeButton: {
|
||||
alignSelf: 'flex-start',
|
||||
backgroundColor: Colors.White,
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16
|
||||
paddingRight: 16,
|
||||
position: 'absolute',
|
||||
right: 8,
|
||||
bottom: -88,
|
||||
zIndex: 100
|
||||
},
|
||||
cover: {
|
||||
width: '100%',
|
||||
height: '20%',
|
||||
},
|
||||
coverImage: {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
},
|
||||
tabBar: {
|
||||
height: 45,
|
||||
backgroundColor: Colors.LbryGreen,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end'
|
||||
},
|
||||
tabTitle: {
|
||||
fontFamily: 'Inter-UI-SemiBold',
|
||||
fontSize: 14,
|
||||
color: Colors.White,
|
||||
},
|
||||
tab: {
|
||||
width: '30%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
activeTabHint: {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
backgroundColor: Colors.White,
|
||||
height: 3,
|
||||
width: '100%'
|
||||
},
|
||||
contentTab: {
|
||||
flex: 1
|
||||
},
|
||||
aboutTab: {
|
||||
flex: 1
|
||||
},
|
||||
aboutScroll: {
|
||||
flex: 1,
|
||||
},
|
||||
aboutItem: {
|
||||
marginBottom: 24
|
||||
},
|
||||
aboutScrollContent: {
|
||||
padding: 24
|
||||
},
|
||||
aboutTitle: {
|
||||
fontFamily: 'Inter-UI-SemiBold',
|
||||
fontSize: 16,
|
||||
lineHeight: 24
|
||||
},
|
||||
aboutText: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
lineHeight: 24
|
||||
},
|
||||
avatarImageContainer: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 160,
|
||||
position: 'absolute',
|
||||
overflow: 'hidden',
|
||||
left: 24,
|
||||
bottom: -40,
|
||||
zIndex: 100
|
||||
},
|
||||
avatarImage: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}
|
||||
});
|
||||
|
||||
export default channelPageStyle;
|
||||
|
|
|
@ -306,6 +306,7 @@ const filePageStyle = StyleSheet.create({
|
|||
tagContainer: {
|
||||
marginLeft: 12,
|
||||
marginRight: 12,
|
||||
marginBottom: 16,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
tagTitle: {
|
||||
|
|
|
@ -84,6 +84,7 @@ ext {
|
|||
buildToolsVersion = '{{ build_tools_version }}'
|
||||
minSdkVersion = {{ args.min_sdk_version }}
|
||||
targetSdkVersion = {{ android_api }}
|
||||
supportLibVersion = '27.1.1'
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
|
BIN
src/main/res/drawable-mdpi/src_assets_default_avatar.jpg
Normal file
BIN
src/main/res/drawable-mdpi/src_assets_default_avatar.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
src/main/res/drawable-mdpi/src_assets_default_channel_cover.png
Normal file
BIN
src/main/res/drawable-mdpi/src_assets_default_channel_cover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 354 KiB |
Loading…
Reference in a new issue