Bring back default channel functionality

- consolidate cases that need to auto set an active channel (like edit page) into channelSelector component
- also for consistency since some components would do it with button click and others on page mount
- prevent clear function on those pages (kind of a manual process to insert each page into the router condition)
This commit is contained in:
Rafael 2022-05-10 09:01:19 -03:00 committed by Thomas Zarebczan
parent d6208707b9
commit 17868635bd
11 changed files with 62 additions and 54 deletions

View file

@ -27,6 +27,8 @@ type Props = {
storeSelection?: boolean, storeSelection?: boolean,
doSetClientSetting: (key: string, value: string, pushPrefs: boolean) => void, doSetClientSetting: (key: string, value: string, pushPrefs: boolean) => void,
isHeaderMenu?: boolean, isHeaderMenu?: boolean,
autoSet?: boolean,
channelToSet?: string,
}; };
export default function ChannelSelector(props: Props) { export default function ChannelSelector(props: Props) {
@ -42,6 +44,8 @@ export default function ChannelSelector(props: Props) {
storeSelection, storeSelection,
doSetClientSetting, doSetClientSetting,
isHeaderMenu, isHeaderMenu,
autoSet,
channelToSet,
} = props; } = props;
const hideAnon = Boolean(props.hideAnon || storeSelection); const hideAnon = Boolean(props.hideAnon || storeSelection);
@ -62,6 +66,20 @@ export default function ChannelSelector(props: Props) {
} }
} }
React.useEffect(() => {
if (!autoSet) return;
if (channelToSet) {
doSetActiveChannel(channelToSet);
doSetIncognito(false);
} else if (!channelToSet) {
doSetIncognito(true);
}
// on mount, if we get to autoSet a channel, set it.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return ( return (
<div className="channel__selector"> <div className="channel__selector">
<Menu> <Menu>

View file

@ -1,7 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { selectClaimForUri, selectClaimIsMine } from 'redux/selectors/claims'; import { selectClaimForUri, selectClaimIsMine } from 'redux/selectors/claims';
import { doCollectionEdit, doFetchItemsInCollection } from 'redux/actions/collections'; import { doCollectionEdit, doFetchItemsInCollection } from 'redux/actions/collections';
import { doEditForChannel } from 'redux/actions/publish'; import { doPrepareEdit } from 'redux/actions/publish';
import { doRemovePersonalRecommendation } from 'redux/actions/search'; import { doRemovePersonalRecommendation } from 'redux/actions/search';
import { import {
makeSelectCollectionForId, makeSelectCollectionForId,
@ -89,7 +89,7 @@ const select = (state, props) => {
}; };
const perform = (dispatch) => ({ const perform = (dispatch) => ({
prepareEdit: (publishData, uri, fileInfo) => dispatch(doEditForChannel(publishData, uri, fileInfo, fs)), prepareEdit: (publishData, uri, fileInfo) => dispatch(doPrepareEdit(publishData, uri, fileInfo, fs)),
doToast: (props) => dispatch(doToast(props)), doToast: (props) => dispatch(doToast(props)),
openModal: (modal, props) => dispatch(doOpenModal(modal, props)), openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
doChannelMute: (channelUri) => dispatch(doChannelMute(channelUri)), doChannelMute: (channelUri) => dispatch(doChannelMute(channelUri)),

View file

@ -21,7 +21,6 @@ import * as ACTIONS from 'constants/action_types';
import CollectionForm from './view'; import CollectionForm from './view';
import { selectActiveChannelClaim, selectIncognito } from 'redux/selectors/app'; import { selectActiveChannelClaim, selectIncognito } from 'redux/selectors/app';
import { doSetActiveChannel, doSetIncognito } from 'redux/actions/app';
import { doCollectionEdit } from 'redux/actions/collections'; import { doCollectionEdit } from 'redux/actions/collections';
const select = (state, props) => ({ const select = (state, props) => ({
@ -49,8 +48,6 @@ const perform = (dispatch, ownProps) => ({
publishCollectionUpdate: (params) => dispatch(doCollectionPublishUpdate(params)), publishCollectionUpdate: (params) => dispatch(doCollectionPublishUpdate(params)),
publishCollection: (params, collectionId) => dispatch(doCollectionPublish(params, collectionId)), publishCollection: (params, collectionId) => dispatch(doCollectionPublish(params, collectionId)),
clearCollectionErrors: () => dispatch({ type: ACTIONS.CLEAR_COLLECTION_ERRORS }), clearCollectionErrors: () => dispatch({ type: ACTIONS.CLEAR_COLLECTION_ERRORS }),
setActiveChannel: (claimId) => dispatch(doSetActiveChannel(claimId)),
setIncognito: (incognito) => dispatch(doSetIncognito(incognito)),
doCollectionEdit: (params) => dispatch(doCollectionEdit(ownProps.collectionId, params)), doCollectionEdit: (params) => dispatch(doCollectionEdit(ownProps.collectionId, params)),
}); });

View file

@ -61,8 +61,6 @@ type Props = {
publishCollection: (CollectionPublishParams, string) => Promise<any>, publishCollection: (CollectionPublishParams, string) => Promise<any>,
clearCollectionErrors: () => void, clearCollectionErrors: () => void,
onDone: (string) => void, onDone: (string) => void,
setActiveChannel: (string) => void,
setIncognito: (boolean) => void,
doCollectionEdit: (CollectionEditParams) => void, doCollectionEdit: (CollectionEditParams) => void,
}; };
@ -94,8 +92,6 @@ function CollectionForm(props: Props) {
publishCollectionUpdate, publishCollectionUpdate,
publishCollection, publishCollection,
clearCollectionErrors, clearCollectionErrors,
setActiveChannel,
setIncognito,
onDone, onDone,
doCollectionEdit, doCollectionEdit,
} = props; } = props;
@ -108,7 +104,6 @@ function CollectionForm(props: Props) {
const collectionName = (claim && claim.name) || (collection && collection.name); const collectionName = (claim && claim.name) || (collection && collection.name);
const collectionChannel = claim && claim.signing_channel ? claim.signing_channel.claim_id : undefined; const collectionChannel = claim && claim.signing_channel ? claim.signing_channel.claim_id : undefined;
const hasClaim = !!claim; const hasClaim = !!claim;
const [initialized, setInitialized] = React.useState(false);
const [nameError, setNameError] = React.useState(undefined); const [nameError, setNameError] = React.useState(undefined);
const [bidError, setBidError] = React.useState(''); const [bidError, setBidError] = React.useState('');
const [thumbStatus, setThumbStatus] = React.useState(''); const [thumbStatus, setThumbStatus] = React.useState('');
@ -264,6 +259,7 @@ function CollectionForm(props: Props) {
const collectionClaimIds = JSON.parse(collectionClaimIdsString); const collectionClaimIds = JSON.parse(collectionClaimIdsString);
setParams({ ...params, claims: collectionClaimIds }); setParams({ ...params, claims: collectionClaimIds });
clearCollectionErrors(); clearCollectionErrors();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [collectionClaimIdsString, setParams]); }, [collectionClaimIdsString, setParams]);
React.useEffect(() => { React.useEffect(() => {
@ -277,35 +273,22 @@ function CollectionForm(props: Props) {
setNameError(nameError); setNameError(nameError);
}, [name]); }, [name]);
// on mount, if we get a collectionChannel, set it.
React.useEffect(() => {
if (hasClaim && !initialized) {
if (collectionChannel) {
setActiveChannel(collectionChannel);
setIncognito(false);
} else if (!collectionChannel && hasClaim) {
setIncognito(true);
}
setInitialized(true);
}
}, [setInitialized, setActiveChannel, collectionChannel, setIncognito, hasClaim, incognito, initialized]);
// every time activechannel or incognito changes, set it. // every time activechannel or incognito changes, set it.
React.useEffect(() => { React.useEffect(() => {
if (initialized) { if (activeChannelId) {
if (activeChannelId) { setParam({ channel_id: activeChannelId });
setParam({ channel_id: activeChannelId }); } else if (incognito) {
} else if (incognito) { setParam({ channel_id: undefined });
setParam({ channel_id: undefined });
}
} }
}, [activeChannelId, incognito, initialized]); // eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeChannelId, incognito]);
// setup initial params after we're sure if it's published or not // setup initial params after we're sure if it's published or not
React.useEffect(() => { React.useEffect(() => {
if (!uri || (uri && hasClaim)) { if (!uri || (uri && hasClaim)) {
updateParams(getCollectionParams()); updateParams(getCollectionParams());
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [uri, hasClaim]); }, [uri, hasClaim]);
return ( return (
@ -322,7 +305,7 @@ function CollectionForm(props: Props) {
<TabPanels> <TabPanels>
<TabPanel> <TabPanel>
<div className={'card-stack'}> <div className={'card-stack'}>
<ChannelSelector disabled={disabled} /> <ChannelSelector disabled={disabled} autoSet channelToSet={collectionChannel} />
<Card <Card
body={ body={
<> <>

View file

@ -6,7 +6,7 @@ import {
makeSelectTagInClaimOrChannelForUri, makeSelectTagInClaimOrChannelForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { makeSelectStreamingUrlForUri } from 'redux/selectors/file_info'; import { makeSelectStreamingUrlForUri } from 'redux/selectors/file_info';
import { doEditForChannel } from 'redux/actions/publish'; import { doPrepareEdit } from 'redux/actions/publish';
import { selectCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri } from 'lbryinc';
import { doDownloadUri } from 'redux/actions/content'; import { doDownloadUri } from 'redux/actions/content';
import { doToast } from 'redux/actions/notifications'; import { doToast } from 'redux/actions/notifications';
@ -35,7 +35,7 @@ const select = (state, props) => {
const perform = { const perform = {
doOpenModal, doOpenModal,
doEditForChannel, doPrepareEdit,
doToast, doToast,
doDownloadUri, doDownloadUri,
}; };

View file

@ -31,7 +31,7 @@ type Props = {
streamingUrl: ?string, streamingUrl: ?string,
disableDownloadButton: boolean, disableDownloadButton: boolean,
doOpenModal: (id: string, { uri: string, claimIsMine?: boolean, isSupport?: boolean }) => void, doOpenModal: (id: string, { uri: string, claimIsMine?: boolean, isSupport?: boolean }) => void,
doEditForChannel: (claim: Claim, uri: string) => void, doPrepareEdit: (claim: Claim, uri: string) => void,
doToast: (data: { message: string }) => void, doToast: (data: { message: string }) => void,
doDownloadUri: (uri: string) => void, doDownloadUri: (uri: string) => void,
}; };
@ -49,7 +49,7 @@ export default function FileActions(props: Props) {
streamingUrl, streamingUrl,
disableDownloadButton, disableDownloadButton,
doOpenModal, doOpenModal,
doEditForChannel, doPrepareEdit,
doToast, doToast,
doDownloadUri, doDownloadUri,
} = props; } = props;
@ -150,7 +150,7 @@ export default function FileActions(props: Props) {
icon={ICONS.EDIT} icon={ICONS.EDIT}
label={isLivestreamClaim ? __('Update or Publish Replay') : __('Edit')} label={isLivestreamClaim ? __('Update or Publish Replay') : __('Edit')}
navigate={`/$/${PAGES.UPLOAD}`} navigate={`/$/${PAGES.UPLOAD}`}
onClick={() => doEditForChannel(claim, editUri)} onClick={() => doPrepareEdit(claim, editUri)}
/> />
</div> </div>
</Tooltip> </Tooltip>
@ -197,7 +197,7 @@ export default function FileActions(props: Props) {
<MenuItem <MenuItem
className="comment__menu-option" className="comment__menu-option"
onSelect={() => { onSelect={() => {
doEditForChannel(claim, editUri); doPrepareEdit(claim, editUri);
push(`/$/${PAGES.UPLOAD}`); push(`/$/${PAGES.UPLOAD}`);
}} }}
> >

View file

@ -255,6 +255,7 @@ function PublishForm(props: Props) {
if (claimChannelId) { if (claimChannelId) {
fetchLivestreams(claimChannelId, activeChannelName); fetchLivestreams(claimChannelId, activeChannelName);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [claimChannelId]); }, [claimChannelId]);
useEffect(() => { useEffect(() => {
@ -352,6 +353,7 @@ function PublishForm(props: Props) {
if (publishing || publishSuccess) { if (publishing || publishSuccess) {
clearPublish(); clearPublish();
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [clearPublish]); }, [clearPublish]);
useEffect(() => { useEffect(() => {
@ -466,6 +468,7 @@ function PublishForm(props: Props) {
const newParams = new URLSearchParams(); const newParams = new URLSearchParams();
newParams.set(TYPE_PARAM, mode.toLowerCase()); newParams.set(TYPE_PARAM, mode.toLowerCase());
replace({ search: newParams.toString() }); replace({ search: newParams.toString() });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [mode, _uploadType]); }, [mode, _uploadType]);
// @if TARGET='web' // @if TARGET='web'
@ -589,7 +592,7 @@ function PublishForm(props: Props) {
// Editing claim uri // Editing claim uri
return ( return (
<div className="card-stack uploadPage-wraper"> <div className="card-stack uploadPage-wraper">
<ChannelSelect hideAnon={isLivestreamMode} disabled={disabled} /> <ChannelSelect hideAnon={isLivestreamMode} disabled={disabled} autoSet channelToSet={claimChannelId} />
<PublishFile <PublishFile
inEditMode={inEditMode} inEditMode={inEditMode}

View file

@ -6,7 +6,7 @@ import { selectClientSetting, selectHomepageData, selectWildWestDisabled } from
import Router from './view'; import Router from './view';
import { normalizeURI } from 'util/lbryURI'; import { normalizeURI } from 'util/lbryURI';
import { selectTitleForUri } from 'redux/selectors/claims'; import { selectTitleForUri } from 'redux/selectors/claims';
import { doSetHasNavigated } from 'redux/actions/app'; import { doSetHasNavigated, doSetActiveChannel } from 'redux/actions/app';
import { doUserSetReferrer } from 'redux/actions/user'; import { doUserSetReferrer } from 'redux/actions/user';
import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards'; import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards';
import { selectUnseenNotificationCount } from 'redux/selectors/notifications'; import { selectUnseenNotificationCount } from 'redux/selectors/notifications';
@ -46,6 +46,7 @@ const select = (state) => {
const perform = { const perform = {
setHasNavigated: doSetHasNavigated, setHasNavigated: doSetHasNavigated,
setReferrer: doUserSetReferrer, setReferrer: doUserSetReferrer,
doSetActiveChannel,
}; };
export default connect(select, perform)(Router); export default connect(select, perform)(Router);

View file

@ -142,6 +142,7 @@ type Props = {
unseenCount: number, unseenCount: number,
hideTitleNotificationCount: boolean, hideTitleNotificationCount: boolean,
hasDefaultChannel: boolean, hasDefaultChannel: boolean,
doSetActiveChannel: (claimId: ?string, override?: boolean) => void,
}; };
type PrivateRouteProps = Props & { type PrivateRouteProps = Props & {
@ -184,6 +185,7 @@ function AppRouter(props: Props) {
unseenCount, unseenCount,
hideTitleNotificationCount, hideTitleNotificationCount,
hasDefaultChannel, hasDefaultChannel,
doSetActiveChannel,
} = props; } = props;
const defaultChannelRef = React.useRef(hasDefaultChannel); const defaultChannelRef = React.useRef(hasDefaultChannel);
@ -263,7 +265,7 @@ function AppRouter(props: Props) {
if (unseenCount > 0 && !hideTitleNotificationCount) { if (unseenCount > 0 && !hideTitleNotificationCount) {
document.title = `(${buildUnseenCountStr(unseenCount)}) ${document.title}`; document.title = `(${buildUnseenCountStr(unseenCount)}) ${document.title}`;
} }
}, [pathname, entries, entryIndex, title, uri, unseenCount]); }, [pathname, entries, entryIndex, title, uri, unseenCount, hideTitleNotificationCount]);
useEffect(() => { useEffect(() => {
if (!hasLinkedCommentInUrl) { if (!hasLinkedCommentInUrl) {
@ -283,6 +285,21 @@ function AppRouter(props: Props) {
defaultChannelRef.current = hasDefaultChannel; defaultChannelRef.current = hasDefaultChannel;
}, [hasDefaultChannel]); }, [hasDefaultChannel]);
React.useEffect(() => {
// has a default channel selected, clear the current active channel
if (
defaultChannelRef.current &&
pathname !== `/$/${PAGES.UPLOAD}` &&
!pathname.includes(`/$/${PAGES.LIST}/`) &&
pathname !== `/$/${PAGES.CREATOR_DASHBOARD}` &&
pathname !== `/$/${PAGES.LIVESTREAM}`
) {
doSetActiveChannel(null, true);
}
// only on pathname change
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname]);
// react-router doesn't decode pathanmes before doing the route matching check // react-router doesn't decode pathanmes before doing the route matching check
// We have to redirect here because if we redirect on the server, it might get encoded again // We have to redirect here because if we redirect on the server, it might get encoded again
// in the browser causing a redirect loop // in the browser causing a redirect loop

View file

@ -18,7 +18,7 @@ import { makeSelectPublishFormValue, selectPublishFormValues, selectMyClaimForUr
import { doError, doToast } from 'redux/actions/notifications'; import { doError, doToast } from 'redux/actions/notifications';
import { push } from 'connected-react-router'; import { push } from 'connected-react-router';
import analytics from 'analytics'; import analytics from 'analytics';
import { doOpenModal, doSetIncognito, doSetActiveChannel } from 'redux/actions/app'; import { doOpenModal } from 'redux/actions/app';
import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/licenses'; import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/licenses';
import { IMG_CDN_PUBLISH_URL, IMG_CDN_STATUS_URL } from 'constants/cdn_urls'; import { IMG_CDN_PUBLISH_URL, IMG_CDN_STATUS_URL } from 'constants/cdn_urls';
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
@ -547,19 +547,6 @@ export const doUploadThumbnail = (
} }
}; };
export const doEditForChannel = (publishData: any, uri: string, fileInfo: FileListItem, fs: any) => (
dispatch: Dispatch
) => {
if (publishData.signing_channel) {
dispatch(doSetIncognito(false));
dispatch(doSetActiveChannel(publishData.signing_channel.claim_id));
} else {
dispatch(doSetIncognito(true));
}
dispatch(doPrepareEdit(publishData, uri, fileInfo, fs));
};
export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem, fs: any) => ( export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem, fs: any) => (
dispatch: Dispatch dispatch: Dispatch
) => { ) => {

View file

@ -131,6 +131,8 @@
flex: 1; flex: 1;
height: var(--header-height); height: var(--header-height);
padding: var(--spacing-s) var(--spacing-m); padding: var(--spacing-s) var(--spacing-m);
margin-right: var(--body-scrollbar-width);
width: unset;
@media (max-width: $breakpoint-small) { @media (max-width: $breakpoint-small) {
padding: var(--spacing-xs); padding: var(--spacing-xs);