Files: 55335207126eb15c3a0f1834ffb8bbcbd32658a8 / app / page / post-rank.js
4736 bytesRaw
1 | const nest = require('depnest') |
2 | const { h } = require('mutant') |
3 | const Scroller = require('pull-scroll') |
4 | const pull = require('pull-stream') |
5 | |
6 | exports.gives = nest({ |
7 | 'app.html.menuItem': true, |
8 | 'app.page.postRank': true |
9 | }) |
10 | |
11 | exports.needs = nest({ |
12 | 'app.html.scroller': 'first', |
13 | 'app.sync.goTo': 'first', |
14 | 'keys.sync.id': 'first', |
15 | 'channel.obs.subscribed': 'first', |
16 | 'contact.obs.following': 'first', |
17 | 'sbot.pull.log': 'first', |
18 | 'message.html.render': 'first' |
19 | }) |
20 | |
21 | exports.create = function (api) { |
22 | return nest({ |
23 | 'app.html.menuItem': menuItem, |
24 | 'app.page.postRank': page |
25 | }) |
26 | |
27 | function menuItem () { |
28 | return h('a', { |
29 | style: { order: 1 }, |
30 | 'ev-click': () => api.app.sync.goTo({ page: 'postRank' }) |
31 | }, '/postRank') |
32 | } |
33 | |
34 | function getPosts (channelPostBoost, friendPostBoost, friendVoteBoost, friendCommentBoost, threshold, cb) { |
35 | let weights = { |
36 | post: 1, // base |
37 | channelPost: channelPostBoost, |
38 | friendPost: friendPostBoost, |
39 | |
40 | vote: 0.5, // base |
41 | friendVote: friendVoteBoost, |
42 | |
43 | comment: 1, // base |
44 | friendComment: friendCommentBoost |
45 | } |
46 | |
47 | console.log('weights', weights) |
48 | |
49 | const myKey = api.keys.sync.id() |
50 | let myChannels = api.channel.obs.subscribed(myKey)() |
51 | let imFollowing = new Set(api.contact.obs.following(myKey)()) |
52 | |
53 | console.log(myChannels) |
54 | console.log(imFollowing) |
55 | |
56 | var messages = {} |
57 | |
58 | console.log('pulling', new Date()) |
59 | |
60 | return pull( |
61 | api.sbot.pull.log({ reverse: true, limit: 10000 }), |
62 | pull.drain((msg) => { |
63 | let content = msg.value.content |
64 | if (content.type === 'post' && content.root === undefined) { |
65 | let score = weights['post'] |
66 | if (imFollowing.has(msg.value.author)) { score += weights['friendPost'] } |
67 | if (myChannels.has(content.channel)) { score += weights['channelPost'] } |
68 | |
69 | msg.score = score |
70 | messages[msg.key] = msg |
71 | } else if (content.type === 'post' && content.root !== msg.key) { |
72 | let score = weights['comment'] |
73 | if (imFollowing.has(msg.value.author)) { score += weights['friendComment'] } |
74 | |
75 | if (content.root in messages) { messages[content.root].score += score } |
76 | } else if (content.type === 'vote') { |
77 | let score = weights['vote'] |
78 | if (imFollowing.has(msg.value.author)) { score += weights['friendVote'] } |
79 | |
80 | if (content.vote && content.vote.link in messages) { messages[content.vote.link].score += score } |
81 | } |
82 | }, function (err) { |
83 | if (err) throw err |
84 | |
85 | console.log('Went through ' + Object.keys(messages).length, new Date()) |
86 | |
87 | let msgs = Object.values(messages) |
88 | msgs.sort((lhs, rhs) => { |
89 | return rhs.score - lhs.score |
90 | }) |
91 | |
92 | cb(msgs.filter(msg => msg.score > threshold)) |
93 | }) |
94 | ) |
95 | } |
96 | |
97 | function page (location) { |
98 | let channelPostBoost = +2 |
99 | let friendPostBoost = +3 |
100 | let friendVoteBoost = +1 |
101 | let friendCommentBoost = +2 |
102 | let threshold = 10 |
103 | |
104 | let top = [ |
105 | h('span.label', 'Channel boost:'), |
106 | h('input', |
107 | { |
108 | 'type': 'number', |
109 | value: channelPostBoost, |
110 | 'ev-input': ev => { channelPostBoost = parseFloat(ev.target.value) } |
111 | }), |
112 | |
113 | h('span.label', 'Friend post boost:'), |
114 | h('input', |
115 | { |
116 | 'type': 'number', |
117 | value: friendPostBoost, |
118 | 'ev-input': ev => { friendPostBoost = parseFloat(ev.target.value) } |
119 | }), |
120 | |
121 | h('span.label', 'Friend vote boost:'), |
122 | h('input', |
123 | { |
124 | 'type': 'number', |
125 | value: friendVoteBoost, |
126 | 'ev-input': ev => { friendVoteBoost = parseFloat(ev.target.value) } |
127 | }), |
128 | |
129 | h('span.label', 'Friend comment boost:'), |
130 | h('input', |
131 | { |
132 | 'type': 'number', |
133 | value: friendCommentBoost, |
134 | 'ev-input': ev => { friendCommentBoost = parseFloat(ev.target.value) } |
135 | }), |
136 | |
137 | h('span.label', 'Threshold:'), |
138 | h('input', |
139 | { |
140 | 'type': 'number', |
141 | value: threshold, |
142 | 'ev-input': ev => { threshold = parseFloat(ev.target.value) } |
143 | }), |
144 | |
145 | h('button', { |
146 | 'ev-click': draw |
147 | }, 'Go!') |
148 | ] |
149 | |
150 | const { container, content } = api.app.html.scroller({ prepend: top }) |
151 | |
152 | function draw () { |
153 | // reset |
154 | container.keyboardScroll(0) |
155 | content.innerHTML = '' |
156 | |
157 | getPosts(channelPostBoost, friendPostBoost, friendVoteBoost, friendCommentBoost, threshold, |
158 | (msgs) => { |
159 | console.log('msgs', msgs) |
160 | |
161 | pull( |
162 | pull.values(msgs), |
163 | Scroller(container, content, api.message.html.render) |
164 | ) |
165 | } |
166 | ) |
167 | } |
168 | |
169 | container.title = '/postRank' |
170 | return container |
171 | } |
172 | } |
173 |
Built with git-ssb-web