diff --git a/webui/html/meetings.html b/webui/html/meetings.html
index 0871117..305eead 100644
--- a/webui/html/meetings.html
+++ b/webui/html/meetings.html
@@ -50,6 +50,7 @@
Life and Ministry
Watchtower
+
diff --git a/webui/html/reader.html b/webui/html/reader.html
index ebfcf2c..52a1f90 100644
--- a/webui/html/reader.html
+++ b/webui/html/reader.html
@@ -40,6 +40,7 @@
@@ -64,6 +65,10 @@
page = location.hash.substr(1)
iframe = document.getElementById('reader')
iframe.src = page
+ // Navigate the iframe when the URL hash changes (e.g. clicking sidebar links while already on reader.html)
+ window.addEventListener('hashchange', function() {
+ iframe.src = location.hash.substr(1)
+ })
// Update the iframe's link
iframe.onload = (() => {
//console.log(this)
diff --git a/webui/html/static/meethelper.js b/webui/html/static/meethelper.js
index a62ba0e..ad74bb4 100644
--- a/webui/html/static/meethelper.js
+++ b/webui/html/static/meethelper.js
@@ -38,33 +38,102 @@
// with mwb things are easier
// 21.01 is used in 21.01 and 21.02
function setMeeting() {
+ // Show loading state immediately while fetches are in flight
+ document.getElementById("mwb_link").textContent = "Life and Ministry — Loading..."
+ document.getElementById("wt_link").textContent = "Watchtower — Loading..."
+
// Watchtower
- date = getThisSunday()
+ // Save the original Sunday before rolling back 2 months for the publication code
+ var thisSunday = getThisSunday()
+ var date = new Date(thisSunday)
date.setMonth(date.getMonth() - 2)
- month = ("00" + (date.getMonth() + 1)).slice(-2)
- year = date.getFullYear()
- wt = "w_"+year+month
+ var month = ("00" + (date.getMonth() + 1)).slice(-2)
+ var year = date.getFullYear()
+ var wt = "w_"+year+month
fetch("/api/publications_json/"+wt+"/toc.xhtml")
.then(response => response.json())
- .then((response) => {
- toc = response.html.body.section.nav[0].ol.li[1].a['-href']
- wtlink = document.getElementById("wt_link")
- wtlink.href = "/reader.html#/api/publications/"+wt+"/"+toc
+ .then((response) => {
+ var items = response.html.body.section.nav[0].ol.li
+ var result = getCurrentWTArticle(items, thisSunday)
+ if (!result) throw new Error("Watchtower TOC has unexpected structure")
+ var wtlink = document.getElementById("wt_link")
+ wtlink.href = "/reader.html#/api/publications/"+wt+"/"+result.href
+ wtlink.textContent = "Watchtower — " + result.title
+ })
+ .catch(() => {
+ var wtlink = document.getElementById("wt_link")
+ wtlink.textContent = "Watchtower — not available offline (open it once with internet)"
+ wtlink.href = "/publications.html"
})
- // Now I need:
- // mwb_202105
- mwbdate = getThisSunday()
- if (((mwbdate.getMonth()) % 2) === 0) {
+
+ // MWB
+ // MWB is bimonthly: mwb_YYYY01 covers Jan+Feb, mwb_YYYY03 covers Mar+Apr, etc.
+ // getMonth() is 0-indexed: odd 0-indexed = 2nd month of pair → go back 1
+ var mwbdate = getThisSunday()
+ if ((mwbdate.getMonth() % 2) === 1) {
mwbdate.setMonth(mwbdate.getMonth() - 1)
- } else {
- mwbdate.setMonth(mwbdate.getMonth())
}
- mwbmonth = ("00" + (mwbdate.getMonth())).slice(-2)
- mwbyear = mwbdate.getFullYear()
- mwb = "mwb_"+mwbyear+mwbmonth
- console.log(mwb)
- mwblink = document.getElementById("mwb_link")
- mwblink.href = "/reader.html#/api/publications/"+mwb+"/"
+ var mwbmonth = ("00" + (mwbdate.getMonth() + 1)).slice(-2)
+ var mwbyear = mwbdate.getFullYear()
+ var mwb = "mwb_"+mwbyear+mwbmonth
+ fetch("/api/publications_json/"+mwb+"/toc.xhtml")
+ .then(response => response.json())
+ .then((response) => {
+ var items = response.html.body.section.nav[0].ol.li
+ var result = getCurrentMWBWeek(items)
+ if (!result) throw new Error("MWB TOC has unexpected structure")
+ var mwblink = document.getElementById("mwb_link")
+ mwblink.href = "/reader.html#/api/publications/"+mwb+"/"+result.href
+ mwblink.textContent = "Life and Ministry — " + result.title
+ })
+ .catch(() => {
+ var mwblink = document.getElementById("mwb_link")
+ mwblink.textContent = "Life and Ministry — not available offline (open it once with internet)"
+ mwblink.href = "/publications.html"
+ })
+}
+
+// Returns the href of the current week's entry in the MWB table of contents.
+// items[0] = publication cover, items[1..N-1] = weekly entries, items[N] = page nav.
+// Parses the start date from items[1]'s title (e.g. "May 4-10") and computes
+// the week offset from today so the link always opens to the current week.
+function getCurrentMWBWeek(items) {
+ if (!items || items.length < 2) return null;
+ var fallback = {href: items[1].a['-href'], title: items[1].a['#content']};
+ var firstTitle = items[1].a['#content'] || '';
+ var match = firstTitle.match(/([A-Za-z]+)\s+(\d+)/);
+ if (!match) return fallback;
+ var monthNames = {
+ January:0, February:1, March:2, April:3,
+ May:4, June:5, July:6, August:7,
+ September:8, October:9, November:10, December:11
+ };
+ var monthNum = monthNames[match[1]];
+ if (monthNum === undefined) return fallback;
+ var today = new Date();
+ var firstWeekStart = new Date(today.getFullYear(), monthNum, parseInt(match[2]));
+ if (firstWeekStart > today) firstWeekStart.setFullYear(today.getFullYear() - 1);
+ var weekOffset = Math.floor((today - firstWeekStart) / 604800000); // ms per week
+ var maxWeek = items.length - 2; // exclude cover (0) and page nav (last)
+ var weekIndex = Math.min(Math.max(1, 1 + weekOffset), maxWeek);
+ return {href: items[weekIndex].a['-href'], title: items[weekIndex].a['#content']};
+}
+
+// Returns the href of the current week's study article in the Watchtower TOC.
+// items[0] = cover, items[1] = Table of Contents, items[2..N-2] = study articles, items[N-1] = page nav.
+// Finds the first Sunday of the study month (= current month, before the 2-month rollback),
+// then computes the week offset to determine the correct article.
+function getCurrentWTArticle(items, thisSunday) {
+ if (!items || items.length < 3) return null;
+ var fallback = {href: items[2].a['-href'], title: items[2].a['#content']};
+ var firstDay = new Date(thisSunday.getFullYear(), thisSunday.getMonth(), 1);
+ var dow = firstDay.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
+ var firstSunday = new Date(firstDay);
+ firstSunday.setDate(1 + (dow === 0 ? 0 : 7 - dow));
+ var weekOffset = Math.floor((thisSunday - firstSunday) / 604800000); // ms per week
+ var maxArticle = items.length - 3; // articles are items[2..length-2], skip cover+toc+pagenav
+ var articleIndex = Math.min(Math.max(0, weekOffset), maxArticle);
+ return {href: items[2 + articleIndex].a['-href'], title: items[2 + articleIndex].a['#content']};
}
function getThisSunday() {