diff --git a/app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt b/app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt index e1c92be898..048fe1d617 100644 --- a/app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt +++ b/app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt @@ -1168,6 +1168,16 @@ class ChatRoomPresenter @Inject constructor( } } + fun updateUnreadRoomsBadge() { + Timber.w("reached updateUnreadRoomsBadge") + view.updateUnreadRoomsBadge(dbManager.totalUnreadRooms) + } + + suspend fun getRoomAlert(roomId: String): Boolean? { + val room = dbManager.getRoom(roomId) + return room?.chatRoom?.alert + } + fun runCommand(text: String, roomId: String) { launchUI(strategy) { try { diff --git a/app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt b/app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt index 15f241b2cb..89ae53f14a 100644 --- a/app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt +++ b/app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt @@ -1,5 +1,6 @@ package chat.rocket.android.chatroom.presentation +import androidx.lifecycle.MutableLiveData import chat.rocket.android.chatroom.uimodel.BaseUiModel import chat.rocket.android.chatroom.uimodel.suggestion.ChatRoomSuggestionUiModel import chat.rocket.android.chatroom.uimodel.suggestion.CommandSuggestionUiModel @@ -145,4 +146,6 @@ interface ChatRoomView : LoadingView, MessageView { fun onRoomUpdated(roomUiModel: RoomUiModel) + fun updateUnreadRoomsBadge(totalUnreadRooms: MutableLiveData) + } diff --git a/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt b/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt index 58f978a914..09526e48b4 100644 --- a/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt +++ b/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt @@ -6,6 +6,7 @@ import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.isVisible import chat.rocket.android.R import chat.rocket.android.chatroom.presentation.ChatRoomNavigator import chat.rocket.android.server.domain.GetCurrentServerInteractor @@ -19,6 +20,7 @@ import dagger.android.AndroidInjector import dagger.android.DispatchingAndroidInjector import dagger.android.support.HasSupportFragmentInjector import kotlinx.android.synthetic.main.app_bar_chat_room.* +import kotlinx.android.synthetic.main.unread_messages_badge.* import javax.inject.Inject fun Context.chatRoomIntent( @@ -163,6 +165,26 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { text_room_name.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) } + fun bindUnreadRooms(totalUnreadRooms: Long) { + val textView = text_total_unread_messages + when { + totalUnreadRooms in 1..9 -> { + textView.textContent = totalUnreadRooms.toString() + textView.isVisible = true + toolbar.setNavigationIcon(R.drawable.ic_keyboard_arrow_left_white_24dp) + } + totalUnreadRooms > 9 -> { + textView.textContent = "!" + textView.isVisible = true + toolbar.setNavigationIcon(R.drawable.ic_keyboard_arrow_left_white_24dp) + } + else -> { + textView.isVisible = false + toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp) + } + } + } + private fun finishActivity() { super.onBackPressed() overridePendingTransition(R.anim.close_enter, R.anim.close_exit) diff --git a/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt b/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt index 85b092845c..d340003674 100644 --- a/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt +++ b/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt @@ -28,6 +28,8 @@ import androidx.core.text.bold import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.Observer import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -94,6 +96,8 @@ import kotlinx.android.synthetic.main.message_attachment_options.* import kotlinx.android.synthetic.main.message_composer.* import kotlinx.android.synthetic.main.message_list.* import kotlinx.android.synthetic.main.reaction_praises_list_item.view.* +import kotlinx.coroutines.experimental.CommonPool +import kotlinx.coroutines.experimental.runBlocking import timber.log.Timber import java.io.File import java.io.IOException @@ -314,6 +318,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) text_message.addTextChangedListener(EmojiKeyboardPopup.EmojiTextWatcher(text_message)) + presenter.updateUnreadRoomsBadge() } override fun onDestroyView() { @@ -1051,6 +1056,25 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR view_dim.isVisible = false } + override fun updateUnreadRoomsBadge(totalUnreadRooms: MutableLiveData) { + ui { + val updateTotalUnreadRooms = Observer { newTotalUnreadRooms -> + var alert: Boolean? = null + runBlocking(CommonPool) { + alert = presenter.getRoomAlert(chatRoomId) + } + Timber.d("newTotalUnreadRooms: ${newTotalUnreadRooms}, alert: ${alert}") + (activity as ChatRoomActivity).let { + if (alert == true) + it.bindUnreadRooms(newTotalUnreadRooms - 1) + else + it.bindUnreadRooms(newTotalUnreadRooms) + } + } + totalUnreadRooms.observe(this, updateTotalUnreadRooms) + } + } + private fun setupToolbar(toolbarTitle: String) { with(activity as ChatRoomActivity) { this.clearLightStatusBar() diff --git a/app/src/main/java/chat/rocket/android/db/DatabaseManager.kt b/app/src/main/java/chat/rocket/android/db/DatabaseManager.kt index 40044c8d5f..c5f55487bb 100644 --- a/app/src/main/java/chat/rocket/android/db/DatabaseManager.kt +++ b/app/src/main/java/chat/rocket/android/db/DatabaseManager.kt @@ -1,6 +1,7 @@ package chat.rocket.android.db import android.app.Application +import androidx.lifecycle.MutableLiveData import chat.rocket.android.R import chat.rocket.android.db.model.BaseMessageEntity import chat.rocket.android.db.model.BaseUserEntity @@ -64,6 +65,9 @@ class DatabaseManager(val context: Application, val serverUrl: String) { private val insertRooms = HashMap() private val updateSubs = LinkedHashMap() private val updateRooms = LinkedHashMap() + val totalUnreadRooms: MutableLiveData by lazy { + MutableLiveData() + } fun chatRoomDao(): ChatRoomDao = database.chatRoomDao() fun userDao(): UserDao = database.userDao() @@ -553,12 +557,15 @@ class DatabaseManager(val context: Application, val serverUrl: String) { Timber.d("Running ChatRooms transaction: remove: ${operation.toRemove} - insert: ${operation.toInsert} - update: ${operation.toUpdate}") chatRoomDao().update(operation.toInsert, operation.toUpdate, operation.toRemove) + updateUnreadRoomsCount() } is Operation.InsertRooms -> { chatRoomDao().insertOrReplace(operation.chatRooms) + updateUnreadRoomsCount() } is Operation.CleanInsertRooms -> { chatRoomDao().cleanInsert(operation.chatRooms) + updateUnreadRoomsCount() } is Operation.InsertUsers -> { val time = measureTimeMillis { userDao().upsert(operation.users) } @@ -572,6 +579,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) { } is Operation.InsertMessages -> { messageDao().insert(operation.list) + updateUnreadRoomsCount() } is Operation.SaveLastSync -> { messageDao().saveLastSync(operation.sync) @@ -579,6 +587,19 @@ class DatabaseManager(val context: Application, val serverUrl: String) { }.exhaustive } } + + private fun updateUnreadRoomsCount() { + val rooms: List = chatRoomDao().getAllSync() + var count: Long = 0 + Timber.d("chatroomdao: ${rooms}") + rooms.forEach { room -> + if (room.chatRoom.alert || room.chatRoom.unread > 0) { + count++ + } + } + Timber.d("Total unread rooms: ${count}") + totalUnreadRooms.postValue(count) + } } sealed class Operation { diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_left_white_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_left_white_24dp.xml new file mode 100644 index 0000000000..b79d00f6e3 --- /dev/null +++ b/app/src/main/res/drawable/ic_keyboard_arrow_left_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/app_bar_chat_room.xml b/app/src/main/res/layout/app_bar_chat_room.xml index c02136c155..77d1c5053a 100644 --- a/app/src/main/res/layout/app_bar_chat_room.xml +++ b/app/src/main/res/layout/app_bar_chat_room.xml @@ -7,6 +7,10 @@ android:background="@color/colorPrimary" android:theme="@style/Theme.AppCompat.Light.NoActionBar"> + + + app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintLeft_toLeftOf="parent"> + + + + \ No newline at end of file