Theme Installer: Handle currently installed themes, add search route, let prev/next refresh collections.

props matveb.
see #27055. fixes #27695.


git-svn-id: https://develop.svn.wordpress.org/trunk@28025 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Nacin 2014-04-07 23:03:05 +00:00
parent e28f610ead
commit bcc41afd37
3 changed files with 83 additions and 17 deletions

View File

@ -216,7 +216,8 @@
* Displays a theme update notice
* when an update is available.
*/
.theme-browser .theme .theme-update {
.theme-browser .theme .theme-update,
.theme-browser .theme .theme-installed {
background: #d54e21;
background: rgba(213, 78, 33, 0.95);
color: #fff;
@ -234,7 +235,8 @@
overflow: hidden;
}
.theme-browser .theme .theme-update:before {
.theme-browser .theme .theme-update:before,
.theme-browser .theme .theme-installed:before {
content: '\f463';
display: inline-block;
font: normal 20px/1 'dashicons';
@ -1074,6 +1076,25 @@ body.folded .theme-overlay .theme-wrap {
16.2 - Install Themes
------------------------------------------------------------------------------*/
/* Already installed theme */
.theme-browser .theme.is-installed {
cursor: default;
}
.theme-browser .theme .theme-installed {
background: #0074a2;
}
.theme-browser .theme .theme-installed:before {
content: '\f147';
}
.theme-browser .theme.is-installed .theme-actions,
.theme-browser.rendered .theme.is-installed .more-details {
display: none !important;
}
.theme-browser.rendered .theme.is-installed:hover .theme-screenshot img,
.theme-browser.rendered .theme.is-installed:focus .theme-screenshot img {
opacity: 1 !important;
}
.theme-navigation {
background: #fff;
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);

View File

@ -22,7 +22,7 @@ themes.Model = Backbone.Model.extend({
// Adds attributes to the default data coming through the .org themes api
// Map `id` to `slug` for shared code
initialize: function() {
var install, preview;
var install, installed;
// Install url for the theme
// using the install nonce
@ -35,18 +35,14 @@ themes.Model = Backbone.Model.extend({
// Build the url query
install = themes.data.settings.updateURI + '?' + $.param( install );
// Preview url for the theme
preview = {
tab: 'theme-information',
theme: this.get( 'slug' )
};
preview = themes.data.settings.installURI + '?' + $.param( preview );
// If theme is already installed, set an attribute.
if ( _.indexOf( themes.data.installedThemes, this.get( 'slug' ) ) !== -1 ) {
this.set({ installed: true });
}
// Set the attributes
this.set({
installURI: install,
previewURI: preview,
installURI: ( this.get( 'slug' ) ) ? install : false,
// slug is for installation, id is for existing.
id: this.get( 'slug' ) || this.get( 'id' )
});
@ -391,6 +387,11 @@ themes.view.Theme = wp.Backbone.View.extend({
if ( this.model.get( 'displayAuthor' ) ) {
this.$el.addClass( 'display-author' );
}
if ( this.model.get( 'installed' ) ) {
this.$el.addClass( 'is-installed' );
this.$el.unbind();
}
},
// Adds a class to the currently active theme
@ -451,6 +452,11 @@ themes.view.Theme = wp.Backbone.View.extend({
return this.touchDrag = false;
}
// Allow direct link path to installing a theme.
if ( $( event.target ).hasClass( 'button-primary' ) ) {
return;
}
// 'enter' and 'space' keys expand the details view when a theme is :focused
if ( event.type === 'keydown' && ( event.which !== 13 && event.which !== 32 ) ) {
return;
@ -494,6 +500,7 @@ themes.view.Theme = wp.Backbone.View.extend({
// If we have no more themes, bail.
if ( _.isUndefined( self.current ) ) {
self.options.parent.parent.trigger( 'theme:end' );
return self.current = current;
}
@ -505,6 +512,7 @@ themes.view.Theme = wp.Backbone.View.extend({
// Render and append.
preview.render();
$( 'div.wrap' ).append( preview.el );
$( '.next-theme' ).focus();
})
.listenTo( preview, 'theme:previous', function() {
@ -532,6 +540,7 @@ themes.view.Theme = wp.Backbone.View.extend({
// Render and append.
preview.render();
$( 'div.wrap' ).append( preview.el );
$( '.previous-theme' ).focus();
});
}
});
@ -882,7 +891,8 @@ themes.view.Themes = wp.Backbone.View.extend({
// Loop through the themes and setup each theme view
self.instance.each( function( theme ) {
self.theme = new themes.view.Theme({
model: theme
model: theme,
parent: self
});
// Render the views...
@ -1158,8 +1168,7 @@ themes.Run = {
// Handles search route event
themes.router.on( 'route:search', function( query ) {
self.view.trigger( 'theme:close' );
self.themes.doSearch( query );
$( '.theme-search' ).trigger( 'keyup' );
});
this.extraRoutes();
@ -1224,6 +1233,9 @@ themes.view.InstallerSearch = themes.view.Search.extend({
// Get the themes by sending Ajax POST request to api.wordpress.org/themes
// or searching the local cache
this.collection.query( request );
// Set route
themes.router.navigate( themes.router.baseUrl( '?search=' + value ), { replace: true } );
}, 300 )
});
@ -1329,7 +1341,7 @@ themes.view.Installer = themes.view.Appearance.extend({
},
sort: function( sort ) {
$( '#theme-search-input' ).val( '' );
this.clearSearch();
$( '.theme-section, .theme-filter' ).removeClass( this.activeClass );
$( '[data-sort="' + sort + '"]' ).addClass( this.activeClass );
@ -1450,6 +1462,9 @@ themes.view.Installer = themes.view.Appearance.extend({
return this.addFilter();
}
this.clearSearch();
themes.router.navigate( themes.router.baseUrl( '' ) );
$( 'body' ).toggleClass( 'more-filters-opened' );
},
@ -1474,6 +1489,10 @@ themes.view.Installer = themes.view.Appearance.extend({
backToFilters: function() {
$( 'body' ).removeClass( 'filters-applied' );
},
clearSearch: function() {
$( '#theme-search-input').val( '' );
}
});
@ -1482,12 +1501,17 @@ themes.InstallerRouter = Backbone.Router.extend({
'theme-install.php?theme=:slug': 'preview',
'theme-install.php?sort=:sort': 'sort',
'theme-install.php?upload': 'upload',
'theme-install.php?search=:query': 'search',
'': 'sort'
},
baseUrl: function( url ) {
return 'theme-install.php' + url;
}
},
search: function( query ) {
$( '.theme-search' ).val( query );
},
});
@ -1542,6 +1566,11 @@ themes.RunInstaller = {
$( 'a.upload' ).trigger( 'click' );
});
// Handles search route event
themes.router.on( 'route:search', function( query ) {
$( '.theme-search' ).focus().trigger( 'keyup' );
});
this.extraRoutes();
},

View File

@ -33,6 +33,13 @@ $sections = array(
'new' => __( 'Newest Themes' ),
);
$installed_themes = search_theme_directories();
foreach ( $installed_themes as $k => $v ) {
if ( false !== strpos( $k, '/' ) ) {
unset( $installed_themes[ $k ] );
}
}
wp_localize_script( 'theme', '_wpThemeSettings', array(
'themes' => false,
'settings' => array(
@ -51,6 +58,7 @@ wp_localize_script( 'theme', '_wpThemeSettings', array(
'back' => __( 'Back' ),
'error' => ( 'There was a problem trying to load the themes. Please, try again.' ), // @todo improve
),
'installedThemes' => array_keys( $installed_themes ),
'browse' => array(
'sections' => $sections,
),
@ -190,13 +198,21 @@ if ( $tab ) {
<a class="button button-primary" href="{{ data.installURI }}"><?php esc_html_e( 'Install' ); ?></a>
<a class="button button-secondary preview install-theme-preview" href="#"><?php esc_html_e( 'Preview' ); ?></a>
</div>
<# if ( data.installed ) { #>
<div class="theme-installed"><?php _e( 'Already Installed' ); ?></div>
<# } #>
</script>
<script id="tmpl-theme-preview" type="text/template">
<div class="wp-full-overlay-sidebar">
<div class="wp-full-overlay-header">
<a href="#" class="close-full-overlay button-secondary"><?php _e( 'Close' ); ?></a>
<# if ( data.installed ) { #>
<a href="#" class="button button-primary theme-install disabled"><?php _e( 'Installed' ); ?></a>
<# } else { #>
<a href="{{ data.installURI }}" class="button button-primary theme-install"><?php _e( 'Install' ); ?></a>
<# } #>
</div>
<div class="wp-full-overlay-sidebar-content">
<div class="install-theme-info">