diff --git a/src/component/fileItem/view.js b/src/component/fileItem/view.js
index 3832a35..e72ed52 100644
--- a/src/component/fileItem/view.js
+++ b/src/component/fileItem/view.js
@@ -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 (
@@ -81,6 +82,7 @@ class FileItem extends React.PureComponent {
)}
-
{!compactView && fileInfo && fileInfo.completed && fileInfo.download_path && (
)}
diff --git a/src/component/fileItemMedia/view.js b/src/component/fileItemMedia/view.js
index f9ac4dc..20ff308 100644
--- a/src/component/fileItemMedia/view.js
+++ b/src/component/fileItemMedia/view.js
@@ -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 (
-
+
+
+ {duration && (
+
+ )}
+
);
}
return (
- this.setState({ imageLoadFailed: true })}
- resizeMode={this.getFastImageResizeMode(resizeMode)}
- style={style}
- />
+
+ this.setState({ imageLoadFailed: true })}
+ resizeMode={this.getFastImageResizeMode(resizeMode)}
+ style={fileItemMediaStyle.image}
+ />
+ {duration && (
+
+ )}
+
);
}
@@ -100,6 +124,13 @@ class FileItemMedia extends React.PureComponent {
.toUpperCase()}
)}
+ {duration && (
+
+ )}
);
}
diff --git a/src/component/fileListItem/view.js b/src/component/fileListItem/view.js
index 11237b5..680b9d5 100644
--- a/src/component/fileListItem/view.js
+++ b/src/component/fileListItem/view.js
@@ -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 {
{
+ 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 (
+
+ {this.getDurationString(duration)}
+
+ );
+ }
+}
diff --git a/src/page/file/view.js b/src/page/file/view.js
index 8459e3a..16da579 100644
--- a/src/page/file/view.js
+++ b/src/page/file/view.js
@@ -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 {
>
{(canOpen || (!fileInfo || (isPlayable && !canLoadMedia)) || (!canOpen && fileInfo)) && (
-
+
)}
{(!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded && (
diff --git a/src/styles/fileItemMedia.js b/src/styles/fileItemMedia.js
index bb5bc83..6d7197d 100644
--- a/src/styles/fileItemMedia.js
+++ b/src/styles/fileItemMedia.js
@@ -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;