src/amo/components/HomepageShelves/index.js (105 lines of code) (raw):
/* @flow */
import url from 'url';
import * as React from 'react';
import LandingAddonsCard from 'amo/components/LandingAddonsCard';
import LoadingText from 'amo/components/LoadingText';
import {
ADDON_TYPE_STATIC_THEME,
INSTALL_SOURCE_FEATURED,
INSTALL_SOURCE_FEATURED_COLLECTION,
INSTALL_SOURCE_TAG_SHELF_PREFIX,
LANDING_PAGE_EXTENSION_COUNT,
LANDING_PAGE_THEME_COUNT,
} from 'amo/constants';
import translate from 'amo/i18n/translate';
import { checkInternalURL } from 'amo/utils';
import type { ResultShelfType } from 'amo/reducers/home';
import type { I18nType } from 'amo/types/i18n';
type Props = {|
loading: boolean,
shelves: Array<ResultShelfType>,
|};
type InternalProps = {|
_checkInternalURL: typeof checkInternalURL,
i18n: I18nType,
...Props,
|};
export const HOMESHELVES_ENDPOINT_COLLECTIONS = 'collections';
export const HOMESHELVES_ENDPOINT_SEARCH = 'search';
export const HOMESHELVES_ENDPOINT_RANDOM_TAG = 'random-tag';
const getTagFromUrl = (apiUrl: string): string => {
const { query } = url.parse(apiUrl, true);
return query && query.tag;
};
export const HomepageShelvesBase = (props: InternalProps): React.Node => {
const {
_checkInternalURL = checkInternalURL,
i18n,
loading,
shelves,
} = props;
let shelvesContent;
if (loading) {
shelvesContent = (
// Display loading shelves to keep components that fall below the fold from
// shifting after homepage shelves are loaded from the API
<div className="HomepageShelves-loading">
{[1, 2, 3].map((key) => {
return (
<LandingAddonsCard
className="HomepageShelves-loading-card"
key={`HomepageShelves-loading-${key}`}
header={<LoadingText width={100} />}
loading
/>
);
})}
</div>
);
} else {
shelvesContent = shelves.map((shelf) => {
const { addons, addonType, endpoint, footer, title, url: apiUrl } = shelf;
const shelfKey = title.replace(/\s/g, '-');
const footerText = footer.text
? footer.text
: i18n.sprintf(i18n.gettext('See more %(categoryName)s'), {
categoryName: title.toLowerCase(),
});
let addonInstallSource;
switch (endpoint) {
case HOMESHELVES_ENDPOINT_COLLECTIONS:
addonInstallSource = INSTALL_SOURCE_FEATURED_COLLECTION;
break;
case HOMESHELVES_ENDPOINT_RANDOM_TAG:
addonInstallSource = `${INSTALL_SOURCE_TAG_SHELF_PREFIX}${getTagFromUrl(
apiUrl,
)}`;
break;
default:
addonInstallSource = INSTALL_SOURCE_FEATURED;
}
const hasThemes = addonType === ADDON_TYPE_STATIC_THEME;
const count = hasThemes
? LANDING_PAGE_THEME_COUNT
: LANDING_PAGE_EXTENSION_COUNT;
let footerLink;
const internalUrlCheck = _checkInternalURL({ urlString: footer.url });
if (internalUrlCheck.isInternal) {
footerLink = internalUrlCheck.relativeURL;
} else {
footerLink = { href: footer.url };
}
return (
<LandingAddonsCard
addonInstallSource={addonInstallSource}
addons={addons}
className={`Home-${shelfKey}`}
footerText={footerText}
footerLink={footerLink}
header={title}
isHomepageShelf
isTheme={hasThemes}
key={shelfKey}
placeholderCount={count}
/>
);
});
}
return <div className="HomepageShelves">{shelvesContent}</div>;
};
const HomepageShelves: React.ComponentType<Props> =
translate()(HomepageShelvesBase);
export default HomepageShelves;