441 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?/)
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
}
}