vue-chat-kit 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -317,7 +317,7 @@
317
317
  </div>
318
318
 
319
319
  <!-- 底部输入区域 -->
320
- <div class="chat-input-area">
320
+ <div class="chat-input-area" @click="showEmojiPicker = false">
321
321
  <!-- 待发送文件预览 -->
322
322
  <div
323
323
  v-if="pendingFiles.length > 0"
@@ -363,7 +363,16 @@
363
363
  </div>
364
364
 
365
365
  <div v-if="config.modules.fileUpload" class="input-toolbar">
366
- <el-icon class="input-toolbar-icon"><ChatDotRound /></el-icon>
366
+ <div class="emoji-button-wrapper">
367
+ <el-icon
368
+ class="input-toolbar-icon"
369
+ @click.stop="showEmojiPicker = !showEmojiPicker"
370
+ ><ChatDotRound /></el-icon>
371
+ <EmojiPicker
372
+ :visible="showEmojiPicker"
373
+ @select="selectEmoji"
374
+ />
375
+ </div>
367
376
  <el-icon
368
377
  class="input-toolbar-icon"
369
378
  @click="triggerFileSelect"
@@ -657,6 +666,7 @@ import {
657
666
  import { useChat } from '../composables/useChat.js'
658
667
  import { ElMessage } from 'element-plus'
659
668
  import AvatarCrop from './AvatarCrop.vue'
669
+ import EmojiPicker from './EmojiPicker.vue'
660
670
 
661
671
  const props = defineProps({
662
672
  config: { type: Object, required: true }
@@ -702,8 +712,7 @@ const {
702
712
  loadFriendApplyList,
703
713
  agreeFriend,
704
714
  updateMyAvatar,
705
- getUserInfo,
706
- updateUserInfo
715
+
707
716
  } = useChat(props.config, (message) => {
708
717
  emit('message', message)
709
718
  })
@@ -738,6 +747,7 @@ const avatarImageSrc = ref('')
738
747
  const fileInputRef = ref(null)
739
748
  const pendingFiles = ref([])
740
749
  const contextMenu = ref({ visible: false, x: 0, y: 0, chat: null })
750
+ const showEmojiPicker = ref(false)
741
751
 
742
752
  const showContextMenuFn = (e, chat) => {
743
753
  e.preventDefault()
@@ -908,6 +918,11 @@ const handleImageError = (e) => {
908
918
  console.warn('图片加载失败', e)
909
919
  }
910
920
 
921
+ const selectEmoji = (emoji) => {
922
+ inputText.value += emoji
923
+ showEmojiPicker.value = false
924
+ }
925
+
911
926
  const handleAvatarFileChange = (e) => {
912
927
  const file = e.target.files[0]
913
928
  if (!file) return
@@ -1017,10 +1032,14 @@ onUnmounted(() => {
1017
1032
  .chat-panel {
1018
1033
  display: flex;
1019
1034
  height: 680px;
1020
- background-color: white;
1035
+ background: rgba(255, 255, 255, 0.7);
1036
+ backdrop-filter: blur(20px);
1037
+ -webkit-backdrop-filter: blur(20px);
1021
1038
  overflow: hidden;
1022
- border-radius: 12px;
1023
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
1039
+ border-radius: 20px;
1040
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12),
1041
+ 0 2px 12px rgba(0, 0, 0, 0.08);
1042
+ border: 1px solid rgba(255, 255, 255, 0.3);
1024
1043
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1025
1044
  }
1026
1045
 
@@ -1031,8 +1050,10 @@ onUnmounted(() => {
1031
1050
  flex-direction: column;
1032
1051
  align-items: center;
1033
1052
  gap: 8px;
1034
- background-color: #f9fafb;
1035
- border-right: 1px solid #e5e7eb;
1053
+ background: rgba(249, 250, 251, 0.6);
1054
+ backdrop-filter: blur(10px);
1055
+ -webkit-backdrop-filter: blur(10px);
1056
+ border-right: 1px solid rgba(229, 231, 235, 0.5);
1036
1057
  }
1037
1058
 
1038
1059
  .sidebar-avatar {
@@ -1096,8 +1117,10 @@ onUnmounted(() => {
1096
1117
  /* ========== 中间内容面板 ========== */
1097
1118
  .chat-content-panel {
1098
1119
  width: 288px;
1099
- background-color: #f5f5f5;
1100
- border-right: 1px solid #e5e7eb;
1120
+ background: rgba(245, 245, 245, 0.5);
1121
+ backdrop-filter: blur(10px);
1122
+ -webkit-backdrop-filter: blur(10px);
1123
+ border-right: 1px solid rgba(229, 231, 235, 0.5);
1101
1124
  display: flex;
1102
1125
  flex-direction: column;
1103
1126
  }
@@ -1123,14 +1146,16 @@ onUnmounted(() => {
1123
1146
  padding: 12px;
1124
1147
  cursor: pointer;
1125
1148
  transition: background-color 0.2s;
1149
+ border-radius: 8px;
1150
+ margin: 0 8px;
1126
1151
  }
1127
1152
 
1128
1153
  .chat-list-item:hover {
1129
- background-color: #e5e5e5;
1154
+ background: rgba(229, 229, 229, 0.6);
1130
1155
  }
1131
1156
 
1132
1157
  .chat-list-item-active {
1133
- background-color: #d6d6d6;
1158
+ background: rgba(7, 193, 96, 0.15);
1134
1159
  }
1135
1160
 
1136
1161
  .chat-list-avatar-wrapper {
@@ -1295,7 +1320,9 @@ onUnmounted(() => {
1295
1320
  display: flex;
1296
1321
  flex-direction: column;
1297
1322
  min-width: 0;
1298
- background-color: white;
1323
+ background: rgba(255, 255, 255, 0.5);
1324
+ backdrop-filter: blur(10px);
1325
+ -webkit-backdrop-filter: blur(10px);
1299
1326
  }
1300
1327
 
1301
1328
  /* 好友信息 */
@@ -1306,7 +1333,7 @@ onUnmounted(() => {
1306
1333
  align-items: center;
1307
1334
  justify-content: center;
1308
1335
  padding: 32px;
1309
- background-color: #f5f5f5;
1336
+ background: rgba(245, 245, 245, 0.4);
1310
1337
  }
1311
1338
 
1312
1339
  .profile-avatar {
@@ -1359,12 +1386,14 @@ onUnmounted(() => {
1359
1386
 
1360
1387
  .chat-window-header {
1361
1388
  height: 56px;
1362
- border-bottom: 1px solid #e5e7eb;
1389
+ border-bottom: 1px solid rgba(229, 231, 235, 0.5);
1363
1390
  display: flex;
1364
1391
  align-items: center;
1365
1392
  justify-content: space-between;
1366
1393
  padding: 0 16px;
1367
- background-color: white;
1394
+ background: rgba(255, 255, 255, 0.3);
1395
+ backdrop-filter: blur(10px);
1396
+ -webkit-backdrop-filter: blur(10px);
1368
1397
  }
1369
1398
 
1370
1399
  .chat-window-title {
@@ -1414,7 +1443,7 @@ onUnmounted(() => {
1414
1443
  flex: 1;
1415
1444
  overflow-y: auto;
1416
1445
  padding: 16px;
1417
- background-color: #f5f5f5;
1446
+ background: rgba(245, 245, 245, 0.3);
1418
1447
  min-height: 0;
1419
1448
  }
1420
1449
 
@@ -1641,8 +1670,17 @@ onUnmounted(() => {
1641
1670
 
1642
1671
  /* 输入区域 */
1643
1672
  .chat-input-area {
1644
- background-color: white;
1645
- border-top: 1px solid #e5e7eb;
1673
+ background: rgba(255, 255, 255, 0.6);
1674
+ backdrop-filter: blur(10px);
1675
+ -webkit-backdrop-filter: blur(10px);
1676
+ border-top: 1px solid rgba(229, 231, 235, 0.5);
1677
+ position: relative;
1678
+ }
1679
+
1680
+ /* 表情按钮包装 */
1681
+ .emoji-button-wrapper {
1682
+ position: relative;
1683
+ display: inline-block;
1646
1684
  }
1647
1685
 
1648
1686
  .pending-files-area {
@@ -1800,8 +1838,10 @@ onUnmounted(() => {
1800
1838
  /* ========== 右侧详情面板 ========== */
1801
1839
  .chat-detail-panel {
1802
1840
  width: 256px;
1803
- background-color: #f5f5f5;
1804
- border-left: 1px solid #e5e7eb;
1841
+ background: rgba(245, 245, 245, 0.5);
1842
+ backdrop-filter: blur(10px);
1843
+ -webkit-backdrop-filter: blur(10px);
1844
+ border-left: 1px solid rgba(229, 231, 235, 0.5);
1805
1845
  display: flex;
1806
1846
  flex-direction: column;
1807
1847
  }
@@ -1811,7 +1851,7 @@ onUnmounted(() => {
1811
1851
  display: flex;
1812
1852
  align-items: center;
1813
1853
  justify-content: center;
1814
- border-bottom: 1px solid #e5e7eb;
1854
+ border-bottom: 1px solid rgba(229, 231, 235, 0.5);
1815
1855
  font-weight: 500;
1816
1856
  color: #374151;
1817
1857
  font-size: 14px;
@@ -2074,10 +2114,12 @@ onUnmounted(() => {
2074
2114
  /* ========== 右键菜单 ========== */
2075
2115
  .chat-context-menu {
2076
2116
  position: fixed;
2077
- background-color: white;
2078
- border-radius: 8px;
2079
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
2080
- border: 1px solid #e5e7eb;
2117
+ background: rgba(255, 255, 255, 0.9);
2118
+ backdrop-filter: blur(20px);
2119
+ -webkit-backdrop-filter: blur(20px);
2120
+ border-radius: 12px;
2121
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
2122
+ border: 1px solid rgba(255, 255, 255, 0.3);
2081
2123
  padding: 4px 0;
2082
2124
  z-index: 1000;
2083
2125
  }
@@ -2087,9 +2129,12 @@ onUnmounted(() => {
2087
2129
  cursor: pointer;
2088
2130
  font-size: 14px;
2089
2131
  color: #374151;
2132
+ margin: 2px 4px;
2133
+ border-radius: 8px;
2134
+ transition: background-color 0.2s;
2090
2135
  }
2091
2136
 
2092
2137
  .chat-context-menu-item:hover {
2093
- background-color: #f3f4f6;
2138
+ background-color: rgba(243, 244, 246, 0.8);
2094
2139
  }
2095
2140
  </style>
@@ -325,7 +325,7 @@
325
325
  </div>
326
326
 
327
327
  <!-- 底部输入区域 -->
328
- <div class="input-area">
328
+ <div class="input-area" @click="showEmojiPicker = false">
329
329
  <!-- 待发送文件预览 -->
330
330
  <div
331
331
  v-if="pendingFiles.length > 0"
@@ -371,7 +371,16 @@
371
371
  </div>
372
372
 
373
373
  <div v-if="config.modules.fileUpload" class="input-actions">
374
- <el-icon class="action-icon"><ChatDotRound /></el-icon>
374
+ <div class="emoji-button-wrapper">
375
+ <el-icon
376
+ class="action-icon"
377
+ @click.stop="showEmojiPicker = !showEmojiPicker"
378
+ ><ChatDotRound /></el-icon>
379
+ <EmojiPicker
380
+ :visible="showEmojiPicker"
381
+ @select="selectEmoji"
382
+ />
383
+ </div>
375
384
  <el-icon
376
385
  class="action-icon"
377
386
  @click="triggerFileSelect"
@@ -667,6 +676,7 @@ import {
667
676
  import { useChat } from '../composables/useChat.js'
668
677
  import { ElMessage } from 'element-plus'
669
678
  import AvatarCrop from './AvatarCrop.vue'
679
+ import EmojiPicker from './EmojiPicker.vue'
670
680
 
671
681
  const props = defineProps({
672
682
  modelValue: { type: Boolean, default: false },
@@ -718,8 +728,7 @@ const {
718
728
  loadFriendApplyList,
719
729
  agreeFriend,
720
730
  updateMyAvatar,
721
- getUserInfo,
722
- updateUserInfo
731
+
723
732
  } = useChat(props.config)
724
733
 
725
734
  const navTabs = computed(() => {
@@ -751,6 +760,7 @@ const avatarImageSrc = ref('')
751
760
  const fileInputRef = ref(null)
752
761
  const pendingFiles = ref([])
753
762
  const contextMenu = ref({ visible: false, x: 0, y: 0, chat: null })
763
+ const showEmojiPicker = ref(false)
754
764
 
755
765
  const showContextMenuFn = (e, chat) => {
756
766
  e.preventDefault()
@@ -921,6 +931,11 @@ const handleImageError = (e) => {
921
931
  console.warn('图片加载失败', e)
922
932
  }
923
933
 
934
+ const selectEmoji = (emoji) => {
935
+ inputText.value += emoji
936
+ showEmojiPicker.value = false
937
+ }
938
+
924
939
  const handleAvatarFileChange = (e) => {
925
940
  const file = e.target.files[0]
926
941
  if (!file) return
@@ -1018,7 +1033,7 @@ const handleClosed = () => {
1018
1033
  }
1019
1034
 
1020
1035
  const handleOpen = async () => {
1021
- await Promise.all([getFriendList(), loadFriendApplyList(), getUserInfo()])
1036
+ await Promise.all([getFriendList(), loadFriendApplyList()])
1022
1037
  initWebSocket()
1023
1038
  if (filteredUsers.value.length > 0) {
1024
1039
  selectChat(filteredUsers.value[0])
@@ -1039,8 +1054,13 @@ onUnmounted(() => {
1039
1054
  <style scoped>
1040
1055
  .chat-dialog :deep(.el-dialog) {
1041
1056
  padding: 0;
1042
- border-radius: 12px;
1057
+ border-radius: 20px;
1043
1058
  overflow: hidden;
1059
+ background: rgba(255, 255, 255, 0.7);
1060
+ backdrop-filter: blur(20px);
1061
+ -webkit-backdrop-filter: blur(20px);
1062
+ border: 1px solid rgba(255, 255, 255, 0.3);
1063
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
1044
1064
  }
1045
1065
 
1046
1066
  .chat-dialog :deep(.el-dialog__header) {
@@ -1102,6 +1122,9 @@ onUnmounted(() => {
1102
1122
  .settings-dialog :deep(.el-dialog) {
1103
1123
  border-radius: 16px;
1104
1124
  overflow: hidden;
1125
+ background: rgba(255, 255, 255, 0.9);
1126
+ backdrop-filter: blur(20px);
1127
+ -webkit-backdrop-filter: blur(20px);
1105
1128
  }
1106
1129
 
1107
1130
  .settings-dialog :deep(.el-dialog__header) {
@@ -1119,7 +1142,7 @@ onUnmounted(() => {
1119
1142
  .chat-container {
1120
1143
  display: flex;
1121
1144
  height: 680px;
1122
- background-color: white;
1145
+ background: rgba(255, 255, 255, 0.7);
1123
1146
  overflow: hidden;
1124
1147
  }
1125
1148
 
@@ -1130,8 +1153,10 @@ onUnmounted(() => {
1130
1153
  flex-direction: column;
1131
1154
  align-items: center;
1132
1155
  gap: 8px;
1133
- background-color: #f9fafb;
1134
- border-right: 1px solid #e5e7eb;
1156
+ background: rgba(249, 250, 251, 0.6);
1157
+ backdrop-filter: blur(10px);
1158
+ -webkit-backdrop-filter: blur(10px);
1159
+ border-right: 1px solid rgba(229, 231, 235, 0.5);
1135
1160
  }
1136
1161
 
1137
1162
  .sidebar-avatar {
@@ -1194,8 +1219,10 @@ onUnmounted(() => {
1194
1219
  /* 内容面板 */
1195
1220
  .content-panel {
1196
1221
  width: 288px;
1197
- background-color: #f5f5f5;
1198
- border-right: 1px solid #e5e7eb;
1222
+ background: rgba(245, 245, 245, 0.5);
1223
+ backdrop-filter: blur(10px);
1224
+ -webkit-backdrop-filter: blur(10px);
1225
+ border-right: 1px solid rgba(229, 231, 235, 0.5);
1199
1226
  display: flex;
1200
1227
  flex-direction: column;
1201
1228
  }
@@ -1217,14 +1244,16 @@ onUnmounted(() => {
1217
1244
  padding: 12px;
1218
1245
  cursor: pointer;
1219
1246
  transition: background-color 0.2s;
1247
+ border-radius: 8px;
1248
+ margin: 0 8px;
1220
1249
  }
1221
1250
 
1222
1251
  .chat-item:hover {
1223
- background-color: #e5e5e5;
1252
+ background: rgba(229, 229, 229, 0.6);
1224
1253
  }
1225
1254
 
1226
1255
  .chat-item-active {
1227
- background-color: #d6d6d6;
1256
+ background: rgba(7, 193, 96, 0.15);
1228
1257
  }
1229
1258
 
1230
1259
  .friend-avatar-wrapper {
@@ -1383,7 +1412,9 @@ onUnmounted(() => {
1383
1412
  display: flex;
1384
1413
  flex-direction: column;
1385
1414
  min-width: 0;
1386
- background-color: white;
1415
+ background: rgba(255, 255, 255, 0.5);
1416
+ backdrop-filter: blur(10px);
1417
+ -webkit-backdrop-filter: blur(10px);
1387
1418
  }
1388
1419
 
1389
1420
  .friend-profile {
@@ -1393,7 +1424,7 @@ onUnmounted(() => {
1393
1424
  align-items: center;
1394
1425
  justify-content: center;
1395
1426
  padding: 32px;
1396
- background-color: #f5f5f5;
1427
+ background: rgba(245, 245, 245, 0.4);
1397
1428
  }
1398
1429
 
1399
1430
  .profile-avatar {
@@ -1446,12 +1477,14 @@ onUnmounted(() => {
1446
1477
 
1447
1478
  .chat-header {
1448
1479
  height: 56px;
1449
- border-bottom: 1px solid #e5e7eb;
1480
+ border-bottom: 1px solid rgba(229, 231, 235, 0.5);
1450
1481
  display: flex;
1451
1482
  align-items: center;
1452
1483
  justify-content: space-between;
1453
1484
  padding: 0 16px;
1454
- background-color: white;
1485
+ background: rgba(255, 255, 255, 0.3);
1486
+ backdrop-filter: blur(10px);
1487
+ -webkit-backdrop-filter: blur(10px);
1455
1488
  }
1456
1489
 
1457
1490
  .chat-title {
@@ -1500,7 +1533,7 @@ onUnmounted(() => {
1500
1533
  flex: 1;
1501
1534
  overflow-y: auto;
1502
1535
  padding: 16px;
1503
- background-color: #f5f5f5;
1536
+ background: rgba(245, 245, 245, 0.3);
1504
1537
  min-height: 0;
1505
1538
  }
1506
1539
 
@@ -1675,13 +1708,22 @@ onUnmounted(() => {
1675
1708
 
1676
1709
  /* 输入区域 */
1677
1710
  .input-area {
1678
- background-color: white;
1679
- border-top: 1px solid #e5e7eb;
1711
+ background: rgba(255, 255, 255, 0.6);
1712
+ backdrop-filter: blur(10px);
1713
+ -webkit-backdrop-filter: blur(10px);
1714
+ border-top: 1px solid rgba(229, 231, 235, 0.5);
1715
+ position: relative;
1716
+ }
1717
+
1718
+ /* 表情按钮包装器 */
1719
+ .emoji-button-wrapper {
1720
+ position: relative;
1721
+ display: inline-block;
1680
1722
  }
1681
1723
 
1682
1724
  .pending-files {
1683
1725
  padding: 8px 12px;
1684
- border-bottom: 1px solid #f3f4f6;
1726
+ border-bottom: 1px solid rgba(243, 244, 246, 0.5);
1685
1727
  display: flex;
1686
1728
  flex-wrap: wrap;
1687
1729
  gap: 8px;
@@ -1697,7 +1739,7 @@ onUnmounted(() => {
1697
1739
  height: 80px;
1698
1740
  border-radius: 8px;
1699
1741
  overflow: hidden;
1700
- border: 1px solid #e5e7eb;
1742
+ border: 1px solid rgba(229, 231, 235, 0.5);
1701
1743
  }
1702
1744
 
1703
1745
  .pending-image {
@@ -1711,8 +1753,8 @@ onUnmounted(() => {
1711
1753
  width: 96px;
1712
1754
  height: 80px;
1713
1755
  border-radius: 8px;
1714
- border: 1px solid #e5e7eb;
1715
- background-color: #f9fafb;
1756
+ border: 1px solid rgba(229, 231, 235, 0.5);
1757
+ background: rgba(249, 250, 251, 0.6);
1716
1758
  display: flex;
1717
1759
  flex-direction: column;
1718
1760
  align-items: center;
@@ -1777,6 +1819,7 @@ onUnmounted(() => {
1777
1819
  outline: none;
1778
1820
  font-size: 14px;
1779
1821
  height: 80px;
1822
+ background: transparent;
1780
1823
  }
1781
1824
 
1782
1825
  .send-btn-wrapper {
@@ -1807,7 +1850,7 @@ onUnmounted(() => {
1807
1850
  align-items: center;
1808
1851
  justify-content: center;
1809
1852
  flex-direction: column;
1810
- background-color: #f5f5f5;
1853
+ background: rgba(245, 245, 245, 0.3);
1811
1854
  }
1812
1855
 
1813
1856
  .empty-icon {
@@ -1822,8 +1865,10 @@ onUnmounted(() => {
1822
1865
  /* 详情面板 */
1823
1866
  .detail-panel {
1824
1867
  width: 256px;
1825
- background-color: #f5f5f5;
1826
- border-left: 1px solid #e5e7eb;
1868
+ background: rgba(245, 245, 245, 0.5);
1869
+ backdrop-filter: blur(10px);
1870
+ -webkit-backdrop-filter: blur(10px);
1871
+ border-left: 1px solid rgba(229, 231, 235, 0.5);
1827
1872
  display: flex;
1828
1873
  flex-direction: column;
1829
1874
  }
@@ -1833,7 +1878,7 @@ onUnmounted(() => {
1833
1878
  display: flex;
1834
1879
  align-items: center;
1835
1880
  justify-content: center;
1836
- border-bottom: 1px solid #e5e7eb;
1881
+ border-bottom: 1px solid rgba(229, 231, 235, 0.5);
1837
1882
  font-weight: 500;
1838
1883
  color: #374151;
1839
1884
  }
@@ -2074,10 +2119,12 @@ onUnmounted(() => {
2074
2119
  /* 右键菜单 */
2075
2120
  .context-menu {
2076
2121
  position: fixed;
2077
- background-color: white;
2078
- border-radius: 8px;
2079
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
2080
- border: 1px solid #e5e7eb;
2122
+ background: rgba(255, 255, 255, 0.9);
2123
+ backdrop-filter: blur(20px);
2124
+ -webkit-backdrop-filter: blur(20px);
2125
+ border-radius: 12px;
2126
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
2127
+ border: 1px solid rgba(255, 255, 255, 0.3);
2081
2128
  padding: 4px 0;
2082
2129
  z-index: 1000;
2083
2130
  }
@@ -2086,9 +2133,12 @@ onUnmounted(() => {
2086
2133
  padding: 8px 16px;
2087
2134
  cursor: pointer;
2088
2135
  font-size: 14px;
2136
+ margin: 2px 4px;
2137
+ border-radius: 8px;
2138
+ transition: background-color 0.2s;
2089
2139
  }
2090
2140
 
2091
2141
  .context-menu-item:hover {
2092
- background-color: #f3f4f6;
2142
+ background: rgba(243, 244, 246, 0.8);
2093
2143
  }
2094
2144
  </style>