diff --git a/ui/component/socialShare/index.js b/ui/component/socialShare/index.js index 6e87e2548..b91dcdd6c 100644 --- a/ui/component/socialShare/index.js +++ b/ui/component/socialShare/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri } from 'lbry-redux'; +import { makeSelectClaimForUri, makeSelectTitleForUri } from 'lbry-redux'; import SocialShare from './view'; import { selectUserInviteReferralCode, selectUser } from 'lbryinc'; @@ -7,6 +7,7 @@ const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), referralCode: selectUserInviteReferralCode(state), user: selectUser(state), + title: makeSelectTitleForUri(props.uri)(state), }); export default connect(select)(SocialShare); diff --git a/ui/component/socialShare/view.jsx b/ui/component/socialShare/view.jsx index 88ce24946..c403abb5b 100644 --- a/ui/component/socialShare/view.jsx +++ b/ui/component/socialShare/view.jsx @@ -5,122 +5,130 @@ import Button from 'component/button'; import CopyableText from 'component/copyableText'; import EmbedTextArea from 'component/embedTextArea'; import { generateDownloadUrl } from 'util/lbrytv'; +import useIsMobile from 'effects/use-is-mobile'; const IOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform); +const SUPPORTS_SHARE_API = typeof navigator.share !== 'undefined'; type Props = { - claim: Claim, + claim: StreamClaim, + title: ?string, webShareable: boolean, referralCode: string, user: any, }; -type State = { - showEmbed: boolean, - showExtra: boolean, -}; +function SocialShare(props: Props) { + const { claim, title, referralCode, user, webShareable } = props; + const [showEmbed, setShowEmbed] = React.useState(false); + const [showExtra, setShowExtra] = React.useState(false); + const isMobile = useIsMobile(); -class SocialShare extends React.PureComponent<Props, State> { - constructor(props: Props) { - super(props); - - this.state = { - showEmbed: false, - showExtra: false, - }; - this.input = undefined; + if (!claim) { + return null; } - 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() { - const { claim, referralCode, user, webShareable } = this.props; - const { showEmbed, showExtra } = this.state; - - if (!claim) { - return null; + function handleWebShareClick() { + if (navigator.share) { + navigator.share({ + title: title || claim.name, + url: window.location.href, + }); } - 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 ( - <React.Fragment> - <CopyableText label={__('LBRY Link')} copyable={openDotLbryDotComUrl} /> - <div className="section__actions"> + return ( + <React.Fragment> + <CopyableText label={__('LBRY Link')} copyable={openDotLbryDotComUrl} /> + <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 className="share" iconSize={24} - icon={ICONS.TWITTER} - href={`https://twitter.com/intent/tweet?text=${encodedLbryURL}`} + icon={ICONS.TELEGRAM} + title={__('Share on Telegram')} + href={`tg://msg_url?url=${encodedLbryURL}&text=text`} /> - <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 + 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}`} + /> + {webShareable && !isChannel && ( + <React.Fragment> <Button className="share" iconSize={24} - icon={ICONS.TELEGRAM} - title={__('Share on Telegram')} - href={`tg://msg_url?url=${encodedLbryURL}&text=text`} + icon={ICONS.EMBED} + title={__('Embed this content')} + onClick={() => { + setShowEmbed(!showEmbed); + setShowExtra(false); + }} /> - )} - <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}`} - /> - {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> + <Button + className="share" + iconSize={24} + icon={ICONS.MORE} + title={__('More actions')} + onClick={() => { + setShowExtra(!showExtra); + setShowEmbed(false); + }} + /> + </React.Fragment> )} - </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; diff --git a/ui/scss/component/_modal.scss b/ui/scss/component/_modal.scss index 92a675c1d..51295e915 100644 --- a/ui/scss/component/_modal.scss +++ b/ui/scss/component/_modal.scss @@ -1,3 +1,10 @@ +.ReactModal__Body--open { + #app { + height: 100vh; + overflow-y: hidden; + } +} + .modal-overlay { top: 0; left: 0; @@ -35,6 +42,7 @@ .card { box-shadow: none; + border: none; } .navigation { diff --git a/ui/scss/component/_share.scss b/ui/scss/component/_share.scss index f11da5a08..70b22dc78 100644 --- a/ui/scss/component/_share.scss +++ b/ui/scss/component/_share.scss @@ -1,8 +1,8 @@ .share { border-radius: 50%; .icon { - height: 2.5rem; - width: 2.5rem; + height: 2.2rem; + width: 2.2rem; stroke: none; }