mirror of
https://github.com/TangSengDaoDao/TangSengDaoDaoWeb
synced 2025-06-01 14:32:51 +00:00
441 lines
13 KiB
TypeScript
441 lines
13 KiB
TypeScript
import { Setting } from "wukongimjssdk"
|
||
import { Channel, ChannelInfo, ChannelTypePerson, Conversation, WKSDK, Message, MessageContentType, MessageStatus, MessageText } from "wukongimjssdk"
|
||
import WKApp from "../App"
|
||
import { MessageContentTypeConst, MessageReasonCode, OrderFactor } from "./Const"
|
||
import { DefaultEmojiService } from "./EmojiService"
|
||
import { TypingManager } from "./TypingManager"
|
||
|
||
export class ConversationWrap {
|
||
conversation: Conversation
|
||
constructor(conversation: Conversation) {
|
||
this.conversation = conversation
|
||
}
|
||
|
||
avatarHashTag?: string
|
||
// channel: Channel;
|
||
// private _channelInfo;
|
||
// unread: number;
|
||
// timestamp: number;
|
||
// lastMessage: Message;
|
||
// isMentionMe: boolean;
|
||
// constructor();
|
||
// get channelInfo(): ChannelInfo;
|
||
// isEqual(c: Conversation): boolean;
|
||
|
||
|
||
public get avatar() {
|
||
if (this.channelInfo && this.channelInfo.logo && this.channelInfo.logo !== "") {
|
||
return `${WKApp.dataSource.commonDataSource.getImageURL(this.channelInfo.logo)}?v=${WKApp.shared.getChannelAvatarTag(this.channel)}`
|
||
}
|
||
return WKApp.shared.avatarChannel(this.channel)
|
||
}
|
||
|
||
public get channel() {
|
||
return this.conversation.channel
|
||
}
|
||
|
||
public get channelInfo() {
|
||
return this.conversation.channelInfo
|
||
}
|
||
public get unread() {
|
||
return this.conversation.unread
|
||
}
|
||
|
||
public get timestamp() {
|
||
return this.conversation.timestamp
|
||
}
|
||
public set timestamp(timestamp: number) {
|
||
this.conversation.timestamp = timestamp
|
||
}
|
||
|
||
public get lastMessage() {
|
||
return this.conversation.lastMessage
|
||
}
|
||
public set lastMessage(lastMessage: Message | undefined) {
|
||
this.conversation.lastMessage = lastMessage
|
||
|
||
}
|
||
|
||
public get isMentionMe() {
|
||
return this.conversation.isMentionMe
|
||
}
|
||
|
||
public get remoteExtra() {
|
||
return this.conversation.remoteExtra
|
||
}
|
||
|
||
public set isMentionMe(isMentionMe: boolean | undefined) {
|
||
this.conversation.isMentionMe = isMentionMe
|
||
}
|
||
|
||
public get reminders() {
|
||
return this.conversation.reminders
|
||
}
|
||
|
||
public get simpleReminders() {
|
||
return this.conversation.simpleReminders
|
||
}
|
||
|
||
reloadIsMentionMe(): void {
|
||
return this.conversation.reloadIsMentionMe()
|
||
}
|
||
|
||
public get extra() {
|
||
if (!this.conversation.extra) {
|
||
this.conversation.extra = {}
|
||
}
|
||
return this.conversation.extra
|
||
}
|
||
|
||
|
||
public get category() {
|
||
if (!this.conversation.channelInfo || !this.conversation.channelInfo.orgData) {
|
||
return ""
|
||
}
|
||
const channelInfo = this.conversation.channelInfo;
|
||
if (channelInfo.orgData.category !== '' && channelInfo.orgData.category === 'solved') {
|
||
return channelInfo.orgData.category
|
||
}
|
||
if (channelInfo.orgData.category === '' && channelInfo.orgData.agent_uid === '') {
|
||
return "new"
|
||
}
|
||
if (channelInfo.orgData.agent_uid === WKApp.loginInfo.uid) {
|
||
return "assignMe"
|
||
}
|
||
if (channelInfo.orgData.agent_uid !== '') {
|
||
return "allAssigned"
|
||
}
|
||
return channelInfo.orgData.category
|
||
}
|
||
|
||
isEqual(c: ConversationWrap): boolean {
|
||
return this.conversation.isEqual(c.conversation)
|
||
}
|
||
}
|
||
|
||
|
||
|
||
export enum PartType {
|
||
text, // 普通文本
|
||
emoji, // emoji
|
||
mention, // @
|
||
link // 链接
|
||
}
|
||
|
||
export enum BubblePosition {
|
||
unknown,
|
||
first, // 第一个
|
||
middle, // 中间
|
||
last, // 最后一个
|
||
single, // 单独
|
||
}
|
||
|
||
|
||
export class Part {
|
||
type!: PartType // 文本内容: text:普通文本 emoji: emoji文本 mention:@文本
|
||
text!: string
|
||
data?: any
|
||
|
||
constructor(type: PartType, text: string, data?: any) {
|
||
this.type = type
|
||
this.text = text
|
||
this.data = data
|
||
}
|
||
}
|
||
export class MessageWrap {
|
||
public message: Message
|
||
public checked!: boolean // 是否选中
|
||
public locateRemind?: boolean // 定位到消息后是否需要提醒
|
||
constructor(message: Message) {
|
||
this.message = message
|
||
this.order = message.messageSeq * OrderFactor
|
||
}
|
||
private _parts?: Array<Part>
|
||
|
||
preMessage?: MessageWrap
|
||
nextMessage?: MessageWrap
|
||
voiceBuff?: any // 声音的二进制文件,用于缓存
|
||
private _reasonCode?: number // 消息错误原因代码
|
||
order: number = 0 // 消息排序号
|
||
/* tslint:disable-line */
|
||
public get header() {
|
||
return this.message.header
|
||
}
|
||
public get setting(): Setting {
|
||
return this.message.setting
|
||
}
|
||
public get clientSeq() {
|
||
return this.message.clientSeq
|
||
}
|
||
public get messageID() {
|
||
return this.message.messageID
|
||
}
|
||
public get messageSeq() {
|
||
return this.message.messageSeq
|
||
}
|
||
public get clientMsgNo() {
|
||
return this.message.clientMsgNo
|
||
}
|
||
public get fromUID() {
|
||
return this.message.fromUID
|
||
}
|
||
|
||
|
||
public get from(): ChannelInfo | undefined {
|
||
return WKSDK.shared().channelManager.getChannelInfo(new Channel(this.fromUID, ChannelTypePerson))
|
||
}
|
||
|
||
public get channel() {
|
||
return this.message.channel
|
||
}
|
||
public get timestamp() {
|
||
return this.message.timestamp
|
||
}
|
||
public get content() {
|
||
return this.message.content
|
||
}
|
||
public get status() {
|
||
return this.message.status
|
||
}
|
||
public set status(status: MessageStatus) {
|
||
this.message.status = status
|
||
}
|
||
public get reasonCode() {
|
||
if (this.status == MessageStatus.Normal) {
|
||
return MessageReasonCode.reasonSuccess
|
||
}
|
||
return this._reasonCode || MessageReasonCode.reasonUnknown
|
||
}
|
||
public set reasonCode(v: number) {
|
||
this._reasonCode = v
|
||
}
|
||
public get voicePlaying() {
|
||
return this.message.voicePlaying
|
||
}
|
||
public get voiceReaded() {
|
||
return this.message.voiceReaded
|
||
}
|
||
public get reactions() {
|
||
return this.message.reactions
|
||
}
|
||
public get unreadCount() {
|
||
return this.message.remoteExtra.unreadCount
|
||
}
|
||
public get readedCount() {
|
||
return this.message.remoteExtra.readedCount
|
||
}
|
||
public set readedCount(v: number) {
|
||
this.message.remoteExtra.readedCount = v
|
||
}
|
||
public get isDeleted() {
|
||
return this.message.isDeleted
|
||
}
|
||
|
||
public set isDeleted(isDeleted: boolean) {
|
||
this.message.isDeleted = isDeleted
|
||
}
|
||
|
||
public get revoke() {
|
||
return this.message.remoteExtra.revoke
|
||
}
|
||
public set revoke(revoke: boolean) {
|
||
this.message.remoteExtra.revoke = revoke
|
||
}
|
||
|
||
public get revoker() {
|
||
return this.message.remoteExtra.revoker
|
||
}
|
||
public set revoker(revoker: string | undefined) {
|
||
this.message.remoteExtra.revoker = revoker
|
||
}
|
||
|
||
// 是否是发送的消息
|
||
public get send(): boolean {
|
||
return this.message.fromUID === WKApp.loginInfo.uid
|
||
}
|
||
|
||
public get contentType(): number {
|
||
return this.message.contentType
|
||
}
|
||
|
||
public resetParts() {
|
||
this._parts = undefined
|
||
this._parts = this.parts
|
||
}
|
||
|
||
public get parts(): Array<Part> {
|
||
if (!this._parts) {
|
||
this._parts = this.parseMention()
|
||
this._parts = this.parseEmoji(this._parts);
|
||
this._parts = this.parseLinks(this._parts)
|
||
}
|
||
return this._parts
|
||
}
|
||
|
||
public get bubblePosition(): BubblePosition {
|
||
|
||
if (!this.preIsSamePerson && this.nextIsSamePerson) {
|
||
return BubblePosition.first
|
||
}
|
||
if (this.preIsSamePerson && this.nextIsSamePerson) {
|
||
return BubblePosition.middle
|
||
}
|
||
|
||
if (this.preIsSamePerson && !this.nextIsSamePerson) {
|
||
return BubblePosition.last
|
||
}
|
||
if (!this.preIsSamePerson && !this.nextIsSamePerson) {
|
||
return BubblePosition.single
|
||
}
|
||
return BubblePosition.unknown
|
||
}
|
||
|
||
private get preIsSamePerson(): boolean {
|
||
if (this.preMessage?.content.contentType === MessageContentTypeConst.time) {
|
||
return false
|
||
}
|
||
if (this.preMessage?.revoke) {
|
||
return false
|
||
}
|
||
return this.preMessage?.fromUID === this.fromUID
|
||
}
|
||
private get nextIsSamePerson(): boolean {
|
||
if (this.nextMessage?.content.contentType === MessageContentTypeConst.time) {
|
||
return false
|
||
}
|
||
if (this.nextMessage?.revoke) {
|
||
return false
|
||
}
|
||
return this.nextMessage?.fromUID === this.fromUID
|
||
}
|
||
|
||
// 解析@
|
||
private parseMention(): Array<Part> {
|
||
if (this.content.contentType !== MessageContentType.text) {
|
||
return new Array<Part>()
|
||
}
|
||
let textContent = this.content as MessageText
|
||
if (this.message.remoteExtra.isEdit && this.message.remoteExtra.contentEdit !== undefined) {
|
||
textContent = this.message.remoteExtra.contentEdit as MessageText
|
||
}
|
||
let text = textContent.text || ''
|
||
const mention = this.content.mention
|
||
if (!mention?.uids || mention.uids.length <= 0) {
|
||
return [new Part(PartType.text, text)]
|
||
}
|
||
let parts = new Array<Part>();
|
||
let i = 0
|
||
while (text.length > 0) {
|
||
const mentionMatchResult = text.match(/@([\w\u4e00-\u9fa5])+/m)
|
||
let index = mentionMatchResult?.index
|
||
if (index === undefined) {
|
||
index = -1
|
||
}
|
||
if (!mentionMatchResult || index === -1) {
|
||
parts.push(new Part(PartType.text, text))
|
||
break
|
||
}
|
||
if (index > 0) {
|
||
parts.push(new Part(PartType.text, text.substring(0, index)));
|
||
}
|
||
let data = {}
|
||
if (i < mention.uids.length) {
|
||
data = { "uid": mention.uids[i] }
|
||
}
|
||
|
||
parts.push(new Part(PartType.mention, text.substr(index, mentionMatchResult[0].length), data))
|
||
text = text.substring(index + mentionMatchResult[0].length);
|
||
|
||
i++
|
||
}
|
||
return parts;
|
||
}
|
||
// 解析emoji
|
||
parseEmoji(parts: Array<Part>): Array<Part> {
|
||
if (!parts || parts.length <= 0) {
|
||
return parts;
|
||
}
|
||
let len = parts.length;
|
||
let newParts = new Array<Part>();
|
||
for (let index = 0; index < len; index++) {
|
||
const part = parts[index];
|
||
if (part.type === PartType.text) {
|
||
let text = part.text;
|
||
while (text.length > 0) {
|
||
const matchResult = text.match(DefaultEmojiService.shared.emojiRegExp())
|
||
if (!matchResult) {
|
||
newParts.push(new Part(PartType.text, text))
|
||
break
|
||
}
|
||
let index = matchResult?.index
|
||
if (index === undefined) {
|
||
index = -1
|
||
}
|
||
if (index === -1) {
|
||
newParts.push(new Part(PartType.text, text))
|
||
break
|
||
}
|
||
if (index > 0) {
|
||
newParts.push(new Part(PartType.text, text.substring(0, index)));
|
||
}
|
||
newParts.push(new Part(PartType.emoji, text.substr(index, matchResult[0].length)));
|
||
text = text.substring(index + matchResult[0].length);
|
||
}
|
||
} else {
|
||
newParts.push(part);
|
||
}
|
||
|
||
}
|
||
return newParts;
|
||
}
|
||
|
||
parseLinks(parts: Array<Part>): Array<Part> {
|
||
if (!parts || parts.length <= 0) {
|
||
return parts;
|
||
}
|
||
let newParts = new Array<Part>();
|
||
let len = parts.length;
|
||
for (let index = 0; index < len; index++) {
|
||
const part = parts[index];
|
||
if (part.type === PartType.text) {
|
||
let text = part.text;
|
||
while (text.length > 0) {
|
||
const matchResult = text.match(/((http|ftp|https):\/\/|www.)[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/)
|
||
if (!matchResult) {
|
||
newParts.push(new Part(PartType.text, text))
|
||
break
|
||
}
|
||
let index = matchResult?.index
|
||
if (index === undefined) {
|
||
index = -1
|
||
}
|
||
if (index === -1) {
|
||
newParts.push(new Part(PartType.text, text))
|
||
break
|
||
}
|
||
if (index > 0) {
|
||
newParts.push(new Part(PartType.text, text.substring(0, index)));
|
||
}
|
||
newParts.push(new Part(PartType.link, text.substr(index, matchResult[0].length)));
|
||
text = text.substring(index + matchResult[0].length);
|
||
}
|
||
} else {
|
||
newParts.push(part)
|
||
}
|
||
}
|
||
return newParts
|
||
}
|
||
|
||
public get flame(): boolean {
|
||
if (this.message.content.contentObj) {
|
||
return this.message.content.contentObj.flame === 1
|
||
}
|
||
return false
|
||
}
|
||
|
||
public get remoteExtra() {
|
||
return this.message.remoteExtra
|
||
}
|
||
|
||
}
|