class Favourites { constructor() { // Initialize DataStore for queue persistence let store = window.jvbStore.register( 'favourites', { storeName: 'favourites', keyPath: 'id', endpoint: 'favourites', headers: { 'X-Action-Nonce': window.auth.getNonce('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.store = store.favourites; // 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; } }); } 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']; window.debouncer.schedule( `favourite-${button.dataset.id}`, this.postFavourite({ user: window.auth.getUser(), target_id: button.dataset.id, action: action, type: button.dataset.type }), 100 ); } async postFavourite(args) { await window.auth.fetch( `${jvbSettings.api}favourites`, { method: 'POST', headers: { 'X-Action-Nonce': window.auth.getNonce('favourites') }, body: args } ); if (args.action === 'add') { await this.store.setItem(button.dataset.id, { target_id: button.dataset.id, action: action, type: button.dataset.type, }).then(()=>{}); } else { await this.store.delete(button.dataset.id).then(()=>{}); } } // 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; window.auth.subscribe((event) => { if (event === 'auth-loaded') { window.jvbFavourites = new Favourites(); } }); }); 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); }