From b29b7e6405393f49fd8894e35ea005363f0d2e85 Mon Sep 17 00:00:00 2001
From: dakedres <ramondolive@gmail.com>
Date: Sat, 10 Feb 2024 02:50:47 -0700
Subject: [PATCH] Ability to jump between lists by clicking links under post
 details

---
 lib.js | 91 ++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 53 insertions(+), 38 deletions(-)

diff --git a/lib.js b/lib.js
index 0776b27..9733db4 100644
--- a/lib.js
+++ b/lib.js
@@ -176,7 +176,7 @@ export const processRss = (source, fromDate, reducerCallback) => {
   }
 
   for(let item of items) {
-    let post = processRssItem(source, item, reducerCallback)
+    let post = createPost(source, item, reducerCallback)
 
     if(post && post.date > fromDate) {
       source.posts.push(post)
@@ -186,7 +186,7 @@ export const processRss = (source, fromDate, reducerCallback) => {
   return source
 }
 
-export const processRssItem = (source, item, reducerCallback) => {
+export const createPost = (source, item, reducerCallback) => {
   let description = new JSDOM(item.querySelector('description').textContent).window.document
   let dateString = item.querySelector('pubDate').textContent
   let link = item.querySelector('link').textContent
@@ -201,7 +201,8 @@ export const processRssItem = (source, item, reducerCallback) => {
     date: new Date(dateString).valueOf() ?? 0,
     link,
     guid,
-    title
+    title,
+    occurances: []
   }
   
   return reducerCallback(post)
@@ -247,10 +248,10 @@ export const extractImages = (post, cache = true) => {
 // |/  | |-' |/|/
 // '   ' `-' ' '
 
-export const writePages = (list, { pageSize, header = '', directory, batch }) => {
+export const createPages = (list, { pageSize }) => {
   let posts = []
+  let pages = []
   let lastPageLink = 'about:blank'
-  let pageIndex = 0
 
   list.posts.sort((a, b) => b.date - a.date)
 
@@ -258,22 +259,37 @@ export const writePages = (list, { pageSize, header = '', directory, batch }) =>
     posts.push(list.posts[i])
 
     if(i % pageSize == 0) {
-      let title = getPageTitle(list, pageIndex)
-      let html = renderPage(title, posts.reverse(), header, renderNextPageLink(lastPageLink))
-      let filename = i < pageSize ? getFinalPageFilename(list) : getPageFilename(list, pageIndex)
-      let promise = write(Path.join(directory, filename), html)
+      let title = getPageTitle(list, pages.length)
+      let filename = i < pageSize ? getFinalPageFilename(list) : getPageFilename(list, pages.length)
+      let page = {
+        filename,
+        title,
+        posts: posts.reverse(),
+        lastPageLink
+      }
 
-      batch.add(promise.then(annotate(`Created "${title}" (${filename})`)))
+      for(let i = 0; i < page.posts.length; i++) {
+        page.posts[i].occurances.push({
+          index: i,
+          list,
+          page
+        })
+      }
+
+      pages.push(page)
       posts = []
       lastPageLink = filename
-      pageIndex++
     }
   }
 
-  // lock.lists[list.name] = {
-  //   pageIndex,
-  //   lastPostDate: posts[0]?.date ?? lastPostDate
-  // }
+  return pages
+}
+
+export const writePage = (page, { header = '', directory, batch }) => {
+  let html = renderPage(page.title, page.posts, header, renderNextPageLink(page.lastPageLink))
+  let promise = write(Path.join(directory, page.filename), html)
+
+  batch.add(promise.then(annotate(`Created "${page.title}" (${page.filename})`)))
 }
 
 export const getFinalPageFilename = list =>
@@ -311,12 +327,8 @@ ${footer}
 </body>
 </html>`
 
-export const renderPost = post => {
-  let date = new Date(post.date)
-
-  let details = [
-    [ 'source', `<a href="${post.source.hostname}">${post.source.hostname}</a>` ]
-  ]
+export const renderPost = (post, index) => {
+  let details = []
 
   if(post.title)
     details.push([ 'title', `"${post.title}"` ])
@@ -324,17 +336,22 @@ export const renderPost = post => {
   if(post.categories && post.categories.length > 0)
     details.push([ 'categories', post.categories.map(name => `<mark>${name}</mark>`).join(', ') ])
 
+  details.push([ 'source', `<a href="${post.source.hostname}">${post.source.hostname}</a>` ])
+  details.push([ 'lists', post.occurances.map(occ => `<a href="${occ.page.filename}#${occ.index}">${occ.list.displayName}</a>`).join(', ') ])
+
   return `\
+<section id="${index}">
 ${post.images.map(renderImage).join('\n')}
 <details>
 
-<summary><b>${post.source.displayName}</b> ${renderDate(date)} <a href="${post.link}">open</a></summary>
+<summary><b>${post.source.displayName}</b> ${renderDate(new Date(post.date))} <a href="${post.link}">open</a></summary>
 <ul>
 ${details.map(args => renderPostDetail(...args)).join('\n')}
 <ul>
 
 </details>
-<hr>`
+<hr>
+</section>`
 }
 
 export const renderPostDetail = (name, value) =>
@@ -411,7 +428,7 @@ export const downloadImages = (images, getImagePath, courtesyWait, { directory,
   return out
 }
 
-export const pullImages = (post, renderer, discardPostIfNoImages = false, getPostId = postIdFromPathname) => {
+export const pullImages = (post, view, discardPostIfNoImages = false, getPostId = postIdFromPathname) => {
   let images = extractImages(post)
 
   if(!discardPostIfNoImages || images.length > 0) {
@@ -419,7 +436,7 @@ export const pullImages = (post, renderer, discardPostIfNoImages = false, getPos
       images,
       buildImagePathHandler(post.source, getPostId(post)),
       post.source.courtesyWait,
-      renderer
+      view
     )
     return post
   }
@@ -458,12 +475,6 @@ export const fetchRssFromInstances = async (source, lock) => {
   return source
 }
 
-// const addPostsToLock = (source, renderer) => {
-//   (renderer.lock.sources[source.name] ??= {})
-  
-//   .postData = source.posts.map(post => post.description)
-// }
-
 export const populateSource = (source, postReducerCallback, lock) => {
   let sourceLock = lock.sources[source.name] ??= {}
 
@@ -474,7 +485,7 @@ export const populateSource = (source, postReducerCallback, lock) => {
     for(let itemText of sourceLock.items) {
       let item = new JSDOM(itemText, { contentType: 'text/xml' }).window.document.documentElement
   
-      source.posts.push(processRssItem(source, item, postReducerCallback))
+      source.posts.push(createPost(source, item, postReducerCallback))
     }
   }
 
@@ -505,20 +516,24 @@ export const lockSources = (sources, lock) => {
   sources.forEach(source => lockSource(source, lock))
 }
 
-export const writeView = (sources, feeds, renderer) => {
-  renderer.header = renderNav(feeds, sources)
+export const writeView = (sources, feeds, view) => {
+  view.header = renderNav(feeds, sources)
+  let pages = []
 
   for(let feed of feeds) {
-    writePages(feed, renderer)
+    pages = pages.concat(createPages(feed, view))
   }
 
   for(let source of sources) {
-    writePages(source, renderer)
+    pages = pages.concat(createPages(source, view))
   }
 
-  writeStylesheet(Path.join(import.meta.dirname, 'assets/style.css'), renderer)
-}
+  for(let page of pages) {
+    writePage(page, view)
+  }
 
+  writeStylesheet(Path.join(import.meta.dirname, 'assets/style.css'), view)
+}
 
 //     |     |    ,-
 // ;-. | ,-: |-   |  ,-. ;-. ;-.-. ,-.