frontend/components/notes/note.vue

102 lines
3.8 KiB
Vue
Raw Normal View History

2024-11-30 02:19:32 +01:00
<template>
<Card as="article" class="relative gap-4 items-stretch">
2025-04-10 14:48:03 +02:00
<CardHeader as="header" class="space-y-2">
<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"
:visibility="noteToUse.visibility"
:created-at="new Date(noteToUse.created_at)"
:small-layout="smallLayout"
class="z-[1]"
/>
<div
v-if="topAvatarBar"
:class="
cn(
'shrink-0 bg-border w-0.5 absolute top-0 h-7 left-[3rem]'
)
"
></div>
<div
v-if="bottomAvatarBar"
:class="
cn(
'shrink-0 bg-border w-0.5 absolute bottom-0 h-[calc(100%-1.5rem)] left-[3rem]'
)
"
></div>
2024-11-30 02:19:32 +01:00
</CardHeader>
<!-- Simply offset by the size of avatar + 0.75rem (the gap) -->
<CardContent
:class="
2025-04-10 14:48:03 +02:00
['space-y-4', contentUnderUsername && (smallLayout ? 'ml-11' : 'ml-[4.25rem]')]
"
>
<Content
:content="noteToUse.content"
:quote="note.quote ?? undefined"
:attachments="noteToUse.media_attachments"
:plain-content="noteToUse.plain_content ?? undefined"
:emojis="noteToUse.emojis"
:sensitive="noteToUse.sensitive"
:content-warning="noteToUse.spoiler_text"
/>
2024-11-30 02:19:32 +01:00
</CardContent>
<CardFooter v-if="!hideActions">
<Actions
:reply-count="noteToUse.replies_count"
:like-count="noteToUse.favourites_count"
:url="url"
:api-note-string="JSON.stringify(noteToUse, null, 4)"
:reblog-count="noteToUse.reblogs_count"
:remote-url="noteToUse.url"
:is-remote="isRemote"
:author-id="noteToUse.account.id"
@edit="useEvent('composer:edit', noteToUse)"
@reply="useEvent('composer:reply', noteToUse)"
@quote="useEvent('composer:quote', noteToUse)"
@delete="useEvent('note:delete', noteToUse)"
:note-id="noteToUse.id"
:liked="noteToUse.favourited ?? false"
:reblogged="noteToUse.reblogged ?? false"
/>
</CardFooter>
2024-11-30 02:19:32 +01:00
</Card>
</template>
<script setup lang="ts">
import { cn } from "@/lib/utils";
2024-11-30 02:19:32 +01:00
import type { Status } from "@versia/client/types";
2025-03-27 22:20:04 +01:00
import { Card, CardContent, CardFooter, CardHeader } from "../ui/card";
import Actions from "./actions.vue";
2024-11-30 02:19:32 +01:00
import Content from "./content.vue";
import Header from "./header.vue";
import ReblogHeader from "./reblog-header.vue";
2024-11-30 02:19:32 +01:00
const { note } = defineProps<{
note: Status;
2024-11-30 16:39:02 +01:00
hideActions?: boolean;
smallLayout?: boolean;
contentUnderUsername?: boolean;
topAvatarBar?: boolean;
bottomAvatarBar?: 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
const noteToUse = computed(() => (note.reblog ? note.reblog : note));
const url = wrapUrl(`/@${noteToUse.value.account.acct}/${noteToUse.value.id}`);
const accountUrl = wrapUrl(`/@${noteToUse.value.account.acct}`);
const reblogAccountUrl = wrapUrl(`/@${note.account.acct}`);
const isRemote = noteToUse.value.account.acct.includes("@");
</script>