lbry-desktop/ui/component/socialShare/view.jsx

263 lines
8.1 KiB
React
Raw Normal View History

2018-09-12 18:42:15 +02:00
// @flow
2018-11-26 02:21:25 +01:00
import * as ICONS from 'constants/icons';
2022-05-13 14:04:26 +02:00
import * as PAGES from 'constants/pages';
2018-11-26 02:21:25 +01:00
import React from 'react';
2018-09-12 18:42:15 +02:00
import Button from 'component/button';
2018-10-04 15:39:14 +02:00
import CopyableText from 'component/copyableText';
import EmbedTextArea from 'component/embedTextArea';
import Spinner from 'component/spinner';
2022-05-13 14:04:26 +02:00
import { generateDownloadUrl, generateNewestUrl } from 'util/web';
2020-08-10 22:47:39 +02:00
import { useIsMobile } from 'effects/use-screensize';
import { FormField } from 'component/common/form';
import { hmsToSeconds, secondsToHms } from 'util/time';
2022-05-13 19:05:04 +02:00
import {
generateLbryContentUrl,
generateLbryWebUrl,
generateEncodedLbryURL,
generateShareUrl,
generateRssUrl,
} from 'util/url';
2021-07-26 19:27:48 +02:00
import { URL, TWITTER_ACCOUNT, SHARE_DOMAIN_URL } from 'config';
2020-03-27 19:57:03 +01:00
2020-09-01 16:36:04 +02:00
const SHARE_DOMAIN = SHARE_DOMAIN_URL || URL;
2020-03-27 19:57:03 +01:00
const IOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
2020-03-30 21:43:27 +02:00
const SUPPORTS_SHARE_API = typeof navigator.share !== 'undefined';
2021-07-24 06:50:20 +02:00
// Twitter share
const TWITTER_INTENT_API = 'https://twitter.com/intent/tweet?';
2018-09-12 18:42:15 +02:00
type Props = {
2020-03-30 21:43:27 +02:00
claim: StreamClaim,
title: ?string,
2019-10-29 17:23:56 +01:00
webShareable: boolean,
inviteStatusFetched: boolean,
2020-01-14 21:44:07 +01:00
referralCode: string,
user: any,
position: number,
2021-06-10 20:23:25 +02:00
collectionId?: number,
doFetchInviteStatus: (boolean) => void,
2018-09-12 18:42:15 +02:00
};
2020-03-30 21:43:27 +02:00
function SocialShare(props: Props) {
const {
claim,
title,
inviteStatusFetched,
referralCode,
user,
webShareable,
position,
collectionId,
doFetchInviteStatus,
} = props;
2020-03-30 21:43:27 +02:00
const [showEmbed, setShowEmbed] = React.useState(false);
2021-06-10 20:23:25 +02:00
const [includeCollectionId, setIncludeCollectionId] = React.useState(Boolean(collectionId)); // unless it *is* a collection?
const [showClaimLinks, setShowClaimLinks] = React.useState(false);
const [includeStartTime, setincludeStartTime]: [boolean, any] = React.useState(false);
const [startTime, setStartTime]: [string, any] = React.useState(secondsToHms(position));
2020-05-07 21:41:20 +02:00
const startTimeSeconds: number = hmsToSeconds(startTime);
2020-03-30 21:43:27 +02:00
const isMobile = useIsMobile();
2018-09-12 18:42:15 +02:00
React.useEffect(() => {
if (!inviteStatusFetched) {
doFetchInviteStatus(false);
}
}, [inviteStatusFetched, doFetchInviteStatus]);
2020-05-07 21:41:20 +02:00
if (!claim) {
return null;
} else if (!inviteStatusFetched) {
return (
<div className="main--empty">
<Spinner />
</div>
);
2018-09-12 18:42:15 +02:00
}
2020-05-07 21:41:20 +02:00
const { canonical_url: canonicalUrl, permanent_url: permanentUrl, name, claim_id: claimId } = claim;
2020-03-30 21:43:27 +02:00
const isChannel = claim.value_type === 'channel';
2021-06-16 21:26:28 +02:00
const isCollection = claim.value_type === 'collection';
const isStream = claim.value_type === 'stream';
const isVideo = isStream && claim.value.stream_type === 'video';
const isAudio = isStream && claim.value.stream_type === 'audio';
const showStartAt = isVideo || isAudio;
2020-03-30 21:43:27 +02:00
const rewardsApproved = user && user.is_reward_approved;
2020-05-07 21:41:20 +02:00
const lbryUrl: string = generateLbryContentUrl(canonicalUrl, permanentUrl);
const lbryWebUrl: string = generateLbryWebUrl(lbryUrl);
2022-05-13 19:05:04 +02:00
const rssUrl = isChannel && generateRssUrl(SHARE_DOMAIN, claim);
2021-06-10 20:23:25 +02:00
const includedCollectionId = collectionId && includeCollectionId ? collectionId : null;
const encodedLbryURL: string = generateEncodedLbryURL(
SHARE_DOMAIN,
lbryWebUrl,
includeStartTime,
startTimeSeconds,
includedCollectionId
);
2020-08-29 19:58:38 +02:00
const shareUrl: string = generateShareUrl(
2020-09-01 16:36:04 +02:00
SHARE_DOMAIN,
2021-01-13 22:39:46 +01:00
lbryUrl,
2020-05-07 21:41:20 +02:00
referralCode,
rewardsApproved,
includeStartTime,
2021-06-10 20:23:25 +02:00
startTimeSeconds,
includedCollectionId
);
2020-03-30 21:43:27 +02:00
const downloadUrl = `${generateDownloadUrl(name, claimId)}`;
2018-09-12 18:42:15 +02:00
2021-07-24 06:50:20 +02:00
// Tweet params
let tweetIntentParams = {
url: shareUrl,
text: title || claim.name,
2022-04-15 02:31:16 +02:00
hashtags: 'Odysee',
2021-07-24 06:50:20 +02:00
};
2021-07-26 19:27:48 +02:00
if (TWITTER_ACCOUNT) {
// $FlowFixMe
tweetIntentParams.via = TWITTER_ACCOUNT;
}
2021-07-24 06:50:20 +02:00
// Generate twitter web intent url
const tweetIntent = TWITTER_INTENT_API + new URLSearchParams(tweetIntentParams).toString();
2020-03-30 21:43:27 +02:00
function handleWebShareClick() {
if (navigator.share) {
navigator.share({
title: title || claim.name,
url: window.location.href,
});
2020-03-27 19:57:03 +01:00
}
2020-03-30 21:43:27 +02:00
}
2018-10-04 15:39:14 +02:00
2020-03-30 21:43:27 +02:00
return (
<React.Fragment>
2020-08-29 19:58:38 +02:00
<CopyableText copyable={shareUrl} />
{showStartAt && (
2021-06-10 20:23:25 +02:00
<div className="section__checkbox">
<FormField
type="checkbox"
name="share_start_at_checkbox"
onChange={() => setincludeStartTime(!includeStartTime)}
checked={includeStartTime}
label={__('Start at')}
/>
<FormField
type="text"
name="share_start_at"
value={startTime}
disabled={!includeStartTime}
wip wip wip - everything but publish, autoplay, and styling collection publishing add channel to collection publish cleanup wip bump clear mass add after success move collection item management controls redirect replace to published collection id bump playlist selector on create bump use new collection add ui element bump wip gitignore add content json wip bump context add to playlist basic collections page style pass wip wip: edits, buttons, styles... change fileAuthor to claimAuthor update, pending bugfixes, delete modal progress, collection header, other bugfixes bump cleaning show page bugfix builtin collection headers no playlists, no grid title wip style tweaks use normal looking claim previews for collection tiles add collection changes style library previews collection menulist for delete/view on library delete modal works for unpublished rearrange collection publish tabs clean up collection publishing and items show on odysee begin collectoin edit header and css renaming better thumbnails bump fix collection publish redirect view collection in menu does something copy and thumbs list previews, pending, context menus, list page enter to add collection, lists page empty state playable lists only, delete feature, bump put fileListDownloaded back better collection titles improve collection claim details fix horiz more icon fix up channel page style, copy, bump refactor preview overlay properties, fix reposts showing as floppydisk add watch later toast, small overlay properties on wunderbar results, fix collection actions buttons bump cleanup cleaning, refactoring bump preview thumb styling, cleanup support discover page lists search sync, bump bump, fix sync more enforce builtin order for now new lists page empty state try to indicate unpublished edits in lists bump fix autoplay and linting consts, fix autoplay bugs fixes cleanup fix, bump lists experimental ui, fixes refactor listIndex out hack in collection fallback thumb bump
2021-02-06 08:03:51 +01:00
onChange={(event) => setStartTime(event.target.value)}
/>
</div>
)}
2021-06-10 20:23:25 +02:00
{Boolean(collectionId) && (
<div className="section__checkbox">
<FormField
type="checkbox"
name="share_collection_id_checkbox"
onChange={() => setIncludeCollectionId(!includeCollectionId)}
checked={includeCollectionId}
label={__('Include List ID')}
/>
</div>
)}
2020-03-30 21:43:27 +02:00
<div className="section__actions">
<Button
className="share"
iconSize={24}
icon={ICONS.TWITTER}
2021-06-09 16:22:29 +02:00
title={__('Share on Twitter')}
2021-07-24 06:50:20 +02:00
href={tweetIntent}
2020-03-30 21:43:27 +02:00
/>
<Button
className="share"
iconSize={24}
icon={ICONS.REDDIT}
2021-06-09 16:22:29 +02:00
title={__('Share on Reddit')}
2020-03-30 21:43:27 +02:00
href={`https://reddit.com/submit?url=${encodedLbryURL}`}
/>
{IOS && (
// Only ios client supports share urls
2020-03-27 19:57:03 +01:00
<Button
className="share"
iconSize={24}
2020-03-30 21:43:27 +02:00
icon={ICONS.TELEGRAM}
title={__('Share on Telegram')}
href={`tg://msg_url?url=${encodedLbryURL}&amp;text=text`}
2020-03-27 19:57:03 +01:00
/>
2020-03-30 21:43:27 +02:00
)}
<Button
className="share"
iconSize={24}
icon={ICONS.LINKEDIN}
title={__('Share on LinkedIn')}
href={`https://www.linkedin.com/sharing/share-offsite/?url=${encodedLbryURL}`}
/>
<Button
className="share"
iconSize={24}
icon={ICONS.FACEBOOK}
title={__('Share on Facebook')}
href={`https://facebook.com/sharer/sharer.php?u=${encodedLbryURL}`}
/>
2022-05-13 14:04:26 +02:00
{webShareable && !isCollection && (
<Button
className="share"
iconSize={24}
icon={ICONS.EMBED}
title={__('Embed this content')}
onClick={() => {
setShowEmbed(!showEmbed);
setShowClaimLinks(false);
}}
/>
2020-03-27 19:57:03 +01:00
)}
<Button
className="share"
iconSize={24}
icon={ICONS.SHARE_LINK}
title={__('Links')}
onClick={() => {
setShowClaimLinks(!showClaimLinks);
setShowEmbed(false);
}}
/>
2020-03-30 21:43:27 +02:00
</div>
{SUPPORTS_SHARE_API && isMobile && (
<div className="section__actions">
<Button icon={ICONS.SHARE} button="primary" label={__('Share via...')} onClick={handleWebShareClick} />
</div>
)}
2022-05-13 14:04:26 +02:00
{showEmbed &&
(!isChannel ? (
<EmbedTextArea
label={__('Embedded')}
claim={claim}
includeStartTime={includeStartTime}
startTime={startTimeSeconds}
referralCode={referralCode}
/>
) : (
<>
<EmbedTextArea label={__('Embedded Latest Video Content')} claim={claim} newestType={PAGES.LATEST} />
<EmbedTextArea label={__('Embedded Current Livestream')} claim={claim} newestType={PAGES.LIVE_NOW} />
2022-05-13 14:04:26 +02:00
</>
))}
{showClaimLinks && (
2020-03-30 21:43:27 +02:00
<div className="section">
wip wip wip - everything but publish, autoplay, and styling collection publishing add channel to collection publish cleanup wip bump clear mass add after success move collection item management controls redirect replace to published collection id bump playlist selector on create bump use new collection add ui element bump wip gitignore add content json wip bump context add to playlist basic collections page style pass wip wip: edits, buttons, styles... change fileAuthor to claimAuthor update, pending bugfixes, delete modal progress, collection header, other bugfixes bump cleaning show page bugfix builtin collection headers no playlists, no grid title wip style tweaks use normal looking claim previews for collection tiles add collection changes style library previews collection menulist for delete/view on library delete modal works for unpublished rearrange collection publish tabs clean up collection publishing and items show on odysee begin collectoin edit header and css renaming better thumbnails bump fix collection publish redirect view collection in menu does something copy and thumbs list previews, pending, context menus, list page enter to add collection, lists page empty state playable lists only, delete feature, bump put fileListDownloaded back better collection titles improve collection claim details fix horiz more icon fix up channel page style, copy, bump refactor preview overlay properties, fix reposts showing as floppydisk add watch later toast, small overlay properties on wunderbar results, fix collection actions buttons bump cleanup cleaning, refactoring bump preview thumb styling, cleanup support discover page lists search sync, bump bump, fix sync more enforce builtin order for now new lists page empty state try to indicate unpublished edits in lists bump fix autoplay and linting consts, fix autoplay bugs fixes cleanup fix, bump lists experimental ui, fixes refactor listIndex out hack in collection fallback thumb bump
2021-02-06 08:03:51 +01:00
{Boolean(isStream) && <CopyableText label={__('Download Link')} copyable={downloadUrl} />}
2022-05-13 19:05:04 +02:00
{Boolean(rssUrl) && <CopyableText label={__('RSS Url')} copyable={rssUrl} />}
2022-05-13 14:04:26 +02:00
{Boolean(isChannel) && (
<>
<CopyableText label={__('Latest Content Link')} copyable={generateNewestUrl(name, PAGES.LATEST)} />
<CopyableText label={__('Current Livestream Link')} copyable={generateNewestUrl(name, PAGES.LIVE_NOW)} />
</>
2022-05-13 14:04:26 +02:00
)}
2020-03-30 21:43:27 +02:00
</div>
)}
</React.Fragment>
);
2018-09-12 18:42:15 +02:00
}
export default SocialShare;