diff --git a/src/components/compose/Status.tsx b/src/components/compose/Status.tsx index db83b6dd..b6fe79b2 100644 --- a/src/components/compose/Status.tsx +++ b/src/components/compose/Status.tsx @@ -34,6 +34,7 @@ type Props = { account: Account client: MegalodonInterface in_reply_to?: Entity.Status + edit_target?: Entity.Status onClose?: () => void } @@ -119,6 +120,29 @@ const Status: React.FC = props => { } }, [props.in_reply_to, props.account]) + useEffect(() => { + if (props.edit_target) { + const target = props.edit_target + let value = { + spoiler: target.spoiler_text, + status: target.plain_content ? target.plain_content : target.content + } + + if (target.sensitive) { + value = Object.assign(value, { + nsfw: target.sensitive + }) + } + if (target.media_attachments.length > 0) { + value = Object.assign(value, { + attachments: target.media_attachments + }) + } + setFormValue(value) + setVisibility(target.visibility) + } + }, [props.edit_target]) + const handleSubmit = async () => { if (loading) { return @@ -157,7 +181,16 @@ const Status: React.FC = props => { poll: formValue.poll }) } - await props.client.postStatus(formValue.status, options) + if (props.edit_target) { + await props.client.editStatus( + props.edit_target.id, + Object.assign({}, options, { + status: formValue.status + }) + ) + } else { + await props.client.postStatus(formValue.status, options) + } clear() } catch { toast.push(alert('error', t('alert.failed_post')), { placement: 'topStart' }) @@ -370,7 +403,7 @@ const Status: React.FC = props => { - {props.in_reply_to && } + {(props.in_reply_to || props.edit_target) && } diff --git a/src/components/timelines/status/Actions.tsx b/src/components/timelines/status/Actions.tsx index 6a3ac771..a45299a3 100644 --- a/src/components/timelines/status/Actions.tsx +++ b/src/components/timelines/status/Actions.tsx @@ -20,6 +20,7 @@ type Props = { status: Entity.Status client: MegalodonInterface setShowReply: Dispatch> + setShowEdit: Dispatch> updateStatus: (status: Entity.Status) => void } @@ -176,6 +177,9 @@ const Actions: React.FC = props => { openBrowser: () => { open(status.url) }, + openEdit: () => { + props.setShowEdit(current => !current) + }, onDelete: () => { // After after deleted, streaming will receive a delete event. // So we don't need update parent timelines, the delete event will be handled. @@ -230,6 +234,7 @@ type DetailMenuProps = { own: boolean openBrowser: () => void onDelete: () => void + openEdit: () => void onClose: (delay?: number) => NodeJS.Timeout | void } @@ -242,6 +247,9 @@ const detailMenu = (props: DetailMenuProps, ref: React.RefCallback) case 'browser': props.openBrowser() return + case 'edit': + props.openEdit() + return case 'delete': props.onDelete() return diff --git a/src/components/timelines/status/Status.tsx b/src/components/timelines/status/Status.tsx index e78f9449..653528bc 100644 --- a/src/components/timelines/status/Status.tsx +++ b/src/components/timelines/status/Status.tsx @@ -31,14 +31,23 @@ type Props = { const Status: React.FC = props => { const { client } = props const [showReply, setShowReply] = useState(false) + const [showEdit, setShowEdit] = useState(false) const status = originalStatus(props.status) useEffect(() => { if (props.setReplyOpened) { - props.setReplyOpened(showReply) + if (showReply) { + props.setReplyOpened(showReply) + setShowEdit(false) + } else if (showEdit) { + props.setReplyOpened(showEdit) + setShowReply(false) + } else { + props.setReplyOpened(false) + } } - }, [showReply]) + }, [showReply, showEdit]) const statusClicked: MouseEventHandler = e => { const url = findLink(e.target as HTMLElement, 'status-body') @@ -124,6 +133,7 @@ const Status: React.FC = props => { status={status} client={client} setShowReply={setShowReply} + setShowEdit={setShowEdit} updateStatus={props.updateStatus} /> @@ -133,6 +143,11 @@ const Status: React.FC = props => { setShowReply(false)} /> )} + {showEdit && ( +
+ setShowEdit(false)} /> +
+ )} ) }