From 805db56d550ea0e228e0e3678868f6505eaf632d Mon Sep 17 00:00:00 2001 From: kaixed Date: Fri, 13 Dec 2024 22:55:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=A5=BD=E5=8F=8B?= =?UTF-8?q?=E5=85=8D=E6=89=93=E6=89=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增好友免打扰功能 - 修复好友未读消息显示错误 --- app/build.gradle.kts | 2 +- app/objectbox-models/default.json | 17 ++- app/objectbox-models/default.json.bak | 23 ++- .../kaixed/kchat/data/local/entity/Contact.kt | 2 +- .../kchat/data/local/entity/Conversation.kt | 2 +- .../kchat/manager/ConversationManager.kt | 43 +++++- .../kchat/ui/activity/ChatDetailActivity.kt | 9 ++ .../ui/activity/setting/AboutActivity.kt | 3 + .../kchat/ui/adapter/ConversationAdapter.kt | 31 +++- .../kaixed/kchat/ui/fragment/HomeFragment.kt | 14 +- .../com/kaixed/kchat/ui/widget/CustomItem.kt | 3 + .../kchat/ui/widget/LoadingDialogFragment.kt | 4 +- app/src/main/res/layout/activity_about.xml | 141 ++++++++++-------- app/src/main/res/layout/activity_chat.xml | 2 +- .../main/res/layout/activity_chat_detail.xml | 4 + app/src/main/res/layout/chat_main_item.xml | 25 +++- app/src/main/res/layout/dialog_loading.xml | 10 +- 17 files changed, 224 insertions(+), 111 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index acb8969..e972320 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,7 +20,7 @@ android { minSdk = 28 targetSdk = 34 versionCode = 1 - versionName = "1.0" + versionName = "0.0.01" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/objectbox-models/default.json b/app/objectbox-models/default.json index 86ff614..1bfa6eb 100644 --- a/app/objectbox-models/default.json +++ b/app/objectbox-models/default.json @@ -74,7 +74,7 @@ }, { "id": "4:6179749773128044271", - "lastPropertyId": "14:5371512009949707960", + "lastPropertyId": "15:191614052410347083", "name": "Contact", "properties": [ { @@ -145,8 +145,8 @@ "type": 9 }, { - "id": "14:5371512009949707960", - "name": "disturb", + "id": "15:191614052410347083", + "name": "doNotDisturb", "type": 1 } ], @@ -200,7 +200,7 @@ }, { "id": "6:411582187056789368", - "lastPropertyId": "12:385998119105891942", + "lastPropertyId": "14:1552912281343049591", "name": "Conversation", "properties": [ { @@ -250,6 +250,11 @@ "id": "11:1529665629379902832", "name": "isPinned", "type": 1 + }, + { + "id": "14:1552912281343049591", + "name": "doNotDisturb", + "type": 1 } ], "relations": [] @@ -292,7 +297,9 @@ 6199737871252062125, 2020630799900991467, 385998119105891942, - 8166842332862045141 + 8166842332862045141, + 605708604168234493, + 5371512009949707960 ], "retiredRelationUids": [], "version": 1 diff --git a/app/objectbox-models/default.json.bak b/app/objectbox-models/default.json.bak index a00d76e..c5f404f 100644 --- a/app/objectbox-models/default.json.bak +++ b/app/objectbox-models/default.json.bak @@ -5,7 +5,7 @@ "entities": [ { "id": "1:488582047102418567", - "lastPropertyId": "15:6294917834245722650", + "lastPropertyId": "16:1385814819739404832", "name": "Messages", "properties": [ { @@ -44,11 +44,6 @@ "name": "senderId", "type": 9 }, - { - "id": "11:8166842332862045141", - "name": "takerId", - "type": 9 - }, { "id": "12:4851920989895940582", "name": "show", @@ -68,6 +63,11 @@ "id": "15:6294917834245722650", "name": "avatarUrl", "type": 9 + }, + { + "id": "16:1385814819739404832", + "name": "talkerId", + "type": 9 } ], "relations": [] @@ -200,7 +200,7 @@ }, { "id": "6:411582187056789368", - "lastPropertyId": "12:385998119105891942", + "lastPropertyId": "14:1552912281343049591", "name": "Conversation", "properties": [ { @@ -250,6 +250,11 @@ "id": "11:1529665629379902832", "name": "isPinned", "type": 1 + }, + { + "id": "14:1552912281343049591", + "name": "doNotDisturb", + "type": 1 } ], "relations": [] @@ -291,7 +296,9 @@ 8705063061921345729, 6199737871252062125, 2020630799900991467, - 385998119105891942 + 385998119105891942, + 8166842332862045141, + 605708604168234493 ], "retiredRelationUids": [], "version": 1 diff --git a/app/src/main/java/com/kaixed/kchat/data/local/entity/Contact.kt b/app/src/main/java/com/kaixed/kchat/data/local/entity/Contact.kt index 6c64899..d11cc0c 100644 --- a/app/src/main/java/com/kaixed/kchat/data/local/entity/Contact.kt +++ b/app/src/main/java/com/kaixed/kchat/data/local/entity/Contact.kt @@ -28,5 +28,5 @@ data class Contact( var showHeader: Boolean? = false, var address: String? = null, var gender: String? = null, - var disturb: Boolean = true + var doNotDisturb: Boolean = false ) diff --git a/app/src/main/java/com/kaixed/kchat/data/local/entity/Conversation.kt b/app/src/main/java/com/kaixed/kchat/data/local/entity/Conversation.kt index fad6c7b..48a5340 100644 --- a/app/src/main/java/com/kaixed/kchat/data/local/entity/Conversation.kt +++ b/app/src/main/java/com/kaixed/kchat/data/local/entity/Conversation.kt @@ -3,7 +3,6 @@ package com.kaixed.kchat.data.local.entity import io.objectbox.annotation.Entity import io.objectbox.annotation.Id import io.objectbox.annotation.Index -import io.objectbox.relation.ToOne /** * @Author: kaixed @@ -23,4 +22,5 @@ data class Conversation( var unreadCount: Int = 0, var isShow: Boolean = true, var isPinned: Boolean = false, + var doNotDisturb: Boolean = false ) \ No newline at end of file diff --git a/app/src/main/java/com/kaixed/kchat/manager/ConversationManager.kt b/app/src/main/java/com/kaixed/kchat/manager/ConversationManager.kt index 519850e..3c34421 100644 --- a/app/src/main/java/com/kaixed/kchat/manager/ConversationManager.kt +++ b/app/src/main/java/com/kaixed/kchat/manager/ConversationManager.kt @@ -4,6 +4,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.kaixed.kchat.data.LocalDatabase.getContactByUsername import com.kaixed.kchat.data.local.box.ObjectBox.getBoxStore +import com.kaixed.kchat.data.local.entity.Contact +import com.kaixed.kchat.data.local.entity.Contact_ import com.kaixed.kchat.data.local.entity.Conversation import com.kaixed.kchat.data.local.entity.Conversation_ import com.kaixed.kchat.data.local.entity.Messages @@ -23,6 +25,7 @@ object ConversationManager { val conversations: LiveData?> get() = _conversationLiveData private val conversationBox: Box by lazy { getBoxStore().boxFor() } + private val contactBox: Box by lazy { getBoxStore().boxFor() } private val messagesBox: Box by lazy { getBoxStore().boxFor() } private val conversationMap: MutableMap = mutableMapOf() @@ -39,13 +42,13 @@ object ConversationManager { // 使用 Map 来优化查找效率 conversationMap.putAll(conversations.associateBy { it.talkerId }) - _conversationLiveData.postValue(conversations.sortedByDescending { it.timestamp }) + updateLiveData() } fun handleMessages(messages: Messages) { val updatedConversation = updateConversation(messages) conversationBox.put(updatedConversation) - _conversationLiveData.postValue(conversationMap.values.sortedByDescending { it.timestamp }) + updateLiveData() } private fun updateConversation(messages: Messages): Conversation { @@ -63,14 +66,46 @@ object ConversationManager { conversationMap[contactId]?.apply { isShow = false } - _conversationLiveData.postValue(conversationMap.values.filter { it.isShow } - .sortedByDescending { it.timestamp }) + updateLiveData() } fun deleteConversation(conversation: Conversation) { conversationMap.remove(conversation.talkerId) conversationBox.query(Conversation_.talkerId.equal(conversation.talkerId)).build().remove() messagesBox.query(Messages_.talkerId.equal(conversation.talkerId)).build().remove() + updateLiveData() + } + + fun updateUnreadCount(talkerId: String) { + conversationMap[talkerId].apply { + this?.unreadCount = 0 + } + val conversation = + conversationBox.query(Conversation_.talkerId.equal(talkerId)).build().findFirst() + + conversation?.let { + it.unreadCount = 0 + conversationBox.put(it) + } + updateLiveData() + } + + fun updateDisturbStatus(contactId: String, isDisturb: Boolean) { + conversationMap[contactId]?.apply { + this.doNotDisturb = isDisturb + } + + conversationBox.put(conversationMap[contactId]!!) + + val dbContact = contactBox.query(Contact_.username.equal(contactId)).build() + .findFirst().apply { + this?.doNotDisturb = isDisturb + } + contactBox.put(dbContact!!) + updateLiveData() + } + + private fun updateLiveData() { _conversationLiveData.postValue(conversationMap.values.sortedByDescending { it.timestamp }) } diff --git a/app/src/main/java/com/kaixed/kchat/ui/activity/ChatDetailActivity.kt b/app/src/main/java/com/kaixed/kchat/ui/activity/ChatDetailActivity.kt index 6cbf949..3c298f7 100644 --- a/app/src/main/java/com/kaixed/kchat/ui/activity/ChatDetailActivity.kt +++ b/app/src/main/java/com/kaixed/kchat/ui/activity/ChatDetailActivity.kt @@ -6,8 +6,10 @@ import androidx.activity.enableEdgeToEdge import com.bumptech.glide.Glide import com.kaixed.kchat.data.LocalDatabase.getContactByUsername import com.kaixed.kchat.databinding.ActivityChatDetailBinding +import com.kaixed.kchat.manager.ConversationManager import com.kaixed.kchat.manager.MessagesManager import com.kaixed.kchat.ui.base.BaseActivity +import com.kaixed.kchat.ui.widget.SwitchButton import org.greenrobot.eventbus.EventBus class ChatDetailActivity : BaseActivity() { @@ -36,9 +38,16 @@ class ChatDetailActivity : BaseActivity() { override fun initData() { contactId = intent.getStringExtra("contactId") ?: "" + binding.ciSetDisturb.setSwitchChecked(contact?.doNotDisturb ?: false) } private fun setListener() { + binding.ciSetDisturb.sbSwitch.setOnCheckedChangeListener(object : + SwitchButton.OnCheckedChangeListener { + override fun onCheckedChanged(button: SwitchButton, isChecked: Boolean) { + ConversationManager.updateDisturbStatus(contactId, isChecked) + } + }) binding.ciCleanChatHistory.setOnClickListener { val timestamp = System.currentTimeMillis() MessagesManager.cleanMessages(timestamp) diff --git a/app/src/main/java/com/kaixed/kchat/ui/activity/setting/AboutActivity.kt b/app/src/main/java/com/kaixed/kchat/ui/activity/setting/AboutActivity.kt index 33fd3f3..3c83959 100644 --- a/app/src/main/java/com/kaixed/kchat/ui/activity/setting/AboutActivity.kt +++ b/app/src/main/java/com/kaixed/kchat/ui/activity/setting/AboutActivity.kt @@ -18,6 +18,9 @@ class AboutActivity : BaseActivity() { } override fun initData() { + val activityInfo = packageManager.getPackageInfo(packageName, 0) + val version = "Version ${activityInfo.versionName}" + binding.tvVersion.text = version binding.ciCheckUpdate.setOnClickListener { val loadingDialog = LoadingDialogFragment.newInstance("检查中...") loadingDialog.showLoading(supportFragmentManager) diff --git a/app/src/main/java/com/kaixed/kchat/ui/adapter/ConversationAdapter.kt b/app/src/main/java/com/kaixed/kchat/ui/adapter/ConversationAdapter.kt index 89327fb..1323314 100644 --- a/app/src/main/java/com/kaixed/kchat/ui/adapter/ConversationAdapter.kt +++ b/app/src/main/java/com/kaixed/kchat/ui/adapter/ConversationAdapter.kt @@ -54,13 +54,7 @@ class ConversationAdapter( Glide.with(context).load(chatList.avatarUrl).apply(options) .into(holder.binding.ifvAvatar) } - - if (chatList.unreadCount != 0) { - holder.binding.tvUnreadCount.text = chatList.unreadCount.toString() - holder.binding.rlUnreadCount.visibility = View.VISIBLE - } else { - holder.binding.rlUnreadCount.visibility = View.INVISIBLE - } + val bind = holder.binding holder.bind(chatList, context) holder.itemView.setOnClickListener { @@ -76,9 +70,30 @@ class ConversationAdapter( onItemListener!!.onItemLongClick(chatList.talkerId, chatList.nickname) true } + + bind.ivDoNotDisturb.visibility = if (chatList.doNotDisturb) View.VISIBLE else View.INVISIBLE + + if (chatList.unreadCount == 0) { + bind.viewRedDot.visibility = View.INVISIBLE + bind.rlUnreadCount.visibility = View.INVISIBLE + return + } + + if (chatList.unreadCount > 99) { + holder.binding.tvUnreadCount.text = "99+" + } + bind.viewRedDot.visibility = + if (chatList.doNotDisturb) View.VISIBLE else View.INVISIBLE + + if (chatList.doNotDisturb) { + bind.rlUnreadCount.visibility = View.INVISIBLE + } else { + bind.tvUnreadCount.text = chatList.unreadCount.toString() + bind.rlUnreadCount.visibility = View.VISIBLE + } } - inner class MyViewHolder(val binding: ChatMainItemBinding) : + class MyViewHolder(val binding: ChatMainItemBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(chatList: Conversation, context: Context) { binding.tvContent.text = chatList.lastContent.replaceSpan("[委屈]") { diff --git a/app/src/main/java/com/kaixed/kchat/ui/fragment/HomeFragment.kt b/app/src/main/java/com/kaixed/kchat/ui/fragment/HomeFragment.kt index 8edb89f..5ef65d4 100644 --- a/app/src/main/java/com/kaixed/kchat/ui/fragment/HomeFragment.kt +++ b/app/src/main/java/com/kaixed/kchat/ui/fragment/HomeFragment.kt @@ -294,19 +294,7 @@ class HomeFragment : BaseFragment(), OnItemListener, override fun onItemClick(talkerId: String) { this.talkerId = talkerId - for (i in chatLists.indices) { - if (chatLists[i].talkerId == talkerId) { - chatLists[i].unreadCount = 0 - } - } - notifyData() - val conversation = - conversationBox.query(Conversation_.talkerId.equal(talkerId)).build().findFirst() - - conversation?.let { - it.unreadCount = 0 - conversationBox.put(it) - } + ConversationManager.updateUnreadCount(talkerId) } private var longClickTalkerId = "" diff --git a/app/src/main/java/com/kaixed/kchat/ui/widget/CustomItem.kt b/app/src/main/java/com/kaixed/kchat/ui/widget/CustomItem.kt index bbefb84..82b841b 100644 --- a/app/src/main/java/com/kaixed/kchat/ui/widget/CustomItem.kt +++ b/app/src/main/java/com/kaixed/kchat/ui/widget/CustomItem.kt @@ -24,6 +24,9 @@ class CustomItem @JvmOverloads constructor( private var binding: ItemCustomBinding = ItemCustomBinding.inflate(LayoutInflater.from(context), this, true) + val sbSwitch: SwitchButton + get() = binding.sbSwitch + init { attrs?.let { val typedArray = context.obtainStyledAttributes(it, R.styleable.CustomItem, 0, 0) diff --git a/app/src/main/java/com/kaixed/kchat/ui/widget/LoadingDialogFragment.kt b/app/src/main/java/com/kaixed/kchat/ui/widget/LoadingDialogFragment.kt index 2e3bc34..a63e8c1 100644 --- a/app/src/main/java/com/kaixed/kchat/ui/widget/LoadingDialogFragment.kt +++ b/app/src/main/java/com/kaixed/kchat/ui/widget/LoadingDialogFragment.kt @@ -42,8 +42,8 @@ class LoadingDialogFragment : DialogFragment() { // 设置对话框的大小 val params = binding.root.layoutParams - params.height = dpToPx(150) - params.width = dpToPx(150) + params.height = dpToPx(120) + params.width = dpToPx(120) binding.root.layoutParams = params return dialog diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index cfbe822..73aa7ab 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -18,74 +18,93 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent"> - + + + + + + + + + + + + + + + + + + + android:layout_marginBottom="20dp" + android:text="Copyright © 2024-Present 糕小菜. All Rights Reserved." + android:textSize="11sp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml index 45757bc..886ce5c 100644 --- a/app/src/main/res/layout/activity_chat.xml +++ b/app/src/main/res/layout/activity_chat.xml @@ -12,8 +12,8 @@ android:id="@+id/ctb" android:layout_width="match_parent" android:layout_height="wrap_content" - app:titleIcon="@drawable/ic_more" android:background="#F7F7F7" + app:titleIcon="@drawable/ic_more" app:titleName="contact" /> + + @@ -86,5 +98,16 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/tv_nickname" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_loading.xml b/app/src/main/res/layout/dialog_loading.xml index 255d21e..1d3ca57 100644 --- a/app/src/main/res/layout/dialog_loading.xml +++ b/app/src/main/res/layout/dialog_loading.xml @@ -7,7 +7,7 @@ android:orientation="vertical" android:paddingHorizontal="25dp" android:paddingVertical="25dp" - app:cardCornerRadius="5dp" + app:cardCornerRadius="8dp" app:cardElevation="0dp">