Add share buttons on channel page
This commit is contained in:
parent
239bde0752
commit
26d7e9a2b6
4 changed files with 60 additions and 24 deletions
|
@ -14,14 +14,15 @@ type Props = {
|
||||||
includeStartTime: boolean,
|
includeStartTime: boolean,
|
||||||
startTime: number,
|
startTime: number,
|
||||||
referralCode: ?string,
|
referralCode: ?string,
|
||||||
|
newestType?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function EmbedTextArea(props: Props) {
|
export default function EmbedTextArea(props: Props) {
|
||||||
const { doToast, snackMessage, label, claim, includeStartTime, startTime, referralCode } = props;
|
const { doToast, snackMessage, label, claim, includeStartTime, startTime, referralCode, newestType } = props;
|
||||||
const { claim_id: claimId, name } = claim;
|
const { claim_id: claimId, name } = claim;
|
||||||
const input = useRef();
|
const input = useRef();
|
||||||
|
|
||||||
const streamUrl = generateEmbedUrl(name, claimId, includeStartTime && startTime, referralCode);
|
const streamUrl = generateEmbedUrl(name, claimId, includeStartTime && startTime, referralCode, newestType);
|
||||||
const { html: embedText } = generateEmbedIframeData(streamUrl);
|
const { html: embedText } = generateEmbedIframeData(streamUrl);
|
||||||
|
|
||||||
function copyToClipboard() {
|
function copyToClipboard() {
|
||||||
|
|
|
@ -1,18 +1,26 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doFetchInviteStatus } from 'redux/actions/user';
|
import { doFetchInviteStatus } from 'redux/actions/user';
|
||||||
import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims';
|
import { selectClaimForUri, selectTitleForUri } from 'redux/selectors/claims';
|
||||||
import SocialShare from './view';
|
import SocialShare from './view';
|
||||||
import { selectUserInviteReferralCode, selectUser, selectUserInviteStatusFetched } from 'redux/selectors/user';
|
import { selectUserInviteReferralCode, selectUser, selectUserInviteStatusFetched } from 'redux/selectors/user';
|
||||||
import { selectContentPositionForUri } from 'redux/selectors/content';
|
import { selectContentPositionForUri } from 'redux/selectors/content';
|
||||||
|
import { selectActiveLivestreamForChannel } from 'redux/selectors/livestream';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => {
|
||||||
claim: makeSelectClaimForUri(props.uri)(state),
|
const { uri } = props;
|
||||||
|
const claim = selectClaimForUri(state, uri);
|
||||||
|
const { claim_id: claimId } = claim || {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
claim,
|
||||||
inviteStatusFetched: selectUserInviteStatusFetched(state),
|
inviteStatusFetched: selectUserInviteStatusFetched(state),
|
||||||
referralCode: selectUserInviteReferralCode(state),
|
referralCode: selectUserInviteReferralCode(state),
|
||||||
user: selectUser(state),
|
user: selectUser(state),
|
||||||
title: selectTitleForUri(state, props.uri),
|
title: selectTitleForUri(state, uri),
|
||||||
position: selectContentPositionForUri(state, props.uri),
|
position: selectContentPositionForUri(state, uri),
|
||||||
});
|
hasActiveLivestream: Boolean(selectActiveLivestreamForChannel(state, claimId)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const perform = {
|
const perform = {
|
||||||
doFetchInviteStatus,
|
doFetchInviteStatus,
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
import * as PAGES from 'constants/pages';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import CopyableText from 'component/copyableText';
|
import CopyableText from 'component/copyableText';
|
||||||
import EmbedTextArea from 'component/embedTextArea';
|
import EmbedTextArea from 'component/embedTextArea';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
import { generateDownloadUrl } from 'util/web';
|
import { generateDownloadUrl, generateNewestUrl } from 'util/web';
|
||||||
import { useIsMobile } from 'effects/use-screensize';
|
import { useIsMobile } from 'effects/use-screensize';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import { hmsToSeconds, secondsToHms } from 'util/time';
|
import { hmsToSeconds, secondsToHms } from 'util/time';
|
||||||
|
@ -28,6 +29,7 @@ type Props = {
|
||||||
user: any,
|
user: any,
|
||||||
position: number,
|
position: number,
|
||||||
collectionId?: number,
|
collectionId?: number,
|
||||||
|
hasActiveLivestream: boolean,
|
||||||
doFetchInviteStatus: (boolean) => void,
|
doFetchInviteStatus: (boolean) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,6 +43,7 @@ function SocialShare(props: Props) {
|
||||||
webShareable,
|
webShareable,
|
||||||
position,
|
position,
|
||||||
collectionId,
|
collectionId,
|
||||||
|
hasActiveLivestream,
|
||||||
doFetchInviteStatus,
|
doFetchInviteStatus,
|
||||||
} = props;
|
} = props;
|
||||||
const [showEmbed, setShowEmbed] = React.useState(false);
|
const [showEmbed, setShowEmbed] = React.useState(false);
|
||||||
|
@ -191,7 +194,7 @@ function SocialShare(props: Props) {
|
||||||
title={__('Share on Facebook')}
|
title={__('Share on Facebook')}
|
||||||
href={`https://facebook.com/sharer/sharer.php?u=${encodedLbryURL}`}
|
href={`https://facebook.com/sharer/sharer.php?u=${encodedLbryURL}`}
|
||||||
/>
|
/>
|
||||||
{webShareable && !isCollection && !isChannel && (
|
{webShareable && !isCollection && (
|
||||||
<Button
|
<Button
|
||||||
className="share"
|
className="share"
|
||||||
iconSize={24}
|
iconSize={24}
|
||||||
|
@ -220,7 +223,8 @@ function SocialShare(props: Props) {
|
||||||
<Button icon={ICONS.SHARE} button="primary" label={__('Share via...')} onClick={handleWebShareClick} />
|
<Button icon={ICONS.SHARE} button="primary" label={__('Share via...')} onClick={handleWebShareClick} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showEmbed && (
|
{showEmbed &&
|
||||||
|
(!isChannel ? (
|
||||||
<EmbedTextArea
|
<EmbedTextArea
|
||||||
label={__('Embedded')}
|
label={__('Embedded')}
|
||||||
claim={claim}
|
claim={claim}
|
||||||
|
@ -228,10 +232,23 @@ function SocialShare(props: Props) {
|
||||||
startTime={startTimeSeconds}
|
startTime={startTimeSeconds}
|
||||||
referralCode={referralCode}
|
referralCode={referralCode}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<EmbedTextArea label={__('Embedded Latest Video Content')} claim={claim} newestType={PAGES.LATEST} />
|
||||||
|
{hasActiveLivestream && (
|
||||||
|
<EmbedTextArea label={__('Embedded Current Livestream')} claim={claim} newestType={PAGES.LIVE_NOW} />
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
))}
|
||||||
{showClaimLinks && (
|
{showClaimLinks && (
|
||||||
<div className="section">
|
<div className="section">
|
||||||
{Boolean(isStream) && <CopyableText label={__('Download Link')} copyable={downloadUrl} />}
|
{Boolean(isStream) && <CopyableText label={__('Download Link')} copyable={downloadUrl} />}
|
||||||
|
{Boolean(isChannel) && (
|
||||||
|
<CopyableText label={__('Latest Content Link')} copyable={generateNewestUrl(name, PAGES.LATEST)} />
|
||||||
|
)}
|
||||||
|
{Boolean(isChannel) && hasActiveLivestream && (
|
||||||
|
<CopyableText label={__('Current Livestream Link')} copyable={generateNewestUrl(name, PAGES.LIVE_NOW)} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|
|
@ -2,7 +2,7 @@ const { URL, THUMBNAIL_CARDS_CDN_URL } = require('../../config');
|
||||||
|
|
||||||
const CONTINENT_COOKIE = 'continent';
|
const CONTINENT_COOKIE = 'continent';
|
||||||
|
|
||||||
function generateEmbedUrl(claimName, claimId, startTime, referralLink) {
|
function generateEmbedUrl(claimName, claimId, startTime, referralLink, newestType) {
|
||||||
let urlParams = new URLSearchParams();
|
let urlParams = new URLSearchParams();
|
||||||
|
|
||||||
if (startTime) {
|
if (startTime) {
|
||||||
|
@ -15,7 +15,12 @@ function generateEmbedUrl(claimName, claimId, startTime, referralLink) {
|
||||||
|
|
||||||
const encodedUriName = encodeURIComponent(claimName).replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
|
const encodedUriName = encodeURIComponent(claimName).replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
|
||||||
|
|
||||||
const embedUrl = `${URL}/$/embed/${escapeHtmlProperty(encodedUriName)}/${escapeHtmlProperty(claimId)}`;
|
let embedUrl;
|
||||||
|
if (newestType) {
|
||||||
|
embedUrl = `${URL}/$/embed/${escapeHtmlProperty(encodedUriName)}?feature=${newestType}`;
|
||||||
|
} else {
|
||||||
|
embedUrl = `${URL}/$/embed/${escapeHtmlProperty(encodedUriName)}/${escapeHtmlProperty(claimId)}`;
|
||||||
|
}
|
||||||
const embedUrlParams = urlParams.toString() ? `?${urlParams.toString()}` : '';
|
const embedUrlParams = urlParams.toString() ? `?${urlParams.toString()}` : '';
|
||||||
|
|
||||||
return `${embedUrl}${embedUrlParams}`;
|
return `${embedUrl}${embedUrlParams}`;
|
||||||
|
@ -41,6 +46,10 @@ function generateDirectUrl(claimName, claimId) {
|
||||||
return `${URL}/$/stream/${claimName}/${claimId}`;
|
return `${URL}/$/stream/${claimName}/${claimId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateNewestUrl(channelName, newestType) {
|
||||||
|
return `${URL}/$/${newestType}/${channelName}`;
|
||||||
|
}
|
||||||
|
|
||||||
function getThumbnailCdnUrl(url) {
|
function getThumbnailCdnUrl(url) {
|
||||||
if (
|
if (
|
||||||
!THUMBNAIL_CARDS_CDN_URL ||
|
!THUMBNAIL_CARDS_CDN_URL ||
|
||||||
|
@ -95,4 +104,5 @@ module.exports = {
|
||||||
getThumbnailCdnUrl,
|
getThumbnailCdnUrl,
|
||||||
escapeHtmlProperty,
|
escapeHtmlProperty,
|
||||||
unscapeHtmlProperty,
|
unscapeHtmlProperty,
|
||||||
|
generateNewestUrl,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue