on master help sign in
Merge pull request #159 from Bradshaw/master

Moves filtering to regexes, adds tag filtering

commitbe1ef7f4d3e24ca66c65275cb9deadbb65742239 authorЛu Лinveгa <aliceffekt@gmail.com> dateFri 5 Jul 2019, 22:11 (7 years ago) parent7c22eab5a4479a
1 file changed+32−28
scripts/hallway.js+32−28
scripts/hallway.js+32−28
@@ -1,5 +1,10 @@
11'use strict'
22
3+const re_channel = /(\s|^)\/([a-zA-Z0-9]+)/g
4+const re_user = /(\s|^)\@([a-zA-Z0-9]+)/g
5+const re_tag = /([^&]|^)\#([a-zA-Z0-9]+)/g
6+const re_url = /((https?):\/\/(([-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b)([-a-zA-Z0-9@:%_\+.~#?&//=]*)))/g
7+
38function Hallway (sites) {
49 const feeds = {}
510 this.sites = sites
@@ -22,10 +27,11 @@ function Hallway (sites) {
2227 const entries = this.findEntries(feeds)
2328 const channels = this.findChannels(entries)
2429 const users = this.findUsers(entries)
30+ const tags = this.findTags(entries)
2531
2632 this.el.innerHTML = `
2733 <ul id='entries'>
28− ${entries.filter((val, id) => { return !(this.filter && val.author !== this.filter && val.channel !== this.filter) }).filter((val, id) => { return id < 50 }).reduce((acc, val, id) => { return acc + this.templateEntry(val) + '\n' }, '')}
34+ ${entries.filter((val, id) => { return !this.filter || (val.author === this.filter || val.channel === this.filter || val.tags.includes(this.filter)) }).filter((val, id) => { return id < 50 }).reduce((acc, val, id) => { return acc + this.templateEntry(val) + '\n' }, '')}
2935 </ul>
3036 <div id='sidebar'>
3137 <ul id='channels'>
@@ -35,6 +41,9 @@ function Hallway (sites) {
3541 <ul id='users'>
3642 ${Object.keys(users).reduce((acc, val, id) => { return acc + `<li onclick='filter("${val}")' class='${hallway.filter === val ? 'selected' : ''}' href='#${val}'>${val} <span class='right'>${users[val]}</span></li>\n` }, '')}
3743 </ul>
44+ <ul id='tags'>
45+ ${Object.keys(tags).reduce((acc, val, id) => { return acc + `<li onclick='filter("${val}")' class='${hallway.filter === val ? 'selected' : ''}' href='#${val}'>#${val} <span class='right'>${tags[val]}</span></li>\n` }, '')}
46+ </ul>
3847 </div>
3948 <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>`
4049
@@ -63,6 +72,17 @@ function Hallway (sites) {
6372 }
6473 return users
6574 }
75+
76+ this.findTags = function (entries){
77+ const tags = {}
78+ for (const id in entries) {
79+ const entry = entries[id]
80+ entry.tags.map(tag => {
81+ tags[tag] = tags[tag] ? tags[tag] + 1 : 1
82+ })
83+ }
84+ return tags
85+ }
6686
6787 this.findEntries = function (feeds) {
6888 const a = []
@@ -71,36 +91,23 @@ function Hallway (sites) {
7191 a.push(feeds[id].content[i])
7292 }
7393 }
74− return a.sort(compare)
94+ return a.sort( (a, b) => a.offset - b.offset )
7595 }
7696
7797 this.templateEntry = function (entry) {
78− const words = entry.body.split(' ')
79− const users = []
80− const channels = []
81− const tags = []
82− const links = []
83−
84− // Channels
85− for (const id in words) {
86− if (words[id].substr(0, 1) === '@') { users.push(words[id]) }
87− if (words[id].substr(0, 1) === '/') { channels.push(words[id]) }
88− if (words[id].substr(0, 1) === '#') { tags.push(words[id]) }
89− if (words[id].substr(0, 4) === 'http') { links.push(words[id]) }
90− }
91−
92− for (const id in users) { entry.body = entry.body.replace(users[id], `<span class='user'>${users[id]}</span>`) }
93− for (const id in channels) { entry.body = entry.body.replace(channels[id], `<span class='channel'>${channels[id]}</span>`) }
94− for (const id in tags) { entry.body = entry.body.replace(tags[id], `<span class='tag'>${tags[id]}</span>`) }
95− for (const id in links) { entry.body = entry.body.replace(links[id], `<a href='${links[id]}'>${links[id].replace('https://', '').replace('http://', '')}</a>`) }
96−
98+ entry.html = entry.body
99+ .replace(re_channel, `$1<span class='channel'>/$2</span>`)
100+ .replace(re_user, `$1<span class='user'>@$2</span>`)
101+ .replace(re_tag, `$1<span class='tag'>#$2</span>`)
102+ .replace(re_url, `<a target="_blank" href='$1'>$1</a>`)
103+
97104 const filter = window.location.hash.substr(1).replace(/\+/g, ' ').toLowerCase()
98105 const highlight = filter === entry.author.toLowerCase()
99106 const origin = feeds[entry.author].path
100107
101− return `<li class='entry ${highlight ? 'highlight' : ''}'><span class='date'>${timeAgo(Date.parse(entry.date))}</span> <a class='author' href='${origin}' target='_blank'>${entry.author}</a> <span class='body'>${entry.body}</span></li>`
108+ return `<li class='entry ${highlight ? 'highlight' : ''}'><span class='date'>${timeAgo(Date.parse(entry.date))}</span> <a class='author' href='${origin}' target='_blank'>${entry.author}</a> <span class='body'>${entry.html}</span></li>`
102109 }
103−
110+
104111 // Feeds
105112
106113 this.findFeeds = function () {
@@ -133,10 +140,6 @@ function Hallway (sites) {
133140
134141 // Utils
135142
136− function compare (a, b) {
137− return a.offset < b.offset ? -1 : a.offset > b.offset ? 1 : 0
138− }
139−
140143 function parseFeed (author, feed) {
141144 const lines = feed.split('\n')
142145 const entries = []
@@ -147,8 +150,9 @@ function Hallway (sites) {
147150 const date = parts[0].trim()
148151 const body = escapeHtml(parts[1].trim()).trim()
149152 const channel = body.substr(0, 1) === '/' ? body.split(' ')[0].substr(1).toLowerCase() : body.substr(0, 1) === '@' ? 'veranda' : 'lobby'
153+ const tags = (body.match(re_tag)||[]).map(a => a.substr(a.indexOf('#')+1).toLowerCase())
150154 const offset = new Date() - new Date(date)
151− entries.push({ date, body, author, offset, channel })
155+ entries.push({ date, body, author, offset, channel, tags })
152156 }
153157 return entries
154158 }