mirror of
https://github.com/versia-pub/frontend.git
synced 2026-03-13 03:29:16 +01:00
feat: ✨ Add note editing capabilities
This commit is contained in:
parent
5a8e4e5d0f
commit
29d98c9f2c
8 changed files with 143 additions and 41 deletions
|
|
@ -47,7 +47,9 @@
|
|||
</ComposerButton>
|
||||
<ButtonsPrimary :loading="loading" @click="send" class="ml-auto rounded-full"
|
||||
:disabled="!canSubmit || loading">
|
||||
<span>Send!</span>
|
||||
<span>{{
|
||||
respondingType === "edit" ? "Edit!" : "Send!"
|
||||
}}</span>
|
||||
</ButtonsPrimary>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -68,7 +70,7 @@ const { input: content } = useTextareaAutosize({
|
|||
});
|
||||
const { Control_Enter, Command_Enter, Control_Alt } = useMagicKeys();
|
||||
const respondingTo = ref<Status | null>(null);
|
||||
const respondingType = ref<"reply" | "quote" | null>(null);
|
||||
const respondingType = ref<"reply" | "quote" | "edit" | null>(null);
|
||||
const me = useMe();
|
||||
const cw = ref(false);
|
||||
const cwContent = ref("");
|
||||
|
|
@ -161,6 +163,30 @@ onMounted(() => {
|
|||
content.value = `@${note.account.acct} `;
|
||||
textarea.value?.focus();
|
||||
});
|
||||
|
||||
useListen("composer:edit", async (note: Status) => {
|
||||
loading.value = true;
|
||||
files.value = note.media_attachments.map((file) => ({
|
||||
id: nanoid(),
|
||||
file: new File([], file.url),
|
||||
progress: 1,
|
||||
api_id: file.id,
|
||||
alt_text: file.description ?? undefined,
|
||||
}));
|
||||
|
||||
// Fetch source
|
||||
const source = await client.value?.getStatusSource(note.id);
|
||||
|
||||
if (source?.data) {
|
||||
respondingTo.value = note;
|
||||
respondingType.value = "edit";
|
||||
content.value = source.data.text;
|
||||
cwContent.value = source.data.spoiler_text;
|
||||
textarea.value?.focus();
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
|
|
@ -185,6 +211,46 @@ const client = useMegalodon(tokenData);
|
|||
const send = async () => {
|
||||
loading.value = true;
|
||||
|
||||
if (respondingType.value === "edit") {
|
||||
fetch(
|
||||
new URL(
|
||||
`/api/v1/statuses/${respondingTo.value?.id}`,
|
||||
client.value?.baseUrl ?? "",
|
||||
).toString(),
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${tokenData.value?.access_token}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
status: content.value?.trim() ?? "",
|
||||
content_type: markdown.value
|
||||
? "text/markdown"
|
||||
: "text/plain",
|
||||
spoiler_text: cw.value ? cwContent.value.trim() : undefined,
|
||||
sensitive: cw.value,
|
||||
media_ids: files.value
|
||||
.filter((file) => !!file.api_id)
|
||||
.map((file) => file.api_id),
|
||||
}),
|
||||
},
|
||||
)
|
||||
.then(async (res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to edit status");
|
||||
}
|
||||
|
||||
content.value = "";
|
||||
loading.value = false;
|
||||
useEvent("composer:send-edit", await res.json());
|
||||
})
|
||||
.finally(() => {
|
||||
useEvent("composer:close");
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(new URL("/api/v1/statuses", client.value?.baseUrl ?? "").toString(), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<Teleport to="body">
|
||||
<Dialog.Positioner
|
||||
class="flex min-h-full items-start z-50 justify-center p-4 text-center sm:items-center sm:p-0 fixed inset-0 w-screen overflow-y-auto">
|
||||
class="flex items-start z-50 justify-center p-4 text-center sm:items-center sm:p-0 fixed inset-0 w-screen h-screen overflow-y-hidden">
|
||||
<HeadlessTransitionChild as="template" enter="ease-out duration-200" enter-from="opacity-0"
|
||||
enter-to="opacity-100" leave="ease-in duration-200" leave-from="opacity-100"
|
||||
leave-to="opacity-0">
|
||||
|
|
@ -16,9 +16,11 @@
|
|||
enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-200"
|
||||
leave-from="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
|
||||
<Dialog.Content
|
||||
class="relative transform overflow-hidden rounded-lg bg-dark-700 ring-1 ring-dark-800 text-left shadow-xl transition-all sm:my-8 w-full max-w-xl">
|
||||
<Composer v-if="instance" :instance="instance" />
|
||||
<Dialog.Content class="overflow-y-auto w-full max-h-full md:py-16">
|
||||
<div
|
||||
class="relative overflow-hidden max-w-xl mx-auto rounded-lg bg-dark-700 ring-1 ring-dark-800 text-left shadow-xl transition-all w-full">
|
||||
<Composer v-if="instance" :instance="instance" />
|
||||
</div>
|
||||
</Dialog.Content>
|
||||
</HeadlessTransitionChild>
|
||||
</Dialog.Positioner>
|
||||
|
|
@ -40,6 +42,11 @@ useListen("note:quote", async (note) => {
|
|||
await nextTick();
|
||||
useEvent("composer:quote", note);
|
||||
});
|
||||
useListen("note:edit", async (note) => {
|
||||
open.value = true;
|
||||
await nextTick();
|
||||
useEvent("composer:edit", note);
|
||||
});
|
||||
useListen("composer:open", () => {
|
||||
if (tokenData.value) open.value = true;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue