mirror of
https://github.com/versia-pub/frontend.git
synced 2025-12-06 08:28:20 +01:00
chore: ⬆️ Upgrade to new @versia/client
This commit is contained in:
parent
0a157d06f6
commit
f807b05784
10
bun.lock
10
bun.lock
|
|
@ -24,7 +24,7 @@
|
|||
"@tiptap/suggestion": "^2.12.0",
|
||||
"@tiptap/vue-3": "^2.12.0",
|
||||
"@vee-validate/zod": "^4.15.0",
|
||||
"@versia/client": "0.1.5",
|
||||
"@versia/client": "0.2.0-alpha.2",
|
||||
"@videojs-player/vue": "^1.0.0",
|
||||
"@vite-pwa/nuxt": "^1.0.1",
|
||||
"@vueuse/core": "^13.2.0",
|
||||
|
|
@ -270,7 +270,7 @@
|
|||
|
||||
"@babel/types": ["@babel/types@7.27.1", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q=="],
|
||||
|
||||
"@badgateway/oauth2-client": ["@badgateway/oauth2-client@2.4.2", "", {}, "sha512-70Fmzlmn8EfCjjssls8N6E94quBUWnLhu4inPZU2pkwpc6ZvbErkLRvtkYl81KFCvVcuVC0X10QPZVNwjXo2KA=="],
|
||||
"@badgateway/oauth2-client": ["@badgateway/oauth2-client@3.2.0", "", {}, "sha512-EHsoV6oLHot7HeYkIoSxCZApNgBjwNo1OTV9kXIDnmijGAshlVkJreVAAtexFn+sfDKPE0JW5SCPYJV1y4IoMg=="],
|
||||
|
||||
"@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="],
|
||||
|
||||
|
|
@ -780,7 +780,7 @@
|
|||
|
||||
"@vercel/nft": ["@vercel/nft@0.29.3", "", { "dependencies": { "@mapbox/node-pre-gyp": "^2.0.0", "@rollup/pluginutils": "^5.1.3", "acorn": "^8.6.0", "acorn-import-attributes": "^1.9.5", "async-sema": "^3.1.1", "bindings": "^1.4.0", "estree-walker": "2.0.2", "glob": "^10.4.5", "graceful-fs": "^4.2.9", "node-gyp-build": "^4.2.2", "picomatch": "^4.0.2", "resolve-from": "^5.0.0" }, "bin": { "nft": "out/cli.js" } }, "sha512-aVV0E6vJpuvImiMwU1/5QKkw2N96BRFE7mBYGS7FhXUoS6V7SarQ+8tuj33o7ofECz8JtHpmQ9JW+oVzOoB7MA=="],
|
||||
|
||||
"@versia/client": ["@versia/client@0.1.5", "", { "dependencies": { "@badgateway/oauth2-client": "^2.4.2", "zod": "^3.24.1" } }, "sha512-POD2/IT98EZZ32kWEPc3XUY2zApX94tuBftNWIMyoT04Sp7CPuvv1TT2fxM2kmgrC6kgbh4I6yirPpzVY+FpSA=="],
|
||||
"@versia/client": ["@versia/client@0.2.0-alpha.2", "", { "dependencies": { "@badgateway/oauth2-client": "^3.0.0", "iso-639-1": "^3.1.5", "magic-regexp": "^0.10.0", "zod": "^3.24.2", "zod-openapi": "^4.2.4" } }, "sha512-/x1Z2tyJsfckCOLX8K8XDVs3rd3vX0wfCz20IMTc9uaGRkDTcL7MYzz20WCgOEW/WmnwL3iVf/jVgJm0NzoF4Q=="],
|
||||
|
||||
"@videojs-player/vue": ["@videojs-player/vue@1.0.0", "", { "peerDependencies": { "@types/video.js": "7.x", "video.js": "7.x", "vue": "3.x" } }, "sha512-WonTezRfKu3fYdQLt/ta+nuKH6gMZUv8l40Jke/j4Lae7IqeO/+lLAmBnh3ni88bwR+vkFXIlZ2Ci7VKInIYJg=="],
|
||||
|
||||
|
|
@ -1516,6 +1516,8 @@
|
|||
|
||||
"isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="],
|
||||
|
||||
"iso-639-1": ["iso-639-1@3.1.5", "", {}, "sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA=="],
|
||||
|
||||
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
|
||||
|
||||
"jake": ["jake@10.9.2", "", { "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", "filelist": "^1.0.4", "minimatch": "^3.1.2" }, "bin": { "jake": "bin/cli.js" } }, "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA=="],
|
||||
|
|
@ -2444,6 +2446,8 @@
|
|||
|
||||
"zod": ["zod@3.25.23", "", {}, "sha512-Od2bdMosahjSrSgJtakrwjMDb1zM1A3VIHCPGveZt/3/wlrTWBya2lmEh2OYe4OIu8mPTmmr0gnLHIWQXdtWBg=="],
|
||||
|
||||
"zod-openapi": ["zod-openapi@4.2.4", "", { "peerDependencies": { "zod": "^3.21.4" } }, "sha512-tsrQpbpqFCXqVXUzi3TPwFhuMtLN3oNZobOtYnK6/5VkXsNdnIgyNr4r8no4wmYluaxzN3F7iS+8xCW8BmMQ8g=="],
|
||||
|
||||
"@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||
|
||||
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import type { ResponseError } from "@versia/client";
|
||||
import type { Status, StatusSource } from "@versia/client/types";
|
||||
import type { Attachment, Status, StatusSource } from "@versia/client/schemas";
|
||||
import {
|
||||
AtSign,
|
||||
FilePlus2,
|
||||
|
|
@ -151,6 +151,7 @@ import {
|
|||
TriangleAlert,
|
||||
} from "lucide-vue-next";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
import Note from "~/components/notes/note.vue";
|
||||
import {
|
||||
Select,
|
||||
|
|
@ -182,8 +183,8 @@ watch([Control_Enter, Command_Enter], () => {
|
|||
const { relation } = defineProps<{
|
||||
relation?: {
|
||||
type: "reply" | "quote" | "edit";
|
||||
note: Status;
|
||||
source?: StatusSource;
|
||||
note: z.infer<typeof Status>;
|
||||
source?: z.infer<typeof StatusSource>;
|
||||
};
|
||||
}>();
|
||||
|
||||
|
|
@ -279,7 +280,7 @@ const submit = async () => {
|
|||
visibility: state.visibility,
|
||||
});
|
||||
|
||||
useEvent("composer:send", data as Status);
|
||||
useEvent("composer:send", data as z.infer<typeof Status>);
|
||||
play("publish");
|
||||
useEvent("composer:close");
|
||||
}
|
||||
|
|
@ -317,7 +318,9 @@ const uploadFiles = (files: File[]) => {
|
|||
return;
|
||||
}
|
||||
|
||||
state.files[index].apiId = media.data.id;
|
||||
state.files[index].apiId = (
|
||||
media.data as z.infer<typeof Attachment>
|
||||
).id;
|
||||
state.files[index].uploading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ import {
|
|||
DialogDescription,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import type { Status, StatusSource } from "@versia/client/types";
|
||||
import type { Status, StatusSource } from "@versia/client/schemas";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import Composer from "./composer.vue";
|
||||
|
||||
|
|
@ -58,8 +59,8 @@ const open = ref(false);
|
|||
const relation = ref(
|
||||
null as {
|
||||
type: "reply" | "quote" | "edit";
|
||||
note: Status;
|
||||
source?: StatusSource;
|
||||
note: z.infer<typeof Status>;
|
||||
source?: z.infer<typeof StatusSource>;
|
||||
} | null,
|
||||
);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
import { VueRenderer } from "@tiptap/vue-3";
|
||||
import tippy, { type Instance } from "tippy.js";
|
||||
|
||||
import type { MentionNodeAttrs } from "@tiptap/extension-mention";
|
||||
import type { SuggestionOptions } from "@tiptap/suggestion";
|
||||
import type { Account } from "@versia/client/types";
|
||||
import { VueRenderer } from "@tiptap/vue-3";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import { go } from "fuzzysort";
|
||||
import tippy, { type Instance } from "tippy.js";
|
||||
import type { z } from "zod";
|
||||
import MentionList from "./mentions-list.vue";
|
||||
|
||||
export type UserData = {
|
||||
key: string;
|
||||
value: Account;
|
||||
value: z.infer<typeof Account>;
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import { Ellipsis, Heart, Quote, Repeat, Reply } from "lucide-vue-next";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { getLocale } from "~/paraglide/runtime";
|
||||
import { confirmModalService } from "../modals/composable";
|
||||
|
|
@ -33,7 +35,7 @@ const { noteId } = defineProps<{
|
|||
noteId: string;
|
||||
isRemote: boolean;
|
||||
url: string;
|
||||
remoteUrl: string;
|
||||
remoteUrl?: string;
|
||||
authorId: string;
|
||||
liked: boolean;
|
||||
reblogged: boolean;
|
||||
|
|
@ -108,7 +110,10 @@ const reblog = async () => {
|
|||
const { data } = await client.value.reblogStatus(noteId);
|
||||
toast.dismiss(id);
|
||||
toast.success(m.weird_moving_hawk_lift());
|
||||
useEvent("note:edit", data.reblog || data);
|
||||
useEvent(
|
||||
"note:edit",
|
||||
(data.reblog as z.infer<typeof Status> | null) || data,
|
||||
);
|
||||
};
|
||||
|
||||
const unreblog = async () => {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment } from "@versia/client/types";
|
||||
import type { Attachment } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import AudioAttachment from "./attachments/audio.vue";
|
||||
import FileAttachment from "./attachments/file.vue";
|
||||
import ImageAttachment from "./attachments/image.vue";
|
||||
import VideoAttachment from "./attachments/video.vue";
|
||||
|
||||
defineProps<{
|
||||
attachment: Attachment;
|
||||
attachment: z.infer<typeof Attachment>;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment as AttachmentType } from "@versia/client/types";
|
||||
import type { Attachment as AttachmentType } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import Attachment from "./attachment.vue";
|
||||
|
||||
defineProps<{
|
||||
attachments: AttachmentType[];
|
||||
attachments: z.infer<typeof AttachmentType>[];
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment } from "@versia/client/types";
|
||||
import type { Attachment } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import Base from "./base.vue";
|
||||
|
||||
const { attachment } = defineProps<{
|
||||
attachment: Attachment;
|
||||
attachment: z.infer<typeof Attachment>;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment } from "@versia/client/types";
|
||||
import type { Attachment } from "@versia/client/schemas";
|
||||
import { Captions, Download, File, X } from "lucide-vue-next";
|
||||
import type { z } from "zod";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Card } from "~/components/ui/card";
|
||||
import {
|
||||
|
|
@ -67,7 +68,7 @@ import {
|
|||
} from "~/components/ui/popover";
|
||||
|
||||
const { attachment, lightbox = false } = defineProps<{
|
||||
attachment: Attachment;
|
||||
attachment: z.infer<typeof Attachment>;
|
||||
lightbox?: boolean;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment } from "@versia/client/types";
|
||||
import type { Attachment } from "@versia/client/schemas";
|
||||
import { File } from "lucide-vue-next";
|
||||
import type { z } from "zod";
|
||||
import Base from "./base.vue";
|
||||
|
||||
const { attachment } = defineProps<{
|
||||
attachment: Attachment;
|
||||
attachment: z.infer<typeof Attachment>;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment } from "@versia/client/types";
|
||||
import type { Attachment } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import Base from "./base.vue";
|
||||
|
||||
const { attachment } = defineProps<{
|
||||
attachment: Attachment;
|
||||
attachment: z.infer<typeof Attachment>;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment } from "@versia/client/types";
|
||||
import type { Attachment } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import Base from "./base.vue";
|
||||
|
||||
const { attachment } = defineProps<{
|
||||
attachment: Attachment;
|
||||
attachment: z.infer<typeof Attachment>;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment, Emoji, Status } from "@versia/client/types";
|
||||
import type { Attachment, CustomEmoji, Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import Attachments from "./attachments.vue";
|
||||
import ContentWarning from "./content-warning.vue";
|
||||
import Note from "./note.vue";
|
||||
|
|
@ -23,9 +24,9 @@ import Prose from "./prose.vue";
|
|||
const { content, plainContent, sensitive, contentWarning } = defineProps<{
|
||||
plainContent?: string;
|
||||
content: string;
|
||||
quote?: NonNullable<Status["quote"]>;
|
||||
emojis: Emoji[];
|
||||
attachments: Attachment[];
|
||||
quote?: NonNullable<z.infer<typeof Status.shape.quote>>;
|
||||
emojis: z.infer<typeof CustomEmoji>[];
|
||||
attachments: z.infer<typeof Attachment>[];
|
||||
sensitive: boolean;
|
||||
contentWarning?: string;
|
||||
}>();
|
||||
|
|
|
|||
|
|
@ -44,12 +44,13 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { Account, StatusVisibility } from "@versia/client/types";
|
||||
import type { Account, Status } from "@versia/client/schemas";
|
||||
import type {
|
||||
UseTimeAgoMessages,
|
||||
UseTimeAgoUnitNamesDefault,
|
||||
} from "@vueuse/core";
|
||||
import { AtSign, Globe, Lock, LockOpen } from "lucide-vue-next";
|
||||
import type { z } from "zod";
|
||||
import { getLocale } from "~/paraglide/runtime";
|
||||
import Avatar from "../profiles/avatar.vue";
|
||||
import SmallCard from "../profiles/small-card.vue";
|
||||
|
|
@ -61,11 +62,11 @@ import {
|
|||
|
||||
const { createdAt, noteUrl, author, authorUrl } = defineProps<{
|
||||
cornerAvatar?: string;
|
||||
visibility: StatusVisibility;
|
||||
visibility: z.infer<typeof Status.shape.visibility>;
|
||||
noteUrl: string;
|
||||
createdAt: Date;
|
||||
smallLayout?: boolean;
|
||||
author: Account;
|
||||
author: z.infer<typeof Account>;
|
||||
authorUrl: string;
|
||||
}>();
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const { authorId, noteId } = defineProps<{
|
|||
apiNoteString: string;
|
||||
isRemote: boolean;
|
||||
url: string;
|
||||
remoteUrl: string;
|
||||
remoteUrl?: string;
|
||||
authorId: string;
|
||||
noteId: string;
|
||||
}>();
|
||||
|
|
@ -102,7 +102,7 @@ const _delete = async () => {
|
|||
<Link />
|
||||
{{ m.ago_new_pelican_drip() }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem as="button" v-if="isRemote" @click="copyText(remoteUrl)">
|
||||
<DropdownMenuItem as="button" v-if="isRemote && remoteUrl" @click="copyText(remoteUrl)">
|
||||
<Link />
|
||||
{{ m.solid_witty_zebra_walk() }}
|
||||
</DropdownMenuItem>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
:content="noteToUse.content"
|
||||
:quote="note.quote ?? undefined"
|
||||
:attachments="noteToUse.media_attachments"
|
||||
:plain-content="noteToUse.plain_content ?? undefined"
|
||||
:plain-content="noteToUse.text ?? undefined"
|
||||
:emojis="noteToUse.emojis"
|
||||
:sensitive="noteToUse.sensitive"
|
||||
:content-warning="noteToUse.spoiler_text"
|
||||
|
|
@ -58,7 +58,7 @@
|
|||
:url="url"
|
||||
:api-note-string="JSON.stringify(noteToUse, null, 4)"
|
||||
:reblog-count="noteToUse.reblogs_count"
|
||||
:remote-url="noteToUse.url"
|
||||
:remote-url="noteToUse.url ?? undefined"
|
||||
:is-remote="isRemote"
|
||||
:author-id="noteToUse.account.id"
|
||||
@edit="useEvent('composer:edit', noteToUse)"
|
||||
|
|
@ -75,15 +75,18 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { Card, CardContent, CardFooter, CardHeader } from "../ui/card";
|
||||
import Actions from "./actions.vue";
|
||||
import Content from "./content.vue";
|
||||
import Header from "./header.vue";
|
||||
import ReblogHeader from "./reblog-header.vue";
|
||||
|
||||
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
||||
|
||||
const { note } = defineProps<{
|
||||
note: Status;
|
||||
note: PartialBy<z.infer<typeof Status>, "reblog" | "quote">;
|
||||
hideActions?: boolean;
|
||||
smallLayout?: boolean;
|
||||
contentUnderUsername?: boolean;
|
||||
|
|
@ -92,7 +95,11 @@ const { note } = defineProps<{
|
|||
}>();
|
||||
|
||||
// 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 noteToUse = computed(() =>
|
||||
note.reblog
|
||||
? (note.reblog as z.infer<typeof Status>)
|
||||
: (note as z.infer<typeof Status>),
|
||||
);
|
||||
|
||||
const url = wrapUrl(`/@${noteToUse.value.account.acct}/${noteToUse.value.id}`);
|
||||
const accountUrl = wrapUrl(`/@${noteToUse.value.account.acct}`);
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Emoji } from "@versia/client/types";
|
||||
import type { CustomEmoji } from "@versia/client/schemas";
|
||||
import { Repeat } from "lucide-vue-next";
|
||||
import type { z } from "zod";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import Avatar from "../profiles/avatar.vue";
|
||||
import { Card } from "../ui/card";
|
||||
|
|
@ -19,7 +20,7 @@ import { Card } from "../ui/card";
|
|||
const { url } = defineProps<{
|
||||
avatar: string;
|
||||
displayName: string;
|
||||
emojis: Emoji[];
|
||||
emojis: z.infer<typeof CustomEmoji>[];
|
||||
url: string;
|
||||
}>();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import Note from "./note.vue";
|
||||
|
||||
const { note } = defineProps<{
|
||||
note: Status;
|
||||
note: z.infer<typeof Status>;
|
||||
}>();
|
||||
|
||||
const parent = useNote(client, note.in_reply_to_id);
|
||||
|
|
|
|||
|
|
@ -35,16 +35,17 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
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 CopyableText from "~/components/notes/copyable-text.vue";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import Avatar from "../profiles/avatar.vue";
|
||||
|
||||
const { follower } = defineProps<{
|
||||
follower: Account;
|
||||
follower: z.infer<typeof Account>;
|
||||
}>();
|
||||
|
||||
const loading = ref(true);
|
||||
|
|
|
|||
|
|
@ -56,16 +56,16 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Notification } from "@versia/client/types";
|
||||
import type { Notification } from "@versia/client/schemas";
|
||||
import {
|
||||
AtSign,
|
||||
ChevronDown,
|
||||
Heart,
|
||||
Repeat,
|
||||
User,
|
||||
UserCheck,
|
||||
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 {
|
||||
|
|
@ -84,7 +84,7 @@ import Avatar from "../profiles/avatar.vue";
|
|||
import FollowRequest from "./follow-request.vue";
|
||||
|
||||
const { notification } = defineProps<{
|
||||
notification: Notification;
|
||||
notification: z.infer<typeof Notification>;
|
||||
}>();
|
||||
|
||||
const icon = computed(() => {
|
||||
|
|
@ -99,8 +99,8 @@ const icon = computed(() => {
|
|||
return Heart;
|
||||
case "follow_request":
|
||||
return User;
|
||||
case "follow_accept":
|
||||
return UserCheck;
|
||||
// case "follow_accept":
|
||||
// return UserCheck;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
@ -118,8 +118,8 @@ const text = computed(() => {
|
|||
return m.swift_just_beetle_devour();
|
||||
case "follow_request":
|
||||
return m.seemly_short_thrush_bloom();
|
||||
case "follow_accept":
|
||||
return m.weird_seemly_termite_scold();
|
||||
//case "follow_accept":
|
||||
// return m.weird_seemly_termite_scold();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { toTypedSchema } from "@vee-validate/zod";
|
||||
import type { Instance } from "@versia/client";
|
||||
import type { Instance } from "@versia/client/schemas";
|
||||
import { Loader } from "lucide-vue-next";
|
||||
import { useForm } from "vee-validate";
|
||||
import * as z from "zod";
|
||||
|
|
@ -16,7 +16,7 @@ import { Input } from "~/components/ui/input";
|
|||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
const { instance } = defineProps<{
|
||||
instance: Instance;
|
||||
instance: z.infer<typeof Instance>;
|
||||
}>();
|
||||
|
||||
const isLoading = ref(false);
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { type Emoji, RolePermission } from "@versia/client/types";
|
||||
import { type CustomEmoji, RolePermission } from "@versia/client/schemas";
|
||||
import { Delete } from "lucide-vue-next";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
import { confirmModalService } from "~/components/modals/composable";
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
|
@ -26,7 +27,7 @@ import {
|
|||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
const { emojis } = defineProps<{
|
||||
emojis: Emoji[];
|
||||
emojis: z.infer<typeof CustomEmoji>[];
|
||||
}>();
|
||||
|
||||
const permissions = usePermissions();
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { type Emoji, RolePermission } from "@versia/client/types";
|
||||
import { type CustomEmoji, RolePermission } from "@versia/client/schemas";
|
||||
import { Delete, MoreHorizontal, TextCursorInput } from "lucide-vue-next";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
import { confirmModalService } from "~/components/modals/composable";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import {
|
||||
|
|
@ -38,7 +39,7 @@ import {
|
|||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
const { emoji } = defineProps<{
|
||||
emoji: Emoji;
|
||||
emoji: z.infer<typeof CustomEmoji>;
|
||||
}>();
|
||||
|
||||
const permissions = usePermissions();
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { type Emoji, RolePermission } from "@versia/client/types";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { RolePermission } from "@versia/client/schemas";
|
||||
import Table from "./table.vue";
|
||||
|
||||
const permissions = usePermissions();
|
||||
|
|
@ -16,36 +15,5 @@ const canUpload = computed(
|
|||
permissions.value.includes(RolePermission.ManageEmojis),
|
||||
);
|
||||
|
||||
const emojis = computed(
|
||||
() =>
|
||||
identity.value?.emojis?.filter((emoji) =>
|
||||
emoji.shortcode.toLowerCase().includes(search.value.toLowerCase()),
|
||||
) ?? [],
|
||||
);
|
||||
|
||||
const search = ref("");
|
||||
|
||||
/**
|
||||
* Sort emojis by category
|
||||
*/
|
||||
const categories = computed(() => {
|
||||
const categories = new Map<string, Emoji[]>();
|
||||
for (const emoji of emojis.value) {
|
||||
if (!emoji.category) {
|
||||
if (!categories.has(m.lucky_ago_rat_pinch())) {
|
||||
categories.set(m.lucky_ago_rat_pinch(), []);
|
||||
}
|
||||
|
||||
categories.get(m.lucky_ago_rat_pinch())?.push(emoji);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!categories.has(emoji.category)) {
|
||||
categories.set(emoji.category, []);
|
||||
}
|
||||
|
||||
categories.get(emoji.category)?.push(emoji);
|
||||
}
|
||||
return categories;
|
||||
});
|
||||
const emojis = computed(() => identity.value?.emojis ?? []);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import {
|
|||
getSortedRowModel,
|
||||
useVueTable,
|
||||
} from "@tanstack/vue-table";
|
||||
import type { Emoji } from "@versia/client/types";
|
||||
import type { CustomEmoji } from "@versia/client/schemas";
|
||||
import {
|
||||
ArrowDownAZ,
|
||||
ArrowUpAz,
|
||||
|
|
@ -45,13 +45,14 @@ import {
|
|||
Plus,
|
||||
} from "lucide-vue-next";
|
||||
import { ref } from "vue";
|
||||
import type { z } from "zod";
|
||||
import BatchDropdown from "./batch-dropdown.vue";
|
||||
import Dropdown from "./dropdown.vue";
|
||||
import Uploader from "./uploader.vue";
|
||||
|
||||
// No destructuring props to avoid reactivity issues
|
||||
const props = defineProps<{
|
||||
emojis: Emoji[];
|
||||
emojis: z.infer<typeof CustomEmoji>[];
|
||||
canUpload: boolean;
|
||||
}>();
|
||||
|
||||
|
|
@ -64,7 +65,7 @@ const valueUpdater = <T extends Updater<any>>(updaterOrValue: T, ref: Ref) => {
|
|||
: updaterOrValue;
|
||||
};
|
||||
|
||||
const columns: ColumnDef<Emoji>[] = [
|
||||
const columns: ColumnDef<z.infer<typeof CustomEmoji>>[] = [
|
||||
{
|
||||
id: "select",
|
||||
header: ({ table }) => (
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { toTypedSchema } from "@vee-validate/zod";
|
||||
import { RolePermission } from "@versia/client/types";
|
||||
import { RolePermission } from "@versia/client/schemas";
|
||||
import { useForm } from "vee-validate";
|
||||
import { toast } from "vue-sonner";
|
||||
import { z } from "zod";
|
||||
|
|
@ -221,11 +221,11 @@ const formSchema = toTypedSchema(
|
|||
.min(1)
|
||||
.max(
|
||||
identity.value?.instance.configuration.emojis
|
||||
.max_emoji_shortcode_characters ?? Number.POSITIVE_INFINITY,
|
||||
.max_shortcode_characters ?? Number.POSITIVE_INFINITY,
|
||||
m.solid_inclusive_owl_hug({
|
||||
count:
|
||||
identity.value?.instance.configuration.emojis
|
||||
.max_emoji_shortcode_characters ??
|
||||
.max_shortcode_characters ??
|
||||
Number.POSITIVE_INFINITY,
|
||||
}),
|
||||
)
|
||||
|
|
@ -244,12 +244,11 @@ const formSchema = toTypedSchema(
|
|||
.string()
|
||||
.max(
|
||||
identity.value?.instance.configuration.emojis
|
||||
.max_emoji_description_characters ??
|
||||
Number.POSITIVE_INFINITY,
|
||||
.max_description_characters ?? Number.POSITIVE_INFINITY,
|
||||
m.key_ago_hound_emerge({
|
||||
count:
|
||||
identity.value?.instance.configuration.emojis
|
||||
.max_emoji_description_characters ??
|
||||
.max_description_characters ??
|
||||
Number.POSITIVE_INFINITY,
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ export const formSchema = (identity: Identity) =>
|
|||
(v) =>
|
||||
v.size <=
|
||||
(identity.instance.configuration.accounts
|
||||
.header_size_limit ?? Number.POSITIVE_INFINITY),
|
||||
.header_limit ?? Number.POSITIVE_INFINITY),
|
||||
m.civil_icy_ant_mend({
|
||||
size: identity.instance.configuration.accounts
|
||||
.header_size_limit,
|
||||
.header_limit,
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
|
|
@ -26,10 +26,10 @@ export const formSchema = (identity: Identity) =>
|
|||
(v) =>
|
||||
v.size <=
|
||||
(identity.instance.configuration.accounts
|
||||
.avatar_size_limit ?? Number.POSITIVE_INFINITY),
|
||||
.avatar_limit ?? Number.POSITIVE_INFINITY),
|
||||
m.zippy_caring_raven_edit({
|
||||
size: identity.instance.configuration.accounts
|
||||
.avatar_size_limit,
|
||||
.avatar_limit,
|
||||
}),
|
||||
)
|
||||
.or(z.string().url())
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ import {
|
|||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import type { Account } from "@versia/client/types";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import {
|
||||
AtSign,
|
||||
Ban,
|
||||
|
|
@ -84,10 +84,11 @@ import {
|
|||
VolumeX,
|
||||
} from "lucide-vue-next";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
const { account } = defineProps<{
|
||||
account: Account;
|
||||
account: z.infer<typeof Account>;
|
||||
}>();
|
||||
|
||||
const isMe = identity.value?.account.id === account.id;
|
||||
|
|
|
|||
|
|
@ -25,12 +25,13 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import ProfileBadge from "./profile-badge.vue";
|
||||
|
||||
const { account } = defineProps<{
|
||||
account: Account;
|
||||
account: z.infer<typeof Account>;
|
||||
}>();
|
||||
|
||||
const config = useConfig();
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Emoji } from "@versia/client/types";
|
||||
import type { CustomEmoji } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
const { content } = defineProps<{
|
||||
content: string;
|
||||
emojis: Emoji[];
|
||||
emojis: z.infer<typeof CustomEmoji>[];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Emoji, Field } from "@versia/client/types";
|
||||
import type { CustomEmoji, Field } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
defineProps<{
|
||||
fields: Field[];
|
||||
emojis: Emoji[];
|
||||
fields: z.infer<typeof Field>[];
|
||||
emojis: z.infer<typeof CustomEmoji>[];
|
||||
}>();
|
||||
</script>
|
||||
|
|
@ -66,9 +66,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import { Ellipsis, Loader } from "lucide-vue-next";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
import CopyableText from "~/components/notes/copyable-text.vue";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Card, CardContent, CardFooter, CardTitle } from "~/components/ui/card";
|
||||
|
|
@ -83,7 +84,7 @@ import ProfileHeader from "./profile-header.vue";
|
|||
import ProfileStats from "./profile-stats.vue";
|
||||
|
||||
const { account } = defineProps<{
|
||||
account: Account;
|
||||
account: z.infer<typeof Account>;
|
||||
}>();
|
||||
|
||||
const { relationship, isLoading } = useRelationship(client, account.id);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { Separator } from "~/components/ui/separator";
|
||||
import CopyableText from "../notes/copyable-text.vue";
|
||||
import Avatar from "./avatar.vue";
|
||||
|
|
@ -60,7 +61,7 @@ import ProfileContent from "./profile-content.vue";
|
|||
import ProfileFields from "./profile-fields.vue";
|
||||
|
||||
const { account } = defineProps<{
|
||||
account: Account;
|
||||
account: z.infer<typeof Account>;
|
||||
}>();
|
||||
|
||||
const [username, instance] = account.acct.split("@");
|
||||
|
|
|
|||
|
|
@ -18,12 +18,13 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { Card, CardContent } from "~/components/ui/card";
|
||||
import Avatar from "./avatar.vue";
|
||||
|
||||
const { account, domain, naked } = defineProps<{
|
||||
account: Account;
|
||||
account: z.infer<typeof Account>;
|
||||
domain: string;
|
||||
naked?: boolean;
|
||||
}>();
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
<template>
|
||||
<!-- OIDC linked accounts manager -->
|
||||
<div class="w-full ring-1 ring-white/5 pb-5 bg-dark-800 rounded overflow-hidden">
|
||||
<div class="px-4 py-4">
|
||||
<h3 class="font-semibold text-gray-300 text-xl">Linked accounts</h3>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2 gap-4">
|
||||
<div v-for="provider of ssoConfig?.providers" :key="provider.id"
|
||||
class="flex items-center justify-between p-4 bg-dark-700 rounded">
|
||||
<div class="flex items-center gap-4">
|
||||
<Avatar :src="provider.icon" :alt="provider.name" class="size-8" />
|
||||
<span class="font-semibold text-gray-300">{{ provider.name }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<Button theme="primary" :loading="loading"
|
||||
v-if="!linkedProviders?.find(p => p.id === provider.id)" @click="link(provider.id)">
|
||||
Link
|
||||
</Button>
|
||||
<Button theme="secondary" :loading="loading" v-else @click="unlink(provider.id)">
|
||||
Unlink
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ResponseError } from "@versia/client";
|
||||
import Button from "~/packages/ui/components/buttons/button.vue";
|
||||
import Avatar from "../avatars/avatar.vue";
|
||||
|
||||
const ssoConfig = useSSOConfig();
|
||||
const linkedProviders = useLinkedSSO(client);
|
||||
const loading = ref(false);
|
||||
|
||||
const link = async (providerId: string) => {
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const output = await client.value.post<{
|
||||
link: string;
|
||||
}>("/api/v1/sso", {
|
||||
issuer: providerId,
|
||||
});
|
||||
|
||||
window.location.href = output.data.link;
|
||||
} catch (error) {
|
||||
const e = error as ResponseError<{ error: string }>;
|
||||
|
||||
useEvent("notification:new", {
|
||||
title: "Failed to link account",
|
||||
description: e.response.data.error,
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const unlink = async (providerId: string) => {
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
await client.value.delete<void>(`/api/v1/sso/${providerId}`);
|
||||
|
||||
useEvent("notification:new", {
|
||||
title: "Account unlinked",
|
||||
type: "success",
|
||||
});
|
||||
|
||||
linkedProviders.value = linkedProviders.value.filter(
|
||||
(p) => p.id !== providerId,
|
||||
);
|
||||
} catch (error) {
|
||||
const e = error as ResponseError<{ error: string }>;
|
||||
|
||||
useEvent("notification:new", {
|
||||
title: "Failed to unlink account",
|
||||
description: e.response.data.error,
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
};
|
||||
</script>
|
||||
|
|
@ -44,8 +44,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Account } from "@versia/client/types";
|
||||
import { ChevronsUpDown, LogIn, LogOut, UserPlus } from "lucide-vue-next";
|
||||
import { LogIn, LogOut, UserPlus } from "lucide-vue-next";
|
||||
import { toast } from "vue-sonner";
|
||||
import TinyCard from "~/components/profiles/tiny-card.vue";
|
||||
import { Button } from "~/components/ui/button";
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<Timeline type="status" :items="(items as Status[])" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
<Timeline type="status" :items="items" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
:error="error" :load-next="loadNext" :load-prev="loadPrev" :remove-item="removeItem"
|
||||
:update-item="updateItem" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { z } from "zod";
|
||||
import Timeline from "./timeline.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<Timeline type="status" :items="(items as Status[])" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
<Timeline type="status" :items="items" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
:error="error" :load-next="loadNext" :load-prev="loadPrev" :remove-item="removeItem"
|
||||
:update-item="updateItem" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { z } from "zod";
|
||||
import { useGlobalTimeline } from "~/composables/GlobalTimeline";
|
||||
import Timeline from "./timeline.vue";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
<template>
|
||||
<Timeline type="status" :items="(items as Status[])" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
<Timeline type="status" :items="items" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
:error="error" :load-next="loadNext" :load-prev="loadPrev" :remove-item="removeItem"
|
||||
:update-item="updateItem" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Status } from "@versia/client/types";
|
||||
import { useHomeTimeline } from "~/composables/HomeTimeline";
|
||||
<script lang="ts" setup>import { useHomeTimeline } from "~/composables/HomeTimeline";
|
||||
import Timeline from "./timeline.vue";
|
||||
import type { z } from "zod";
|
||||
|
||||
const {
|
||||
error,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<Timeline type="status" :items="(items as Status[])" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
<Timeline type="status" :items="items" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
:error="error" :load-next="loadNext" :load-prev="loadPrev" :remove-item="removeItem"
|
||||
:update-item="updateItem" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { z } from "zod";
|
||||
import { useLocalTimeline } from "~/composables/LocalTimeline";
|
||||
import Timeline from "./timeline.vue";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
<template>
|
||||
<Timeline type="notification" :items="(items as Notification[])" :is-loading="isLoading"
|
||||
<Timeline type="notification" :items="items" :is-loading="isLoading"
|
||||
:has-reached-end="hasReachedEnd" :error="error" :load-next="loadNext" :load-prev="loadPrev"
|
||||
:remove-item="removeItem" :update-item="updateItem" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Notification } from "@versia/client/types";
|
||||
import { useNotificationTimeline } from "~/composables/NotificationTimeline";
|
||||
import Timeline from "./timeline.vue";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
<template>
|
||||
<Timeline type="status" :items="(items as Status[])" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
<Timeline type="status" :items="items" :is-loading="isLoading" :has-reached-end="hasReachedEnd"
|
||||
:error="error" :load-next="loadNext" :load-prev="loadPrev" :remove-item="removeItem"
|
||||
:update-item="updateItem" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Status } from "@versia/client/types";
|
||||
import { usePublicTimeline } from "~/composables/PublicTimeline";
|
||||
import Timeline from "./timeline.vue";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
<template>
|
||||
<component :is="itemComponent" :note="type === 'status' ? item : undefined" :notification="type === 'notification' ? item : undefined" @update="$emit('update', $event)"
|
||||
<component :is="itemComponent" :note="type === 'status' ? item : undefined" :notification="type === 'notification' ? item : (undefined as any)" @update="$emit('update', $event)"
|
||||
@delete="$emit('delete', item?.id)" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Notification, Status } from "@versia/client/types";
|
||||
import type { Notification, Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import Thread from "../notes/thread.vue";
|
||||
import NotificationItem from "../notifications/notification.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
item?: Status | Notification;
|
||||
item?: z.infer<typeof Status> | z.infer<typeof Notification>;
|
||||
type: "status" | "notification";
|
||||
}>();
|
||||
|
||||
|
|
@ -17,9 +18,11 @@ const itemComponent = computed(() => {
|
|||
if (props.type === "status") {
|
||||
return Thread;
|
||||
}
|
||||
|
||||
if (props.type === "notification") {
|
||||
return NotificationItem;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -40,8 +40,9 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Notification, Status } from "@versia/client/types";
|
||||
import type { Notification, Status } from "@versia/client/schemas";
|
||||
import { useIntersectionObserver } from "@vueuse/core";
|
||||
import type { z } from "zod";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import NoPosts from "../errors/NoPosts.vue";
|
||||
import ReachedEnd from "../errors/ReachedEnd.vue";
|
||||
|
|
@ -50,7 +51,7 @@ import { Button } from "../ui/button";
|
|||
import TimelineItem from "./timeline-item.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
items: Status[] | Notification[];
|
||||
items: z.infer<typeof Status>[] | z.infer<typeof Notification>[];
|
||||
type: "status" | "notification";
|
||||
isLoading: boolean;
|
||||
hasReachedEnd: boolean;
|
||||
|
|
@ -58,14 +59,15 @@ const props = defineProps<{
|
|||
loadNext: () => void;
|
||||
loadPrev: () => void;
|
||||
removeItem: (id: string) => void;
|
||||
updateItem: ((item: Status) => void) | ((item: Notification) => void);
|
||||
updateItem:
|
||||
| ((item: z.infer<typeof Status>) => void)
|
||||
| ((item: z.infer<typeof Notification>) => void);
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<(e: "update") => void>();
|
||||
|
||||
const loadMoreTrigger = ref<HTMLElement | null>(null);
|
||||
|
||||
// @ts-expect-error Too complex?
|
||||
useIntersectionObserver(loadMoreTrigger, ([observer]) => {
|
||||
if (observer?.isIntersecting && !props.isLoading && !props.hasReachedEnd) {
|
||||
props.loadNext();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { DrawerRoot } from "vaul-vue";
|
|||
|
||||
const props = withDefaults(defineProps<DrawerRootProps>(), {
|
||||
shouldScaleBackground: true,
|
||||
});
|
||||
}) as DrawerRootProps;
|
||||
|
||||
const emits = defineEmits<DrawerRootEmits>();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Account } from "@versia/client/types";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useAccount = (
|
||||
client: MaybeRef<Client | null>,
|
||||
accountId: MaybeRef<string | null>,
|
||||
) => {
|
||||
if (!client) {
|
||||
return ref(null as Account | null);
|
||||
return ref(null as z.infer<typeof Account> | null);
|
||||
}
|
||||
|
||||
const output = ref(null as Account | null);
|
||||
const output = ref(null as z.infer<typeof Account> | null);
|
||||
|
||||
watchEffect(() => {
|
||||
if (toValue(accountId)) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Account } from "@versia/client/types";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useAccountFromAcct = (
|
||||
client: MaybeRef<Client | null>,
|
||||
acct: string,
|
||||
): { account: Ref<Account | null>; isLoading: Ref<boolean> } => {
|
||||
const output = ref(null as Account | null);
|
||||
): {
|
||||
account: Ref<z.infer<typeof Account> | null>;
|
||||
isLoading: Ref<boolean>;
|
||||
} => {
|
||||
const output = ref(null as z.infer<typeof Account> | null);
|
||||
const isLoading = ref(true);
|
||||
|
||||
ref(client)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Account } from "@versia/client/types";
|
||||
import type { Account } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useAccountSearch = (
|
||||
client: MaybeRef<Client | null>,
|
||||
q: string,
|
||||
): Ref<Account[] | null> => {
|
||||
const output = ref(null as Account[] | null);
|
||||
): Ref<z.infer<typeof Account>[] | null> => {
|
||||
const output = ref(null as z.infer<typeof Account>[] | null);
|
||||
|
||||
ref(client)
|
||||
.value?.searchAccount(q, {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { type TimelineOptions, useTimeline } from "./Timeline";
|
||||
|
||||
export function useAccountTimeline(
|
||||
client: Client,
|
||||
accountId: string,
|
||||
options: Partial<TimelineOptions<Status>> = {},
|
||||
options: Partial<TimelineOptions<z.infer<typeof Status>>> = {},
|
||||
) {
|
||||
return useTimeline(client, {
|
||||
fetchFunction: (client, opts) =>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
import type { ApplicationData } from "@versia/client/types";
|
||||
import type { CredentialApplication } from "@versia/client/schemas";
|
||||
import { StorageSerializers } from "@vueuse/core";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useAppData = () => {
|
||||
return useLocalStorage<ApplicationData | null>("versia:app_data", null, {
|
||||
return useLocalStorage<z.infer<typeof CredentialApplication> | null>(
|
||||
"versia:app_data",
|
||||
null,
|
||||
{
|
||||
serializer: StorageSerializers.object,
|
||||
});
|
||||
},
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { RolePermission } from "@versia/client/types";
|
||||
import type { RolePermission } from "@versia/client/schemas";
|
||||
import { toast } from "vue-sonner";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import { Client, type Token } from "@versia/client";
|
||||
import { Client } from "@versia/client";
|
||||
import type { Token } from "@versia/client/schemas";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useClient = (
|
||||
origin?: MaybeRef<URL>,
|
||||
customToken: MaybeRef<Token | null> = null,
|
||||
customToken: MaybeRef<z.infer<typeof Token> | null> = null,
|
||||
): Ref<Client> => {
|
||||
const apiHost = window.location.origin;
|
||||
const domain = identity.value?.instance.domain;
|
||||
|
|
@ -15,11 +17,15 @@ export const useClient = (
|
|||
toValue(customToken)?.access_token ??
|
||||
identity.value?.tokens.access_token ??
|
||||
undefined,
|
||||
(error) => {
|
||||
{
|
||||
globalCatch: (error) => {
|
||||
toast.error(
|
||||
error.response.data.error ?? "No error message provided",
|
||||
error.response.data.error ??
|
||||
"No error message provided",
|
||||
);
|
||||
},
|
||||
throwOnError: false,
|
||||
},
|
||||
),
|
||||
) as Ref<Client>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,27 +1,28 @@
|
|||
import type { Account, Attachment, Status } from "@versia/client/types";
|
||||
import type { Account, Attachment, Status } from "@versia/client/schemas";
|
||||
import mitt from "mitt";
|
||||
import type { z } from "zod";
|
||||
import type { Identity } from "./Identities";
|
||||
|
||||
type ApplicationEvents = {
|
||||
"note:reply": Status;
|
||||
"note:delete": Status;
|
||||
"note:edit": Status;
|
||||
"note:like": Status;
|
||||
"note:unlike": Status;
|
||||
"note:reblog": Status;
|
||||
"note:unreblog": Status;
|
||||
"note:quote": Status;
|
||||
"note:report": Status;
|
||||
"note:reply": z.infer<typeof Status>;
|
||||
"note:delete": z.infer<typeof Status>;
|
||||
"note:edit": z.infer<typeof Status>;
|
||||
"note:like": z.infer<typeof Status>;
|
||||
"note:unlike": z.infer<typeof Status>;
|
||||
"note:reblog": z.infer<typeof Status>;
|
||||
"note:unreblog": z.infer<typeof Status>;
|
||||
"note:quote": z.infer<typeof Status>;
|
||||
"note:report": z.infer<typeof Status>;
|
||||
"composer:open": undefined;
|
||||
"composer:reply": Status;
|
||||
"composer:quote": Status;
|
||||
"composer:edit": Status;
|
||||
"composer:send": Status;
|
||||
"composer:send-edit": Status;
|
||||
"composer:reply": z.infer<typeof Status>;
|
||||
"composer:quote": z.infer<typeof Status>;
|
||||
"composer:edit": z.infer<typeof Status>;
|
||||
"composer:send": z.infer<typeof Status>;
|
||||
"composer:send-edit": z.infer<typeof Status>;
|
||||
"composer:close": undefined;
|
||||
"account:report": Account;
|
||||
"account:update": Account;
|
||||
"attachment:view": Attachment;
|
||||
"account:report": z.infer<typeof Account>;
|
||||
"account:update": z.infer<typeof Account>;
|
||||
"attachment:view": z.infer<typeof Attachment>;
|
||||
"identity:change": Identity;
|
||||
"preferences:open": undefined;
|
||||
error: {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,13 @@
|
|||
import type { Client } from "@versia/client";
|
||||
|
||||
type ExtendedDescription = {
|
||||
updated_at: string;
|
||||
content: string;
|
||||
};
|
||||
import type { ExtendedDescription } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useExtendedDescription = (client: MaybeRef<Client | null>) => {
|
||||
if (!ref(client).value) {
|
||||
return ref(null as ExtendedDescription | null);
|
||||
return ref(null as z.infer<typeof ExtendedDescription> | null);
|
||||
}
|
||||
|
||||
const output = ref(null as ExtendedDescription | null);
|
||||
const output = ref(null as z.infer<typeof ExtendedDescription> | null);
|
||||
|
||||
ref(client)
|
||||
.value?.getInstanceExtendedDescription()
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { type TimelineOptions, useTimeline } from "./Timeline";
|
||||
|
||||
export function useGlobalTimeline(
|
||||
client: Client,
|
||||
options: Partial<TimelineOptions<Status>> = {},
|
||||
options: Partial<TimelineOptions<z.infer<typeof Status>>> = {},
|
||||
) {
|
||||
return useTimeline(client, {
|
||||
// TODO: Implement global timeline in client sdk
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { type TimelineOptions, useTimeline } from "./Timeline";
|
||||
|
||||
export function useHomeTimeline(
|
||||
client: Client,
|
||||
options: Partial<TimelineOptions<Status>> = {},
|
||||
options: Partial<TimelineOptions<z.infer<typeof Status>>> = {},
|
||||
) {
|
||||
return useTimeline(client, {
|
||||
fetchFunction: (client, opts) => client.getHomeTimeline(opts),
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
import type { Token } from "@versia/client";
|
||||
import type {
|
||||
Account,
|
||||
Emoji,
|
||||
CustomEmoji,
|
||||
Instance,
|
||||
RolePermission,
|
||||
} from "@versia/client/types";
|
||||
Token,
|
||||
} from "@versia/client/schemas";
|
||||
import { StorageSerializers, useLocalStorage } from "@vueuse/core";
|
||||
import { ref, watch } from "vue";
|
||||
import type { z } from "zod";
|
||||
|
||||
/**
|
||||
* Represents an identity with associated tokens, account, instance, permissions, and emojis.
|
||||
*/
|
||||
export interface Identity {
|
||||
id: string;
|
||||
tokens: Token;
|
||||
account: Account;
|
||||
instance: Instance;
|
||||
tokens: z.infer<typeof Token>;
|
||||
account: z.infer<typeof Account>;
|
||||
instance: z.infer<typeof Instance>;
|
||||
permissions: RolePermission[];
|
||||
emojis: Emoji[];
|
||||
emojis: z.infer<typeof CustomEmoji>[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { ExtendedDescription, Instance } from "@versia/client/types";
|
||||
import type { Instance, TermsOfService } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useInstance = () => {
|
||||
return computed(() => identity.value?.instance);
|
||||
|
|
@ -7,10 +8,10 @@ export const useInstance = () => {
|
|||
|
||||
export const useInstanceFromClient = (client: MaybeRef<Client>) => {
|
||||
if (!client) {
|
||||
return ref(null as Instance | null);
|
||||
return ref(null as z.infer<typeof Instance> | null);
|
||||
}
|
||||
|
||||
const output = ref(null as Instance | null);
|
||||
const output = ref(null as z.infer<typeof Instance> | null);
|
||||
|
||||
watchEffect(() => {
|
||||
toValue(client)
|
||||
|
|
@ -25,10 +26,10 @@ export const useInstanceFromClient = (client: MaybeRef<Client>) => {
|
|||
|
||||
export const useTos = (client: MaybeRef<Client>) => {
|
||||
if (!client) {
|
||||
return ref(null as ExtendedDescription | null);
|
||||
return ref(null as z.infer<typeof TermsOfService> | null);
|
||||
}
|
||||
|
||||
const output = ref(null as ExtendedDescription | null);
|
||||
const output = ref(null as z.infer<typeof TermsOfService> | null);
|
||||
|
||||
watchEffect(() => {
|
||||
toValue(client)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { type TimelineOptions, useTimeline } from "./Timeline";
|
||||
|
||||
export function useLocalTimeline(
|
||||
client: Client,
|
||||
options: Partial<TimelineOptions<Status>> = {},
|
||||
options: Partial<TimelineOptions<z.infer<typeof Status>>> = {},
|
||||
) {
|
||||
return useTimeline(client, {
|
||||
fetchFunction: (client, opts) => client.getLocalTimeline(opts),
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useNote = (
|
||||
client: MaybeRef<Client | null>,
|
||||
noteId: MaybeRef<string | null>,
|
||||
) => {
|
||||
if (!(toValue(client) && toValue(noteId))) {
|
||||
return ref(null as Status | null);
|
||||
return ref(null as z.infer<typeof Status> | null);
|
||||
}
|
||||
|
||||
const output = ref(null as Status | null);
|
||||
const output = ref(null as z.infer<typeof Status> | null);
|
||||
|
||||
watchEffect(() => {
|
||||
toValue(noteId) &&
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Context } from "@versia/client/types";
|
||||
import type { Context } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useNoteContext = (
|
||||
client: MaybeRef<Client | null>,
|
||||
noteId: MaybeRef<string | null>,
|
||||
) => {
|
||||
if (!ref(client).value) {
|
||||
return ref(null as Context | null);
|
||||
return ref(null as z.infer<typeof Context> | null);
|
||||
}
|
||||
|
||||
const output = ref(null as Context | null);
|
||||
const output = ref(null as z.infer<typeof Context> | null);
|
||||
|
||||
watchEffect(() => {
|
||||
if (toValue(noteId)) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Notification } from "@versia/client/types";
|
||||
import type { Notification } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { type TimelineOptions, useTimeline } from "./Timeline";
|
||||
|
||||
export function useNotificationTimeline(
|
||||
client: Client,
|
||||
options: Partial<TimelineOptions<Notification>> = {},
|
||||
options: Partial<TimelineOptions<z.infer<typeof Notification>>> = {},
|
||||
) {
|
||||
return useTimeline(client, {
|
||||
fetchFunction: (client, opts) => client.getNotifications(opts),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Status } from "@versia/client/types";
|
||||
import type { Status } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
import { type TimelineOptions, useTimeline } from "./Timeline";
|
||||
|
||||
export function usePublicTimeline(
|
||||
client: Client,
|
||||
options: Partial<TimelineOptions<Status>> = {},
|
||||
options: Partial<TimelineOptions<z.infer<typeof Status>>> = {},
|
||||
) {
|
||||
return useTimeline(client, {
|
||||
fetchFunction: (client, opts) => client.getPublicTimeline(opts),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Relationship } from "@versia/client/types";
|
||||
import type { Relationship } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useRelationship = (
|
||||
client: MaybeRef<Client | null>,
|
||||
accountId: MaybeRef<string | null>,
|
||||
) => {
|
||||
const relationship = ref(null as Relationship | null);
|
||||
const relationship = ref(null as z.infer<typeof Relationship> | null);
|
||||
const isLoading = ref(false);
|
||||
|
||||
if (!identity.value) {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { Account, Mention } from "@versia/client/types";
|
||||
import type { Account, Mention } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useResolveMentions = (
|
||||
mentions: Ref<Mention[]>,
|
||||
mentions: Ref<z.infer<typeof Mention>[]>,
|
||||
client: Client | null,
|
||||
): Ref<Account[]> => {
|
||||
): Ref<z.infer<typeof Account>[]> => {
|
||||
if (!client) {
|
||||
return ref([]);
|
||||
}
|
||||
|
||||
const output = ref<Account[]>([]);
|
||||
const output = ref<z.infer<typeof Account>[]>([]);
|
||||
|
||||
watch(
|
||||
mentions,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import type { Instance } from "@versia/client/types";
|
||||
import type { Instance } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useSSOConfig = (): Ref<Instance["sso"] | null> => {
|
||||
export const useSSOConfig = (): Ref<z.infer<
|
||||
typeof Instance.shape.sso
|
||||
> | null> => {
|
||||
const instance = useInstance();
|
||||
|
||||
return computed(() => instance.value?.sso || null);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { Client, Output } from "@versia/client";
|
||||
import type { Notification, Status } from "@versia/client/types";
|
||||
import type { Notification, Status } from "@versia/client/schemas";
|
||||
import { useIntervalFn } from "@vueuse/core";
|
||||
import type { z } from "zod";
|
||||
|
||||
export interface TimelineOptions<T> {
|
||||
fetchFunction: (client: Client, options: object) => Promise<Output<T[]>>;
|
||||
|
|
@ -8,10 +9,9 @@ export interface TimelineOptions<T> {
|
|||
limit?: number;
|
||||
}
|
||||
|
||||
export function useTimeline<T extends Status | Notification>(
|
||||
client: Client,
|
||||
options: TimelineOptions<T>,
|
||||
) {
|
||||
export function useTimeline<
|
||||
T extends z.infer<typeof Status> | z.infer<typeof Notification>,
|
||||
>(client: Client, options: TimelineOptions<T>) {
|
||||
const items = ref<T[]>([]) as Ref<T[]>;
|
||||
const isLoading = ref(false);
|
||||
const hasReachedEnd = ref(false);
|
||||
|
|
|
|||
|
|
@ -248,6 +248,7 @@ export default defineNuxtConfig({
|
|||
htmlAttrs: { lang: "en-us" },
|
||||
},
|
||||
rootAttrs: {
|
||||
// @ts-expect-error Nonstandard HTML attribute for Vaul
|
||||
"vaul-drawer-wrapper": true,
|
||||
},
|
||||
keepalive: true,
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
"@tiptap/suggestion": "^2.12.0",
|
||||
"@tiptap/vue-3": "^2.12.0",
|
||||
"@vee-validate/zod": "^4.15.0",
|
||||
"@versia/client": "0.1.5",
|
||||
"@versia/client": "0.2.0-alpha.2",
|
||||
"@videojs-player/vue": "^1.0.0",
|
||||
"@vite-pwa/nuxt": "^1.0.1",
|
||||
"@vueuse/core": "^13.2.0",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import type { Emoji } from "@versia/client/types";
|
||||
import type { CustomEmoji } from "@versia/client/schemas";
|
||||
import type { z } from "zod";
|
||||
|
||||
const emojisRegex =
|
||||
/\p{RI}\p{RI}|\p{Emoji}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?(\u200D(\p{RI}\p{RI}|\p{Emoji}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?))*/gu;
|
||||
const incorrectEmojisRegex = /^[#*0-9©®]$/;
|
||||
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
nuxtApp.vueApp.directive<HTMLElement, Emoji[]>("render-emojis", {
|
||||
nuxtApp.vueApp.directive<HTMLElement, z.infer<typeof CustomEmoji>[]>(
|
||||
"render-emojis",
|
||||
{
|
||||
beforeMount(el, binding) {
|
||||
// Replace emoji shortcodes with images
|
||||
if (preferences.custom_emojis.value) {
|
||||
|
|
@ -32,13 +35,16 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||
}
|
||||
|
||||
if (preferences.emoji_theme.value !== "native") {
|
||||
el.innerHTML = el.innerHTML.replace(emojisRegex, (match) => {
|
||||
el.innerHTML = el.innerHTML.replace(
|
||||
emojisRegex,
|
||||
(match) => {
|
||||
if (incorrectEmojisRegex.test(match)) {
|
||||
return match;
|
||||
}
|
||||
|
||||
return `<img src="/emojis/${preferences.emoji_theme.value}/${match}.svg" alt="${match}" class="h-[1em] inline not-prose hover:scale-110 transition-transform duration-75 ease-in-out">`;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Make all links that don't open to the same origin open in a new tab
|
||||
|
|
@ -49,5 +55,6 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { ApplicationData } from "@versia/client/types";
|
||||
import type { CredentialApplication } from "@versia/client/schemas";
|
||||
import { nanoid } from "nanoid";
|
||||
import { toast } from "vue-sonner";
|
||||
import type { z } from "zod";
|
||||
import { confirmModalService } from "~/components/modals/composable";
|
||||
import pkg from "~/package.json";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
|
@ -23,7 +23,7 @@ export const askForInstance = async (): Promise<URL> => {
|
|||
};
|
||||
|
||||
export const signIn = async (
|
||||
appData: Ref<ApplicationData | null>,
|
||||
appData: Ref<z.infer<typeof CredentialApplication> | null>,
|
||||
origin: URL,
|
||||
) => {
|
||||
const id = toast.loading(m.level_due_ox_greet());
|
||||
|
|
@ -74,7 +74,7 @@ export const signIn = async (
|
|||
|
||||
export const signInWithCode = (
|
||||
code: string,
|
||||
appData: ApplicationData,
|
||||
appData: z.infer<typeof CredentialApplication>,
|
||||
origin: URL,
|
||||
) => {
|
||||
const client = useClient(origin);
|
||||
|
|
@ -126,7 +126,7 @@ export const signInWithCode = (
|
|||
};
|
||||
|
||||
export const signOut = async (
|
||||
appData: ApplicationData | null,
|
||||
appData: z.infer<typeof CredentialApplication> | null,
|
||||
identityToRevoke: Identity,
|
||||
) => {
|
||||
const id = toast.loading("Signing out...");
|
||||
|
|
|
|||
Loading…
Reference in a new issue