更新了搜索功能 (终于!) 1.1.0 版本 Release!
All checks were successful
Build / build-and-test (push) Successful in 33s
All checks were successful
Build / build-and-test (push) Successful in 33s
This commit is contained in:
62
src/views/About.md
Normal file
62
src/views/About.md
Normal file
@ -0,0 +1,62 @@
|
||||
<script setup>
|
||||
import About from '../texts/about.md'
|
||||
import FunAnimation from '../components/FunAnimation.vue'
|
||||
|
||||
import 'mdui/components/avatar.js'
|
||||
/*import { onBeforeMount, onMounted, onUnmounted, onBeforeUnmount, onActivated, onDeactivated } from 'vue'
|
||||
console.log('Setup')
|
||||
onBeforeMount(() => console.log('Before mount'))
|
||||
onMounted(() => console.log('Mounted'))
|
||||
onDeactivated(() => console.log('Deactivated'))
|
||||
onActivated(() => console.log('Activated'))
|
||||
onBeforeUnmount(() => console.log('Before unmount'))
|
||||
onUnmounted(() => console.log('Unmounted'))*/
|
||||
</script>
|
||||
|
||||
# 关于
|
||||
|
||||
这是什么, 有口舍用 ?
|
||||
|
||||
概述
|
||||
---
|
||||
一个 AO3 镜像站, 优化了 UI/UX
|
||||
|
||||
作者 (1)
|
||||
---
|
||||
- [UnknownMp](https://www.unknownmp.top)
|
||||
<mdui-avatar src="https://cdn.unknownmp.top/website/logo.jpg"></mdui-avatar>
|
||||
|
||||
---
|
||||
|
||||
源代码
|
||||
---
|
||||
- 前端 Vue3 + Vite 6 (SSR) + MDUI 2 [Gitea](https://git.unknownmp.top/default/ao3-mirror-ssr)
|
||||
- 后端 FastAPI + HttpX + LXML *(暂无仓库)*
|
||||
|
||||
组件库与工具链
|
||||
---
|
||||
### 前端
|
||||
- MDUI 2 [mdui.org](https://mdui.org)
|
||||
- Vue 3 [vuejs.org](https://vuejs.org)
|
||||
- Vite 6 [vite.dev](https://vite.dev)
|
||||
### 后端
|
||||
- FastAPI [fastapi.tiangolo.com](https://fastapi.tiangolo.com/)
|
||||
- HttpX [python-httpx.org](https://www.python-httpx.org/)
|
||||
- LXML [lxml.de](https://lxml.de/)
|
||||
|
||||
废弃特性 {#deprecated}
|
||||
---
|
||||
|
||||
### 书签 {#deprecated-feature-bookmark}
|
||||
|
||||
因为底层 IndexedDB 更新困难和作品段落解析困难问题, 所以在 [**v1.0.7**](https://git.unknownmp.top/default/ao3-mirror-ssr/releases/tag/v1.0.7) 以后的版本废弃了书签机制
|
||||
|
||||
---
|
||||
|
||||
其他
|
||||
---
|
||||
本站支持 "Server Side Rendering" by Vite SSR
|
||||
|
||||
CDN by Cloudflare (赛博佛祖😭)
|
||||
|
||||
<FunAnimation />
|
@ -1,19 +0,0 @@
|
||||
<script setup>
|
||||
import About from '../texts/about.md'
|
||||
import FunAnimation from '../components/FunAnimation.vue'
|
||||
|
||||
import 'mdui/components/avatar.js'
|
||||
/*import { onBeforeMount, onMounted, onUnmounted, onBeforeUnmount, onActivated, onDeactivated } from 'vue'
|
||||
console.log('Setup')
|
||||
onBeforeMount(() => console.log('Before mount'))
|
||||
onMounted(() => console.log('Mounted'))
|
||||
onDeactivated(() => console.log('Deactivated'))
|
||||
onActivated(() => console.log('Activated'))
|
||||
onBeforeUnmount(() => console.log('Before unmount'))
|
||||
onUnmounted(() => console.log('Unmounted'))*/
|
||||
</script>
|
||||
<template>
|
||||
<About/>
|
||||
<FunAnimation />
|
||||
</template>
|
||||
|
@ -9,9 +9,6 @@ import Intro from '../texts/intro.md'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const err = ref(false)
|
||||
const srcText = ref(null)
|
||||
|
||||
function convert(from) {
|
||||
if( Number(from) ) {
|
||||
return {
|
||||
@ -20,7 +17,6 @@ function convert(from) {
|
||||
}
|
||||
} else if (from.includes('https://archiveofourown.org/works/')) {
|
||||
const sid = from.split('https://archiveofourown.org/works/')[1];
|
||||
console.log(sid)
|
||||
if ( sid ) {
|
||||
const id = Number(sid)
|
||||
if (id) {
|
||||
@ -41,16 +37,15 @@ function convert(from) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return { type: null }
|
||||
return { type: 'f', key: from }
|
||||
}
|
||||
|
||||
function onConvert(data) {
|
||||
const { type, id, cid } = convert(data.src)
|
||||
const { type, id, cid, key } = convert(data.src)
|
||||
if (type == null) {
|
||||
err.value = true
|
||||
srcText.value?.focus()
|
||||
} else if ( type == 'f') {
|
||||
router.push(`/search/simple?keyword=${encodeURIComponent(key)}`)
|
||||
} else {
|
||||
err.value = false
|
||||
if (cid) router.push(`/work/${id}/${cid}`)
|
||||
else router.push(`/work/${id}`)
|
||||
}
|
||||
@ -60,14 +55,14 @@ function onConvert(data) {
|
||||
|
||||
<template>
|
||||
<img style="display: block; margin: 0px auto 10px;" height="200px" alt="logo" src="/favicon.svg" />
|
||||
<Intro />
|
||||
<br/><Hr/>
|
||||
<h1>欢迎来到 AO3 Mirror! 👋👋</h1>
|
||||
<p>一个基于重构渲染的 AO3 镜像站</p>
|
||||
<Hr />
|
||||
<section id="converter">
|
||||
<h2>链接转换</h2>
|
||||
<p>输入完整链接或者 ID</p>
|
||||
<p>AO3 链接 或 关键词搜索</p>
|
||||
<Form @submit="onConvert"><ClientOnly>
|
||||
<mdui-text-field variant="filled" label="链接" name="src" placeholder="https://archiveofourown.org/works/114514" ref='srcText'>
|
||||
<span v-if='err' slot="helper" class='warn-text'>链接格式错误!</span>
|
||||
<mdui-text-field variant="filled" label="链接 / 关键词" name="src">
|
||||
</mdui-text-field><br/>
|
||||
<div style="display: flex">
|
||||
<div style="flex-grow: 1"></div>
|
||||
@ -78,4 +73,7 @@ function onConvert(data) {
|
||||
<input type="submit" />
|
||||
</template></ClientOnly></Form>
|
||||
</section>
|
||||
<Hr/>
|
||||
<Intro />
|
||||
</template>
|
||||
|
||||
|
62
src/views/SimpleSearch.vue
Normal file
62
src/views/SimpleSearch.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onServerPrefetch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import 'mdui/components/text-field.js'
|
||||
import 'mdui/components/card.js'
|
||||
|
||||
import { escapeAndFormatText } from '../utils.js'
|
||||
import { useSimpleSearchState } from '../stores/search.js'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const inputField = ref('')
|
||||
|
||||
const simpleSearchState = useSimpleSearchState()
|
||||
|
||||
onServerPrefetch(async () => {
|
||||
if (route.query.keyword) {
|
||||
await simpleSearchState.start(route.query.keyword)
|
||||
}
|
||||
console.log(simpleSearchState.result[0])
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
inputField.value = route.query.keyword || ''
|
||||
if (inputField.value && simpleSearchState != 'ssrready') simpleSearchState.start(inputField.value)
|
||||
})
|
||||
|
||||
function onSubmit(data) {
|
||||
if (simpleSearchState) simpleSearchState.start(data.src)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>搜索</h1>
|
||||
<Form @submit="onSubmit"><ClientOnly>
|
||||
<mdui-text-field variant="filled" :value="inputField" label="链接 / 关键词" name="src">
|
||||
</mdui-text-field><br/>
|
||||
<div style="display: flex">
|
||||
<div style="flex-grow: 1"></div>
|
||||
<mdui-button type="submit">-></mdui-button>
|
||||
</div>
|
||||
<template #ssr>
|
||||
<input type="text" id="src" name="src" />
|
||||
<input type="submit" />
|
||||
</template></ClientOnly></Form><Hr />
|
||||
<p>State: {{ simpleSearchState.state }}</p><Hr/>
|
||||
<template v-if="simpleSearchState.result" v-for="work in simpleSearchState.result" :key="work.workId">
|
||||
<ClientOnly><mdui-card style="margin: 8px 0px;"><article>
|
||||
<router-link :to="`/work/${work.workId}`"><h3>{{ work.title }}</h3></router-link>
|
||||
<h4>{{ work.pseud }}</h4>
|
||||
<Hr />
|
||||
<p v-html="escapeAndFormatText(work.summary)"></p>
|
||||
</article></mdui-card><template #ssr>
|
||||
<router-link :to="`/work/${work.workId}`"><h3>{{ work.title }}</h3></router-link>
|
||||
<h4>{{ work.pseud }}</h4>
|
||||
<p>{{ work.summary }}</p>
|
||||
<Hr />
|
||||
</template></ClientOnly>
|
||||
</template>
|
||||
</template>
|
@ -168,8 +168,8 @@ onBeforeUnmount(() => {
|
||||
<a @click="$router.back()">返回</a>
|
||||
</template>
|
||||
<template v-if="workReadState.state == 'ready'">
|
||||
<h1>{{ workReadState.title }}</h1>
|
||||
<h2>{{ workReadState.pesud }}</h2>
|
||||
<h2>{{ workReadState.title }}</h2>
|
||||
<h4>{{ workReadState.pesud }}</h4>
|
||||
<dl>
|
||||
<template v-if="workReadState.category"><dt>作品圈</dt><ul>
|
||||
<li v-for="item in workReadState.category" :key="item">
|
||||
|
Reference in New Issue
Block a user