chore: ⬆️ Upgrade to Nuxt 4
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 1s
Deploy to GitHub Pages / build (push) Failing after 1s
Deploy to GitHub Pages / deploy (push) Has been skipped
Docker / build (push) Failing after 1s
Mirror to Codeberg / Mirror (push) Failing after 1s

This commit is contained in:
Jesse Wierzbinski 2025-07-16 07:48:39 +02:00
parent 8debe97f63
commit 7f7cf20311
386 changed files with 2376 additions and 2332 deletions

View file

@ -0,0 +1,80 @@
<template>
<div v-if="relationship?.requested_by !== false" class="flex flex-row items-center gap-3 p-4">
<NuxtLink :href="followerUrl" class="relative size-10">
<Avatar class="size-10 border border-border" :src="follower.avatar" :name="follower.display_name" />
</NuxtLink>
<div class="flex flex-col gap-0.5 justify-center flex-1 text-left leading-tight text-sm">
<span class="truncate font-semibold" v-render-emojis="follower.emojis">{{
follower.display_name
}}</span>
<span class="truncate tracking-tight">
<Address :username="username" :domain="domain" />
</span>
</div>
</div>
<div v-if="loading" class="flex p-2 items-center justify-center h-12">
<Loader class="size-4 animate-spin" />
</div>
<div v-else-if="relationship?.requested_by === false" class="flex p-2 items-center justify-center h-12">
<Check class="size-4" />
</div>
<div v-else class="grid grid-cols-2 p-2 gap-2">
<Button variant="secondary" size="sm" @click="accept" :title="m.slow_these_kestrel_sail()">
<Check />
</Button>
<Button variant="ghost" size="sm" @click="reject" :title="m.weary_steep_yak_embrace()">
<X />
</Button>
</div>
</template>
<script lang="ts" setup>
import type { Account } from "@versia/client/schemas";
import { Check, Loader, X } from "lucide-vue-next";
import { toast } from "vue-sonner";
import type { z } from "zod";
import { Button } from "~/components/ui/button";
import * as m from "~~/paraglide/messages.js";
import Address from "../profiles/address.vue";
import Avatar from "../profiles/avatar.vue";
const { follower } = defineProps<{
follower: z.infer<typeof Account>;
}>();
const loading = ref(true);
const followerUrl = `/@${follower.acct}`;
const [username, domain] = follower.acct.split("@");
const { relationship } = useRelationship(client, follower.id);
// TODO: Add "followed" notification
watch(relationship, () => {
if (relationship.value) {
loading.value = false;
}
});
const accept = async () => {
const id = toast.loading(m.cool_slimy_coyote_affirm());
loading.value = true;
const { data } = await client.value.acceptFollowRequest(follower.id);
toast.dismiss(id);
toast.success(m.busy_awful_mouse_jump());
relationship.value = data;
loading.value = false;
};
const reject = async () => {
const id = toast.loading(m.front_sunny_penguin_flip());
loading.value = true;
const { data } = await client.value.rejectFollowRequest(follower.id);
toast.dismiss(id);
toast.success(m.green_flat_mayfly_trust());
relationship.value = data;
loading.value = false;
};
</script>

View file

@ -0,0 +1,127 @@
<template>
<Card class="*:w-full p-2">
<Collapsible :default-open="true" v-slot="{ open }" class="space-y-1">
<Tooltip>
<TooltipTrigger :as-child="true">
<CardHeader
v-if="notification.account"
class="flex flex-row items-center gap-2 px-2"
>
<component :is="icon" class="size-5 shrink-0" />
<Avatar
class="size-5 border border-card"
:src="notification.account.avatar"
:name="notification.account.display_name"
/>
<span
class="font-semibold text-sm"
v-render-emojis="notification.account.emojis"
>{{ notification.account.display_name }}</span
>
<CollapsibleTrigger :as-child="true">
<Button
variant="ghost"
size="icon"
class="ml-auto [&_svg]:data-[state=open]:-rotate-180"
:title="open ? 'Collapse' : 'Expand'"
>
<ChevronDown class="duration-200" />
</Button>
</CollapsibleTrigger>
</CardHeader>
</TooltipTrigger>
<TooltipContent>
<p>{{ text }}</p>
</TooltipContent>
</Tooltip>
<CollapsibleContent :as-child="true">
<CardContent class="p-0">
<Note
v-if="notification.status"
:note="notification.status"
:small-layout="true"
:hide-actions="true"
/>
<FollowRequest
v-else-if="
notification.type === 'follow_request' &&
notification.account
"
:follower="notification.account"
/>
</CardContent>
</CollapsibleContent>
</Collapsible>
</Card>
</template>
<script lang="ts" setup>
import type { Notification } from "@versia/client/schemas";
import {
AtSign,
ChevronDown,
Heart,
Repeat,
User,
UserPlus,
} from "lucide-vue-next";
import type { z } from "zod";
import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader } from "~/components/ui/card";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "~/components/ui/collapsible";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "~/components/ui/tooltip";
import * as m from "~~/paraglide/messages.js";
import Note from "../notes/note.vue";
import Avatar from "../profiles/avatar.vue";
import FollowRequest from "./follow-request.vue";
const { notification } = defineProps<{
notification: z.infer<typeof Notification>;
}>();
const icon = computed(() => {
switch (notification.type) {
case "mention":
return AtSign;
case "reblog":
return Repeat;
case "follow":
return UserPlus;
case "favourite":
return Heart;
case "follow_request":
return User;
// case "follow_accept":
// return UserCheck;
default:
return null;
}
});
const text = computed(() => {
switch (notification.type) {
case "mention":
return m.fuzzy_orange_tuna_succeed();
case "reblog":
return m.grand_proof_quail_read();
case "follow":
return m.top_steep_scallop_care();
case "favourite":
return m.swift_just_beetle_devour();
case "follow_request":
return m.seemly_short_thrush_bloom();
//case "follow_accept":
// return m.weird_seemly_termite_scold();
default:
return "";
}
});
</script>