use web share api
This commit is contained in:
parent
dbdef22f46
commit
27397285bc
4 changed files with 112 additions and 95 deletions
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { makeSelectClaimForUri } from 'lbry-redux';
|
import { makeSelectClaimForUri, makeSelectTitleForUri } from 'lbry-redux';
|
||||||
import SocialShare from './view';
|
import SocialShare from './view';
|
||||||
import { selectUserInviteReferralCode, selectUser } from 'lbryinc';
|
import { selectUserInviteReferralCode, selectUser } from 'lbryinc';
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ const select = (state, props) => ({
|
||||||
claim: makeSelectClaimForUri(props.uri)(state),
|
claim: makeSelectClaimForUri(props.uri)(state),
|
||||||
referralCode: selectUserInviteReferralCode(state),
|
referralCode: selectUserInviteReferralCode(state),
|
||||||
user: selectUser(state),
|
user: selectUser(state),
|
||||||
|
title: makeSelectTitleForUri(props.uri)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select)(SocialShare);
|
export default connect(select)(SocialShare);
|
||||||
|
|
|
@ -5,122 +5,130 @@ 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 { generateDownloadUrl } from 'util/lbrytv';
|
import { generateDownloadUrl } from 'util/lbrytv';
|
||||||
|
import useIsMobile from 'effects/use-is-mobile';
|
||||||
|
|
||||||
const IOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
|
const IOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
|
||||||
|
const SUPPORTS_SHARE_API = typeof navigator.share !== 'undefined';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
claim: Claim,
|
claim: StreamClaim,
|
||||||
|
title: ?string,
|
||||||
webShareable: boolean,
|
webShareable: boolean,
|
||||||
referralCode: string,
|
referralCode: string,
|
||||||
user: any,
|
user: any,
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
function SocialShare(props: Props) {
|
||||||
showEmbed: boolean,
|
const { claim, title, referralCode, user, webShareable } = props;
|
||||||
showExtra: boolean,
|
const [showEmbed, setShowEmbed] = React.useState(false);
|
||||||
};
|
const [showExtra, setShowExtra] = React.useState(false);
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
class SocialShare extends React.PureComponent<Props, State> {
|
if (!claim) {
|
||||||
constructor(props: Props) {
|
return null;
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
showEmbed: false,
|
|
||||||
showExtra: false,
|
|
||||||
};
|
|
||||||
this.input = undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input: ?HTMLInputElement;
|
const { canonical_url: canonicalUrl, permanent_url: permanentUrl, name, claim_id: claimId } = claim;
|
||||||
|
const isChannel = claim.value_type === 'channel';
|
||||||
|
const rewardsApproved = user && user.is_reward_approved;
|
||||||
|
const OPEN_URL = 'https://open.lbry.com/';
|
||||||
|
const lbryUrl = canonicalUrl ? canonicalUrl.split('lbry://')[1] : permanentUrl.split('lbry://')[1];
|
||||||
|
const lbryWebUrl = lbryUrl.replace(/#/g, ':');
|
||||||
|
const encodedLbryURL: string = `${OPEN_URL}${encodeURIComponent(lbryWebUrl)}`;
|
||||||
|
const referralParam: string = referralCode && rewardsApproved ? `?r=${referralCode}` : '';
|
||||||
|
const openDotLbryDotComUrl: string = `${OPEN_URL}${lbryWebUrl}${referralParam}`;
|
||||||
|
const downloadUrl = `${generateDownloadUrl(name, claimId)}`;
|
||||||
|
|
||||||
render() {
|
function handleWebShareClick() {
|
||||||
const { claim, referralCode, user, webShareable } = this.props;
|
if (navigator.share) {
|
||||||
const { showEmbed, showExtra } = this.state;
|
navigator.share({
|
||||||
|
title: title || claim.name,
|
||||||
if (!claim) {
|
url: window.location.href,
|
||||||
return null;
|
});
|
||||||
}
|
}
|
||||||
const { canonical_url: canonicalUrl, permanent_url: permanentUrl, name, claim_id: claimId } = claim;
|
}
|
||||||
const isChannel = claim.value_type === 'channel';
|
|
||||||
const rewardsApproved = user && user.is_reward_approved;
|
|
||||||
const OPEN_URL = 'https://open.lbry.com/';
|
|
||||||
const lbryUrl = canonicalUrl ? canonicalUrl.split('lbry://')[1] : permanentUrl.split('lbry://')[1];
|
|
||||||
const lbryWebUrl = lbryUrl.replace(/#/g, ':');
|
|
||||||
const encodedLbryURL: string = `${OPEN_URL}${encodeURIComponent(lbryWebUrl)}`;
|
|
||||||
const referralParam: string = referralCode && rewardsApproved ? `?r=${referralCode}` : '';
|
|
||||||
const openDotLbryDotComUrl: string = `${OPEN_URL}${lbryWebUrl}${referralParam}`;
|
|
||||||
const downloadUrl = `${generateDownloadUrl(name, claimId)}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<CopyableText label={__('LBRY Link')} copyable={openDotLbryDotComUrl} />
|
<CopyableText label={__('LBRY Link')} copyable={openDotLbryDotComUrl} />
|
||||||
<div className="section__actions">
|
<div className="section__actions">
|
||||||
|
<Button
|
||||||
|
className="share"
|
||||||
|
iconSize={24}
|
||||||
|
icon={ICONS.TWITTER}
|
||||||
|
href={`https://twitter.com/intent/tweet?text=${encodedLbryURL}`}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="share"
|
||||||
|
iconSize={24}
|
||||||
|
icon={ICONS.REDDIT}
|
||||||
|
title={__('Share on Facebook')}
|
||||||
|
href={`https://reddit.com/submit?url=${encodedLbryURL}`}
|
||||||
|
/>
|
||||||
|
{IOS && (
|
||||||
|
// Only ios client supports share urls
|
||||||
<Button
|
<Button
|
||||||
className="share"
|
className="share"
|
||||||
iconSize={24}
|
iconSize={24}
|
||||||
icon={ICONS.TWITTER}
|
icon={ICONS.TELEGRAM}
|
||||||
href={`https://twitter.com/intent/tweet?text=${encodedLbryURL}`}
|
title={__('Share on Telegram')}
|
||||||
|
href={`tg://msg_url?url=${encodedLbryURL}&text=text`}
|
||||||
/>
|
/>
|
||||||
<Button
|
)}
|
||||||
className="share"
|
<Button
|
||||||
iconSize={24}
|
className="share"
|
||||||
icon={ICONS.REDDIT}
|
iconSize={24}
|
||||||
title={__('Share on Facebook')}
|
icon={ICONS.LINKEDIN}
|
||||||
href={`https://reddit.com/submit?url=${encodedLbryURL}`}
|
title={__('Share on LinkedIn')}
|
||||||
/>
|
href={`https://www.linkedin.com/sharing/share-offsite/?url=${encodedLbryURL}`}
|
||||||
{IOS && (
|
/>
|
||||||
// Only ios client supports share urls
|
<Button
|
||||||
|
className="share"
|
||||||
|
iconSize={24}
|
||||||
|
icon={ICONS.FACEBOOK}
|
||||||
|
title={__('Share on Facebook')}
|
||||||
|
href={`https://facebook.com/sharer/sharer.php?u=${encodedLbryURL}`}
|
||||||
|
/>
|
||||||
|
{webShareable && !isChannel && (
|
||||||
|
<React.Fragment>
|
||||||
<Button
|
<Button
|
||||||
className="share"
|
className="share"
|
||||||
iconSize={24}
|
iconSize={24}
|
||||||
icon={ICONS.TELEGRAM}
|
icon={ICONS.EMBED}
|
||||||
title={__('Share on Telegram')}
|
title={__('Embed this content')}
|
||||||
href={`tg://msg_url?url=${encodedLbryURL}&text=text`}
|
onClick={() => {
|
||||||
|
setShowEmbed(!showEmbed);
|
||||||
|
setShowExtra(false);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
<Button
|
||||||
<Button
|
className="share"
|
||||||
className="share"
|
iconSize={24}
|
||||||
iconSize={24}
|
icon={ICONS.MORE}
|
||||||
icon={ICONS.LINKEDIN}
|
title={__('More actions')}
|
||||||
title={__('Share on LinkedIn')}
|
onClick={() => {
|
||||||
href={`https://www.linkedin.com/sharing/share-offsite/?url=${encodedLbryURL}`}
|
setShowExtra(!showExtra);
|
||||||
/>
|
setShowEmbed(false);
|
||||||
<Button
|
}}
|
||||||
className="share"
|
/>
|
||||||
iconSize={24}
|
</React.Fragment>
|
||||||
icon={ICONS.FACEBOOK}
|
|
||||||
title={__('Share on Facebook')}
|
|
||||||
href={`https://facebook.com/sharer/sharer.php?u=${encodedLbryURL}`}
|
|
||||||
/>
|
|
||||||
{webShareable && !isChannel && (
|
|
||||||
<React.Fragment>
|
|
||||||
<Button
|
|
||||||
className="share"
|
|
||||||
iconSize={24}
|
|
||||||
icon={ICONS.EMBED}
|
|
||||||
title={__('Embed this content')}
|
|
||||||
onClick={() => this.setState({ showEmbed: !showEmbed })}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
className="share"
|
|
||||||
iconSize={24}
|
|
||||||
icon={ICONS.MORE}
|
|
||||||
title={__('More actions')}
|
|
||||||
onClick={() => this.setState({ showExtra: !showExtra })}
|
|
||||||
/>
|
|
||||||
</React.Fragment>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{showEmbed && <EmbedTextArea label={__('Embedded')} claim={claim} />}
|
|
||||||
{showExtra && (
|
|
||||||
<div className="section">
|
|
||||||
<CopyableText label={__('LBRY URL')} copyable={`lbry://${lbryUrl}`} />
|
|
||||||
<CopyableText label={__('Download Link')} copyable={downloadUrl} />
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</div>
|
||||||
);
|
|
||||||
}
|
{SUPPORTS_SHARE_API && isMobile && (
|
||||||
|
<div className="section__actions">
|
||||||
|
<Button icon={ICONS.SHARE} button="primary" label={__('Share via...')} onClick={handleWebShareClick} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showEmbed && <EmbedTextArea label={__('Embedded')} claim={claim} />}
|
||||||
|
{showExtra && (
|
||||||
|
<div className="section">
|
||||||
|
<CopyableText label={__('LBRY URL')} copyable={`lbry://${lbryUrl}`} />
|
||||||
|
<CopyableText label={__('Download Link')} copyable={downloadUrl} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SocialShare;
|
export default SocialShare;
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
.ReactModal__Body--open {
|
||||||
|
#app {
|
||||||
|
height: 100vh;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.modal-overlay {
|
.modal-overlay {
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -35,6 +42,7 @@
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation {
|
.navigation {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
.share {
|
.share {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
.icon {
|
.icon {
|
||||||
height: 2.5rem;
|
height: 2.2rem;
|
||||||
width: 2.5rem;
|
width: 2.2rem;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue