Playlist fall out fixes #7032

Merged
saltrafael merged 4 commits from list-fall-out into master 2021-09-10 19:27:21 +02:00
13 changed files with 127 additions and 161 deletions
Showing only changes of commit 1471910ccd - Show all commits
ui
component
claimMenuList
claimPreviewTile
collectionActions
collectionMenuList
collectionPreviewTile
fileRenderFloating
fileRenderInitiator
viewers/videoViewer
util

View file

@ -31,14 +31,13 @@ import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscrip
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
import { selectUserVerifiedEmail } from 'redux/selectors/user';
import { selectListShuffle } from 'redux/selectors/content';
import { doSetPlayingUri, doToggleShuffleList } from 'redux/actions/content';
import { doToggleLoopList, doToggleShuffleList } from 'redux/actions/content';
import ClaimPreview from './view';
import fs from 'fs';
const select = (state, props) => {
const claim = makeSelectClaimForUri(props.uri, false)(state);
const collectionId = props.collectionId;
const resolvedList = makeSelectUrlsForCollectionId(collectionId)(state);
const repostedClaim = claim && claim.reposted_claim;
const contentClaim = repostedClaim || claim;
const contentSigningChannel = contentClaim && contentClaim.signing_channel;
@ -73,7 +72,7 @@ const select = (state, props) => {
isMyCollection: makeSelectCollectionIsMine(collectionId)(state),
editedCollection: makeSelectEditedCollectionForId(collectionId)(state),
isAuthenticated: Boolean(selectUserVerifiedEmail(state)),
resolvedList,
resolvedList: makeSelectUrlsForCollectionId(collectionId)(state),
playNextUri,
};
};
@ -102,8 +101,10 @@ const perform = (dispatch) => ({
doChannelUnsubscribe: (subscription) => dispatch(doChannelUnsubscribe(subscription)),
doCollectionEdit: (collection, props) => dispatch(doCollectionEdit(collection, props)),
fetchCollectionItems: (collectionId) => dispatch(doFetchItemsInCollection({ collectionId })),
doSetPlayingUri: (uri) => dispatch(doSetPlayingUri({ uri })),
doToggleShuffleList: (collectionId) => dispatch(doToggleShuffleList(undefined, collectionId, true, true)),
doToggleShuffleList: (collectionId) => {
dispatch(doToggleLoopList(collectionId, false, true));
dispatch(doToggleShuffleList(undefined, collectionId, true, true));
},
});
export default connect(select, perform)(ClaimPreview);

View file

@ -7,7 +7,13 @@ import React from 'react';
import classnames from 'classnames';
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
import Icon from 'component/common/icon';
import { generateShareUrl, generateRssUrl, generateLbryContentUrl, formatLbryUrlForWeb } from 'util/url';
import {
generateShareUrl,
generateRssUrl,
generateLbryContentUrl,
formatLbryUrlForWeb,
generateListSearchUrlParams,
} from 'util/url';
import { useHistory } from 'react-router';
import { buildURI, parseURI, COLLECTIONS_CONSTS } from 'lbry-redux';
@ -59,7 +65,6 @@ type Props = {
playNextUri: string,
resolvedList: boolean,
fetchCollectionItems: (string) => void,
doSetPlayingUri: (string) => void,
doToggleShuffleList: (string) => void,
};
@ -101,7 +106,6 @@ function ClaimMenuList(props: Props) {
playNextUri,
resolvedList,
fetchCollectionItems,
doSetPlayingUri,
doToggleShuffleList,
} = props;
const [doShuffle, setDoShuffle] = React.useState(false);
@ -129,15 +133,15 @@ function ClaimMenuList(props: Props) {
if (doShuffle && resolvedList) {
doToggleShuffleList(collectionId);
if (playNextUri) {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
const navigateUrl = formatLbryUrlForWeb(playNextUri) + `?` + collectionParams.toString();
setDoShuffle(false);
doSetPlayingUri(playNextUri);
push(navigateUrl);
const navigateUrl = formatLbryUrlForWeb(playNextUri);
push({
pathname: navigateUrl,
search: generateListSearchUrlParams(collectionId),
state: { collectionId, forceAutoplay: true },
});
}
}
}, [collectionId, doSetPlayingUri, doShuffle, doToggleShuffleList, playNextUri, push, resolvedList]);
}, [collectionId, doShuffle, doToggleShuffleList, playNextUri, push, resolvedList]);
if (!claim) {
return null;

View file

@ -10,9 +10,9 @@ import ChannelThumbnail from 'component/channelThumbnail';
import FileViewCountInline from 'component/fileViewCountInline';
import SubscribeButton from 'component/subscribeButton';
import useGetThumbnail from 'effects/use-get-thumbnail';
import { formatLbryUrlForWeb } from 'util/url';
import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
import { formatClaimPreviewTitle } from 'util/formatAriaLabel';
import { parseURI, COLLECTIONS_CONSTS, isURIEqual } from 'lbry-redux';
import { parseURI, isURIEqual } from 'lbry-redux';
import PreviewOverlayProperties from 'component/previewOverlayProperties';
import FileDownloadLink from 'component/fileDownloadLink';
import FileWatchLaterLink from 'component/fileWatchLaterLink';
@ -98,13 +98,9 @@ function ClaimPreviewTile(props: Props) {
const thumbnailUrl = useGetThumbnail(uri, claim, streamingUrl, getFile, placeholder) || thumbnail;
const canonicalUrl = claim && claim.canonical_url;
const permanentUrl = claim && claim.permanent_url;
let navigateUrl = formatLbryUrlForWeb(canonicalUrl || uri || '/');
const listId = collectionId || collectionClaimId;
if (listId) {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, listId);
navigateUrl = navigateUrl + `?` + collectionParams.toString();
}
const navigateUrl =
formatLbryUrlForWeb(canonicalUrl || uri || '/') + (listId ? generateListSearchUrlParams(listId) : '');
const navLinkProps = {
to: navigateUrl,
onClick: (e) => e.stopPropagation(),

View file

@ -1,17 +1,13 @@
import { connect } from 'react-redux';
import {
makeSelectClaimIsMine,
makeSelectClaimForUri,
selectMyChannelClaims,
makeSelectClaimIsPending,
makeSelectCollectionIsMine,
makeSelectEditedCollectionForId,
} from 'lbry-redux';
import { makeSelectCostInfoForUri } from 'lbryinc';
import { doToast } from 'redux/actions/notifications';
import { doOpenModal } from 'redux/actions/app';
import { selectListShuffle } from 'redux/selectors/content';
import { doPlayUri, doSetPlayingUri, doToggleShuffleList, doToggleLoopList } from 'redux/actions/content';
import { doToggleShuffleList, doToggleLoopList } from 'redux/actions/content';
import CollectionActions from './view';
const select = (state, props) => {
@ -31,29 +27,23 @@ const select = (state, props) => {
const shuffleList = selectListShuffle(state);
const shuffle = shuffleList && shuffleList.collectionId === collectionId && shuffleList.newUrls;
const playNextUri = shuffle && shuffle[0];
const playNextClaim = makeSelectClaimForUri(playNextUri)(state);
return {
claim: makeSelectClaimForUri(props.uri)(state),
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
costInfo: makeSelectCostInfoForUri(props.uri)(state),
myChannels: selectMyChannelClaims(state),
claimIsPending: makeSelectClaimIsPending(props.uri)(state),
isMyCollection: makeSelectCollectionIsMine(collectionId)(state),
collectionHasEdits: Boolean(makeSelectEditedCollectionForId(collectionId)(state)),
firstItem,
playNextUri,
playNextClaim,
};
};
const perform = (dispatch) => ({
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
doToast: (options) => dispatch(doToast(options)),
doPlayUri: (uri) => dispatch(doPlayUri(uri)),
doSetPlayingUri: (uri) => dispatch(doSetPlayingUri({ uri })),
doToggleShuffleList: (collectionId, shuffle) => dispatch(doToggleShuffleList(undefined, collectionId, shuffle, true)),
doToggleLoopList: (collectionId, loop) => dispatch(doToggleLoopList(collectionId, loop)),
doToggleShuffleList: (collectionId, shuffle) => {
dispatch(doToggleLoopList(collectionId, false, true));
dispatch(doToggleShuffleList(undefined, collectionId, shuffle, true));
},
});
export default connect(select, perform)(CollectionActions);

View file

@ -11,15 +11,12 @@ import { useHistory } from 'react-router';
import { EDIT_PAGE, PAGE_VIEW_QUERY } from 'page/collection/view';
import classnames from 'classnames';
import { ENABLE_FILE_REACTIONS } from 'config';
import { COLLECTIONS_CONSTS } from 'lbry-redux';
import { formatLbryUrlForWeb } from 'util/url';
import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
type Props = {
uri: string,
claim: StreamClaim,
openModal: (id: string, { uri: string, claimIsMine?: boolean, isSupport?: boolean }) => void,
myChannels: ?Array<ChannelClaim>,
doToast: ({ message: string }) => void,
openModal: (id: string, {}) => void,
claimIsPending: boolean,
isMyCollection: boolean,
collectionId: string,
@ -28,11 +25,7 @@ type Props = {
collectionHasEdits: boolean,
isBuiltin: boolean,
doToggleShuffleList: (string, boolean) => void,
doToggleLoopList: (string, boolean) => void,
playNextUri: string,
playNextClaim: StreamClaim,
doPlayUri: (string) => void,
doSetPlayingUri: (string) => void,
firstItem: string,
};
@ -49,11 +42,7 @@ function CollectionActions(props: Props) {
collectionHasEdits,
isBuiltin,
doToggleShuffleList,
doToggleLoopList,
playNextUri,
playNextClaim,
doPlayUri,
doSetPlayingUri,
firstItem,
} = props;
const [doShuffle, setDoShuffle] = React.useState(false);
@ -63,23 +52,23 @@ function CollectionActions(props: Props) {
const webShareable = true; // collections have cost?
const doPlay = React.useCallback(
(uri) => {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
const navigateUrl = formatLbryUrlForWeb(uri) + `?` + collectionParams.toString();
push(navigateUrl);
doSetPlayingUri(uri);
doPlayUri(uri);
(playUri) => {
const navigateUrl = formatLbryUrlForWeb(playUri);
push({
pathname: navigateUrl,
search: generateListSearchUrlParams(collectionId),
state: { forceAutoplay: true },
});
},
[collectionId, push, doSetPlayingUri, doPlayUri]
[collectionId, push]
);
React.useEffect(() => {
if (playNextClaim && doShuffle) {
if (playNextUri && doShuffle) {
setDoShuffle(false);
doPlay(playNextUri);
}
}, [doPlay, doShuffle, playNextClaim, playNextUri]);
}, [doPlay, doShuffle, playNextUri]);
const lhsSection = (
<>
@ -90,7 +79,6 @@ function CollectionActions(props: Props) {
title={__('Play')}
onClick={() => {
doToggleShuffleList(collectionId, false);
doToggleLoopList(collectionId, false);
doPlay(firstItem);
}}
/>

View file

@ -1,8 +1,8 @@
import { connect } from 'react-redux';
import { doCollectionEdit, makeSelectNameForCollectionId, doCollectionDelete } from 'lbry-redux';
import { makeSelectNameForCollectionId } from 'lbry-redux';
import { doOpenModal } from 'redux/actions/app';
import { selectListShuffle } from 'redux/selectors/content';
import { doSetPlayingUri, doToggleShuffleList } from 'redux/actions/content';
import { doToggleLoopList, doToggleShuffleList } from 'redux/actions/content';
import CollectionMenuList from './view';
const select = (state, props) => {
@ -17,10 +17,12 @@ const select = (state, props) => {
};
};
export default connect(select, {
doCollectionEdit,
doOpenModal,
doCollectionDelete,
doSetPlayingUri,
doToggleShuffleList,
})(CollectionMenuList);
const perform = (dispatch) => ({
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
doToggleShuffleList: (collectionId) => {
dispatch(doToggleLoopList(collectionId, false, true));
dispatch(doToggleShuffleList(undefined, collectionId, true, true));
},
});
export default connect(select, perform)(CollectionMenuList);

View file

@ -7,8 +7,7 @@ import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
import Icon from 'component/common/icon';
import * as PAGES from 'constants/pages';
import { useHistory } from 'react-router';
import { formatLbryUrlForWeb } from 'util/url';
import { COLLECTIONS_CONSTS } from 'lbry-redux';
import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
type Props = {
inline?: boolean,
@ -16,34 +15,26 @@ type Props = {
collectionName?: string,
collectionId: string,
playNextUri: string,
doSetPlayingUri: ({ uri: ?string }) => void,
doToggleShuffleList: (string, string, boolean, boolean) => void,
doToggleShuffleList: (string) => void,
};
function CollectionMenuList(props: Props) {
const {
inline = false,
collectionId,
collectionName,
doOpenModal,
playNextUri,
doSetPlayingUri,
doToggleShuffleList,
} = props;
const { inline = false, collectionId, collectionName, doOpenModal, playNextUri, doToggleShuffleList } = props;
const [doShuffle, setDoShuffle] = React.useState(false);
const { push } = useHistory();
React.useEffect(() => {
if (playNextUri && doShuffle) {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
const navigateUrl = formatLbryUrlForWeb(playNextUri) + `?` + collectionParams.toString();
setDoShuffle(false);
doSetPlayingUri({ uri: playNextUri });
push(navigateUrl);
const navigateUrl = formatLbryUrlForWeb(playNextUri);
push({
pathname: navigateUrl,
search: generateListSearchUrlParams(collectionId),
state: { forceAutoplay: true },
});
}
}, [push, doSetPlayingUri, collectionId, playNextUri, doShuffle]);
}, [collectionId, doShuffle, playNextUri, push]);
return (
<Menu>
@ -68,7 +59,7 @@ function CollectionMenuList(props: Props) {
<MenuItem
className="comment__menu-option"
onSelect={() => {
doToggleShuffleList('', collectionId, true, true);
doToggleShuffleList(collectionId);
setDoShuffle(true);
}}
>

View file

@ -7,8 +7,7 @@ import TruncatedText from 'component/common/truncated-text';
import CollectionCount from './collectionCount';
import CollectionPrivate from './collectionPrivate';
import CollectionMenuList from 'component/collectionMenuList';
import { formatLbryUrlForWeb } from 'util/url';
import { COLLECTIONS_CONSTS } from 'lbry-redux';
import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
import FileThumbnail from 'component/fileThumbnail';
type Props = {
@ -62,16 +61,12 @@ function CollectionPreviewTile(props: Props) {
if (collectionId && hasClaim && resolveCollectionItems) {
resolveCollectionItems({ collectionId, page_size: 5 });
}
}, [collectionId, hasClaim]);
}, [collectionId, hasClaim, resolveCollectionItems]);
// const signingChannel = claim && claim.signing_channel;
let navigateUrl = formatLbryUrlForWeb(collectionItemUrls[0] || '/');
if (collectionId) {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
navigateUrl = navigateUrl + `?` + collectionParams.toString();
}
const navigateUrl =
formatLbryUrlForWeb(collectionItemUrls[0] || '/') + (collectionId ? generateListSearchUrlParams(collectionId) : '');
function handleClick(e) {
if (navigateUrl) {

View file

@ -11,10 +11,11 @@ import usePersistedState from 'effects/use-persisted-state';
import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view';
import Draggable from 'react-draggable';
import { onFullscreenChange } from 'util/full-screen';
import { generateListSearchUrlParams } from 'util/url';
import { useIsMobile } from 'effects/use-screensize';
import debounce from 'util/debounce';
import { useHistory } from 'react-router';
import { isURIEqual, COLLECTIONS_CONSTS } from 'lbry-redux';
import { isURIEqual } from 'lbry-redux';
const IS_DESKTOP_MAC = typeof process === 'object' ? process.platform === 'darwin' : false;
const DEBOUNCE_WINDOW_RESIZE_HANDLER_MS = 60;
@ -54,9 +55,8 @@ export default function FileRenderFloating(props: Props) {
doFetchRecommendedContent,
collectionId,
} = props;
const {
location: { pathname },
} = useHistory();
const { location } = useHistory();
const hideFloatingPlayer = location.state && location.state.hideFloatingPlayer;
const isMobile = useIsMobile();
const mainFilePlaying = playingUri && isURIEqual(playingUri.uri, primaryUri);
const [fileViewerRect, setFileViewerRect] = useState();
@ -71,12 +71,7 @@ export default function FileRenderFloating(props: Props) {
y: 0,
});
let navigateUrl;
if (collectionId) {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
navigateUrl = uri + `?` + collectionParams.toString();
}
const navigateUrl = uri + (collectionId ? generateListSearchUrlParams(collectionId) : '');
const playingUriSource = playingUri && playingUri.source;
const isPlayable = RENDER_MODES.FLOATING_MODES.includes(renderMode);
@ -102,7 +97,7 @@ export default function FileRenderFloating(props: Props) {
}
}
function clampToScreen(pos) {
const clampToScreen = React.useCallback((pos) => {
const ESTIMATED_SCROLL_BAR_PX = 50;
const FLOATING_PLAYER_CLASS = 'content__viewer--floating';
const fpPlayerElem = document.querySelector(`.${FLOATING_PLAYER_CLASS}`);
@ -115,7 +110,7 @@ export default function FileRenderFloating(props: Props) {
pos.y = getScreenHeight() - fpPlayerElem.getBoundingClientRect().height;
}
}
}
}, []);
// Updated 'relativePos' based on persisted 'position':
const stringifiedPosition = JSON.stringify(position);
@ -139,7 +134,7 @@ export default function FileRenderFloating(props: Props) {
setPosition({ x: pos.x, y: pos.y });
}
}
}, [isFloating, stringifiedPosition]);
}, [clampToScreen, isFloating, position.x, position.y, setPosition, stringifiedPosition]);
// Listen to main-window resizing and adjust the fp position accordingly:
useEffect(() => {
@ -157,9 +152,9 @@ export default function FileRenderFloating(props: Props) {
// 'relativePos' is needed in the dependency list to avoid stale closure.
// Otherwise, this could just be changed to a one-time effect.
}, [relativePos]);
}, [clampToScreen, relativePos.x, relativePos.y, setPosition]);
function handleResize() {
const handleResize = React.useCallback(() => {
const element = mainFilePlaying
? document.querySelector(`.${PRIMARY_PLAYER_WRAPPER_CLASS}`)
: document.querySelector(`.${INLINE_PLAYER_WRAPPER_CLASS}`);
@ -184,13 +179,13 @@ export default function FileRenderFloating(props: Props) {
// $FlowFixMe
setFileViewerRect({ ...objectRect, windowOffset: window.pageYOffset });
}
}, [mainFilePlaying]);
useEffect(() => {
if (streamingUrl) {
handleResize();
}
}, [streamingUrl, pathname, playingUriSource, isFloating, mainFilePlaying]);
}, [handleResize, streamingUrl]);
useEffect(() => {
handleResize();
@ -201,7 +196,7 @@ export default function FileRenderFloating(props: Props) {
window.removeEventListener('resize', handleResize);
onFullscreenChange(window, 'remove', handleResize);
};
}, [setFileViewerRect, isFloating, playingUriSource, mainFilePlaying, videoTheaterMode]);
}, [handleResize]);
useEffect(() => {
// @if TARGET='app'
@ -219,9 +214,9 @@ export default function FileRenderFloating(props: Props) {
if (isFloating) {
doFetchRecommendedContent(uri, mature);
}
}, [uri, mature, isFloating]);
}, [doFetchRecommendedContent, isFloating, mature, uri]);
if (!isPlayable || !uri || (isFloating && (isMobile || !floatingPlayerEnabled))) {
if (!isPlayable || !uri || (isFloating && (isMobile || !floatingPlayerEnabled || hideFloatingPlayer))) {
return null;
}
@ -312,12 +307,7 @@ export default function FileRenderFloating(props: Props) {
{isFloating && (
<div className="draggable content__info">
<div className="claim-preview__title" title={title || uri}>
<Button
label={title || uri}
navigate={navigateUrl || uri}
button="link"
className="content__floating-link"
/>
<Button label={title || uri} navigate={navigateUrl} button="link" className="content__floating-link" />
</div>
<UriIndicator link uri={uri} />
</div>

View file

@ -22,7 +22,7 @@ type Props = {
fileInfo: FileListItem,
uri: string,
history: { push: (string) => void },
location: { search: ?string, pathname: string },
location: { search: ?string, pathname: string, href: string, state: { forceAutoplay: boolean } },
obscurePreview: boolean,
insufficientCredits: boolean,
claimThumbnail?: string,
@ -58,14 +58,10 @@ export default function FileRenderInitiator(props: Props) {
collectionId,
} = props;
// force autoplay if a timestamp is present
let autoplay = props.autoplay;
// get current url
const url = window.location.href;
// check if there is a time parameter, if so force autoplay
if (url.indexOf('t=') > -1) {
autoplay = true;
}
// check if there is a time or autoplay parameter, if so force autoplay
const urlTimeParam = location && location.href && location.href.indexOf('t=') > -1;
const forceAutoplayParam = location && location.state && location.state.forceAutoplay;
const autoplay = forceAutoplayParam || urlTimeParam || props.autoplay;
const cost = costInfo && costInfo.cost;
const isFree = hasCostInfo && cost === 0;
@ -75,7 +71,7 @@ export default function FileRenderInitiator(props: Props) {
const [thumbnail, setThumbnail] = React.useState(FileRenderPlaceholder);
const containerRef = React.useRef<any>();
React.useEffect(() => {
useEffect(() => {
if (claimThumbnail) {
setTimeout(() => {
let newThumbnail = claimThumbnail;
@ -96,7 +92,7 @@ export default function FileRenderInitiator(props: Props) {
}
}, 200);
}
}, [claimThumbnail]);
}, [claimThumbnail, thumbnail]);
function doAuthRedirect() {
history.push(`/$/${PAGES.AUTH}?redirect=${encodeURIComponent(location.pathname)}`);
@ -138,11 +134,12 @@ export default function FileRenderInitiator(props: Props) {
const videoOnPage = document.querySelector('video');
if (
(isFree || claimWasPurchased) &&
((autoplay && !videoOnPage && isPlayable) || RENDER_MODES.AUTO_RENDER_MODES.includes(renderMode))
((autoplay && (!videoOnPage || forceAutoplayParam) && isPlayable) ||
RENDER_MODES.AUTO_RENDER_MODES.includes(renderMode))
) {
viewFile();
}
}, [autoplay, viewFile, isFree, renderMode, isPlayable, claimWasPurchased]);
}, [autoplay, viewFile, isFree, renderMode, isPlayable, claimWasPurchased, forceAutoplayParam]);
/*
once content is playing, let the appropriate <FileRender> take care of it...

View file

@ -8,7 +8,13 @@ import {
makeSelectNextUrlForCollectionAndUrl,
makeSelectPreviousUrlForCollectionAndUrl,
} from 'lbry-redux';
import { doChangeVolume, doChangeMute, doAnalyticsView, doAnalyticsBuffer } from 'redux/actions/app';
import {
doChangeVolume,
doChangeMute,
doAnalyticsView,
doAnalyticsBuffer,
doAnaltyicsPurchaseEvent,
} from 'redux/actions/app';
import { selectVolume, selectMute } from 'redux/selectors/app';
import { savePosition, clearPosition, doPlayUri, doSetPlayingUri } from 'redux/actions/content';
import {
@ -78,8 +84,13 @@ const perform = (dispatch) => ({
toggleVideoTheaterMode: () => dispatch(toggleVideoTheaterMode()),
toggleAutoplayNext: () => dispatch(toggleAutoplayNext()),
setVideoPlaybackRate: (rate) => dispatch(doSetClientSetting(SETTINGS.VIDEO_PLAYBACK_RATE, rate)),
doPlayUri: (uri) => dispatch(doPlayUri(uri)),
doSetPlayingUri: (uri, collectionId) => dispatch(doSetPlayingUri({ uri, collectionId })),
doPlayUri: (uri, collectionId) =>
dispatch(
doPlayUri(uri, false, false, (fileInfo) => {
dispatch(doAnaltyicsPurchaseEvent(fileInfo));
dispatch(doSetPlayingUri({ uri, collectionId }));
})
),
});
export default withRouter(connect(select, perform)(VideoViewer));

View file

@ -25,8 +25,7 @@ import I18nMessage from 'component/i18nMessage';
import { useHistory } from 'react-router';
import { getAllIds } from 'util/buildHomepage';
import type { HomepageCat } from 'util/buildHomepage';
import { formatLbryUrlForWeb } from 'util/url';
import { COLLECTIONS_CONSTS } from 'lbry-redux';
import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
const PLAY_TIMEOUT_ERROR = 'play_timeout_error';
const PLAY_TIMEOUT_LIMIT = 2000;
@ -60,8 +59,7 @@ type Props = {
homepageData?: { [string]: HomepageCat },
shareTelemetry: boolean,
isFloating: boolean,
doPlayUri: (string) => void,
doSetPlayingUri: (string, string) => void,
doPlayUri: (string, string) => void,
collectionId: string,
nextRecommendedUri: string,
previousListUri: string,
@ -104,7 +102,6 @@ function VideoViewer(props: Props) {
shareTelemetry,
isFloating,
doPlayUri,
doSetPlayingUri,
collectionId,
nextRecommendedUri,
previousListUri,
@ -183,21 +180,20 @@ function VideoViewer(props: Props) {
const doPlay = useCallback(
(playUri) => {
let navigateUrl = formatLbryUrlForWeb(playUri);
if (collectionId) {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
navigateUrl = navigateUrl + `?` + collectionParams.toString();
clearPosition(playUri);
}
if (!isFloating) {
push(navigateUrl);
}
doPlayUri(playUri);
doSetPlayingUri(playUri, collectionId);
setDoNavigate(false);
const navigateUrl = formatLbryUrlForWeb(playUri);
if (collectionId) clearPosition(playUri);
if (!isFloating) {
push({
pathname: navigateUrl,
search: collectionId && generateListSearchUrlParams(collectionId),
state: { collectionId, forceAutoplay: true, hideFloatingPlayer: true },
});
} else {
doPlayUri(playUri, collectionId);
}
},
[clearPosition, collectionId, doPlayUri, doSetPlayingUri, isFloating, push]
[clearPosition, collectionId, doPlayUri, isFloating, push]
);
useEffect(() => {
@ -397,7 +393,6 @@ function VideoViewer(props: Props) {
>
{showAutoplayCountdown && (
<AutoplayCountdown
uri={uri}
nextRecommendedUri={nextRecommendedUri}
doNavigate={() => setDoNavigate(true)}
doReplay={() => setReplay(true)}

View file

@ -156,3 +156,9 @@ export const generateRssUrl = (domain, channelClaim) => {
const url = `${domain}/$/rss/${channelClaim.canonical_url.replace('lbry://', '').replace('#', ':')}`;
return url;
};
export const generateListSearchUrlParams = (collectionId) => {
const urlParams = new URLSearchParams();
urlParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
return `?` + urlParams.toString();
};