git ssb

10+

Matt McKegg / patchwork



Commit 24269db9f3d8f25ca1b4996019e7c798f5ee96b8

Add option to only show posts from channels you actually subscribe to in main feed

Allows you can hide posts from your friends about topics you don’t care
about (by not subscribing to that channel). It will still appear if
that post has a tag you follow or mentions you or someone replies with
a tag you follow.
Matt McKegg committed on 12/12/2017, 3:56:43 AM
Parent: a224084e5f0cf22563242ad706400c3e4a22d5c5

Files changed

locales/en.jsonchanged
modules/feed/html/rollup.jschanged
modules/page/html/render/public.jschanged
modules/page/html/render/settings.jschanged
package.jsonchanged
sbot/roots.jschanged
locales/en.jsonView
@@ -185,6 +185,9 @@
185185 "See more": "See more",
186186 "(missing message)": "(missing message)",
187187 "assigned a description to ": "assigned a description to ",
188188 "Unread Message": "Unread Message",
189- "Font Size": "Font Size"
189 + "Font Size": "Font Size",
190 + "Public Feed Options": "Public Feed Options",
191 + "Only include posts from subscribed channels": "Only include posts from subscribed channels",
192 + "Default": "Default"
190193 }
modules/feed/html/rollup.jsView
@@ -171,11 +171,11 @@
171171 stream,
172172 abortable,
173173 pull.filter(msg => msg && msg.value && msg.value.content),
174174 prefiltered ? pull(
175- api.feed.pull.unique(),
176175 pull.filter(msg => !api.message.sync.isBlocked(msg)),
177176 pull.filter(rootFilter),
177 + api.feed.pull.unique(),
178178 api.feed.pull.withReplies()
179179 ) : pull(
180180 pull.filter(bumpFilter),
181181 api.feed.pull.rollup(rootFilter)
modules/page/html/render/public.jsView
@@ -71,9 +71,12 @@
7171 if (opts.lt != null && !opts.lt.marker) {
7272 // if an lt has been specified that is not a marker, assume stream is finished
7373 return pull.empty()
7474 } else {
75- return api.sbot.pull.stream(sbot => sbot.patchwork.roots(extend(opts, { ids: [id] })))
75 + return api.sbot.pull.stream(sbot => sbot.patchwork.roots(extend(opts, {
76 + ids: [id],
77 + onlySubscribedChannels: filters() && filters().onlySubscribed
78 + })))
7679 }
7780 }
7881
7982 var filters = api.settings.obs.get('filters')
@@ -88,21 +91,17 @@
8891 var type = msg.value.content.type
8992 if (type === 'vote') return false
9093
9194 var author = msg.value.author
92- var channel = api.channel.sync.normalize(msg.value.content.channel)
93- var tagged = checkTag(msg.value.content.mentions)
94- var isSubscribed = channel ? subscribedChannels().has(channel) : false
95- return isSubscribed || id === author || following().includes(author) || tagged
95 + return matchesSubscribedChannel(msg) || id === author || following().includes(author)
9696 }
9797 },
9898 rootFilter: function (msg) {
99- var filtered = filters() && filters().following && getType(msg) === 'contact'
10099 // skip messages that are directly replaced by the previous message
101100 // e.g. follow / unfollow in quick succession
102101 // THIS IS A TOTAL HACK!!! SHOULD BE REPLACED WITH A PROPER ROLLUP!
103102 var isOutdated = isReplacementMessage(msg, lastMessage)
104- if (!filtered && !isOutdated) {
103 + if (checkFeedFilter(msg) && !isOutdated) {
105104 lastMessage = msg
106105 return true
107106 }
108107 },
@@ -134,8 +133,22 @@
134133 }
135134
136135 return result
137136
137 + function checkFeedFilter (root) {
138 + if (filters()) {
139 + if (filters().following && getType(root) === 'contact') return false
140 + }
141 + return true
142 + }
143 +
144 + function matchesSubscribedChannel (msg) {
145 + var channel = api.channel.sync.normalize(msg.value.content.channel)
146 + var tagged = checkTag(msg.value.content.mentions)
147 + var isSubscribed = channel ? subscribedChannels().has(channel) : false
148 + return isSubscribed || tagged
149 + }
150 +
138151 function checkTag (mentions) {
139152 if (Array.isArray(mentions)) {
140153 return mentions.some((mention) => {
141154 if (mention && typeof mention.link === 'string' && mention.link.startsWith('#')) {
@@ -254,8 +267,12 @@
254267 function getType (msg) {
255268 return msg && msg.value && msg.value.content && msg.value.content.type
256269 }
257270
271 +function hasChannel (msg) {
272 + return getType(msg) !== 'channel' && msg && msg.value && msg.value.content && !!msg.value.content.channel
273 +}
274 +
258275 function arrayEq (a, b) {
259276 if (Array.isArray(a) && Array.isArray(b) && a.length === b.length && a !== b) {
260277 return a.every((value, i) => value === b[i])
261278 }
modules/page/html/render/settings.jsView
@@ -79,16 +79,19 @@
7979 ]),
8080
8181 h('section', [
8282 h('h2', i18n('Public Feed Options')),
83 +
8384 h('div', [
84- h('label', [
85- h('input', {
86- type: 'checkbox',
87- checked: filterFollowing,
88- 'ev-change': (ev) => filterFollowing.set(ev.target.checked)
89- }), ' ', i18n('Hide following messages')
90- ])
85 + checkbox(filterFollowing, {
86 + label: i18n('Hide following messages')
87 + })
88 + ]),
89 +
90 + h('div', [
91 + checkbox(onlySubscribed, {
92 + label: i18n('Only include posts from subscribed channels')
93 + })
9194 ])
9295 ])
9396 ])
9497 ])
@@ -105,4 +108,14 @@
105108 }
106109 }
107110 })
108111 }
112 +
113 +function checkbox (param, {label}) {
114 + return h('label', [
115 + h('input', {
116 + type: 'checkbox',
117 + checked: param,
118 + 'ev-change': (ev) => param.set(ev.target.checked)
119 + }), ' ', label
120 + ])
121 +}
package.jsonView
@@ -39,9 +39,9 @@
3939 "moment": "^2.18.1",
4040 "mutant": "^3.21.2",
4141 "mutant-pull-reduce": "^1.1.0",
4242 "obv": "0.0.1",
43- "patch-settings": "github:mmckegg/patch-settings#e808303e2d3e6c88519266e0d9e18a750dee97a2",
43 + "patch-settings": "~1.1.0",
4444 "patchcore": "~1.21.0",
4545 "pull-abortable": "^4.1.0",
4646 "pull-defer": "^0.2.2",
4747 "pull-file": "~1.0.0",
sbot/roots.jsView
@@ -25,9 +25,9 @@
2525 // not really big enough for multiple refresh cycles
2626 var cache = HLRU(100)
2727
2828 return {
29- latest: function ({ids = [ssb.id]}) {
29 + latest: function ({ids = [ssb.id], onlySubscribedChannels = false}) {
3030 var stream = Defer.source()
3131 getFilter((err, filter) => {
3232 if (err) return stream.abort(err)
3333 stream.resolve(pull(
@@ -52,17 +52,18 @@
5252 var root = item.root || item
5353 var isPrivate = root.value && typeof root.value.content === 'string'
5454
5555 if (filter && root && root.value && !isPrivate) {
56- return checkReplyForcesDisplay(item) || filter(ids, root)
56 + var filterResult = filter(ids, root)
57 + return checkReplyForcesDisplay(item) || shouldShow(filterResult, {onlySubscribedChannels})
5758 }
5859 })
5960 ))
6061 })
6162 return stream
6263 },
6364
64- read: function ({ids = [ssb.id], reverse, limit, lt, gt}) {
65 + read: function ({ids = [ssb.id], reverse, limit, lt, gt, onlySubscribedChannels = false}) {
6566 var opts = {reverse, old: true}
6667
6768 // handle markers passed in to lt / gt
6869 if (lt && typeof lt.timestamp === 'number') lt = lt.timestamp
@@ -111,11 +112,10 @@
111112 included.add(root.key)
112113 return true
113114 } else if (!seen.has(root.key)) {
114115 seen.add(root.key)
115- var result = filter(ids, root)
116- if (result) {
117- // include this item if we have not yet seen it and the root filter passes
116 + var filterResult = filter(ids, root)
117 + if (shouldShow(filterResult, {onlySubscribedChannels})) {
118118 included.add(root.key)
119119 return true
120120 }
121121 }
@@ -124,8 +124,9 @@
124124
125125 // MAP ROOT ITEMS
126126 pull.map(item => {
127127 var root = item.root || item
128 + root.filterResult = item.filterResult
128129 return root
129130 })
130131 ))
131132 })
@@ -153,8 +154,16 @@
153154 }
154155 }
155156 }
156157
158 + function shouldShow (filterResult, {onlySubscribedChannels}) {
159 + if (filterResult && onlySubscribedChannels && filterResult.hasChannel) {
160 + return filterResult.matchesChannel || filterResult.matchingTags.length || filterResult.mentionsYou || filterResult.isYours
161 + } else {
162 + return !!filterResult
163 + }
164 + }
165 +
157166 function getThruCache (key, cb) {
158167 if (cache.has(key)) {
159168 cb(null, cache.get(key))
160169 } else {
@@ -176,16 +185,17 @@
176185 if (err) return cb(err)
177186 cb(null, function (ids, msg) {
178187 var type = msg.value.content.type
179188 if (type === 'vote') return false // filter out likes
189 + var hasChannel = !!msg.value.content.channel
180190 var matchesChannel = (type !== 'channel' && checkChannel(subscriptions, ids, msg.value.content.channel))
181191 var matchingTags = getMatchingTags(subscriptions, ids, msg.value.content.mentions)
182192 var isYours = ids.includes(msg.value.author)
183193 var mentionsYou = getMentionsYou(ids, msg.value.content.mentions)
184194 var following = checkFollowing(friends, ids, msg.value.author)
185195 if (isYours || matchesChannel || matchingTags.length || following || mentionsYou) {
186196 return {
187- matchingTags, matchesChannel, isYours, following, mentionsYou
197 + matchingTags, matchesChannel, isYours, following, mentionsYou, hasChannel
188198 }
189199 }
190200 })
191201 })

Built with git-ssb-web