From c88d9f71f813007993f8ee8334635d865d527654 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola <akinwale@gmail.com> Date: Wed, 8 Jan 2020 00:44:43 +0100 Subject: [PATCH 1/5] unified display of channel results --- src/component/fileListItem/view.js | 55 ++++++++++--- src/component/fileResultItem/view.js | 82 +++++++++++++++---- .../suggestedSubscriptionItem/view.js | 27 ++++-- src/page/subscriptions/view.js | 2 +- src/styles/fileList.js | 15 ++++ src/styles/subscriptions.js | 2 + 6 files changed, 146 insertions(+), 37 deletions(-) diff --git a/src/component/fileListItem/view.js b/src/component/fileListItem/view.js index 8d8ffdc..95bc9df 100644 --- a/src/component/fileListItem/view.js +++ b/src/component/fileListItem/view.js @@ -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, ); }} /> diff --git a/src/component/fileResultItem/view.js b/src/component/fileResultItem/view.js index 0c0b10e..8f0d584 100644 --- a/src/component/fileResultItem/view.js +++ b/src/component/fileResultItem/view.js @@ -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 && ( diff --git a/src/component/suggestedSubscriptionItem/view.js b/src/component/suggestedSubscriptionItem/view.js index ac24a31..5f7e37c 100644 --- a/src/component/suggestedSubscriptionItem/view.js +++ b/src/component/suggestedSubscriptionItem/view.js @@ -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}> diff --git a/src/page/subscriptions/view.js b/src/page/subscriptions/view.js index e48487e..83b9027 100644 --- a/src/page/subscriptions/view.js +++ b/src/page/subscriptions/view.js @@ -73,7 +73,7 @@ class SubscriptionsPage extends React.PureComponent { }; componentDidMount() { - // this.onComponentFocused(); + this.onComponentFocused(); } componentWillReceiveProps(nextProps) { diff --git a/src/styles/fileList.js b/src/styles/fileList.js index fe5811b..d3d5f4f 100644 --- a/src/styles/fileList.js +++ b/src/styles/fileList.js @@ -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', }, diff --git a/src/styles/subscriptions.js b/src/styles/subscriptions.js index bb1ff78..20e90d8 100644 --- a/src/styles/subscriptions.js +++ b/src/styles/subscriptions.js @@ -199,6 +199,8 @@ const subscriptionsStyle = StyleSheet.create({ height: 70, borderRadius: 140, overflow: 'hidden', + alignItems: 'center', + justifyContent: 'center', }, suggestedItemThumbnail: { width: '100%', From d87c2a2218266619dfe6b505e41cc18a20dc7d29 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola <akinwale@gmail.com> Date: Wed, 8 Jan 2020 06:35:37 +0100 Subject: [PATCH 2/5] add autoStyle to thumbnail container --- src/component/fileListItem/view.js | 2 +- src/component/fileResultItem/view.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/component/fileListItem/view.js b/src/component/fileListItem/view.js index 95bc9df..34d4edb 100644 --- a/src/component/fileListItem/view.js +++ b/src/component/fileListItem/view.js @@ -169,7 +169,7 @@ class FileListItem extends React.PureComponent { {isChannel && ( <View style={fileListStyle.thumbnail}> - <View style={fileListStyle.channelThumbnailContainer}> + <View style={[fileListStyle.channelThumbnailContainer, this.state.autoStyle]}> {hasThumbnail && ( <Image style={fileListStyle.channelThumbnail} resizeMode={'cover'} source={{ uri: thumbnail }} /> )} diff --git a/src/component/fileResultItem/view.js b/src/component/fileResultItem/view.js index 8f0d584..0339532 100644 --- a/src/component/fileResultItem/view.js +++ b/src/component/fileResultItem/view.js @@ -98,7 +98,7 @@ class FileResultItem extends React.PureComponent { {isChannel && ( <View style={fileListStyle.thumbnail}> - <View style={fileListStyle.channelThumbnailContainer}> + <View style={[fileListStyle.channelThumbnailContainer, this.state.autoStyle]}> {hasThumbnail && ( <FastImage style={fileListStyle.channelThumbnail} From 4e88d7563944a29acb3b68ec37cfca0d33617f3f Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola <akinwale@gmail.com> Date: Wed, 8 Jan 2020 08:13:48 +0100 Subject: [PATCH 3/5] move common shared methods to helper --- src/component/fileListItem/view.js | 26 ++++-------------------- src/component/fileResultItem/view.js | 30 ++++------------------------ src/utils/helper.js | 22 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/component/fileListItem/view.js b/src/component/fileListItem/view.js index 34d4edb..26b4e93 100644 --- a/src/component/fileListItem/view.js +++ b/src/component/fileListItem/view.js @@ -1,7 +1,7 @@ import React from 'react'; import { normalizeURI, parseURI } from 'lbry-redux'; import { ActivityIndicator, Image, Platform, Text, TouchableOpacity, View } from 'react-native'; -import { navigateToUri, formatBytes } from 'utils/helper'; +import { navigateToUri, formatTitle, getDownloadProgress, getStorageForFileInfo } from 'utils/helper'; import Colors from 'styles/colors'; import ChannelIconItem from 'component/channelIconItem'; import channelIconStyle from 'styles/channelIcon'; @@ -21,24 +21,6 @@ class FileListItem extends React.PureComponent { url: null, }; - getStorageForFileInfo = fileInfo => { - if (!fileInfo.completed) { - const written = formatBytes(fileInfo.written_bytes); - const total = formatBytes(fileInfo.total_bytes); - return `(${written} / ${total})`; - } - - return formatBytes(fileInfo.written_bytes); - }; - - formatTitle = title => { - if (!title) { - return title; - } - - return title.length > 80 ? title.substring(0, 77).trim() + '...' : title; - }; - getDownloadProgress = fileInfo => { return Math.ceil((fileInfo.written_bytes / fileInfo.total_bytes) * 100); }; @@ -223,7 +205,7 @@ class FileListItem extends React.PureComponent { {(title || name) && ( <View style={fileListStyle.titleContainer}> <Text style={featuredResult ? fileListStyle.featuredTitle : fileListStyle.title}> - {this.formatTitle(title) || this.formatTitle(name)} + {formatTitle(title) || formatTitle(name)} </Text> {isRewardContent && <Icon style={fileListStyle.rewardIcon} name="award" size={12} />} </View> @@ -253,7 +235,7 @@ class FileListItem extends React.PureComponent { <View style={fileListStyle.info}> {fileInfo && !isNaN(fileInfo.written_bytes) && fileInfo.written_bytes > 0 && ( - <Text style={fileListStyle.infoText}>{this.getStorageForFileInfo(fileInfo)}</Text> + <Text style={fileListStyle.infoText}>{getStorageForFileInfo(fileInfo)}</Text> )} <DateTime style={fileListStyle.publishInfo} textStyle={fileListStyle.infoText} timeAgo uri={uri} /> </View> @@ -266,7 +248,7 @@ class FileListItem extends React.PureComponent { color={Colors.NextLbryGreen} height={3} style={fileListStyle.progress} - progress={this.getDownloadProgress(fileInfo)} + progress={getDownloadProgress(fileInfo)} /> )} </View> diff --git a/src/component/fileResultItem/view.js b/src/component/fileResultItem/view.js index 0339532..ecf2e8c 100644 --- a/src/component/fileResultItem/view.js +++ b/src/component/fileResultItem/view.js @@ -1,7 +1,7 @@ import React from 'react'; import { normalizeURI, parseURI } from 'lbry-redux'; import { ActivityIndicator, Platform, Text, TouchableOpacity, View } from 'react-native'; -import { navigateToUri, formatBytes } from 'utils/helper'; +import { navigateToUri, formatTitle, getDownloadProgress, getStorageForFileInfo } from 'utils/helper'; import Colors from 'styles/colors'; import ChannelIconItem from 'component/channelIconItem'; import channelIconStyle from 'styles/channelIcon'; @@ -28,28 +28,6 @@ class FileResultItem extends React.PureComponent { }); } - getStorageForFileInfo = fileInfo => { - if (!fileInfo.completed) { - const written = formatBytes(fileInfo.written_bytes); - const total = formatBytes(fileInfo.total_bytes); - return `(${written} / ${total})`; - } - - return formatBytes(fileInfo.written_bytes); - }; - - formatTitle = title => { - if (!title) { - return title; - } - - return title.length > 80 ? title.substring(0, 77).trim() + '...' : title; - }; - - getDownloadProgress = fileInfo => { - return Math.ceil((fileInfo.written_bytes / fileInfo.total_bytes) * 100); - }; - onPressHandler = () => { const { autoplay, navigation, result } = this.props; const { claimId, name } = result; @@ -135,7 +113,7 @@ class FileResultItem extends React.PureComponent { {(title || name) && ( <View style={fileListStyle.titleContainer}> <Text style={featuredResult ? fileListStyle.featuredTitle : fileListStyle.title}> - {this.formatTitle(title) || this.formatTitle(name)} + {formatTitle(title) || formatTitle(name)} </Text> {isRewardContent && <Icon style={fileListStyle.rewardIcon} name="award" size={12} />} </View> @@ -160,7 +138,7 @@ class FileResultItem extends React.PureComponent { <View style={fileListStyle.info}> {fileInfo && !isNaN(fileInfo.written_bytes) && fileInfo.written_bytes > 0 && ( - <Text>{this.getStorageForFileInfo(fileInfo)}</Text> + <Text>{getStorageForFileInfo(fileInfo)}</Text> )} <DateTime style={fileListStyle.publishInfo} @@ -178,7 +156,7 @@ class FileResultItem extends React.PureComponent { color={Colors.NextLbryGreen} height={3} style={fileListStyle.progress} - progress={this.getDownloadProgress(fileInfo)} + progress={getDownloadProgress(fileInfo)} /> )} </View> diff --git a/src/utils/helper.js b/src/utils/helper.js index bf3e938..4f57b62 100644 --- a/src/utils/helper.js +++ b/src/utils/helper.js @@ -370,3 +370,25 @@ export function uploadImageAsset(filePath, success, failure) { export function formatLbryUrlForWeb(url) { return url.replace('lbry://', '/').replace(/#/g, ':'); } + +export function getDownloadProgress(fileInfo) { + return Math.ceil((fileInfo.written_bytes / fileInfo.total_bytes) * 100); +} + +export function getStorageForFileInfo(fileInfo) { + if (!fileInfo.completed) { + const written = formatBytes(fileInfo.written_bytes); + const total = formatBytes(fileInfo.total_bytes); + return `(${written} / ${total})`; + } + + return formatBytes(fileInfo.written_bytes); +} + +export function formatTitle(title) { + if (!title) { + return title; + } + + return title.length > 80 ? title.substring(0, 77).trim() + '...' : title; +} From fa122ce5ea5cac7ed9171580712e8892a6322111 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola <akinwale@gmail.com> Date: Wed, 8 Jan 2020 10:25:25 +0100 Subject: [PATCH 4/5] change Image to FastImage in list views --- src/component/fileListItem/view.js | 9 +++++++-- src/page/channelCreator/view.js | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/component/fileListItem/view.js b/src/component/fileListItem/view.js index 26b4e93..97398d3 100644 --- a/src/component/fileListItem/view.js +++ b/src/component/fileListItem/view.js @@ -1,12 +1,13 @@ import React from 'react'; import { normalizeURI, parseURI } from 'lbry-redux'; -import { ActivityIndicator, Image, Platform, Text, TouchableOpacity, View } from 'react-native'; +import { ActivityIndicator, Platform, Text, TouchableOpacity, View } from 'react-native'; import { navigateToUri, formatTitle, getDownloadProgress, getStorageForFileInfo } 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'; @@ -153,7 +154,11 @@ class FileListItem extends React.PureComponent { <View style={fileListStyle.thumbnail}> <View style={[fileListStyle.channelThumbnailContainer, this.state.autoStyle]}> {hasThumbnail && ( - <Image style={fileListStyle.channelThumbnail} resizeMode={'cover'} source={{ uri: thumbnail }} /> + <FastImage + style={fileListStyle.channelThumbnail} + resizeMode={FastImage.resizeMode.cover} + source={{ uri: thumbnail }} + /> )} {!hasThumbnail && ( <Text style={channelIconStyle.autothumbCharacter}> diff --git a/src/page/channelCreator/view.js b/src/page/channelCreator/view.js index 8a86ad8..55baef9 100644 --- a/src/page/channelCreator/view.js +++ b/src/page/channelCreator/view.js @@ -21,6 +21,7 @@ import ChannelRewardsDriver from 'component/channelRewardsDriver'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import EmptyStateView from 'component/emptyStateView'; +import FastImage from 'react-native-fast-image'; import FloatingWalletBalance from 'component/floatingWalletBalance'; import Icon from 'react-native-vector-icons/FontAwesome5'; import Link from 'component/link'; @@ -867,9 +868,9 @@ export default class ChannelCreator extends React.PureComponent { > <View style={[channelCreatorStyle.channelListAvatar, itemAutoStyle]}> {itemThumbnailUrl && ( - <Image + <FastImage style={channelCreatorStyle.avatarImage} - resizeMode={'cover'} + resizeMode={FastImage.resizeMode.cover} source={{ uri: itemThumbnailUrl }} /> )} From 7f065ed0bca25d45d1f240293d6f07c20be26f19 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola <akinwale@gmail.com> Date: Thu, 9 Jan 2020 17:18:47 +0100 Subject: [PATCH 5/5] fixes as per review --- .../index.js | 4 ++-- .../view.js | 22 ++++++++++++++----- src/component/relatedContent/view.js | 4 ++-- src/page/search/view.js | 9 ++++++-- 4 files changed, 27 insertions(+), 12 deletions(-) rename src/component/{fileResultItem => claimResultItem}/index.js (95%) rename src/component/{fileResultItem => claimResultItem}/view.js (89%) diff --git a/src/component/fileResultItem/index.js b/src/component/claimResultItem/index.js similarity index 95% rename from src/component/fileResultItem/index.js rename to src/component/claimResultItem/index.js index f1bff41..4a44701 100644 --- a/src/component/fileResultItem/index.js +++ b/src/component/claimResultItem/index.js @@ -12,7 +12,7 @@ import { } from 'lbry-redux'; import { selectBlackListedOutpoints, selectFilteredOutpoints, selectRewardContentClaimIds } from 'lbryinc'; import { selectShowNsfw } from 'redux/selectors/settings'; -import FileResultItem from './view'; +import ClaimResultItem from './view'; const select = (state, props) => ({ blackListedOutpoints: selectBlackListedOutpoints(state), @@ -37,4 +37,4 @@ const perform = dispatch => ({ export default connect( select, perform, -)(FileResultItem); +)(ClaimResultItem); diff --git a/src/component/fileResultItem/view.js b/src/component/claimResultItem/view.js similarity index 89% rename from src/component/fileResultItem/view.js rename to src/component/claimResultItem/view.js index ecf2e8c..1f55801 100644 --- a/src/component/fileResultItem/view.js +++ b/src/component/claimResultItem/view.js @@ -15,17 +15,27 @@ import Link from 'component/link'; import NsfwOverlay from 'component/nsfwOverlay'; import ProgressBar from 'component/progressBar'; import fileListStyle from 'styles/fileList'; +import seedrandom from 'seedrandom'; -class FileResultItem extends React.PureComponent { +class ClaimResultItem extends React.PureComponent { state = { autoStyle: null, }; componentDidMount() { - this.setState({ - autoStyle: - ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)], - }); + const { result } = this.props; + + if (!result || !result.name || !result.claimId) { + this.setState({ + autoStyle: + ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)], + }); + } else { + // result property set, use deterministic random style + const rng = seedrandom(normalizeURI(`${result.name}#${result.claimId}`)); + const index = Math.floor(rng.quick() * ChannelIconItem.AUTO_THUMB_STYLES.length); + this.setState({ autoStyle: ChannelIconItem.AUTO_THUMB_STYLES[index] }); + } } onPressHandler = () => { @@ -169,4 +179,4 @@ class FileResultItem extends React.PureComponent { } } -export default FileResultItem; +export default ClaimResultItem; diff --git a/src/component/relatedContent/view.js b/src/component/relatedContent/view.js index e0830f4..f5ab361 100644 --- a/src/component/relatedContent/view.js +++ b/src/component/relatedContent/view.js @@ -4,7 +4,7 @@ import { normalizeURI } from 'lbry-redux'; import { navigateToUri } from 'utils/helper'; import Colors from 'styles/colors'; import FileListItem from 'component/fileListItem'; -import FileResultItem from 'component/fileResultItem'; +import ClaimResultItem from 'component/claimResultItem'; import fileListStyle from 'styles/fileList'; import relatedContentStyle from 'styles/relatedContent'; @@ -30,7 +30,7 @@ export default class RelatedContent extends React.PureComponent { {isSearching && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />} {recommendedContent && recommendedContent.map(result => ( - <FileResultItem + <ClaimResultItem style={fileListStyle.item} key={result.claimId} result={result} diff --git a/src/page/search/view.js b/src/page/search/view.js index 5747637..22dc55b 100644 --- a/src/page/search/view.js +++ b/src/page/search/view.js @@ -15,7 +15,7 @@ import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import PageHeader from 'component/pageHeader'; import FileListItem from 'component/fileListItem'; -import FileResultItem from 'component/fileResultItem'; +import ClaimResultItem from 'component/claimResultItem'; import FloatingWalletBalance from 'component/floatingWalletBalance'; import UriBar from 'component/uriBar'; import searchStyle from 'styles/search'; @@ -213,7 +213,12 @@ class SearchPage extends React.PureComponent { ListEmptyComponent={!isSearching ? this.listEmptyComponent() : null} ListHeaderComponent={this.listHeaderComponent(this.state.showTagResult, this.state.currentQuery)} renderItem={({ item }) => ( - <FileResultItem key={item.claimId} result={item} style={searchStyle.resultItem} navigation={navigation} /> + <ClaimResultItem + key={item.claimId} + result={item} + style={searchStyle.resultItem} + navigation={navigation} + /> )} /> )}