diff --git a/components/composer/composer.vue b/components/composer/composer.vue index d7d2d13..a1d8d42 100644 --- a/components/composer/composer.vue +++ b/components/composer/composer.vue @@ -47,7 +47,9 @@ - Send! + {{ + respondingType === "edit" ? "Edit!" : "Send!" + }} @@ -68,7 +70,7 @@ const { input: content } = useTextareaAutosize({ }); const { Control_Enter, Command_Enter, Control_Alt } = useMagicKeys(); const respondingTo = ref(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: { diff --git a/components/composer/modal.client.vue b/components/composer/modal.client.vue index 2e307a7..c3f958c 100644 --- a/components/composer/modal.client.vue +++ b/components/composer/modal.client.vue @@ -5,7 +5,7 @@ + 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"> @@ -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"> - - + +
+ +
@@ -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; }); diff --git a/components/social-elements/notes/attachment.vue b/components/social-elements/notes/attachment.vue index aa35a08..8ea7329 100644 --- a/components/social-elements/notes/attachment.vue +++ b/components/social-elements/notes/attachment.vue @@ -10,7 +10,7 @@ -
+

{{ getFilename(attachment.url) }}

{{ @@ -60,7 +60,9 @@ const getFilename = (url: string) => { if (url.includes("/media/proxy")) { // Decode last part of URL as base64url, which is the real URL const realUrl = atob(url.split("/").pop() ?? ""); - return realUrl.substring(realUrl.lastIndexOf("/") + 1); + return decodeURIComponent( + realUrl.substring(realUrl.lastIndexOf("/") + 1), + ); } const path = new URL(url).pathname; return path.substring(path.lastIndexOf("/") + 1); diff --git a/components/social-elements/notes/note.vue b/components/social-elements/notes/note.vue index 5ca530a..02c60ae 100644 --- a/components/social-elements/notes/note.vue +++ b/components/social-elements/notes/note.vue @@ -12,33 +12,35 @@ reblogged

- - - + +
- -