Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(view): ⚡ 优化聊天框用户信息操作选项 #173

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ body:
label: '💻 Operating System'
multiple: true
options:
- 'Windows'
- 'Windows 10'
- 'Windows 11'
- 'macOS'
- 'Linux'
- 'Android'
- 'ios'
validations:
required: true

Expand Down
6 changes: 5 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report_cn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ body:
label: '💻 系统环境'
multiple: true
options:
- 'Windows'
- 'Windows 10'
- 'Windows 11'
- 'macOS'
- 'Linux'
- 'Android'
- 'ios'
validations:
required: true

Expand Down
32 changes: 2 additions & 30 deletions scripts/check-dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,11 @@ const INSTALL_GUIDES = {
'Node.js': 'https://nodejs.org/zh-cn/download/',
pnpm: 'https://pnpm.io/zh/installation',
Rust: 'https://www.rust-lang.org/tools/install',
'Visual C++ Build Tools': 'https://visualstudio.microsoft.com/visual-cpp-build-tools/',
'WebView2 Runtime': 'https://developer.microsoft.com/microsoft-edge/webview2/'
}

// Windows 特定的检查路径
const WINDOWS_PATHS = {
'Visual C++ Build Tools': [
'C:\\Program Files (x86)\\Microsoft Visual Studio\\',
'C:\\Program Files\\Microsoft Visual Studio\\',
'C:\\Program Files (x86)\\Windows Kits\\10\\bin'
],
'WebView2 Runtime': [
'C:\\Program Files (x86)\\Microsoft\\EdgeWebView\\Application',
'C:\\Program Files\\Microsoft\\EdgeWebView\\Application',
Expand Down Expand Up @@ -57,23 +51,6 @@ const checks = [
}
]

/**
* 检查 Visual C++ Build Tools 是否安装
* @returns {boolean}
*/
const checkVCBuildTools = () => {
try {
// 检查 cl.exe 是否存在
execSync('where cl.exe', { stdio: 'ignore' })

// 检查是否能正常执行
const output = execSync('cl.exe 2>&1', { encoding: 'utf8' })
return output.includes('Microsoft') && output.includes('Compiler')
} catch {
return false
}
}

/**
* 检查 WebView2 是否安装
* @returns {boolean}
Expand All @@ -93,11 +70,6 @@ const checkWebView2 = () => {

// Windows 特定的检查
const windowsChecks = [
{
name: 'Visual C++ Build Tools',
checkInstalled: checkVCBuildTools,
isRequired: true
},
{
name: 'WebView2 Runtime',
checkInstalled: checkWebView2,
Expand Down Expand Up @@ -141,7 +113,7 @@ function checkDependency(check) {
const isVersionValid = compareVersions(version, check.minVersion) >= 0

if (isVersionValid) {
console.log(chalk.green(`✓ ${check.name} 版本 ${output} 已安装`))
console.log(chalk.green(`✓ ${check.name} 版本 ${output} 已安装\n`))
return true
} else {
console.log(chalk.yellow(`⚠️ ${check.name} 版本过低`))
Expand Down Expand Up @@ -191,7 +163,7 @@ function main() {

// 在 Windows 上执行额外检查
if (isWindows) {
console.log(chalk.blue('\n正在检查 Windows 开发环境...'))
console.log(chalk.blue(`\n[HuLa ${new Date().toLocaleTimeString()}] 正在检查 Windows 开发环境...\n`))
const windowsResults = windowsChecks.map(checkWindowsDependency)
results.push(...windowsResults)
}
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/gen/schemas/acl-manifests.json

Large diffs are not rendered by default.

72 changes: 55 additions & 17 deletions src/components/common/InfoPopover.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
<template>
<!-- 个人信息框 -->
<n-flex vertical :size="26" class="size-fit box-border rounded-8px relative min-h-[300px]">
<n-flex vertical :size="20" class="size-full p-10px box-border z-10">
<n-flex vertical :size="20" align="center">
<n-avatar :bordered="true" round :size="80" :src="avatarSrc" fallback-src="/logo.png" />
<!-- 背景 -->
<img
class="absolute rounded-t-8px z-2 top-0 left-0 w-full h-100px object-cover"
src="@/assets/img/dispersion-bg.png"
alt="" />
<div class="h-20px"></div>
<n-flex vertical :size="20" class="size-full p-10px box-border z-10 relative">
<n-flex vertical :size="20">
<n-avatar
class="border-(8px solid [--avatar-border-color])"
:bordered="true"
round
:size="80"
:src="avatarSrc"
fallback-src="/logo.png" />

Check warning on line 18 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L4-L18

Added lines #L4 - L18 were not covered by tests

<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>
<span
@click="openContent('在线状态', 'onlineStatus', 320, 480)"
:class="[activeStatus === OnlineEnum.ONLINE ? 'bg-#1ab292' : 'bg-#909090']"
class="absolute top-72px left-72px cursor-pointer border-(6px solid [--avatar-border-color]) rounded-full size-18px"></span>

Check warning on line 23 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L20-L23

Added lines #L20 - L23 were not covered by tests

<div
v-if="useUserInfo(uid).value.wearingItemId === 6"
class="absolute top-72px left-142px bg-[--bate-bg] border-(1px solid [--bate-color]) text-(12px [--bate-color] center) font-bold p-8px rounded-full">

Check warning on line 27 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L25-L27

Added lines #L25 - L27 were not covered by tests
HuLa开发工程师
</div>

Check warning on line 29 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L29

Added line #L29 was not covered by tests

<p class="text-(18px [--text-color])" style="font-family: none !important; font-weight: bold !important">
{{ useUserInfo(uid).value.name }}
</p>

Check warning on line 33 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L31-L33

Added lines #L31 - L33 were not covered by tests
</n-flex>

<!-- 地址 -->
Expand Down Expand Up @@ -44,29 +64,47 @@
</n-flex>

<n-flex justify="center" align="center" :size="40">
<n-button secondary> 发信息 </n-button>
<n-button v-if="isCurrentUserUid" secondary type="info" @click="openEditInfo"> 编辑资料 </n-button>
<n-button v-else-if="isMyFriend" secondary type="primary" @click="openMsgSession(uid)"> 发信息 </n-button>
<n-button v-else secondary @click="addFriend"> 加好友 </n-button>

Check warning on line 69 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L67-L69

Added lines #L67 - L69 were not covered by tests
</n-flex>
</n-flex>

<!-- 背景 -->
<img
class="size-full rounded-8px box-border p-20px absolute top-0 left-0 blur-xl opacity-80"
:src="avatarSrc"
alt="" />
</n-flex>
</template>

<script setup lang="ts">
import { useBadgeInfo, useUserInfo } from '@/hooks/useCached.ts'
import { AvatarUtils } from '@/utils/avatarUtils'
import { OnlineEnum } from '@/enums/index.ts'
import { MittEnum, OnlineEnum } from '@/enums/index.ts'
import { useCommon } from '@/hooks/useCommon.ts'
import { useContactStore } from '@/stores/contacts.ts'
import { leftHook } from '@/layout/left/hook'
import { useMitt } from '@/hooks/useMitt'
import { useGlobalStore } from '@/stores/global'

Check warning on line 83 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L78-L83

Added lines #L78 - L83 were not covered by tests

const { uid } = defineProps<{
uid: number
activeStatus?: OnlineEnum
}>()
const { userUid, openMsgSession } = useCommon()
const globalStore = useGlobalStore()
const { openContent } = leftHook()
const contactStore = useContactStore()

Check warning on line 92 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L89-L92

Added lines #L89 - L92 were not covered by tests
const isCurrentUser = computed(() => useUserInfo(uid).value)
const avatarSrc = computed(() => AvatarUtils.getAvatarUrl(useUserInfo(uid).value.avatar as string))
/** 是否是当前登录的用户 */
const isCurrentUserUid = computed(() => userUid.value === uid)

Check warning on line 96 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L96

Added line #L96 was not covered by tests
/** 是否是我的好友 */
const isMyFriend = computed(() => !!contactStore.contactsList.find((item) => item.uid === uid))

Check warning on line 98 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L98

Added line #L98 was not covered by tests

const openEditInfo = () => {
useMitt.emit(MittEnum.OPEN_EDIT_INFO)
}

Check warning on line 102 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L100-L102

Added lines #L100 - L102 were not covered by tests

const addFriend = () => {
globalStore.addFriendModalInfo.show = true
globalStore.addFriendModalInfo.uid = uid
}

Check warning on line 107 in src/components/common/InfoPopover.vue

View check run for this annotation

Codecov / codecov/patch

src/components/common/InfoPopover.vue#L104-L107

Added lines #L104 - L107 were not covered by tests
</script>

<style scoped lang="scss">
Expand Down
18 changes: 11 additions & 7 deletions src/layout/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import { isPermissionGranted, requestPermission, sendNotification } from '@tauri-apps/plugin-notification'
import { useUserInfo } from '@/hooks/useCached.ts'
import { emitTo } from '@tauri-apps/api/event'
import { useThrottleFn } from '@vueuse/core'

Check warning on line 31 in src/layout/index.vue

View check run for this annotation

Codecov / codecov/patch

src/layout/index.vue#L31

Added line #L31 was not covered by tests

const globalStore = useGlobalStore()
const contactStore = useContactStore()
Expand Down Expand Up @@ -105,16 +106,19 @@
chatStore.pushMsg(data)
console.log('接收消息', data)
// 接收到通知就设置图标闪烁
await emitTo('tray', 'show_tip')
await emitTo('notify', 'notify_cotent', data)
const username = useUserInfo(data.fromUser.uid).value.name!
// 不是自己发的消息才通知
if (data.fromUser.uid !== userStore.userInfo.uid) {
sendNotification({
title: username,
body: data.message.body.content,
icon: 'src-tauri/tray/icon.png'
})
await emitTo('tray', 'show_tip')
await emitTo('notify', 'notify_cotent', data)
const throttleSendNotification = useThrottleFn(() => {
sendNotification({
title: username,
body: data.message.body.content,
icon: 'src-tauri/tray/icon.png'
})
}, 3000)
throttleSendNotification()

Check warning on line 121 in src/layout/index.vue

View check run for this annotation

Codecov / codecov/patch

src/layout/index.vue#L112-L121

Added lines #L112 - L121 were not covered by tests
}
})
useMitt.on(WsResponseMessageType.REQUEST_NEW_FRIEND, (data: { uid: number; unreadCount: number }) => {
Expand Down
9 changes: 1 addition & 8 deletions src/services/webSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@ class WS {
this.initConnect()
// 收到消息
worker.addEventListener('message', this.onWorkerMsg)

// 后台重试次数达到上限之后,tab 获取焦点再重试
document.addEventListener('visibilitychange', () => {
if (!document.hidden && !this.#connectReady) {
this.initConnect()
}
})
}

initConnect = () => {
Expand Down Expand Up @@ -178,7 +171,7 @@ class WS {
useMitt.emit(WsResponseMessageType.REQUEST_NEW_FRIEND, params.data as { uid: number; unreadCount: number })
break
}
// 新好友申请
// 成员变动
case WsResponseMessageType.NEW_FRIEND_SESSION: {
console.log('新好友')
useMitt.emit(
Expand Down
4 changes: 2 additions & 2 deletions src/services/wsType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export enum WsResponseMessageType {
MSG_RECALL = 'msgRecall',
/** 新好友申请 */
REQUEST_NEW_FRIEND = 'requestNewFriend',
/** 新好友会话 */
/** 成员变动 */
NEW_FRIEND_SESSION = 'newFriendSession',
/** 线推送 */
/** 下线通知 */
OFFLINE = 'offline'
}

Expand Down
16 changes: 10 additions & 6 deletions src/stores/contacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@ export const pageSize = 20
export const useContactStore = defineStore('contact', () => {
const globalStore = useGlobalStore()

const contactsList = reactive<ContactItem[]>([]) // 联系人列表
const requestFriendsList = reactive<RequestFriendItem[]>([]) // 好友请求列表
/** 联系人列表 */
const contactsList = reactive<ContactItem[]>([])
/** 好友请求列表 */
const requestFriendsList = reactive<RequestFriendItem[]>([])

// 分页加载相关的状态
const contactsOptions = reactive({ isLast: false, isLoading: false, cursor: '' }) // 联系人列表分页选项
const requestFriendsOptions = reactive({ isLast: false, isLoading: false, cursor: '' }) // 好友请求列表分页选项
/** 联系人列表分页选项 */
const contactsOptions = reactive({ isLast: false, isLoading: false, cursor: '' })
/** 好友请求列表分页选项 */
const requestFriendsOptions = reactive({ isLast: false, isLoading: false, cursor: '' })

const groupChatList = reactive<GroupListReq[]>([]) // 群聊列表
/** 群聊列表 */
const groupChatList = reactive<GroupListReq[]>([])

/**
* 获取联系人列表
Expand Down
4 changes: 4 additions & 0 deletions src/styles/scss/global/variable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ svg {
// 危险样式
--danger-text: #c14053;
--danger-bg: #f6dfe3;
// 头像边框颜色
--avatar-border-color: #fff;
}

html[data-theme='dark'] {
Expand Down Expand Up @@ -183,6 +185,8 @@ html[data-theme='dark'] {
// 危险样式
--danger-text: #da8583;
--danger-bg: #37292c;
// 头像边框颜色
--avatar-border-color: #232223;
}
/**! end */
// 线性动画
Expand Down
9 changes: 5 additions & 4 deletions src/views/Notify.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,19 @@ const sortMessages = () => {
})
}

onMounted(async () => {
onBeforeMount(async () => {
// 确保用户已登录并初始化会话列表
await chatStore.getSessionList(true)
})

onMounted(async () => {
// 初始化窗口高度
resizeWindow('notify', 280, 140)

await pushListeners([
// 监听托盘鼠标进入事件
appWindow.listen('notify_enter', async (event: Event<any>) => {
if (tipVisible.value) {
await showWindow(event)
}
await showWindow(event)
}),

// 监听托盘鼠标离开事件
Expand Down
5 changes: 5 additions & 0 deletions src/views/Tray.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,14 @@ watch([isFocused, () => tipVisible.value], ([newFocused, newTipVisible]) => {
console.log('Focus or tip state changed:', { focused: newFocused, tipVisible: newTipVisible })
})

onBeforeMount(() => {
globalStore.setTipVisible(false)
})

onMounted(async () => {
home = await WebviewWindow.getByLabel('home')
isFocused.value = (await home?.isFocused()) || false

if (home) {
// 监听窗口焦点变化
home.listen('tauri://focus', () => {
Expand Down
4 changes: 4 additions & 0 deletions src/views/loginWindow/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,12 @@
import { useNetwork } from '@vueuse/core'
import { computedToken } from '@/services/request'
import ws from '@/services/webSocket'
import { useGlobalStore } from '@/stores/global.ts'

Check warning on line 175 in src/views/loginWindow/Login.vue

View check run for this annotation

Codecov / codecov/patch

src/views/loginWindow/Login.vue#L175

Added line #L175 was not covered by tests

const settingStore = useSettingStore()
const userStore = useUserStore()
const globalStore = useGlobalStore()
const { isTrayMenuShow } = storeToRefs(globalStore)

Check warning on line 180 in src/views/loginWindow/Login.vue

View check run for this annotation

Codecov / codecov/patch

src/views/loginWindow/Login.vue#L179-L180

Added lines #L179 - L180 were not covered by tests
/** 网络连接是否正常 */
const { isOnline } = useNetwork()
const loginHistoriesStore = useLoginHistoriesStore()
Expand Down Expand Up @@ -359,6 +362,7 @@
// 如果不是自动登录且当前在登录页面,清除 TOKEN,防止用户直接使用控制台退出导致登录前还没有退出账号就继续登录
if (!login.value.autoLogin && route.path === '/login') {
await apis.logout().catch(() => {})
isTrayMenuShow.value = false

Check warning on line 365 in src/views/loginWindow/Login.vue

View check run for this annotation

Codecov / codecov/patch

src/views/loginWindow/Login.vue#L365

Added line #L365 was not covered by tests
computedToken.clear()
// 重新初始化 WebSocket 连接,此时传入 null 作为 token
ws.initConnect()
Expand Down
Loading