* i18n all the strings * assign file content * download and save language files * load language on startup * load language setting correctly when app launches * fix i18n calls in constants * pin lbryinc commit
240 lines
7.7 KiB
JavaScript
240 lines
7.7 KiB
JavaScript
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 Colors from 'styles/colors';
|
|
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
|
import DateTime from 'component/dateTime';
|
|
import FileItemMedia from 'component/fileItemMedia';
|
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
|
import Link from 'component/link';
|
|
import NsfwOverlay from 'component/nsfwOverlay';
|
|
import ProgressBar from 'component/progressBar';
|
|
import fileListStyle from 'styles/fileList';
|
|
|
|
class FileListItem extends React.PureComponent {
|
|
state = {
|
|
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);
|
|
};
|
|
|
|
componentDidMount() {
|
|
const { claim, resolveUri, uri, batchResolve } = this.props;
|
|
if (!claim && !batchResolve) {
|
|
resolveUri(uri);
|
|
}
|
|
}
|
|
|
|
componentDidUpdate() {
|
|
const { claim, resolveUri, uri } = this.props;
|
|
if (!claim && uri !== this.state.url) {
|
|
this.setState({ url: uri }, () => resolveUri(uri));
|
|
}
|
|
}
|
|
|
|
defaultOnPress = () => {
|
|
const { autoplay, claim, featuredResult, navigation, uri, shortUrl } = this.props;
|
|
|
|
if (featuredResult && !claim) {
|
|
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH, params: { vanityUrl: uri.trim() } });
|
|
} else {
|
|
navigateToUri(navigation, shortUrl || uri, { autoplay }, false, claim ? claim.permanent_url : null);
|
|
}
|
|
};
|
|
|
|
onPressHandler = () => {
|
|
const { claim, onPress } = this.props;
|
|
if (onPress) {
|
|
onPress(claim);
|
|
} else {
|
|
this.defaultOnPress();
|
|
}
|
|
};
|
|
|
|
render() {
|
|
const {
|
|
blackListedOutpoints,
|
|
claim,
|
|
fileInfo,
|
|
filteredOutpoints,
|
|
metadata,
|
|
nsfw,
|
|
featuredResult,
|
|
isResolvingUri,
|
|
isDownloaded,
|
|
style,
|
|
obscureNsfw,
|
|
onPress,
|
|
navigation,
|
|
rewardedContentClaimIds,
|
|
thumbnail,
|
|
hideChannel,
|
|
onLongPress,
|
|
selected,
|
|
title,
|
|
} = this.props;
|
|
|
|
const uri = normalizeURI(this.props.uri);
|
|
const obscure = obscureNsfw && nsfw;
|
|
const isResolving = !fileInfo && isResolvingUri;
|
|
const duration = claim && claim.value && claim.value.video ? claim.value.video.duration : null;
|
|
|
|
let name,
|
|
channel,
|
|
height,
|
|
isRewardContent,
|
|
channelClaimId,
|
|
fullChannelUri,
|
|
shortChannelUri,
|
|
shouldHide,
|
|
signingChannel;
|
|
if (claim) {
|
|
name = claim.name;
|
|
signingChannel = claim.signing_channel;
|
|
channel = signingChannel ? signingChannel.name : null;
|
|
height = claim.height;
|
|
isRewardContent = rewardedContentClaimIds.includes(claim.claim_id);
|
|
channelClaimId = signingChannel ? signingChannel.claim_id : null;
|
|
fullChannelUri = channelClaimId ? `${channel}#${channelClaimId}` : channel;
|
|
shortChannelUri = signingChannel ? signingChannel.short_url : null;
|
|
|
|
if (blackListedOutpoints || filteredOutpoints) {
|
|
const outpointsToHide = !blackListedOutpoints
|
|
? filteredOutpoints
|
|
: blackListedOutpoints.concat(filteredOutpoints);
|
|
shouldHide = outpointsToHide.some(outpoint => outpoint.txid === claim.txid && outpoint.nout === claim.nout);
|
|
}
|
|
|
|
// TODO: hide channels on tag pages?
|
|
// shouldHide = 'channel' === claim.value_type;
|
|
}
|
|
|
|
if (shouldHide || (!isResolvingUri && !claim && !featuredResult)) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<View style={style}>
|
|
<TouchableOpacity
|
|
style={style}
|
|
onPress={this.onPressHandler}
|
|
onLongPress={() => {
|
|
if (onLongPress) {
|
|
onLongPress(claim);
|
|
}
|
|
}}
|
|
>
|
|
<FileItemMedia
|
|
style={fileListStyle.thumbnail}
|
|
duration={duration}
|
|
resizeMode="cover"
|
|
title={title || name || normalizeURI(uri).substring(7)}
|
|
thumbnail={thumbnail}
|
|
/>
|
|
{selected && (
|
|
<View style={fileListStyle.selectedOverlay}>
|
|
<Icon name={'check-circle'} solid color={Colors.NextLbryGreen} size={32} />
|
|
</View>
|
|
)}
|
|
{fileInfo && fileInfo.completed && fileInfo.download_path && (
|
|
<Icon style={fileListStyle.downloadedIcon} solid color={Colors.NextLbryGreen} name={'folder'} size={16} />
|
|
)}
|
|
<View style={fileListStyle.detailsContainer}>
|
|
{featuredResult && (
|
|
<Text style={fileListStyle.featuredUri} numberOfLines={1}>
|
|
{uri}
|
|
</Text>
|
|
)}
|
|
|
|
{!title && !name && !channel && isResolving && (
|
|
<View>
|
|
{!title && !name && <Text style={fileListStyle.uri}>{uri}</Text>}
|
|
{!title && !name && (
|
|
<View style={fileListStyle.row}>
|
|
<ActivityIndicator size={'small'} color={featuredResult ? Colors.White : Colors.LbryGreen} />
|
|
</View>
|
|
)}
|
|
</View>
|
|
)}
|
|
|
|
{(title || name) && (
|
|
<View style={fileListStyle.titleContainer}>
|
|
<Text style={featuredResult ? fileListStyle.featuredTitle : fileListStyle.title}>
|
|
{this.formatTitle(title) || this.formatTitle(name)}
|
|
</Text>
|
|
{isRewardContent && <Icon style={fileListStyle.rewardIcon} name="award" size={12} />}
|
|
</View>
|
|
)}
|
|
|
|
{featuredResult && !isResolving && !claim && (
|
|
<View style={fileListStyle.titleContainer}>
|
|
<Text style={fileListStyle.featuredTitle}>{__('Nothing here. Publish something!')}</Text>
|
|
</View>
|
|
)}
|
|
|
|
{channel && !hideChannel && (
|
|
<Link
|
|
style={fileListStyle.publisher}
|
|
text={channel}
|
|
onPress={() => {
|
|
navigateToUri(
|
|
navigation,
|
|
normalizeURI(shortChannelUri || fullChannelUri),
|
|
null,
|
|
false,
|
|
fullChannelUri
|
|
);
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
<View style={fileListStyle.info}>
|
|
{fileInfo && !isNaN(fileInfo.written_bytes) && fileInfo.written_bytes > 0 && (
|
|
<Text style={fileListStyle.infoText}>{this.getStorageForFileInfo(fileInfo)}</Text>
|
|
)}
|
|
<DateTime style={fileListStyle.publishInfo} textStyle={fileListStyle.infoText} timeAgo uri={uri} />
|
|
</View>
|
|
|
|
{fileInfo && fileInfo.download_path && (
|
|
<View style={fileListStyle.downloadInfo}>
|
|
{!fileInfo.completed && (
|
|
<ProgressBar
|
|
borderRadius={3}
|
|
color={Colors.NextLbryGreen}
|
|
height={3}
|
|
style={fileListStyle.progress}
|
|
progress={this.getDownloadProgress(fileInfo)}
|
|
/>
|
|
)}
|
|
</View>
|
|
)}
|
|
</View>
|
|
</TouchableOpacity>
|
|
{obscure && <NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />}
|
|
</View>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default FileListItem;
|