diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 113f8744..c1e3d820 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -28,5 +28,6 @@ module.exports = {
'@typescript-eslint/no-explicit-any': 0, // 允许any类型
'no-param-reassign': 0, // 允许修改函数参数
'prefer-regex-literals': 0, // 允许使用new RegExp
+ 'no-unused-vars': 2, // 禁止未使用的变量
},
}
diff --git a/src/components/UserSettingBox/index.vue b/src/components/UserSettingBox/index.vue
index b75f51b1..7bbf5a16 100644
--- a/src/components/UserSettingBox/index.vue
+++ b/src/components/UserSettingBox/index.vue
@@ -4,6 +4,7 @@ import { useRequest } from 'alova'
import { ElMessage } from 'element-plus'
import { Select, CloseBold, EditPen } from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'
+import { useCachedStore } from '@/stores/cached'
import { SexEnum, IsYetEnum } from '@/enums'
import type { BadgeType } from '@/services/types'
import apis from '@/services/apis'
@@ -30,6 +31,7 @@ const editName = reactive({
})
const userStore = useUserStore()
+const cachedStore = useCachedStore()
const userInfo = computed(() => userStore.userInfo)
const { send: handlerGetBadgeList, data: badgeList } = useRequest(apis.getBadgeList, {
@@ -47,12 +49,21 @@ const currentBadge = computed(() =>
badgeList.value.find((item) => item.obtain === IsYetEnum.YES && item.wearing === IsYetEnum.YES),
)
+// 更新缓存里面的用户信息
+const updateCurrentUserCache = (key: 'name' | 'wearingItemId', value: any) => {
+ const currentUser = userStore.userInfo.uid && cachedStore.userCachedList[userStore.userInfo.uid]
+ if (currentUser) {
+ currentUser[key] = value // 更新缓存里面的用户信息
+ }
+}
+
// 佩戴卸下徽章
const toggleWarningBadge = async (badge: BadgeType) => {
if (!badge?.id) return
await apis.setUserBadge(badge.id).send()
handlerGetBadgeList()
badge.img && (userInfo.value.badge = badge.img)
+ updateCurrentUserCache('wearingItemId', badge.id) // 更新缓存里面的用户徽章
}
// 编辑用户名
@@ -73,13 +84,15 @@ const onSaveUserName = async () => {
return
}
editName.saving = true
- await apis.modifyUserName(editName.tempName).send()
- userStore.userInfo.name = editName.tempName
- editName.saving = false
- editName.isEdit = false
- editName.tempName = ''
+
+ await apis.modifyUserName(editName.tempName).send() // 更改用户名
+ userStore.userInfo.name = editName.tempName // 更新用户信息里面的用户名
+ updateCurrentUserCache('name', editName.tempName) // 更新缓存里面的用户信息
+ // 重置状态
+ onCancelEditName()
+ // 没有更名机会就不走下去
if (!userInfo.value?.modifyNameChance || userInfo.value.modifyNameChance === 0) return
- userInfo.value.modifyNameChance = userInfo.value?.modifyNameChance - 1
+ userInfo.value.modifyNameChance = userInfo.value?.modifyNameChance - 1 // 减少更名次数
}
// 确认保存用户名
const onCancelEditName = async () => {
diff --git a/src/utils/copy.ts b/src/utils/copy.ts
index efcdb31b..4008a6df 100644
--- a/src/utils/copy.ts
+++ b/src/utils/copy.ts
@@ -15,3 +15,30 @@ export const copyToClip = (text: string) => {
}
})
}
+
+export const handleCopyImg = (imgUrl: string) => {
+ const canvas = document.createElement('canvas')
+ const ctx = canvas.getContext('2d')
+ const img = new Image()
+ img.crossOrigin = 'Anonymous'
+ img.src = imgUrl
+ img.onload = () => {
+ if (!ctx) return
+ canvas.width = img.width
+ canvas.height = img.height
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
+ ctx.drawImage(img, 0, 0) // 将canvas转为blob
+ canvas.toBlob(async (blob) => {
+ if (!blob) return
+ const data = [new ClipboardItem({ [blob.type]: blob })] // https://w3c.github.io/clipboard-apis/#dom-clipboard-write
+ try {
+ await navigator.clipboard.write(data)
+ // console.log('Copied to clipboard successfully!')
+ } catch (error) {
+ // console.error('Unable to write to clipboard.')
+ } finally {
+ canvas.remove()
+ }
+ })
+ }
+}
diff --git a/src/views/Home/components/ChatBox/MsgInput/index.vue b/src/views/Home/components/ChatBox/MsgInput/index.vue
index 4e96db63..dda534ee 100644
--- a/src/views/Home/components/ChatBox/MsgInput/index.vue
+++ b/src/views/Home/components/ChatBox/MsgInput/index.vue
@@ -1,6 +1,6 @@
@@ -553,11 +555,13 @@ defineExpose({ input: editorRef, range: editorRange, onSelectPerson })
dataPropName="item"
:itemProps="{ activeIndex, onSelect: onSelectPerson }"
:data="personList"
- data-key="uid"
+ :data-key="getKey"
:item="MentionItem"
:size="20"
/>
+
+
diff --git a/src/views/Home/components/ChatBox/MsgInput/item.vue b/src/views/Home/components/ChatBox/MsgInput/item.vue
index 0025f5c0..0e6f764f 100644
--- a/src/views/Home/components/ChatBox/MsgInput/item.vue
+++ b/src/views/Home/components/ChatBox/MsgInput/item.vue
@@ -17,8 +17,6 @@ const props = defineProps({
onSelect: Function,
})
-const emit = defineEmits(['select'])
-
const onClick = () => {
props.onSelect?.(props.item)
}
diff --git a/src/views/Home/components/ChatBox/PasteImageDialog/index.vue b/src/views/Home/components/ChatBox/PasteImageDialog/index.vue
new file mode 100644
index 00000000..edfe93ba
--- /dev/null
+++ b/src/views/Home/components/ChatBox/PasteImageDialog/index.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/Home/components/ChatBox/PasteImageDialog/styles.scss b/src/views/Home/components/ChatBox/PasteImageDialog/styles.scss
new file mode 100644
index 00000000..873f644b
--- /dev/null
+++ b/src/views/Home/components/ChatBox/PasteImageDialog/styles.scss
@@ -0,0 +1,19 @@
+.image-paste-modal {
+ display: flex;
+ flex-direction: column;
+ width: 600px;
+ max-height: 80vh;
+ overflow: hidden;
+ text-align: center;
+
+ .el-dialog__body {
+ flex: 1;
+ max-height: 100%;
+ overflow-y: auto;
+ }
+
+ img {
+ max-width: 100%;
+ max-height: 100%;
+ }
+}
diff --git a/src/views/Home/components/ChatBox/index.vue b/src/views/Home/components/ChatBox/index.vue
index e75956f3..4684dfe4 100644
--- a/src/views/Home/components/ChatBox/index.vue
+++ b/src/views/Home/components/ChatBox/index.vue
@@ -55,6 +55,7 @@ const onSelectPerson = (uid: number, ignoreCheck?: boolean) => {
provide('focusMsgInput', focusMsgInput)
provide('onSelectPerson', onSelectPerson)
+// 发送消息
const send = (msgType: MsgEnum, body: any, roomId = 1) => {
apis
.sendMsg({ roomId, msgType, body })
@@ -160,7 +161,7 @@ const openFileSelect = (fileType: string) => {
open()
}
-onChange((files) => {
+const selectAndUploadFile = async (files?: FileList | null) => {
if (!files?.length) return
const file = files[0]
if (nowMsgType.value === MsgEnum.IMAGE) {
@@ -168,9 +169,18 @@ onChange((files) => {
return ElMessage.error('请选择图片文件')
}
}
- uploadFile(file)
+ await uploadFile(file)
+}
+
+// 选中文件上传并发送消息
+provide('onChangeFile', selectAndUploadFile)
+// 设置消息类型
+provide('onChangeMsgType', (msgType: MsgEnum) => {
+ nowMsgType.value = msgType
})
+onChange(selectAndUploadFile)
+
onStart(() => {
if (!fileInfo.value) return
diff --git a/src/views/Home/components/ChatList/ContextMenu/index.vue b/src/views/Home/components/ChatList/ContextMenu/index.vue
index 0d4b8afa..fe3eddba 100644
--- a/src/views/Home/components/ChatList/ContextMenu/index.vue
+++ b/src/views/Home/components/ChatList/ContextMenu/index.vue
@@ -1,5 +1,6 @@