|
|
@@ -2,9 +2,11 @@ package com.adealink.weparty.message.manager
|
|
|
|
|
|
import android.app.Application
|
|
|
import android.graphics.Bitmap
|
|
|
+import android.os.Bundle
|
|
|
import android.text.Spannable
|
|
|
import android.text.SpannableString
|
|
|
import android.text.SpannableStringBuilder
|
|
|
+import androidx.fragment.app.FragmentActivity
|
|
|
import com.adealink.frame.aab.util.getCompatDrawable
|
|
|
import com.adealink.frame.aab.util.getCompatString
|
|
|
import com.adealink.frame.base.Rlt
|
|
|
@@ -21,20 +23,26 @@ import com.adealink.frame.imkit.model.TAG_IM_UI
|
|
|
import com.adealink.frame.log.Log
|
|
|
import com.adealink.frame.network.ISocketNotify
|
|
|
import com.adealink.frame.network.data.Res
|
|
|
+import com.adealink.frame.router.Router
|
|
|
import com.adealink.frame.storage.cache.TimeoutLruCache
|
|
|
import com.adealink.frame.util.AppUtil
|
|
|
import com.adealink.frame.util.ONE_MINUTE
|
|
|
import com.adealink.weparty.App
|
|
|
+import com.adealink.weparty.commonui.dialogchain.DialogShowManager
|
|
|
+import com.adealink.weparty.commonui.dialogchain.DialogTaskManager
|
|
|
+import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
|
|
|
import com.adealink.weparty.commonui.ext.dp
|
|
|
import com.adealink.weparty.commonui.ext.onSuccess
|
|
|
import com.adealink.weparty.commonui.text.span.DraweeSpan
|
|
|
import com.adealink.weparty.commonui.widget.CenterImageSpan
|
|
|
import com.adealink.weparty.commonui.widget.floatview.FloatViewFactory
|
|
|
import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
|
|
|
+import com.adealink.weparty.commonui.widget.floatview.data.FloatWindowType
|
|
|
import com.adealink.weparty.commonui.widget.floatview.data.IFloatData
|
|
|
import com.adealink.weparty.commonui.widget.floatview.data.MODE_APPLICATION
|
|
|
import com.adealink.weparty.commonui.widget.floatview.view.BaseFloatView
|
|
|
import com.adealink.weparty.message.R
|
|
|
+import com.adealink.weparty.message.callback.ISessionInfoChangeCallback
|
|
|
import com.adealink.weparty.message.config.IMConfigCenter
|
|
|
import com.adealink.weparty.message.constant.IM_NOTIFICATION_CHANNEL_ID
|
|
|
import com.adealink.weparty.message.constant.OFFICIAL_NAME
|
|
|
@@ -53,7 +61,10 @@ import com.adealink.weparty.message.conversation.message.ProxyInviteWithdrawMess
|
|
|
import com.adealink.weparty.message.conversation.message.TransferDealMessage
|
|
|
import com.adealink.weparty.message.conversation.util.getCPTypeName
|
|
|
import com.adealink.weparty.message.datasource.remote.MessageHttpService
|
|
|
+import com.adealink.weparty.message.floatview.NotificationIncomeMessageFloatData
|
|
|
+import com.adealink.weparty.message.floatview.NotificationIncomeMessageFloatView
|
|
|
import com.adealink.weparty.message.floatview.NotificationMessageFloatData
|
|
|
+import com.adealink.weparty.message.floatview.NotificationMessageFloatView
|
|
|
import com.adealink.weparty.message.listener.IMessageListener
|
|
|
import com.adealink.weparty.message.manager.IMessageManager.Companion.NEW_MSG_DISMISS_ACTIVITIES
|
|
|
import com.adealink.weparty.message.userinfo.IMUserInfoManager
|
|
|
@@ -67,22 +78,31 @@ import com.adealink.weparty.module.couple.data.IntimacyValInfo
|
|
|
import com.adealink.weparty.module.couple.listener.ICoupleListener
|
|
|
import com.adealink.weparty.module.message.data.BatchGetFirstChatTsReq
|
|
|
import com.adealink.weparty.module.message.data.BatchGetSessionListReq
|
|
|
+import com.adealink.weparty.module.message.data.BatchSendQuickMessageReq
|
|
|
import com.adealink.weparty.module.message.data.CustomerInfo
|
|
|
import com.adealink.weparty.module.message.data.EnterConversationFrom
|
|
|
import com.adealink.weparty.module.message.data.FamilyImInfoRsp
|
|
|
import com.adealink.weparty.module.message.data.IMMessageScene
|
|
|
import com.adealink.weparty.module.message.data.Im1v1ContinuousSendMessageDeductNotifyInfo
|
|
|
+import com.adealink.weparty.module.message.data.ImMessageNotifyInfo
|
|
|
+import com.adealink.weparty.module.message.data.MessagePriceInfo
|
|
|
+import com.adealink.weparty.module.message.data.NoReplyMessageRsp
|
|
|
import com.adealink.weparty.module.message.data.OFFICIAL_TARGET_ID
|
|
|
import com.adealink.weparty.module.message.data.SendQuickMessageReq
|
|
|
import com.adealink.weparty.module.message.data.SessionInfo
|
|
|
import com.adealink.weparty.module.message.data.isSystemTarget
|
|
|
+import com.adealink.weparty.module.message.reminder.MessageIncomeReminderDialogTask
|
|
|
+import com.adealink.weparty.module.message.reminder.MessageReminderDialogTask
|
|
|
import com.adealink.weparty.module.profile.ProfileModule
|
|
|
import com.adealink.weparty.module.profile.data.UserConfigType
|
|
|
import com.adealink.weparty.module.profile.data.UserFamilySetting
|
|
|
import com.adealink.weparty.module.profile.data.UserInfo
|
|
|
import com.adealink.weparty.push.NotificationUtil
|
|
|
+import com.adealink.weparty.push.data.FirstGetDiamondsFromChatNotify
|
|
|
+import com.adealink.weparty.push.data.NoReplyPaidMessageNotify
|
|
|
import com.adealink.weparty.push.data.NotificationMessage
|
|
|
import com.adealink.weparty.push.data.PushMessageType
|
|
|
+import com.adealink.weparty.push.data.SessionInfoChangeNotify
|
|
|
import com.adealink.weparty.push.data.WeNextPushMessage
|
|
|
import com.adealink.weparty.ui.home.util.HomeUIUtil
|
|
|
import com.facebook.common.util.UriUtil
|
|
|
@@ -97,6 +117,7 @@ import kotlinx.coroutines.launch
|
|
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
|
import kotlinx.coroutines.withContext
|
|
|
import java.util.LinkedList
|
|
|
+import java.util.concurrent.ConcurrentHashMap
|
|
|
import kotlin.coroutines.resume
|
|
|
import com.adealink.weparty.R as APP_R
|
|
|
import com.adealink.weparty.module.message.Message as MESSAGE_ROUTER
|
|
|
@@ -105,6 +126,9 @@ val messageManager: IMessageManager by lazy { MessageManager() }
|
|
|
|
|
|
class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
UserDataProvider.UserInfoProvider, ICoupleListener {
|
|
|
+ private val sessionInfoChangeCallbackMap by lazy {
|
|
|
+ ConcurrentHashMap<Int, ISessionInfoChangeCallback>()
|
|
|
+ }
|
|
|
private val messageHttpService by lazy {
|
|
|
App.instance.networkService.getHttpService(MessageHttpService::class.java)
|
|
|
}
|
|
|
@@ -127,6 +151,79 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private val noReplyPaidMessageNotify = object : ISocketNotify<NoReplyPaidMessageNotify> {
|
|
|
+
|
|
|
+ override val uri: String = "NO_REPLY_PAID_MESSAGE_NOTIFY"
|
|
|
+
|
|
|
+ override fun needHandle(data: NoReplyPaidMessageNotify?): Boolean {
|
|
|
+ return data != null
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onNotify(data: NoReplyPaidMessageNotify) {
|
|
|
+ val messageSender = data.messageSender
|
|
|
+ if (messageSender != null) {
|
|
|
+ DialogTaskManager.submit(
|
|
|
+ MessageIncomeReminderDialogTask(
|
|
|
+ data.content, messageSender
|
|
|
+ )
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ Log.e(TAG_IM_MSG_RECEIVE, "noReplyPaidMessageNotify messageSender null")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private val firstGetDiamondsFromChatNotify =
|
|
|
+ object : ISocketNotify<FirstGetDiamondsFromChatNotify> {
|
|
|
+
|
|
|
+ override val uri: String = "FIRST_GET_DIAMONDS_FROM_CHAT_NOTIFY"
|
|
|
+
|
|
|
+ override fun needHandle(data: FirstGetDiamondsFromChatNotify?): Boolean {
|
|
|
+ return data != null
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onNotify(data: FirstGetDiamondsFromChatNotify) {
|
|
|
+ Router.getRouterInstance<BaseDialogFragment>(com.adealink.weparty.module.message.Message.MessageReplyReward.PATH)
|
|
|
+ ?.apply {
|
|
|
+ arguments = Bundle().apply {
|
|
|
+ putString(
|
|
|
+ com.adealink.weparty.module.message.Message.MessageReplyReward.EXTRA_TITLE,
|
|
|
+ data.title
|
|
|
+ )
|
|
|
+ putString(
|
|
|
+ com.adealink.weparty.module.message.Message.MessageReplyReward.EXTRA_CONTENT,
|
|
|
+ data.content
|
|
|
+ )
|
|
|
+ }
|
|
|
+ val curActivity = AppUtil.currentActivity as? FragmentActivity ?: return
|
|
|
+ show(curActivity.supportFragmentManager)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private val sessionInfoChangeNotify = object : ISocketNotify<SessionInfoChangeNotify> {
|
|
|
+
|
|
|
+ override val uri: String = "SESSION_INFO_CHANGE_NOTIFY"
|
|
|
+
|
|
|
+ override fun needHandle(data: SessionInfoChangeNotify?): Boolean {
|
|
|
+ return data != null
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onNotify(data: SessionInfoChangeNotify) {
|
|
|
+ val changedSessionInfos = ArrayList<SessionInfo>()
|
|
|
+ data.sessionInfos.forEach {
|
|
|
+ val cache = sessionInfoCache[it.uid]
|
|
|
+ if (cache != null) {
|
|
|
+ cache.existsNoReplyPaidMessage = it.existsNoReplyPaidMessage
|
|
|
+ }
|
|
|
+ changedSessionInfos.add(it)
|
|
|
+ }
|
|
|
+ data.listTypes.forEach {
|
|
|
+ sessionInfoChangeCallbackMap[it]?.onSessionInfoChanged(changedSessionInfos)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private val im1v1ContinuousSendMessageDeductNotify =
|
|
|
object : ISocketNotify<Im1v1ContinuousSendMessageDeductNotifyInfo> {
|
|
|
|
|
|
@@ -173,74 +270,8 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
//处理新消息提醒条
|
|
|
if (message == null) return false
|
|
|
if (offline) return false
|
|
|
- launch {
|
|
|
- val targetIdLong =
|
|
|
- if (message.conversationType == Conversation.ConversationType.GROUP) {
|
|
|
- message.senderUserId.toLongOrNull()
|
|
|
- } else {
|
|
|
- message.targetId.toLongOrNull()
|
|
|
- } ?: return@launch
|
|
|
- if (isSystemTarget(targetIdLong)) {
|
|
|
- return@launch
|
|
|
- }
|
|
|
- if (message.senderUserId == AccountModule.uid.toString()) {
|
|
|
- return@launch
|
|
|
- }
|
|
|
- val msgTag =
|
|
|
- message.content?.javaClass?.getAnnotation(MessageTag::class.java)
|
|
|
- if (msgTag?.flag != MessageTag.ISCOUNTED) {
|
|
|
- //不计数消息不提醒
|
|
|
- return@launch
|
|
|
- }
|
|
|
- if (disableNotifyMessageContentClass.any { it.isInstance(message.content) }) {
|
|
|
- //不提醒的消息类型
|
|
|
- return@launch
|
|
|
- }
|
|
|
- val targetUserInfoRlt = ProfileModule.getUserInfoByUid(targetIdLong, true)
|
|
|
- val targetUserInfo = (targetUserInfoRlt as? Rlt.Success)?.data ?: return@launch
|
|
|
- val deeplink =
|
|
|
- if (message.conversationType == Conversation.ConversationType.GROUP) {
|
|
|
- val familyInfo = targetUserInfo.familyInfo ?: return@launch
|
|
|
- MESSAGE_ROUTER.GroupConversation.getGroupConversationDeeplink(
|
|
|
- familyInfo.imGroupId, EnterConversationFrom.Push.name
|
|
|
- )
|
|
|
- } else {
|
|
|
- MESSAGE_ROUTER.Conversation.getPrivateConversationDeeplink(
|
|
|
- targetIdLong, EnterConversationFrom.Push.name
|
|
|
- )
|
|
|
- }
|
|
|
- val title = when (msgTag.value) {
|
|
|
- CP_INVITE_MESSAGE_TYPE, APP_INFO_MESSAGE_TYPE, FAMILY_INVITE_MESSAGE_TYPE -> {
|
|
|
- null
|
|
|
- }
|
|
|
-
|
|
|
- else -> {
|
|
|
- if (message.conversationType == Conversation.ConversationType.GROUP) {
|
|
|
- val familyInfo = targetUserInfo.familyInfo ?: return@launch
|
|
|
- "${targetUserInfo.name}(${familyInfo.name})"
|
|
|
- } else {
|
|
|
- targetUserInfo.name
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- val messageSummary = getMessageSummary(message.content, targetUserInfo.name ?: "")
|
|
|
- val newMessageData = NotificationMessage(
|
|
|
- targetId = targetIdLong.toString(),
|
|
|
- title = title,
|
|
|
- message = messageSummary.toString(),
|
|
|
- largeIconUrl = targetUserInfo.url,
|
|
|
- pushId = System.currentTimeMillis(),
|
|
|
- messageType = PushMessageType.IM.type,
|
|
|
- deeplink = deeplink
|
|
|
- ).apply {
|
|
|
- this.messageSummary = messageSummary
|
|
|
- this.targetUserInfo = targetUserInfo
|
|
|
- }
|
|
|
- if (shouldAllowNewMessageInUIScene(newMessageData.targetId)) {
|
|
|
- notificationMessageNoticeQueue.add(newMessageData)
|
|
|
- showNextNewMessageNotice()
|
|
|
- }
|
|
|
- }
|
|
|
+ handleReceivedMessageNotice(message)
|
|
|
+ showMessageReminderDialogIfNeed(message)
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
@@ -250,6 +281,117 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private fun handleReceivedMessageNotice(message: Message) {
|
|
|
+ launch {
|
|
|
+ val targetIdLong =
|
|
|
+ if (message.conversationType == Conversation.ConversationType.GROUP) {
|
|
|
+ message.senderUserId.toLongOrNull()
|
|
|
+ } else {
|
|
|
+ message.targetId.toLongOrNull()
|
|
|
+ } ?: return@launch
|
|
|
+ if (isSystemTarget(targetIdLong)) {
|
|
|
+ return@launch
|
|
|
+ }
|
|
|
+ if (isFilterMessage(message)) {
|
|
|
+ return@launch
|
|
|
+ }
|
|
|
+ val msgTag = message.content?.javaClass?.getAnnotation(MessageTag::class.java)
|
|
|
+ val targetUserInfoRlt = ProfileModule.getUserInfoByUid(targetIdLong, true)
|
|
|
+ val targetUserInfo = (targetUserInfoRlt as? Rlt.Success)?.data ?: return@launch
|
|
|
+ val deeplink = if (message.conversationType == Conversation.ConversationType.GROUP) {
|
|
|
+ val familyInfo = targetUserInfo.familyInfo ?: return@launch
|
|
|
+ MESSAGE_ROUTER.GroupConversation.getGroupConversationDeeplink(
|
|
|
+ familyInfo.imGroupId, EnterConversationFrom.Push.name
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ MESSAGE_ROUTER.Conversation.getPrivateConversationDeeplink(
|
|
|
+ targetIdLong, EnterConversationFrom.Push.name
|
|
|
+ )
|
|
|
+ }
|
|
|
+ val title = when (msgTag?.value) {
|
|
|
+ CP_INVITE_MESSAGE_TYPE, APP_INFO_MESSAGE_TYPE, FAMILY_INVITE_MESSAGE_TYPE -> {
|
|
|
+ null
|
|
|
+ }
|
|
|
+
|
|
|
+ else -> {
|
|
|
+ if (message.conversationType == Conversation.ConversationType.GROUP) {
|
|
|
+ val familyInfo = targetUserInfo.familyInfo ?: return@launch
|
|
|
+ "${targetUserInfo.name}(${familyInfo.name})"
|
|
|
+ } else {
|
|
|
+ targetUserInfo.name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ val spend = message.expansion?.get(MessageExpansionKey.Spend.key)
|
|
|
+ val messagePrice = froJsonErrorNull<MessagePriceInfo>(spend)
|
|
|
+ val messageSummary =
|
|
|
+ if (messagePrice != null && messagePrice.targetIncomeCurrencyValue > 0) {
|
|
|
+ SpannableStringBuilder(
|
|
|
+ getCompatString(
|
|
|
+ com.adealink.weparty.message.R.string.message_notificaiton_income_tip,
|
|
|
+ messagePrice.targetIncomeCurrencyValue
|
|
|
+ )
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ getMessageSummary(message.content, targetUserInfo.name ?: "")
|
|
|
+ }
|
|
|
+ val messageType =
|
|
|
+ if (messagePrice != null && messagePrice.targetIncomeCurrencyValue > 0) {
|
|
|
+ PushMessageType.INCOME_IM.type
|
|
|
+ } else {
|
|
|
+ PushMessageType.IM.type
|
|
|
+ }
|
|
|
+ val newMessageData = NotificationMessage(
|
|
|
+ targetId = targetIdLong.toString(),
|
|
|
+ title = title,
|
|
|
+ message = messageSummary.toString(),
|
|
|
+ largeIconUrl = targetUserInfo.url,
|
|
|
+ pushId = System.currentTimeMillis(),
|
|
|
+ messageType = messageType,
|
|
|
+ deeplink = deeplink
|
|
|
+ ).apply {
|
|
|
+ this.messageSummary = messageSummary
|
|
|
+ this.targetUserInfo = targetUserInfo
|
|
|
+ this.messageId = message.messageId
|
|
|
+ }
|
|
|
+ if (shouldAllowNewMessageInUIScene()) {
|
|
|
+ notificationMessageNoticeQueue.add(newMessageData)
|
|
|
+ showNextNewMessageNotice()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun showMessageReminderDialogIfNeed(message: Message) {
|
|
|
+ if (isSystemTarget(message.targetId)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (isFilterMessage(message)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ val info = message.expansion?.get(MessageExpansionKey.MessageNotifyInfo.key)
|
|
|
+ val messageNotifyInfo = froJsonErrorNull<ImMessageNotifyInfo>(info)
|
|
|
+ if (messageNotifyInfo?.fromSystem == 1) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ DialogTaskManager.submit(MessageReminderDialogTask(message))
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun isFilterMessage(message: Message): Boolean {
|
|
|
+ if (message.senderUserId == AccountModule.uid.toString()) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ val msgTag = message.content?.javaClass?.getAnnotation(MessageTag::class.java)
|
|
|
+ if (msgTag?.flag != MessageTag.ISCOUNTED) {
|
|
|
+ //不计数消息不提醒
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if (disableNotifyMessageContentClass.any { it.isInstance(message.content) }) {
|
|
|
+ //不提醒的消息类型
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
private val messageExpansionListener = object : RongIMClient.MessageExpansionListener {
|
|
|
override fun onMessageExpansionUpdate(
|
|
|
expansion: MutableMap<String, String>?,
|
|
|
@@ -265,6 +407,12 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
IMService.innerService.setMessageSentStatus(message, null)
|
|
|
}
|
|
|
}
|
|
|
+ val spend = expansion?.get(MessageExpansionKey.Spend.key)
|
|
|
+ val messagePrice = froJsonErrorNull<MessagePriceInfo>(spend)
|
|
|
+ val serverTimeNow = System.currentTimeMillis() + RongIMClient.getInstance().deltaTime
|
|
|
+ if (messagePrice != null && messagePrice.targetIncomeCurrencyValue > 0 && serverTimeNow - message.sentTime <= messagePrice.messageExpireMilliseconds) {
|
|
|
+ handleReceivedMessageNotice(message)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
override fun onMessageExpansionRemove(
|
|
|
@@ -280,6 +428,9 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
init {
|
|
|
App.instance.networkService.subscribeNotify(notificationMessageNotify)
|
|
|
App.instance.networkService.subscribeNotify(im1v1ContinuousSendMessageDeductNotify)
|
|
|
+ App.instance.networkService.subscribeNotify(noReplyPaidMessageNotify)
|
|
|
+ App.instance.networkService.subscribeNotify(firstGetDiamondsFromChatNotify)
|
|
|
+ App.instance.networkService.subscribeNotify(sessionInfoChangeNotify)
|
|
|
}
|
|
|
|
|
|
override fun appOnCreateMainTask(application: Application) {
|
|
|
@@ -435,11 +586,16 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ if (newMessageData.messageType == PushMessageType.INCOME_IM.type && !shouldShowNewIncomeMessageNotice(newMessageData)) {
|
|
|
+ Log.e(TAG_IM_NEW_MSG_NTF, "IMNewIncomeMessage shouldNotShow, messageData:$newMessageData")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
Log.i(TAG_IM_NEW_MSG_NTF, "showNotificationMessageNotice, messageData:$newMessageData")
|
|
|
showNotificationMessageNotice(newMessageData)
|
|
|
}
|
|
|
|
|
|
- private fun shouldAllowNewMessageInUIScene(targetId: String?): Boolean {
|
|
|
+ private fun shouldAllowNewMessageInUIScene(): Boolean {
|
|
|
//1. 应用在后台,都展示
|
|
|
if (AppUtil.background) return true
|
|
|
//2. 不在会话列表tab页
|
|
|
@@ -453,7 +609,7 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
|
|
|
private fun shouldShowNewMessageNotice(data: NotificationMessage): Boolean {
|
|
|
//1. UI场景判断
|
|
|
- if (!shouldAllowNewMessageInUIScene(data.targetId)) return false
|
|
|
+ if (!shouldAllowNewMessageInUIScene()) return false
|
|
|
//2. 币商不频控
|
|
|
if (data.targetUserInfo?.isMerchant() == true || ProfileModule.getMyUserInfo()?.isMerchant() == true) {
|
|
|
return true
|
|
|
@@ -464,16 +620,37 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
+ private fun shouldShowNewIncomeMessageNotice(data: NotificationMessage): Boolean {
|
|
|
+ //1. UI场景判断
|
|
|
+ if (!shouldAllowNewMessageInUIScene()) return false
|
|
|
+ //2. 币商不频控
|
|
|
+ if (data.targetUserInfo?.isMerchant() == true || ProfileModule.getMyUserInfo()?.isMerchant() == true) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ //3. 满足所有条件,允许展示
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
private fun showNotificationMessageNotice(data: NotificationMessage) {
|
|
|
launch {
|
|
|
//应用在后台,发notification
|
|
|
if (AppUtil.background) {
|
|
|
NotificationUtil.createNotificationChannel(IM_NOTIFICATION_CHANNEL_ID)
|
|
|
+ val pushMessage = WeNextPushMessage(
|
|
|
+ data.toPushMessage(), IM_NOTIFICATION_CHANNEL_ID
|
|
|
+ )
|
|
|
NotificationUtil.showNotification(
|
|
|
- WeNextPushMessage(
|
|
|
- data.toPushMessage(),
|
|
|
- IM_NOTIFICATION_CHANNEL_ID
|
|
|
- )
|
|
|
+ pushMessage, {
|
|
|
+ val messageId = pushMessage.getMessageId()
|
|
|
+ if (messageId.isNullOrEmpty()) {
|
|
|
+ return@showNotification
|
|
|
+ }
|
|
|
+ val notificationId = msgNotificationIdCache[messageId]?.toInt()
|
|
|
+ if (notificationId != null) {
|
|
|
+ NotificationUtil.cancelNotification(notificationId)
|
|
|
+ }
|
|
|
+ msgNotificationIdCache.put(messageId, pushMessage.pushId)
|
|
|
+ }
|
|
|
)
|
|
|
//模拟3s后消失
|
|
|
delay(3000)
|
|
|
@@ -482,9 +659,9 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
}
|
|
|
|
|
|
val largeIconUrl = data.largeIconUrl ?: return@launch
|
|
|
- //先下载完图片再显示
|
|
|
val resizeUrl = imageService.getResizeUrl(largeIconUrl, 48.dp(), 48.dp())
|
|
|
- fetchImage(resizeUrl)
|
|
|
+ //为避免付费消息Push闪烁,不先下载完图片再显示
|
|
|
+// fetchImage(resizeUrl)
|
|
|
|
|
|
withContext(Dispatcher.UI) {
|
|
|
val floatData = when (data.messageType) {
|
|
|
@@ -497,6 +674,13 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
)
|
|
|
}
|
|
|
|
|
|
+ PushMessageType.INCOME_IM.type -> {
|
|
|
+ NotificationIncomeMessageFloatData(
|
|
|
+ MODE_APPLICATION, data.apply {
|
|
|
+ this.largeIconUrl = resizeUrl
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
else -> {
|
|
|
NotificationMessageFloatData(
|
|
|
MODE_APPLICATION,
|
|
|
@@ -516,6 +700,29 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ if (floatData is NotificationIncomeMessageFloatData) {
|
|
|
+ WindowManagerProxy.getWindowManager()
|
|
|
+ .findAllFloatViews(FloatWindowType.NOTIFICATION_MESSAGE).mapNotNull {
|
|
|
+ (it as? NotificationMessageFloatView)
|
|
|
+ }.forEach {
|
|
|
+ if (floatData.data.messageId == it.notificationMessageFloatData.data.messageId) {
|
|
|
+ WindowManagerProxy.getWindowManager().removeView(it)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (floatData is NotificationMessageFloatData) {
|
|
|
+ WindowManagerProxy.getWindowManager()
|
|
|
+ .findAllFloatViews(FloatWindowType.NOTIFICATION_INCOME_MESSAGE).mapNotNull {
|
|
|
+ (it as? NotificationIncomeMessageFloatView)
|
|
|
+ }.forEach {
|
|
|
+ if (floatData.data.messageId == it.notificationIncomeMessageFloatData.data.messageId) {
|
|
|
+ Log.e(
|
|
|
+ TAG_IM_UI,
|
|
|
+ "notification Message filter,messageId:${floatData.data.messageId}"
|
|
|
+ )
|
|
|
+ return@withContext
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
if (floatView != null) {
|
|
|
WindowManagerProxy.getWindowManager().addView(floatView)
|
|
|
}
|
|
|
@@ -541,7 +748,7 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private fun getMessageSummary(messageContent: MessageContent, targetName: String): Spannable {
|
|
|
+ override fun getMessageSummary(messageContent: MessageContent, targetName: String): Spannable {
|
|
|
if (messageContent is CPInviteMessage) {
|
|
|
val giftIconUrl = messageContent.giftIcon
|
|
|
val giftPrice = messageContent.giftPrice
|
|
|
@@ -570,6 +777,14 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
return IMConfigCenter.conversationConfig.getMessageSummary(messageContent)
|
|
|
}
|
|
|
|
|
|
+ override fun addSessionInfoChangeCallback(listType: Int, callback: ISessionInfoChangeCallback) {
|
|
|
+ sessionInfoChangeCallbackMap[listType] = callback
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun removeSessionInfoChangeCallback(listType: Int) {
|
|
|
+ sessionInfoChangeCallbackMap.remove(listType)
|
|
|
+ }
|
|
|
+
|
|
|
private fun handleIm1v1ContinuousSendMessageDeductNotify(data: Im1v1ContinuousSendMessageDeductNotifyInfo) {
|
|
|
dispatch {
|
|
|
it.onIm1v1ContinuousSendMessageDeductNotify(data)
|
|
|
@@ -578,6 +793,7 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
|
|
|
override fun logout() {
|
|
|
sayHiCache.clear()
|
|
|
+ sessionInfoCache.evictAll()
|
|
|
launch {
|
|
|
gettingUserInfoSet.clear()
|
|
|
}
|
|
|
@@ -620,6 +836,8 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private val msgNotificationIdCache = TimeoutLruCache<String, Long>(500, 5 * 60 * 1000)//最多500个,缓存5分钟
|
|
|
+
|
|
|
private val sessionInfoCache = TimeoutLruCache<Long, SessionInfo>(500, 5 * 60 * 1000)//最多500个,缓存5分钟
|
|
|
override suspend fun batchGetSessionInfo(
|
|
|
targetIdSet: Set<Long>,
|
|
|
@@ -668,6 +886,31 @@ class MessageManager : BaseFrame<IMessageListener>(), IMessageManager,
|
|
|
return resultMap
|
|
|
}
|
|
|
|
|
|
+ override suspend fun batchSendQuickMessage(uidList: List<Long>): Rlt<Any> {
|
|
|
+ return when (val rlt =
|
|
|
+ messageHttpService.batchSendQuickMessage(BatchSendQuickMessageReq(uidList))) {
|
|
|
+ is Rlt.Success -> {
|
|
|
+ Rlt.Success(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ is Rlt.Failed -> {
|
|
|
+ rlt
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun getNoReplyMessage(): Rlt<NoReplyMessageRsp?> {
|
|
|
+ return when (val rlt = messageHttpService.getNoReplyMessage()) {
|
|
|
+ is Rlt.Success -> {
|
|
|
+ Rlt.Success(rlt.data.data)
|
|
|
+ }
|
|
|
+
|
|
|
+ is Rlt.Failed -> {
|
|
|
+ rlt
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
override fun onAddIntimacyVal(intimacyValInfo: IntimacyValInfo) {
|
|
|
super.onAddIntimacyVal(intimacyValInfo)
|
|
|
if (!intimacyValInfo.isSelfInvolved()) {
|