Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
foreign
/
customer-service
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
a5b8ff29
authored
Sep 06, 2021
by
Sixong.Zhu
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
style
parent
ebbb6725
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
334 additions
and
306 deletions
components/message-list.vue
components/message.vue
components/message-list.vue
View file @
a5b8ff29
<
template
>
<
template
>
<div
v-loading=
"chatIniting"
class=
"message-list h-100"
>
<div
v-loading=
"chatIniting"
class=
"message-list h-100"
>
<el-scrollbar
<el-scrollbar
ref=
"message-scrollbar"
ref=
"message-scrollbar"
class=
"
class=
"
message-list-scrollbar
message-list-scrollbar
no-bottom-scrollbar
no-bottom-scrollbar
adjust-el-scroll-right-bar
adjust-el-scroll-right-bar
h-100
h-100
"
"
>
>
<template
v-for=
"item in messages"
>
<template
v-for=
"item in messages"
>
<div
:key=
"item.id"
class=
"message-template"
>
<div
:key=
"item.id"
class=
"message-template"
>
<div
<div
v-if=
"
v-if=
"
item.id > 0 && messageTimestampDictionary[item.id] && item.msg
item.id > 0 &&
"
messageTimestampDictionary[item.id] &&
class=
"text-center text-hint timestamp"
item.msg
>
"
{{
format2Time
(
item
.
ts
)
}}
class=
"text-center text-hint timestamp"
</div>
>
<message
{{
format2Time
(
item
.
ts
)
}}
:is-sending-message=
"item.id
<
0
"
</div>
:failed=
"item.status === -1"
<message
:key=
"item.id"
:is-sending-message=
"item.id
<
0
"
:data=
"item"
:failed=
"item.status === -1"
:shape=
"shape"
:key=
"item.id"
@
open=
"open"
:data=
"item"
/>
:shape=
"shape"
</div>
@
open=
"open"
</
template
>
/>
</el-scrollbar>
</div>
</
template
>
<image-preview
v-model=
"preview"
:file=
"imagePreview"
></image-preview>
</el-scrollbar>
<video-preview
v-model=
"previewVideo"
:file=
"videoPreview"
></video-preview>
</div>
<image-preview
v-model=
"preview"
:file=
"imagePreview"
></image-preview>
<video-preview
v-model=
"previewVideo"
:file=
"videoPreview"
></video-preview>
</div>
</template>
</template>
<
script
lang=
"ts"
>
<
script
lang=
"ts"
>
...
@@ -51,325 +56,331 @@ import { ChatStore, chatStore } from "@/customer-service/store/model";
...
@@ -51,325 +56,331 @@ import { ChatStore, chatStore } from "@/customer-service/store/model";
@
Component
({
components
:
{
message
,
ImagePreview
,
VideoPreview
}
})
@
Component
({
components
:
{
message
,
ImagePreview
,
VideoPreview
}
})
export
default
class
MessageList
extends
Vue
{
export
default
class
MessageList
extends
Vue
{
@
chatStore
.
Getter
(
ChatStore
.
STATE_CHAT_MSG_HISTORY
)
@
chatStore
.
Getter
(
ChatStore
.
STATE_CHAT_MSG_HISTORY
)
private
readonly
historyMessage
!
:
ChatStore
.
STATE_CHAT_MSG_HISTORY
;
private
readonly
historyMessage
!
:
ChatStore
.
STATE_CHAT_MSG_HISTORY
;
@
chatStore
.
Getter
(
ChatStore
.
STATE_CHAT_SENDING_MESSAGES
)
@
chatStore
.
Getter
(
ChatStore
.
STATE_CHAT_SENDING_MESSAGES
)
private
readonly
sendingMessages
!
:
ChatStore
.
STATE_CHAT_SENDING_MESSAGES
;
private
readonly
sendingMessages
!
:
ChatStore
.
STATE_CHAT_SENDING_MESSAGES
;
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
)
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
)
private
readonly
chatId
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
;
private
readonly
chatId
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
;
@
chatStore
.
State
(
ChatStore
.
STATE_CURRENT_CHAT_INITING
)
@
chatStore
.
State
(
ChatStore
.
STATE_CURRENT_CHAT_INITING
)
private
readonly
chatIniting
!
:
ChatStore
.
STATE_CURRENT_CHAT_INITING
;
private
readonly
chatIniting
!
:
ChatStore
.
STATE_CURRENT_CHAT_INITING
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES_BEFORE_SPECIFIC_ID
)
@
chatStore
.
Action
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES_BEFORE_SPECIFIC_ID
)
private
readonly
getLastPageMsg
!
:
ChatStore
.
ACTION_GET_CHAT_MESSAGES_BEFORE_SPECIFIC_ID
;
private
readonly
getLastPageMsg
!
:
ChatStore
.
ACTION_GET_CHAT_MESSAGES_BEFORE_SPECIFIC_ID
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES_AFTER_SPECIFIC_ID
)
@
chatStore
.
Action
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES_AFTER_SPECIFIC_ID
)
private
readonly
getNextPageMsg
!
:
ChatStore
.
ACTION_GET_CHAT_MESSAGES_AFTER_SPECIFIC_ID
;
private
readonly
getNextPageMsg
!
:
ChatStore
.
ACTION_GET_CHAT_MESSAGES_AFTER_SPECIFIC_ID
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
)
@
chatStore
.
Action
(
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
)
private
readonly
clearChatId
!
:
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
;
private
readonly
clearChatId
!
:
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_SAVE_FUNC_SCROLL_TO_BOTTOM
)
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_SAVE_FUNC_SCROLL_TO_BOTTOM
)
private
readonly
saveScrollToBottomFunc
!
:
ChatStore
.
MUTATION_SAVE_FUNC_SCROLL_TO_BOTTOM
;
private
readonly
saveScrollToBottomFunc
!
:
ChatStore
.
MUTATION_SAVE_FUNC_SCROLL_TO_BOTTOM
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_CLEAR_FUNC_SCROLL_TO_BOTTOM
)
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_CLEAR_FUNC_SCROLL_TO_BOTTOM
)
private
readonly
clearScrollToBottomFunc
!
:
ChatStore
.
MUTATION_CLEAR_FUNC_SCROLL_TO_BOTTOM
;
private
readonly
clearScrollToBottomFunc
!
:
ChatStore
.
MUTATION_CLEAR_FUNC_SCROLL_TO_BOTTOM
;
@
Prop
({
default
:
"circle"
})
@
Prop
({
default
:
"circle"
})
private
shape
!
:
string
;
private
shape
!
:
string
;
private
get
messages
()
{
private
get
messages
()
{
if
(
this
.
historyMessage
)
{
if
(
this
.
historyMessage
)
{
if
(
this
.
sendingMessages
)
{
if
(
this
.
sendingMessages
)
{
return
[...
this
.
historyMessage
,
...
this
.
sendingMessages
].
filter
(
return
[...
this
.
historyMessage
,
...
this
.
sendingMessages
].
filter
(
(
i
)
=>
i
.
chat_id
===
this
.
chatId
(
i
)
=>
i
.
chat_id
===
this
.
chatId
);
);
}
}
return
this
.
historyMessage
;
return
this
.
historyMessage
;
}
}
if
(
this
.
sendingMessages
)
{
if
(
this
.
sendingMessages
)
{
return
this
.
sendingMessages
.
filter
((
i
)
=>
i
.
chat_id
===
this
.
chatId
);
return
this
.
sendingMessages
.
filter
(
(
i
)
=>
i
.
chat_id
===
this
.
chatId
);
}
return
[];
}
}
return
[];
// 添加时间戳的最大间隔消息数
}
private
readonly
timeLimit
=
48
;
// 添加时间戳的最大间隔消息数
private
scroll2EndWhenMessageLoaded
=
false
;
private
readonly
timeLimit
=
48
;
private
scroll2EndWhenMessageLoaded
=
false
;
private
preview
=
false
;
private
imagePreview
=
{};
private
preview
=
false
;
private
previewVideo
=
false
;
private
image
Preview
=
{};
private
video
Preview
=
{};
private
previewVideo
=
false
;
@
Ref
(
"message-scrollbar"
)
private
videoPreview
=
{};
private
scollbarElement
!
:
Vue
&
{
update
:
()
=>
void
;
};
@
Ref
(
"message-scrollbar"
)
private
get
scollWrapper
():
HTMLElement
|
null
{
private
scollbarElement
!
:
Vue
&
{
return
this
.
scollbarElement
?.
$el
?.
firstChild
as
HTMLElement
;
update
:
()
=>
void
;
}
};
private
get
scollWrapper
():
HTMLElement
|
null
{
@
Watch
(
"messages"
)
return
this
.
scollbarElement
?.
$el
?.
firstChild
as
HTMLElement
;
private
whenHasMessages
()
{
}
this
.
$nextTick
(()
=>
this
.
scollbarElement
.
update
());
}
@
Watch
(
"messages"
)
@
Watch
(
"preview"
)
private
whenHasMessages
()
{
private
onPreviewChanged
()
{
this
.
$nextTick
(()
=>
this
.
scollbarElement
.
update
());
if
(
!
this
.
preview
)
{
}
this
.
raiseFileOpen
(
false
);
}
}
@
Watch
(
"preview"
)
@
Watch
(
"previewVideo"
)
private
onPreviewChanged
()
{
private
onVideoPreviewChanged
()
{
if
(
!
this
.
preview
)
{
if
(
!
this
.
previewVideo
)
{
this
.
raiseFileOpen
(
false
);
this
.
raiseFileOpen
(
false
);
}
}
}
}
@
Watch
(
"previewVideo"
)
private
raiseFileOpen
(
value
:
boolean
)
{
private
onVideoPreviewChanged
()
{
this
.
$emit
(
"file-open"
,
value
);
if
(
!
this
.
previewVideo
)
{
this
.
raiseFileOpen
(
false
);
}
}
}
private
get
messageTimestampDictionary
()
{
private
raiseFileOpen
(
value
:
boolean
)
{
const
dic
=
{}
as
{
[
prop
:
number
]:
boolean
};
this
.
$emit
(
"file-open"
,
value
);
let
count
=
0
;
}
if
(
this
.
historyMessage
)
{
private
get
messageTimestampDictionary
()
{
this
.
historyMessage
.
forEach
((
message
,
index
,
array
)
=>
{
const
dic
=
{}
as
{
[
prop
:
number
]:
boolean
};
if
(
let
count
=
0
;
index
===
0
||
this
.
whetherShowTime
(
array
[
index
-
1
],
message
)
||
if
(
this
.
historyMessage
)
{
count
===
this
.
timeLimit
-
1
this
.
historyMessage
.
forEach
((
message
,
index
,
array
)
=>
{
)
{
if
(
dic
[
message
.
id
]
=
true
;
index
===
0
||
count
=
0
;
this
.
whetherShowTime
(
array
[
index
-
1
],
message
)
||
}
else
{
count
===
this
.
timeLimit
-
1
count
++
;
)
{
}
dic
[
message
.
id
]
=
true
;
});
count
=
0
;
}
else
{
count
++
;
}
}
});
return
dic
;
}
private
loading
=
false
;
private
loadingOld
=
false
;
private
loadingNew
=
false
;
public
created
()
{
this
.
handleScrollWrapper
();
}
public
mounted
()
{
this
.
scollWrapper
&&
this
.
scollWrapper
.
addEventListener
(
"scroll"
,
this
.
handleScroll
);
this
.
saveScrollToBottomFunc
(
this
.
scrollToNewMsg
);
this
.
scrollToNewMsg
();
}
public
beforeDestroy
()
{
this
.
scollWrapper
&&
this
.
scollWrapper
.
removeEventListener
(
"scroll"
,
this
.
handleScroll
);
this
.
clearScrollToBottomFunc
();
// this.clearChatId();
}
public
scroll2End
(
delay
?:
number
)
{
this
.
$nextTick
(()
=>
{
const
wrap
=
this
.
scollbarElement
?.
$el
.
querySelector
(
".el-scrollbar__wrap"
)
as
HTMLElement
;
if
(
wrap
)
{
if
(
delay
)
{
setTimeout
(()
=>
{
wrap
.
scrollTop
=
100000
;
},
delay
);
return
;
}
wrap
.
scrollTop
=
100000
;
}
});
}
private
startLoading
()
{
this
.
loading
=
true
;
}
private
endLoading
()
{
this
.
loading
=
false
;
}
private
startLoadingOld
()
{
this
.
startLoading
();
this
.
loadingOld
=
true
;
}
}
return
dic
;
private
endLoadingOld
()
{
}
this
.
endLoading
();
this
.
loadingOld
=
false
;
private
loading
=
false
;
}
private
loadingOld
=
false
;
private
loadingNew
=
false
;
private
startLoadingNew
()
{
this
.
startLoading
();
public
created
()
{
this
.
loadingNew
=
true
;
this
.
handleScrollWrapper
();
}
}
private
endLoadingNew
()
{
public
mounted
()
{
this
.
endLoading
();
this
.
scollWrapper
&&
this
.
loadingNew
=
false
;
this
.
scollWrapper
.
addEventListener
(
"scroll"
,
this
.
handleScroll
);
}
this
.
saveScrollToBottomFunc
(
this
.
scrollToNewMsg
);
this
.
scrollToNewMsg
();
private
handleScroll
!
:
()
=>
void
;
}
private
handleScrollWrapper
()
{
let
oldScrollTop
=
0
;
public
beforeDestroy
()
{
this
.
handleScroll
=
()
=>
{
this
.
scollWrapper
&&
const
wrapper
=
this
.
scollWrapper
;
this
.
scollWrapper
.
removeEventListener
(
"scroll"
,
this
.
handleScroll
);
const
gap
=
150
;
this
.
clearScrollToBottomFunc
();
if
(
wrapper
==
null
)
return
;
// this.clearChatId();
const
view
=
wrapper
.
firstChild
as
HTMLElement
;
}
const
wrapperH
=
wrapper
.
getBoundingClientRect
().
height
;
const
viewH
=
view
.
getBoundingClientRect
().
height
;
public
scroll2End
(
delay
?:
number
)
{
let
scrollUp
=
false
;
this
.
$nextTick
(()
=>
{
let
scrollDown
=
false
;
const
wrap
=
this
.
scollbarElement
?.
$el
.
querySelector
(
if
(
oldScrollTop
>
wrapper
.
scrollTop
)
{
".el-scrollbar__wrap"
scrollUp
=
true
;
)
as
HTMLElement
;
scrollDown
=
false
;
if
(
wrap
)
{
}
else
if
(
oldScrollTop
<
wrapper
.
scrollTop
)
{
if
(
delay
)
{
scrollUp
=
false
;
setTimeout
(()
=>
{
scrollDown
=
true
;
wrap
.
scrollTop
=
100000
;
}
},
delay
);
this
.
forbidScrollTopToZero
(
wrapper
);
return
;
if
(
wrapper
.
scrollTop
<=
gap
)
{
scrollUp
&&
this
.
fetchOldMsg
();
}
if
(
wrapper
.
scrollTop
-
40
-
(
viewH
-
wrapperH
)
>=
-
gap
)
{
scrollDown
&&
this
.
fetchNewMsg
();
}
oldScrollTop
=
wrapper
.
scrollTop
;
};
}
/* scrollTop为0时,新加载的消息后,滚动条也会保持在0的位置 */
private
forbidScrollTopToZero
(
ele
:
HTMLElement
)
{
if
(
ele
.
scrollTop
<=
10
)
{
ele
.
scrollTop
=
10
;
}
}
wrap
.
scrollTop
=
100000
;
}
}
});
}
private
startLoading
()
{
this
.
loading
=
true
;
}
private
endLoading
()
{
this
.
loading
=
false
;
}
private
startLoadingOld
()
{
this
.
startLoading
();
this
.
loadingOld
=
true
;
}
private
endLoadingOld
()
{
this
.
endLoading
();
this
.
loadingOld
=
false
;
}
private
startLoadingNew
()
{
this
.
startLoading
();
this
.
loadingNew
=
true
;
}
private
endLoadingNew
()
{
this
.
endLoading
();
this
.
loadingNew
=
false
;
}
private
handleScroll
!
:
()
=>
void
;
private
handleScrollWrapper
()
{
let
oldScrollTop
=
0
;
this
.
handleScroll
=
()
=>
{
const
wrapper
=
this
.
scollWrapper
;
const
gap
=
150
;
if
(
wrapper
==
null
)
return
;
const
view
=
wrapper
.
firstChild
as
HTMLElement
;
const
wrapperH
=
wrapper
.
getBoundingClientRect
().
height
;
const
viewH
=
view
.
getBoundingClientRect
().
height
;
let
scrollUp
=
false
;
let
scrollDown
=
false
;
if
(
oldScrollTop
>
wrapper
.
scrollTop
)
{
scrollUp
=
true
;
scrollDown
=
false
;
}
else
if
(
oldScrollTop
<
wrapper
.
scrollTop
)
{
scrollUp
=
false
;
scrollDown
=
true
;
}
this
.
forbidScrollTopToZero
(
wrapper
);
if
(
wrapper
.
scrollTop
<=
gap
)
{
scrollUp
&&
this
.
fetchOldMsg
();
}
if
(
wrapper
.
scrollTop
-
40
-
(
viewH
-
wrapperH
)
>=
-
gap
)
{
scrollDown
&&
this
.
fetchNewMsg
();
}
oldScrollTop
=
wrapper
.
scrollTop
;
};
}
/* scrollTop为0时,新加载的消息后,滚动条也会保持在0的位置 */
private
scrollToNewMsg
()
{
private
forbidScrollTopToZero
(
ele
:
HTMLElement
)
{
this
.
$nextTick
(()
=>
{
if
(
ele
.
scrollTop
<=
10
)
{
if
(
this
.
loading
)
return
;
ele
.
scrollTop
=
10
;
this
.
scroll2End
();
});
}
}
}
@
throttle
()
private
scrollToNewMsg
()
{
private
async
fetchOldMsg
()
{
this
.
$nextTick
(()
=>
{
if
(
this
.
loading
)
return
;
if
(
this
.
loading
)
return
;
const
msg
=
this
.
historyMessage
;
this
.
scroll2End
();
if
(
msg
==
null
)
return
;
});
if
(
msg
.
length
===
0
)
return
;
}
this
.
startLoadingOld
();
const
msgId
=
msg
[
0
].
id
;
@
throttle
()
const
data
=
await
this
.
getLastPageMsg
(
msgId
);
private
async
fetchOldMsg
()
{
if
(
data
.
length
===
0
)
{
if
(
this
.
loading
)
return
;
// eslint-disable-next-line no-console
const
msg
=
this
.
historyMessage
;
console
.
log
(
"没有更多老消息了"
);
if
(
msg
==
null
)
return
;
}
if
(
msg
.
length
===
0
)
return
;
this
.
$emit
(
"last-page"
,
msgId
);
this
.
startLoadingOld
();
this
.
endLoadingOld
();
const
msgId
=
msg
[
0
].
id
;
}
const
data
=
await
this
.
getLastPageMsg
(
msgId
);
if
(
data
.
length
===
0
)
{
@
throttle
()
// eslint-disable-next-line no-console
private
async
fetchNewMsg
()
{
console
.
log
(
"没有更多老消息了"
);
if
(
this
.
loading
)
return
;
const
msg
=
this
.
historyMessage
;
if
(
msg
==
null
)
return
;
if
(
msg
.
length
===
0
)
return
;
this
.
startLoadingNew
();
const
msgId
=
msg
[
msg
.
length
-
1
].
id
;
const
data
=
await
this
.
getNextPageMsg
(
msgId
);
if
(
data
.
length
===
0
)
{
// eslint-disable-next-line no-console
console
.
log
(
"没有更多新消息了"
);
}
this
.
$emit
(
"next-page"
,
msgId
);
this
.
endLoadingNew
();
}
}
this
.
$emit
(
"last-page"
,
msgId
);
this
.
endLoadingOld
();
private
format2Time
(
time
:
number
)
{
}
return
formatTime
(
time
);
@
throttle
()
private
async
fetchNewMsg
()
{
if
(
this
.
loading
)
return
;
const
msg
=
this
.
historyMessage
;
if
(
msg
==
null
)
return
;
if
(
msg
.
length
===
0
)
return
;
this
.
startLoadingNew
();
const
msgId
=
msg
[
msg
.
length
-
1
].
id
;
const
data
=
await
this
.
getNextPageMsg
(
msgId
);
if
(
data
.
length
===
0
)
{
// eslint-disable-next-line no-console
console
.
log
(
"没有更多新消息了"
);
}
}
this
.
$emit
(
"next-page"
,
msgId
);
this
.
endLoadingNew
();
private
whetherShowTime
(
previous
:
Message
,
current
:
Message
)
{
}
return
current
.
ts
-
previous
.
ts
>
180
;
private
format2Time
(
time
:
number
)
{
return
formatTime
(
time
);
}
private
whetherShowTime
(
previous
:
Message
,
current
:
Message
)
{
return
current
.
ts
-
previous
.
ts
>
180
;
}
private
open
(
file
:
{
type
:
string
;
msg
:
{
url
:
string
;
name
:
string
;
size
:
number
};
})
{
if
(
file
.
type
===
"image"
)
{
this
.
imagePreview
=
file
.
msg
;
this
.
preview
=
true
;
return
this
.
raiseFileOpen
(
true
);
}
}
if
(
file
.
type
===
"video"
)
{
private
open
(
file
:
{
this
.
videoPreview
=
file
.
msg
;
type
:
string
;
this
.
previewVideo
=
true
;
msg
:
{
url
:
string
;
name
:
string
;
size
:
number
};
return
this
.
raiseFileOpen
(
true
);
})
{
if
(
file
.
type
===
"image"
)
{
this
.
imagePreview
=
file
.
msg
;
this
.
preview
=
true
;
return
this
.
raiseFileOpen
(
true
);
}
if
(
file
.
type
===
"video"
)
{
this
.
videoPreview
=
file
.
msg
;
this
.
previewVideo
=
true
;
return
this
.
raiseFileOpen
(
true
);
}
}
}
}
/**
/**
* 获取当期消息列表头尾消息的id
* 获取当期消息列表头尾消息的id
*/
*/
public
getStart2EndMessageIds
()
{
public
getStart2EndMessageIds
()
{
const
v
:
{
start
:
number
;
end
:
number
}
=
{
start
:
0
,
end
:
0
};
const
v
:
{
start
:
number
;
end
:
number
}
=
{
start
:
0
,
end
:
0
};
if
(
this
.
historyMessage
&&
this
.
historyMessage
.
length
)
{
if
(
this
.
historyMessage
&&
this
.
historyMessage
.
length
)
{
const
start
=
this
.
historyMessage
[
0
];
const
start
=
this
.
historyMessage
[
0
];
v
.
start
=
start
.
id
;
v
.
start
=
start
.
id
;
const
end
=
this
.
historyMessage
[
this
.
historyMessage
.
length
-
1
];
const
end
=
this
.
historyMessage
[
this
.
historyMessage
.
length
-
1
];
v
.
end
=
end
.
id
;
v
.
end
=
end
.
id
;
}
return
v
;
}
}
return
v
;
}
}
}
</
script
>
</
script
>
<
style
lang=
"less"
scoped
>
<
style
lang=
"less"
scoped
>
.message-list
{
.message-list
{
padding
:
0
20px
;
padding
:
0
20px
;
}
}
.loading-mask
{
.loading-mask
{
height
:
50px
;
height
:
50px
;
line-height
:
50px
;
line-height
:
50px
;
text-align
:
center
;
text-align
:
center
;
}
}
.message-template
{
.message-template
{
&:first-child
{
&:first-child
{
.timestamp
{
.timestamp
{
margin-top
:
20px
;
margin-top
:
20px
;
}
}
}
}
.timestamp
{
&
:last-child
{
font-size
:
12px
;
padding-bottom
:
10px
;
user-select
:
none
;
}
}
.timestamp
{
font-size
:
12px
;
user-select
:
none
;
}
}
}
</
style
>
</
style
>
components/message.vue
View file @
a5b8ff29
...
@@ -3,8 +3,13 @@
...
@@ -3,8 +3,13 @@
class=
"message-con d-flex align-items-center"
class=
"message-con d-flex align-items-center"
:class=
"isMyMessage ? 'my-message flex-row-reverse' : ''"
:class=
"isMyMessage ? 'my-message flex-row-reverse' : ''"
>
>
<div
class=
"msg-content"
:class=
"
{'algin-left': !isMyMessage}">
<div
class=
"msg-content"
:class=
"
{ 'algin-left': !isMyMessage }">
<div
class=
"msg-name no-selection"
:class=
"
{'algin-left': !isMyMessage}">
{{
userName
}}
</div>
<div
class=
"msg-name no-selection"
:class=
"
{ 'algin-left': !isMyMessage }"
>
{{
userName
}}
</div>
<!-- Image -->
<!-- Image -->
<div
<div
class=
"msg-detail image-message"
class=
"msg-detail image-message"
...
@@ -111,7 +116,11 @@
...
@@ -111,7 +116,11 @@
<template
v-if=
"showReadSummary"
>
<template
v-if=
"showReadSummary"
>
<div
v-if=
"isMyMessage"
class=
"msg-read pos-rel"
>
<div
v-if=
"isMyMessage"
class=
"msg-read pos-rel"
>
<span
@
click=
"readListVisibility = true"
class=
"pointer"
>
<span
@
click=
"readListVisibility = true"
class=
"pointer"
:class=
"
{ all: isAllRead }"
>
<template
v-if=
"isAllRead"
>
全部已读
</
template
>
<template
v-if=
"isAllRead"
>
全部已读
</
template
>
<
template
v-else-if=
"data.read_count > 0"
<
template
v-else-if=
"data.read_count > 0"
>
{{
data
.
read_count
}}
人已读
</
template
>
{{
data
.
read_count
}}
人已读
</
template
...
@@ -260,11 +269,14 @@ export default class Message extends Mixins(Filters) {
...
@@ -260,11 +269,14 @@ export default class Message extends Mixins(Filters) {
}
}
private
mounted
()
{
private
mounted
()
{
this
.
buildMessageUrl
()
this
.
buildMessageUrl
()
;
}
}
private
get
userName
()
{
private
get
userName
()
{
return
this
.
chatMembers
.
find
(
member
=>
member
.
eid
===
this
.
data
.
eid
)?.
name
??
""
;
return
(
this
.
chatMembers
.
find
((
member
)
=>
member
.
eid
===
this
.
data
.
eid
)
?.
name
??
""
);
}
}
private
get
avatar
()
{
private
get
avatar
()
{
...
@@ -460,6 +472,7 @@ export default class Message extends Mixins(Filters) {
...
@@ -460,6 +472,7 @@ export default class Message extends Mixins(Filters) {
margin-right
:
15px
;
margin-right
:
15px
;
user-select
:
none
;
user-select
:
none
;
flex
:
none
;
flex
:
none
;
margin-top
:
auto
;
}
}
.download-icon
{
.download-icon
{
...
@@ -605,4 +618,8 @@ i.msg-avatar {
...
@@ -605,4 +618,8 @@ i.msg-avatar {
width
:
100%
;
width
:
100%
;
}
}
}
}
.all
{
color
:
#4389f8
;
}
</
style
>
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment