3function Hallway (sites) {
6 this.el = document.createElement('div')
9 this.install = function (host) {
10 host.appendChild(this.el)
14 this.start = function () {
15 this.el.innerHTML = 'hello'
19 this.refresh = function () {
20 const entries = this.sortEntries()
22 for (const id in entries) {
23 html += `${this.templateEntry(entries[id])}\n`
25 this.el.innerHTML = `<ul>${html}</ul>${this._footer()}`
30 this.sortEntries = function () {
32 for (const id in feeds) {
33 const feed = feeds[id]
34 for (const i in feed.content) {
35 const entry = feed.content[i]
39 return a.sort(compare).reverse()
42 this.templateEntry = function (entry) {
44 if (entry.body.indexOf('@<') > -1) {
45 const data = entry.body.split('@<').pop().split('>')[0]
46 const mention = data.split(' ')
47 const name = mention[0]
48 const path = mention[1]
49 entry.body = entry.body.replace(`@<${data}>`, `<a href='${path}'>@${name}</a>`)
52 return `<li class='entry'><span class='date'>${timeAgo(Date.parse(entry.date))}</span> <span class='author'>${entry.author}</span> <span class='body'>${entry.body}</span></li>`
57 this.findFeeds = function () {
58 console.log('Finding feeds..')
59 for (const id in sites) {
60 const site = sites[id]
61 if (site.feed && site.author) {
62 feeds[site.author] = { path: site.feed }
65 console.log(`Found ${Object.keys(feeds).length} feeds.`)
68 this.fetchFeeds = function () {
69 console.log(`Fetching ${Object.keys(feeds).length} feeds..`)
70 for (const id in feeds) {
71 this.fetchFeed(id, feeds[id])
75 this.fetchFeed = function (id, feed) {
76 console.log(`Fetching ${id}(${feed.path})..`)
77 Promise.all([ fetch(feed.path + '?v=1', { cache: 'no-store' }).then(x => x.text()) ]).then(([content]) => {
78 feeds[id].content = parseFeed(id, content)
85 this._footer = function () {
86 return '<p>The <b>Hallway</b> is a decentralized forum, to join the conversation, simply create yourself a <a href="https://twtxt.readthedocs.io/en/stable/user/twtxtfile.html">twtxt</a> feed and <a href="https://github.com/XXIIVV/Webring/">add it</a> to your entry in the <a href="index.html">webring</a>.</p>'
91 function compare (a, b) {
92 return a.date < b.date ? -1 : a.date > b.date ? 1 : 0
95 function parseFeed (author, feed) {
96 const lines = feed.split('\n')
98 for (const id in lines) {
99 const line = lines[id].trim()
100 if (line === '') { continue }
101 const date = line.substr(0, 25).trim()
102 const body = line.substr(26).trim()
103 entries.push({ date, body, author })
108 function timeAgo (dateParam) {
113 const date = typeof dateParam === 'object' ? dateParam : new Date(dateParam)
114 const DAY_IN_MS = 86400000 // 24 * 60 * 60 * 1000
115 const today = new Date()
116 const yesterday = new Date(today - DAY_IN_MS)
117 const seconds = Math.round((today - date) / 1000)
118 const minutes = Math.round(seconds / 60)
119 const isToday = today.toDateString() === date.toDateString()
120 const isYesterday = yesterday.toDateString() === date.toDateString()
124 } else if (seconds < 60) {
125 return `${seconds} seconds ago`
126 } else if (seconds < 90) {
127 return 'about a minute ago'
128 } else if (minutes < 60) {
129 return `${minutes} minutes ago`
130 } else if (isToday) {
131 return `${Math.floor(minutes / 60)} hours ago`
132 } else if (isYesterday) {
136 return `${Math.floor(minutes / 1440)} days ago`
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list