changed repost to open a modal instead of new page

This commit is contained in:
Bradley 2022-02-26 18:52:14 -06:00 committed by infinite-persistence
parent f3ff88d74e
commit 98154a1921
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
13 changed files with 169 additions and 44 deletions

View file

@ -0,0 +1,9 @@
import { connect } from 'react-redux';
import { doOpenModal } from 'redux/actions/app';
import ClaimRepostButton from './view';
const perform = {
doOpenModal,
};
export default connect(null, perform)(ClaimRepostButton);

View file

@ -0,0 +1,32 @@
// @flow
import * as MODALS from 'constants/modal_types';
import * as ICONS from 'constants/icons';
import React from 'react';
import classnames from 'classnames';
import Button from 'component/button';
import Tooltip from 'component/common/tooltip';
type Props = {
uri: string,
fileAction?: boolean,
doOpenModal: (string, {}) => void,
};
export default function ClaimRepostButton(props: Props) {
const { uri, fileAction, doOpenModal } = props;
console.log('uri', uri);
return (
<Tooltip title={__('Repost this claim')} arrow={false}>
<Button
button={!fileAction ? 'alt' : undefined}
className={classnames({ 'button--file-action': fileAction })}
icon={ICONS.REPOST}
iconSize={fileAction ? 22 : undefined}
label={__('Repost')}
onClick={() => doOpenModal(MODALS.REPOST, { uri })}
/>
</Tooltip>
);
}

View file

@ -11,6 +11,7 @@ import * as COLLECTIONS_CONSTS from 'constants/collections';
import * as RENDER_MODES from 'constants/file_render_modes'; import * as RENDER_MODES from 'constants/file_render_modes';
import ClaimSupportButton from 'component/claimSupportButton'; import ClaimSupportButton from 'component/claimSupportButton';
import ClaimCollectionAddButton from 'component/claimCollectionAddButton'; import ClaimCollectionAddButton from 'component/claimCollectionAddButton';
import ClaimRepostButton from 'component/claimRepostButton';
import { useHistory } from 'react-router'; 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';
@ -102,6 +103,7 @@ export default function FileActions(props: Props) {
} }
}, [downloadClicked, streamingUrl, fileName]); }, [downloadClicked, streamingUrl, fileName]);
// TODO: don't want to redirect. need to instead show modal
function handleRepostClick() { function handleRepostClick() {
if (!hasChannels) { if (!hasChannels) {
doClearPlayingUri(); doClearPlayingUri();
@ -119,7 +121,9 @@ export default function FileActions(props: Props) {
<ClaimCollectionAddButton uri={uri} fileAction /> <ClaimCollectionAddButton uri={uri} fileAction />
{!hideRepost && !isMobile && !isLivestreamClaim && ( <ClaimRepostButton uri={uri} pathname={pathname} fileAction />
{/* {!hideRepost && !isMobile && !isLivestreamClaim && (
<Tooltip title={__('Repost')} arrow={false}> <Tooltip title={__('Repost')} arrow={false}>
<Button <Button
button="alt" button="alt"
@ -132,7 +136,7 @@ export default function FileActions(props: Props) {
onClick={handleRepostClick} onClick={handleRepostClick}
/> />
</Tooltip> </Tooltip>
)} )} */}
<Tooltip title={__('Share')} arrow={false}> <Tooltip title={__('Share')} arrow={false}>
<Button <Button

View file

@ -1,9 +1,7 @@
// @flow // @flow
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import { MINIMUM_PUBLISH_BID, INVALID_NAME_ERROR } from 'constants/claim'; import { MINIMUM_PUBLISH_BID, INVALID_NAME_ERROR } from 'constants/claim';
import React from 'react'; import React from 'react';
import { useHistory } from 'react-router';
import Card from 'component/common/card'; import Card from 'component/common/card';
import Button from 'component/button'; import Button from 'component/button';
import ChannelSelector from 'component/channelSelector'; import ChannelSelector from 'component/channelSelector';
@ -23,6 +21,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,
@ -36,7 +35,6 @@ type Props = {
setRepostUri: (string) => void, setRepostUri: (string) => void,
setContentUri: (string) => void, setContentUri: (string) => void,
doCheckPendingClaims: () => void, doCheckPendingClaims: () => void,
redirectUri?: string,
passedRepostAmount: number, passedRepostAmount: number,
enteredRepostAmount: number, enteredRepostAmount: number,
isResolvingPassedRepost: boolean, isResolvingPassedRepost: boolean,
@ -48,10 +46,10 @@ type Props = {
function RepostCreate(props: Props) { function RepostCreate(props: Props) {
const { const {
redirectUri,
doToast, doToast,
doClearRepostError, doClearRepostError,
doRepost, doRepost,
doHideModal,
claim, claim,
enteredContentClaim, enteredContentClaim,
balance, balance,
@ -83,7 +81,6 @@ function RepostCreate(props: Props) {
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 resolvingRepost = isResolvingEnteredRepost || isResolvingPassedRepost; const resolvingRepost = isResolvingEnteredRepost || isResolvingPassedRepost;
const repostUrlName = `lbry://${incognito || !activeChannelClaim ? '' : `${activeChannelClaim.name}/`}`; const repostUrlName = `lbry://${incognito || !activeChannelClaim ? '' : `${activeChannelClaim.name}/`}`;
@ -255,27 +252,27 @@ function RepostCreate(props: Props) {
const repostClaimId = contentClaimId || enteredClaimId; const repostClaimId = contentClaimId || enteredClaimId;
const getRedirect = (entered, passed, redirect) => { // const getRedirect = (entered, passed, redirect) => {
if (redirect) { // if (redirect) {
return redirect; // return redirect;
} else if (entered) { // } else if (entered) {
try { // try {
const { claimName } = parseURI(entered); // const { claimName } = parseURI(entered);
return claimName ? `/${claimName}` : '/'; // return claimName ? `/${claimName}` : '/';
} catch (e) { // } catch (e) {
return '/'; // return '/';
} // }
} else if (passed) { // } else if (passed) {
try { // try {
const { claimName } = parseURI(passed); // const { claimName } = parseURI(passed);
return claimName ? `/${claimName}` : '/'; // return claimName ? `/${claimName}` : '/';
} catch (e) { // } catch (e) {
return '/'; // return '/';
} // }
} else { // } else {
return '/'; // return '/';
} // }
}; // };
function handleSubmit() { function handleSubmit() {
if (enteredRepostName && repostBid && repostClaimId) { if (enteredRepostName && repostBid && repostClaimId) {
@ -292,14 +289,14 @@ function RepostCreate(props: Props) {
linkText: __('Uploads'), linkText: __('Uploads'),
linkTarget: '/uploads', linkTarget: '/uploads',
}); });
replace(getRedirect(contentUri, uri, redirectUri)); doHideModal();
}); });
} }
} }
function cancelIt() { function cancelIt() {
doClearRepostError(); doClearRepostError();
goBack(); doHideModal();
} }
if (fetchingMyChannels) { if (fetchingMyChannels) {
@ -312,12 +309,12 @@ function RepostCreate(props: Props) {
return ( return (
<> <>
<ChannelSelector />
<Card <Card
title={__('Repost')}
className="repost-wrapper" className="repost-wrapper"
actions={ actions={
<div> <div>
<ChannelSelector />
{uri && ( {uri && (
<fieldset-section> <fieldset-section>
<ClaimPreview key={uri} uri={uri} actions={''} showNullPlaceholder /> <ClaimPreview key={uri} uri={uri} actions={''} showNullPlaceholder />

View file

@ -1,6 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doClearPublish, doPrepareEdit } from 'redux/actions/publish'; import { doClearPublish, doPrepareEdit } from 'redux/actions/publish';
import { doResolveUris } from 'redux/actions/claims'; import { doResolveUris } from 'redux/actions/claims';
import { doOpenModal } from 'redux/actions/app';
import { selectPendingIds, makeSelectClaimForUri } from 'redux/selectors/claims'; import { selectPendingIds, makeSelectClaimForUri } from 'redux/selectors/claims';
import { makeSelectWinningUriForQuery, selectIsResolvingWinningUri } from 'redux/selectors/search'; import { makeSelectWinningUriForQuery, selectIsResolvingWinningUri } from 'redux/selectors/search';
import SearchTopClaim from './view'; import SearchTopClaim from './view';
@ -25,6 +26,7 @@ const perform = (dispatch) => ({
dispatch(push(`/$/${PAGES.UPLOAD}`)); dispatch(push(`/$/${PAGES.UPLOAD}`));
}, },
doResolveUris: (uris) => dispatch(doResolveUris(uris)), doResolveUris: (uris) => dispatch(doResolveUris(uris)),
doOpenModal: (id, props) => dispatch(doOpenModal(id, props)),
}); });
export default connect(select, perform)(SearchTopClaim); export default connect(select, perform)(SearchTopClaim);

View file

@ -1,6 +1,7 @@
// @flow // @flow
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages'; import * as PAGES from 'constants/pages';
import * as MODALS from 'constants/modal_types';
import React from 'react'; import React from 'react';
import { parseURI } from 'util/lbryURI'; import { parseURI } from 'util/lbryURI';
import ClaimPreview from 'component/claimPreview'; import ClaimPreview from 'component/claimPreview';
@ -8,11 +9,11 @@ import Button from 'component/button';
import ClaimEffectiveAmount from 'component/claimEffectiveAmount'; import ClaimEffectiveAmount from 'component/claimEffectiveAmount';
import ClaimRepostAuthor from 'component/claimRepostAuthor'; import ClaimRepostAuthor from 'component/claimRepostAuthor';
import I18nMessage from 'component/i18nMessage'; import I18nMessage from 'component/i18nMessage';
import { useHistory } from 'react-router';
import LbcSymbol from 'component/common/lbc-symbol'; import LbcSymbol from 'component/common/lbc-symbol';
import { DOMAIN } from 'config'; import { DOMAIN } from 'config';
type Props = { type Props = {
doOpenModal: (string, {}) => void,
query: string, query: string,
winningUri: ?string, winningUri: ?string,
doResolveUris: (Array<string>) => void, doResolveUris: (Array<string>) => void,
@ -28,6 +29,7 @@ type Props = {
export default function SearchTopClaim(props: Props) { export default function SearchTopClaim(props: Props) {
const { const {
doResolveUris, doResolveUris,
doOpenModal,
query = '', query = '',
winningUri, winningUri,
winningClaim, winningClaim,
@ -38,7 +40,6 @@ export default function SearchTopClaim(props: Props) {
isSearching, isSearching,
} = props; } = props;
const uriFromQuery = `lbry://${query}`; const uriFromQuery = `lbry://${query}`;
const { push } = useHistory();
let name; let name;
let channelUriFromQuery; let channelUriFromQuery;
let winningUriIsChannel; let winningUriIsChannel;
@ -115,13 +116,7 @@ export default function SearchTopClaim(props: Props) {
<div className="card card--section help--inline"> <div className="card card--section help--inline">
<I18nMessage <I18nMessage
tokens={{ tokens={{
repost: ( repost: <Button button="link" onClick={() => doOpenModal(MODALS.REPOST, {})} label={__('Repost')} />,
<Button
button="link"
onClick={() => push(`/$/${PAGES.REPOST_NEW}${name ? `?to=${name}` : ''}`)}
label={__('Repost')}
/>
),
publish: ( publish: (
<span> <span>
<Button button="link" onClick={() => beginPublish(name)} label={__('publish')} /> <Button button="link" onClick={() => beginPublish(name)} label={__('publish')} />

View file

@ -20,6 +20,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 SEND_TIP = 'send_tip'; export const SEND_TIP = 'send_tip';
export const CONFIRM_SEND_TIP = 'confirm_send_tip'; export const CONFIRM_SEND_TIP = 'confirm_send_tip';
export const REPOST = 'repost';
export const SOCIAL_SHARE = 'social_share'; export const SOCIAL_SHARE = 'social_share';
export const PUBLISH = 'publish'; export const PUBLISH = 'publish';
export const PUBLISH_PREVIEW = 'publish_preview'; export const PUBLISH_PREVIEW = 'publish_preview';

View file

@ -0,0 +1,11 @@
import { connect } from 'react-redux';
import { doHideModal } from 'redux/actions/app';
import { doResolveUri } from 'redux/actions/claims';
import ModalRepost from './view';
const perform = (dispatch) => ({
closeModal: () => dispatch(doHideModal()),
resolveUri: (uri) => dispatch(doResolveUri(uri)),
});
export default connect(null, perform)(ModalRepost);

View file

@ -0,0 +1,62 @@
// @flow
import React from 'react';
import { useHistory } from 'react-router';
import Modal from 'modal/modal';
import RepostCreate from 'component/repostCreate';
import useThrottle from 'effects/use-throttle';
type Props = {
uri: string,
closeModal: () => void,
resolveUri: (string) => void,
};
function ModalRepost(props: Props) {
const { uri, closeModal, resolveUri } = props;
const {
location: { search },
} = useHistory();
const urlParams = new URLSearchParams(search);
const param = urlParams.get('name') || urlParams.get('q');
const repostTo = param && param[0] === '@' ? param.slice(1) : param;
const [contentUri, setContentUri] = React.useState('');
const [repostUri, setRepostUri] = React.useState('');
const throttledContentValue = useThrottle(contentUri, 500);
const throttledRepostValue = useThrottle(repostUri, 500);
React.useEffect(() => {
if (throttledContentValue) {
resolveUri(throttledContentValue);
}
}, [throttledContentValue, resolveUri]);
React.useEffect(() => {
if (throttledRepostValue) {
resolveUri(throttledRepostValue);
}
}, [throttledRepostValue, resolveUri]);
React.useEffect(() => {
if (repostTo) {
resolveUri(repostTo);
}
}, [repostTo, resolveUri]);
return (
<Modal onAborted={closeModal} isOpen type="card">
<RepostCreate
uri={uri}
name={repostTo}
contentUri={contentUri}
repostUri={repostUri}
setContentUri={setContentUri}
setRepostUri={setRepostUri}
/>
</Modal>
);
}
export default ModalRepost;

View file

@ -39,6 +39,7 @@ const MAP = Object.freeze({
[MODALS.PHONE_COLLECTION]: lazyImport(() => import('modal/modalPhoneCollection' /* webpackChunkName: "modalPhoneCollection" */)), [MODALS.PHONE_COLLECTION]: lazyImport(() => import('modal/modalPhoneCollection' /* webpackChunkName: "modalPhoneCollection" */)),
[MODALS.PUBLISH]: lazyImport(() => import('modal/modalPublish' /* webpackChunkName: "modalPublish" */)), [MODALS.PUBLISH]: lazyImport(() => import('modal/modalPublish' /* webpackChunkName: "modalPublish" */)),
[MODALS.PUBLISH_PREVIEW]: lazyImport(() => import('modal/modalPublishPreview' /* webpackChunkName: "modalPublishPreview" */)), [MODALS.PUBLISH_PREVIEW]: lazyImport(() => import('modal/modalPublishPreview' /* webpackChunkName: "modalPublishPreview" */)),
[MODALS.REPOST]: lazyImport(() => import('modal/modalRepost' /* webpackChunkName: "modalRepost" */)),
[MODALS.REWARD_GENERATED_CODE]: lazyImport(() => import('modal/modalRewardCode' /* webpackChunkName: "modalRewardCode" */)), [MODALS.REWARD_GENERATED_CODE]: lazyImport(() => import('modal/modalRewardCode' /* webpackChunkName: "modalRewardCode" */)),
[MODALS.SEND_TIP]: lazyImport(() => import('modal/modalSendTip' /* webpackChunkName: "modalSendTip" */)), [MODALS.SEND_TIP]: lazyImport(() => import('modal/modalSendTip' /* webpackChunkName: "modalSendTip" */)),
[MODALS.SET_REFERRER]: lazyImport(() => import('modal/modalSetReferrer' /* webpackChunkName: "modalSetReferrer" */)), [MODALS.SET_REFERRER]: lazyImport(() => import('modal/modalSetReferrer' /* webpackChunkName: "modalSetReferrer" */)),

View file

@ -2,6 +2,7 @@ import { connect } from 'react-redux';
import TopPage from './view'; import TopPage from './view';
import { doClearPublish, doPrepareEdit } from 'redux/actions/publish'; import { doClearPublish, doPrepareEdit } from 'redux/actions/publish';
import { doResolveUris } from 'redux/actions/claims'; import { doResolveUris } from 'redux/actions/claims';
import { doOpenModal } from 'redux/actions/app';
import { push } from 'connected-react-router'; import { push } from 'connected-react-router';
import * as PAGES from 'constants/pages'; import * as PAGES from 'constants/pages';
@ -22,6 +23,7 @@ const perform = (dispatch) => ({
dispatch(push(`/$/${PAGES.UPLOAD}`)); dispatch(push(`/$/${PAGES.UPLOAD}`));
}, },
doResolveUris: (uris) => dispatch(doResolveUris(uris)), doResolveUris: (uris) => dispatch(doResolveUris(uris)),
doOpenModal: (id, props) => dispatch(doOpenModal(id, props)),
}); });
export default connect(select, perform)(TopPage); export default connect(select, perform)(TopPage);

View file

@ -7,16 +7,17 @@ import ClaimEffectiveAmount from 'component/claimEffectiveAmount';
import SearchTopClaim from 'component/searchTopClaim'; import SearchTopClaim from 'component/searchTopClaim';
import * as CS from 'constants/claim_search'; import * as CS from 'constants/claim_search';
import Button from 'component/button'; import Button from 'component/button';
import * as PAGES from 'constants/pages'; import * as MODALS from 'constants/modal_types';
import { SIMPLE_SITE } from 'config'; import { SIMPLE_SITE } from 'config';
type Props = { type Props = {
name: string, name: string,
beginPublish: (string) => void, beginPublish: (string) => void,
doOpenModal: (string, {}) => void,
}; };
function TopPage(props: Props) { function TopPage(props: Props) {
const { name, beginPublish } = props; const { name, beginPublish, doOpenModal } = props;
const [channelActive, setChannelActive] = React.useState(false); const [channelActive, setChannelActive] = React.useState(false);
// if the query was actually '@name', still offer repost for 'name' // if the query was actually '@name', still offer repost for 'name'
const queryName = name[0] === '@' ? name.slice(1) : name; const queryName = name[0] === '@' ? name.slice(1) : name;
@ -30,7 +31,8 @@ function TopPage(props: Props) {
streamType={SIMPLE_SITE ? CS.CONTENT_ALL : undefined} streamType={SIMPLE_SITE ? CS.CONTENT_ALL : undefined}
meta={ meta={
<div className="search__top-links"> <div className="search__top-links">
<Button button="secondary" navigate={`/$/${PAGES.REPOST_NEW}?to=${queryName}`} label={__('Repost Here')} /> {/* <Button button="secondary" navigate={`/$/${PAGES.REPOST_NEW}?to=${queryName}`} label={__('Repost Here')} /> */}
<Button button="secondary" onClick={() => doOpenModal(MODALS.REPOST, {})} label={__('Repost Here')} />
<Button button="secondary" onClick={() => beginPublish(queryName)} label={__('Publish Here')} /> <Button button="secondary" onClick={() => beginPublish(queryName)} label={__('Publish Here')} />
</div> </div>
} }

View file

@ -1117,6 +1117,13 @@ img {
} }
.repost-wrapper { .repost-wrapper {
// Repost now uses a modal. Lock the width because the bid message
// keeps changing as you type the desired name.
min-width: var(--modal-width);
@media (max-width: $breakpoint-small) {
min-width: 100%;
}
.claim-preview__wrapper { .claim-preview__wrapper {
background-color: rgba(var(--color-header-background-base), 0.6); background-color: rgba(var(--color-header-background-base), 0.6);
&:hover { &:hover {