mirror of
https://github.com/versia-pub/frontend.git
synced 2026-06-14 15:39:15 +02:00
chore: ⬆️ Upgrade to Nuxt 4
Some checks failed
Some checks failed
This commit is contained in:
parent
8debe97f63
commit
7f7cf20311
386 changed files with 2376 additions and 2332 deletions
87
app/components/timelines/timeline.vue
Normal file
87
app/components/timelines/timeline.vue
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<template>
|
||||
<div
|
||||
role="status"
|
||||
class="flex flex-col gap-4 items-center *:max-w-2xl *:w-full p-4"
|
||||
>
|
||||
<TimelineItem
|
||||
:type="type"
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
@update="updateItem"
|
||||
@delete="removeItem"
|
||||
/>
|
||||
|
||||
<Spinner v-if="isLoading" />
|
||||
|
||||
<div v-if="error" class="timeline-error">
|
||||
{{ error.message }}
|
||||
</div>
|
||||
|
||||
<!-- If there are some posts, but the user scrolled to the end -->
|
||||
<ReachedEnd v-if="hasReachedEnd && items.length > 0" />
|
||||
|
||||
<!-- If there are no posts at all -->
|
||||
<NoPosts v-else-if="hasReachedEnd && items.length === 0" />
|
||||
|
||||
<div v-else-if="!preferences.infinite_scroll" class="py-10 px-4">
|
||||
<Button
|
||||
variant="secondary"
|
||||
@click="loadNext"
|
||||
:disabled="isLoading"
|
||||
class="w-full"
|
||||
>
|
||||
{{ m.gaudy_bland_gorilla_talk() }}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div v-else ref="loadMoreTrigger" class="h-20"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
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";
|
||||
import Spinner from "../graphics/spinner.vue";
|
||||
import { Button } from "../ui/button";
|
||||
import TimelineItem from "./timeline-item.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
items: z.infer<typeof Status>[] | z.infer<typeof Notification>[];
|
||||
type: "status" | "notification";
|
||||
isLoading: boolean;
|
||||
hasReachedEnd: boolean;
|
||||
error: Error | null;
|
||||
loadNext: () => void;
|
||||
loadPrev: () => void;
|
||||
removeItem: (id: string) => 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);
|
||||
|
||||
useIntersectionObserver(loadMoreTrigger, ([observer]) => {
|
||||
if (observer?.isIntersecting && !props.isLoading && !props.hasReachedEnd) {
|
||||
props.loadNext();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.items,
|
||||
() => {
|
||||
emit("update");
|
||||
},
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
props.loadNext();
|
||||
});
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue