Add viewed bar in thumbnails.

This commit is contained in:
Franco Montenegro 2022-04-12 13:05:47 -03:00 committed by jessopb
parent d1c82c9af0
commit 3fd3a548ec
7 changed files with 33 additions and 5 deletions

View file

@ -347,7 +347,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
<> <>
{!pending ? ( {!pending ? (
<NavLink aria-hidden tabIndex={-1} {...navLinkProps}> <NavLink aria-hidden tabIndex={-1} {...navLinkProps}>
<FileThumbnail thumbnail={thumbnailUrl}> <FileThumbnail uri={uri} thumbnail={thumbnailUrl}>
<div className="claim-preview__hover-actions"> <div className="claim-preview__hover-actions">
{isPlayable && <FileWatchLaterLink focusable={false} uri={repostedContentUri} />} {isPlayable && <FileWatchLaterLink focusable={false} uri={repostedContentUri} />}
</div> </div>
@ -364,7 +364,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
</FileThumbnail> </FileThumbnail>
</NavLink> </NavLink>
) : ( ) : (
<FileThumbnail thumbnail={thumbnailUrl} /> <FileThumbnail uri={uri} thumbnail={thumbnailUrl} />
)} )}
</> </>
)} )}

View file

@ -175,7 +175,7 @@ function ClaimPreviewTile(props: Props) {
})} })}
> >
<NavLink {...navLinkProps} role="none" tabIndex={-1} aria-hidden> <NavLink {...navLinkProps} role="none" tabIndex={-1} aria-hidden>
<FileThumbnail thumbnail={thumbnailUrl} allowGifs> <FileThumbnail uri={uri} thumbnail={thumbnailUrl} allowGifs>
{!isChannel && ( {!isChannel && (
<React.Fragment> <React.Fragment>
<div className="claim-preview__hover-actions"> <div className="claim-preview__hover-actions">

View file

@ -1,9 +1,11 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doResolveUri } from 'redux/actions/claims'; import { doResolveUri } from 'redux/actions/claims';
import { makeSelectClaimForUri } from 'redux/selectors/claims'; import { makeSelectClaimForUri } from 'redux/selectors/claims';
import { makeSelectContentPositionForUri } from 'redux/selectors/content';
import CardMedia from './view'; import CardMedia from './view';
const select = (state, props) => ({ const select = (state, props) => ({
position: makeSelectContentPositionForUri(props.uri)(state),
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
}); });

View file

@ -16,10 +16,11 @@ type Props = {
claim: ?StreamClaim, claim: ?StreamClaim,
doResolveUri: (string) => void, doResolveUri: (string) => void,
className?: string, className?: string,
position?: number,
}; };
function FileThumbnail(props: Props) { function FileThumbnail(props: Props) {
const { claim, uri, doResolveUri, thumbnail: rawThumbnail, children, allowGifs = false, className } = props; const { claim, uri, doResolveUri, thumbnail: rawThumbnail, children, allowGifs = false, className, position } = props;
const passedThumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://'); const passedThumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://');
const thumbnailFromClaim = const thumbnailFromClaim =
@ -29,6 +30,14 @@ function FileThumbnail(props: Props) {
const hasResolvedClaim = claim !== undefined; const hasResolvedClaim = claim !== undefined;
const isGif = thumbnail && thumbnail.endsWith('gif'); const isGif = thumbnail && thumbnail.endsWith('gif');
const media = claim && claim.value && (claim.value.video || claim.value.audio);
const duration = media && media.duration;
const viewedBar = position && duration && (
<div className="file-thumbnail__viewed-bar">
<div className="file-thumbnail__viewed-bar-progress" style={{ width: (position / duration) * 100 + '%' }} />
</div>
);
React.useEffect(() => { React.useEffect(() => {
if (!hasResolvedClaim && uri) { if (!hasResolvedClaim && uri) {
doResolveUri(uri); doResolveUri(uri);
@ -39,6 +48,7 @@ function FileThumbnail(props: Props) {
return ( return (
<FreezeframeWrapper src={thumbnail} className={classnames('media__thumb', className)}> <FreezeframeWrapper src={thumbnail} className={classnames('media__thumb', className)}>
{children} {children}
{viewedBar}
</FreezeframeWrapper> </FreezeframeWrapper>
); );
} }
@ -59,6 +69,7 @@ function FileThumbnail(props: Props) {
return ( return (
<Thumb thumb={thumbnailUrl} fallback={fallback} className={className}> <Thumb thumb={thumbnailUrl} fallback={fallback} className={className}>
{children} {children}
{viewedBar}
</Thumb> </Thumb>
); );
} }
@ -69,6 +80,7 @@ function FileThumbnail(props: Props) {
})} })}
> >
{children} {children}
{viewedBar}
</div> </div>
); );
} }

View file

@ -20,7 +20,7 @@ export const makeSelectMyReactionForUri = (uri) =>
} }
const claimId = claim.claim_id; const claimId = claim.claim_id;
const myReactions = reactions.my_reactions[claimId]; const myReactions = reactions.my_reactions ? reactions.my_reactions[claimId] : {};
if (myReactions[REACTION_TYPES.LIKE]) { if (myReactions[REACTION_TYPES.LIKE]) {
return REACTION_TYPES.LIKE; return REACTION_TYPES.LIKE;
} else if (myReactions[REACTION_TYPES.DISLIKE]) { } else if (myReactions[REACTION_TYPES.DISLIKE]) {

View file

@ -26,6 +26,7 @@
@import 'component/file-list'; @import 'component/file-list';
@import 'component/file-properties'; @import 'component/file-properties';
@import 'component/file-render'; @import 'component/file-render';
@import 'component/file-thumbnail';
@import 'component/footer'; @import 'component/footer';
@import 'component/form-field'; @import 'component/form-field';
@import 'component/header'; @import 'component/header';

View file

@ -0,0 +1,13 @@
.file-thumbnail__viewed-bar {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
background-color: gray;
}
.file-thumbnail__viewed-bar-progress {
height: 5px;
background-color: red;
}