/** * FediStream Library JavaScript * * @package WP_FediStream */ ( function( $ ) { 'use strict'; const Library = { currentTab: 'favorites', currentPage: { favorites: 1, artists: 1, history: 1 }, currentFilter: 'all', isLoading: false, init: function() { this.bindEvents(); this.loadInitialTab(); }, bindEvents: function() { const self = this; // Tab navigation. $( '.fedistream-library-nav .tab-btn' ).on( 'click', function() { const tab = $( this ).data( 'tab' ); self.switchTab( tab ); } ); // Filter change. $( '.fedistream-library-filters .filter-type' ).on( 'change', function() { self.currentFilter = $( this ).val(); self.currentPage.favorites = 1; self.loadFavorites(); } ); // Clear history. $( '.btn-clear-history' ).on( 'click', function() { self.clearHistory(); } ); // Pagination clicks. $( document ).on( 'click', '.library-pagination .page-btn', function() { const page = $( this ).data( 'page' ); const tab = $( this ).closest( '.library-pagination' ).data( 'tab' ); self.goToPage( tab, page ); } ); // Unfavorite button. $( document ).on( 'click', '.unfavorite-btn', function() { const btn = $( this ); const contentType = btn.data( 'content-type' ); const contentId = btn.data( 'content-id' ); self.toggleFavorite( contentType, contentId, btn.closest( '.library-item' ) ); } ); // Unfollow button. $( document ).on( 'click', '.unfollow-btn', function() { const btn = $( this ); const artistId = btn.data( 'artist-id' ); self.toggleFollow( artistId, btn.closest( '.library-item' ) ); } ); // Play button. $( document ).on( 'click', '.play-btn', function( e ) { e.preventDefault(); const trackId = $( this ).data( 'track-id' ); self.playTrack( trackId ); } ); }, loadInitialTab: function() { const initialTab = $( '.fedistream-library' ).data( 'initial-tab' ) || 'favorites'; this.switchTab( initialTab ); }, switchTab: function( tab ) { this.currentTab = tab; // Update nav. $( '.fedistream-library-nav .tab-btn' ).removeClass( 'active' ); $( '.fedistream-library-nav .tab-btn[data-tab="' + tab + '"]' ).addClass( 'active' ); // Update content. $( '.tab-content' ).removeClass( 'active' ); $( '#tab-' + tab ).addClass( 'active' ); // Show/hide filters. if ( tab === 'favorites' ) { $( '.fedistream-library-filters' ).show(); } else { $( '.fedistream-library-filters' ).hide(); } // Load content. this.loadTabContent( tab ); }, loadTabContent: function( tab ) { switch ( tab ) { case 'favorites': this.loadFavorites(); break; case 'artists': this.loadArtists(); break; case 'history': this.loadHistory(); break; } }, loadFavorites: function() { const self = this; if ( this.isLoading ) { return; } this.showLoading(); $.ajax( { url: fedistreamLibrary.ajaxUrl, type: 'POST', data: { action: 'fedistream_get_library', nonce: fedistreamLibrary.nonce, type: this.currentFilter, page: this.currentPage.favorites }, success: function( response ) { self.hideLoading(); if ( response.success ) { self.renderFavorites( response.data ); } else { self.showError( response.data.message ); } }, error: function() { self.hideLoading(); self.showError( fedistreamLibrary.i18n.error ); } } ); }, loadArtists: function() { const self = this; if ( this.isLoading ) { return; } this.showLoading(); $.ajax( { url: fedistreamLibrary.ajaxUrl, type: 'POST', data: { action: 'fedistream_get_followed_artists', nonce: fedistreamLibrary.nonce, page: this.currentPage.artists }, success: function( response ) { self.hideLoading(); if ( response.success ) { self.renderArtists( response.data ); } else { self.showError( response.data.message ); } }, error: function() { self.hideLoading(); self.showError( fedistreamLibrary.i18n.error ); } } ); }, loadHistory: function() { const self = this; if ( this.isLoading ) { return; } this.showLoading(); $.ajax( { url: fedistreamLibrary.ajaxUrl, type: 'POST', data: { action: 'fedistream_get_history', nonce: fedistreamLibrary.nonce, page: this.currentPage.history }, success: function( response ) { self.hideLoading(); if ( response.success ) { self.renderHistory( response.data ); } else { self.showError( response.data.message ); } }, error: function() { self.hideLoading(); self.showError( fedistreamLibrary.i18n.error ); } } ); }, renderFavorites: function( data ) { const container = $( '.favorites-grid' ); container.empty(); if ( ! data.items || data.items.length === 0 ) { container.html( '
' ); $( '.library-pagination[data-tab="favorites"]' ).empty(); return; } data.items.forEach( function( item ) { container.append( this.createFavoriteItem( item ) ); }, this ); this.renderPagination( 'favorites', data ); }, renderArtists: function( data ) { const container = $( '.artists-grid' ); container.empty(); if ( ! data.artists || data.artists.length === 0 ) { container.html( '' ); $( '.library-pagination[data-tab="artists"]' ).empty(); return; } data.artists.forEach( function( artist ) { container.append( this.createArtistItem( artist ) ); }, this ); this.renderPagination( 'artists', data ); }, renderHistory: function( data ) { const container = $( '.history-list' ); container.empty(); if ( ! data.tracks || data.tracks.length === 0 ) { container.html( '' ); $( '.library-pagination[data-tab="history"]' ).empty(); return; } data.tracks.forEach( function( track ) { container.append( this.createHistoryItem( track ) ); }, this ); this.renderPagination( 'history', data ); }, createFavoriteItem: function( item ) { const thumbnail = item.thumbnail ? '' + this.escapeHtml( item.artist ) + '
' : ''; let metaInfo = ''; if ( item.type === 'track' && item.duration ) { metaInfo = '' + this.formatDuration( item.duration ) + '
'; } else if ( item.type === 'album' && item.track_count ) { metaInfo = '' + item.track_count + ' tracks
'; } return ` `; }, createArtistItem: function( artist ) { const thumbnail = artist.thumbnail ? '' + this.escapeHtml( track.artist ) + '
' : ''; const duration = track.duration ? '' + this.formatDuration( track.duration ) + '' : ''; return `${this.formatPlayedTime( track.played_at )}