fix(common): 🐛 修复系统托盘状态切换问题 (#153)

修改github issues模版|优化群聊用户侧边栏
This commit is contained in:
Dawn
2025-01-07 21:44:47 +08:00
committed by GitHub
parent cb08e62cc6
commit 00e2a89745
14 changed files with 83 additions and 63 deletions

View File

@@ -38,11 +38,9 @@ body:
- type: textarea
id: info
attributes:
label: '☄️ 完整的 `tauri info` 输出'
description: '请运行 “tauri info” 在控制台等待输出完毕,并将输出内容复制到此处'
label: '☄️ 完整的 `pnpm tauri info` 输出'
description: '请运行 “pnpm tauri info” 在控制台等待输出完毕,并将输出内容复制到此处'
render: text
validations:
required: true
- type: textarea
attributes:

View File

@@ -38,11 +38,9 @@ body:
- type: textarea
id: info
attributes:
label: '☄️ intact `tauri info` output'
description: 'Please run "tauri info" in the console and wait for the output to finish, then copy the output here'
label: '☄️ intact `pnpm tauri info` output'
description: 'Please run "pnpm tauri info" in the console and wait for the output to finish, then copy the output here'
render: text
validations:
required: true
- type: textarea
attributes:

View File

@@ -38,11 +38,9 @@ body:
- type: textarea
id: info
attributes:
label: '☄️ 完整的 `tauri info` 输出'
description: '请运行 “tauri info” 在控制台等待输出完毕,并将输出内容复制到此处'
label: '☄️ 完整的 `pnpm tauri info` 输出'
description: '请运行 “pnpm tauri info” 在控制台等待输出完毕,并将输出内容复制到此处'
render: text
validations:
required: true
- type: textarea
attributes:

View File

@@ -13,7 +13,7 @@
"author": {
"name": "HuLaSpark团队",
"email": "2439646234@qq.com",
"url": "https://github.com/HuLaSpark/HuLa"
"url": "https://github.com/HuLaSpark"
},
"scripts": {
"========= 启动vue(tauri项目会连带执行不需要单独执行) =========": "",
@@ -28,8 +28,8 @@
"tauri:build:debug": "tauri build --debug",
"========= 生成icon =========": "",
"tauri:icon": "tauri icon hula.png",
"========= 安装依赖前执行校验包管理器 =========": "",
"preinstall": "npx only-allow pnpm",
"========= 安装依赖前执行 =========": "",
"preinstall": "npx only-allow pnpm && node scripts/check-env.js",
"========= 使用commit来进行代码提交 =========": "",
"commit": "git add . && git-cz",
"========= 校验代码规范 =========": "",

25
scripts/check-env.js Normal file
View File

@@ -0,0 +1,25 @@
import { existsSync, writeFileSync } from 'fs'
import { join } from 'path'
// 用于写入.env.local配置文件该文件默认不会被git管理所以不必担心会提交到远程仓库
const envPath = join(process.cwd(), '.env.local')
if (!existsSync(envPath)) {
const defaultEnvContent = `# 有道云翻译key
VITE_YOUDAO_APP_KEY=
VITE_YOUDAO_APP_SECRET=
# 腾讯云翻译key
VITE_TENCENT_API_KEY=
VITE_TENCENT_SECRET_ID=
`
try {
writeFileSync(envPath, defaultEnvContent, 'utf8')
console.log('✨ 成功创建.env.local文件')
} catch (error) {
console.error('❌ 创建.env.local文件失败:', error)
process.exit(1)
}
} else {
console.log('✅ .env.local文件已存在')
}

View File

@@ -5,9 +5,11 @@
<n-flex vertical :size="20" align="center">
<n-avatar :bordered="true" round :size="80" :src="avatarSrc" fallback-src="/logo.png" />
<n-flex :size="5" align="center" style="margin-left: -4px" class="item-hover">
<img class="rounded-50% w-18px h-18px" src="/status/weather_3x.png" alt="" />
<span>在线状态</span>
<n-flex v-if="activeStatus" :size="6" align="center" style="margin-left: -4px" class="item-hover">
<n-badge :color="activeStatus === OnlineEnum.ONLINE ? '#1ab292' : '#909090'" dot />
<p class="text-(12px [--text-color])">
{{ activeStatus === OnlineEnum.ONLINE ? '在线' : '离线' }}
</p>
</n-flex>
</n-flex>
@@ -57,9 +59,11 @@
<script setup lang="ts">
import { useBadgeInfo, useUserInfo } from '@/hooks/useCached.ts'
import { AvatarUtils } from '@/utils/avatarUtils'
import { OnlineEnum } from '@/enums/index.ts'
const { uid } = defineProps<{
uid: number
activeStatus?: OnlineEnum
}>()
const isCurrentUser = computed(() => useUserInfo(uid).value)
const avatarSrc = computed(() => AvatarUtils.getAvatarUrl(useUserInfo(uid).value.avatar as string))

View File

@@ -135,7 +135,9 @@
<!-- 群聊成员列表 -->
<div class="box-item cursor-default">
<n-flex vertical justify="center" :size="16">
<p class="text-(14px --text-color)">群成员</p>
<p class="text-(14px --text-color)">
{{ activeItem.hotFlag !== IsAllUserEnum.Yes ? '群成员' : '频道成员' }}
</p>
<n-flex align="center" justify="start" :size="[24, 20]">
<template v-for="(item, _index) in userList" :key="_index">
@@ -149,7 +151,10 @@
</n-flex>
</div>
<div class="box-item cursor-pointer" @click="handleDelete(RoomActEnum.DELETE_RECORD)">
<div
v-if="activeItem.hotFlag !== IsAllUserEnum.Yes"
class="box-item cursor-pointer"
@click="handleDelete(RoomActEnum.DELETE_RECORD)">
<p>删除聊天记录</p>
</div>
@@ -160,7 +165,11 @@
<p class="color-#d03553">退出群聊</p>
</div>
<p class="m-[0_auto] text-(12px #13987f) mt-20px cursor-pointer">被骚扰了?&nbsp;&nbsp;举报该群</p>
<p
v-if="activeItem.hotFlag !== IsAllUserEnum.Yes"
class="m-[0_auto] text-(12px #13987f) mt-20px cursor-pointer">
被骚扰了?&nbsp;&nbsp;举报该群
</p>
</template>
</div>
</Transition>

View File

@@ -79,18 +79,12 @@
:special-menu="report">
<n-flex @click="selectKey = item.uid" :key="item.uid" :size="10" align="center" class="item">
<n-avatar
lazy
round
class="grayscale"
:class="{ 'grayscale-0': item.activeStatus === OnlineEnum.ONLINE }"
:color="'#fff'"
:size="24"
:src="AvatarUtils.getAvatarUrl(item.avatar)"
fallback-src="/logo.png"
:render-placeholder="() => null"
:intersection-observer-options="{
root: '#image-chat-sidebar'
}" />
:src="AvatarUtils.getAvatarUrl(item.avatar)" />
<p class="text-12px truncate flex-1">{{ item.name }}</p>
<div
v-if="item.roleId === RoleEnum.LORD"
@@ -106,7 +100,7 @@
</ContextMenu>
</template>
<!-- 用户个人信息框 -->
<InfoPopover v-if="selectKey === item.uid" :uid="item.uid" />
<InfoPopover v-if="selectKey === item.uid" :uid="item.uid" :activeStatus="item.activeStatus" />
</n-popover>
</template>
</n-virtual-list>

View File

@@ -1,10 +1,10 @@
<template>
<!-- 头部 -->
<ChatHeader :active-item="activeItemRef as any" />
<ChatHeader :active-item="activeItemRef" />
<n-flex :class="{ 'shadow-inner': page.shadow }" :size="0" class="h-full">
<n-flex vertical :size="0" class="flex-1 relative">
<!-- 中间聊天框内容 -->
<ChatMain :active-item="activeItemRef as any" />
<ChatMain :active-item="activeItemRef" />
<!-- 输入框和操作列表 -->
<ChatFooter class="flex-1" />
</n-flex>
@@ -12,7 +12,7 @@
</n-flex>
</template>
<script setup lang="ts">
import { MockItem } from '@/services/types.ts'
import type { SessionItem } from '@/services/types.ts'
import { WebviewWindow } from '@tauri-apps/api/webviewWindow'
import { useSettingStore } from '@/stores/setting.ts'
import { useTauriListener } from '@/hooks/useTauriListener'
@@ -22,7 +22,7 @@ const settingStore = useSettingStore()
const { page } = storeToRefs(settingStore)
const appWindow = WebviewWindow.getCurrent()
const { activeItem } = defineProps<{
activeItem?: MockItem
activeItem?: SessionItem
}>()
provide('activeItem', { ...activeItem! })
const activeItemRef = ref({ ...activeItem! })

View File

@@ -1,8 +1,12 @@
import { emitTo, emit } from '@tauri-apps/api/event'
import { emit } from '@tauri-apps/api/event'
import { EventEnum } from '@/enums'
import { useWindow } from '@/hooks/useWindow.ts'
import { useGlobalStore } from '@/stores/global.ts'
export const useLogin = () => {
const { resizeWindow } = useWindow()
const globalStore = useGlobalStore()
const { isTrayMenuShow } = storeToRefs(globalStore)
/**
* 设置登录状态(系统托盘图标,系统托盘菜单选项)
*/
@@ -11,7 +15,8 @@ export const useLogin = () => {
if (localStorage.getItem('wsLogin')) {
localStorage.removeItem('wsLogin')
}
await emitTo('tray', 'login_success')
isTrayMenuShow.value = true
await resizeWindow('tray', 130, 356)
}
/**
@@ -19,10 +24,11 @@ export const useLogin = () => {
*/
const logout = async () => {
const { createWebviewWindow } = useWindow()
isTrayMenuShow.value = false
// todo 退出账号 需要关闭其他的全部窗口
await createWebviewWindow('登录', 'login', 320, 448, 'home', false, 320, 448).then(async () => {
await resizeWindow('tray', 130, 44)
await emit(EventEnum.LOGOUT)
await emitTo('tray', 'logout_success')
})
}

View File

@@ -104,7 +104,8 @@ useMitt.on(WsResponseMessageType.MSG_RECALL, (data: RevokedMsgType) => {
useMitt.on(WsResponseMessageType.RECEIVE_MESSAGE, async (data: MessageType) => {
chatStore.pushMsg(data)
console.log('接收消息', data)
await emitTo('tray', 'show_tip')
// 接收到通知就设置图标闪烁
globalStore.setTipVisible(true)
await emitTo('notify', 'notify_cotent', data)
const username = useUserInfo(data.fromUser.uid).value.name!
// 不是自己发的消息才通知

View File

@@ -49,8 +49,10 @@ export const useGlobalStore = defineStore(
selectedUid: []
})
// 提示框显示状态
/** 提示框显示状态 */
const tipVisible = ref<boolean>(false)
/** 系统托盘菜单显示的状态 */
const isTrayMenuShow = ref<boolean>(false)
// 更新全局未读消息计数
const updateGlobalUnreadCount = async () => {
@@ -89,6 +91,7 @@ export const useGlobalStore = defineStore(
currentReadUnreadList,
createGroupModalInfo,
tipVisible,
isTrayMenuShow,
setTipVisible,
updateGlobalUnreadCount
}

View File

@@ -1,5 +1,5 @@
<template>
<n-flex v-if="!isLoginWin" vertical :size="6" class="tray">
<n-flex v-if="isTrayMenuShow" vertical :size="6" class="tray">
<n-flex vertical :size="6">
<n-flex
v-for="(item, index) in statusItem.slice(0, 6)"
@@ -59,21 +59,18 @@ import { useSettingStore } from '@/stores/setting.ts'
import { useGlobalStore } from '@/stores/global.ts'
import { TrayIcon } from '@tauri-apps/api/tray'
import { type } from '@tauri-apps/plugin-os'
import { useTauriListener } from '@/hooks/useTauriListener'
const appWindow = WebviewWindow.getCurrent()
const { checkWinExist, createWebviewWindow, resizeWindow } = useWindow()
const { checkWinExist, createWebviewWindow } = useWindow()
const OLStatusStore = onlineStatus()
const settingStore = useSettingStore()
const globalStore = useGlobalStore()
const { lockScreen } = storeToRefs(settingStore)
const { tipVisible } = storeToRefs(globalStore)
const isLoginWin = ref(true)
const { tipVisible, isTrayMenuShow } = storeToRefs(globalStore)
const isFocused = ref(false)
let home: WebviewWindow | null = null
// 状态栏图标是否显示
const iconVisible = ref(false)
const { pushListeners } = useTauriListener()
let interval: any
const division = () => {
@@ -127,7 +124,6 @@ watch([isFocused, () => tipVisible.value], ([newFocused, newTipVisible]) => {
onMounted(async () => {
home = await WebviewWindow.getByLabel('home')
isFocused.value = (await home?.isFocused()) || false
if (home) {
// 监听窗口焦点变化
home.listen('tauri://focus', () => {
@@ -136,20 +132,6 @@ onMounted(async () => {
home.listen('tauri://blur', () => {
isFocused.value = false
})
await pushListeners([
appWindow.listen('login_success', () => {
isLoginWin.value = false
resizeWindow('tray', 130, 356)
}),
appWindow.listen('logout_success', () => {
isLoginWin.value = true
resizeWindow('tray', 130, 44)
}),
appWindow.listen('show_tip', async () => {
console.log('Received show_tip event')
globalStore.setTipVisible(true)
})
])
}
})

View File

@@ -174,12 +174,14 @@ onMounted(() => {
useMitt.on(MittEnum.DELETE_SESSION, (roomId) => {
handleMsgDelete(roomId)
})
useMitt.on(MittEnum.LOCATE_SESSION, (e) => {
useMitt.on(MittEnum.LOCATE_SESSION, async (e) => {
const index = sessionList.value.findIndex((item) => item.roomId === e.roomId)
if (index !== -1) {
msgScrollbar.value?.scrollTo({
top: index * (75 + 5) - 264,
behavior: 'smooth'
await nextTick(() => {
msgScrollbar.value?.scrollTo({
top: index * (75 + 5) - 264,
behavior: 'smooth'
})
})
}
})