79 lines
1.7 KiB
Vue
79 lines
1.7 KiB
Vue
<template>
|
|
<h1 class="mb-4 font-semibold text-xl">
|
|
{{ title }}
|
|
</h1>
|
|
|
|
|
|
<div v-if="messages.length == 0">Empty...</div>
|
|
<template v-else>
|
|
<ListItem v-for="message in messages" :key="message.ID" :item="message" />
|
|
|
|
<div class="flex items-center justify-center mb-10">
|
|
<button class="py-4 hover:bg-slate-100 rounded border text-xl font-bold w-full"
|
|
@click="loadMore()">LoadMore</button>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
<script>
|
|
import { defineComponent, onMounted, ref } from 'vue';
|
|
import ListItem from './ListItem.vue';
|
|
|
|
|
|
export default defineComponent({
|
|
components: {
|
|
ListItem,
|
|
},
|
|
name: 'MessageList',
|
|
props: {
|
|
getTitle: { type: String, required: true },
|
|
routeName: { type: String, required: true },
|
|
getMessages: { type: Function, required: true },
|
|
},
|
|
setup(props) {
|
|
const router = useRouter();
|
|
const route = useRoute();
|
|
|
|
const messages = ref([]);
|
|
|
|
const title = ref('');
|
|
|
|
onMounted(async () => {
|
|
title.value = await props.getTitle()
|
|
});
|
|
|
|
const loadData = async () => {
|
|
messages.value = await props.getMessages(route.params?.channel, { offset: route.params.offset });
|
|
}
|
|
|
|
const loadMore = async () => {
|
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
|
|
|
const offset = messages.value[messages.value.length - 1].ID
|
|
|
|
messages.value = [];
|
|
|
|
router.push({
|
|
name: props.routeName,
|
|
params: {
|
|
channel: route.params.channel,
|
|
offset: offset,
|
|
},
|
|
});
|
|
|
|
nextTick(loadData);
|
|
}
|
|
|
|
|
|
watch(route, loadData);
|
|
onMounted(loadData);
|
|
|
|
return {
|
|
messages,
|
|
loadMore,
|
|
title,
|
|
}
|
|
}
|
|
});
|
|
</script>
|