Commit 65ce170e059f57ece5d94c7f5d29f1efff4d2b7c
add stars messages, star buttons, and realtime star updates on messages!
Ev Bogue committed on 5/30/2018, 11:52:43 PMParent: f0a148f88934ef29c598e1e1521839e2bf5b75ca
Files changed
render.js | changed |
style.css | changed |
style.css.json | changed |
tools.js | changed |
views.js | changed |
render.js | ||
---|---|---|
@@ -10,9 +10,8 @@ | ||
10 | 10 … | var id = require('./keys').id |
11 | 11 … | |
12 | 12 … | |
13 | 13 … | module.exports = function (msg) { |
14 | - console.log(msg) | |
15 | 14 … | var message = h('div.message#' + msg.key.substring(0, 44)) |
16 | 15 … | if (msg.value.content.type == 'post') { |
17 | 16 … | var opts = { |
18 | 17 … | type: 'post', |
@@ -36,11 +35,10 @@ | ||
36 | 35 … | |
37 | 36 … | pull( |
38 | 37 … | sbot.query({query: [{$filter: {value: {content: {type: 'edit', original: msg.key}}}}], limit: 100, live: true}), |
39 | 38 … | pull.drain(function (update) { |
40 | - console.log(update) | |
41 | 39 … | if (update.sync) { |
42 | - console.log('Waiting for new edits.') | |
40 … | + //console.log('Waiting for new edits.') | |
43 | 41 … | } else { |
44 | 42 … | var newMessage = h('div', tools.markdown(update.value.content.text)) |
45 | 43 … | var latest = h('div.message__body', |
46 | 44 … | tools.timestamp(update, {edited: true}), |
@@ -86,33 +84,18 @@ | ||
86 | 84 … | var compose = h('div#edit:' + msg.key.substring(0, 44), composer(opts, fallback)) |
87 | 85 … | message.replaceChild(compose, message.lastElementChild) |
88 | 86 … | } |
89 | 87 … | })) |
90 | - | |
88 … | + buttons.appendChild(tools.star(msg)) | |
91 | 89 … | message.appendChild(buttons) |
92 | 90 … | return message |
93 | 91 … | |
94 | 92 … | } else if (msg.value.content.type == 'vote') { |
95 | - message.appendChild(tools.header(msg)) | |
96 | - message.appendChild(h('span', 'Starred:')) | |
97 | - var embed = msg.value.content.vote.link | |
98 | - | |
99 | - var embedded = h('div.embedded') | |
100 | - sbot.get(embed, function (err, msg) { | |
101 | - if (err) {console.log('could not find message locally, try ooo?') } | |
102 | - msg.value = msg | |
103 | - msg.key = embed | |
104 | - if (msg.value.content.text) { | |
105 | - message.appendChild(embedded) | |
106 | - embedded.appendChild(tools.header(msg)) | |
107 | - embedded.appendChild( | |
108 | - h('div.message__body', | |
109 | - tools.markdown(msg.value.content.text.substring(0, 256) + '...'), | |
110 | - h('span', '[', h('a', {href: '#' + msg.key}, 'Full Post'), ']') | |
111 | - ) | |
112 | - ) | |
113 | - } | |
114 | - }) | |
93 … | + if (msg.value.content.vote.value == 1) | |
94 … | + var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'star.png'}), ' ', h('a', {href: msg.value.content.vote.link}, msg.value.content.vote.link.substring(0,16) + '...')) | |
95 … | + else if (msg.value.content.vote.value == -1) | |
96 … | + var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'stars.png'}), ' ', h('a', {href: msg.value.content.vote.link}, msg.value.content.vote.link.substring(0,16) + '...')) | |
97 … | + message.appendChild(tools.mini(msg, link)) | |
115 | 98 … | return message |
116 | 99 … | } else { |
117 | 100 … | //message.appendChild(tools.header(msg)) |
118 | 101 … | //message.appendChild(h('pre', tools.rawJSON(msg.value.content))) |
style.css | ||
---|---|---|
@@ -158,31 +158,41 @@ | ||
158 | 158 … | height: 1.4em; |
159 | 159 … | margin-right: .2em; |
160 | 160 … | } |
161 | 161 … | |
162 | -.compose, textarea { | |
162 … | +.compose, textarea, input { | |
163 | 163 … | font-family: sans-serif; |
164 | 164 … | font-size: 14px; |
165 | 165 … | line-height: 20px; |
166 | 166 … | background: #111; |
167 | 167 … | color: #ccc; |
168 | - width: 100%; | |
169 | - height: 100px; | |
170 | 168 … | border: none; |
171 | - *border: 1px solid #252525; | |
172 | 169 … | border-radius: 3px; |
173 | 170 … | } |
174 | 171 … | |
172 … | +textarea { | |
173 … | + width: 100%; | |
174 … | + height: 100px; | |
175 … | +} | |
176 … | + | |
175 | 177 … | .compose:hover { |
176 | 178 … | background: #141414; |
177 | 179 … | } |
178 | 180 … | |
179 | 181 … | .compose:focus { |
180 | 182 … | outline: none; |
181 | 183 … | } |
182 | 184 … | |
185 … | +.btn .emoji { | |
186 … | + padding: .2em; | |
187 … | +} | |
188 … | + | |
189 … | +.right { | |
190 … | + float: right; | |
191 … | +} | |
192 … | + | |
183 | 193 … | .emoji { |
184 | - float: left; | |
194 … | + *float: left; | |
185 | 195 … | width: 1em; |
186 | 196 … | vertical-align: top; |
187 | 197 … | } |
188 | 198 … |
style.css.json | ||
---|---|---|
@@ -1,1 +1,1 @@ | ||
1 | -"body {\n margin: 0;\n background: #141414;\n font-family: sans-serif;\n color: #d5d5d5;\n font-size: 14px; \n line-height: 20px;\n}\n\n#screen {\n position: absolute;\n top: 35px;\n bottom: 0px;\n left: 0px;\n right: 0px;\n}\n\n.hyperscroll {\n width: 100%;\n}\n\n.header {\n padding-bottom: .7em;\n border-bottom: 1px solid #252525;\n}\n\nh1, h2, h3, h4, h5, h6 {\n font-size: 1.2em;\n margin-top: .35ex;\n}\n\nhr {\n border: solid #222;\n clear: both;\n border-width: 1px 0 0;\n height: 0;\n margin-bottom: .9em;\n}\n\n\np {\n margin-top: .35ex;\n margin-bottom: 10px;\n}\n\n\na {\n color: white;\n *text-decoration: none;\n}\n\na:hover {\n color: #ddd;\n}\n\n.navbar a {\n color: #999;\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n text-decoration: none;\n}\n\n.navbar a:hover, .navbar a:focus {\n color: #fff;\n text-decoration: none;\n}\n\n.navbar {\n background: #1b1b1b;\n background: linear-gradient(#222, #111);\n border-bottom: 1px solid #252525;\n}\n\n.navbar {\n width: 100%;\n position: fixed;\n z-index: 1000;\n margin: 0;\n padding-top: .3em;\n padding-bottom: .3em;\n left: 0; right: 0;\n top: 0;\n}\n\n.navbar .internal {\n max-width: 680px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.navbar li {\n margin-top: .3em;\n float: left;\n margin-right: .6em;\n margin-left: .3em;\n list-style-type: none;\n}\n\n.navbar li.right {\n padding-left: .4em;\n padding-right: .4em;\n margin-top: .3em;\n margin-right: 1.7em;\n float: right;\n list-style-type: none;\n background: #333;\n border-radius: 100%;\n}\n\n.content {\n max-width: 680px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.hyperscroll > .content {\n max-width: 680px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.message, .message > *, .navbar, .navbar > * {\n animation: fadein .5s;\n}\n\n@keyframes fadein {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.message, .embedded {\n display: block;\n margin: .6em;\n background: #111;\n padding: .7em;\n border-radius: 3px;\n border: 1px solid #252525;\n}\n\n.embedded {\n padding-left: 1em;\n}\n\n.message:hover, .embedded:hover {\n background: #141414;\n}\n\n.message img, .message video {\n max-width: 100%;\n}\n\n.timestamp, .votes {\n float: right;\n}\n \n.avatar--small img {\n vertical-align: top;\n width: 1.4em;\n height: 1.4em;\n margin-right: .2em;\n}\n\n.compose, textarea {\n font-family: sans-serif;\n font-size: 14px;\n line-height: 20px;\n background: #111;\n color: #ccc;\n width: 100%;\n height: 100px;\n border: none;\n *border: 1px solid #252525;\n border-radius: 3px;\n}\n\n.compose:hover {\n background: #141414;\n}\n\n.compose:focus {\n outline: none;\n}\n\n.emoji {\n float: left;\n width: 1em;\n vertical-align: top;\n}\n\npre {\n width: 100%;\n display: block;\n}\n\ncode {\n display: inline-block;\n vertical-align: bottom;\n}\n\ncode, pre {\noverflow: auto;\nword-break: break-all;\nword-wrap: break-word;\nwhite-space: pre;\nwhite-space: -moz-pre-wrap;\nwhite-space: pre-wrap;\nwhite-space: pre\\9;\n}\n\n\n.btn {\n display: inline-block;\n *display: inline;\n padding: 2px 6px;\n margin-bottom: 0;\n margin-right: .2em;\n font-size: 14px;\n line-height: 20px;\n color: #d5d5d5;\n text-align: center;\n text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);\n vertical-align: middle;\n cursor: pointer;\n background-color: #222;\n border: 1px solid #222;\n border-radius: 4px;\n}\n\n\n.btn:hover,\n.btn:focus,\n.btn:active,\n.btn.active,\n.btn.disabled,\n.btn[disabled] {\n color: white;\n background-color: black;\n}\n\n.btn:active,\n.btn.active {\n background-color: #111;\n}\n\n.btn:first-child {\n *margin-left: 0;\n}\n\n" | |
1 … | +"body {\n margin: 0;\n background: #141414;\n font-family: sans-serif;\n color: #d5d5d5;\n font-size: 14px; \n line-height: 20px;\n}\n\n#screen {\n position: absolute;\n top: 35px;\n bottom: 0px;\n left: 0px;\n right: 0px;\n}\n\n.hyperscroll {\n width: 100%;\n}\n\n.header {\n padding-bottom: .7em;\n border-bottom: 1px solid #252525;\n}\n\nh1, h2, h3, h4, h5, h6 {\n font-size: 1.2em;\n margin-top: .35ex;\n}\n\nhr {\n border: solid #222;\n clear: both;\n border-width: 1px 0 0;\n height: 0;\n margin-bottom: .9em;\n}\n\n\np {\n margin-top: .35ex;\n margin-bottom: 10px;\n}\n\n\na {\n color: white;\n *text-decoration: none;\n}\n\na:hover {\n color: #ddd;\n}\n\n.navbar a {\n color: #999;\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n text-decoration: none;\n}\n\n.navbar a:hover, .navbar a:focus {\n color: #fff;\n text-decoration: none;\n}\n\n.navbar {\n background: #1b1b1b;\n background: linear-gradient(#222, #111);\n border-bottom: 1px solid #252525;\n}\n\n.navbar {\n width: 100%;\n position: fixed;\n z-index: 1000;\n margin: 0;\n padding-top: .3em;\n padding-bottom: .3em;\n left: 0; right: 0;\n top: 0;\n}\n\n.navbar .internal {\n max-width: 680px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.navbar li {\n margin-top: .3em;\n float: left;\n margin-right: .6em;\n margin-left: .3em;\n list-style-type: none;\n}\n\n.navbar li.right {\n padding-left: .4em;\n padding-right: .4em;\n margin-top: .3em;\n margin-right: 1.7em;\n float: right;\n list-style-type: none;\n background: #333;\n border-radius: 100%;\n}\n\n.content {\n max-width: 680px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.hyperscroll > .content {\n max-width: 680px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.message, .message > *, .navbar, .navbar > * {\n animation: fadein .5s;\n}\n\n@keyframes fadein {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.message, .embedded {\n display: block;\n margin: .6em;\n background: #111;\n padding: .7em;\n border-radius: 3px;\n border: 1px solid #252525;\n}\n\n.embedded {\n padding-left: 1em;\n}\n\n.message:hover, .embedded:hover {\n background: #141414;\n}\n\n.message img, .message video {\n max-width: 100%;\n}\n\n.timestamp, .votes {\n float: right;\n}\n \n.avatar--small img {\n vertical-align: top;\n width: 1.4em;\n height: 1.4em;\n margin-right: .2em;\n}\n\n.compose, textarea, input {\n font-family: sans-serif;\n font-size: 14px;\n line-height: 20px;\n background: #111;\n color: #ccc;\n border: none;\n border-radius: 3px;\n}\n\ntextarea {\n width: 100%;\n height: 100px;\n}\n\n.compose:hover {\n background: #141414;\n}\n\n.compose:focus {\n outline: none;\n}\n\n.btn .emoji {\n padding: .2em;\n}\n\n.right {\n float: right;\n}\n\n.emoji {\n *float: left;\n width: 1em;\n vertical-align: top;\n}\n\npre {\n width: 100%;\n display: block;\n}\n\ncode {\n display: inline-block;\n vertical-align: bottom;\n}\n\ncode, pre {\noverflow: auto;\nword-break: break-all;\nword-wrap: break-word;\nwhite-space: pre;\nwhite-space: -moz-pre-wrap;\nwhite-space: pre-wrap;\nwhite-space: pre\\9;\n}\n\n\n.btn {\n display: inline-block;\n *display: inline;\n padding: 2px 6px;\n margin-bottom: 0;\n margin-right: .2em;\n font-size: 14px;\n line-height: 20px;\n color: #d5d5d5;\n text-align: center;\n text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);\n vertical-align: middle;\n cursor: pointer;\n background-color: #222;\n border: 1px solid #222;\n border-radius: 4px;\n}\n\n\n.btn:hover,\n.btn:focus,\n.btn:active,\n.btn.active,\n.btn.disabled,\n.btn[disabled] {\n color: white;\n background-color: black;\n}\n\n.btn:active,\n.btn.active {\n background-color: #111;\n}\n\n.btn:first-child {\n *margin-left: 0;\n}\n\n" |
tools.js | ||
---|---|---|
@@ -8,9 +8,11 @@ | ||
8 | 8 … | var sbot = require('./scuttlebot') |
9 | 9 … | |
10 | 10 … | var config = require('./config')() |
11 | 11 … | |
12 | -function votes (msg) { | |
12 … | +var id = require('./keys').id | |
13 … | + | |
14 … | +/*function votes (msg) { | |
13 | 15 … | var votes = h('div.votes') |
14 | 16 … | if (msg.key) { |
15 | 17 … | pull( |
16 | 18 … | sbot.links({dest: msg.key, rel: 'vote'}), |
@@ -21,10 +23,94 @@ | ||
21 | 23 … | }) |
22 | 24 … | ) |
23 | 25 … | } |
24 | 26 … | return votes |
27 … | +}*/ | |
28 … | + | |
29 … | +function votes (msg) { | |
30 … | + var votes = h('div.votes') | |
31 … | + if (msg.key) { | |
32 … | + console.log('Looking for votes') | |
33 … | + pull( | |
34 … | + sbot.backlinks({query: [{$filter: {value: {content: {type: 'vote', vote: {link: msg.key}}}}}], live: true}), | |
35 … | + pull.drain(function (data) { | |
36 … | + if (data.sync) { console.log('waiting for new votes')} | |
37 … | + else if (data.value.content.vote.value == 1) { | |
38 … | + votes.appendChild(h('a#vote:' + data.value.author.substring(0, 44), {href:'#' + data.value.author}, h('img.emoji', {src: config.emojiUrl + 'star.png'}))) | |
39 … | + } | |
40 … | + else if (data.value.content.vote.value == -1) { | |
41 … | + var lookFor = 'vote:' + data.value.author.substring(0, 44) | |
42 … | + var remove = document.getElementById(lookFor) | |
43 … | + remove.parentNode.removeChild(remove) | |
44 … | + } | |
45 … | + }) | |
46 … | + ) | |
47 … | + } | |
48 … | + return votes | |
25 | 49 … | } |
26 | 50 … | |
51 … | +module.exports.star = function (msg) { | |
52 … | + var votebutton = h('span#star:' + msg.key.substring(0, 44)) | |
53 … | + var vote = { | |
54 … | + type: 'vote', | |
55 … | + vote: { link: msg.key, expression: 'Star' } | |
56 … | + } | |
57 … | + | |
58 … | + var star = h('button.btn.right', | |
59 … | + h('img.emoji', {src: config.emojiUrl + 'star.png'}), { | |
60 … | + onclick: function () { | |
61 … | + console.log(vote) | |
62 … | + vote.vote.value = 1 | |
63 … | + sbot.publish(vote, function (err, voted) { | |
64 … | + if(err) throw err | |
65 … | + console.log('Starred!', voted) | |
66 … | + votebutton.replaceChild(unstar, star) | |
67 … | + }) | |
68 … | + } | |
69 … | + } | |
70 … | + ) | |
71 … | + | |
72 … | + var unstar = h('button.btn.right', | |
73 … | + h('img.emoji', {src: config.emojiUrl + 'stars.png'}), { | |
74 … | + onclick: function () { | |
75 … | + vote.vote.value = -1 | |
76 … | + sbot.publish(vote, function (err, voted) { | |
77 … | + if(err) throw err | |
78 … | + console.log('Unstarred!', voted) | |
79 … | + votebutton.replaceChild(star, unstar) | |
80 … | + }) | |
81 … | + } | |
82 … | + } | |
83 … | + ) | |
84 … | + | |
85 … | + pull( | |
86 … | + sbot.backlinks({query: [{$filter: {value: {content: {type: 'vote', vote: {link: msg.key}}}}}]}), | |
87 … | + pull.drain(function (data) { | |
88 … | + if (data.sync) { } | |
89 … | + else if (data.value.content.vote.value == 1) { | |
90 … | + votebutton.replaceChild(unstar, star) | |
91 … | + } | |
92 … | + else if (data.value.content.vote.value == -1) { | |
93 … | + votebutton.replaceChild(star, unstar) | |
94 … | + } | |
95 … | + }) | |
96 … | + ) | |
97 … | + /*pull( | |
98 … | + sbot.links({dest: msg.key, rel: 'vote', author: id}), | |
99 … | + pull.drain(function (data) { | |
100 … | + if (data) | |
101 … | + console.log(data) | |
102 … | + if (data.value.vote.value == 1) | |
103 … | + votebutton.replaceChild(unstar, star) | |
104 … | + else if (data.value.vote.value == -1) | |
105 … | + votebutton.replaceChild(star, unstar) | |
106 … | + }) | |
107 … | + )*/ | |
108 … | + | |
109 … | + votebutton.appendChild(star) | |
110 … | + return votebutton | |
111 … | +} | |
112 … | + | |
27 | 113 … | module.exports.timestamp = function (msg, edited) { |
28 | 114 … | var timestamp |
29 | 115 … | if (edited) |
30 | 116 … | timestamp = h('span.timestamp', 'Edited: ', h('a', {href: '#' + msg.key}, human(new Date(msg.value.timestamp)))) |
@@ -32,8 +118,23 @@ | ||
32 | 118 … | timestamp = h('span.timestamp', h('a', {href: '#' + msg.key}, human(new Date(msg.value.timestamp)))) |
33 | 119 … | return timestamp |
34 | 120 … | } |
35 | 121 … | |
122 … | + | |
123 … | +module.exports.mini = function (msg, content) { | |
124 … | + return h('div.mini', | |
125 … | + h('span.avatar', | |
126 … | + h('a', {href: '#' + msg.value.author}, | |
127 … | + h('span.avatar--small', avatar.image(msg.value.author)), | |
128 … | + avatar.name(msg.value.author) | |
129 … | + ) | |
130 … | + ), | |
131 … | + exports.timestamp(msg), | |
132 … | + content | |
133 … | + ) | |
134 … | +} | |
135 … | + | |
136 … | + | |
36 | 137 … | module.exports.header = function (msg) { |
37 | 138 … | return h('div.header', |
38 | 139 … | h('span.avatar', |
39 | 140 … | h('a', {href: '#' + msg.value.author}, |
views.js | ||
---|---|---|
@@ -24,8 +24,61 @@ | ||
24 | 24 … | |
25 | 25 … | screen.appendChild(hyperscroll(content)) |
26 | 26 … | } |
27 | 27 … | |
28 … | +var edit = function() { | |
29 … | + var content = h('div.content') | |
30 … | + | |
31 … | + var screen = document.getElementById('screen') | |
32 … | + | |
33 … | + screen.appendChild(hyperscroll(content)) | |
34 … | + | |
35 … | + var nameInput = h('input', {placeholder: 'New name'}) | |
36 … | + | |
37 … | + var locInput = h('input', {placeholder: 'New location'}) | |
38 … | + | |
39 … | + var descInput = h('textarea', {placeholder: 'New description'}) | |
40 … | + | |
41 … | + var editor = h('div.message', | |
42 … | + h('h1', 'Edit profile'), | |
43 … | + nameInput, | |
44 … | + h('button.btn.btn-primary', 'Preview', {onclick: function () { | |
45 … | + if(nameInput.value) { | |
46 … | + api.message_confirm({ | |
47 … | + type: 'about', | |
48 … | + about: id, | |
49 … | + name: nameInput.value || undefined | |
50 … | + }) | |
51 … | + } | |
52 … | + }}), | |
53 … | + h('hr'), | |
54 … | + locInput, | |
55 … | + h('button.btn.btn-primary', 'Preview', {onclick: function () { | |
56 … | + if(locInput.value) { | |
57 … | + api.message_confirm({ | |
58 … | + type: 'loc', | |
59 … | + about: id, | |
60 … | + loc: locInput.value || undefined | |
61 … | + }) | |
62 … | + } | |
63 … | + }}), | |
64 … | + h('hr'), | |
65 … | + descInput, | |
66 … | + h('button.btn.btn-primary', 'Preview', {onclick: function (){ | |
67 … | + if(descInput.value) { | |
68 … | + api.message_confirm({ | |
69 … | + type: 'description', | |
70 … | + about: id, | |
71 … | + description: descInput.value || undefined | |
72 … | + }) | |
73 … | + } | |
74 … | + }}), | |
75 … | + h('hr') | |
76 … | + ) | |
77 … | + | |
78 … | + content.appendChild(editor) | |
79 … | +} | |
80 … | + | |
28 | 81 … | var mentionsStream = function () { |
29 | 82 … | var content = h('div.content') |
30 | 83 … | |
31 | 84 … | var screen = document.getElementById('screen') |
@@ -182,8 +235,10 @@ | ||
182 | 235 … | console.log('mentions') |
183 | 236 … | mentionsStream() |
184 | 237 … | } else if (src == 'about') { |
185 | 238 … | about() |
239 … | + } else if (src == 'edit') { | |
240 … | + edit() | |
186 | 241 … | } else if (src == 'key') { |
187 | 242 … | keyPage() |
188 | 243 … | } else { |
189 | 244 … | logStream() |
Built with git-ssb-web