feat: 移动端功能优化 (#132)

* feat: 移动端双击返回顶部

* feat: 深色模式下的底色

* feat: 移动端标题返回顶部和返回底部
main
Redon 2 years ago committed by GitHub
parent 1406292405
commit 90f6989445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-cmn-Hans"> <html lang="zh-cmn-Hans">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" type="image/svg+xml" href="/favicon.svg"> <link rel="icon" type="image/svg+xml" href="/favicon.svg">
@ -9,7 +8,7 @@
<title>ChatGPT Web</title> <title>ChatGPT Web</title>
</head> </head>
<body> <body class="dark:bg-black">
<div id="app"> <div id="app">
<style> <style>
.loading-wrap { .loading-wrap {

@ -6,6 +6,13 @@ export const useChatStore = defineStore('chat-store', {
state: (): Chat.ChatState => getLocalState(), state: (): Chat.ChatState => getLocalState(),
getters: { getters: {
getChatHistoryByCurrentActive(state: Chat.ChatState) {
const index = state.history.findIndex(item => item.uuid === state.active)
if (index !== -1)
return state.history[index]
return null
},
getChatByUuid(state: Chat.ChatState) { getChatByUuid(state: Chat.ChatState) {
return (uuid?: number) => { return (uuid?: number) => {
if (uuid) if (uuid)
@ -68,6 +75,18 @@ export const useChatStore = defineStore('chat-store', {
return await this.reloadRoute(uuid) return await this.reloadRoute(uuid)
}, },
getChatByUuidAndIndex(uuid: number, index: number) {
if (!uuid || uuid === 0) {
if (this.chat.length)
return this.chat[0].data[index]
return null
}
const chatIndex = this.chat.findIndex(item => item.uuid === uuid)
if (chatIndex !== -1)
return this.chat[chatIndex].data[index]
return null
},
addChatByUuid(uuid: number, chat: Chat.Chat) { addChatByUuid(uuid: number, chat: Chat.Chat) {
if (!uuid || uuid === 0) { if (!uuid || uuid === 0) {
if (this.history.length === 0) { if (this.history.length === 0) {

@ -310,7 +310,12 @@ onUnmounted(() => {
<template> <template>
<div class="flex flex-col h-full" :class="wrapClass"> <div class="flex flex-col h-full" :class="wrapClass">
<main class="flex-1 overflow-hidden"> <main class="flex-1 overflow-hidden">
<div ref="scrollRef" class="h-full overflow-hidden overflow-y-auto" :class="[isMobile ? 'p-2' : 'p-4']"> <div
id="scrollRef"
ref="scrollRef"
class="h-full overflow-hidden overflow-y-auto"
:class="[isMobile ? 'p-2' : 'p-4']"
>
<template v-if="!dataSources.length"> <template v-if="!dataSources.length">
<div class="flex items-center justify-center mt-4 text-center text-neutral-300"> <div class="flex items-center justify-center mt-4 text-center text-neutral-300">
<SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" /> <SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" />

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue' import { computed, nextTick } from 'vue'
import { SvgIcon } from '@/components/common' import { SvgIcon } from '@/components/common'
import { useAppStore, useChatStore } from '@/store' import { useAppStore, useChatStore } from '@/store'
@ -7,25 +7,48 @@ const appStore = useAppStore()
const chatStore = useChatStore() const chatStore = useChatStore()
const collapsed = computed(() => appStore.siderCollapsed) const collapsed = computed(() => appStore.siderCollapsed)
const currentChatHistory = computed(() => chatStore.getChatHistoryByCurrentActive)
function handleAdd() {
chatStore.addHistory({ title: 'New Chat', uuid: Date.now(), isEdit: false })
}
function handleUpdateCollapsed() { function handleUpdateCollapsed() {
appStore.setSiderCollapsed(!collapsed.value) appStore.setSiderCollapsed(!collapsed.value)
} }
function onScrollToTop() {
const scrollRef = document.querySelector('#scrollRef')
if (scrollRef)
nextTick(() => scrollRef.scrollTop = 0)
}
function onScrollToBottom() {
const scrollRef = document.querySelector('#scrollRef')
if (scrollRef)
nextTick(() => scrollRef.scrollTop = scrollRef.scrollHeight)
}
</script> </script>
<template> <template>
<header class="fixed top-0 left-0 right-0 z-30 border-b dark:border-neutral-800 bg-white/80 dark:bg-black/20 backdrop-blur"> <header
class="fixed top-0 left-0 right-0 z-30 border-b dark:border-neutral-800 bg-white/80 dark:bg-black/20 backdrop-blur"
>
<div class="relative flex items-center justify-between h-14"> <div class="relative flex items-center justify-between h-14">
<button class="flex items-center justify-center w-11 h-11" @click="handleUpdateCollapsed"> <button
class="flex items-center justify-center w-11 h-11"
@click="handleUpdateCollapsed"
>
<SvgIcon v-if="collapsed" class="text-2xl" icon="ri:align-justify" /> <SvgIcon v-if="collapsed" class="text-2xl" icon="ri:align-justify" />
<SvgIcon v-else class="text-2xl" icon="ri:align-right" /> <SvgIcon v-else class="text-2xl" icon="ri:align-right" />
</button> </button>
<button class="flex items-center justify-center w-11 h-11" @click="handleAdd"> <h1
<SvgIcon class="text-2xl" icon="ri:add-fill" /> class="flex-1 px-4 overflow-hidden text-center cursor-pointer select-none text-ellipsis whitespace-nowrap"
@dblclick="onScrollToTop"
>
{{ currentChatHistory?.title ?? '' }}
</h1>
<button
class="flex items-center justify-center w-11 h-11"
@click="onScrollToBottom"
>
<SvgIcon class="text-2xl" icon="ri:arrow-down-s-line" />
</button> </button>
</div> </div>
</header> </header>

Loading…
Cancel
Save