perf(views): 优化页面收缩功能

优化连接错误提示
优化自动登录时可中断登录
This commit is contained in:
nongyehong 2024-04-27 05:28:24 +08:00
parent 94d2cb1fec
commit 31f7e1732c
16 changed files with 274 additions and 157 deletions

View File

@ -7,7 +7,7 @@
<title>HuLa</title>
<!--引入iconpark图标库-->
<script defer src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/svg_30895_78.2ef5ae05e210de3f66b0fe5c58a7a130.js"></script>
<script defer src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/svg_30895_79.b97eb7e69b543ed2cec6ad36e086c40b.js"></script>
</head>
<body>

View File

@ -24,10 +24,7 @@
class="flex flex-col w-full"
:class="[{ 'items-end': item.accountId === userId }, isGroup ? 'gap-18px' : 'gap-2px']">
<!-- 信息时间(单聊) -->
<div
v-if="!isGroup"
class="text-(12px #909090) h-12px w-fit select-none"
:class="item.accountId === userId ? 'pr-42px' : 'pl-42px'">
<div v-if="!isGroup" class="text-(12px #909090) h-12px w-fit select-none" :class="getTimePosition(item)">
<Transition name="fade">
<span v-if="hoverBubble.key === item.key">
{{ new Date().toLocaleString() }}
@ -348,6 +345,12 @@ watchEffect(() => {
activeItemRef.value = { ...activeItem }
})
/** 计算单聊时间戳显示的位置 */
const getTimePosition = (item: any) => {
const pxVal = activeReply.value === item.key ? '68px' : '42px'
return item.accountId === userId.value ? `pr-${pxVal}` : `pl-${pxVal}`
}
//
const handleMouseEnter = (key: any) => {
// 1600key
@ -542,13 +545,4 @@ onUnmounted(() => {
<style scoped lang="scss">
@import '@/styles/scss/chat-main';
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.4s ease-in-out;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@ -1,5 +1,10 @@
<template>
<main data-tauri-drag-region class="resizable select-none" :style="{ width: width + 'px' }">
<main
data-tauri-drag-region
id="center"
class="resizable select-none flex flex-col"
:style="{ width: `${initWidth}px` }">
<div class="resize-handle" @mousedown="initDrag"></div>
<ActionBar
class="absolute right-0"
v-if="shrinkStatus"
@ -48,20 +53,47 @@ import router from '@/router'
import { MittEnum } from '@/enums'
import { appWindow } from '@tauri-apps/api/window'
// const minWidth = 160 //
// const maxWidth = 320 //
const width = ref(250) //
/** 设置最小宽度 */
const minWidth = 160
/** 设置最大宽度 */
const maxWidth = 300
/** 初始化宽度 */
const initWidth = ref(250)
/** 窗口宽度 */
const windowWidth = ref(0)
/** 是否拖拽 */
const isDrag = ref(true)
/** 当前消息 */
const currentMsg = ref()
// const startX = ref()
// const startWidth = ref()
const startX = ref()
const startWidth = ref()
const shrinkStatus = ref(false)
// todo 1. 2.
Mitt.on(MittEnum.SHRINK_WINDOW, (event) => {
shrinkStatus.value = event as boolean
width.value = 250
watchEffect(() => {
if (windowWidth.value >= 310 && windowWidth.value < 800) {
Mitt.emit(MittEnum.SHRINK_WINDOW, true)
const center = document.querySelector('#center')
center?.classList.add('flex-1')
isDrag.value = false
}
if (windowWidth.value >= 800) {
Mitt.emit(MittEnum.SHRINK_WINDOW, false)
if (currentMsg.value) {
Mitt.emit(MittEnum.MSG_BOX_SHOW, { msgBoxShow: true, ...currentMsg.value })
}
const center = document.querySelector('#center')
center?.classList.remove('flex-1')
isDrag.value = true
}
})
/** 更新窗口宽度 */
const updateWindowWidth = async () => {
const { width } = await appWindow.innerSize()
windowWidth.value = width
}
const closeMenu = (event: Event) => {
const e = event.target as HTMLInputElement
const route = router.currentRoute.value.path
@ -71,42 +103,54 @@ const closeMenu = (event: Event) => {
}
}
onMounted(() => {
/** 定义一个函数,在鼠标拖动时调用 */
const doDrag = (e: MouseEvent) => {
// 使 requestAnimationFrame
requestAnimationFrame(() => {
//
const newWidth = startWidth.value + e.clientX - startX.value
//
if (newWidth !== maxWidth) {
initWidth.value = clamp(newWidth, minWidth, maxWidth) // 使 clamp
}
})
}
/** 定义一个函数,用于将数值限制在指定的最小值和最大值之间 */
const clamp = (value: number, min: number, max: number) => {
return Math.min(Math.max(value, min), max) // 使 Math.min Math.max
}
const initDrag = (e: MouseEvent) => {
if (!isDrag.value) return
startX.value = e.clientX
startWidth.value = initWidth.value
document.addEventListener('mousemove', doDrag, false)
document.addEventListener('mouseup', stopDrag, false)
}
const stopDrag = () => {
document.removeEventListener('mousemove', doDrag, false)
document.removeEventListener('mouseup', stopDrag, false)
}
onMounted(async () => {
await updateWindowWidth()
Mitt.on(MittEnum.SHRINK_WINDOW, (event) => {
shrinkStatus.value = event as boolean
})
Mitt.on(MittEnum.MSG_BOX_SHOW, (event: any) => {
if (!event) return
currentMsg.value = event
})
window.addEventListener('resize', updateWindowWidth)
window.addEventListener('click', closeMenu, true)
})
onUnmounted(() => {
window.removeEventListener('resize', updateWindowWidth)
window.removeEventListener('click', closeMenu, true)
})
// watchEffect(() => {
// if (width.value === maxWidth) {
// Mitt.emit('shrinkWindow', false)
// }
// })
// const initDrag = (e: MouseEvent) => {
// startX.value = e.clientX
// startWidth.value = width.value
//
// document.addEventListener('mousemove', doDrag, false)
// document.addEventListener('mouseup', stopDrag, false)
// }
//
// const doDrag = (e: MouseEvent) => {
// const newWidth = startWidth.value + e.clientX - startX.value
// if (newWidth <= maxWidth && newWidth >= minWidth) {
// width.value = newWidth
// } else if (newWidth > maxWidth) {
// width.value = maxWidth
// } else if (newWidth < minWidth) {
// width.value = minWidth
// }
// }
//
// const stopDrag = () => {
// document.removeEventListener('mousemove', doDrag, false)
// document.removeEventListener('mouseup', stopDrag, false)
// }
</script>
<style scoped lang="scss">

View File

@ -10,7 +10,8 @@
right: 0;
top: 0;
bottom: 0;
width: 2px;
width: 1px;
cursor: ew-resize;
background-color: #ccc; /** 可以根据需要更改颜色 */
z-index: 9999;
background-color: var(--split-color);
}

View File

@ -13,7 +13,6 @@ import Right from './right/index.vue'
import Mitt from '@/utils/Bus'
import { MittEnum } from '@/enums'
/** todo home窗口创建的时候已经设置了resizable: true,可以调整大小了,但是还是不可以调整大小 */
const shrinkStatus = ref(false)
/**
* event默认如果没有传递值就为true所以shrinkStatus的值为false就会发生值的变化

View File

@ -1,5 +1,5 @@
<template>
<main data-tauri-drag-region class="left w-60px h-full p-[30px_6px_15px] box-border flex-col-center select-none">
<main data-tauri-drag-region class="left min-w-60px h-full p-[30px_6px_15px] box-border flex-col-center select-none">
<!-- 点击时头像内容框 -->
<n-popover
v-model:show="infoShow"

View File

@ -1,5 +1,5 @@
<template>
<main class="flex-1 bg-[--right-bg-color] h-full w-100vw">
<main class="flex-1 bg-[--right-bg-color] h-full w-100vw min-w-600px">
<ActionBar :current-label="appWindow.label" />
<!-- 需要判断当前路由是否是信息详情界面 -->
<ChatBox :active-item="activeItem" v-if="msgBoxShow && isChat && activeItem !== -1" />

View File

@ -4,13 +4,19 @@ import Mitt from '@/utils/Bus.ts'
const { VITE_WEBSOCKET_URL } = import.meta.env
/** websocket连接对象 */
let ws: WebSocket
/** 尝试重新连接数 */
let reconnectAttempts = 0
/** 最大重连次数 */
const maxReconnectAttempts = 5
/** 重连间隔 */
const reconnectDelay = 3000
/** 初始化websocket连接 */
const initWebSocket = () => {
ws = new WebSocket(`${VITE_WEBSOCKET_URL}/`)
ws.onopen = () => {
// 发送心跳
setInterval(() => {
sendToServer({
setInterval(async () => {
await sendToServer({
type: WsReqEnum.HEARTBEAT
})
}, 1000 * 60)
@ -31,10 +37,23 @@ const initWebSocket = () => {
}
}
/** 尝试重新连接 */
const retryConnection = () => {
setTimeout(() => {
if (reconnectAttempts < maxReconnectAttempts) {
reconnectAttempts++
initWebSocket()
} else {
console.error('已达到最大重连次数,放弃重连')
}
}, reconnectDelay)
}
// websocket出错重连
ws.onerror = () => {
if (ws.readyState !== WebSocket.OPEN) return
// websocket出错重连
initWebSocket()
retryConnection()
}
}
@ -44,8 +63,13 @@ const initWebSocket = () => {
* @param data json数据对象
*/
const sendToServer = (data: Record<string, any>) => {
const json = JSON.stringify(data)
ws.send(json)
if (ws.readyState === WebSocket.OPEN) {
const json = JSON.stringify(data)
ws.send(json)
return Promise.resolve(true)
} else {
return Promise.reject('网络连接失败,请检查网络设置')
}
}
export { initWebSocket, sendToServer }

View File

@ -68,7 +68,7 @@ export const setting = defineStore(StoresEnum.SETTING, {
},
/** 清空账号信息 */
clearAccount() {
this.login.accountInfo = { account: '', avatar: '', name: '', password: '', uid: '' }
this.login.accountInfo.password = ''
}
},
share: {

View File

@ -95,6 +95,15 @@
border-radius: 0;
transition: all 0.4s ease-in-out;
}
/** 时间搓显示时候的动画 */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.4s ease-in-out;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
/**! 替换ait的字体颜色 */
:deep(#aitSpan) {
@apply text-inherit cursor-pointer;

View File

@ -59,6 +59,8 @@
--reply-color: #909090;
--reply-hover: #505050;
--bg-reply-img-count: #e3e3e3;
// 主页面面板分割线样式
--split-color: #f1f1f1;
}
html[data-theme='dark'] {
@ -121,6 +123,8 @@ html[data-theme='dark'] {
--reply-color: #e3e3e3;
--reply-hover: #b1b1b1;
--bg-reply-img-count: #505050;
// 主页面面板分割线样式
--split-color: #3b3b3b;
}
/**! end */
// 线性动画

View File

@ -50,10 +50,10 @@ declare module 'vue' {
NScrollbar: typeof import('naive-ui')['NScrollbar']
NSelect: typeof import('naive-ui')['NSelect']
NSkeleton: typeof import('naive-ui')['NSkeleton']
NSplit: typeof import('naive-ui')['NSplit']
NSwitch: typeof import('naive-ui')['NSwitch']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag']
NTooltip: typeof import('naive-ui')['NTooltip']
NVirtualList: typeof import('naive-ui')['NVirtualList']
RenderMessage: typeof import('./../components/rightBox/renderMessage/index.vue')['default']

View File

@ -18,28 +18,26 @@
<!-- 用户框 多套一层div来移除默认的右键事件然后覆盖掉因为margin空隙而导致右键可用 -->
<div @contextmenu.stop="$event.preventDefault()">
<div
<n-flex
v-slide
:size="10"
@click="handleClick(item.key, 2)"
:class="{ active: activeItem === item.key }"
class="user-box w-full h-75px mb-5px"
v-for="item in friendsList"
:key="item.key">
<div class="flex items-center h-full pl-6px pr-8px gap-10px">
<n-avatar round bordered :color="'#fff'" :size="44" :src="item.avatar" />
<n-flex v-slide align="center" :size="10" class="h-75px pl-6px pr-8px flex-1 truncate">
<n-avatar round bordered :color="'#fff'" :size="44" :src="item.avatar" fallback-src="/logo.png" />
<div class="h-38px flex flex-1 flex-col justify-between">
<div class="text-14px flex-y-center gap-4px">
{{ item.accountName }}
</div>
<n-flex vertical justify="space-between" class="h-fit flex-1 truncate">
<span class="text-14px leading-tight flex-1 truncate">{{ item.accountName }}</span>
<div class="text w-155px h-14px text-12px flex-y-center gap-4px">
<span class="text-12px">[今日天气]</span>
<span class="flex-1 truncate">说的很经典哈萨克的哈萨克看到贺卡上</span>
</div>
</div>
</div>
</div>
<span class="text leading-tight text-12px flex-1 truncate">
[今日天气] 说的很经典哈萨克的哈萨克看到贺卡上
</span>
</n-flex>
</n-flex>
</n-flex>
</div>
</n-collapse-item>
<n-collapse-item title="默认分组" name="3">
@ -57,19 +55,14 @@
<div
@click="handleClick(item.key, 1)"
:class="{ active: activeItem === item.key }"
class="w-full h-75px mb-5px cursor-pointer"
class="w-full h-75px mb-5px"
v-for="item in groupChatList"
:key="item.key">
<!-- 消息框使用v-slide自定义指令来自动抉择右键菜单位置 -->
<div v-slide class="flex items-center h-full pl-6px pr-8px gap-10px">
<n-avatar round bordered :color="'#fff'" :size="44" :src="item.avatar" />
<n-flex v-slide align="center" :size="10" class="h-75px pl-6px pr-8px flex-1 truncate">
<n-avatar round bordered :color="'#fff'" :size="44" :src="item.avatar" fallback-src="/logo.png" />
<div class="h-38px flex flex-1 flex-col justify-center">
<div class="flex-between-center">
<span class="text-14px">{{ item.accountName }}</span>
</div>
</div>
</div>
<span class="text-14px leading-tight flex-1 truncate">{{ item.accountName }}</span>
</n-flex>
</div>
</n-tab-pane>
</n-tabs>

View File

@ -17,17 +17,17 @@
v-for="item in MockList"
:key="item.key">
<!-- 消息框使用v-slide自定义指令来自动抉择右键菜单位置 -->
<n-flex v-slide align="center" :size="10" class="h-75px pl-6px pr-8px">
<n-avatar round bordered :color="'#fff'" :size="44" :src="item.avatar" fallback-src="/logo.png" alt="" />
<n-flex v-slide align="center" :size="10" class="h-75px pl-6px pr-8px flex-1">
<n-avatar round bordered :color="'#fff'" :size="44" :src="item.avatar" fallback-src="/logo.png" />
<n-flex vertical justify="space-between" class="h-38px flex-1">
<n-flex align="center" justify="space-between">
<span class="text-14px">{{ item.accountName }}</span>
<span class="text text-10px">昨天</span>
<n-flex vertical justify="space-between" class="h-fit flex-1 truncate">
<n-flex :size="4" align="center" justify="space-between" class="flex-1 truncate">
<span class="text-14px leading-tight flex-1 truncate">{{ item.accountName }}</span>
<span class="text text-10px w-fit truncate text-right">星期一</span>
</n-flex>
<n-flex align="center" justify="space-between">
<span class="text w-135px text-12px truncate"> 说的很经典哈萨克的哈萨克看到贺卡上 </span>
<span class="text flex-1 leading-tight text-12px truncate"> 说的很经典哈萨克的哈萨克看到贺卡上 </span>
<!-- 消息提示 -->
<n-badge :value="msgTotal" :max="99" />

View File

@ -9,7 +9,10 @@
<n-flex vertical :size="25" v-if="!isAutoLogin">
<!-- 头像 -->
<n-flex justify="center" class="w-full mt-35px">
<img class="w-80px h-80px rounded-50% bg-#fff border-(2px solid #fff)" :src="avatarRef || '/logo.png'" alt="" />
<img
class="w-80px h-80px rounded-50% bg-#fff border-(2px solid #fff)"
:src="info.avatar || '/logo.png'"
alt="" />
</n-flex>
<!-- 登录菜单 -->
@ -19,7 +22,7 @@
size="large"
maxlength="16"
minlength="6"
v-model:value="accountRef"
v-model:value="info.account"
type="text"
:placeholder="accountPH"
@focus="accountPH = ''"
@ -62,7 +65,7 @@
maxlength="16"
minlength="6"
size="large"
v-model:value="passwordRef"
v-model:value="info.password"
type="password"
:placeholder="passwordPH"
@focus="passwordPH = ''"
@ -116,18 +119,19 @@
:loading="loading"
:disabled="loginDisabled"
class="w-200px mt-12px mb-40px"
@click="loginWin"
@click="autoLogin"
color="#13987f">
{{ loginText }}
</n-button>
</n-flex>
</n-flex>
<!-- 部操作栏 -->
<n-flex justify="center" class="text-14px">
<!-- 部操作栏 -->
<n-flex justify="center" class="text-14px" id="bottomBar">
<div class="color-#13987f cursor-pointer" @click="router.push('/qrCode')">扫码登录</div>
<div class="w-1px h-14px bg-#ccc"></div>
<n-popover trigger="click" :show-checkmark="false" :show-arrow="false">
<div v-if="isAutoLogin" class="color-#13987f cursor-pointer">移除账号</div>
<n-popover v-else trigger="click" :show-checkmark="false" :show-arrow="false">
<template #trigger>
<div class="color-#13987f cursor-pointer">更多选项</div>
</template>
@ -151,10 +155,16 @@ import { useLogin } from '@/hooks/useLogin.ts'
const settingStore = setting()
const { login } = storeToRefs(settingStore)
const accountRef = ref()
const passwordRef = ref()
const avatarRef = ref()
const nameRef = ref()
/** 账号信息 */
const info = ref({
account: '',
password: '',
avatar: '',
name: ''
})
/** 是否中断登录 */
const interruptLogin = ref(false)
/** 协议 */
const protocol = ref()
const loginDisabled = ref(false)
const loading = ref(false)
@ -199,10 +209,13 @@ const loginText = ref('登录')
const { createWebviewWindow } = useWindow()
watchEffect(() => {
loginDisabled.value = !(accountRef.value && passwordRef.value && protocol.value)
loginDisabled.value = !(info.value.account && info.value.password && protocol.value)
//
if (!accountRef.value) {
avatarRef.value = '/logo.png'
if (!info.value.account) {
info.value.avatar = '/logo.png'
}
if (interruptLogin.value) {
loginDisabled.value = false
}
})
@ -217,9 +230,9 @@ const delAccount = (index: number) => {
if (lengthBeforeDelete === 1 && accountOption.value.length === 0) {
arrowStatus.value = false
}
accountRef.value = null
passwordRef.value = null
avatarRef.value = '/logo.png'
info.value.account = ''
info.value.password = ''
info.value.avatar = '/logo.png'
}
/**
@ -228,25 +241,26 @@ const delAccount = (index: number) => {
* */
const giveAccount = (item: STO.Setting['login']['accountInfo']) => {
const { account, password, avatar, name } = item
accountRef.value = account
passwordRef.value = password
avatarRef.value = avatar
nameRef.value = name
info.value.account = account || ''
info.value.password = password || ''
info.value.avatar = avatar
info.value.name = name
arrowStatus.value = false
}
/**登录后创建主页窗口*/
const loginWin = () => {
if (interruptLogin.value) return
loading.value = true
delay(async () => {
await createWebviewWindow('HuLa', 'home', 960, 720, 'login', false, true)
loading.value = false
if (!login.value.autoLogin || login.value.accountInfo.password === '') {
settingStore.setAccountInfo({
account: accountRef.value,
password: passwordRef.value,
avatar: avatarRef.value,
name: nameRef.value,
account: info.value.account,
password: info.value.password,
avatar: info.value.avatar,
name: info.value.name,
uid: '123456'
})
await setLoginState()
@ -254,12 +268,27 @@ const loginWin = () => {
}, 1000)
}
/**监听是否点击了除了下拉框外的其他地方*/
const handleClickOutside = (event: MouseEvent) => {
/** 自动登录 */
const autoLogin = () => {
interruptLogin.value = false
isAutoLogin.value = true
// TODO (nyh -> 2024-03-16 12:06:59)
loginText.value = '网络连接中'
delay(async () => {
loginWin()
loginText.value = '登录'
await setLoginState()
}, 1000)
}
const closeMenu = (event: MouseEvent) => {
const target = event.target as Element
if (!target.matches('.account-box, .account-box *, .down')) {
arrowStatus.value = false
}
if (target.matches('#bottomBar *') && isAutoLogin.value) {
interruptLogin.value = true
}
}
onMounted(async () => {
@ -267,20 +296,13 @@ onMounted(async () => {
console.error('设置无状态图标失败:', error)
})
if (login.value.autoLogin && login.value.accountInfo.password !== '') {
isAutoLogin.value = true
// TODO (nyh -> 2024-03-16 12:06:59)
loginText.value = '网络连接中'
delay(async () => {
loginWin()
loginText.value = '登录'
await setLoginState()
}, 1000)
autoLogin()
}
window.addEventListener('click', handleClickOutside, true)
window.addEventListener('click', closeMenu, true)
})
onUnmounted(() => {
window.removeEventListener('click', handleClickOutside, true)
window.removeEventListener('click', closeMenu, true)
})
</script>

View File

@ -14,18 +14,19 @@
v-else
:size="180"
class="rounded-12px relative"
:class="{ blur: scanSuccess }"
:class="{ blur: scanStatus.show }"
:value="QRCode"
icon-src="/logo.png"
error-correction-level="H" />
<!-- 二维码状态 -->
<n-flex
v-if="scanSuccess"
v-if="scanStatus.show"
vertical
:size="12"
align="center"
class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<svg class="size-42px"><use href="#success"></use></svg>
<span class="text-(16px #e3e3e3)">扫码成功</span>
<svg class="size-42px"><use :href="`#${scanStatus.icon}`"></use></svg>
<span class="text-(16px #e3e3e3)">{{ scanStatus.text }}</span>
</n-flex>
</n-flex>
@ -33,7 +34,7 @@
<!-- 顶部操作栏 -->
<n-flex justify="center" class="text-14px mt-48px">
<div class="color-#13987f cursor-pointer" @click="toLogin">账密登录</div>
<div class="color-#13987f cursor-pointer" @click="router.push('/login')">账密登录</div>
<div class="w-1px h-14px bg-#ccc"></div>
<div class="color-#13987f cursor-pointer">注册账号</div>
</n-flex>
@ -56,34 +57,60 @@ const { createWebviewWindow } = useWindow()
const loading = ref(true)
const loadText = ref('加载中...')
const QRCode = ref()
const scanSuccess = ref(false)
const scanStatus = ref<{
status: 'error' | 'success'
icon: 'cloudError' | 'success'
text: string
show: boolean
}>({ status: 'success', icon: 'success', text: '扫码成功', show: false })
const toLogin = () => {
router.push('/login')
/** 处理二维码登录 */
const handleQRCodeLogin = (e: any) => {
QRCode.value = e.data.loginUrl
loading.value = false
loadText.value = '请使用微信扫码登录'
}
/** 处理登录成功 */
const handleLoginSuccess = async (e: any) => {
scanStatus.value.show = true
loadText.value = '登录中...'
delay(async () => {
await createWebviewWindow('HuLa', 'home', 960, 720, 'login', false, true)
settingStore.setAccountInfo({
avatar: e.data.avatar,
name: e.data.name,
uid: e.data.uid
})
await setLoginState()
}, 1000)
}
/** 处理失败场景 */
const handleError = (e: any) => {
loading.value = false
scanStatus.value = {
status: 'error',
icon: 'cloudError',
text: e,
show: true
}
loadText.value = '请稍后再试'
}
// TODO (nyh -> 2024-01-27 00:37:18)
onMounted(() => {
initWebSocket()
Mitt.on(WsResEnum.QRCODE_LOGIN, (e: any) => {
QRCode.value = e.data.loginUrl
loading.value = false
loadText.value = '请使用微信扫码登录'
handleQRCodeLogin(e)
})
Mitt.on(WsResEnum.LOGIN_SUCCESS, (e: any) => {
scanSuccess.value = true
loadText.value = '登录中...'
delay(async () => {
await createWebviewWindow('HuLa', 'home', 960, 720, 'login', false, true)
settingStore.setAccountInfo({
avatar: e.data.avatar,
name: e.data.name,
uid: e.data.uid
})
await setLoginState()
}, 1000)
handleLoginSuccess(e)
})
delay(() => {
sendToServer({ type: WsReqEnum.LOGIN })
sendToServer({ type: WsReqEnum.LOGIN }).catch((e) => {
handleError(e)
})
}, 1000)
})
</script>