Merge pull request #1989 from jessopb/expandedShare
adds open.lbry.io links to socialShare Re: Issue # 1810
This commit is contained in:
commit
a895617342
6 changed files with 155 additions and 44 deletions
10
src/renderer/component/copyableText/index.js
Normal file
10
src/renderer/component/copyableText/index.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doNotify } from 'lbry-redux';
|
||||||
|
import CopyableText from './view';
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
doNotify,
|
||||||
|
}
|
||||||
|
)(CopyableText);
|
63
src/renderer/component/copyableText/view.jsx
Normal file
63
src/renderer/component/copyableText/view.jsx
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react';
|
||||||
|
import { clipboard } from 'electron';
|
||||||
|
import { FormRow } from 'component/common/form';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import * as icons from 'constants/icons';
|
||||||
|
/*
|
||||||
|
noSnackbar added due to issue 1945
|
||||||
|
https://github.com/lbryio/lbry-desktop/issues/1945
|
||||||
|
"Snackbars and modals can't be displayed at the same time"
|
||||||
|
*/
|
||||||
|
type Props = {
|
||||||
|
copyable: string,
|
||||||
|
noSnackbar: boolean,
|
||||||
|
doNotify: ({ message: string, displayType: Array<string> }) => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class CopyableText extends React.PureComponent<Props> {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.input = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
input: ?HTMLInputElement;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { copyable, doNotify, noSnackbar } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormRow verticallyCentered padded stretch>
|
||||||
|
<input
|
||||||
|
className="input-copyable form-field__input"
|
||||||
|
readOnly
|
||||||
|
value={copyable || ''}
|
||||||
|
ref={input => {
|
||||||
|
this.input = input;
|
||||||
|
}}
|
||||||
|
onFocus={() => {
|
||||||
|
if (this.input) {
|
||||||
|
this.input.select();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
noPadding
|
||||||
|
button="secondary"
|
||||||
|
icon={icons.CLIPBOARD}
|
||||||
|
onClick={() => {
|
||||||
|
clipboard.writeText(copyable);
|
||||||
|
if (!noSnackbar) {
|
||||||
|
doNotify({
|
||||||
|
message: __('Text copied'),
|
||||||
|
displayType: ['snackbar'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,13 @@ import React from 'react';
|
||||||
import type { Claim } from 'types/claim';
|
import type { Claim } from 'types/claim';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
import Tooltip from 'component/common/tooltip';
|
import CopyableText from 'component/copyableText';
|
||||||
import Address from 'component/address';
|
import ToolTip from 'component/common/tooltip';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
claim: Claim,
|
claim: Claim,
|
||||||
onDone: () => void,
|
onDone: () => void,
|
||||||
|
speechShareable: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
class SocialShare extends React.PureComponent<Props> {
|
class SocialShare extends React.PureComponent<Props> {
|
||||||
|
@ -27,46 +28,79 @@ class SocialShare extends React.PureComponent<Props> {
|
||||||
channel_name: channelName,
|
channel_name: channelName,
|
||||||
value,
|
value,
|
||||||
} = this.props.claim;
|
} = this.props.claim;
|
||||||
|
const { speechShareable, onDone } = this.props;
|
||||||
const channelClaimId =
|
const channelClaimId =
|
||||||
value && value.publisherSignature && value.publisherSignature.certificateId;
|
value && value.publisherSignature && value.publisherSignature.certificateId;
|
||||||
const { onDone } = this.props;
|
|
||||||
const speechPrefix = 'http://spee.ch/';
|
const speechPrefix = 'http://spee.ch/';
|
||||||
|
const lbryPrefix = 'http://open.lbry.io/';
|
||||||
|
|
||||||
const speechURL =
|
const speechURL =
|
||||||
channelName && channelClaimId
|
channelName && channelClaimId
|
||||||
? `${speechPrefix}${channelName}:${channelClaimId}/${claimName}`
|
? `${speechPrefix}${channelName}:${channelClaimId}/${claimName}`
|
||||||
: `${speechPrefix}${claimName}#${claimId}`;
|
: `${speechPrefix}${claimName}#${claimId}`;
|
||||||
|
|
||||||
|
const lbryURL = `${lbryPrefix}${claimName}#${claimId}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="card__content">
|
<section className="card__content">
|
||||||
<Address address={speechURL} noSnackbar />
|
{speechShareable && (
|
||||||
<div className="card__actions card__actions--center">
|
<div className="card__content">
|
||||||
<Tooltip onComponent body={__('Facebook')}>
|
<label className="card__subtitle">{__('Web link')}</label>
|
||||||
<Button
|
<CopyableText copyable={speechURL} noSnackbar />
|
||||||
iconColor="blue"
|
<div className="card__actions card__actions--center">
|
||||||
icon={icons.FACEBOOK}
|
<ToolTip onComponent body={__('Facebook')}>
|
||||||
button="alt"
|
<Button
|
||||||
label={__('')}
|
iconColor="blue"
|
||||||
href={`https://facebook.com/sharer/sharer.php?u=${speechURL}`}
|
icon={icons.FACEBOOK}
|
||||||
/>
|
button="alt"
|
||||||
</Tooltip>
|
label={__('')}
|
||||||
<Tooltip onComponent body={__('Twitter')}>
|
href={`https://facebook.com/sharer/sharer.php?u=${speechURL}`}
|
||||||
<Button
|
/>
|
||||||
iconColor="blue"
|
</ToolTip>
|
||||||
icon={icons.TWITTER}
|
<ToolTip onComponent body={__('Twitter')}>
|
||||||
button="alt"
|
<Button
|
||||||
label={__('')}
|
iconColor="blue"
|
||||||
href={`https://twitter.com/home?status=${speechURL}`}
|
icon={icons.TWITTER}
|
||||||
/>
|
button="alt"
|
||||||
</Tooltip>
|
label={__('')}
|
||||||
<Tooltip onComponent body={__('View on Spee.ch')}>
|
href={`https://twitter.com/home?status=${speechURL}`}
|
||||||
<Button
|
/>
|
||||||
icon={icons.GLOBE}
|
</ToolTip>
|
||||||
iconColor="blue"
|
<ToolTip onComponent body={__('View on Spee.ch')}>
|
||||||
button="alt"
|
<Button
|
||||||
label={__('')}
|
icon={icons.GLOBE}
|
||||||
href={`${speechURL}`}
|
iconColor="blue"
|
||||||
/>
|
button="alt"
|
||||||
</Tooltip>
|
label={__('')}
|
||||||
|
href={`${speechURL}`}
|
||||||
|
/>
|
||||||
|
</ToolTip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="card__content">
|
||||||
|
<label className="card__subtitle">{__('LBRY App link')}</label>
|
||||||
|
<CopyableText copyable={lbryURL} noSnackbar />
|
||||||
|
<div className="card__actions card__actions--center">
|
||||||
|
<ToolTip onComponent body={__('Facebook')}>
|
||||||
|
<Button
|
||||||
|
iconColor="blue"
|
||||||
|
icon={icons.FACEBOOK}
|
||||||
|
button="alt"
|
||||||
|
label={__('')}
|
||||||
|
href={`https://facebook.com/sharer/sharer.php?u=${lbryURL}`}
|
||||||
|
/>
|
||||||
|
</ToolTip>
|
||||||
|
<ToolTip onComponent body={__('Twitter')}>
|
||||||
|
<Button
|
||||||
|
iconColor="blue"
|
||||||
|
icon={icons.TWITTER}
|
||||||
|
button="alt"
|
||||||
|
label={__('')}
|
||||||
|
href={`https://twitter.com/home?status=${lbryURL}`}
|
||||||
|
/>
|
||||||
|
</ToolTip>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Button button="link" label={__('Done')} onClick={onDone} />
|
<Button button="link" label={__('Done')} onClick={onDone} />
|
||||||
|
|
|
@ -6,14 +6,15 @@ import SocialShare from 'component/socialShare';
|
||||||
type Props = {
|
type Props = {
|
||||||
closeModal: () => void,
|
closeModal: () => void,
|
||||||
uri: string,
|
uri: string,
|
||||||
|
speechShareable: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModalSocialShare extends React.PureComponent<Props> {
|
class ModalSocialShare extends React.PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { closeModal, uri } = this.props;
|
const { closeModal, uri, speechShareable } = this.props;
|
||||||
return (
|
return (
|
||||||
<Modal isOpen onAborted={closeModal} type="custom" title={__('Share')}>
|
<Modal isOpen onAborted={closeModal} type="custom" title={__('Share')}>
|
||||||
<SocialShare uri={uri} onDone={closeModal} />
|
<SocialShare uri={uri} onDone={closeModal} speechShareable={speechShareable} />
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,12 +145,11 @@ class FilePage extends React.Component<Props> {
|
||||||
if (channelName && channelClaimId) {
|
if (channelName && channelClaimId) {
|
||||||
subscriptionUri = buildURI({ channelName, claimId: channelClaimId }, false);
|
subscriptionUri = buildURI({ channelName, claimId: channelClaimId }, false);
|
||||||
}
|
}
|
||||||
const speechSharable =
|
const speechShareable =
|
||||||
costInfo &&
|
costInfo &&
|
||||||
costInfo.cost === 0 &&
|
costInfo.cost === 0 &&
|
||||||
contentType &&
|
contentType &&
|
||||||
['video', 'image'].includes(contentType.split('/')[0]);
|
['video', 'image'].includes(contentType.split('/')[0]);
|
||||||
|
|
||||||
// We want to use the short form uri for editing
|
// We want to use the short form uri for editing
|
||||||
// This is what the user is used to seeing, they don't care about the claim id
|
// This is what the user is used to seeing, they don't care about the claim id
|
||||||
// We will select the claim id before they publish
|
// We will select the claim id before they publish
|
||||||
|
@ -222,14 +221,17 @@ class FilePage extends React.Component<Props> {
|
||||||
onClick={() => openModal({ id: MODALS.SEND_TIP }, { uri })}
|
onClick={() => openModal({ id: MODALS.SEND_TIP }, { uri })}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{speechSharable && (
|
<Button
|
||||||
<Button
|
button="alt"
|
||||||
button="alt"
|
icon={icons.GLOBE}
|
||||||
icon={icons.GLOBE}
|
label={__('Share')}
|
||||||
label={__('Share')}
|
onClick={() =>
|
||||||
onClick={() => openModal({ id: MODALS.SOCIAL_SHARE }, { uri })}
|
openModal(
|
||||||
/>
|
{ id: MODALS.SOCIAL_SHARE },
|
||||||
)}
|
{ uri, speechShareable: speechShareable }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
|
|
|
@ -92,6 +92,7 @@ input {
|
||||||
color: var(--input-copyable-color);
|
color: var(--input-copyable-color);
|
||||||
padding: 10px 16px;
|
padding: 10px 16px;
|
||||||
border: 1px dashed var(--input-copyable-border);
|
border: 1px dashed var(--input-copyable-border);
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.input-copyable):not(.wunderbar__input):not(:placeholder-shown):not(:disabled) {
|
&:not(.input-copyable):not(.wunderbar__input):not(:placeholder-shown):not(:disabled) {
|
||||||
|
|
Loading…
Reference in a new issue