Skip to content

Commit

Permalink
Merge pull request #171 from sharetribe/update-v10.0.0-from-upstream
Browse files Browse the repository at this point in the history
Update v10.0.0 from upstream
  • Loading branch information
Gnito authored Feb 14, 2023
2 parents 24f42cb + b1531d6 commit 2560e0c
Show file tree
Hide file tree
Showing 138 changed files with 7,602 additions and 1,071 deletions.
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,25 @@ way to update this template, but currently, we follow a pattern:

---

## Upcoming version 2022-XX-XX
## Upcoming version 2023-XX-XX

## [v11.0.0] 2023-02-14

### Updates from upstream (FTW-daily v10.0.0)

- [add] This adds support for page asset files that can be created in Console. These asset files are
taken into use for

- LandingPage
- TermsOfServicePage
- PrivacyPolicyPage
- AboutPage
- and other static pages can also be created through Console (they'll be visible in route:
/p/:asset-name/)

[#1520](https://github.com/sharetribe/ftw-daily/pull/1520)

[v11.0.0]: https://github.com/sharetribe/ftw-product/compare/v10.1.0.../v11.0.0

## [v10.1.0] 2023-02-07

Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "app",
"version": "10.1.0",
"version": "11.0.0",
"private": true,
"license": "Apache-2.0",
"dependencies": {
Expand Down Expand Up @@ -54,11 +54,16 @@
"react-with-direction": "^1.4.0",
"redux": "^4.2.0",
"redux-thunk": "^2.4.1",
"rehype-react": "^6.2.1",
"rehype-sanitize": "^4.0.0",
"remark-parse": "^9.0.0",
"remark-rehype": "^8.1.0",
"seedrandom": "^3.0.5",
"sharetribe-flex-sdk": "^1.17.0",
"sharetribe-scripts": "6.0.1",
"smoothscroll-polyfill": "^0.4.0",
"source-map-support": "^0.5.21",
"unified": "^9.2.2",
"url": "^0.11.0"
},
"devDependencies": {
Expand Down
7 changes: 6 additions & 1 deletion server/csp.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const defaultDirectives = {
'*.stripe.com',
],
fontSrc: [self, data, 'assets-sharetribecom.sharetribe.com', 'fonts.gstatic.com'],
frameSrc: [self, '*.stripe.com'],
frameSrc: [self, '*.stripe.com', '*.youtube-nocookie.com'],
imgSrc: [
self,
data,
Expand All @@ -50,6 +50,8 @@ const defaultDirectives = {
'sharetribe.imgix.net', // Safari 9.1 didn't recognize asterisk rule.

// Styleguide placeholder images
'picsum.photos',
'*.picsum.photos',
'via.placeholder.com',

'api.mapbox.com',
Expand All @@ -64,6 +66,9 @@ const defaultDirectives = {
'www.google-analytics.com',
'stats.g.doubleclick.net',

// Youtube (static image)
'*.ytimg.com',

'*.stripe.com',
],
scriptSrc: [
Expand Down
21 changes: 11 additions & 10 deletions server/dataLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,24 @@ exports.loadData = function(requestUrl, sdk, appInfo) {
let translations = {};
const store = configureStore({}, sdk);

const dataLoadingCalls = matchedRoutes.reduce((calls, match) => {
const { route, params } = match;
if (typeof route.loadData === 'function' && !route.auth) {
calls.push(store.dispatch(route.loadData(params, query)));
}
return calls;
}, []);
const dataLoadingCalls = () =>
matchedRoutes.reduce((calls, match) => {
const { route, params } = match;
if (typeof route.loadData === 'function' && !route.auth) {
calls.push(store.dispatch(route.loadData(params, query)));
}
return calls;
}, []);

// First fetch app-wide assets
// Then make loadData calls
// And return object containing preloaded state and translations
// This order supports other asset (in the future) that should be fetched before data calls.
return store
.dispatch(fetchAppAssets(config.appCdnAssets))
.then(fetchedAssets => {
translations = fetchedAssets?.translations?.data || {};
return Promise.all(dataLoadingCalls);
.then(fetchedAppAssets => {
translations = fetchedAppAssets?.translations?.data || {};
return Promise.all(dataLoadingCalls());
})
.then(() => {
return { preloadedState: store.getState(), translations };
Expand Down
4 changes: 3 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ const setupLocale = () => {
export const ClientApp = props => {
const { store, hostedTranslations = {} } = props;
setupLocale();
// This gives good input for debugging issues on live environments, but with test it's not needed.
const logLoadDataCalls = config?.env !== 'test';
return (
<IntlProvider
locale={config.locale}
Expand All @@ -103,7 +105,7 @@ export const ClientApp = props => {
<HelmetProvider>
<IncludeMapLibraryScripts />
<BrowserRouter>
<Routes routes={routeConfiguration()} />
<Routes routes={routeConfiguration()} logLoadDataCalls={logLoadDataCalls} />
</BrowserRouter>
</HelmetProvider>
</Provider>
Expand Down
17 changes: 15 additions & 2 deletions src/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,22 @@ afterAll(() => {
});

describe('Application - JSDOM environment', () => {
it('renders in the client without crashing', () => {
it('renders the LandingPage without crashing', () => {
window.google = { maps: {} };
const store = configureStore();

// LandingPage gets rendered and it calls hostedAsset > fetchPageAssets > sdk.assetByVersion
const pageData = {
data: {
sections: [],
_schema: './schema.json',
},
meta: {
version: 'bCsMYVYVawc8SMPzZWJpiw',
},
};
const resolvePageAssetCall = () => Promise.resolve(pageData);
const fakeSdk = { assetByVersion: resolvePageAssetCall, assetByAlias: resolvePageAssetCall };
const store = configureStore({}, fakeSdk);
const div = document.createElement('div');
ReactDOM.render(<ClientApp store={store} />, div);
delete window.google;
Expand Down
4 changes: 2 additions & 2 deletions src/components/Avatar/Avatar.example.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ const userWithProfileImage = {
name: 'square-small',
width: 240,
height: 240,
url: 'https://via.placeholder.com/240x240',
url: 'https://picsum.photos/240/240/',
},
'square-small2x': {
name: 'square-small2x',
width: 480,
height: 480,
url: 'https://via.placeholder.com/480x480',
url: 'https://picsum.photos/480/480/',
},
},
},
Expand Down
9 changes: 7 additions & 2 deletions src/components/Footer/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const Footer = props => {
</NamedLink>
</li>
<li className={css.listItem}>
<NamedLink name="AboutPage" className={css.link}>
<NamedLink name="CMSPage" params={{ pageId: 'about' }} className={css.link}>
<FormattedMessage id="Footer.toAboutPage" />
</NamedLink>
</li>
Expand All @@ -102,7 +102,12 @@ const Footer = props => {
</NamedLink>
</li>
<li className={css.listItem}>
<NamedLink name="AboutPage" to={{ hash: '#contact' }} className={css.link}>
<NamedLink
name="CMSPage"
params={{ pageId: 'about' }}
to={{ hash: '#contact' }}
className={css.link}
>
<FormattedMessage id="Footer.toContactPage" />
</NamedLink>
</li>
Expand Down
1 change: 1 addition & 0 deletions src/components/Footer/Footer.module.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@import '../../styles/customMediaQueries.css';

.root {
position: relative;
border-top-style: solid;
border-top-width: 1px;
border-top-color: var(--matterColorNegative);
Expand Down
73 changes: 51 additions & 22 deletions src/components/Page/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,12 @@ class PageComponent extends Component {
scrollingDisabled,
referrer,
author,
contentType,
openGraphType,
description,
facebookImages,
published,
schema,
socialSharing,
tags,
title,
twitterHandle,
Expand All @@ -97,7 +98,6 @@ class PageComponent extends Component {
});

this.scrollingDisabledChanged(scrollingDisabled);
const referrerMeta = referrer ? <meta name="referrer" content={referrer} /> : null;

const canonicalRootURL = config.canonicalRootURL;
const shouldReturnPathOnly = referrer && referrer !== 'unsafe-url';
Expand All @@ -107,43 +107,51 @@ class PageComponent extends Component {
const siteTitle = config.siteTitle;
const schemaTitle = intl.formatMessage({ id: 'Page.schemaTitle' }, { siteTitle });
const schemaDescription = intl.formatMessage({ id: 'Page.schemaDescription' });
const metaTitle = title || schemaTitle;
const metaDescription = description || schemaDescription;
const facebookImgs = facebookImages || [
const pageTitle = title || schemaTitle;
const pageDescription = description || schemaDescription;
const {
title: socialSharingTitle,
description: socialSharingDescription,
images1200: socialSharingImages1200,
// Note: we use image with open graph's aspect ratio (1.91:1) also with Twitter
images600: socialSharingImages600,
} = socialSharing || {};

const openGraphFallbackImages = [
{
name: 'facebook',
url: `${canonicalRootURL}${facebookImage}`,
width: 1200,
height: 630,
},
];
const twitterImgs = twitterImages || [
const twitterFallbackImages = [
{
name: 'twitter',
url: `${canonicalRootURL}${twitterImage}`,
width: 600,
height: 314,
},
];
const facebookImgs = socialSharingImages1200 || facebookImages || openGraphFallbackImages;
const twitterImgs = socialSharingImages600 || twitterImages || twitterFallbackImages;

const metaToHead = metaTagProps({
author,
contentType,
description: metaDescription,
openGraphType,
socialSharingTitle: socialSharingTitle || pageTitle,
socialSharingDescription: socialSharingDescription || pageDescription,
description: pageDescription,
facebookImages: facebookImgs,
twitterImages: twitterImgs,
published,
tags,
title: metaTitle,
twitterHandle,
updated,
url: canonicalUrl,
locale: intl.locale,
});

// eslint-disable-next-line react/no-array-index-key
const metaTags = metaToHead.map((metaProps, i) => <meta key={i} {...metaProps} />);

const facebookPage = config.siteFacebookPage;
const twitterPage = twitterPageURL(config.siteTwitterHandle);
const instagramPage = config.siteInstagramPage;
Expand All @@ -156,7 +164,8 @@ class PageComponent extends Component {
// Schema attribute can be either single schema object or an array of objects
// This makes it possible to include several different items from the same page.
// E.g. Product, Place, Video
const schemaFromProps = Array.isArray(schema) ? schema : [schema];
const hasSchema = schema != null;
const schemaFromProps = hasSchema && Array.isArray(schema) ? schema : hasSchema ? [schema] : [];
const schemaArrayJSONString = JSON.stringify([
...schemaFromProps,
{
Expand All @@ -175,9 +184,6 @@ class PageComponent extends Component {
url: canonicalRootURL,
description: schemaDescription,
name: schemaTitle,
publisher: {
'@id': `${canonicalRootURL}#organization`,
},
},
]);

Expand All @@ -201,12 +207,14 @@ class PageComponent extends Component {
lang: intl.locale,
}}
>
<title>{title}</title>
{referrerMeta}
<title>{pageTitle}</title>
{referrer ? <meta name="referrer" content={referrer} /> : null}
<link rel="canonical" href={canonicalUrl} />
<meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
<meta httpEquiv="Content-Language" content={intl.locale} />
{metaTags}
{metaToHead.map((metaProps, i) => (
<meta key={i} {...metaProps} />
))}
<script id="page-schema" type="application/ld+json">
{schemaArrayJSONString.replace(/</g, '\\u003c')}
</script>
Expand All @@ -233,13 +241,14 @@ PageComponent.defaultProps = {
rootClassName: null,
children: null,
author: null,
contentType: 'website',
openGraphType: 'website',
description: null,
facebookImages: null,
twitterImages: null,
published: null,
referrer: null,
schema: null,
socialSharing: null,
tags: null,
twitterHandle: null,
updated: null,
Expand All @@ -256,7 +265,7 @@ PageComponent.propTypes = {

// SEO related props
author: string,
contentType: string, // og:type
openGraphType: string, // og:type
description: string, // page description
facebookImages: arrayOf(
shape({
Expand All @@ -274,8 +283,28 @@ PageComponent.propTypes = {
),
published: string, // article:published_time
schema: oneOfType([object, array]), // http://schema.org
socialSharing: shape({
title: string,
description: string,
images1200: arrayOf(
// Page asset file can define this
shape({
width: number.isRequired,
height: number.isRequired,
url: string.isRequired,
})
),
images600: arrayOf(
// Page asset file can define this
shape({
width: number.isRequired,
height: number.isRequired,
url: string.isRequired,
})
),
}),
tags: string, // article:tag
title: string.isRequired, // page title
title: string, // page title
twitterHandle: string, // twitter handle
updated: string, // article:modified_time

Expand Down
Loading

0 comments on commit 2560e0c

Please sign in to comment.