Monorepo for Tangled tangled.org

appview/pages: PR comment link button when comment box is closed #1181

merged opened by oyster.cafe targeting master from lt/appview-pages-pr-comment-tweak

Anirudh and I keep motioning to click and hold a button that isn't there unless the comment box is open. Instead, show the button at all times and open the comment box with a link added if it's not already.

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:3fwecdnvtcscjnrx2p4n7alz/sh.tangled.repo.pull/3mhg6n5ok4o22
+71 -41
Diff #0
+71 -41
appview/pages/templates/fragments/line-quote-button.html
··· 107 107 let dragCurrent = null; 108 108 let hoverTarget = null; 109 109 110 + const commentBtn = () => 111 + document.querySelector('[hx-get$="/comment"]:not(form *)'); 112 + 113 + const openCommentForm = () => { 114 + const ta = textarea(); 115 + if (ta) return Promise.resolve(ta); 116 + const trigger = commentBtn(); 117 + if (!trigger) return Promise.resolve(null); 118 + trigger.click(); 119 + return new Promise(resolve => { 120 + const handler = () => { 121 + const ta = textarea(); 122 + if (!ta) return; 123 + document.body.removeEventListener('htmx:afterSettle', handler); 124 + clearTimeout(timer); 125 + resolve(ta); 126 + }; 127 + const timer = setTimeout(() => { 128 + document.body.removeEventListener('htmx:afterSettle', handler); 129 + resolve(null); 130 + }, 5000); 131 + document.body.addEventListener('htmx:afterSettle', handler); 132 + }); 133 + }; 134 + 110 135 const showBtn = (lineEl) => { 111 - if (!textarea() || !anchorOf(lineEl)) return; 136 + if ((!textarea() && !commentBtn()) || !anchorOf(lineEl)) return; 112 137 const rect = lineEl.getBoundingClientRect(); 113 138 Object.assign(btn.style, { 114 139 top: `${rect.top + rect.height / 2 - btn.offsetHeight / 2}px`, ··· 182 207 stretchBtn(dragAnchor, dragCurrent); 183 208 }); 184 209 210 + const insertIntoTextarea = (ta, selected) => { 211 + const first = selected[0]; 212 + const last = selected[selected.length - 1]; 213 + const fNum = lineNumOf(first); 214 + const firstAnchor = anchorOf(first); 215 + 216 + if (!fNum || !firstAnchor) return; 217 + 218 + const file = fileOf(first); 219 + const lNum = lineNumOf(last); 220 + const lastAnchor = anchorOf(last); 221 + 222 + const label = selected.length === 1 223 + ? (file ? `${file}:${fNum}` : `L${fNum}`) 224 + : (file ? `${file}:${fNum}-${lNum}` : `L${fNum}-${lNum}`); 225 + 226 + const fragment = selected.length === 1 227 + ? firstAnchor 228 + : `${firstAnchor}~${lastAnchor}`; 229 + 230 + const md = `[\`${label}\`](${window.location.pathname}${window.location.search}#${fragment})`; 231 + 232 + const { selectionStart: s, selectionEnd: end, value } = ta; 233 + const before = value.slice(0, s); 234 + const after = value.slice(end); 235 + let pre = '', suf = ''; 236 + if (s === end && before.length > 0) { 237 + const cur = before.slice(before.lastIndexOf('\n') + 1); 238 + if (cur.length > 0) { 239 + const nextNl = after.indexOf('\n'); 240 + const rest = nextNl === -1 ? after : after.slice(0, nextNl); 241 + if (rest.trim().length === 0) { pre = '\n'; } 242 + else { pre = before.endsWith(' ') ? '' : ' '; suf = after.startsWith(' ') ? '' : ' '; } 243 + } 244 + } 245 + ta.value = before + pre + md + suf + after; 246 + ta.selectionStart = ta.selectionEnd = s + pre.length + md.length + suf.length; 247 + ta.focus(); 248 + ta.dispatchEvent(new Event('input', { bubbles: true })); 249 + }; 250 + 185 251 document.addEventListener('mouseup', () => { 186 252 if (!dragging) return; 187 253 dragging = false; 188 254 document.body.style.userSelect = ''; 189 255 190 256 const selected = rangeBetween(dragAnchor, dragCurrent); 191 - const ta = textarea(); 192 - if (ta && selected.length > 0) { 193 - const first = selected[0]; 194 - const last = selected[selected.length - 1]; 195 - const fNum = lineNumOf(first); 196 - const firstAnchor = anchorOf(first); 197 - 198 - if (fNum && firstAnchor) { 199 - const file = fileOf(first); 200 - const lNum = lineNumOf(last); 201 - const lastAnchor = anchorOf(last); 202 - 203 - const label = selected.length === 1 204 - ? (file ? `${file}:${fNum}` : `L${fNum}`) 205 - : (file ? `${file}:${fNum}-${lNum}` : `L${fNum}-${lNum}`); 206 - 207 - const fragment = selected.length === 1 208 - ? firstAnchor 209 - : `${firstAnchor}~${lastAnchor}`; 210 - 211 - const md = `[\`${label}\`](${window.location.pathname}${window.location.search}#${fragment})`; 212 - 213 - const { selectionStart: s, selectionEnd: end, value } = ta; 214 - const before = value.slice(0, s); 215 - const after = value.slice(end); 216 - let pre = '', suf = ''; 217 - if (s === end && before.length > 0) { 218 - const cur = before.slice(before.lastIndexOf('\n') + 1); 219 - if (cur.length > 0) { 220 - const nextNl = after.indexOf('\n'); 221 - const rest = nextNl === -1 ? after : after.slice(0, nextNl); 222 - if (rest.trim().length === 0) { pre = '\n'; } 223 - else { pre = before.endsWith(' ') ? '' : ' '; suf = after.startsWith(' ') ? '' : ' '; } 224 - } 225 - } 226 - ta.value = before + pre + md + suf + after; 227 - ta.selectionStart = ta.selectionEnd = s + pre.length + md.length + suf.length; 228 - ta.focus(); 229 - ta.dispatchEvent(new Event('input', { bubbles: true })); 230 - } 257 + if (selected.length > 0) { 258 + openCommentForm().then(ta => { 259 + if (ta) insertIntoTextarea(ta, selected); 260 + }); 231 261 } 232 262 233 263 clearHl('line-quote-hl');

History

1 round 0 comments
sign up or login to add to the discussion
oyster.cafe submitted #0
1 commit
expand
appview/pages: PR comment link button when comment box is closed
1/3 failed, 1/3 success, 1/3 running
expand
expand 0 comments
pull request successfully merged