Defer user/invite_status from startup

## Issue
Closes 385

## Approach
As mentioned in the ticket, the current places where that info is needed is in the Invites Page and Social Share Component.

1. Invites Page: it is already doing the fetch on mount, so no issue there.
2. Social Share: show spinner until the data is fetched.
This commit is contained in:
infinite-persistence 2022-01-21 18:11:42 +08:00 committed by Thomas Zarebczan
parent 2340138ab5
commit 7fc66aecb6
6 changed files with 47 additions and 7 deletions

View file

@ -1,15 +1,21 @@
import { connect } from 'react-redux';
import { doFetchInviteStatus } from 'redux/actions/user';
import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims';
import SocialShare from './view';
import { selectUserInviteReferralCode, selectUser } from 'redux/selectors/user';
import { selectUserInviteReferralCode, selectUser, selectUserInviteStatusFetched } from 'redux/selectors/user';
import { makeSelectContentPositionForUri } from 'redux/selectors/content';
const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
inviteStatusFetched: selectUserInviteStatusFetched(state),
referralCode: selectUserInviteReferralCode(state),
user: selectUser(state),
title: selectTitleForUri(state, props.uri),
position: makeSelectContentPositionForUri(props.uri)(state),
});
export default connect(select)(SocialShare);
const perform = {
doFetchInviteStatus,
};
export default connect(select, perform)(SocialShare);

View file

@ -4,6 +4,7 @@ import React from 'react';
import Button from 'component/button';
import CopyableText from 'component/copyableText';
import EmbedTextArea from 'component/embedTextArea';
import Spinner from 'component/spinner';
import { generateDownloadUrl } from 'util/web';
import { useIsMobile } from 'effects/use-screensize';
import { FormField } from 'component/common/form';
@ -22,14 +23,26 @@ type Props = {
claim: StreamClaim,
title: ?string,
webShareable: boolean,
inviteStatusFetched: boolean,
referralCode: string,
user: any,
position: number,
collectionId?: number,
doFetchInviteStatus: (boolean) => void,
};
function SocialShare(props: Props) {
const { claim, title, referralCode, user, webShareable, position, collectionId } = props;
const {
claim,
title,
inviteStatusFetched,
referralCode,
user,
webShareable,
position,
collectionId,
doFetchInviteStatus,
} = props;
const [showEmbed, setShowEmbed] = React.useState(false);
const [includeCollectionId, setIncludeCollectionId] = React.useState(Boolean(collectionId)); // unless it *is* a collection?
const [showClaimLinks, setShowClaimLinks] = React.useState(false);
@ -38,8 +51,20 @@ function SocialShare(props: Props) {
const startTimeSeconds: number = hmsToSeconds(startTime);
const isMobile = useIsMobile();
React.useEffect(() => {
if (!inviteStatusFetched) {
doFetchInviteStatus(false);
}
}, [inviteStatusFetched, doFetchInviteStatus]);
if (!claim) {
return null;
} else if (!inviteStatusFetched) {
return (
<div className="main--empty">
<Spinner />
</div>
);
}
const { canonical_url: canonicalUrl, permanent_url: permanentUrl, name, claim_id: claimId } = claim;

View file

@ -18,7 +18,7 @@ const select = (state) => ({
});
const perform = (dispatch) => ({
fetchInviteStatus: () => dispatch(doFetchInviteStatus()),
fetchInviteStatus: (callRewardList) => dispatch(doFetchInviteStatus(callRewardList)),
acknowledgeInivte: () => dispatch(doSetClientSetting(SETTINGS.INVITE_ACKNOWLEDGED, true)),
});

View file

@ -13,13 +13,13 @@ type Props = {
inviteAcknowledged: boolean,
authenticated: boolean,
acknowledgeInivte: () => void,
fetchInviteStatus: () => void,
fetchInviteStatus: (boolean) => void,
};
class InvitePage extends React.PureComponent<Props> {
componentDidMount() {
const { fetchInviteStatus, inviteAcknowledged, acknowledgeInivte } = this.props;
fetchInviteStatus();
fetchInviteStatus(false);
if (!inviteAcknowledged) {
acknowledgeInivte();

View file

@ -126,7 +126,7 @@ export function doAuthenticate(
if (shareUsageData) {
dispatch(doRewardList());
dispatch(doFetchInviteStatus(false));
if (callInstall && !user?.device_types?.includes('web')) {
doInstallNew(appVersion, callbackForUsersWhoAreSharingData, DOMAIN);
}

View file

@ -82,10 +82,19 @@ export const selectUserInviteStatusFailed = createSelector(
() => selectUserInvitesRemaining === null
);
export const selectUserInviteStatusFetched = (state) => {
// A successful fetch produces something; a failed fetch sets it to 'null'.
return selectUserInvitees(state) !== undefined;
};
export const selectUserInviteNewIsPending = (state) => selectState(state).inviteNewIsPending;
export const selectUserInviteNewErrorMessage = (state) => selectState(state).inviteNewErrorMessage;
export const selectUserInviteReferralLink = (state) => selectState(state).referralLink;
/**
* Returns the invitation referral code.
* Clients should use selectUserInviteStatusFetched to check if the info has been fetched.
*/
export const selectUserInviteReferralCode = createSelector(selectState, (state) =>
state.referralCode ? state.referralCode[0] : ''
);