2024-11-30 02:19:32 +01:00
|
|
|
<template>
|
2025-12-09 23:26:59 +01:00
|
|
|
<Card
|
|
|
|
|
as="article"
|
|
|
|
|
:class="['relative gap-1.5 items-stretch bg-background', replyBar && 'pl-6']"
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
v-if="replyBar"
|
|
|
|
|
class="absolute left-0 top-0 bottom-0 w-2 bg-border rounded-tl-md"
|
|
|
|
|
/>
|
2025-04-10 14:48:03 +02:00
|
|
|
<CardHeader as="header" class="space-y-2">
|
2025-03-28 01:16:24 +01:00
|
|
|
<ReblogHeader
|
|
|
|
|
v-if="note.reblog"
|
|
|
|
|
:avatar="note.account.avatar"
|
|
|
|
|
:display-name="note.account.display_name"
|
|
|
|
|
:url="reblogAccountUrl"
|
|
|
|
|
:emojis="note.account.emojis"
|
|
|
|
|
/>
|
|
|
|
|
<Header
|
|
|
|
|
:author="noteToUse.account"
|
|
|
|
|
:author-url="accountUrl"
|
|
|
|
|
:corner-avatar="note.reblog ? note.account.avatar : undefined"
|
|
|
|
|
:note-url="url"
|
2025-12-09 23:26:59 +01:00
|
|
|
:is-remote="isRemote"
|
|
|
|
|
:remote-url="noteToUse.url ?? undefined"
|
|
|
|
|
:api-note-string="JSON.stringify(noteToUse, null, 4)"
|
2025-03-28 01:16:24 +01:00
|
|
|
:visibility="noteToUse.visibility"
|
|
|
|
|
:created-at="new Date(noteToUse.created_at)"
|
2025-12-09 23:26:59 +01:00
|
|
|
@edit="useEvent('composer:edit', noteToUse)"
|
|
|
|
|
@delete="useEvent('note:delete', noteToUse)"
|
|
|
|
|
:note-id="noteToUse.id"
|
2025-11-21 12:16:00 +01:00
|
|
|
class="z-1"
|
2025-03-28 01:16:24 +01:00
|
|
|
/>
|
2024-11-30 02:19:32 +01:00
|
|
|
</CardHeader>
|
2025-12-09 23:26:59 +01:00
|
|
|
<CardContent class="space-y-2">
|
2025-03-28 01:16:24 +01:00
|
|
|
<Content
|
|
|
|
|
:content="noteToUse.content"
|
|
|
|
|
:quote="note.quote ?? undefined"
|
|
|
|
|
:attachments="noteToUse.media_attachments"
|
2025-05-26 11:19:15 +02:00
|
|
|
:plain-content="noteToUse.text ?? undefined"
|
2025-03-28 01:16:24 +01:00
|
|
|
:emojis="noteToUse.emojis"
|
|
|
|
|
:sensitive="noteToUse.sensitive"
|
|
|
|
|
:content-warning="noteToUse.spoiler_text"
|
|
|
|
|
/>
|
2025-12-09 22:32:22 +01:00
|
|
|
<Reactions
|
|
|
|
|
v-if="noteToUse.reactions && noteToUse.reactions.length > 0"
|
|
|
|
|
:reactions="noteToUse.reactions"
|
|
|
|
|
:emojis="noteToUse.emojis"
|
|
|
|
|
:status-id="noteToUse.id"
|
|
|
|
|
/>
|
2024-11-30 02:19:32 +01:00
|
|
|
</CardContent>
|
2025-03-28 01:16:24 +01:00
|
|
|
<CardFooter v-if="!hideActions">
|
|
|
|
|
<Actions
|
|
|
|
|
:reply-count="noteToUse.replies_count"
|
|
|
|
|
:like-count="noteToUse.favourites_count"
|
|
|
|
|
:url="url"
|
2025-05-01 19:34:36 +02:00
|
|
|
:api-note-string="JSON.stringify(noteToUse, null, 4)"
|
2025-03-28 01:16:24 +01:00
|
|
|
:reblog-count="noteToUse.reblogs_count"
|
2025-05-26 11:19:15 +02:00
|
|
|
:remote-url="noteToUse.url ?? undefined"
|
2025-03-28 01:16:24 +01:00
|
|
|
:is-remote="isRemote"
|
|
|
|
|
:author-id="noteToUse.account.id"
|
2025-05-01 19:34:36 +02:00
|
|
|
@edit="useEvent('composer:edit', noteToUse)"
|
|
|
|
|
@reply="useEvent('composer:reply', noteToUse)"
|
|
|
|
|
@quote="useEvent('composer:quote', noteToUse)"
|
|
|
|
|
@delete="useEvent('note:delete', noteToUse)"
|
2025-03-28 01:16:24 +01:00
|
|
|
:note-id="noteToUse.id"
|
|
|
|
|
:liked="noteToUse.favourited ?? false"
|
|
|
|
|
:reblogged="noteToUse.reblogged ?? false"
|
|
|
|
|
/>
|
2024-11-30 16:21:16 +01:00
|
|
|
</CardFooter>
|
2024-11-30 02:19:32 +01:00
|
|
|
</Card>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2025-05-26 11:19:15 +02:00
|
|
|
import type { Status } from "@versia/client/schemas";
|
|
|
|
|
import type { z } from "zod";
|
2025-03-27 22:20:04 +01:00
|
|
|
import { Card, CardContent, CardFooter, CardHeader } from "../ui/card";
|
2024-11-30 16:21:16 +01:00
|
|
|
import Actions from "./actions.vue";
|
2024-11-30 02:19:32 +01:00
|
|
|
import Content from "./content.vue";
|
|
|
|
|
import Header from "./header.vue";
|
2025-05-26 19:21:13 +02:00
|
|
|
import Reactions from "./reactions/index.vue";
|
2024-11-30 16:21:16 +01:00
|
|
|
import ReblogHeader from "./reblog-header.vue";
|
2024-11-30 02:19:32 +01:00
|
|
|
|
2025-05-26 11:19:15 +02:00
|
|
|
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
|
|
|
|
2025-12-09 23:26:59 +01:00
|
|
|
const {
|
|
|
|
|
note,
|
|
|
|
|
hideActions,
|
|
|
|
|
replyBar = false,
|
|
|
|
|
} = defineProps<{
|
2025-05-26 11:19:15 +02:00
|
|
|
note: PartialBy<z.infer<typeof Status>, "reblog" | "quote">;
|
2024-11-30 16:39:02 +01:00
|
|
|
hideActions?: boolean;
|
2025-12-09 23:26:59 +01:00
|
|
|
replyBar?: boolean;
|
2024-11-30 02:19:32 +01:00
|
|
|
}>();
|
|
|
|
|
|
2024-11-30 16:39:02 +01:00
|
|
|
// Notes can be reblogs, in which case the actual thing to render is inside the reblog property
|
2025-05-26 11:19:15 +02:00
|
|
|
const noteToUse = computed(() =>
|
|
|
|
|
note.reblog
|
|
|
|
|
? (note.reblog as z.infer<typeof Status>)
|
|
|
|
|
: (note as z.infer<typeof Status>),
|
|
|
|
|
);
|
2024-11-30 16:21:16 +01:00
|
|
|
|
2024-12-01 18:54:17 +01:00
|
|
|
const url = wrapUrl(`/@${noteToUse.value.account.acct}/${noteToUse.value.id}`);
|
|
|
|
|
const accountUrl = wrapUrl(`/@${noteToUse.value.account.acct}`);
|
2024-11-30 18:21:40 +01:00
|
|
|
const reblogAccountUrl = wrapUrl(`/@${note.account.acct}`);
|
2024-12-01 18:54:17 +01:00
|
|
|
const isRemote = noteToUse.value.account.acct.includes("@");
|
2024-11-30 16:21:16 +01:00
|
|
|
</script>
|