| | 216 | }, |
| | 217 | |
| | 218 | // Handles requests for more themes |
| | 219 | // and caches results |
| | 220 | // |
| | 221 | // When we are missing a cache object we fire an apiCall() |
| | 222 | // which triggers events of `query:success` or `query:fail` |
| | 223 | query: function( request ) { |
| | 224 | /** |
| | 225 | * @static |
| | 226 | * @type Array |
| | 227 | */ |
| | 228 | var queries = this.queries, |
| | 229 | self = this, |
| | 230 | query, paginatedQuery, combined; |
| | 231 | |
| | 232 | // Search the query cache for matches. |
| | 233 | query = _.find( queries, function( query ) { |
| | 234 | return _.isEqual( query.request, request ); |
| | 235 | }); |
| | 236 | |
| | 237 | // If the request matches the stored currentQuery.request |
| | 238 | // it means we have a paginated request. |
| | 239 | isPaginated = _.isEqual( self.currentQuery.request, request ); |
| | 240 | |
| | 241 | // Reset the internal api page counter for non paginated queries. |
| | 242 | if ( ! isPaginated ) { |
| | 243 | this.currentQuery.page = 1; |
| | 244 | } |
| | 245 | |
| | 246 | // Otherwise, send a new API call and add it to the cache. |
| | 247 | if ( ! query ) { |
| | 248 | query = this.apiCall( request ).done( function( data ) { |
| | 249 | // Update the collection with the queried data. |
| | 250 | self.reset( data.themes ); |
| | 251 | |
| | 252 | // Trigger a `query:success` event |
| | 253 | // and a collection refresh event so the views are aware of changes. |
| | 254 | self.trigger( 'query:success' ); |
| | 255 | self.trigger( 'update' ); |
| | 256 | |
| | 257 | // Store the results and the query request |
| | 258 | queries.push( { themes: data.themes, request: request } ); |
| | 259 | }).fail( function() { |
| | 260 | self.trigger( 'query:fail' ); |
| | 261 | }); |
| | 262 | } else { |
| | 263 | // If it's a paginated request we need to fetch more themes... |
| | 264 | if ( isPaginated ) { |
| | 265 | return this.apiCall( request, isPaginated ).done( function( data ) { |
| | 266 | // Add the new themes to the current collection |
| | 267 | // @todo update counter |
| | 268 | self.add( data.themes ); |
| | 269 | self.trigger( 'query:success' ); |
| | 270 | |
| | 271 | }).fail( function() { |
| | 272 | self.trigger( 'query:fail' ); |
| | 273 | }); |
| | 274 | } |
| | 275 | |
| | 276 | // Only trigger an update event since we already have the themes |
| | 277 | // on our cached object |
| | 278 | this.reset( query.themes ); |
| | 279 | this.trigger( 'update' ); |
| | 280 | } |
| | 281 | }, |
| | 282 | |
| | 283 | // Local cache array for API queries |
| | 284 | queries: [], |
| | 285 | |
| | 286 | // Keep track of current query so we can handle pagination |
| | 287 | currentQuery: { |
| | 288 | page: 1, |
| | 289 | request: {} |
| | 290 | }, |
| | 291 | |
| | 292 | // Send Ajax POST request to api.wordpress.org/themes |
| | 293 | apiCall: function( request, paginated ) { |
| | 294 | // Store current query request args |
| | 295 | // for later use with the event `theme:end` |
| | 296 | this.currentQuery.request = request; |
| | 297 | |
| | 298 | // Ajax request to .org API |
| | 299 | return $.ajax({ |
| | 300 | url: 'https://api.wordpress.org/themes/info/1.1/?action=query_themes', |
| | 301 | |
| | 302 | // We want JSON data |
| | 303 | dataType: 'json', |
| | 304 | type: 'POST', |
| | 305 | crossDomain: true, |
| | 306 | |
| | 307 | // Request data |
| | 308 | data: { |
| | 309 | action: 'query_themes', |
| | 310 | request: _.extend({ |
| | 311 | per_page: 72, |
| | 312 | page: this.currentQuery.page, |
| | 313 | fields: { |
| | 314 | description: true, |
| | 315 | tested: true, |
| | 316 | requires: true, |
| | 317 | rating: true, |
| | 318 | downloaded: true, |
| | 319 | downloadLink: true, |
| | 320 | last_updated: true, |
| | 321 | homepage: true, |
| | 322 | num_ratings: true |
| | 323 | } |
| | 324 | }, request) |
| | 325 | }, |
| | 326 | |
| | 327 | beforeSend: function() { |
| | 328 | if ( ! paginated ) { |
| | 329 | // Spin it |
| | 330 | $( 'body' ).addClass( 'loading-themes' ); |
| | 331 | } |
| | 332 | } |
| | 333 | }); |
| 994 | | // Send Ajax POST request to api.wordpress.org/themes |
| 995 | | themes.view.Installer.prototype.apiCall( request ).done( function( data ) { |
| 996 | | // Update the collection with the queried data |
| 997 | | self.collection.reset( data.themes ); |
| 998 | | // Trigger a collection refresh event to render the views |
| 999 | | self.collection.trigger( 'update' ); |
| 1000 | | |
| 1001 | | // Un-spin it |
| 1002 | | $( 'body' ).removeClass( 'loading-themes' ); |
| 1003 | | $( '.theme-browser' ).find( 'div.error' ).remove(); |
| 1004 | | }).fail( function() { |
| 1005 | | $( '.theme-browser' ).find( 'div.error' ).remove(); |
| 1006 | | $( '.theme-browser' ).append( '<div class="error"><p>' + l10n.error + '</p></div>' ); |
| 1007 | | }); |
| 1008 | | |
| 1009 | | return false; |
| 1010 | | } |
| | 1117 | // Get the themes by sending Ajax POST request to api.wordpress.org/themes |
| | 1118 | // or searching the local cache |
| | 1119 | this.collection.query( request ); |
| | 1120 | }, 300 ), |
| 1068 | | // Create a new collection with the proper theme data |
| 1069 | | // for each section |
| 1070 | | this.apiCall({ browse: section }).done( function( data ) { |
| 1071 | | // Update the collection with the queried data |
| 1072 | | self.collection.reset( data.themes ); |
| 1073 | | // Trigger a collection refresh event to render the views |
| 1074 | | self.collection.trigger( 'update' ); |
| | 1141 | // Bump `collection.currentQuery.page` and request more themes if we hit the end of the page. |
| | 1142 | this.listenTo( this, 'theme:end', function() { |
| | 1143 | self.collection.currentQuery.page++; |
| | 1144 | self.collection.query( self.collection.currentQuery.request ); |
| | 1145 | }); |
| 1161 | | // Send Ajax POST request to api.wordpress.org/themes |
| 1162 | | this.apiCall( request ).done( function( data ) { |
| 1163 | | // Update the collection with the queried data |
| 1164 | | self.collection.reset( data.themes ); |
| 1165 | | // Trigger a collection refresh event to render the views |
| 1166 | | self.collection.trigger( 'update' ); |
| 1167 | | |
| 1168 | | // Un-spin it |
| 1169 | | $( 'body' ).removeClass( 'loading-themes' ); |
| 1170 | | $( '.theme-browser' ).find( 'div.error' ).remove(); |
| 1171 | | }).fail( function() { |
| 1172 | | $( '.theme-browser' ).find( 'div.error' ).remove(); |
| 1173 | | $( '.theme-browser' ).append( '<div class="error"><p>' + l10n.error + '</p></div>' ); |
| 1174 | | }); |
| 1175 | | |
| 1176 | | return false; |
| | 1239 | // Get the themes by sending Ajax POST request to api.wordpress.org/themes |
| | 1240 | // or searching the local cache |
| | 1241 | this.collection.query( request ); |
| 1185 | | // Send Ajax POST request to api.wordpress.org/themes |
| 1186 | | this.apiCall( request ).done( function( data ) { |
| 1187 | | // Update the collection with the queried data |
| 1188 | | self.collection.reset( data.themes ); |
| 1189 | | // Trigger a collection refresh event to render the views |
| 1190 | | self.collection.trigger( 'update' ); |
| 1191 | | |
| 1192 | | // Un-spin it |
| 1193 | | $( 'body' ).removeClass( 'loading-themes' ); |
| 1194 | | $( '.theme-browser' ).find( 'div.error' ).remove(); |
| 1195 | | }).fail( function() { |
| 1196 | | $( '.theme-browser' ).find( 'div.error' ).remove(); |
| 1197 | | $( '.theme-browser' ).append( '<div class="error"><p>' + l10n.error + '</p></div>' ); |
| 1198 | | }); |
| | 1250 | // Get the themes by sending Ajax POST request to api.wordpress.org/themes |
| | 1251 | // or searching the local cache |
| | 1252 | this.collection.query( request ); |