display the video duration in the FileItemMedia component #27

Merged
akinwale merged 3 commits from video-duration into master 2019-08-20 10:03:56 +02:00
7 changed files with 107 additions and 10 deletions

View file

@ -71,6 +71,7 @@ class FileItem extends React.PureComponent {
const fullChannelUri = channelClaimId ? `${channelName}#${channelClaimId}` : channelName;
const shortChannelUri = signingChannel ? signingChannel.short_url : null;
const height = claim ? claim.height : null;
const duration = claim && claim.value && claim.value.video ? claim.value.video.duration : null;
return (
<View style={style}>
@ -81,6 +82,7 @@ class FileItem extends React.PureComponent {
</Text>
)}
<FileItemMedia
duration={duration}
title={title}
thumbnail={thumbnail}
blurRadius={obscure ? 15 : 0}
@ -88,7 +90,6 @@ class FileItem extends React.PureComponent {
isResolvingUri={isResolvingUri}
style={mediaStyle}
/>
{!compactView && fileInfo && fileInfo.completed && fileInfo.download_path && (
<Icon style={discoverStyle.downloadedIcon} solid color={Colors.NextLbryGreen} name={'folder'} size={16} />
)}

View file

@ -2,6 +2,7 @@ import React from 'react';
import { ActivityIndicator, Image, Text, View } from 'react-native';
import Colors from 'styles/colors';
import FastImage from 'react-native-fast-image';
import VideoDuration from 'component/videoDuration';
import autothumbStyle from 'styles/autothumb';
import fileItemMediaStyle from 'styles/fileItemMedia';
@ -58,7 +59,7 @@ class FileItemMedia extends React.PureComponent {
render() {
let style = this.props.style;
const { blurRadius, isResolvingUri, thumbnail, title, resizeMode } = this.props;
const { blurRadius, duration, isResolvingUri, thumbnail, title, resizeMode } = this.props;
const atStyle = this.state.autoThumbStyle;
if (this.isThumbnailValid(thumbnail) && !this.state.imageLoadFailed) {
if (style == null) {
@ -68,17 +69,40 @@ class FileItemMedia extends React.PureComponent {
if (blurRadius > 0) {
// No blur radius support in FastImage yet
return (
<Image source={{ uri: thumbnail }} blurRadius={blurRadius} resizeMode={resizeMode || 'cover'} style={style} />
<View style={style}>
<Image
source={{ uri: thumbnail }}
blurRadius={blurRadius}
resizeMode={resizeMode || 'cover'}
style={fileItemMediaStyle.image}
/>
{duration && (
<VideoDuration
duration={duration}
style={fileItemMediaStyle.duration}
textStyle={fileItemMediaStyle.durationText}
/>
)}
</View>
);
}
return (
<FastImage
source={{ uri: thumbnail }}
onError={() => this.setState({ imageLoadFailed: true })}
resizeMode={this.getFastImageResizeMode(resizeMode)}
style={style}
/>
<View style={style}>
<FastImage
source={{ uri: thumbnail }}
onError={() => this.setState({ imageLoadFailed: true })}
resizeMode={this.getFastImageResizeMode(resizeMode)}
style={fileItemMediaStyle.image}
/>
{duration && (
<VideoDuration
duration={duration}
style={fileItemMediaStyle.duration}
textStyle={fileItemMediaStyle.durationText}
/>
)}
</View>
);
}
@ -100,6 +124,13 @@ class FileItemMedia extends React.PureComponent {
.toUpperCase()}
</Text>
)}
{duration && (
<VideoDuration
duration={duration}
style={fileItemMediaStyle.duration}
textStyle={fileItemMediaStyle.durationText}
/>
)}
</View>
);
}

View file

@ -80,6 +80,7 @@ class FileListItem extends React.PureComponent {
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, channelClaimId, fullChannelUri, shortChannelUri, shouldHide, signingChannel;
if (claim) {
@ -110,6 +111,7 @@ class FileListItem extends React.PureComponent {
<FileItemMedia
style={fileListStyle.thumbnail}
blurRadius={obscure ? 15 : 0}
duration={duration}
resizeMode="cover"
title={title || name}
thumbnail={thumbnail}

View file

@ -0,0 +1,4 @@
import { connect } from 'react-redux';
import VideoDuration from './view';
export default connect()(VideoDuration);

View file

@ -0,0 +1,36 @@
import React from 'react';
import { Text, View } from 'react-native';
import fileListStyle from 'styles/fileList';
import _ from 'lodash';
export default class VideoDuration extends React.PureComponent {
getDurationString = duration => {
let seconds = duration;
const hours = Math.floor(seconds / 3600);
seconds = duration - hours * 3600;
const minutes = Math.floor(seconds / 60);
seconds = seconds % 60;
let durationString = '';
if (hours > 0) {
durationString += hours + ':';
}
durationString += _.padStart(minutes, hours > 0 ? 2 : 0, '0') + ':';
durationString += _.padStart(seconds, 2, '0');
return durationString;
};
render() {
const { duration, style, textStyle } = this.props;
if (!duration || isNaN(parseFloat(duration))) {
return null;
}
return (
<View style={style}>
<Text style={textStyle}>{this.getDurationString(duration)}</Text>
</View>
);
}
}

View file

@ -658,6 +658,7 @@ class FilePage extends React.PureComponent {
const canLoadMedia =
this.state.streamingMode ||
(fileInfo && (fileInfo.written_bytes >= 2097152 || fileInfo.written_bytes === fileInfo.total_bytes)); // 2MB = 1024*1024*2
const duration = claim && claim.value && claim.value.video ? claim.value.video.duration : null;
const isViewable = mediaType === 'image' || mediaType === 'text';
const isWebViewable = mediaType === 'text';
const canOpen = isViewable && completed;
@ -725,7 +726,12 @@ class FilePage extends React.PureComponent {
>
<View style={filePageStyle.mediaContainer}>
{(canOpen || (!fileInfo || (isPlayable && !canLoadMedia)) || (!canOpen && fileInfo)) && (
<FileItemMedia style={filePageStyle.thumbnail} title={title} thumbnail={thumbnail} />
<FileItemMedia
duration={duration}
style={filePageStyle.thumbnail}
title={title}
thumbnail={thumbnail}
/>
)}
{(!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded && (
<ActivityIndicator size="large" color={Colors.NextLbryGreen} style={filePageStyle.loading} />

View file

@ -26,12 +26,29 @@ const fileItemMediaStyle = StyleSheet.create({
fontSize: 16,
marginTop: 8,
},
image: {
width: '100%',
height: '100%',
},
thumbnail: {
flex: 1,
width: '100%',
height: 200,
shadowColor: 'transparent',
},
duration: {
backgroundColor: Colors.Black,
position: 'absolute',
right: 4,
bottom: 4,
paddingLeft: 2,
paddingRight: 2,
},
durationText: {
fontFamily: 'Inter-UI-SemiBold',
fontSize: 12,
color: Colors.White,
},
});
export default fileItemMediaStyle;