Commit c20f1f54514253fb0cd2fbeb38bc3cbbc5f0f12d
add click handler, "publish" translation
mix irving committed on 4/10/2018, 10:06:11 PMParent: 35b74ae2d81cf0619ba5864d5875785f83255ef3
Files changed
app/page/blogNew.js | changed |
app/page/blogNew.mcss | changed |
app/page/blogShow.js | changed |
app/page/blogShow.mcss | changed |
message/html/compose.js | changed |
styles/mixins.js | changed |
translations/en.js | changed |
app/page/blogNew.js | ||
---|---|---|
@@ -33,12 +33,9 @@ | ||
33 | 33 … | summary: Value(), |
34 | 34 … | text: Value('') |
35 | 35 … | }) |
36 | 36 … | |
37 | - const mediumComposer = h('div.editor.Markdown', { | |
38 | - 'ev-input': e => { | |
39 | - } | |
40 | - }) | |
37 … | + const mediumComposer = h('Markdown.editor') | |
41 | 38 … | var filesById = {} |
42 | 39 … | const composer = initialiseDummyComposer({ filesById, meta, api }) |
43 | 40 … | // NOTE we are bootstrapping off the message.html.compose logic |
44 | 41 … | // - the mediumComposer feeds content into the composer, which the provides publishing |
@@ -49,18 +46,28 @@ | ||
49 | 46 … | 'ev-input': e => meta.channel.set(e.target.value), |
50 | 47 … | value: meta.channel, |
51 | 48 … | placeholder: strings.channel |
52 | 49 … | }) |
50 … | + const updateTitle = e => { | |
51 … | + if (e.target.childElementCount) { | |
52 … | + // catch people pasting html in here! | |
53 … | + e.target.innerHTML = e.target.innerText | |
54 … | + } | |
55 … | + meta.title.set(e.target.innerText) | |
56 … | + } | |
53 | 57 … | |
54 | 58 … | var page = h('Page -blogNew', [ |
55 | 59 … | api.app.html.sideNav(location), |
56 | 60 … | h('div.content', [ |
57 | 61 … | h('div.container', [ |
58 | 62 … | h('div.field -title', [ |
59 | - h('input', { | |
60 | - 'ev-input': e => meta.title.set(e.target.value), | |
61 | - className: when(meta.title, '', '-empty'), | |
62 | - placeholder: strings.blogNew.field.title | |
63 … | + h('h1.input', { | |
64 … | + attributes: { | |
65 … | + contenteditable: true, | |
66 … | + 'data-placeholder': strings.blogNew.field.title | |
67 … | + }, | |
68 … | + 'ev-input': updateTitle, | |
69 … | + className: when(meta.title, '', '-empty') | |
63 | 70 … | }) |
64 | 71 … | ]), |
65 | 72 … | mediumComposer, |
66 | 73 … | h('div.field -attachment', |
@@ -90,8 +97,9 @@ | ||
90 | 97 … | } |
91 | 98 … | |
92 | 99 … | function AddFileButton ({ api, filesById, meta, textArea }) { |
93 | 100 … | // var textRaw = meta.text |
101 … | + // | |
94 | 102 … | |
95 | 103 … | const fileInput = api.blob.html.input(file => { |
96 | 104 … | filesById[file.link] = file |
97 | 105 … | |
@@ -107,9 +115,14 @@ | ||
107 | 115 … | } else { |
108 | 116 … | content = h('a', { href: file.link }, file.name) |
109 | 117 … | } |
110 | 118 … | // TODO - insert where the mouse is yo |
111 | - textArea.appendChild(h('p', content)) | |
119 … | + var editor = MediumEditor.getEditorFromElement(textArea) | |
120 … | + debugger | |
121 … | + textArea.insertBefore( | |
122 … | + h('p', content), | |
123 … | + editor.currentEl || null | |
124 … | + ) | |
112 | 125 … | |
113 | 126 … | console.log('added:', file) |
114 | 127 … | }) |
115 | 128 … | |
@@ -121,8 +134,11 @@ | ||
121 | 134 … | { |
122 | 135 … | meta, |
123 | 136 … | // placeholder: strings.blogNew.actions.writeBlog, |
124 | 137 … | shrink: false, |
138 … | + canAttach: false, | |
139 … | + canPreview: false, | |
140 … | + publishString: api.translations.sync.strings().publishBlog, | |
125 | 141 … | filesById, |
126 | 142 … | prepublish: function (content, cb) { |
127 | 143 … | var m = /\!\[[^]+\]\(([^\)]+)\)/.exec(marksum.image(content.text)) |
128 | 144 … | content.thumbnail = m && m[1] |
@@ -172,11 +188,8 @@ | ||
172 | 188 … | }) |
173 | 189 … | } |
174 | 190 … | |
175 | 191 … | function initialiseMedium ({ page, el, meta }) { |
176 | - // el.addEventListener('keyup', ev => { | |
177 | - // debugger | |
178 | - // }) | |
179 | 192 … | var editor = new MediumEditor(el, { |
180 | 193 … | elementsContainer: page, |
181 | 194 … | // autoLink: true, |
182 | 195 … | buttonLabels: 'fontawesome', |
@@ -220,8 +233,11 @@ | ||
220 | 233 … | replacement: (content, node) => { |
221 | 234 … | var blob = decodeURIComponent(node.src.replace('http://localhost:8989/blobs/get/', '')) |
222 | 235 … | return `![${node.alt}](${blob})` |
223 | 236 … | } |
237 … | + }, { | |
238 … | + filter: 'span', | |
239 … | + replacement: (content, node) => content | |
224 | 240 … | }] |
225 | 241 … | }, |
226 | 242 … | events: ['input', 'change', 'DOMNodeInserted'] |
227 | 243 … | }, |
@@ -229,6 +245,17 @@ | ||
229 | 245 … | ) |
230 | 246 … | } |
231 | 247 … | }) |
232 | 248 … | |
249 … | + editor.on(el, 'keyup', setCurrentEl) | |
250 … | + editor.on(el, 'click', setCurrentEl) | |
251 … | + | |
252 … | + function setCurrentEl (ev) { | |
253 … | + var sel = window.getSelection() | |
254 … | + var container = sel.getRangeAt(0).commonAncestorContainer | |
255 … | + editor.currentEl = container.textContent === '' // NOTE this could be a brittle check | |
256 … | + ? container | |
257 … | + : container.parentElement | |
258 … | + } | |
259 … | + | |
233 | 260 … | return editor |
234 | 261 … | } |
app/page/blogNew.mcss | ||
---|---|---|
@@ -33,19 +33,27 @@ | ||
33 | 33 … | } |
34 | 34 … | |
35 | 35 … | -title { |
36 | 36 … | margin: 0 |
37 … | + background-color: #fff | |
37 | 38 … | |
38 | - input { | |
39 | - font-size: 2em | |
40 | - font-weight: bold | |
39 … | + h1.input { | |
40 … | + flex-grow: 1 | |
41 … | + $fontTitle | |
41 | 42 … | |
42 | - padding-top: 2rem | |
43 … | + padding: 2rem 1rem .6rem 1rem | |
43 | 44 … | border: none |
44 | 45 … | border-radius: 0 |
46 … | + margin: 0 | |
47 … | + outline: none | |
45 | 48 … | |
46 | 49 … | -empty { |
47 | 50 … | font-style: italic |
51 … | + color: #b3b3b1 | |
52 … | + | |
53 … | + ::after { | |
54 … | + content: attr(data-placeholder) | |
55 … | + } | |
48 | 56 … | } |
49 | 57 … | } |
50 | 58 … | } |
51 | 59 … | |
@@ -86,9 +94,11 @@ | ||
86 | 94 … | |
87 | 95 … | -channel {} |
88 | 96 … | } |
89 | 97 … | |
90 | - div.editor{ | |
98 … | + div.editor.Makdown { | |
99 … | + $markdownBlog | |
100 … | + | |
91 | 101 … | background-color: #fff |
92 | 102 … | padding: 1rem |
93 | 103 … | min-height: 30rem |
94 | 104 … | outline: none |
@@ -100,11 +110,12 @@ | ||
100 | 110 … | } |
101 | 111 … | } |
102 | 112 … | |
103 | 113 … | div.Compose { |
114 … | + margin-bottom: 4rem | |
115 … | + | |
104 | 116 … | textarea { |
105 | - margin-top: 2rem | |
106 | - min-height: 30rem | |
117 … | + display: none | |
107 | 118 … | } |
108 | 119 … | } |
109 | 120 … | } |
110 | 121 … | } |
app/page/blogShow.js | ||
---|---|---|
@@ -37,9 +37,9 @@ | ||
37 | 37 … | return h('Page -blogShow', [ |
38 | 38 … | api.app.html.sideNav({ page: 'blogShow' }), // HACK to highlight discover |
39 | 39 … | h('Scroller.content', [ |
40 | 40 … | h('section.top', [ |
41 | - api.app.html.topNav(location) | |
41 … | + api.app.html.topNav(blogMsg) | |
42 | 42 … | ]), |
43 | 43 … | h('section.content', [ |
44 | 44 … | h('header', [ |
45 | 45 … | h('div.blog', [ |
app/page/blogShow.mcss | ||
---|---|---|
@@ -32,12 +32,10 @@ | ||
32 | 32 … | align-items: center |
33 | 33 … | |
34 | 34 … | h1 { |
35 | 35 … | flex-basis: 100% |
36 … | + $fontTitle | |
36 | 37 … | |
37 | - $markdownLarge | |
38 | - font-size: 2rem | |
39 | - font-weight: 300 | |
40 | 38 … | margin: 0 0 1rem 0 |
41 | 39 … | } |
42 | 40 … | |
43 | 41 … | div.Timeago { |
@@ -87,8 +85,12 @@ | ||
87 | 85 … | $backgroundPrimaryText |
88 | 86 … | padding: 1.5rem |
89 | 87 … | |
90 | 88 … | margin-bottom: 1.5rem |
89 … | + | |
90 … | + div.Markdown { | |
91 … | + $markdownBlog | |
92 … | + } | |
91 | 93 … | } |
92 | 94 … | |
93 | 95 … | div.Comments { |
94 | 96 … | flex-basis: 100% |
message/html/compose.js | ||
---|---|---|
@@ -27,8 +27,9 @@ | ||
27 | 27 … | var { |
28 | 28 … | meta, // required |
29 | 29 … | feedIdsInThread = [], |
30 | 30 … | placeholder, |
31 … | + publishString, | |
31 | 32 … | shrink = true, |
32 | 33 … | canAttach = true, canPreview = true, |
33 | 34 … | filesById = {}, |
34 | 35 … | prepublish |
@@ -39,8 +40,9 @@ | ||
39 | 40 … | const getChannelSuggestions = api.channel.async.suggest() |
40 | 41 … | const getEmojiSuggestions = api.emoji.async.suggest() |
41 | 42 … | |
42 | 43 … | placeholder = placeholder || strings.writeMessage |
44 … | + publishString = publishString || strings.sendMessage | |
43 | 45 … | |
44 | 46 … | var textAreaFocused = Value(false) |
45 | 47 … | var focused = textAreaFocused |
46 | 48 … | var hasContent = Value(false) |
@@ -104,9 +106,9 @@ | ||
104 | 106 … | } |
105 | 107 … | var { previewBtn, showPreview } = PreviewSetup(strings) |
106 | 108 … | var preview = computed(textRaw, text => api.message.html.markdown(text)) |
107 | 109 … | |
108 | - var publishBtn = h('Button -primary', { 'ev-click': () => publish({ filesById }) }, strings.sendMessage) | |
110 … | + var publishBtn = h('Button -primary', { 'ev-click': () => publish({ filesById }) }, publishString) | |
109 | 111 … | |
110 | 112 … | var actions = h('section.actions', [ |
111 | 113 … | canAttach ? fileInput : '', |
112 | 114 … | canPreview ? previewBtn : '', |
@@ -163,9 +165,11 @@ | ||
163 | 165 … | prepublish(content, function (err, content) { |
164 | 166 … | if (err) handleErr(err) |
165 | 167 … | else api.message.async.publish(content, done) |
166 | 168 … | }) |
167 | - } else { api.message.async.publish(content, done) } | |
169 … | + } else { | |
170 … | + api.message.async.publish(content, done) | |
171 … | + } | |
168 | 172 … | |
169 | 173 … | function done (err, msg) { |
170 | 174 … | publishBtn.disabled = false |
171 | 175 … | if (err) handleErr(err) |
styles/mixins.js | ||
---|---|---|
@@ -9,14 +9,28 @@ | ||
9 | 9 … | }) |
10 | 10 … | } |
11 | 11 … | |
12 | 12 … | const mainMixins = ` |
13 … | +$fontSerif { | |
14 … | + font-family: Georgia,Cambria,"Times New Roman",Times,serif | |
15 … | +} | |
16 … | + | |
17 … | +$fontSansSerif { | |
18 … | + font-family: "Lucida Grande","Lucida Sans Unicode","Lucida Sans",Geneva,Arial,sans-serif | |
19 … | +} | |
20 … | + | |
13 | 21 … | $fontBasic { |
14 | - font-family: arial | |
22 … | + color: rgba(0,0,0,.84) | |
23 … | + $fontSansSerif | |
24 … | + font-size: 1rem | |
15 | 25 … | line-height: 1.2 |
16 | - font-size: 1rem | |
17 | 26 … | } |
18 | 27 … | |
28 … | +$fontTitle { | |
29 … | + $fontSansSerif | |
30 … | + font-size: 2.5rem | |
31 … | +} | |
32 … | + | |
19 | 33 … | $maxWidth { |
20 | 34 … | max-width: 1000px |
21 | 35 … | } |
22 | 36 … | |
@@ -114,23 +128,23 @@ | ||
114 | 128 … | |
115 | 129 … | $markdownSmall { |
116 | 130 … | div.Markdown { |
117 | 131 … | h1, h2, h3, h4, h5, h6, p { |
118 | - font-size: .9rem | |
132 … | + font-size: 1rem | |
119 | 133 … | font-weight: 300 |
120 | 134 … | margin: 0 |
121 | 135 … | } |
122 | 136 … | (img.emoji) { |
123 | - height: .9rem | |
137 … | + height: 1rem | |
124 | 138 … | } |
125 | 139 … | } |
126 | 140 … | h1, h2, h3, h4, h5, h6, p { |
127 | - font-size: .9rem | |
141 … | + font-size: 1rem | |
128 | 142 … | font-weight: 300 |
129 | 143 … | margin: 0 |
130 | 144 … | } |
131 | 145 … | (img.emoji) { |
132 | - height: .9rem | |
146 … | + height: 1rem | |
133 | 147 … | } |
134 | 148 … | } |
135 | 149 … | |
136 | 150 … | $markdownLarge { |
@@ -161,8 +175,20 @@ | ||
161 | 175 … | font-weight: bold |
162 | 176 … | } |
163 | 177 … | } |
164 | 178 … | |
179 … | +$markdownBlog { | |
180 … | + $fontSerif | |
181 … | + line-height: 1.58 | |
182 … | + | |
183 … | + h1, h2, h3, h4, h5, h6 { | |
184 … | + $fontSansSerif | |
185 … | + letter-spacing: -.015rem | |
186 … | + } | |
187 … | + | |
188 … | + font-size: 1.25rem | |
189 … | +} | |
190 … | + | |
165 | 191 … | $borderSubtle { |
166 | 192 … | border: 1px solid #b9b9b9 |
167 | 193 … | } |
168 | 194 … |
translations/en.js | ||
---|---|---|
@@ -37,8 +37,9 @@ | ||
37 | 37 … | writeMessage: 'Write a message', |
38 | 38 … | writeComment: 'Write a comment', |
39 | 39 … | peopleNearby: 'People nearby', |
40 | 40 … | sendMessage: 'Send', |
41 … | + publishBlog: 'Publish', | |
41 | 42 … | showMore: 'Show More', |
42 | 43 … | directMessages: 'Direct Messages', |
43 | 44 … | home: 'Home', |
44 | 45 … | error: 'Error', |
Built with git-ssb-web