class FrontendFavourites { constructor() { // Initialize DataStore for queue persistence this.store = window.jvbStore.register( 'favourites', { storeName: 'favourites', endpoint: 'favourites', indexes: [ {name: 'content', keyPath: 'content'}, {name: 'listId', keyPath: 'listId'}, ], TTL: 6 * 60 * 1000, showLoading: false, filters: { user: window.auth.getUser(), content: 'all', order: 'desc', orderby: 'date', page: 1, all: true, } }); this.listStore = window.jvbStore.register( 'favourites_lists', { storeName: 'lists', keyPath: 'listId', endpoint: 'favourites/lists', TTL: 6 * 60 * 1000, }); this.store.subscribe((event, data) => { switch (event) { case 'data-fetched': case 'data-cached': // this.updateOperationsFromServer(data.data.items); break; case 'items-updated': // this.updateOperationsFromServer(data.items); break; case 'item-stored': // this.updateOperationsFromServer([data]) break; } }); this.store.fetch(); } toggleFavourite(button) { if (!window.auth.getUser()) { window.location.href = jvbSettings.redirect + '&action=register&type=favourites'; return; } // Toggle UI immediately button.classList.toggle('favourited'); const action = button.classList.contains('favourited') ? 'add' : 'remove'; const message = button.classList.contains('favourited') ? `Added ${button.dataset.type} to favourites.` : `Removed ${button.dataset.type} from favourites.`; window.jvbA11y.announce(message); // Update button icon button.innerHTML = jvbSettings.icons[button.classList.contains('favourited') ? 'heart-filled' : 'heart']; this.store.setItem(button.dataset.id, { target_id: button.dataset.id, action: action, type: button.dataset.type, artist: button.dataset.artist, }); } // async toggleFavourite(itemType, itemId) { // const favId = `${this.userId}_${itemType}_${itemId}`; // const existing = this.store.get(favId); // // if (existing) { // // Remove favorite // await this.store.delete(favId); // // // Queue for server deletion // if (window.jvbQueue) { // window.jvbQueue.addOperation({ // type: 'remove_favourite', // endpoint: 'favourites', // data: { favId } // }); // } // // return false; // Not favorited anymore // // } else { // // Add favorite // const favourite = { // id: favId, // userId: this.userId, // itemType, // itemId, // listId: 'default', // timestamp: Date.now() // }; // // await this.store.save(favourite); // // // Queue for server save // if (window.jvbQueue) { // window.jvbQueue.addOperation({ // type: 'add_favourite', // endpoint: 'favourites', // data: favourite // }); // } // // return true; // Now favorited // } // } // async createList(name, visibility = 'private') { // const list = { // listId: `list_${Date.now()}`, // userId: this.userId, // name, // visibility, // created: Date.now(), // itemCount: 0 // }; // // await this.listsStore.save(list); // // // Queue for server // if (window.jvbQueue) { // window.jvbQueue.addOperation({ // type: 'create_list', // endpoint: 'favourite-lists', // data: list // }); // } // // return list; // } // // async addToList(listId, itemType, itemId) { // const favId = `${this.userId}_${itemType}_${itemId}_${listId}`; // // const favourite = { // id: favId, // userId: this.userId, // itemType, // itemId, // listId, // timestamp: Date.now() // }; // // await this.store.save(favourite); // // // Update list count // const list = this.listsStore.get(listId); // if (list) { // list.itemCount++; // await this.listsStore.save(list); // } // // // Queue for server // if (window.jvbQueue) { // window.jvbQueue.addOperation({ // type: 'add_to_list', // endpoint: 'favourites', // data: favourite // }); // } // } isFavourited(itemType, itemId) { const favId = `${this.userId}_${itemType}_${itemId}`; return this.store.get(favId) !== undefined; } } document.addEventListener('DOMContentLoaded', function() { window.jvbFavourites = false; if (window.auth.getUser() !== '') { window.jvbFavourites = new FrontendFavourites(); } }); window.toggleFavourite = function(button) { if (!window.jvbFavourites()) { console.log('No Favourites Loaded'); return; } window.jvbFavourites.toggleFavourite(button); } /** * Tests whether item is favourited by current user * @param content * @param id * @returns {*|boolean} */ window.isFavourited = function(content, id){ if (!window.jvbFavourites()) { console.log('No Favourites Loaded'); return; } return window.jvbFavourites.isFavourited(content, id); }