mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-05-19 04:49:36 +08:00
feat: 初始化文档信息
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@
|
||||
"@electron-toolkit/preload": "^3.0.1",
|
||||
"@electron-toolkit/utils": "^4.0.0",
|
||||
"@nuxt/ui": "^4.2.1",
|
||||
"@vueuse/core": "^14.0.0",
|
||||
"@vueuse/core": "^13.9.0",
|
||||
"axios": "^1.13.2",
|
||||
"dayjs": "^1.11.19",
|
||||
"electron-updater": "^6.6.2",
|
||||
|
||||
Generated
+2
-28
@@ -18,8 +18,8 @@ importers:
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1(@babel/parser@7.28.5)(axios@1.13.2)(embla-carousel@8.6.0)(typescript@5.9.2)(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.2)))(vue@3.5.25(typescript@5.9.2))
|
||||
'@vueuse/core':
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0(vue@3.5.25(typescript@5.9.2))
|
||||
specifier: ^13.9.0
|
||||
version: 13.9.0(vue@3.5.25(typescript@5.9.2))
|
||||
axios:
|
||||
specifier: ^1.13.2
|
||||
version: 1.13.2
|
||||
@@ -1189,11 +1189,6 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^3.5.0
|
||||
|
||||
'@vueuse/core@14.0.0':
|
||||
resolution: {integrity: sha512-d6tKRWkZE8IQElX2aHBxXOMD478fHIYV+Dzm2y9Ag122ICBpNKtGICiXKOhWU3L1kKdttDD9dCMS4bGP3jhCTQ==}
|
||||
peerDependencies:
|
||||
vue: ^3.5.0
|
||||
|
||||
'@vueuse/integrations@13.9.0':
|
||||
resolution: {integrity: sha512-SDobKBbPIOe0cVL7QxMzGkuUGHvWTdihi9zOrrWaWUgFKe15cwEcwfWmgrcNzjT6kHnNmWuTajPHoIzUjYNYYQ==}
|
||||
peerDependencies:
|
||||
@@ -1245,9 +1240,6 @@ packages:
|
||||
'@vueuse/metadata@13.9.0':
|
||||
resolution: {integrity: sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg==}
|
||||
|
||||
'@vueuse/metadata@14.0.0':
|
||||
resolution: {integrity: sha512-6yoGqbJcMldVCevkFiHDBTB1V5Hq+G/haPlGIuaFZHpXC0HADB0EN1ryQAAceiW+ryS3niUwvdFbGiqHqBrfVA==}
|
||||
|
||||
'@vueuse/shared@10.11.1':
|
||||
resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
|
||||
|
||||
@@ -1259,11 +1251,6 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^3.5.0
|
||||
|
||||
'@vueuse/shared@14.0.0':
|
||||
resolution: {integrity: sha512-mTCA0uczBgurRlwVaQHfG0Ja7UdGe4g9mwffiJmvLiTtp1G4AQyIjej6si/k8c8pUwTfVpNufck+23gXptPAkw==}
|
||||
peerDependencies:
|
||||
vue: ^3.5.0
|
||||
|
||||
'@xmldom/xmldom@0.8.11':
|
||||
resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@@ -4886,13 +4873,6 @@ snapshots:
|
||||
'@vueuse/shared': 13.9.0(vue@3.5.25(typescript@5.9.2))
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
|
||||
'@vueuse/core@14.0.0(vue@3.5.25(typescript@5.9.2))':
|
||||
dependencies:
|
||||
'@types/web-bluetooth': 0.0.21
|
||||
'@vueuse/metadata': 14.0.0
|
||||
'@vueuse/shared': 14.0.0(vue@3.5.25(typescript@5.9.2))
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
|
||||
'@vueuse/integrations@13.9.0(axios@1.13.2)(fuse.js@7.1.0)(vue@3.5.25(typescript@5.9.2))':
|
||||
dependencies:
|
||||
'@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.2))
|
||||
@@ -4908,8 +4888,6 @@ snapshots:
|
||||
|
||||
'@vueuse/metadata@13.9.0': {}
|
||||
|
||||
'@vueuse/metadata@14.0.0': {}
|
||||
|
||||
'@vueuse/shared@10.11.1(vue@3.5.25(typescript@5.9.2))':
|
||||
dependencies:
|
||||
vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.2))
|
||||
@@ -4927,10 +4905,6 @@ snapshots:
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
|
||||
'@vueuse/shared@14.0.0(vue@3.5.25(typescript@5.9.2))':
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
|
||||
'@xmldom/xmldom@0.8.11': {}
|
||||
|
||||
abbrev@1.1.1: {}
|
||||
|
||||
Vendored
+3
@@ -14,11 +14,13 @@ declare module 'vue' {
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
UApp: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/App.vue')['default']
|
||||
UAvatar: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Avatar.vue')['default']
|
||||
UBadge: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Badge.vue')['default']
|
||||
UButton: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Button.vue')['default']
|
||||
UCard: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Card.vue')['default']
|
||||
UCheckbox: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Checkbox.vue')['default']
|
||||
UFormField: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/FormField.vue')['default']
|
||||
UIcon: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/vue/components/Icon.vue')['default']
|
||||
UInput: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Input.vue')['default']
|
||||
UModal: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Modal.vue')['default']
|
||||
UProgress: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Progress.vue')['default']
|
||||
@@ -28,5 +30,6 @@ declare module 'vue' {
|
||||
UTabs: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Tabs.vue')['default']
|
||||
UTextarea: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Textarea.vue')['default']
|
||||
UToaster: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Toaster.vue')['default']
|
||||
UTooltip: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Tooltip.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<script setup lang="ts">
|
||||
import { useChatStore } from '@/stores/chat'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const chatStore = useChatStore()
|
||||
const { sessions, currentSessionId } = storeToRefs(chatStore)
|
||||
|
||||
const isCollapsed = ref(false)
|
||||
|
||||
function toggleSidebar() {
|
||||
isCollapsed.value = !isCollapsed.value
|
||||
}
|
||||
|
||||
function handleImport() {
|
||||
// TODO: Implement import logic
|
||||
console.log('Import clicked')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex h-full flex-col border-r border-gray-200 bg-gray-50 transition-all duration-300 ease-in-out dark:border-gray-800 dark:bg-gray-900"
|
||||
:class="[isCollapsed ? 'w-20' : 'w-72']"
|
||||
>
|
||||
<!-- Top Section -->
|
||||
<div class="flex flex-col p-4">
|
||||
<!-- Header / Toggle -->
|
||||
<div class="mb-6 flex items-center" :class="[isCollapsed ? 'justify-center' : 'justify-between']">
|
||||
<div v-if="!isCollapsed" class="text-lg font-semibold text-gray-900 dark:text-white">
|
||||
ChatLens
|
||||
</div>
|
||||
<UButton
|
||||
icon="i-heroicons-bars-3"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
@click="toggleSidebar"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- New Analysis Button -->
|
||||
<UTooltip :text="isCollapsed ? '新建分析' : ''" :popper="{ placement: 'right' }">
|
||||
<UButton
|
||||
block
|
||||
class="transition-all"
|
||||
:class="[isCollapsed ? 'px-0' : '']"
|
||||
color="gray"
|
||||
variant="solid"
|
||||
:icon="isCollapsed ? 'i-heroicons-plus' : 'i-heroicons-plus'"
|
||||
:label="isCollapsed ? '' : '新建分析'"
|
||||
@click="handleImport"
|
||||
/>
|
||||
</UTooltip>
|
||||
</div>
|
||||
|
||||
<!-- Session List -->
|
||||
<div class="flex-1 overflow-y-auto px-3">
|
||||
<div v-if="sessions.length === 0 && !isCollapsed" class="py-8 text-center text-sm text-gray-500">
|
||||
暂无记录
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<div v-if="!isCollapsed && sessions.length > 0" class="mb-2 px-2 text-xs font-medium text-gray-500">
|
||||
最近
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-for="session in sessions"
|
||||
:key="session.id"
|
||||
class="flex w-full items-center rounded-full p-2 text-left transition-colors hover:bg-gray-200 dark:hover:bg-gray-800"
|
||||
:class="[
|
||||
currentSessionId === session.id ? 'bg-primary-100 text-primary-900 dark:bg-primary-900/30 dark:text-primary-100' : 'text-gray-700 dark:text-gray-200',
|
||||
isCollapsed ? 'justify-center' : ''
|
||||
]"
|
||||
@click="chatStore.selectSession(session.id)"
|
||||
>
|
||||
<UAvatar
|
||||
:src="session.avatar"
|
||||
:alt="session.name"
|
||||
size="sm"
|
||||
:class="[isCollapsed ? '' : 'mr-3']"
|
||||
/>
|
||||
|
||||
<div v-if="!isCollapsed" class="min-w-0 flex-1">
|
||||
<p class="truncate text-sm font-medium">
|
||||
{{ session.name }}
|
||||
</p>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer (Optional settings or help) -->
|
||||
<div class="border-t border-gray-200 p-4 dark:border-gray-800">
|
||||
<UTooltip :text="isCollapsed ? '设置' : ''" :popper="{ placement: 'right' }">
|
||||
<UButton
|
||||
block
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
icon="i-heroicons-cog-6-tooth"
|
||||
:label="isCollapsed ? '' : '设置'"
|
||||
:class="[isCollapsed ? 'px-0' : 'justify-start']"
|
||||
/>
|
||||
</UTooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,93 @@
|
||||
<script setup lang="ts">
|
||||
const features = [
|
||||
{
|
||||
icon: '🏆',
|
||||
title: '活跃度分析',
|
||||
desc: '谁是群里的潜水王?',
|
||||
color: 'text-yellow-500',
|
||||
bg: 'bg-yellow-50',
|
||||
delay: '0ms',
|
||||
},
|
||||
{
|
||||
icon: '☁️',
|
||||
title: '词云生成',
|
||||
desc: '大家最爱说什么?',
|
||||
color: 'text-blue-500',
|
||||
bg: 'bg-blue-50',
|
||||
delay: '100ms',
|
||||
},
|
||||
{
|
||||
icon: '❤️',
|
||||
title: '情感分析',
|
||||
desc: '群聊氛围怎么样?',
|
||||
color: 'text-pink-500',
|
||||
bg: 'bg-pink-50',
|
||||
delay: '200ms',
|
||||
},
|
||||
]
|
||||
|
||||
function handleImport() {
|
||||
console.log('Import clicked')
|
||||
}
|
||||
|
||||
function openTutorial(type: 'ios' | 'android') {
|
||||
console.log('Tutorial:', type)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative flex h-full w-full overflow-hidden bg-white">
|
||||
<!-- Content Container -->
|
||||
<div class="relative z-10 flex h-full w-full flex-col items-center justify-center px-4">
|
||||
<!-- Hero Section -->
|
||||
<div class="mb-12 text-center">
|
||||
<div class="mb-6 inline-flex animate-bounce items-center justify-center rounded-3xl bg-white p-4 shadow-lg shadow-purple-100 ring-1 ring-gray-100">
|
||||
<UIcon name="i-heroicons-sparkles" class="h-8 w-8 text-purple-500" />
|
||||
</div>
|
||||
<h1 class="mb-4 bg-gradient-to-r from-purple-600 via-pink-500 to-orange-400 bg-clip-text text-5xl font-black tracking-tight text-transparent sm:text-6xl">
|
||||
探索你的群聊记忆
|
||||
</h1>
|
||||
<p class="text-lg font-medium text-gray-500">
|
||||
ChatLens 帮你发现那些被遗忘的有趣瞬间
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Feature Cards -->
|
||||
<div class="mb-12 grid max-w-4xl grid-cols-1 gap-6 sm:grid-cols-3">
|
||||
<div
|
||||
v-for="feature in features"
|
||||
:key="feature.title"
|
||||
class="group relative transform cursor-default rounded-2xl border border-gray-100 bg-white p-6 shadow-sm transition-all duration-300 hover:-translate-y-2 hover:shadow-xl hover:shadow-purple-500/10"
|
||||
:style="{ animationDelay: feature.delay }"
|
||||
>
|
||||
<div class="mb-4 text-4xl transition-transform duration-300 group-hover:scale-110">{{ feature.icon }}</div>
|
||||
<h3 class="mb-2 text-lg font-bold text-gray-900">{{ feature.title }}</h3>
|
||||
<p class="text-sm text-gray-500">{{ feature.desc }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="flex flex-col items-center space-y-8">
|
||||
<button
|
||||
class="group relative inline-flex items-center justify-center rounded-full bg-gradient-to-r from-purple-500 to-pink-500 px-8 py-4 text-lg font-bold text-white shadow-lg shadow-purple-500/30 transition-all duration-300 hover:scale-105 hover:shadow-purple-500/50 focus:outline-none focus:ring-4 focus:ring-purple-500/30"
|
||||
@click="handleImport"
|
||||
>
|
||||
<UIcon name="i-heroicons-arrow-up-tray" class="mr-2 h-5 w-5 transition-transform group-hover:-translate-y-1" />
|
||||
立即导入聊天记录
|
||||
</button>
|
||||
|
||||
<div class="flex items-center space-x-6 text-sm font-medium text-gray-400">
|
||||
<button class="flex items-center transition-colors hover:text-gray-600" @click="openTutorial('ios')">
|
||||
<UIcon name="i-simple-icons-apple" class="mr-1.5 h-4 w-4" />
|
||||
iOS 教程
|
||||
</button>
|
||||
<span class="h-1 w-1 rounded-full bg-gray-300"></span>
|
||||
<button class="flex items-center transition-colors hover:text-gray-600" @click="openTutorial('android')">
|
||||
<UIcon name="i-simple-icons-android" class="mr-1.5 h-4 w-4" />
|
||||
Android 教程
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
+22
-47
@@ -1,55 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import { useChatStore } from '@/stores/chat'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import Sidebar from '@/components/Sidebar.vue'
|
||||
import WelcomeGuide from '@/components/WelcomeGuide.vue'
|
||||
|
||||
const chatStore = useChatStore()
|
||||
const { currentSessionId } = storeToRefs(chatStore)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col items-center justify-center p-8">
|
||||
<div class="text-center max-w-2xl">
|
||||
<!-- Logo / 标题 -->
|
||||
<div class="mb-8">
|
||||
<div class="w-20 h-20 mx-auto mb-6 bg-primary-500 rounded-2xl flex items-center justify-center">
|
||||
<span class="text-4xl">💬</span>
|
||||
<div class="flex h-screen w-full overflow-hidden bg-white dark:bg-gray-950">
|
||||
<!-- Sidebar -->
|
||||
<Sidebar />
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="flex-1 overflow-hidden">
|
||||
<template v-if="!currentSessionId">
|
||||
<WelcomeGuide />
|
||||
</template>
|
||||
<template v-else>
|
||||
<!-- TODO: Analysis Dashboard -->
|
||||
<div class="flex h-full items-center justify-center text-gray-500">
|
||||
分析仪表盘 (开发中...)
|
||||
</div>
|
||||
<h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
ChatLens
|
||||
</h1>
|
||||
<p class="text-lg text-gray-600 dark:text-gray-400">
|
||||
聊天记录分析工具 - 让你更好地了解你的聊天数据
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 功能入口 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8">
|
||||
<UCard class="hover:shadow-lg transition-shadow cursor-pointer">
|
||||
<div class="text-center p-4">
|
||||
<div class="text-3xl mb-3">📁</div>
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white mb-2">导入聊天记录</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">支持多种格式的聊天记录导入</p>
|
||||
</div>
|
||||
</UCard>
|
||||
<UCard class="hover:shadow-lg transition-shadow cursor-pointer">
|
||||
<div class="text-center p-4">
|
||||
<div class="text-3xl mb-3">📊</div>
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white mb-2">数据分析</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">可视化展示聊天数据统计</p>
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
<!-- 快速开始按钮 -->
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<UButton size="lg" color="primary">
|
||||
开始使用
|
||||
</UButton>
|
||||
<UButton size="lg" variant="outline" to="/ui">
|
||||
组件演示
|
||||
</UButton>
|
||||
</div>
|
||||
|
||||
<!-- 版本信息 -->
|
||||
<p class="mt-12 text-sm text-gray-400">
|
||||
v0.1.0 · Built with Vue 3 + Electron + Nuxt UI
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export interface ChatSession {
|
||||
id: string
|
||||
name: string
|
||||
avatar?: string
|
||||
lastMessage?: string
|
||||
timestamp: number
|
||||
}
|
||||
|
||||
export const useChatStore = defineStore(
|
||||
'chat',
|
||||
() => {
|
||||
const sessions = ref<ChatSession[]>([])
|
||||
const currentSessionId = ref<string | null>(null)
|
||||
|
||||
function addSession(session: ChatSession) {
|
||||
sessions.value.push(session)
|
||||
currentSessionId.value = session.id
|
||||
}
|
||||
|
||||
function removeSession(id: string) {
|
||||
const index = sessions.value.findIndex((s) => s.id === id)
|
||||
if (index !== -1) {
|
||||
sessions.value.splice(index, 1)
|
||||
if (currentSessionId.value === id) {
|
||||
currentSessionId.value = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectSession(id: string) {
|
||||
currentSessionId.value = id
|
||||
}
|
||||
|
||||
return {
|
||||
sessions,
|
||||
currentSessionId,
|
||||
addSession,
|
||||
removeSession,
|
||||
selectSession,
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: true,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user