This commit is contained in:
oneao committed 2025-10-13 17:32:02 +08:00
1 parent a6c5e70f85
commit 2598098876
8 files changed
+646 -45

No files matched your search

+525 -34
View File
@@ -36,26 +36,48 @@ import Icon from '@/components/icon.vue'
</div>
<div class="im__body">
<div class="im__list">
<div class="im__list-input">
<div class="im__list-search">
<el-input placeholder="请根据名称搜索" :prefix-icon="Search" />
</div>
<div class="im__list-item">
<div class="im__list-header">
单聊
<Icon icon="tabler:message-circle" :size="16" />
<span class="im__list-header-title">
单聊
</span>
</div>
<div class="im__list-body">
<div class="im__chat-user">
<Avatar name="A" />
<div class="im__chat-user-info">
<div class="im__chat-user-main">
<div class="im__chat-user-name">张三</div>
<div class="im__chat-user-last-time">聊天时间</div>
<div
v-for="i in 10" :key="i" class="im__chat-item im__chat-item"
:class="[{ 'im__chat-item--selected': i === 1 }]"
>
<el-badge
is-dot
color="#24e68a"
:badge-style="{
width: '12px',
height: '12px',
}"
:offset="[-4, 34]"
>
<!-- 未登录:b3b7c2 -->
<Avatar name="A" class="im__chat-item-avatar" />
</el-badge>
<div class="im__chat-item-info">
<div class="im__chat-item-main">
<div class="im__chat-item-name">
张三张三张三张三张三张三张三张三张三张三
</div>
<div class="im__chat-item-last-time">
10:20
</div>
</div>
<div class="im__chat-user-message">
<div class="im__chat-user-last-message">下周一起吃个饭</div>
<div class="im__chat-user-unread-count">2</div>
<div class="im__chat-item-message">
<div class="im__chat-item-last-message">
下周下周下周下周下周下周下周下周下周下周
</div>
<el-badge :value="100" :max="10" class="im__chat-item-unread-count" />
</div>
</div>
</div>
@@ -63,23 +85,160 @@ import Icon from '@/components/icon.vue'
</div>
<div class="im__list-item">
<div class="im__list-header">
群聊
<Icon icon="bi:people" :size="16" />
<span class="im__list-header-title">
群聊
</span>
</div>
<div class="im__list-body">
<div>
Operation feedback: enable the users to clearly perceive their
operations by style updates and interactive effects;
</div>
<div>
Visual feedback: reflect current state by updating or rearranging
elements of the page.
<div v-for="i in 10" :key="i" class="im__chat-item">
<Avatar name="#" class="im__chat-item-avatar" bg-color="#574b90" />
<div class="im__chat-item-info">
<div class="im__chat-item-main">
<div class="im__chat-item-name">
张三张三张三张三张三张三张三张三张三张三
</div>
<div class="im__chat-item-last-time">
10:20
</div>
</div>
<div class="im__chat-item-message">
<div class="im__chat-item-last-message">
下周下周下周下周下周下周下周下周下周下周
</div>
<el-badge :value="100" :max="10" class="im__chat-item-unread-count" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="im__window">
chat
<div class="im__window-header">
<div class="im__window-peer">
<div class="im__window-peer-avatar">
<Avatar name="A" />
</div>
<div class="im__window-peer-info">
<div class="im__window-peer-name">
张三
</div>
<div class="im__window-peer-desc">
<div class="im__window-peer-status im__window-peer-status--online">
<span>[ </span>
<div class="im__window-peer-status-dot" />
<span>在线</span>
<span> ]</span>
</div>
<span>
公司描述等等等...
</span>
</div>
</div>
</div>
<div class="im__window-actions" />
</div>
<div class="im__window-body">
<el-splitter layout="vertical">
<el-splitter-panel>
<div class="im__chat-main">
<div class="im__chat-message im__chat-message--from">
<div class="im__chat-message-avatar">
<Avatar name="A" />
</div>
<div class="im__chat-message-body">
<div class="im__chat-message-name">
张三
</div>
<div class="im__chat-message-content">
<div class="im__chat-message-content--text">
这是一条文本消息这是一条文本消息这是一条文本消息这是一条文本消息这是一条文本消息这是一条文本消息这是一条文本消息这是一条文本消息
</div>
</div>
</div>
</div>
<div class="im__chat-message im__chat-message--to">
<Avatar name="B" />
<div class="im__chat-message-body">
<div class="im__chat-message-name">
张三
</div>
<div class="im__chat-message-content">
<div class="im__chat-message-content--text">
这是一条文本消息
</div>
</div>
</div>
</div>
</div>
</el-splitter-panel>
<el-splitter-panel :min="100" :max="300" :size="150">
<div class="im__chat-footer">
<div class="im__chat-toolbar">
<Icon icon="proicons:emoji" />
<div class="im__chat-toolbar-right">
<Icon
icon="solar:history-broken"
/>
</div>
</div>
<div class="im__chat-editor">
<div
class="im__chat-editor-input"
contenteditable="true"
/>
</div>
<div class="im__chat-sendarea">
<el-button type="primary" size="small" class="im__chat-send">
发送(回车)
</el-button>
</div>
</div>
</el-splitter-panel>
</el-splitter>
<div class="im__chat-group">
<div class="im__group-section-header">
<!-- <el-input placeholder="请根据名称搜索" :prefix-icon="Search" /> -->
<div class="im__group-section-header-title">
<Icon icon="bi:people" :size="18" color="#666666" />
<span class="im__group-section-header-text">群成员(222)</span>
</div>
<div class="im__group-section-header-extra">
<div class="im__group-section-header--search">
<Icon icon="lucide:search" :size="16" />
</div>
</div>
</div>
<div class="im__group-section-body">
<div v-for="i in 20" :key="i" class="im__group-item">
<el-badge
is-dot
color="#24e68a"
:badge-style="{
width: '12px',
height: '12px',
}"
:offset="[-4, 34]"
>
<!-- 未登录:b3b7c2 -->
<Avatar name="A" />
</el-badge>
<div class="im__group-item-info">
<div class="im__group-item-name">
name
</div>
<div class="im__group-item-desc">
desc
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -96,23 +255,23 @@ import Icon from '@/components/icon.vue'
background-color: #f5f6fa;
& *::-webkit-scrollbar {
width: 8px;
height: 8px;
width: 6px;
height: 6px;
}
& *::-webkit-scrollbar-track {
background-color: #f1f1f1;
border-radius: 10px;
background-color: #fff;
border-radius: 3px;
}
& *::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 10px;
border: 2px solid #f1f1f1;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 3px;
transition: background-color 0.2s ease;
}
& *::-webkit-scrollbar-thumb:hover {
background-color: #555;
background-color: rgba(0, 0, 0, 0.4);
}
.im__container {
@@ -208,9 +367,9 @@ import Icon from '@/components/icon.vue'
flex-direction: column;
min-height: 0;
.im__list-input {
.im__list-search {
padding: 10px;
background-color: #1553f1;
border-bottom: 1px solid #e6e9ef;
}
.im__list-item {
@@ -218,26 +377,104 @@ import Icon from '@/components/icon.vue'
flex-direction: column;
flex: 1;
min-height: 0;
transition: background-color 0.25s ease;
.im__list-header {
font-size: 14px;
padding: 8px 10px;
background-color: #f8f9fc;
flex-shrink: 0;
display: flex;
align-items: center;
.im__list-header-title {
margin-left: 4px;
}
}
.im__list-body {
overflow-y: auto;
flex: 1;
min-height: 0;
.im__chat-user {
.im__chat-item {
display: flex;
align-items: center;
height: 56px;
width: 100%;
padding: 0 10px;
overflow-x: hidden;
&:hover {
background-color: #f5f7fa;
cursor: pointer;
}
.im__chat-item-avatar {
flex-shrink: 0;
}
.im__chat-item-info {
display: flex;
flex-direction: column;
flex: 1;
margin-left: 10px;
min-width: 0;
.im__chat-item-main,
.im__chat-item-message {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.im__chat-item-message {
margin-top: 4px;
}
.im__chat-item-name {
font-size: 14px;
font-weight: 500;
}
.im__chat-item-last-time,
.im__chat-item-last-message {
flex-shrink: 0;
color: #666;
font-size: 12px;
}
.im__chat-item-last-message,
.im__chat-item-name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.im__chat-item-last-time {
margin-left: 8px;
}
.im__chat-item-unread-count {
display: flex;
margin-left: 8px;
}
}
}
.im__chat-item--selected {
position: relative;
background-color: #f0f6ff;
transition: background-color 0.25s ease;
&::before {
content: '';
position: absolute;
left: 0;
top: 4px;
bottom: 4px;
width: 3px;
background-color: #3b82f6;
border-radius: 2px;
box-shadow: 0 0 4px rgba(59, 130, 246, 0.4);
}
}
}
}
@@ -246,8 +483,262 @@ import Icon from '@/components/icon.vue'
.im__window {
flex: 1;
background-color: #fff;
padding: 10px;
overflow-y: auto;
display: flex;
flex-direction: column;
.im__window-header {
height: 64px;
border-bottom: 1px solid #e6e9ef;
display: flex;
align-items: center;
flex-shrink: 0;
.im__window-peer {
display: flex;
align-items: center;
padding: 0px 12px;
.im__window-peer-info {
margin-left: 8px;
.im__window-peer-name {
font-size: 16px;
line-height: 1;
}
.im__window-peer-desc {
display: flex;
align-items: center;
font-size: 12px;
line-height: 1;
margin-top: 6px;
color: #666;
height: 12px;
.im__window-peer-status {
display: flex;
align-items: center;
margin-right: 4px;
.im__window-peer-status-dot {
width: 12px;
height: 12px;
border-radius: 50%;
margin: 0px 4px;
}
}
.im__window-peer-status--online {
.im__window-peer-status-dot {
background-color: #24e68a;
}
}
.im__window-peer-status--offline {
.im__window-peer-status-dot {
background-color: #b3b7c2;
}
}
}
}
}
}
.im__window-body {
flex: 1;
display: flex;
min-height: 0;
:deep(.el-splitter-panel) {
scrollbar-width: auto;
}
.im__chat-main {
padding: 16px 8px;
display: flex;
flex-direction: column;
gap: 14px;
width: 100%;
scrollbar-gutter: stable both-edges;
overflow-y: auto;
min-width: 0;
background-color: #f8fafc;
height: 100%;
.im__chat-message {
display: flex;
width: fit-content;
max-width: 70%;
.im__chat-message-avatar {
flex-shrink: 0;
}
.im__chat-message-body {
.im__chat-message-name {
font-size: 14px;
line-height: 1;
}
.im__chat-message-content {
display: inline-flex;
flex-direction: column;
margin-top: 8px;
}
.im__chat-message-content--text {
background-color: #ffffff;
color: #000000;
word-break: break-all;
padding: 6px 12px;
border-radius: 4px;
}
}
}
.im__chat-message--from {
align-items: flex-start;
.im__chat-message-body {
margin-left: 8px;
}
}
.im__chat-message--to {
align-self: flex-end;
flex-direction: row-reverse;
.im__chat-message-body {
margin-right: 8px;
.im__chat-message-content--text {
background-color: #3c73ff;
color: #fff;
}
.im__chat-message-name {
text-align: right;
}
}
}
}
.im__chat-group {
width: 300px;
border-left: 1px solid #e6e9ef;
min-height: 0;
display: flex;
flex-direction: column;
flex-shrink: 0;
.im__group-section-header {
height: 46px;
border-bottom: 1px solid #e6e9ef;
display: flex;
align-items: center;
padding: 0px 8px;
justify-content: space-between;
.im__group-section-header-title {
display: flex;
align-items: center;
}
.im__group-section-header-text {
margin-left: 4px;
line-height: 1;
font-size: 14px;
}
.im__group-section-header--search {
cursor: pointer;
color: #666666;
&:hover {
color: #1553f1 !important;
}
}
}
.im__group-section-body {
flex: 1;
display: flex;
flex-direction: column;
overflow-y: auto;
min-height: 0;
.im__group-item {
height: 56px;
padding: 0 10px;
display: flex;
align-items: center;
cursor: pointer;
flex-shrink: 0;
&:hover {
background-color: #f5f7fa;
}
.im__group-item-info {
margin-left: 8px;
.im__group-item-name {
line-height: 1;
font-size: 14px;
}
.im__group-item-desc {
margin-top: 6px;
font-size: 12px;
color: #666;
}
}
}
}
}
.im__chat-footer {
display: flex;
flex-direction: column;
min-height: 0;
width: 100%;
height: 100%;
.im__chat-toolbar {
height: 36px;
flex-shrink: 0;
display: flex;
align-items: center;
padding: 0px 8px;
gap: 8px;
.im__chat-toolbar-right {
margin-left: auto;
}
}
.im__chat-editor {
display: flex;
flex-direction: column;
height: 100%;
overflow-y: auto;
flex: 1;
min-height: 0;
width: 100%;
scrollbar-gutter: stable both-edges;
.im__chat-editor-input {
padding: 4px;
flex: 1;
// overflow-y: auto;
box-sizing: border-box;
border: none;
resize: none;
background-color: transparent;
outline: none;
word-wrap: break-word;
word-break: break-all;
white-space: pre-wrap;
-webkit-user-select: text;
-moz-user-select: text;
user-select: text;
cursor: text;
}
}
.im__chat-sendarea {
height: 36px;
flex-shrink: 0;
display: flex;
align-items: center;
margin-left: auto;
padding: 0px 16px;
.im__chat-send {
background-color: #1553f1;
}
}
}
}
}
}
</style>