mirror of
https://github.com/versia-pub/frontend.git
synced 2025-12-06 16:38:20 +01:00
feat: ✨ Add actions dropdown on user view
This commit is contained in:
parent
8ee6aa83b3
commit
54221ce42f
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<ButtonBase class="enabled:hover:bg-white/20 !rounded-sm !ring-0 !p-4 sm:!p-2 !justify-start">
|
<ButtonBase class="enabled:hover:bg-white/20 text-sm !rounded-sm !ring-0 !py-3 sm:!py-1.5 sm:!px-2 !justify-start">
|
||||||
<Icon :icon="icon" />
|
<Icon :icon="icon" />
|
||||||
<slot />
|
<slot />
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
class="h-6 w-6 text-green-400" aria-hidden="true" />
|
class="h-6 w-6 text-green-400" aria-hidden="true" />
|
||||||
<iconify-icon v-else-if="toast.type === 'error'" icon="tabler:alert-triangle" height="none"
|
<iconify-icon v-else-if="toast.type === 'error'" icon="tabler:alert-triangle" height="none"
|
||||||
class="h-6 w-6 text-red-400" aria-hidden="true" />
|
class="h-6 w-6 text-red-400" aria-hidden="true" />
|
||||||
<iconify-icon v-else-if="toast.type === 'progress'" icon="tabler:loader" height="none"
|
<iconify-icon v-else-if="toast.type === 'loading'" icon="tabler:loader" height="none"
|
||||||
class="h-6 w-6 text-primary-500 animate-spin" aria-hidden="true" />
|
class="h-6 w-6 text-primary-500 animate-spin" aria-hidden="true" />
|
||||||
<iconify-icon v-else-if="toast.type === 'info'" icon="tabler:info-circle" height="none"
|
<iconify-icon v-else-if="toast.type === 'info'" icon="tabler:info-circle" height="none"
|
||||||
class="h-6 w-6 text-blue-500" aria-hidden="true" />
|
class="h-6 w-6 text-blue-500" aria-hidden="true" />
|
||||||
|
|
|
||||||
|
|
@ -64,23 +64,23 @@
|
||||||
<ButtonDropdown @click="copy(JSON.stringify(props.element, null, 4))" icon="tabler:code"
|
<ButtonDropdown @click="copy(JSON.stringify(props.element, null, 4))" icon="tabler:code"
|
||||||
class="w-full">
|
class="w-full">
|
||||||
Copy API
|
Copy API
|
||||||
Response
|
response
|
||||||
</ButtonDropdown>
|
</ButtonDropdown>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item value="">
|
<Menu.Item value="">
|
||||||
<ButtonDropdown @click="copy(url)" icon="tabler:link" class="w-full">
|
<ButtonDropdown @click="copy(url)" icon="tabler:link" class="w-full">
|
||||||
Copy Link
|
Copy link
|
||||||
</ButtonDropdown>
|
</ButtonDropdown>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item value="" v-if="outputtedNote?.url && isRemote">
|
<Menu.Item value="" v-if="outputtedNote?.url && isRemote">
|
||||||
<ButtonDropdown @click="copy(outputtedNote.url)" icon="tabler:link" class="w-full">
|
<ButtonDropdown @click="copy(outputtedNote.url)" icon="tabler:link" class="w-full">
|
||||||
Copy Link (Origin)
|
Copy link (origin)
|
||||||
</ButtonDropdown>
|
</ButtonDropdown>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item value="" v-if="outputtedNote?.url && isRemote">
|
<Menu.Item value="" v-if="outputtedNote?.url && isRemote">
|
||||||
<ButtonDropdown @click="openBlank(outputtedNote.url)" icon="tabler:external-link"
|
<ButtonDropdown @click="openBlank(outputtedNote.url)" icon="tabler:external-link"
|
||||||
class="w-full">
|
class="w-full">
|
||||||
View on Remote
|
View on remote
|
||||||
</ButtonDropdown>
|
</ButtonDropdown>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item value="" v-if="isMyAccount">
|
<Menu.Item value="" v-if="isMyAccount">
|
||||||
|
|
@ -134,7 +134,7 @@
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item value="" v-if="permissions.includes(RolePermission.ManageAccounts)">
|
<Menu.Item value="" v-if="permissions.includes(RolePermission.ManageAccounts)">
|
||||||
<ButtonDropdown icon="tabler:shield-bolt" class="w-full">
|
<ButtonDropdown icon="tabler:shield-bolt" class="w-full">
|
||||||
Open Moderation Panel
|
Open moderation panel
|
||||||
</ButtonDropdown>
|
</ButtonDropdown>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu.ItemGroup>
|
</Menu.ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,25 @@
|
||||||
<Avatar :src="account?.avatar" :alt="`${account?.acct}'s avatar'`"
|
<Avatar :src="account?.avatar" :alt="`${account?.acct}'s avatar'`"
|
||||||
class="h-32 w-32 -mt-[4.5rem] z-10 shrink-0 rounded ring-2 ring-dark-800" />
|
class="h-32 w-32 -mt-[4.5rem] z-10 shrink-0 rounded ring-2 ring-dark-800" />
|
||||||
|
|
||||||
<Button theme="secondary" v-if="account && account?.id === identity?.account?.id">Edit Profile
|
<div class="flex gap-x-2">
|
||||||
</Button>
|
<Button theme="secondary" v-if="account && account?.id === identity?.account?.id">Edit Profile
|
||||||
<Button theme="secondary" :loading="isLoading" @click="follow()"
|
</Button>
|
||||||
v-if="account && account?.id !== identity?.account?.id && relationship && !relationship.following && !relationship.requested">
|
<Button theme="secondary" :loading="isLoading" @click="follow()"
|
||||||
<span>Follow</span>
|
v-if="account && account?.id !== identity?.account?.id && relationship && !relationship.following && !relationship.requested">
|
||||||
</Button>
|
<span>Follow</span>
|
||||||
<Button theme="secondary" :loading="isLoading" @click="unfollow()"
|
</Button>
|
||||||
v-if="account && account?.id !== identity?.account?.id && relationship && relationship.following">
|
<Button theme="secondary" :loading="isLoading" @click="unfollow()"
|
||||||
<span>Unfollow</span>
|
v-if="account && account?.id !== identity?.account?.id && relationship && relationship.following">
|
||||||
</Button>
|
<span>Unfollow</span>
|
||||||
<Button theme="secondary" :loading="isLoading" :disabled="true"
|
</Button>
|
||||||
v-if="account && account?.id !== identity?.account?.id && relationship && !relationship.following && relationship.requested">
|
<Button theme="secondary" :loading="isLoading" :disabled="true"
|
||||||
<span>Requested</span>
|
v-if="account && account?.id !== identity?.account?.id && relationship && !relationship.following && relationship.requested">
|
||||||
</Button>
|
<span>Requested</span>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<AccountActionsDropdown v-if="account && relationship" :account="account"
|
||||||
|
:relationship="relationship" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-2 px-4">
|
<div class="mt-2 px-4">
|
||||||
|
|
@ -102,19 +107,26 @@ import type { Account } from "@lysand-org/client/types";
|
||||||
import Avatar from "~/components/avatars/avatar.vue";
|
import Avatar from "~/components/avatars/avatar.vue";
|
||||||
import Skeleton from "~/components/skeleton/Skeleton.vue";
|
import Skeleton from "~/components/skeleton/Skeleton.vue";
|
||||||
import Button from "~/packages/ui/components/buttons/button.vue";
|
import Button from "~/packages/ui/components/buttons/button.vue";
|
||||||
|
import AccountActionsDropdown from "./AccountActionsDropdown.vue";
|
||||||
import Badge from "./Badge.vue";
|
import Badge from "./Badge.vue";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
account?: Account;
|
account?: Account;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const skeleton = computed(() => !props.account);
|
const account = ref(props.account);
|
||||||
|
|
||||||
|
watch(props, () => {
|
||||||
|
account.value = props.account;
|
||||||
|
});
|
||||||
|
|
||||||
|
const skeleton = computed(() => !account.value);
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const accountId = computed(() => props.account?.id ?? null);
|
const accountId = computed(() => account.value?.id ?? null);
|
||||||
const { relationship, isLoading } = useRelationship(client, accountId);
|
const { relationship, isLoading } = useRelationship(client, accountId);
|
||||||
|
|
||||||
const follow = () => {
|
const follow = () => {
|
||||||
if (!(identity.value && props.account && relationship.value)) {
|
if (!(identity.value && account.value && relationship.value)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
relationship.value = {
|
relationship.value = {
|
||||||
|
|
@ -124,7 +136,7 @@ const follow = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const unfollow = () => {
|
const unfollow = () => {
|
||||||
if (!(identity.value && props.account && relationship.value)) {
|
if (!(identity.value && account.value && relationship.value)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
relationship.value = {
|
relationship.value = {
|
||||||
|
|
@ -137,24 +149,24 @@ const formattedJoin = computed(() =>
|
||||||
Intl.DateTimeFormat("en-US", {
|
Intl.DateTimeFormat("en-US", {
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
}).format(new Date(props.account?.created_at ?? 0)),
|
}).format(new Date(account.value?.created_at ?? 0)),
|
||||||
);
|
);
|
||||||
|
|
||||||
const handle = computed(() => {
|
const handle = computed(() => {
|
||||||
if (!props.account?.acct.includes("@")) {
|
if (!account.value?.acct.includes("@")) {
|
||||||
return `${props.account?.acct}@${new URL(useBaseUrl().value).host}`;
|
return `${account.value?.acct}@${new URL(useBaseUrl().value).host}`;
|
||||||
}
|
}
|
||||||
return props.account?.acct;
|
return account.value?.acct;
|
||||||
});
|
});
|
||||||
const isDeveloper = computed(() =>
|
const isDeveloper = computed(() =>
|
||||||
config.DEVELOPER_HANDLES.includes(handle.value),
|
config.DEVELOPER_HANDLES.includes(handle.value),
|
||||||
);
|
);
|
||||||
const visibleRoles = computed(
|
const visibleRoles = computed(
|
||||||
() => props.account?.roles.filter((r) => r.visible) ?? [],
|
() => account.value?.roles.filter((r) => r.visible) ?? [],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { display_name, fields, note } = useParsedAccount(
|
const { display_name, fields, note } = useParsedAccount(
|
||||||
computed(() => props.account),
|
computed(() => account.value),
|
||||||
settings,
|
settings,
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
164
components/social-elements/users/AccountActionsDropdown.vue
Normal file
164
components/social-elements/users/AccountActionsDropdown.vue
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
<template>
|
||||||
|
<AdaptiveDropdown>
|
||||||
|
<template #button>
|
||||||
|
<Button theme="secondary" class="h-full">
|
||||||
|
<iconify-icon width="unset" icon="tabler:dots" class="size-5 text-gray-200" aria-hidden="true" />
|
||||||
|
<span class="sr-only">Open menu</span>
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #items>
|
||||||
|
<Menu.ItemGroup>
|
||||||
|
<Menu.Item value="">
|
||||||
|
<ButtonDropdown @click="copyUsername" icon="tabler:at" class="w-full">
|
||||||
|
Copy username
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item value="">
|
||||||
|
<ButtonDropdown @click="copyId" icon="tabler:hash" class="w-full">
|
||||||
|
Copy ID
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item value="">
|
||||||
|
<ButtonDropdown @click="copy(JSON.stringify(account, null, 4))" icon="tabler:code" class="w-full">
|
||||||
|
Copy API
|
||||||
|
response
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.ItemGroup>
|
||||||
|
<hr class="border-white/10 rounded" />
|
||||||
|
<Menu.ItemGroup>
|
||||||
|
<Menu.Item value="" v-if="isRemoteUser">
|
||||||
|
<ButtonDropdown @click="viewOnRemote" icon="tabler:external-link" class="w-full">
|
||||||
|
Open remote profile
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item value="">
|
||||||
|
<ButtonDropdown @click="copyUrl" icon="tabler:link" class="w-full">
|
||||||
|
Copy URL
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.ItemGroup>
|
||||||
|
<hr class="border-white/10 rounded" v-if="identity && !isMyAccount" />
|
||||||
|
<Menu.ItemGroup v-if="identity && !isMyAccount">
|
||||||
|
<Menu.Item value="">
|
||||||
|
<ButtonDropdown @click="mute" icon="tabler:volume-off" class="w-full" v-if="!relationship.muting">
|
||||||
|
Mute
|
||||||
|
</ButtonDropdown>
|
||||||
|
<ButtonDropdown @click="unmute" icon="tabler:volume-2" class="w-full" v-else>
|
||||||
|
Unmute
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item value="">
|
||||||
|
<ButtonDropdown @click="block" icon="tabler:shield-x" class="w-full" v-if="!relationship.blocking">
|
||||||
|
Block
|
||||||
|
</ButtonDropdown>
|
||||||
|
<ButtonDropdown @click="unblock" icon="tabler:shield-check" class="w-full" v-else>
|
||||||
|
Unblock
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.ItemGroup>
|
||||||
|
<hr class="border-white/10 rounded" v-if="identity && isRemoteUser" />
|
||||||
|
<Menu.ItemGroup v-if="identity && isRemoteUser">
|
||||||
|
<Menu.Item value="">
|
||||||
|
<ButtonDropdown @click="refetch" icon="tabler:refresh" class="w-full">
|
||||||
|
Update remote user information
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.ItemGroup>
|
||||||
|
<hr class="border-white/10 rounded" v-if="identity" />
|
||||||
|
<Menu.ItemGroup v-if="identity">
|
||||||
|
<Menu.Item value="">
|
||||||
|
<ButtonDropdown @click="useEvent('account:report', account)" icon="tabler:flag" class="w-full"
|
||||||
|
:disabled="!permissions.includes(RolePermission.ManageOwnReports)">
|
||||||
|
Report
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item value="" v-if="permissions.includes(RolePermission.ManageAccounts)">
|
||||||
|
<ButtonDropdown icon="tabler:shield-bolt" class="w-full">
|
||||||
|
Open moderation panel
|
||||||
|
</ButtonDropdown>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.ItemGroup>
|
||||||
|
</template>
|
||||||
|
</AdaptiveDropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { Menu } from "@ark-ui/vue";
|
||||||
|
import {
|
||||||
|
type Account,
|
||||||
|
type Relationship,
|
||||||
|
RolePermission,
|
||||||
|
} from "@lysand-org/client/types";
|
||||||
|
import ButtonDropdown from "~/components/buttons/button-dropdown.vue";
|
||||||
|
import AdaptiveDropdown from "~/components/dropdowns/AdaptiveDropdown.vue";
|
||||||
|
import Button from "~/packages/ui/components/buttons/button.vue";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
account: Account;
|
||||||
|
relationship: Relationship;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const relationship = ref(props.relationship);
|
||||||
|
|
||||||
|
const permissions = usePermissions();
|
||||||
|
const isMyAccount = computed(
|
||||||
|
() => identity.value?.account.id === props.account.id,
|
||||||
|
);
|
||||||
|
const isRemoteUser = computed(() => props.account.acct.includes("@"));
|
||||||
|
const { copy } = useClipboard();
|
||||||
|
|
||||||
|
const copyUsername = () => copy(props.account.acct);
|
||||||
|
const copyId = () => copy(props.account.id);
|
||||||
|
const viewOnRemote = () => window.open(props.account.url, "_blank");
|
||||||
|
const copyUrl = () => copy(props.account.url);
|
||||||
|
|
||||||
|
const mute = async () => {
|
||||||
|
const { data } = await client.value.muteAccount(props.account.id);
|
||||||
|
relationship.value = data;
|
||||||
|
useEvent("notification:new", {
|
||||||
|
type: "success",
|
||||||
|
title: "Account muted",
|
||||||
|
description: `You will no longer see notifications from ${props.account.acct}`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const unmute = async () => {
|
||||||
|
const { data } = await client.value.unmuteAccount(props.account.id);
|
||||||
|
relationship.value = data;
|
||||||
|
useEvent("notification:new", {
|
||||||
|
type: "success",
|
||||||
|
title: "Account unmuted",
|
||||||
|
description: `You will now see notifications from ${props.account.acct}`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const block = async () => {
|
||||||
|
const { data } = await client.value.blockAccount(props.account.id);
|
||||||
|
relationship.value = data;
|
||||||
|
useEvent("notification:new", {
|
||||||
|
type: "success",
|
||||||
|
title: "Account blocked",
|
||||||
|
description: `You will no longer see content from ${props.account.acct}`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const unblock = async () => {
|
||||||
|
const { data } = await client.value.unblockAccount(props.account.id);
|
||||||
|
relationship.value = data;
|
||||||
|
useEvent("notification:new", {
|
||||||
|
type: "success",
|
||||||
|
title: "Account unblocked",
|
||||||
|
description: `You will now see content from ${props.account.acct}`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const refetch = async () => {
|
||||||
|
const { data } = await client.value.refetchAccount(props.account.id);
|
||||||
|
useEvent("account:update", data);
|
||||||
|
useEvent("notification:new", {
|
||||||
|
type: "success",
|
||||||
|
title: "Remote user information updated",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -23,7 +23,6 @@ const {
|
||||||
updateItem,
|
updateItem,
|
||||||
} = useAccountTimeline(client.value, props.id);
|
} = useAccountTimeline(client.value, props.id);
|
||||||
|
|
||||||
// Example of how to handle global events
|
|
||||||
useListen("note:delete", ({ id }) => {
|
useListen("note:delete", ({ id }) => {
|
||||||
removeItem(id);
|
removeItem(id);
|
||||||
});
|
});
|
||||||
|
|
@ -31,4 +30,8 @@ useListen("note:delete", ({ id }) => {
|
||||||
useListen("note:edit", (updatedNote) => {
|
useListen("note:edit", (updatedNote) => {
|
||||||
updateItem(updatedNote);
|
updateItem(updatedNote);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useListen("composer:send", (ee) => {
|
||||||
|
loadPrev();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -20,7 +20,6 @@ const {
|
||||||
updateItem,
|
updateItem,
|
||||||
} = useHomeTimeline(client.value);
|
} = useHomeTimeline(client.value);
|
||||||
|
|
||||||
// Example of how to handle global events
|
|
||||||
useListen("note:delete", ({ id }) => {
|
useListen("note:delete", ({ id }) => {
|
||||||
removeItem(id);
|
removeItem(id);
|
||||||
});
|
});
|
||||||
|
|
@ -28,4 +27,8 @@ useListen("note:delete", ({ id }) => {
|
||||||
useListen("note:edit", (updatedNote) => {
|
useListen("note:edit", (updatedNote) => {
|
||||||
updateItem(updatedNote);
|
updateItem(updatedNote);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useListen("composer:send", (ee) => {
|
||||||
|
loadPrev();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -20,7 +20,6 @@ const {
|
||||||
updateItem,
|
updateItem,
|
||||||
} = useLocalTimeline(client.value);
|
} = useLocalTimeline(client.value);
|
||||||
|
|
||||||
// Example of how to handle global events
|
|
||||||
useListen("note:delete", ({ id }) => {
|
useListen("note:delete", ({ id }) => {
|
||||||
removeItem(id);
|
removeItem(id);
|
||||||
});
|
});
|
||||||
|
|
@ -28,4 +27,8 @@ useListen("note:delete", ({ id }) => {
|
||||||
useListen("note:edit", (updatedNote) => {
|
useListen("note:edit", (updatedNote) => {
|
||||||
updateItem(updatedNote);
|
updateItem(updatedNote);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useListen("composer:send", (ee) => {
|
||||||
|
loadPrev();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -20,7 +20,6 @@ const {
|
||||||
updateItem,
|
updateItem,
|
||||||
} = usePublicTimeline(client.value);
|
} = usePublicTimeline(client.value);
|
||||||
|
|
||||||
// Example of how to handle global events
|
|
||||||
useListen("note:delete", ({ id }) => {
|
useListen("note:delete", ({ id }) => {
|
||||||
removeItem(id);
|
removeItem(id);
|
||||||
});
|
});
|
||||||
|
|
@ -28,4 +27,8 @@ useListen("note:delete", ({ id }) => {
|
||||||
useListen("note:edit", (updatedNote) => {
|
useListen("note:edit", (updatedNote) => {
|
||||||
updateItem(updatedNote);
|
updateItem(updatedNote);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useListen("composer:send", (ee) => {
|
||||||
|
loadPrev();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -87,6 +87,6 @@ onMounted(() => {
|
||||||
.timeline-item-enter-from,
|
.timeline-item-enter-from,
|
||||||
.timeline-item-leave-to {
|
.timeline-item-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateX(30px);
|
scale: 0.99;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { createToaster } from "@ark-ui/vue";
|
import type { createToaster } from "@ark-ui/vue";
|
||||||
import type { Attachment, Status } from "@lysand-org/client/types";
|
import type { Account, Attachment, Status } from "@lysand-org/client/types";
|
||||||
import mitt from "mitt";
|
import mitt from "mitt";
|
||||||
import type { Identity } from "./Identities";
|
import type { Identity } from "./Identities";
|
||||||
|
|
||||||
|
|
@ -24,6 +24,8 @@ type ApplicationEvents = {
|
||||||
"composer:send": Status;
|
"composer:send": Status;
|
||||||
"composer:send-edit": Status;
|
"composer:send-edit": Status;
|
||||||
"composer:close": undefined;
|
"composer:close": undefined;
|
||||||
|
"account:report": Account;
|
||||||
|
"account:update": Account;
|
||||||
"notification:new": NotificationEvent;
|
"notification:new": NotificationEvent;
|
||||||
"attachment:view": Attachment;
|
"attachment:view": Attachment;
|
||||||
"identity:change": Identity;
|
"identity:change": Identity;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ark-ui/vue": "^3.6.0",
|
"@ark-ui/vue": "^3.6.0",
|
||||||
"@lysand-org/client": "^0.2.4",
|
"@lysand-org/client": "^0.2.5",
|
||||||
"@nuxt/fonts": "^0.7.1",
|
"@nuxt/fonts": "^0.7.1",
|
||||||
"@tailwindcss/typography": "^0.5.13",
|
"@tailwindcss/typography": "^0.5.13",
|
||||||
"@vee-validate/nuxt": "^4.13.2",
|
"@vee-validate/nuxt": "^4.13.2",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue