unified display of channel results #108
6 changed files with 146 additions and 37 deletions
|
@ -1,8 +1,10 @@
|
|||
import React from 'react';
|
||||
import { normalizeURI, parseURI } from 'lbry-redux';
|
||||
import { ActivityIndicator, Platform, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { ActivityIndicator, Image, Platform, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { navigateToUri, formatBytes } from 'utils/helper';
|
||||
import Colors from 'styles/colors';
|
||||
import ChannelIconItem from 'component/channelIconItem';
|
||||
import channelIconStyle from 'styles/channelIcon';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import DateTime from 'component/dateTime';
|
||||
import FileItemMedia from 'component/fileItemMedia';
|
||||
|
@ -15,6 +17,7 @@ import fileListStyle from 'styles/fileList';
|
|||
|
||||
class FileListItem extends React.PureComponent {
|
||||
state = {
|
||||
autoStyle: null,
|
||||
url: null,
|
||||
};
|
||||
|
||||
|
@ -45,6 +48,11 @@ class FileListItem extends React.PureComponent {
|
|||
if (!claim && !batchResolve) {
|
||||
resolveUri(uri);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
autoStyle:
|
||||
ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)],
|
||||
});
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
|
@ -135,10 +143,13 @@ class FileListItem extends React.PureComponent {
|
|||
return null;
|
||||
}
|
||||
|
||||
const isChannel = name && name.startsWith('@');
|
||||
const hasThumbnail = !!thumbnail;
|
||||
|
||||
return (
|
||||
<View style={style}>
|
||||
<TouchableOpacity
|
||||
style={style}
|
||||
style={[style, isChannel ? fileListStyle.channelContainer : null]}
|
||||
onPress={this.onPressHandler}
|
||||
onLongPress={() => {
|
||||
if (onLongPress) {
|
||||
|
@ -146,13 +157,31 @@ class FileListItem extends React.PureComponent {
|
|||
}
|
||||
}}
|
||||
>
|
||||
<FileItemMedia
|
||||
style={fileListStyle.thumbnail}
|
||||
duration={duration}
|
||||
resizeMode="cover"
|
||||
title={title || name || normalizeURI(uri).substring(7)}
|
||||
thumbnail={thumbnail}
|
||||
/>
|
||||
{!isChannel && (
|
||||
<FileItemMedia
|
||||
style={fileListStyle.thumbnail}
|
||||
duration={duration}
|
||||
resizeMode="cover"
|
||||
title={title || name || normalizeURI(uri).substring(7)}
|
||||
thumbnail={thumbnail}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isChannel && (
|
||||
<View style={fileListStyle.thumbnail}>
|
||||
<View style={fileListStyle.channelThumbnailContainer}>
|
||||
{hasThumbnail && (
|
||||
<Image style={fileListStyle.channelThumbnail} resizeMode={'cover'} source={{ uri: thumbnail }} />
|
||||
)}
|
||||
{!hasThumbnail && (
|
||||
<Text style={channelIconStyle.autothumbCharacter}>
|
||||
{title ? title.substring(0, 1).toUpperCase() : claim.name.substring(1, 2).toUpperCase()}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{selected && (
|
||||
<View style={fileListStyle.selectedOverlay}>
|
||||
<Icon name={'check-circle'} solid color={Colors.NextLbryGreen} size={32} />
|
||||
|
@ -206,17 +235,17 @@ class FileListItem extends React.PureComponent {
|
|||
</View>
|
||||
)}
|
||||
|
||||
{channel && !hideChannel && (
|
||||
{(channel || isChannel) && !hideChannel && (
|
||||
<Link
|
||||
style={fileListStyle.publisher}
|
||||
text={channel}
|
||||
text={isChannel ? name : channel}
|
||||
onPress={() => {
|
||||
navigateToUri(
|
||||
navigation,
|
||||
normalizeURI(shortChannelUri || fullChannelUri),
|
||||
normalizeURI(isChannel ? uri : shortChannelUri || fullChannelUri),
|
||||
null,
|
||||
false,
|
||||
fullChannelUri,
|
||||
isChannel ? claim && claim.permanent_url : fullChannelUri,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -3,8 +3,11 @@ import { normalizeURI, parseURI } from 'lbry-redux';
|
|||
import { ActivityIndicator, Platform, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { navigateToUri, formatBytes } from 'utils/helper';
|
||||
import Colors from 'styles/colors';
|
||||
import ChannelIconItem from 'component/channelIconItem';
|
||||
import channelIconStyle from 'styles/channelIcon';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import DateTime from 'component/dateTime';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import FileItemMedia from 'component/fileItemMedia';
|
||||
import FilePrice from 'component/filePrice';
|
||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||
|
@ -14,6 +17,17 @@ import ProgressBar from 'component/progressBar';
|
|||
import fileListStyle from 'styles/fileList';
|
||||
|
||||
class FileResultItem extends React.PureComponent {
|
||||
state = {
|
||||
autoStyle: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
autoStyle:
|
||||
ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)],
|
||||
});
|
||||
}
|
||||
|
||||
getStorageForFileInfo = fileInfo => {
|
||||
if (!fileInfo.completed) {
|
||||
const written = formatBytes(fileInfo.written_bytes);
|
||||
|
@ -58,6 +72,8 @@ class FileResultItem extends React.PureComponent {
|
|||
title,
|
||||
} = result;
|
||||
|
||||
const isChannel = name && name.startsWith('@');
|
||||
const hasThumbnail = !!thumbnailUrl;
|
||||
const obscure = obscureNsfw && nsfw;
|
||||
const url = normalizeURI(`${name}#${claimId}`);
|
||||
const hasChannel = !!channel;
|
||||
|
@ -66,14 +82,39 @@ class FileResultItem extends React.PureComponent {
|
|||
|
||||
return (
|
||||
<View style={style}>
|
||||
<TouchableOpacity style={style} onPress={this.onPressHandler}>
|
||||
<FileItemMedia
|
||||
style={fileListStyle.thumbnail}
|
||||
duration={duration}
|
||||
resizeMode="cover"
|
||||
title={title || name || normalizeURI(url).substring(7)}
|
||||
thumbnail={thumbnailUrl}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={[style, isChannel ? fileListStyle.channelContainer : null]}
|
||||
onPress={this.onPressHandler}
|
||||
>
|
||||
{!isChannel && (
|
||||
<FileItemMedia
|
||||
style={fileListStyle.thumbnail}
|
||||
duration={duration}
|
||||
resizeMode="cover"
|
||||
title={title || name || normalizeURI(url).substring(7)}
|
||||
thumbnail={thumbnailUrl}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isChannel && (
|
||||
<View style={fileListStyle.thumbnail}>
|
||||
<View style={fileListStyle.channelThumbnailContainer}>
|
||||
{hasThumbnail && (
|
||||
<FastImage
|
||||
style={fileListStyle.channelThumbnail}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
source={{ uri: thumbnailUrl }}
|
||||
/>
|
||||
)}
|
||||
{!hasThumbnail && (
|
||||
<Text style={channelIconStyle.autothumbCharacter}>
|
||||
{title ? title.substring(0, 1).toUpperCase() : name.substring(1, 2).toUpperCase()}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{fileInfo && fileInfo.completed && fileInfo.download_path && (
|
||||
<Icon
|
||||
style={featuredResult ? fileListStyle.featuredDownloadedIcon : fileListStyle.downloadedIcon}
|
||||
|
@ -100,15 +141,22 @@ class FileResultItem extends React.PureComponent {
|
|||
</View>
|
||||
)}
|
||||
|
||||
{hasChannel && (
|
||||
<Link
|
||||
style={fileListStyle.publisher}
|
||||
text={channel}
|
||||
onPress={() => {
|
||||
navigateToUri(navigation, normalizeURI(channelUrl), null, false, channelUrl);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{hasChannel ||
|
||||
(isChannel && (
|
||||
<Link
|
||||
style={fileListStyle.publisher}
|
||||
text={isChannel ? name : channel}
|
||||
onPress={() => {
|
||||
navigateToUri(
|
||||
navigation,
|
||||
normalizeURI(isChannel ? url : channelUrl),
|
||||
null,
|
||||
false,
|
||||
isChannel ? url : channelUrl,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
<View style={fileListStyle.info}>
|
||||
{fileInfo && !isNaN(fileInfo.written_bytes) && fileInfo.written_bytes > 0 && (
|
||||
|
|
|
@ -3,6 +3,8 @@ import { buildURI, normalizeURI } from 'lbry-redux';
|
|||
import { ActivityIndicator, FlatList, Image, Text, View } from 'react-native';
|
||||
import { navigateToUri } from 'utils/helper';
|
||||
import Colors from 'styles/colors';
|
||||
import ChannelIconItem from 'component/channelIconItem';
|
||||
import channelIconStyle from 'styles/channelIcon';
|
||||
import discoverStyle from 'styles/discover';
|
||||
import FileItem from 'component/fileItem';
|
||||
import SubscribeButton from 'component/subscribeButton';
|
||||
|
@ -11,11 +13,20 @@ import Link from 'component/link';
|
|||
import Tag from 'component/tag';
|
||||
|
||||
class SuggestedSubscriptionItem extends React.PureComponent {
|
||||
state = {
|
||||
autoStyle: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { claim, uri, resolveUri } = this.props;
|
||||
if (!claim) {
|
||||
resolveUri(uri);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
autoStyle:
|
||||
ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)],
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -28,6 +39,7 @@ class SuggestedSubscriptionItem extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
const hasThumbnail = !!thumbnail;
|
||||
if (isResolvingUri) {
|
||||
return (
|
||||
<View style={subscriptionsStyle.itemLoadingContainer}>
|
||||
|
@ -38,12 +50,15 @@ class SuggestedSubscriptionItem extends React.PureComponent {
|
|||
|
||||
return (
|
||||
<View style={subscriptionsStyle.suggestedItem}>
|
||||
<View style={subscriptionsStyle.suggestedItemThumbnailContainer}>
|
||||
<Image
|
||||
style={subscriptionsStyle.suggestedItemThumbnail}
|
||||
resizeMode={'cover'}
|
||||
source={thumbnail ? { uri: thumbnail } : require('../../assets/default_avatar.jpg')}
|
||||
/>
|
||||
<View style={[subscriptionsStyle.suggestedItemThumbnailContainer, this.state.autoStyle]}>
|
||||
{hasThumbnail && (
|
||||
<Image style={subscriptionsStyle.suggestedItemThumbnail} resizeMode={'cover'} source={{ uri: thumbnail }} />
|
||||
)}
|
||||
{!hasThumbnail && (
|
||||
<Text style={channelIconStyle.autothumbCharacter}>
|
||||
{title ? title.substring(0, 1).toUpperCase() : claim ? claim.name.substring(1, 2).toUpperCase() : ''}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View style={subscriptionsStyle.suggestedItemDetails}>
|
||||
|
|
|
@ -73,7 +73,7 @@ class SubscriptionsPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
componentDidMount() {
|
||||
// this.onComponentFocused();
|
||||
this.onComponentFocused();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
|
|
|
@ -38,6 +38,18 @@ const fileListStyle = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
channelThumbnailContainer: {
|
||||
width: thumbnailHeight, // maintain same width and height
|
||||
height: thumbnailHeight,
|
||||
borderRadius: 140,
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
channelThumbnail: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
selectedOverlay: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
|
@ -63,6 +75,9 @@ const fileListStyle = StyleSheet.create({
|
|||
marginTop: screenWidthPixels <= 720 ? 1 : 3,
|
||||
color: Colors.LbryGreen,
|
||||
},
|
||||
channelContainer: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
loading: {
|
||||
position: 'absolute',
|
||||
},
|
||||
|
|
|
@ -199,6 +199,8 @@ const subscriptionsStyle = StyleSheet.create({
|
|||
height: 70,
|
||||
borderRadius: 140,
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
suggestedItemThumbnail: {
|
||||
width: '100%',
|
||||
|
|
Loading…
Reference in a new issue