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 54%
rename from src/component/fileResultItem/view.js
rename to src/component/claimResultItem/view.js
index 0c0b10e..1f55801 100644
--- a/src/component/fileResultItem/view.js
+++ b/src/component/claimResultItem/view.js
@@ -1,10 +1,13 @@
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';
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';
@@ -12,29 +15,28 @@ 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 {
- getStorageForFileInfo = fileInfo => {
- if (!fileInfo.completed) {
- const written = formatBytes(fileInfo.written_bytes);
- const total = formatBytes(fileInfo.total_bytes);
- return `(${written} / ${total})`;
+class ClaimResultItem extends React.PureComponent {
+ state = {
+ autoStyle: null,
+ };
+
+ componentDidMount() {
+ 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] });
}
-
- 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;
@@ -58,6 +60,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 +70,39 @@ class FileResultItem extends React.PureComponent {
return (
-
-
+
+ {!isChannel && (
+
+ )}
+
+ {isChannel && (
+
+
+ {hasThumbnail && (
+
+ )}
+ {!hasThumbnail && (
+
+ {title ? title.substring(0, 1).toUpperCase() : name.substring(1, 2).toUpperCase()}
+
+ )}
+
+
+ )}
+
{fileInfo && fileInfo.completed && fileInfo.download_path && (
- {this.formatTitle(title) || this.formatTitle(name)}
+ {formatTitle(title) || formatTitle(name)}
{isRewardContent && }
)}
- {hasChannel && (
- {
- navigateToUri(navigation, normalizeURI(channelUrl), null, false, channelUrl);
- }}
- />
- )}
+ {hasChannel ||
+ (isChannel && (
+ {
+ navigateToUri(
+ navigation,
+ normalizeURI(isChannel ? url : channelUrl),
+ null,
+ false,
+ isChannel ? url : channelUrl,
+ );
+ }}
+ />
+ ))}
{fileInfo && !isNaN(fileInfo.written_bytes) && fileInfo.written_bytes > 0 && (
- {this.getStorageForFileInfo(fileInfo)}
+ {getStorageForFileInfo(fileInfo)}
)}
)}
@@ -143,4 +179,4 @@ class FileResultItem extends React.PureComponent {
}
}
-export default FileResultItem;
+export default ClaimResultItem;
diff --git a/src/component/fileListItem/view.js b/src/component/fileListItem/view.js
index 8d8ffdc..97398d3 100644
--- a/src/component/fileListItem/view.js
+++ b/src/component/fileListItem/view.js
@@ -1,10 +1,13 @@
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';
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';
@@ -15,27 +18,10 @@ import fileListStyle from 'styles/fileList';
class FileListItem extends React.PureComponent {
state = {
+ autoStyle: null,
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);
};
@@ -45,6 +31,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 +126,13 @@ class FileListItem extends React.PureComponent {
return null;
}
+ const isChannel = name && name.startsWith('@');
+ const hasThumbnail = !!thumbnail;
+
return (
{
if (onLongPress) {
@@ -146,13 +140,35 @@ class FileListItem extends React.PureComponent {
}
}}
>
-
+ {!isChannel && (
+
+ )}
+
+ {isChannel && (
+
+
+ {hasThumbnail && (
+
+ )}
+ {!hasThumbnail && (
+
+ {title ? title.substring(0, 1).toUpperCase() : claim.name.substring(1, 2).toUpperCase()}
+
+ )}
+
+
+ )}
+
{selected && (
@@ -194,7 +210,7 @@ class FileListItem extends React.PureComponent {
{(title || name) && (
- {this.formatTitle(title) || this.formatTitle(name)}
+ {formatTitle(title) || formatTitle(name)}
{isRewardContent && }
@@ -206,17 +222,17 @@ class FileListItem extends React.PureComponent {
)}
- {channel && !hideChannel && (
+ {(channel || isChannel) && !hideChannel && (
{
navigateToUri(
navigation,
- normalizeURI(shortChannelUri || fullChannelUri),
+ normalizeURI(isChannel ? uri : shortChannelUri || fullChannelUri),
null,
false,
- fullChannelUri,
+ isChannel ? claim && claim.permanent_url : fullChannelUri,
);
}}
/>
@@ -224,7 +240,7 @@ class FileListItem extends React.PureComponent {
{fileInfo && !isNaN(fileInfo.written_bytes) && fileInfo.written_bytes > 0 && (
- {this.getStorageForFileInfo(fileInfo)}
+ {getStorageForFileInfo(fileInfo)}
)}
@@ -237,7 +253,7 @@ class FileListItem extends React.PureComponent {
color={Colors.NextLbryGreen}
height={3}
style={fileListStyle.progress}
- progress={this.getDownloadProgress(fileInfo)}
+ progress={getDownloadProgress(fileInfo)}
/>
)}
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 && }
{recommendedContent &&
recommendedContent.map(result => (
-
@@ -38,12 +50,15 @@ class SuggestedSubscriptionItem extends React.PureComponent {
return (
-
-
+
+ {hasThumbnail && (
+
+ )}
+ {!hasThumbnail && (
+
+ {title ? title.substring(0, 1).toUpperCase() : claim ? claim.name.substring(1, 2).toUpperCase() : ''}
+
+ )}
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 {
>
{itemThumbnailUrl && (
-
)}
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 }) => (
-
+
)}
/>
)}
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%',
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;
+}