From f4be611c51473359e6d41780f0313c446079e9d3 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Tue, 09 Jun 2026 15:19:24 +0000
Subject: [PATCH] =Switched the /base/options.php to the same pattern as Site.php: a class based approached rather than a filter. Updated Meta.php to play along with the defined fields from there in Meta::forOptions. Had to change openingHoursSpecificationsTrait.php to not use the translater functions __('text','textdomain') for now, as we load before init.
---
assets/js/concise/FrontendFavourites.js | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 209 insertions(+), 30 deletions(-)
diff --git a/assets/js/concise/FrontendFavourites.js b/assets/js/concise/FrontendFavourites.js
index 2ef641b..f986ff1 100644
--- a/assets/js/concise/FrontendFavourites.js
+++ b/assets/js/concise/FrontendFavourites.js
@@ -1,21 +1,46 @@
-class FrontendFavourites {
+class Favourites {
constructor() {
// Initialize DataStore for queue persistence
- this.store = new window.jvbStore({
- name: 'favourites',
- endpoint: 'favourites',
- useIndexedDB: true,
- TTL: Infinity,
- showLoading: false,
- filters: {
- user: jvbSettings.currentUser,
- content: 'all',
- order: 'desc',
- orderby: 'date',
- page: 1,
- all: true,
- }
- });
+ 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.queue = {
+ add: new Map(),
+ remove: new Map(),
+ };
+
+ 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) {
@@ -32,12 +57,10 @@
}
});
-
- this.store.fetch();
}
toggleFavourite(button) {
- if (!jvbSettings.currentUser) {
+ if (!window.auth.getUser()) {
window.location.href = jvbSettings.redirect + '&action=register&type=favourites';
return;
}
@@ -53,27 +76,183 @@
// Update button icon
button.innerHTML = jvbSettings.icons[button.classList.contains('favourited') ? 'heart-filled' : 'heart'];
- this.store.setItem(button.dataset.id, {
+ this.checkQueue(action, {
target_id: button.dataset.id,
action: action,
- type: button.dataset.type,
- artist: button.dataset.artist,
+ type: button.dataset.type
});
+ window.debouncer.schedule('favourites', this.postFavourites.bind(this), 200);
+
+
}
- isFavourited(content, id){
- if(!jvbSettings.currentUser){
- return false;
+ checkQueue(action, item) {
+ switch (action) {
+ case 'add':
+ if (this.queue.remove.has(item.target_id)) {
+ this.queue.remove.delete(item.target_id);
+ }
+ this.queue.add.set(item.target_id, item);
+ break;
+ case 'remove':
+ if (this.queue.add.has(item.target_id)) {
+ this.queue.add.delete(item.target_id);
+ }
+ this.queue.remove.set(item.target_id, item);
+ break;
+ default:
+ return;
}
- let item = this.store.getItem(id);
- return (item) ? item.action === 'add' : false;
+ }
+ async postFavourites() {
+ console.log(this.queue,'Posting favourites');
+ const response = await window.auth.fetch(
+ `${jvbSettings.api}favourites`,
+ {
+ method: 'POST',
+ headers: {
+ 'X-Action-Nonce': window.auth.getNonce('favourites')
+ },
+ body: {
+ user: window.auth.getUser(),
+ ... this.queue
+ }
+ }
+ );
+
+ if (response.ok) {
+ console.log('Posted favourites - clearing queue');
+ //Add or remove from store
+ for (let item of this.queue.add.entries()) {
+ await this.store.setItem(item.target_id,
+ item);
+ }
+ for (let item of this.queue.remove.entries()) {
+ await this.store.delete(item.target_id);
+ }
+ //Clear the favourite queue
+ this.queue.add.clear();
+ this.queue.remove.clear();
+ } else {
+ console.log(await response.json(), 'Something went wrong');
+ window.debouncer.schedule('favourites', this.postFavourites.bind(this), 200);
+ }
+ }
+
+ // 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 (jvbSettings.currentUser !== '') {
- window.jvbFavourites = new FrontendFavourites();
- }
+ window.auth.subscribe((event) => {
+ if (event === 'auth-loaded') {
+ window.jvbFavourites = new Favourites();
+ }
+ });
});
--
Gitblit v1.10.0