Code-split homepages
## Ticket 97 ## Issue 8% of the ui.js chunk consists of the 5 custom homepages
This commit is contained in:
parent
9569b6c7a5
commit
310fc81bd9
7 changed files with 55 additions and 15 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
// Data is lazy-loaded in `doSetHomepage()`
|
||||||
|
window.odysee_homepages = window.odysee_homepages || {};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
en: {},
|
en: null,
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
selectLanguage,
|
selectLanguage,
|
||||||
selectLoadedLanguages,
|
selectLoadedLanguages,
|
||||||
selectThemePath,
|
selectThemePath,
|
||||||
|
selectHomepageCode,
|
||||||
} from 'redux/selectors/settings';
|
} from 'redux/selectors/settings';
|
||||||
import {
|
import {
|
||||||
selectIsUpgradeAvailable,
|
selectIsUpgradeAvailable,
|
||||||
|
@ -21,7 +22,7 @@ import {
|
||||||
selectModal,
|
selectModal,
|
||||||
selectActiveChannelClaim,
|
selectActiveChannelClaim,
|
||||||
} from 'redux/selectors/app';
|
} from 'redux/selectors/app';
|
||||||
import { doGetWalletSyncPreference, doSetLanguage } from 'redux/actions/settings';
|
import { doGetWalletSyncPreference, doSetLanguage, doSetHomepage } from 'redux/actions/settings';
|
||||||
import { doSyncLoop } from 'redux/actions/sync';
|
import { doSyncLoop } from 'redux/actions/sync';
|
||||||
import {
|
import {
|
||||||
doDownloadUpgradeRequested,
|
doDownloadUpgradeRequested,
|
||||||
|
@ -38,6 +39,7 @@ const select = (state) => ({
|
||||||
accessToken: selectAccessToken(state),
|
accessToken: selectAccessToken(state),
|
||||||
theme: selectThemePath(state),
|
theme: selectThemePath(state),
|
||||||
language: selectLanguage(state),
|
language: selectLanguage(state),
|
||||||
|
homepageCode: selectHomepageCode(state),
|
||||||
syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state),
|
syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state),
|
||||||
languages: selectLoadedLanguages(state),
|
languages: selectLoadedLanguages(state),
|
||||||
autoUpdateDownloaded: selectAutoUpdateDownloaded(state),
|
autoUpdateDownloaded: selectAutoUpdateDownloaded(state),
|
||||||
|
@ -58,6 +60,7 @@ const perform = (dispatch) => ({
|
||||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||||
fetchCollectionListMine: () => dispatch(doFetchCollectionListMine()),
|
fetchCollectionListMine: () => dispatch(doFetchCollectionListMine()),
|
||||||
setLanguage: (language) => dispatch(doSetLanguage(language)),
|
setLanguage: (language) => dispatch(doSetLanguage(language)),
|
||||||
|
doSetHomepage: (value) => dispatch(doSetHomepage(value)),
|
||||||
signIn: () => dispatch(doSignIn()),
|
signIn: () => dispatch(doSignIn()),
|
||||||
requestDownloadUpgrade: () => dispatch(doDownloadUpgradeRequested()),
|
requestDownloadUpgrade: () => dispatch(doDownloadUpgradeRequested()),
|
||||||
updatePreferences: () => dispatch(doGetAndPopulatePreferences()),
|
updatePreferences: () => dispatch(doGetAndPopulatePreferences()),
|
||||||
|
|
|
@ -72,6 +72,7 @@ const imaLibraryPath = 'https://imasdk.googleapis.com/js/sdkloader/ima3.js';
|
||||||
type Props = {
|
type Props = {
|
||||||
language: string,
|
language: string,
|
||||||
languages: Array<string>,
|
languages: Array<string>,
|
||||||
|
homepageCode: string,
|
||||||
theme: string,
|
theme: string,
|
||||||
user: ?{ id: string, has_verified_email: boolean, is_reward_approved: boolean },
|
user: ?{ id: string, has_verified_email: boolean, is_reward_approved: boolean },
|
||||||
location: { pathname: string, hash: string, search: string },
|
location: { pathname: string, hash: string, search: string },
|
||||||
|
@ -89,6 +90,7 @@ type Props = {
|
||||||
requestDownloadUpgrade: () => void,
|
requestDownloadUpgrade: () => void,
|
||||||
onSignedIn: () => void,
|
onSignedIn: () => void,
|
||||||
setLanguage: (string) => void,
|
setLanguage: (string) => void,
|
||||||
|
doSetHomepage: (string) => void,
|
||||||
isUpgradeAvailable: boolean,
|
isUpgradeAvailable: boolean,
|
||||||
autoUpdateDownloaded: boolean,
|
autoUpdateDownloaded: boolean,
|
||||||
updatePreferences: () => Promise<any>,
|
updatePreferences: () => Promise<any>,
|
||||||
|
@ -130,7 +132,9 @@ function App(props: Props) {
|
||||||
syncError,
|
syncError,
|
||||||
language,
|
language,
|
||||||
languages,
|
languages,
|
||||||
|
homepageCode,
|
||||||
setLanguage,
|
setLanguage,
|
||||||
|
doSetHomepage,
|
||||||
updatePreferences,
|
updatePreferences,
|
||||||
getWalletSyncPref,
|
getWalletSyncPref,
|
||||||
rewards,
|
rewards,
|
||||||
|
@ -307,6 +311,11 @@ function App(props: Props) {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [language, languages]);
|
}, [language, languages]);
|
||||||
|
|
||||||
|
// Fetch homepage for the first time
|
||||||
|
useEffect(() => {
|
||||||
|
doSetHomepage(homepageCode);
|
||||||
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (shouldMigrateLanguage) {
|
if (shouldMigrateLanguage) {
|
||||||
setLanguage(shouldMigrateLanguage);
|
setLanguage(shouldMigrateLanguage);
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { doAlertWaitingForSync, doGetAndPopulatePreferences } from 'redux/action
|
||||||
import { selectPrefsReady } from 'redux/selectors/sync';
|
import { selectPrefsReady } from 'redux/selectors/sync';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { getDefaultLanguage } from 'util/default-languages';
|
import { getDefaultLanguage } from 'util/default-languages';
|
||||||
|
import homepages from 'homepages';
|
||||||
|
|
||||||
const { DEFAULT_LANGUAGE } = require('config');
|
const { DEFAULT_LANGUAGE } = require('config');
|
||||||
const { SDK_SYNC_KEYS } = SHARED_PREFERENCES;
|
const { SDK_SYNC_KEYS } = SHARED_PREFERENCES;
|
||||||
|
@ -298,13 +299,22 @@ export function doFetchLanguage(language) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doSetHomepage(code) {
|
export function doSetHomepage(code) {
|
||||||
return (dispatch, getState) => {
|
return async (dispatch, getState) => {
|
||||||
let languageCode;
|
let languageCode;
|
||||||
if (code === getDefaultLanguage()) {
|
if (code === getDefaultLanguage()) {
|
||||||
languageCode = null;
|
languageCode = null;
|
||||||
} else {
|
} else {
|
||||||
languageCode = code;
|
languageCode = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const homepage = homepages[code || 'en'];
|
||||||
|
if (homepage && homepage.lazyLoad) {
|
||||||
|
const homepageData = await homepage.lazyLoad();
|
||||||
|
if (homepageData) {
|
||||||
|
window.odysee_homepages[code || 'en'] = homepageData.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(doSetClientSetting(SETTINGS.HOMEPAGE, languageCode));
|
dispatch(doSetClientSetting(SETTINGS.HOMEPAGE, languageCode));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,21 +53,16 @@ export const selectThemePath = createSelector(
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectHomepageCode = createSelector(makeSelectClientSetting(SETTINGS.HOMEPAGE), (setting) => {
|
export const selectHomepageCode = createSelector(makeSelectClientSetting(SETTINGS.HOMEPAGE), (setting) => {
|
||||||
return homepages[setting] ? setting : getDefaultHomepageKey();
|
return Object.keys(homepages).includes(setting) ? setting : getDefaultHomepageKey();
|
||||||
});
|
});
|
||||||
|
|
||||||
export const selectLanguage = createSelector(makeSelectClientSetting(SETTINGS.LANGUAGE), (setting) => {
|
export const selectLanguage = createSelector(makeSelectClientSetting(SETTINGS.LANGUAGE), (setting) => {
|
||||||
return setting || getDefaultLanguage();
|
return setting || getDefaultLanguage();
|
||||||
});
|
});
|
||||||
|
|
||||||
export const selectHomepageData = createSelector(
|
export const selectHomepageData = (state) => {
|
||||||
// using homepage setting,
|
const homepageCode = selectHomepageCode(state);
|
||||||
selectHomepageCode,
|
return window.odysee_homepages[homepageCode] || {};
|
||||||
(homepageCode) => {
|
};
|
||||||
// homepages = { 'en': homepageFile, ... }
|
|
||||||
// mixin Homepages here
|
|
||||||
return homepages[homepageCode] || homepages['en'] || {};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectosNotificationsEnabled = makeSelectClientSetting(SETTINGS.OS_NOTIFICATIONS_ENABLED);
|
export const selectosNotificationsEnabled = makeSelectClientSetting(SETTINGS.OS_NOTIFICATIONS_ENABLED);
|
||||||
|
|
|
@ -77,9 +77,11 @@ export const getHomepageRowForCat = (cat: HomepageCat) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
let urlParams = new URLSearchParams();
|
let urlParams = new URLSearchParams();
|
||||||
|
|
||||||
if (cat.claimType) {
|
if (cat.claimType) {
|
||||||
urlParams.set(CS.CLAIM_TYPE, cat.claimType);
|
urlParams.set(CS.CLAIM_TYPE, cat.claimType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cat.channelIds) {
|
if (cat.channelIds) {
|
||||||
urlParams.set(CS.CHANNEL_IDS_KEY, cat.channelIds.join(','));
|
urlParams.set(CS.CHANNEL_IDS_KEY, cat.channelIds.join(','));
|
||||||
}
|
}
|
||||||
|
@ -88,11 +90,13 @@ export const getHomepageRowForCat = (cat: HomepageCat) => {
|
||||||
|
|
||||||
// can intend no limit, numerica auto limit, specific limit.
|
// can intend no limit, numerica auto limit, specific limit.
|
||||||
let limitClaims;
|
let limitClaims;
|
||||||
|
|
||||||
if (typeof cat.channelLimit === 'string' && cat.channelIds && cat.channelIds.length) {
|
if (typeof cat.channelLimit === 'string' && cat.channelIds && cat.channelIds.length) {
|
||||||
if (cat.channelLimit === 'auto') {
|
if (cat.channelLimit === 'auto') {
|
||||||
limitClaims = getLimitPerChannel(cat.channelIds.length, isChannelType);
|
limitClaims = getLimitPerChannel(cat.channelIds.length, isChannelType);
|
||||||
} else if (cat.channelLimit) {
|
} else if (cat.channelLimit) {
|
||||||
const limitNumber = Number(cat.channelLimit);
|
const limitNumber = Number(cat.channelLimit);
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
if (limitNumber === limitNumber && limitNumber !== 0) {
|
if (limitNumber === limitNumber && limitNumber !== 0) {
|
||||||
// because javascript and NaN !== NaN
|
// because javascript and NaN !== NaN
|
||||||
|
@ -293,9 +297,11 @@ export function GetLinksData(
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// $FlowFixMe flow thinks this might not be Array<string>
|
// $FlowFixMe flow thinks this might not be Array<string>
|
||||||
rowData.push(RECENT_FROM_FOLLOWING);
|
rowData.push(RECENT_FROM_FOLLOWING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHomepage && !CUSTOM_HOMEPAGE) {
|
if (isHomepage && !CUSTOM_HOMEPAGE) {
|
||||||
if (followedTags) {
|
if (followedTags) {
|
||||||
const TRENDING_FOR_TAGS = {
|
const TRENDING_FOR_TAGS = {
|
||||||
|
@ -310,6 +316,7 @@ export function GetLinksData(
|
||||||
limitClaimsPerChannel: 2,
|
limitClaimsPerChannel: 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
followedTags.forEach((tag: Tag) => {
|
followedTags.forEach((tag: Tag) => {
|
||||||
const tagName = `#${toCapitalCase(tag.name)}`;
|
const tagName = `#${toCapitalCase(tag.name)}`;
|
||||||
individualTagDataItems.push({
|
individualTagDataItems.push({
|
||||||
|
@ -322,7 +329,11 @@ export function GetLinksData(
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (showPersonalizedTags && !showIndividualTags) rowData.push(TRENDING_FOR_TAGS);
|
|
||||||
|
if (showPersonalizedTags && !showIndividualTags) {
|
||||||
|
rowData.push(TRENDING_FOR_TAGS);
|
||||||
|
}
|
||||||
|
|
||||||
if (showPersonalizedTags && showIndividualTags) {
|
if (showPersonalizedTags && showIndividualTags) {
|
||||||
individualTagDataItems.forEach((item: RowDataItem) => {
|
individualTagDataItems.forEach((item: RowDataItem) => {
|
||||||
rowData.push(item);
|
rowData.push(item);
|
||||||
|
@ -330,6 +341,7 @@ export function GetLinksData(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CUSTOM_HOMEPAGE) {
|
if (!CUSTOM_HOMEPAGE) {
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
rowData.push(YOUTUBE_CREATOR_ROW);
|
rowData.push(YOUTUBE_CREATOR_ROW);
|
||||||
|
@ -338,6 +350,7 @@ export function GetLinksData(
|
||||||
rowData.push(LATEST_FROM_LBRY);
|
rowData.push(LATEST_FROM_LBRY);
|
||||||
if (!showPersonalizedChannels) rowData.push(TOP_CHANNELS);
|
if (!showPersonalizedChannels) rowData.push(TOP_CHANNELS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: provide better method for exempting from homepage
|
// TODO: provide better method for exempting from homepage
|
||||||
(Object.values(all): any)
|
(Object.values(all): any)
|
||||||
.filter((row) => !(isHomepage && row.name === 'news'))
|
.filter((row) => !(isHomepage && row.name === 'news'))
|
||||||
|
|
|
@ -10,7 +10,14 @@ export const getDefaultLanguage = () => {
|
||||||
// If homepages has a key "zh-Hant" return that, otherwise return "zh", otherwise "en"
|
// If homepages has a key "zh-Hant" return that, otherwise return "zh", otherwise "en"
|
||||||
export const getDefaultHomepageKey = () => {
|
export const getDefaultHomepageKey = () => {
|
||||||
const language = getDefaultLanguage();
|
const language = getDefaultLanguage();
|
||||||
return (homepages[language] && language) || (homepages[language.slice(0, 2)] && language.slice(0, 2)) || DEFAULT_LANG;
|
const keys = Object.keys(homepages);
|
||||||
|
if (keys.includes(language)) {
|
||||||
|
return language;
|
||||||
|
} else if (keys.include(language.slice(0, 2))) {
|
||||||
|
return language.slice(0, 2);
|
||||||
|
} else {
|
||||||
|
return DEFAULT_LANG;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue