From a24a06002081ad71a78ffeff9072725ba39cf121 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Tue, 17 Feb 2026 20:05:31 +0000
Subject: [PATCH] =minor changes, particularly around the JVB_CHILD_URL pattern

---
 src/feed/view.js |   64 ++++++++++++++++++++++++--------
 1 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/src/feed/view.js b/src/feed/view.js
index 3590a17..87e79b9 100644
--- a/src/feed/view.js
+++ b/src/feed/view.js
@@ -66,22 +66,28 @@
 			buttons: {
 				loadMore: 		'button.load-more',
 				remove:			'.remove-term',
-				clearFilters: 	'button.clear-filters'
+				clearFilters: 	'button.clear-filters',
+				refresh:		'button[data-action="refresh"]'
 			}
 		};
 		this.ui = window.uiFromSelectors(this.selectors, this.container);
+		this.ui.buttons.refresh = document.querySelector(this.selectors.buttons.refresh);
 
 		//Add content and taxonomies
 		this.ui.content = this.ui.filters.container.querySelectorAll('[name="content"]');
 		if (this.ui.content.length === 0) this.ui.content = false;
 		this.ui.taxonomies = this.ui.filters.container.querySelectorAll('[data-taxonomy]');
-		if (this.ui.taxonomies.length === 0) this.ui.content = false;
+		if (this.ui.taxonomies.length === 0) this.ui.taxonomies = false;
 		this.ui.orderbyWrap = this.ui.filters.container.querySelector('[data-for-order]');
-		if (this.ui.orderbyWrap.length === 0) this.ui.content = false;
+		if (this.ui.orderbyWrap.length === 0) this.ui.orderbyWrap = false;
 		this.ui.order = this.ui.filters.container.querySelectorAll('[data-filter="order"]');
-		if (this.ui.order.length === 0) this.ui.content = false;
+		if (this.ui.order.length === 0) this.ui.order = false;
 		this.ui.orderby = this.ui.filters.container.querySelectorAll('[data-filter="orderby"]');
-		if (this.ui.orderby.length === 0) this.ui.content = false;
+		if (this.ui.orderby.length === 0) this.ui.orderby = false;
+
+		this.orderbyFilters = (this.ui.orderby)
+			? Array.from(this.ui.orderby).map(o => o.value)
+			: [];
 
 		this.contentTypes = (this.ui.content)
 			? Array.from(this.ui.content).map(c => c.value)
@@ -171,6 +177,18 @@
 		if (remove) {
 			this.removeSelectedTerm(remove);
 		}
+
+		let refresh = window.targetCheck(e, this.selectors.buttons.refresh);
+		if (refresh) {
+			this.store.clearCache();
+			this.store.fetch();
+		}
+
+		let orderbyButton = window.targetCheck(e, '[data-filter="orderby"]');
+		if (orderbyButton && orderbyButton.value === 'random' && orderbyButton.checked) {
+			// Already selected random, just re-render to trigger new shuffle
+			this.renderItems();
+		}
 	}
 
 	nextPage() {
@@ -425,6 +443,11 @@
 		}
 	}
 	initStore() {
+		let extraOrderby = this.orderbyFilters.filter(v => !['date','modified','title','random'].includes(v));
+		let extraIndexes = [];
+		extraOrderby.forEach(orderby =>{
+			extraIndexes.push({name:orderby, keyPath: orderby});
+		});
 		const store = window.jvbStore.register(
 			'feed',
 			{
@@ -435,8 +458,10 @@
 					{ name: 'content', keyPath: 'content'},
 					{ name: 'taxonomy', keyPath: 'taxonomy'},
 					{ name: 'user', keyPath: 'user'},
-					{ name: 'date', keyPath: 'modified'},
-					{ name: 'title', keyPath: 'title'}
+					{ name: 'date', keyPath: 'date'},
+					{ name: 'modified', keyPath: 'modified'},
+					{ name: 'title', keyPath: 'title'},
+					... extraIndexes
 				],
 				filters: this.filters,
 				TTL: 6 * 60 * 60 * 1000, //6 hours
@@ -444,12 +469,13 @@
 				required: 'content',
 			}
 		);
+
 		this.store = store.feed;
 
 		this.store.subscribe((event, data) => {
 			switch (event) {
 				case 'data-loaded':
-					this.renderItems();
+					this.renderItems(data.items);
 					this.ui.buttons.loadMore.hidden = true;
 					if (this.store.lastResponse && this.store.lastResponse?.has_more) {
 						this.ui.buttons.loadMore.hidden = !this.store.lastResponse?.has_more??true;
@@ -463,8 +489,8 @@
 		return this.store.filters.page === 1;
 	}
 
-	renderItems() {
-		let items = this.store.getFiltered();
+	renderItems(items = null) {
+		items = items??this.store.getFiltered();
 		if (this.isFirstPage()) {
 			window.removeChildren(this.ui.grid);
 		}
@@ -495,6 +521,10 @@
 	}
 
 	createItemElement(item) {
+		if (typeof item !== 'object') {
+			item = this.store.get(item);
+			if (!item) return;
+		}
 		return this.templates.create(`feedItem${window.uppercaseFirst(item.content)}`, item);
 	}
 	splitIDs(value) {
@@ -566,14 +596,16 @@
 			let link = termItem.querySelector('a');
 			if (!link) continue;
 
+			let title = window.decodeHTMLEntities(term.title);
+
 			[
 				link.href,
 				link.title,
 				link.textContent
 			] = [
 				term.url,
-				`See more ${term.title}`,
-				term.title
+				`See more ${title}`,
+				title
 			];
 			element.append(termItem);
 		}
@@ -591,7 +623,7 @@
 		element.textContent = window.formatTimeAgo(value, 'F Y');
 	}
 	formatField(element, value) {
-		element.textContent = value;
+		element.textContent = window.decodeHTMLEntities(value);
 	}
 
 	addTimelineElements(item, template) {
@@ -608,10 +640,10 @@
 		];
 
 		if (afterEl) {
-			afterEl.textContent = `After ${item.fields.number} Tx`;
+			afterEl.textContent = `After ${item.number - 1} Tx`;
 		}
 		if (number) {
-			number.textContent = item.fields.number;
+			number.textContent = item.number - 1;
 		}
 		if (started) {
 			this.formatTimeField(started, item.fields.timeline[0]['post_date']);
@@ -641,7 +673,7 @@
 				el.dataset.id = data.id;
 				el.dataset.taxonomy = data.taxonomy;
 				if (refs.icon) refs.icon.className = `icon icon=${data.icon}`;
-				if (refs.span) refs.span.textContent = data.name;
+				if (refs.span) refs.span.textContent = window.decodeHTMLEntities(data.name);
 			}
 		});
 		T.define('emptyState');

--
Gitblit v1.10.0