Modal repost (#7341)
* make repost into a modal * remove unecessary import * removed page/repost * fixed yarn lint errors * added page/repost back * added "Repost" title bar * fixed yarn lint errors
This commit is contained in:
parent
6fed123253
commit
e5072c8681
8 changed files with 123 additions and 38 deletions
6
ui/component/claimRepostButton/index.js
Normal file
6
ui/component/claimRepostButton/index.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doOpenModal } from 'redux/actions/app';
|
||||||
|
import { doToast } from 'redux/actions/notifications';
|
||||||
|
import ClaimReportButton from './view';
|
||||||
|
|
||||||
|
export default connect(null, { doOpenModal, doToast })(ClaimReportButton);
|
44
ui/component/claimRepostButton/view.jsx
Normal file
44
ui/component/claimRepostButton/view.jsx
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// @flow
|
||||||
|
import { SITE_NAME } from 'config';
|
||||||
|
import * as MODALS from 'constants/modal_types';
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
|
import React from 'react';
|
||||||
|
import Button from 'component/button';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
uri: string,
|
||||||
|
claim: StreamClaim,
|
||||||
|
hasChannels: boolean,
|
||||||
|
doOpenModal: (string, {}) => void,
|
||||||
|
doToast: ({ message: string }) => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ClaimRepostButton(props: Props) {
|
||||||
|
const { uri, claim, hasChannels, doOpenModal, doToast } = props;
|
||||||
|
const [contentUri, setContentUri] = React.useState('');
|
||||||
|
const [repostUri, setRepostUri] = React.useState('');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
button="alt"
|
||||||
|
className="button--file-action"
|
||||||
|
icon={ICONS.REPOST}
|
||||||
|
label={
|
||||||
|
claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost')
|
||||||
|
}
|
||||||
|
description={__('Repost')}
|
||||||
|
requiresAuth={IS_WEB}
|
||||||
|
onClick={() => {
|
||||||
|
if (!hasChannels) {
|
||||||
|
doToast({
|
||||||
|
message: __('A channel is required to repost on %SITE_NAME%', { SITE_NAME }),
|
||||||
|
linkText: __('Create Channel'),
|
||||||
|
linkTarget: '/channel/new',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
doOpenModal(MODALS.REPOST, { uri, contentUri, setContentUri, repostUri, setRepostUri, isModal: true });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { SITE_NAME, ENABLE_FILE_REACTIONS } from 'config';
|
import { ENABLE_FILE_REACTIONS } from 'config';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
@ -16,6 +16,7 @@ import { useHistory } from 'react-router';
|
||||||
import FileReactions from 'component/fileReactions';
|
import FileReactions from 'component/fileReactions';
|
||||||
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
|
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
|
import ClaimRepostButton from 'component/claimRepostButton';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -27,8 +28,6 @@ type Props = {
|
||||||
costInfo: ?{ cost: number },
|
costInfo: ?{ cost: number },
|
||||||
renderMode: string,
|
renderMode: string,
|
||||||
myChannels: ?Array<ChannelClaim>,
|
myChannels: ?Array<ChannelClaim>,
|
||||||
doToast: ({ message: string }) => void,
|
|
||||||
clearPlayingUri: () => void,
|
|
||||||
hideRepost?: boolean,
|
hideRepost?: boolean,
|
||||||
reactionsDisabled: boolean,
|
reactionsDisabled: boolean,
|
||||||
download: (string) => void,
|
download: (string) => void,
|
||||||
|
@ -46,14 +45,12 @@ function FileActions(props: Props) {
|
||||||
renderMode,
|
renderMode,
|
||||||
prepareEdit,
|
prepareEdit,
|
||||||
myChannels,
|
myChannels,
|
||||||
clearPlayingUri,
|
|
||||||
doToast,
|
|
||||||
hideRepost,
|
hideRepost,
|
||||||
reactionsDisabled,
|
reactionsDisabled,
|
||||||
} = props;
|
} = props;
|
||||||
const {
|
const {
|
||||||
push,
|
push,
|
||||||
location: { pathname, search },
|
location: { search },
|
||||||
} = useHistory();
|
} = useHistory();
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const webShareable = costInfo && costInfo.cost === 0 && RENDER_MODES.WEB_SHAREABLE_MODES.includes(renderMode);
|
const webShareable = costInfo && costInfo.cost === 0 && RENDER_MODES.WEB_SHAREABLE_MODES.includes(renderMode);
|
||||||
|
@ -82,33 +79,13 @@ function FileActions(props: Props) {
|
||||||
const urlParams = new URLSearchParams(search);
|
const urlParams = new URLSearchParams(search);
|
||||||
const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID);
|
const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID);
|
||||||
|
|
||||||
function handleRepostClick() {
|
|
||||||
if (!hasChannels) {
|
|
||||||
clearPlayingUri();
|
|
||||||
push(`/$/${PAGES.CHANNEL_NEW}?redirect=${pathname}`);
|
|
||||||
doToast({ message: __('A channel is required to repost on %SITE_NAME%', { SITE_NAME }) });
|
|
||||||
} else {
|
|
||||||
push(`/$/${PAGES.REPOST_NEW}?from=${encodeURIComponent(uri)}&redirect=${pathname}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lhsSection = (
|
const lhsSection = (
|
||||||
<>
|
<>
|
||||||
{ENABLE_FILE_REACTIONS && !reactionsDisabled && <FileReactions uri={uri} />}
|
{ENABLE_FILE_REACTIONS && !reactionsDisabled && <FileReactions uri={uri} />}
|
||||||
<ClaimSupportButton uri={uri} fileAction />
|
<ClaimSupportButton uri={uri} fileAction />
|
||||||
<ClaimCollectionAddButton uri={uri} fileAction />
|
<ClaimCollectionAddButton uri={uri} fileAction />
|
||||||
{!hideRepost && (
|
{!hideRepost && (
|
||||||
<Button
|
<ClaimRepostButton uri={uri} claim={claim} hasChannels={hasChannels} />
|
||||||
button="alt"
|
|
||||||
className="button--file-action"
|
|
||||||
icon={ICONS.REPOST}
|
|
||||||
label={
|
|
||||||
claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost')
|
|
||||||
}
|
|
||||||
description={__('Repost')}
|
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
onClick={handleRepostClick}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
className="button--file-action"
|
className="button--file-action"
|
||||||
|
|
|
@ -23,6 +23,7 @@ type Props = {
|
||||||
doToast: ({ message: string }) => void,
|
doToast: ({ message: string }) => void,
|
||||||
doClearRepostError: () => void,
|
doClearRepostError: () => void,
|
||||||
doRepost: (StreamRepostOptions) => Promise<*>,
|
doRepost: (StreamRepostOptions) => Promise<*>,
|
||||||
|
doHideModal: () => void,
|
||||||
title: string,
|
title: string,
|
||||||
claim?: StreamClaim,
|
claim?: StreamClaim,
|
||||||
enteredContentClaim?: StreamClaim,
|
enteredContentClaim?: StreamClaim,
|
||||||
|
@ -33,11 +34,7 @@ type Props = {
|
||||||
reposting: boolean,
|
reposting: boolean,
|
||||||
uri: string,
|
uri: string,
|
||||||
name: string,
|
name: string,
|
||||||
contentUri: string,
|
|
||||||
setRepostUri: (string) => void,
|
|
||||||
setContentUri: (string) => void,
|
|
||||||
doCheckPendingClaims: () => void,
|
doCheckPendingClaims: () => void,
|
||||||
redirectUri?: string,
|
|
||||||
passedRepostAmount: number,
|
passedRepostAmount: number,
|
||||||
enteredRepostAmount: number,
|
enteredRepostAmount: number,
|
||||||
isResolvingPassedRepost: boolean,
|
isResolvingPassedRepost: boolean,
|
||||||
|
@ -45,11 +42,16 @@ type Props = {
|
||||||
activeChannelClaim: ?ChannelClaim,
|
activeChannelClaim: ?ChannelClaim,
|
||||||
fetchingMyChannels: boolean,
|
fetchingMyChannels: boolean,
|
||||||
incognito: boolean,
|
incognito: boolean,
|
||||||
|
contentUri: string,
|
||||||
|
setContentUri: (string) => void,
|
||||||
|
repostUri: string,
|
||||||
|
setRepostUri: (string) => void,
|
||||||
|
isModal: boolean,
|
||||||
|
redirectUri?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
function RepostCreate(props: Props) {
|
function RepostCreate(props: Props) {
|
||||||
const {
|
const {
|
||||||
redirectUri,
|
|
||||||
doToast,
|
doToast,
|
||||||
doClearRepostError,
|
doClearRepostError,
|
||||||
doRepost,
|
doRepost,
|
||||||
|
@ -60,9 +62,6 @@ function RepostCreate(props: Props) {
|
||||||
doCheckPublishNameAvailability,
|
doCheckPublishNameAvailability,
|
||||||
uri, // ?from
|
uri, // ?from
|
||||||
name, // ?to
|
name, // ?to
|
||||||
contentUri,
|
|
||||||
setRepostUri,
|
|
||||||
setContentUri,
|
|
||||||
doCheckPendingClaims,
|
doCheckPendingClaims,
|
||||||
enteredRepostAmount,
|
enteredRepostAmount,
|
||||||
passedRepostAmount,
|
passedRepostAmount,
|
||||||
|
@ -71,6 +70,12 @@ function RepostCreate(props: Props) {
|
||||||
activeChannelClaim,
|
activeChannelClaim,
|
||||||
fetchingMyChannels,
|
fetchingMyChannels,
|
||||||
incognito,
|
incognito,
|
||||||
|
doHideModal,
|
||||||
|
contentUri,
|
||||||
|
setContentUri,
|
||||||
|
setRepostUri,
|
||||||
|
isModal,
|
||||||
|
redirectUri,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const defaultName = name || (claim && claim.name) || '';
|
const defaultName = name || (claim && claim.name) || '';
|
||||||
|
@ -83,8 +88,8 @@ function RepostCreate(props: Props) {
|
||||||
const [available, setAvailable] = React.useState(true);
|
const [available, setAvailable] = React.useState(true);
|
||||||
const [enteredContent, setEnteredContentUri] = React.useState(undefined);
|
const [enteredContent, setEnteredContentUri] = React.useState(undefined);
|
||||||
const [contentError, setContentError] = React.useState('');
|
const [contentError, setContentError] = React.useState('');
|
||||||
|
|
||||||
const { replace, goBack } = useHistory();
|
const { replace, goBack } = useHistory();
|
||||||
|
|
||||||
const resolvingRepost = isResolvingEnteredRepost || isResolvingPassedRepost;
|
const resolvingRepost = isResolvingEnteredRepost || isResolvingPassedRepost;
|
||||||
const repostUrlName = `lbry://${incognito || !activeChannelClaim ? '' : `${activeChannelClaim.name}/`}`;
|
const repostUrlName = `lbry://${incognito || !activeChannelClaim ? '' : `${activeChannelClaim.name}/`}`;
|
||||||
|
|
||||||
|
@ -293,14 +298,22 @@ function RepostCreate(props: Props) {
|
||||||
linkText: __('Uploads'),
|
linkText: __('Uploads'),
|
||||||
linkTarget: '/uploads',
|
linkTarget: '/uploads',
|
||||||
});
|
});
|
||||||
replace(getRedirect(contentUri, uri, redirectUri));
|
if (isModal) {
|
||||||
|
doHideModal();
|
||||||
|
} else {
|
||||||
|
replace(getRedirect(contentUri, uri, redirectUri));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelIt() {
|
function cancelIt() {
|
||||||
doClearRepostError();
|
doClearRepostError();
|
||||||
goBack();
|
if (isModal) {
|
||||||
|
doHideModal();
|
||||||
|
} else {
|
||||||
|
goBack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fetchingMyChannels) {
|
if (fetchingMyChannels) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ export const AFFIRM_PURCHASE = 'affirm_purchase';
|
||||||
export const CONFIRM_CLAIM_REVOKE = 'confirm_claim_revoke';
|
export const CONFIRM_CLAIM_REVOKE = 'confirm_claim_revoke';
|
||||||
export const FIRST_SUBSCRIPTION = 'firstSubscription';
|
export const FIRST_SUBSCRIPTION = 'firstSubscription';
|
||||||
export const SEND_TIP = 'send_tip';
|
export const SEND_TIP = 'send_tip';
|
||||||
|
export const REPOST = 'repost';
|
||||||
export const CONFIRM_SEND_TIP = 'confirm_send_tip';
|
export const CONFIRM_SEND_TIP = 'confirm_send_tip';
|
||||||
export const SOCIAL_SHARE = 'social_share';
|
export const SOCIAL_SHARE = 'social_share';
|
||||||
export const PUBLISH = 'publish';
|
export const PUBLISH = 'publish';
|
||||||
|
|
9
ui/modal/modalRepost/index.js
Normal file
9
ui/modal/modalRepost/index.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doHideModal } from 'redux/actions/app';
|
||||||
|
import ModalRepost from './view';
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
closeModal: () => dispatch(doHideModal()),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(null, perform)(ModalRepost);
|
32
ui/modal/modalRepost/view.jsx
Normal file
32
ui/modal/modalRepost/view.jsx
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import { Modal } from 'modal/modal';
|
||||||
|
import RepostCreate from 'component/repostCreate';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
closeModal: () => void,
|
||||||
|
uri: string,
|
||||||
|
name: string,
|
||||||
|
contentUri: string,
|
||||||
|
setContentUri: () => void,
|
||||||
|
repostUri: string,
|
||||||
|
setRepostUri: () => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModalRepost extends React.PureComponent<Props> {
|
||||||
|
render() {
|
||||||
|
const { closeModal, uri, name, contentUri, setContentUri, repostUri, setRepostUri } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal onAborted={closeModal} isOpen type="card">
|
||||||
|
<Card
|
||||||
|
title={__('Repost')}
|
||||||
|
actions={<RepostCreate isModal uri={uri} name={name} onCancel={closeModal} contentUri={contentUri} setContentUri={setContentUri} repostUri={repostUri} setRepostUri={setRepostUri} />}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalRepost;
|
|
@ -53,6 +53,7 @@ import ModalRemoveFile from 'modal/modalRemoveFile';
|
||||||
import ModalRevokeClaim from 'modal/modalRevokeClaim';
|
import ModalRevokeClaim from 'modal/modalRevokeClaim';
|
||||||
import ModalRewardCode from 'modal/modalRewardCode';
|
import ModalRewardCode from 'modal/modalRewardCode';
|
||||||
import ModalSendTip from 'modal/modalSendTip';
|
import ModalSendTip from 'modal/modalSendTip';
|
||||||
|
import ModalRepost from 'modal/modalRepost';
|
||||||
import ModalSetReferrer from 'modal/modalSetReferrer';
|
import ModalSetReferrer from 'modal/modalSetReferrer';
|
||||||
import ModalSignOut from 'modal/modalSignOut';
|
import ModalSignOut from 'modal/modalSignOut';
|
||||||
import ModalSocialShare from 'modal/modalSocialShare';
|
import ModalSocialShare from 'modal/modalSocialShare';
|
||||||
|
@ -124,6 +125,8 @@ function ModalRouter(props: Props) {
|
||||||
return ModalFirstSubscription;
|
return ModalFirstSubscription;
|
||||||
case MODALS.SEND_TIP:
|
case MODALS.SEND_TIP:
|
||||||
return ModalSendTip;
|
return ModalSendTip;
|
||||||
|
case MODALS.REPOST:
|
||||||
|
return ModalRepost;
|
||||||
case MODALS.SOCIAL_SHARE:
|
case MODALS.SOCIAL_SHARE:
|
||||||
return ModalSocialShare;
|
return ModalSocialShare;
|
||||||
case MODALS.PUBLISH:
|
case MODALS.PUBLISH:
|
||||||
|
|
Loading…
Reference in a new issue