diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6e8f6777..899d0828 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -82,15 +82,17 @@ dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") + implementation("androidx.core:core-splashscreen:1.0.0-alpha02") + implementation("androidx.work:work-runtime-ktx:2.6.0") implementation("androidx.datastore:datastore-preferences:1.0.0") implementation("androidx.paging:paging-runtime-ktx:3.0.1") - implementation("androidx.appcompat:appcompat:1.4.0-alpha03") - implementation("com.google.android.material:material:1.5.0-alpha03") - implementation("androidx.core:core-ktx:1.7.0-beta01") + implementation("androidx.appcompat:appcompat:1.4.0-beta01") + implementation("com.google.android.material:material:1.5.0-alpha04") + implementation("androidx.core:core-ktx:1.7.0-beta02") implementation("androidx.preference:preference-ktx:1.1.1") implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01") implementation("androidx.recyclerview:recyclerview:1.2.1") @@ -118,16 +120,16 @@ dependencies { implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") - implementation("com.google.dagger:hilt-android:2.38.1") - kapt("com.google.dagger:hilt-android-compiler:2.38.1") + implementation("com.google.dagger:hilt-android:2.39.1") + kapt("com.google.dagger:hilt-android-compiler:2.39.1") implementation("androidx.hilt:hilt-navigation-fragment:1.0.0") implementation("com.github.yogacp:android-viewbinding:1.0.3") - implementation("io.coil-kt:coil:1.3.2") + implementation("io.coil-kt:coil:1.4.0") implementation("com.google.code.gson:gson:2.8.8") - implementation("org.jsoup:jsoup:1.14.2") + implementation("org.jsoup:jsoup:1.14.3") implementation("ch.acra:acra:4.11.1") } \ No newline at end of file diff --git a/app/src/main/kotlin/com/meloda/fast/activity/MainActivity.kt b/app/src/main/kotlin/com/meloda/fast/activity/MainActivity.kt index d7f095d2..e02414e4 100644 --- a/app/src/main/kotlin/com/meloda/fast/activity/MainActivity.kt +++ b/app/src/main/kotlin/com/meloda/fast/activity/MainActivity.kt @@ -1,8 +1,17 @@ package com.meloda.fast.activity +import android.os.Bundle +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import com.meloda.fast.R import com.meloda.fast.base.BaseActivity import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class MainActivity : BaseActivity(R.layout.activity_main) \ No newline at end of file +class MainActivity : BaseActivity(R.layout.activity_main) { + + override fun onCreate(savedInstanceState: Bundle?) { + installSplashScreen() + super.onCreate(savedInstanceState) + } + +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/meloda/fast/api/network/conversations/ConversationsDataSource.kt b/app/src/main/kotlin/com/meloda/fast/api/network/conversations/ConversationsDataSource.kt index 515dd4b5..838a5a8f 100644 --- a/app/src/main/kotlin/com/meloda/fast/api/network/conversations/ConversationsDataSource.kt +++ b/app/src/main/kotlin/com/meloda/fast/api/network/conversations/ConversationsDataSource.kt @@ -13,7 +13,9 @@ class ConversationsDataSource @Inject constructor( suspend fun delete(params: ConversationsDeleteRequest) = repo.delete(params.map) + suspend fun pin(params: ConversationsPinRequest) = repo.pin(params.map) + suspend fun unpin(params: ConversationsUnpinRequest) = repo.unpin(params.map) suspend fun store(conversations: List) = dao.insert(conversations) diff --git a/app/src/main/kotlin/com/meloda/fast/api/network/conversations/ConversationsRequest.kt b/app/src/main/kotlin/com/meloda/fast/api/network/conversations/ConversationsRequest.kt index 81fdca5d..9bd9a622 100644 --- a/app/src/main/kotlin/com/meloda/fast/api/network/conversations/ConversationsRequest.kt +++ b/app/src/main/kotlin/com/meloda/fast/api/network/conversations/ConversationsRequest.kt @@ -28,4 +28,14 @@ data class ConversationsGetRequest( @Parcelize data class ConversationsDeleteRequest(val peerId: Int) : Parcelable { val map get() = mapOf("peer_id" to peerId.toString()) +} + +@Parcelize +data class ConversationsPinRequest(val peerId: Int) : Parcelable { + val map get() = mapOf("peer_id" to peerId.toString()) +} + +@Parcelize +data class ConversationsUnpinRequest(val peerId: Int) : Parcelable { + val map get() = mapOf("peer_id" to peerId.toString()) } \ No newline at end of file diff --git a/app/src/main/kotlin/com/meloda/fast/screens/conversations/ConversationsFragment.kt b/app/src/main/kotlin/com/meloda/fast/screens/conversations/ConversationsFragment.kt index a807c83e..e63621a3 100644 --- a/app/src/main/kotlin/com/meloda/fast/screens/conversations/ConversationsFragment.kt +++ b/app/src/main/kotlin/com/meloda/fast/screens/conversations/ConversationsFragment.kt @@ -187,6 +187,9 @@ class ConversationsFragment : is ConversationsLoaded -> refreshConversations(event) is ConversationsDelete -> deleteConversation(event.peerId) + + // TODO: 10-Oct-21 remove this and sort conversations list + is ConversationsPin, is ConversationsUnpin -> viewModel.loadConversations() } } @@ -240,13 +243,19 @@ class ConversationsFragment : private fun fillRecyclerView(values: List) { adapter.values.clear() adapter.values += values - adapter.notifyItemRangeChanged(0, adapter.itemCount) + adapter.submitList(values) } private fun onItemClick(position: Int) { val conversation = adapter[position] - val user = if (conversation.isUser()) adapter.profiles[conversation.id] else null - val group = if (conversation.isGroup()) adapter.groups[conversation.id] else null + + val user = + if (conversation.isUser()) adapter.profiles[conversation.id] + else null + + val group = + if (conversation.isGroup()) adapter.groups[conversation.id] + else null findNavController().navigate( R.id.toMessagesHistory, @@ -266,15 +275,36 @@ class ConversationsFragment : private fun showOptionsDialog(position: Int) { val conversation = adapter[position] + var canPinOneMoreDialog = true + if (adapter.itemCount > 4) { + val firstFiveDialogs = adapter.values.subList(0, 5) + var pinnedCount = 0 + + firstFiveDialogs.forEach { if (it.isPinned) pinnedCount++ } + if (pinnedCount == 5 && position > 4) { + canPinOneMoreDialog = false + } + } + + val pin = getString( + if (conversation.isPinned) R.string.conversation_context_action_unpin + else R.string.conversation_context_action_pin + ) + val delete = getString(R.string.conversation_context_action_delete) - val params = mutableListOf(delete) + val params = mutableListOf() + + if (canPinOneMoreDialog) params += pin + + params += delete val arrayParams = params.toTypedArray() MaterialAlertDialogBuilder(requireContext()) .setItems(arrayParams) { _, which -> when (params[which]) { + pin -> showPinConversationDialog(conversation) delete -> showDeleteConversationDialog(conversation.id) } }.show() @@ -295,4 +325,24 @@ class ConversationsFragment : adapter.notifyItemRemoved(index) } + private fun showPinConversationDialog(conversation: VkConversation) { + val isPinned = conversation.isPinned + MaterialAlertDialogBuilder(requireContext()) + .setTitle( + if (isPinned) R.string.confirm_unpin_conversation + else R.string.confirm_pin_conversation + ) + .setPositiveButton( + if (isPinned) R.string.action_unpin + else R.string.action_pin + ) { _, _ -> + viewModel.pinConversation( + peerId = conversation.id, + pin = !isPinned + ) + } + .setNegativeButton(android.R.string.cancel, null) + .show() + } + } \ No newline at end of file diff --git a/app/src/main/kotlin/com/meloda/fast/screens/conversations/ConversationsViewModel.kt b/app/src/main/kotlin/com/meloda/fast/screens/conversations/ConversationsViewModel.kt index 866d7f80..c750edd0 100644 --- a/app/src/main/kotlin/com/meloda/fast/screens/conversations/ConversationsViewModel.kt +++ b/app/src/main/kotlin/com/meloda/fast/screens/conversations/ConversationsViewModel.kt @@ -6,9 +6,7 @@ import com.meloda.fast.api.VKConstants import com.meloda.fast.api.model.VkConversation import com.meloda.fast.api.model.VkGroup import com.meloda.fast.api.model.VkUser -import com.meloda.fast.api.network.conversations.ConversationsDataSource -import com.meloda.fast.api.network.conversations.ConversationsDeleteRequest -import com.meloda.fast.api.network.conversations.ConversationsGetRequest +import com.meloda.fast.api.network.conversations.* import com.meloda.fast.api.network.users.UsersDataSource import com.meloda.fast.api.network.users.UsersGetRequest import com.meloda.fast.base.viewmodel.BaseViewModel @@ -34,7 +32,7 @@ class ConversationsViewModel @Inject constructor( count = 30, extended = true, offset = offset, - fields = "${VKConstants.ALL_FIELDS}" + fields = VKConstants.ALL_FIELDS ) ) }, @@ -88,6 +86,23 @@ class ConversationsViewModel @Inject constructor( ) }, onAnswer = { sendEvent(ConversationsDelete(peerId)) }) } + + fun pinConversation( + peerId: Int, + pin: Boolean + ) = viewModelScope.launch { + if (pin) { + makeJob( + { conversations.pin(ConversationsPinRequest(peerId)) }, + onAnswer = { sendEvent(ConversationsPin(peerId)) } + ) + } else { + makeJob( + { conversations.unpin(ConversationsUnpinRequest(peerId)) }, + onAnswer = { sendEvent(ConversationsUnpin(peerId)) } + ) + } + } } data class ConversationsLoaded( @@ -99,4 +114,8 @@ data class ConversationsLoaded( val groups: HashMap ) : VkEvent() -data class ConversationsDelete(val peerId: Int) : VkEvent() \ No newline at end of file +data class ConversationsDelete(val peerId: Int) : VkEvent() + +data class ConversationsPin(val peerId: Int) : VkEvent() + +data class ConversationsUnpin(val peerId: Int) : VkEvent() \ No newline at end of file diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml index f1503161..0deb0bf0 100644 --- a/app/src/main/res/values/ic_launcher_background.xml +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,5 @@ - #4184F5 + + @color/a1_500 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1fabaf95..989b5d0a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -134,4 +134,10 @@ Delete the conversation? Sign out Sign out + Unpin + Pin + Unpin the conversation? + Pin the conversation? + Pin + Unpin diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 145b8b2f..517ae724 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -41,5 +41,10 @@ 12dp + \ No newline at end of file