FYP: show placeholder tiles when fetching membership or fyp itself.
This prevents the "no membership" and "no recommendations" message from flashing during load.
This commit is contained in:
parent
09557c8ce2
commit
a96db41782
4 changed files with 39 additions and 8 deletions
3
flow-typed/search.js
vendored
3
flow-typed/search.js
vendored
|
@ -33,7 +33,7 @@ declare type SearchState = {
|
||||||
hasReachedMaxResultsLength: {},
|
hasReachedMaxResultsLength: {},
|
||||||
searching: boolean,
|
searching: boolean,
|
||||||
mentionQuery: string,
|
mentionQuery: string,
|
||||||
personalRecommendations: { gid: string, uris: Array<string> },
|
personalRecommendations: { gid: string, uris: Array<string>, fetched: boolean },
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type SearchSuccess = {
|
declare type SearchSuccess = {
|
||||||
|
@ -44,7 +44,6 @@ declare type SearchSuccess = {
|
||||||
size: number,
|
size: number,
|
||||||
uris: Array<string>,
|
uris: Array<string>,
|
||||||
recsys: string,
|
recsys: string,
|
||||||
query: string,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import ClaimList from 'component/claimList';
|
import ClaimList from 'component/claimList';
|
||||||
|
import ClaimPreviewTile from 'component/claimPreviewTile';
|
||||||
import I18nMessage from 'component/i18nMessage';
|
import I18nMessage from 'component/i18nMessage';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
|
@ -26,8 +27,8 @@ type Props = {
|
||||||
onLoad: (displayed: boolean) => void,
|
onLoad: (displayed: boolean) => void,
|
||||||
// --- redux ---
|
// --- redux ---
|
||||||
userId: ?string,
|
userId: ?string,
|
||||||
personalRecommendations: { gid: string, uris: Array<string> },
|
personalRecommendations: { gid: string, uris: Array<string>, fetched: boolean },
|
||||||
hasMembership: boolean,
|
hasMembership: ?boolean,
|
||||||
doFetchPersonalRecommendations: () => void,
|
doFetchPersonalRecommendations: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -89,6 +90,26 @@ export default function RecommendedPersonal(props: Props) {
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
|
if (hasMembership === undefined || !personalRecommendations.fetched) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{header}
|
||||||
|
<ul className="claim-grid">
|
||||||
|
{new Array(countCollapsed).fill(1).map((x, i) => (
|
||||||
|
<ClaimPreviewTile key={i} placeholder />
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<div className="livestream-list--view-more" style={{ visibility: 'hidden' }}>
|
||||||
|
<Button
|
||||||
|
label='"View More" dummy to reduce layout shift'
|
||||||
|
button="link"
|
||||||
|
className="claim-grid__title--secondary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!hasMembership) {
|
if (!hasMembership) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -22,7 +22,7 @@ const defaultState: SearchState = {
|
||||||
searching: false,
|
searching: false,
|
||||||
results: [],
|
results: [],
|
||||||
mentionQuery: '',
|
mentionQuery: '',
|
||||||
personalRecommendations: { gid: '', uris: [] },
|
personalRecommendations: { gid: '', uris: [], fetched: false },
|
||||||
};
|
};
|
||||||
|
|
||||||
export default handleActions(
|
export default handleActions(
|
||||||
|
@ -82,13 +82,17 @@ export default handleActions(
|
||||||
personalRecommendations: {
|
personalRecommendations: {
|
||||||
gid: action.data.gid,
|
gid: action.data.gid,
|
||||||
uris: action.data.uris,
|
uris: action.data.uris,
|
||||||
|
fetched: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
[ACTIONS.FYP_FETCH_FAILED]: (state: SearchState, action: any): SearchState => ({
|
[ACTIONS.FYP_FETCH_FAILED]: (state: SearchState, action: any): SearchState => ({
|
||||||
...state,
|
...state,
|
||||||
personalRecommendations: defaultState.personalRecommendations,
|
personalRecommendations: {
|
||||||
|
...defaultState.personalRecommendations,
|
||||||
|
fetched: true,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
[ACTIONS.FYP_HIDE_URI]: (state: SearchState, action: any): SearchState => {
|
[ACTIONS.FYP_HIDE_URI]: (state: SearchState, action: any): SearchState => {
|
||||||
|
@ -100,6 +104,7 @@ export default handleActions(
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
personalRecommendations: {
|
personalRecommendations: {
|
||||||
|
...state.personalRecommendations,
|
||||||
gid: state.personalRecommendations.gid,
|
gid: state.personalRecommendations.gid,
|
||||||
uris,
|
uris,
|
||||||
},
|
},
|
||||||
|
|
|
@ -114,6 +114,12 @@ export const selectOdyseeMembershipIsPremiumPlus = (state) => {
|
||||||
return selectState(state).odyseeMembershipName === 'Premium+';
|
return selectState(state).odyseeMembershipName === 'Premium+';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* selectHasOdyseeMembership
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* @returns 'undefined' if not yet fetched; boolean otherwise.
|
||||||
|
*/
|
||||||
export const selectHasOdyseeMembership = (state) => {
|
export const selectHasOdyseeMembership = (state) => {
|
||||||
// @if process.env.NODE_ENV!='production'
|
// @if process.env.NODE_ENV!='production'
|
||||||
const override = window.localStorage.getItem('hasMembershipOverride');
|
const override = window.localStorage.getItem('hasMembershipOverride');
|
||||||
|
@ -122,8 +128,8 @@ export const selectHasOdyseeMembership = (state) => {
|
||||||
}
|
}
|
||||||
// @endif
|
// @endif
|
||||||
|
|
||||||
const membershipName = selectOdyseeMembershipName(state);
|
const membership = selectOdyseeMembershipName(state);
|
||||||
return Boolean(membershipName);
|
return membership === undefined ? membership : Boolean(membership);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const selectYouTubeImportVideosComplete = createSelector(selectState, (state) => {
|
export const selectYouTubeImportVideosComplete = createSelector(selectState, (state) => {
|
||||||
|
|
Loading…
Reference in a new issue