-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Theme Sheet: Use information from WordPress.org for themes on Jetpack sites #9875
Changes from 24 commits
de72945
f15e9b5
b4b6fcc
6205d1b
5d99f41
8a13f1c
0c70ad7
26ec67e
ef5a339
52e4b1d
4000d43
83517d6
5a08543
5a9185b
6c80ebc
23f07df
f80aab5
9a54916
4cd7918
157a342
2b0a677
443292e
738baab
8cbee7e
62b6788
42429c5
1834607
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import React from 'react'; | |
import { connect } from 'react-redux'; | ||
import i18n from 'i18n-calypso'; | ||
import titlecase from 'to-title-case'; | ||
import { isArray } from 'lodash'; | ||
|
||
/** | ||
* Internal dependencies | ||
|
@@ -28,7 +29,6 @@ import { getSelectedSite } from 'state/ui/selectors'; | |
import { getSiteSlug, isJetpackSite } from 'state/sites/selectors'; | ||
import { getCurrentUserId } from 'state/current-user/selectors'; | ||
import { isUserPaid } from 'state/purchases/selectors'; | ||
import { getForumUrl } from 'my-sites/themes/helpers'; | ||
import { isPremiumTheme as isPremium } from 'state/themes/utils'; | ||
import ThanksModal from 'my-sites/themes/thanks-modal'; | ||
import QueryActiveTheme from 'components/data/query-active-theme'; | ||
|
@@ -37,7 +37,7 @@ import QueryUserPurchases from 'components/data/query-user-purchases'; | |
import QuerySitePurchases from 'components/data/query-site-purchases'; | ||
import ThemesSiteSelectorModal from 'my-sites/themes/themes-site-selector-modal'; | ||
import { connectOptions } from 'my-sites/themes/theme-options'; | ||
import { isThemeActive, isThemePurchased, getThemeRequestErrors } from 'state/themes/selectors'; | ||
import { isThemeActive, isThemePurchased, getThemeRequestErrors, getThemeForumUrl } from 'state/themes/selectors'; | ||
import { getBackPath } from 'state/themes/themes-ui/selectors'; | ||
import EmptyContentComponent from 'components/empty-content'; | ||
import ThemePreview from 'my-sites/themes/theme-preview'; | ||
|
@@ -156,6 +156,17 @@ const ThemeSheet = React.createClass( { | |
return null; | ||
}, | ||
|
||
renderPreviewButton() { | ||
return ( | ||
<a className="theme__sheet-preview-link" onClick={ this.togglePreview } data-tip-target="theme-sheet-preview"> | ||
<Gridicon icon="themes" size={ 18 } /> | ||
<span className="theme__sheet-preview-link-text"> | ||
{ i18n.translate( 'Open Live Demo', { context: 'Individual theme live preview button' } ) } | ||
</span> | ||
</a> | ||
); | ||
}, | ||
|
||
renderScreenshot() { | ||
let screenshot; | ||
if ( this.props.isJetpack ) { | ||
|
@@ -166,12 +177,7 @@ const ThemeSheet = React.createClass( { | |
const img = screenshot && <img className="theme__sheet-img" src={ screenshot + '?=w680' } />; | ||
return ( | ||
<div className="theme__sheet-screenshot"> | ||
<a className="theme__sheet-preview-link" onClick={ this.togglePreview } data-tip-target="theme-sheet-preview"> | ||
<Gridicon icon="themes" size={ 18 } /> | ||
<span className="theme__sheet-preview-link-text"> | ||
{ i18n.translate( 'Open Live Demo', { context: 'Individual theme live preview button' } ) } | ||
</span> | ||
</a> | ||
{ this.props.demo_uri && this.renderPreviewButton() } | ||
{ img } | ||
</div> | ||
); | ||
|
@@ -232,7 +238,7 @@ const ThemeSheet = React.createClass( { | |
</Card> | ||
{ this.renderFeaturesCard() } | ||
{ this.renderDownload() } | ||
{ this.renderRelatedThemes() } | ||
{ ! this.props.isJetpack && this.renderRelatedThemes() } | ||
</div> | ||
); | ||
}, | ||
|
@@ -261,6 +267,10 @@ const ThemeSheet = React.createClass( { | |
}, | ||
|
||
renderThemeForumCard( isPrimary = false ) { | ||
if ( ! this.props.forumUrl ) { | ||
return null; | ||
} | ||
|
||
const description = isPremium( this.props ) | ||
? i18n.translate( 'Get in touch with the theme author' ) | ||
: i18n.translate( 'Get help from volunteers and staff' ); | ||
|
@@ -272,7 +282,7 @@ const ThemeSheet = React.createClass( { | |
{ i18n.translate( 'Have a question about this theme?' ) } | ||
<small>{ description }</small> | ||
</div> | ||
<Button primary={ isPrimary } href={ getForumUrl( this.props ) }>Visit forum</Button> | ||
<Button primary={ isPrimary } href={ this.props.forumUrl }>Visit forum</Button> | ||
</Card> | ||
); | ||
}, | ||
|
@@ -310,16 +320,22 @@ const ThemeSheet = React.createClass( { | |
}, | ||
|
||
renderFeaturesCard() { | ||
const { siteSlug, taxonomies } = this.props; | ||
const themeFeatures = taxonomies && taxonomies.theme_feature instanceof Array | ||
? taxonomies.theme_feature.map( function( item ) { | ||
const { isJetpack, siteSlug, taxonomies } = this.props; | ||
if ( ! taxonomies || ! isArray( taxonomies.theme_feature ) ) { | ||
return null; | ||
} | ||
|
||
const themeFeatures = taxonomies.theme_feature.map( function( item ) { | ||
const term = isValidTerm( item.slug ) ? item.slug : `feature:${ item.slug }`; | ||
return ( | ||
<li key={ 'theme-features-item-' + item.slug }> | ||
<a href={ `/design/filter/${ term }/${ siteSlug || '' }` }>{ item.name }</a> | ||
{ isJetpack | ||
? <a>{ item.name }</a> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just curious if adding the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, we're styling it. (I had removed it and noticed it didn't look the same.) I opted for keeping the element instead of tweaking the styling 😄 |
||
: <a href={ `/design/filter/${ term }/${ siteSlug || '' }` }>{ item.name }</a> | ||
} | ||
</li> | ||
); | ||
} ) : []; | ||
} ); | ||
|
||
return ( | ||
<div> | ||
|
@@ -334,7 +350,13 @@ const ThemeSheet = React.createClass( { | |
}, | ||
|
||
renderDownload() { | ||
if ( isPremium( this.props ) ) { | ||
// Don't render download button: | ||
// * If it's a premium theme | ||
// * If it's on a Jetpack site, and the theme object doesn't have a 'download' attr | ||
// Note that not having a 'download' attr would be permissible for a theme on WPCOM | ||
// since we don't provide any for some themes found on WordPress.org (notably the 'Twenties'). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Think it is just Twenty Sixteen There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked a bunch of other Twenties to which the same seems to apply, but possibly not all of them. |
||
// The <ThemeDownloadCard /> component can handle that case. | ||
if ( isPremium( this.props ) || ( this.props.isJetpack && ! this.props.download ) ) { | ||
return null; | ||
} | ||
return <ThemeDownloadCard theme={ this.props.id } href={ this.props.download } />; | ||
|
@@ -426,7 +448,7 @@ const ThemeSheet = React.createClass( { | |
const analyticsPath = `/theme/:slug${ section ? '/' + section : '' }${ siteID ? '/:site_id' : '' }`; | ||
const analyticsPageTitle = `Themes > Details Sheet${ section ? ' > ' + titlecase( section ) : '' }${ siteID ? ' > Site' : '' }`; | ||
|
||
const { name: themeName, description, currentUserId, siteIdOrWpcom } = this.props; | ||
const { name: themeName, description, currentUserId, isJetpack, siteIdOrWpcom } = this.props; | ||
const title = themeName && i18n.translate( '%(themeName)s Theme', { | ||
args: { themeName } | ||
} ); | ||
|
@@ -451,6 +473,7 @@ const ThemeSheet = React.createClass( { | |
return ( | ||
<Main className="theme__sheet"> | ||
<QueryTheme themeId={ this.props.id } siteId={ siteIdOrWpcom } /> | ||
{ isJetpack && <QueryTheme themeId={ this.props.id } siteId="wporg" /> } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need the two instances of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, the first one fetches the theme object from the JP site, and the second one fetches the supplementary one from the WP.org API. |
||
{ currentUserId && <QueryUserPurchases userId={ currentUserId } /> } | ||
{ siteID && <QuerySitePurchases siteId={ siteID } /> } | ||
{ siteID && <QuerySitePlans siteId={ siteID } /> } | ||
|
@@ -576,6 +599,7 @@ export default connect( | |
const isCurrentUserPaid = isUserPaid( state, currentUserId ); | ||
const theme = getTheme( state, siteIdOrWpcom, id ); | ||
const error = theme ? false : getThemeRequestErrors( state, id, siteIdOrWpcom ); | ||
|
||
return { | ||
...theme, | ||
id, | ||
|
@@ -593,6 +617,7 @@ export default connect( | |
isThemePurchased( state, id, selectedSite.ID ) || | ||
hasFeature( state, selectedSite.ID, FEATURE_UNLIMITED_PREMIUM_THEMES ) | ||
), | ||
forumUrl: selectedSite && getThemeForumUrl( state, id, selectedSite.ID ) | ||
}; | ||
} | ||
)( ThemeSheetWithOptions ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A theme can only be active on an actual site, not on all of WP.com 😄
(Discovered while adding
wporg
to some otherpropTypes
andschema
s.)