fix: components

This commit is contained in:
Rogee
2024-09-24 21:23:09 +08:00
parent 9b295864fc
commit db5db42181
7 changed files with 347 additions and 106 deletions

View File

@@ -20,6 +20,7 @@
"autoprefixer": "^10.4.20",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.12",
"unplugin-auto-import": "^0.18.3",
"vite": "^5.3.1"
}
},
@@ -36,6 +37,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@antfu/utils": {
"version": "0.7.10",
"resolved": "https://npm.hub.ipao.vip/repository/npm/@antfu/utils/-/utils-0.7.10.tgz",
"integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.24.8",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
@@ -617,6 +628,29 @@
"node": ">=14"
}
},
"node_modules/@rollup/pluginutils": {
"version": "5.1.2",
"resolved": "https://npm.hub.ipao.vip/repository/npm/@rollup/pluginutils/-/pluginutils-5.1.2.tgz",
"integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.22.0",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.0.tgz",
@@ -994,6 +1028,19 @@
"integrity": "sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA==",
"license": "MIT"
},
"node_modules/acorn": {
"version": "8.12.1",
"resolved": "https://npm.hub.ipao.vip/repository/npm/acorn/-/acorn-8.12.1.tgz",
"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/ansi-regex": {
"version": "6.1.0",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/ansi-regex/-/ansi-regex-6.1.0.tgz",
@@ -1290,6 +1337,13 @@
"node": ">= 6"
}
},
"node_modules/confbox": {
"version": "0.1.7",
"resolved": "https://npm.hub.ipao.vip/repository/npm/confbox/-/confbox-0.1.7.tgz",
"integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
"dev": true,
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -1429,6 +1483,19 @@
"node": ">=6"
}
},
"node_modules/escape-string-regexp": {
"version": "5.0.0",
"resolved": "https://npm.hub.ipao.vip/repository/npm/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
"integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/estree-walker/-/estree-walker-2.0.2.tgz",
@@ -1730,6 +1797,13 @@
"jiti": "bin/jiti.js"
}
},
"node_modules/js-tokens": {
"version": "9.0.0",
"resolved": "https://npm.hub.ipao.vip/repository/npm/js-tokens/-/js-tokens-9.0.0.tgz",
"integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
"dev": true,
"license": "MIT"
},
"node_modules/lilconfig": {
"version": "2.1.0",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/lilconfig/-/lilconfig-2.1.0.tgz",
@@ -1747,6 +1821,23 @@
"dev": true,
"license": "MIT"
},
"node_modules/local-pkg": {
"version": "0.5.0",
"resolved": "https://npm.hub.ipao.vip/repository/npm/local-pkg/-/local-pkg-0.5.0.tgz",
"integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
"dev": true,
"license": "MIT",
"dependencies": {
"mlly": "^1.4.2",
"pkg-types": "^1.0.3"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/lru-cache/-/lru-cache-10.4.3.tgz",
@@ -1834,6 +1925,19 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/mlly": {
"version": "1.7.1",
"resolved": "https://npm.hub.ipao.vip/repository/npm/mlly/-/mlly-1.7.1.tgz",
"integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==",
"dev": true,
"license": "MIT",
"dependencies": {
"acorn": "^8.11.3",
"pathe": "^1.1.2",
"pkg-types": "^1.1.1",
"ufo": "^1.5.3"
}
},
"node_modules/mz": {
"version": "2.7.0",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/mz/-/mz-2.7.0.tgz",
@@ -1952,6 +2056,13 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/pathe": {
"version": "1.1.2",
"resolved": "https://npm.hub.ipao.vip/repository/npm/pathe/-/pathe-1.1.2.tgz",
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
"dev": true,
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.0",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/picocolors/-/picocolors-1.1.0.tgz",
@@ -2043,6 +2154,18 @@
"node": ">= 6"
}
},
"node_modules/pkg-types": {
"version": "1.2.0",
"resolved": "https://npm.hub.ipao.vip/repository/npm/pkg-types/-/pkg-types-1.2.0.tgz",
"integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==",
"dev": true,
"license": "MIT",
"dependencies": {
"confbox": "^0.1.7",
"mlly": "^1.7.1",
"pathe": "^1.1.2"
}
},
"node_modules/postcss": {
"version": "8.4.47",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/postcss/-/postcss-8.4.47.tgz",
@@ -2344,6 +2467,13 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/scule": {
"version": "1.3.0",
"resolved": "https://npm.hub.ipao.vip/repository/npm/scule/-/scule-1.3.0.tgz",
"integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
"dev": true,
"license": "MIT"
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -2493,6 +2623,19 @@
"node": ">=8"
}
},
"node_modules/strip-literal": {
"version": "2.1.0",
"resolved": "https://npm.hub.ipao.vip/repository/npm/strip-literal/-/strip-literal-2.1.0.tgz",
"integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
"dev": true,
"license": "MIT",
"dependencies": {
"js-tokens": "^9.0.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/sucrase": {
"version": "3.35.0",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/sucrase/-/sucrase-3.35.0.tgz",
@@ -2619,6 +2762,102 @@
"dev": true,
"license": "Apache-2.0"
},
"node_modules/ufo": {
"version": "1.5.4",
"resolved": "https://npm.hub.ipao.vip/repository/npm/ufo/-/ufo-1.5.4.tgz",
"integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
"dev": true,
"license": "MIT"
},
"node_modules/unimport": {
"version": "3.12.0",
"resolved": "https://npm.hub.ipao.vip/repository/npm/unimport/-/unimport-3.12.0.tgz",
"integrity": "sha512-5y8dSvNvyevsnw4TBQkIQR1Rjdbb+XjVSwQwxltpnVZrStBvvPkMPcZrh1kg5kY77kpx6+D4Ztd3W6FOBH/y2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.1.0",
"acorn": "^8.12.1",
"escape-string-regexp": "^5.0.0",
"estree-walker": "^3.0.3",
"fast-glob": "^3.3.2",
"local-pkg": "^0.5.0",
"magic-string": "^0.30.11",
"mlly": "^1.7.1",
"pathe": "^1.1.2",
"pkg-types": "^1.2.0",
"scule": "^1.3.0",
"strip-literal": "^2.1.0",
"unplugin": "^1.14.1"
}
},
"node_modules/unimport/node_modules/estree-walker": {
"version": "3.0.3",
"resolved": "https://npm.hub.ipao.vip/repository/npm/estree-walker/-/estree-walker-3.0.3.tgz",
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.0"
}
},
"node_modules/unplugin": {
"version": "1.14.1",
"resolved": "https://npm.hub.ipao.vip/repository/npm/unplugin/-/unplugin-1.14.1.tgz",
"integrity": "sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==",
"dev": true,
"license": "MIT",
"dependencies": {
"acorn": "^8.12.1",
"webpack-virtual-modules": "^0.6.2"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"webpack-sources": "^3"
},
"peerDependenciesMeta": {
"webpack-sources": {
"optional": true
}
}
},
"node_modules/unplugin-auto-import": {
"version": "0.18.3",
"resolved": "https://npm.hub.ipao.vip/repository/npm/unplugin-auto-import/-/unplugin-auto-import-0.18.3.tgz",
"integrity": "sha512-q3FUtGQjYA2e+kb1WumyiQMjHM27MrTQ05QfVwtLRVhyYe+KF6TblBYaEX9L6Z0EibsqaXAiW+RFfkcQpfaXzg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@antfu/utils": "^0.7.10",
"@rollup/pluginutils": "^5.1.0",
"fast-glob": "^3.3.2",
"local-pkg": "^0.5.0",
"magic-string": "^0.30.11",
"minimatch": "^9.0.5",
"unimport": "^3.12.0",
"unplugin": "^1.14.1"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@nuxt/kit": "^3.2.2",
"@vueuse/core": "*"
},
"peerDependenciesMeta": {
"@nuxt/kit": {
"optional": true
},
"@vueuse/core": {
"optional": true
}
}
},
"node_modules/update-browserslist-db": {
"version": "1.1.0",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
@@ -2753,6 +2992,13 @@
"vue": "^3.2.0"
}
},
"node_modules/webpack-virtual-modules": {
"version": "0.6.2",
"resolved": "https://npm.hub.ipao.vip/repository/npm/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
"dev": true,
"license": "MIT"
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://npm.hub.ipao.vip:88/repository/npm/which/-/which-2.0.2.tgz",

View File

@@ -21,6 +21,7 @@
"autoprefixer": "^10.4.20",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.12",
"unplugin-auto-import": "^0.18.3",
"vite": "^5.3.1"
}
}

View File

@@ -1,6 +1,7 @@
<template>
<div class="mb-4 md:mb-8 border rounded overflow-hidden" :id="`message-${item.ID}`">
<div class="bg-slate-100 p-2 md:p-4">
<div class="mb-2 font-semibold text-right text-gray-400">#{{ item.ID }}</div>
<div v-if="item.Content.length > 0" class="text-wrap font-sans" v-html="processedContent"></div>
<div v-if="item.Media.length > 0" class="mt-2 md:mt-4">

View File

@@ -0,0 +1,78 @@
<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>

View File

@@ -1,65 +1,17 @@
<template>
<h1 class="mb-4 font-semibold text-xl">{{ channel.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-2 hover:bg-slate-100 rounded border text-xl font-bold w-full"
@click="loadMore">LoadMore</button>
</div>
</template>
<MessageList :getTitle="getTitle" routeName="channel-messages" :getMessages="getChannelMessages" />
</template>
<script setup>
import ListItem from "@/components/ListItem.vue";
import MessageList from "@/components/MessageList.vue";
import { getChannel } from "@/services/channels";
import { getChannelMessages } from "@/services/messages";
import { nextTick, onMounted, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useRoute } from "vue-router";
const route = useRoute();
const router = useRouter();
const channel = ref({});
const messages = ref([]);
const loadMore = async () => {
// router goto next page
// offset is last message ID
// page scroll to top with animation
window.scrollTo({ top: 0, behavior: "smooth" });
const offset = messages.value[messages.value.length - 1].ID
messages.value = [];
router.push({
name: "channel-messages",
params: {
channel: route.params.channel,
offset: offset,
},
});
// nextTick 干什么用的?
nextTick(async () => {
messages.value = await getChannelMessages(route.params.channel, { offset: offset });
console.log("messages", messages.value);
});
const getTitle = async () => {
const channel = await getChannel(route.params.channel);
return channel.Title;
}
const loadData = async () => {
// get channel info
channel.value = await getChannel(route.params.channel);
console.log("channel", channel.value);
// get channel messages
messages.value = await getChannelMessages(route.params.channel, { offset: route.params.offset });
console.log("messages", messages.value);
}
watch(route, loadData);
onMounted(loadData);
</script>

View File

@@ -1,56 +1,10 @@
<template>
<h1 class="mb-4 font-semibold text-xl">Favorites</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>
<MessageList :getTitle="async () => 'Favorite'" routeName="favorite-messages" :getMessages="getMessages" />
</template>
<script setup>
import ListItem from "@/components/ListItem.vue";
import MessageList from "@/components/MessageList.vue";
import { getFavoriteMessages } from "@/services/messages";
import { nextTick, onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
const messages = ref([]);
const loadMore = async () => {
// router goto next page
// offset is last message ID
// page scroll to top with animation
window.scrollTo({ top: 0, behavior: "smooth" });
const offset = messages.value[messages.value.length - 1].ID
messages.value = [];
router.push({
name: "favorite-messages",
params: {
channel: route.params.channel,
offset: offset,
},
});
nextTick(async () => {
messages.value = await getFavoriteMessages({ offset: offset });
console.log("messages", messages.value);
});
}
const loadData = async () => {
messages.value = await getFavoriteMessages({ offset: route.params.offset });
}
watch(route, loadData);
onMounted(loadData);
const getMessages = async (ch, params) => await getFavoriteMessages(params)
</script>

View File

@@ -1,12 +1,21 @@
import { fileURLToPath, URL } from 'node:url'
import { fileURLToPath, URL } from 'node:url';
import vue from '@vitejs/plugin-vue';
import AutoImport from 'unplugin-auto-import/vite';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
imports: [
'vue',
'vue-router',
'pinia'
],
}),
],
resolve: {
alias: {