mirror of
https://github.com/versia-pub/frontend.git
synced 2026-03-13 11:39:16 +01:00
chore: ⬆️ Upgrade to the latest Shadcn-Vue version
Some checks failed
Some checks failed
This commit is contained in:
parent
7649ecfb80
commit
092bce0f24
169 changed files with 1860 additions and 1088 deletions
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<Avatar :shape="(shape.value as 'circle' | 'square')">
|
||||
<Avatar :shape="(shape.value as 'circle' | 'square')" :size="size">
|
||||
<AvatarFallback v-if="name">
|
||||
{{ getInitials(name) }}
|
||||
</AvatarFallback>
|
||||
|
|
@ -11,9 +11,10 @@
|
|||
import { SettingIds } from "~/settings";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar";
|
||||
|
||||
const { name } = defineProps<{
|
||||
const { name, size = "base" } = defineProps<{
|
||||
src?: string;
|
||||
name?: string;
|
||||
size?: "base" | "sm" | "lg";
|
||||
}>();
|
||||
|
||||
/**
|
||||
|
|
|
|||
47
components/profiles/profile-badges.vue
Normal file
47
components/profiles/profile-badges.vue
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div
|
||||
class="flex flex-row flex-wrap gap-2 -mx-2"
|
||||
v-if="isDeveloper || account.bot || roles.length > 0"
|
||||
>
|
||||
<ProfileBadge
|
||||
v-if="isDeveloper"
|
||||
:name="m.nice_bad_grizzly_coax()"
|
||||
:description="m.honest_jolly_shell_blend()"
|
||||
:verified="true"
|
||||
/>
|
||||
<ProfileBadge
|
||||
v-if="account.bot"
|
||||
:name="m.merry_red_shrimp_bump()"
|
||||
:description="m.sweet_mad_jannes_create()"
|
||||
/>
|
||||
<ProfileBadge
|
||||
v-for="role in roles"
|
||||
:key="role.id"
|
||||
:name="role.name"
|
||||
:description="role.description"
|
||||
:icon="role.icon"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import ProfileBadge from "./profile-badge.vue";
|
||||
|
||||
const { account } = defineProps<{
|
||||
account: Account;
|
||||
}>();
|
||||
|
||||
const config = useConfig();
|
||||
const roles = account.roles.filter((r) => r.visible);
|
||||
// Get user handle in username@instance format
|
||||
const handle = account.acct.includes("@")
|
||||
? account.acct
|
||||
: `${account.acct}@${
|
||||
identity.value?.instance.domain ?? window.location.host
|
||||
}`;
|
||||
const isDeveloper = config.DEVELOPER_HANDLES.includes(handle);
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
|
@ -1,12 +1,26 @@
|
|||
<template>
|
||||
<CardHeader class="p-0 relative">
|
||||
<CardHeader class="relative w-full">
|
||||
<div class="bg-muted rounded overflow-hidden h-48 md:h-72 w-full">
|
||||
<img :src="header" alt="" class="object-cover w-full h-full" />
|
||||
<img
|
||||
v-if="header"
|
||||
:src="header"
|
||||
alt=""
|
||||
class="object-cover w-full h-full"
|
||||
/>
|
||||
<!-- Shadow overlay at the bottom -->
|
||||
<div class="absolute bottom-0 w-full h-1/3 bg-gradient-to-b from-black/0 to-black/40"></div>
|
||||
<div
|
||||
class="absolute bottom-0 w-full h-1/3 bg-gradient-to-b from-black/0 to-black/40"
|
||||
></div>
|
||||
</div>
|
||||
<div class="absolute bottom-0 translate-y-1/3 left-4 flex flex-row items-start gap-2">
|
||||
<Avatar size="lg" class="border" :src="avatar" :name="displayName" />
|
||||
<div
|
||||
class="absolute bottom-0 translate-y-1/3 left-4 flex flex-row items-start gap-2"
|
||||
>
|
||||
<Avatar
|
||||
size="lg"
|
||||
class="border"
|
||||
:src="avatar"
|
||||
:name="displayName"
|
||||
/>
|
||||
</div>
|
||||
</CardHeader>
|
||||
</template>
|
||||
|
|
@ -20,4 +34,4 @@ defineProps<{
|
|||
avatar: string;
|
||||
displayName: string;
|
||||
}>();
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,27 @@
|
|||
<template>
|
||||
<Card>
|
||||
<ProfileHeader :header="account.header" :avatar="account.avatar" :display-name="account.display_name" />
|
||||
<CardContent class="pt-3 gap-4 flex flex-col">
|
||||
<Card class="*:w-full">
|
||||
<ProfileHeader
|
||||
:header="account.header"
|
||||
:avatar="account.avatar"
|
||||
:display-name="account.display_name"
|
||||
/>
|
||||
<CardContent>
|
||||
<div class="flex flex-row justify-end gap-2">
|
||||
<Button variant="secondary" :disabled="isLoading || relationship?.requested" v-if="!isMe && identity"
|
||||
@click="relationship?.following ? unfollow() : follow()">
|
||||
<Button
|
||||
variant="secondary"
|
||||
:disabled="isLoading || relationship?.requested"
|
||||
v-if="!isMe && identity"
|
||||
@click="relationship?.following ? unfollow() : follow()"
|
||||
>
|
||||
<Loader v-if="isLoading" class="animate-spin" />
|
||||
<span v-else>
|
||||
{{ relationship?.following ? m.brief_upper_otter_cuddle() : relationship?.requested ? m.weak_bright_larva_grasp() : m.lazy_major_loris_grasp() }}
|
||||
{{
|
||||
relationship?.following
|
||||
? m.brief_upper_otter_cuddle()
|
||||
: relationship?.requested
|
||||
? m.weak_bright_larva_grasp()
|
||||
: m.lazy_major_loris_grasp()
|
||||
}}
|
||||
</span>
|
||||
</Button>
|
||||
<ProfileActions :account="account">
|
||||
|
|
@ -22,27 +36,31 @@
|
|||
</CardTitle>
|
||||
<CopyableText :text="account.acct">
|
||||
<span
|
||||
class="font-semibold bg-gradient-to-tr from-pink-700 dark:from-indigo-400 via-purple-700 dark:via-purple-400 to-indigo-700 dark:to-indigo-400 text-transparent bg-clip-text">
|
||||
class="font-semibold bg-gradient-to-tr from-pink-700 dark:from-indigo-400 via-purple-700 dark:via-purple-400 to-indigo-700 dark:to-indigo-400 text-transparent bg-clip-text"
|
||||
>
|
||||
@{{ username }}
|
||||
</span>
|
||||
<span class="text-muted-foreground">{{ instance && "@" }}{{ instance }}</span>
|
||||
<span class="text-muted-foreground"
|
||||
>{{ instance && "@" }}{{ instance }}</span
|
||||
>
|
||||
</CopyableText>
|
||||
</div>
|
||||
<div class="flex flex-row flex-wrap gap-2 -mx-2" v-if="isDeveloper || account.bot || roles.length > 0">
|
||||
<ProfileBadge v-if="isDeveloper" :name="m.nice_bad_grizzly_coax()" :description="m.honest_jolly_shell_blend()"
|
||||
:verified="true" />
|
||||
<ProfileBadge v-if="account.bot" :name="m.merry_red_shrimp_bump()"
|
||||
:description="m.sweet_mad_jannes_create()" />
|
||||
<ProfileBadge v-for="role in roles" :key="role.id" :name="role.name" :description="role.description"
|
||||
:icon="role.icon" />
|
||||
</div>
|
||||
<ProfileBadges :account="account" />
|
||||
<ProfileContent :content="account.note" :emojis="account.emojis" />
|
||||
</CardContent>
|
||||
<CardFooter class="flex-col items-start gap-4">
|
||||
<ProfileStats :creation-date="new Date(account.created_at || 0)" :follower-count="account.followers_count"
|
||||
:following-count="account.following_count" :note-count="account.statuses_count" />
|
||||
<CardFooter>
|
||||
<ProfileStats
|
||||
:creation-date="new Date(account.created_at || 0)"
|
||||
:follower-count="account.followers_count"
|
||||
:following-count="account.following_count"
|
||||
:note-count="account.statuses_count"
|
||||
/>
|
||||
<Separator v-if="account.fields.length > 0" />
|
||||
<ProfileFields v-if="account.fields.length > 0" :fields="account.fields" :emojis="account.emojis" />
|
||||
<ProfileFields
|
||||
v-if="account.fields.length > 0"
|
||||
:fields="account.fields"
|
||||
:emojis="account.emojis"
|
||||
/>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</template>
|
||||
|
|
@ -59,7 +77,7 @@ import * as m from "~/paraglide/messages.js";
|
|||
import { SettingIds } from "~/settings";
|
||||
import { confirmModalService } from "../modals/composable";
|
||||
import ProfileActions from "./profile-actions.vue";
|
||||
import ProfileBadge from "./profile-badge.vue";
|
||||
import ProfileBadges from "./profile-badges.vue";
|
||||
import ProfileContent from "./profile-content.vue";
|
||||
import ProfileFields from "./profile-fields.vue";
|
||||
import ProfileHeader from "./profile-header.vue";
|
||||
|
|
@ -69,16 +87,9 @@ const { account } = defineProps<{
|
|||
account: Account;
|
||||
}>();
|
||||
|
||||
const config = useConfig();
|
||||
const { relationship, isLoading } = useRelationship(client, account.id);
|
||||
const isMe = identity.value?.account.id === account.id;
|
||||
const [username, instance] = account.acct.split("@");
|
||||
const roles = account.roles.filter((r) => r.visible);
|
||||
// Get user handle in username@instance format
|
||||
const handle = account.acct.includes("@")
|
||||
? account.acct
|
||||
: `${account.acct}@${identity.value?.instance.domain ?? window.location.host}`;
|
||||
const isDeveloper = config.DEVELOPER_HANDLES.includes(handle);
|
||||
|
||||
const confirmFollows = useSetting(SettingIds.ConfirmFollow);
|
||||
|
||||
|
|
@ -129,4 +140,4 @@ const unfollow = async () => {
|
|||
relationship.value = data;
|
||||
toast.success(m.misty_level_stingray_expand());
|
||||
};
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,25 @@
|
|||
<template>
|
||||
<div class="relative">
|
||||
<div class="bg-muted rounded overflow-hidden h-32 w-full">
|
||||
<img :src="account.header" alt="" class="object-cover w-full h-full" />
|
||||
<img
|
||||
:src="account.header"
|
||||
alt=""
|
||||
class="object-cover w-full h-full"
|
||||
/>
|
||||
<!-- Shadow overlay at the bottom -->
|
||||
<div class="absolute bottom-0 w-full h-1/3 bg-gradient-to-b from-black/0 to-black/40"></div>
|
||||
<div
|
||||
class="absolute bottom-0 w-full h-1/3 bg-gradient-to-b from-black/0 to-black/40"
|
||||
></div>
|
||||
</div>
|
||||
<div class="absolute bottom-0 left-1/2 translate-y-1/3 -translate-x-1/2 flex flex-row items-start gap-2">
|
||||
<Avatar size="base" class="border" :src="account.avatar" :name="account.display_name" />
|
||||
<div
|
||||
class="absolute bottom-0 left-1/2 translate-y-1/3 -translate-x-1/2 flex flex-row items-start gap-2"
|
||||
>
|
||||
<Avatar
|
||||
size="base"
|
||||
class="border"
|
||||
:src="account.avatar"
|
||||
:name="account.display_name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center items-center mt-8">
|
||||
|
|
@ -15,19 +28,32 @@
|
|||
</span>
|
||||
<CopyableText :text="account.acct" class="text-sm">
|
||||
<span
|
||||
class="font-semibold bg-gradient-to-tr from-pink-700 dark:from-indigo-400 via-purple-700 dark:via-purple-400 to-indigo-700 dark:to-indigo-400 text-transparent bg-clip-text">
|
||||
class="font-semibold bg-gradient-to-tr from-pink-700 dark:from-indigo-400 via-purple-700 dark:via-purple-400 to-indigo-700 dark:to-indigo-400 text-transparent bg-clip-text"
|
||||
>
|
||||
@{{ username }}
|
||||
</span>
|
||||
<span class="text-muted-foreground">{{ instance && "@" }}{{ instance }}</span>
|
||||
<span class="text-muted-foreground"
|
||||
>{{ instance && "@" }}{{ instance }}</span
|
||||
>
|
||||
</CopyableText>
|
||||
</div>
|
||||
<ProfileContent :content="account.note" :emojis="account.emojis" class="mt-4 max-h-72 overflow-y-auto" />
|
||||
<ProfileContent
|
||||
:content="account.note"
|
||||
:emojis="account.emojis"
|
||||
class="mt-4 max-h-72 overflow-y-auto"
|
||||
/>
|
||||
<Separator v-if="account.fields.length > 0" class="mt-4" />
|
||||
<ProfileFields v-if="account.fields.length > 0" :fields="account.fields" :emojis="account.emojis" class="mt-4 max-h-48 overflow-y-auto" />
|
||||
<ProfileFields
|
||||
v-if="account.fields.length > 0"
|
||||
:fields="account.fields"
|
||||
:emojis="account.emojis"
|
||||
class="mt-4 max-h-48 overflow-y-auto"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
import { Separator } from "~/components/ui/separator";
|
||||
import CopyableText from "../notes/copyable-text.vue";
|
||||
import Avatar from "./avatar.vue";
|
||||
import ProfileContent from "./profile-content.vue";
|
||||
|
|
@ -38,4 +64,4 @@ const { account } = defineProps<{
|
|||
}>();
|
||||
|
||||
const [username, instance] = account.acct.split("@");
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
|||
32
components/profiles/tiny-card.vue
Normal file
32
components/profiles/tiny-card.vue
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<template>
|
||||
<Card
|
||||
class="flex-row gap-4 p-2"
|
||||
:class="naked ? 'p-0 bg-transparent ring-0 border-none' : ''"
|
||||
>
|
||||
<Avatar :src="account.avatar" :name="account.display_name" size="sm" />
|
||||
<CardContent class="gap-1">
|
||||
<span
|
||||
class="truncate font-semibold"
|
||||
v-render-emojis="account.emojis"
|
||||
>{{ account.display_name }}</span
|
||||
>
|
||||
<span class="truncate text-xs">
|
||||
@{{ account.username }}@{{ domain }}
|
||||
</span>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
import { Card, CardContent } from "~/components/ui/card";
|
||||
import Avatar from "./avatar.vue";
|
||||
|
||||
const { account, domain, naked } = defineProps<{
|
||||
account: Account;
|
||||
domain: string;
|
||||
naked?: boolean;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue