a tool for shared writing and social publishing

enable submit via ctrl/cmd+enter for comments

+52 -43
+52 -43
app/lish/[did]/[publication]/[rkey]/Interactions/Comments/CommentBox.tsx
··· 45 45 }) { 46 46 let mountRef = useRef<HTMLPreElement | null>(null); 47 47 let { commentBox: { quote } } = useInteractionState(props.doc_uri); 48 + let [loading, setLoading] = useState(false); 49 + 50 + const handleSubmit = async () => { 51 + if (loading || !view.current) return; 52 + 53 + setLoading(true); 54 + let currentState = view.current.state; 55 + let [plaintext, facets] = docToFacetedText(currentState.doc); 56 + let comment = await publishComment({ 57 + document: props.doc_uri, 58 + comment: { 59 + plaintext, 60 + facets, 61 + replyTo: props.replyTo, 62 + attachment: quote 63 + ? { 64 + $type: "pub.leaflet.comment#linearDocumentQuote", 65 + document: props.doc_uri, 66 + quote, 67 + } 68 + : undefined, 69 + }, 70 + }); 71 + 72 + let tr = currentState.tr; 73 + tr = tr.replaceWith( 74 + 0, 75 + currentState.doc.content.size, 76 + multiBlockSchema.nodes.paragraph.createAndFill()!, 77 + ); 78 + view.current.dispatch(tr); 79 + setLoading(false); 80 + props.onSubmit?.(); 81 + setInteractionState(props.doc_uri, (s) => ({ 82 + commentBox: { 83 + quote: null, 84 + }, 85 + localComments: [ 86 + ...s.localComments, 87 + { 88 + record: comment.record, 89 + uri: comment.uri, 90 + bsky_profiles: { record: comment.profile as Json }, 91 + }, 92 + ], 93 + })); 94 + }; 95 + 48 96 let [editorState, setEditorState] = useState(() => 49 97 EditorState.create({ 50 98 schema: multiBlockSchema, ··· 60 108 "Mod-z": undo, 61 109 "Mod-y": redo, 62 110 "Shift-Mod-z": redo, 111 + "Ctrl-Enter": () => { handleSubmit(); return true; }, 112 + "Meta-Enter": () => { handleSubmit(); return true; }, 63 113 }), 64 114 keymap(baseKeymap), 65 115 autolink({ ··· 157 207 view.current = null; 158 208 }; 159 209 }, []); 160 - let [loading, setLoading] = useState(false); 210 + 161 211 return ( 162 212 <div className=" flex flex-col"> 163 213 {quote && ( ··· 203 253 </div> 204 254 <ButtonPrimary 205 255 compact 206 - onClick={async () => { 207 - setLoading(true); 208 - let [plaintext, facets] = docToFacetedText(editorState.doc); 209 - let comment = await publishComment({ 210 - document: props.doc_uri, 211 - comment: { 212 - plaintext, 213 - facets, 214 - replyTo: props.replyTo, 215 - attachment: quote 216 - ? { 217 - $type: "pub.leaflet.comment#linearDocumentQuote", 218 - document: props.doc_uri, 219 - quote, 220 - } 221 - : undefined, 222 - }, 223 - }); 224 - 225 - let tr = editorState.tr; 226 - tr = tr.replaceWith( 227 - 0, 228 - editorState.doc.content.size, 229 - multiBlockSchema.nodes.paragraph.createAndFill()!, 230 - ); 231 - view.current?.dispatch(tr); 232 - setLoading(false); 233 - props.onSubmit?.(); 234 - setInteractionState(props.doc_uri, (s) => ({ 235 - commentBox: { 236 - quote: null, 237 - }, 238 - localComments: [ 239 - ...s.localComments, 240 - { 241 - record: comment.record, 242 - uri: comment.uri, 243 - bsky_profiles: { record: comment.profile as Json }, 244 - }, 245 - ], 246 - })); 247 - }} 256 + onClick={handleSubmit} 248 257 > 249 258 {loading ? <DotLoader /> : <ShareSmall />} 250 259 </ButtonPrimary>