diff --git a/app/build.gradle b/app/build.gradle index c130bae25d629221f5e4b64a9f0bd608d520f366..cfd661ff35416bdeba2124d8d53e4bdb0166d4f9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -105,7 +105,7 @@ dependencies { implementation project(path: ':gallery') //Firebase - gplayImplementation platform('com.google.firebase:firebase-bom:32.7.2') + gplayImplementation platform('com.google.firebase:firebase-bom:32.7.4') gplayImplementation 'com.google.firebase:firebase-crashlytics-ktx' gplayImplementation 'com.google.firebase:firebase-analytics-ktx' gplayImplementation 'com.google.firebase:firebase-messaging-ktx' diff --git a/app/src/main/java/org/futo/circles/feature/home/HomeFragment.kt b/app/src/main/java/org/futo/circles/feature/home/HomeFragment.kt index 77b7a50edf43ef92c14a69a0d69a53ffd667f987..d639cd939f4109e6007ef70d3acc8664b48ffb4b 100644 --- a/app/src/main/java/org/futo/circles/feature/home/HomeFragment.kt +++ b/app/src/main/java/org/futo/circles/feature/home/HomeFragment.kt @@ -140,7 +140,7 @@ class HomeFragment : Fragment(R.layout.fragment_bottom_navigation), DeepLinkInte } viewModel.syncStateLiveData.observeData(this) { if (it is SyncState.Running && it.afterPause) { - syncLoadingDialog.handleLoading(LoadingData(org.futo.circles.auth.R.string.initial_sync)) + syncLoadingDialog.handleLoading(LoadingData(org.futo.circles.auth.R.string.session_sync)) } else syncLoadingDialog.dismiss() } } diff --git a/app/src/main/java/org/futo/circles/feature/notifications/NotifiableEventResolver.kt b/app/src/main/java/org/futo/circles/feature/notifications/NotifiableEventResolver.kt index 9b749b3df705cc6f1d39460d6bb65b9d0dc9f2b9..23ecfaa3c0d36aa57121e8d6468ea5b731049325 100644 --- a/app/src/main/java/org/futo/circles/feature/notifications/NotifiableEventResolver.kt +++ b/app/src/main/java/org/futo/circles/feature/notifications/NotifiableEventResolver.kt @@ -5,6 +5,7 @@ import android.net.Uri import dagger.hilt.android.qualifiers.ApplicationContext import org.futo.circles.R import org.futo.circles.core.extensions.notEmptyDisplayName +import org.futo.circles.core.utils.circlesRoomsTypes import org.futo.circles.model.InviteNotifiableEvent import org.futo.circles.model.NotifiableEvent import org.futo.circles.model.NotifiableMessageEvent @@ -49,6 +50,11 @@ class NotifiableEventResolver @Inject constructor( suspend fun resolveEvent(event: Event, session: Session): NotifiableEvent? { val roomID = event.roomId ?: return null val eventId = event.eventId ?: return null + + // filter + val roomType = session.getRoom(roomID)?.roomSummary()?.roomType + if (roomType !in circlesRoomsTypes) return null + if (event.getClearType() == EventType.STATE_ROOM_MEMBER) { return resolveStateRoomEvent(event, session) } diff --git a/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt b/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt index bd0b1f1831d8b78a169b26fadb159d6a9798ba24..7a2a90a277ec57fb32999218c9d67a2453831ae2 100644 --- a/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt +++ b/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt @@ -6,7 +6,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.withContext import org.futo.circles.core.feature.room.knoks.KnockRequestsDataSource import org.futo.circles.core.feature.select_users.SearchUserDataSource @@ -28,9 +27,7 @@ class PeopleDataSource @Inject constructor( private fun getKnockRequestCountFlow(): Flow<Int> = knockRequestsDataSource.getKnockRequestsListItemsLiveData(peopleCategoryDataSource.getProfileRoomId()) - ?.map { - it.size - }?.asFlow() ?: flowOf() + .map { it.size }.asFlow() private fun getProfileSpaceInvitesCountFlow() = getSpacesLiveData(listOf(Membership.INVITE)).map { it.size }.asFlow() diff --git a/app/src/main/java/org/futo/circles/view/SimpleTextWatcher.kt b/app/src/main/java/org/futo/circles/view/SimpleTextWatcher.kt deleted file mode 100644 index d471738bd4a6fecc6bf8f737e20858a25a5a0e78..0000000000000000000000000000000000000000 --- a/app/src/main/java/org/futo/circles/view/SimpleTextWatcher.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2019 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.futo.circles.view - -import android.text.Editable -import android.text.TextWatcher - -/** - * TextWatcher with default no op implementation. - */ -open class SimpleTextWatcher : TextWatcher { - override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { - // No op - } - - override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { - // No op - } - - override fun afterTextChanged(s: Editable) { - // No op - } -} diff --git a/app/src/main/java/org/futo/circles/view/UriContentListener.kt b/app/src/main/java/org/futo/circles/view/UriContentListener.kt deleted file mode 100644 index 3cc04857fddff947b9ee079e09e7455eb073e60d..0000000000000000000000000000000000000000 --- a/app/src/main/java/org/futo/circles/view/UriContentListener.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.futo.circles.view - -import android.content.ClipData -import android.net.Uri -import android.view.View -import androidx.core.view.ContentInfoCompat -import androidx.core.view.OnReceiveContentListener - -class UriContentListener( - private val onContent: (uri: Uri) -> Unit -) : OnReceiveContentListener { - override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? { - val split = payload.partition { item -> item.uri != null } - val uriContent = split.first - val remaining = split.second - - if (uriContent != null) { - val clip: ClipData = uriContent.clip - for (i in 0 until clip.itemCount) { - val uri = clip.getItemAt(i).uri - // ... app-specific logic to handle the URI ... - onContent(uri) - } - } - // Return anything that we didn't handle ourselves. This preserves the default platform - // behavior for text and anything else for which we are not implementing custom handling. - return remaining - } -} diff --git a/app/src/main/res/drawable/bg_code_block.xml b/app/src/main/res/drawable/bg_code_block.xml deleted file mode 100644 index ef7227f6842b28bc38823dbcb26415fed7bde875..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/bg_code_block.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <solid android:color="#F4F6FA" /> - <stroke - android:width="@dimen/code_block_border_width" - android:color="#E3E8F0" /> - <corners android:radius="@dimen/code_block_border_radius" /> -</shape> diff --git a/app/src/main/res/drawable/ic_check_box.xml b/app/src/main/res/drawable/ic_check_box.xml deleted file mode 100644 index 92c21a81c2284293ee353b1e992424321db858d8..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_check_box.xml +++ /dev/null @@ -1,10 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:tint="@color/menu_icon_color" - android:viewportWidth="24" - android:viewportHeight="24"> - <path - android:fillColor="#000000" - android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM19,19L5,19L5,5h14v14zM17.99,9l-1.41,-1.42 -6.59,6.59 -2.58,-2.57 -1.42,1.41 4,3.99z" /> -</vector> \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_composer_bold.xml b/app/src/main/res/drawable/ic_composer_bold.xml deleted file mode 100644 index d2e26cf1e59a3105483837beaadd6acbfeadf1cb..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_bold.xml +++ /dev/null @@ -1,10 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:viewportWidth="44" - android:viewportHeight="44"> - <path - android:fillColor="@color/blue" - android:fillType="evenOdd" - android:pathData="M16,14.5C16,13.672 16.672,13 17.5,13H22.288C25.139,13 27.25,15.466 27.25,18.25C27.25,19.38 26.902,20.458 26.298,21.34C27.765,22.268 28.75,23.882 28.75,25.75C28.75,28.689 26.311,31 23.393,31H17.5C16.672,31 16,30.328 16,29.5V14.5ZM19,16V20.5H22.288C23.261,20.5 24.25,19.608 24.25,18.25C24.25,16.892 23.261,16 22.288,16H19ZM19,23.5V28H23.393C24.735,28 25.75,26.953 25.75,25.75C25.75,24.547 24.735,23.5 23.393,23.5H19Z" /> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_bullet_list.xml b/app/src/main/res/drawable/ic_composer_bullet_list.xml deleted file mode 100644 index d372209ced344182d558b43d73f89df20eaa9307..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_bullet_list.xml +++ /dev/null @@ -1,12 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:viewportWidth="44" - android:viewportHeight="44"> - <group> - <clip-path android:pathData="M10,10h24v24h-24z" /> - <path - android:fillColor="@color/blue" - android:pathData="M14,20.5C13.17,20.5 12.5,21.17 12.5,22C12.5,22.83 13.17,23.5 14,23.5C14.83,23.5 15.5,22.83 15.5,22C15.5,21.17 14.83,20.5 14,20.5ZM14,14.5C13.17,14.5 12.5,15.17 12.5,16C12.5,16.83 13.17,17.5 14,17.5C14.83,17.5 15.5,16.83 15.5,16C15.5,15.17 14.83,14.5 14,14.5ZM14,26.5C13.17,26.5 12.5,27.18 12.5,28C12.5,28.82 13.18,29.5 14,29.5C14.82,29.5 15.5,28.82 15.5,28C15.5,27.18 14.83,26.5 14,26.5ZM18,29H30C30.55,29 31,28.55 31,28C31,27.45 30.55,27 30,27H18C17.45,27 17,27.45 17,28C17,28.55 17.45,29 18,29ZM18,23H30C30.55,23 31,22.55 31,22C31,21.45 30.55,21 30,21H18C17.45,21 17,21.45 17,22C17,22.55 17.45,23 18,23ZM17,16C17,16.55 17.45,17 18,17H30C30.55,17 31,16.55 31,16C31,15.45 30.55,15 30,15H18C17.45,15 17,15.45 17,16Z" /> - </group> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_code_block.xml b/app/src/main/res/drawable/ic_composer_code_block.xml deleted file mode 100644 index aaa3dbe78da6559eef7d6eb4c6c35e1dd7c9b32b..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_code_block.xml +++ /dev/null @@ -1,10 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:tint="@color/menu_icon_color" - android:viewportWidth="44" - android:viewportHeight="44"> - <path - android:fillColor="@color/white" - android:pathData="m18,22c0.7,-0.72 1.4,-1.4 2.1,-2.1 0.68,-0.98 -0.93,-1.9 -1.5,-0.96 -0.87,0.88 -1.8,1.7 -2.6,2.6 -0.45,0.67 0.27,1.2 0.7,1.6 0.75,0.74 1.5,1.5 2.2,2.2 0.98,0.68 1.9,-0.93 0.96,-1.5l-1.9,-1.9zM26.6,22c-0.71,0.72 -1.5,1.4 -2.1,2.2 -0.68,0.98 0.93,1.9 1.5,0.96 0.88,-0.89 1.8,-1.8 2.6,-2.7 0.45,-0.67 -0.27,-1.2 -0.7,-1.6 -0.75,-0.74 -1.5,-1.5 -2.2,-2.2 -0.99,-0.66 -2,0.94 -0.96,1.5l1.9,1.9zM13.6,32c-1.1,0.021 -1.9,-1 -1.7,-2.1 0.005,-5.7 -0.011,-11 0.008,-17 0.088,-1 1.1,-1.7 2.1,-1.5 5.6,0.005 11,-0.011 17,0.008 1,0.088 1.7,1.1 1.5,2.1 -0.005,5.6 0.011,11 -0.008,17 -0.088,1 -1.1,1.7 -2.1,1.5h-17zM13.6,30.3h17v-17h-17v17z" /> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_indent.xml b/app/src/main/res/drawable/ic_composer_indent.xml deleted file mode 100644 index cbef736659cf55c7868cf0ddad15fd7a0acf24f8..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_indent.xml +++ /dev/null @@ -1,13 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:tint="@color/menu_icon_color" - android:viewportWidth="44" - android:viewportHeight="44"> - <group> - <clip-path android:pathData="M10,10h24v24h-24z" /> - <path - android:fillColor="@color/blue" - android:pathData="M14,31H30C30.55,31 31,30.55 31,30C31,29.45 30.55,29 30,29H14C13.45,29 13,29.45 13,30C13,30.55 13.45,31 14,31ZM13,19.21V24.8C13,25.25 13.54,25.47 13.85,25.15L16.64,22.36C16.84,22.16 16.84,21.85 16.64,21.65L13.85,18.85C13.54,18.54 13,18.76 13,19.21ZM22,27H30C30.55,27 31,26.55 31,26C31,25.45 30.55,25 30,25H22C21.45,25 21,25.45 21,26C21,26.55 21.45,27 22,27ZM13,14C13,14.55 13.45,15 14,15H30C30.55,15 31,14.55 31,14C31,13.45 30.55,13 30,13H14C13.45,13 13,13.45 13,14ZM22,19H30C30.55,19 31,18.55 31,18C31,17.45 30.55,17 30,17H22C21.45,17 21,17.45 21,18C21,18.55 21.45,19 22,19ZM22,23H30C30.55,23 31,22.55 31,22C31,21.45 30.55,21 30,21H22C21.45,21 21,21.45 21,22C21,22.55 21.45,23 22,23Z" /> - </group> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_inline_code.xml b/app/src/main/res/drawable/ic_composer_inline_code.xml deleted file mode 100644 index bc054e639a79590165c84994b991961df2579493..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_inline_code.xml +++ /dev/null @@ -1,15 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:viewportWidth="44" - android:viewportHeight="44"> - <path - android:fillColor="@color/blue" - android:pathData="M24.958,15.621C25.117,15.092 24.816,14.534 24.287,14.375C23.758,14.217 23.201,14.517 23.042,15.046L19.042,28.379C18.883,28.908 19.184,29.466 19.713,29.624C20.242,29.783 20.799,29.483 20.958,28.954L24.958,15.621Z" /> - <path - android:fillColor="@color/blue" - android:pathData="M15.974,17.232C15.549,16.878 14.919,16.936 14.565,17.36L11.232,21.36C10.923,21.731 10.923,22.269 11.232,22.64L14.565,26.64C14.919,27.065 15.549,27.122 15.974,26.768C16.398,26.415 16.455,25.784 16.102,25.36L13.302,22L16.102,18.64C16.455,18.216 16.398,17.585 15.974,17.232Z" /> - <path - android:fillColor="@color/blue" - android:pathData="M28.027,17.232C28.451,16.878 29.081,16.936 29.435,17.36L32.768,21.36C33.077,21.731 33.077,22.269 32.768,22.64L29.435,26.64C29.081,27.065 28.451,27.122 28.027,26.768C27.602,26.415 27.545,25.784 27.898,25.36L30.698,22L27.898,18.64C27.545,18.216 27.602,17.585 28.027,17.232Z" /> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_italic.xml b/app/src/main/res/drawable/ic_composer_italic.xml deleted file mode 100644 index 15c40a206504405f3a9bb5fbb2056e3da01512e2..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_italic.xml +++ /dev/null @@ -1,10 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:viewportWidth="44" - android:viewportHeight="44"> - <path - android:pathData="M22.619,14.999L19.747,29.005H17.2C16.758,29.005 16.4,29.363 16.4,29.805C16.4,30.247 16.758,30.605 17.2,30.605H20.389C20.397,30.605 20.405,30.605 20.412,30.605H23.6C24.042,30.605 24.4,30.247 24.4,29.805C24.4,29.363 24.042,29.005 23.6,29.005H21.381L24.253,14.999H26.8C27.242,14.999 27.6,14.64 27.6,14.199C27.6,13.757 27.242,13.399 26.8,13.399H23.615C23.604,13.398 23.594,13.398 23.583,13.399H20.4C19.958,13.399 19.6,13.757 19.6,14.199C19.6,14.64 19.958,14.999 20.4,14.999H22.619Z" - android:fillColor="@color/blue" - android:fillType="evenOdd" /> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_link.xml b/app/src/main/res/drawable/ic_composer_link.xml deleted file mode 100644 index be76286af10f63eb0c7dac33ec22a30781103e52..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_link.xml +++ /dev/null @@ -1,12 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:viewportWidth="44" - android:viewportHeight="44"> - <path - android:fillColor="#00000000" - android:pathData="M22.566,16.151L23.101,15.616C24.577,14.14 26.956,14.126 28.415,15.585C29.874,17.044 29.86,19.423 28.383,20.899L25.844,23.438C24.368,24.915 21.989,24.929 20.53,23.47M21.434,27.849L20.899,28.383C19.423,29.86 17.044,29.874 15.585,28.415C14.126,26.956 14.14,24.577 15.616,23.101L18.156,20.562C19.632,19.086 22.011,19.071 23.47,20.53" - android:strokeWidth="1.5" - android:strokeColor="@color/blue" - android:strokeLineCap="round" /> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_numbered_list.xml b/app/src/main/res/drawable/ic_composer_numbered_list.xml deleted file mode 100644 index 5690e2de91efcec7eb129bfcf564f3139882153d..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_numbered_list.xml +++ /dev/null @@ -1,24 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:viewportWidth="44" - android:viewportHeight="44"> - <path - android:pathData="m14.5,20h-2c-0.28,0 -0.5,0.22 -0.5,0.5 0,0.28 0.22,0.5 0.5,0.5h1.3l-1.68,1.96C12.04,23.05 12,23.17 12,23.28v0.22c0,0.28 0.22,0.5 0.5,0.5h2C14.78,24 15,23.78 15,23.5 15,23.22 14.78,23 14.5,23h-1.3l1.68,-1.96C14.96,20.95 15,20.83 15,20.72V20.5C15,20.22 14.78,20 14.5,20Z" - android:fillColor="@color/blue" /> - <path - android:pathData="M12.5,15H13v2.5c0,0.28 0.22,0.5 0.5,0.5 0.28,0 0.5,-0.22 0.5,-0.5v-3C14,14.22 13.78,14 13.5,14h-1c-0.28,0 -0.5,0.22 -0.5,0.5 0,0.28 0.22,0.5 0.5,0.5z" - android:fillColor="@color/blue" /> - <path - android:pathData="m14.5,26h-2c-0.28,0 -0.5,0.22 -0.5,0.5 0,0.28 0.22,0.5 0.5,0.5H14v0.5h-0.5c-0.28,0 -0.5,0.22 -0.5,0.5 0,0.28 0.22,0.5 0.5,0.5H14V29h-1.5c-0.28,0 -0.5,0.22 -0.5,0.5 0,0.28 0.22,0.5 0.5,0.5h2c0.28,0 0.5,-0.22 0.5,-0.5v-3C15,26.22 14.78,26 14.5,26Z" - android:fillColor="@color/blue" /> - <path - android:pathData="M30,21H18c-0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1 0,-0.55 -0.45,-1 -1,-1z" - android:fillColor="@color/blue" /> - <path - android:pathData="M30,27H18c-0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1 0,-0.55 -0.45,-1 -1,-1z" - android:fillColor="@color/blue" /> - <path - android:pathData="m18,17h12c0.55,0 1,-0.45 1,-1 0,-0.55 -0.45,-1 -1,-1H18c-0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1z" - android:fillColor="@color/blue" /> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_strikethrough.xml b/app/src/main/res/drawable/ic_composer_strikethrough.xml deleted file mode 100644 index 593cd3aca18017d5ffca71a20b2905dc443def31..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_strikethrough.xml +++ /dev/null @@ -1,12 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:viewportWidth="44" - android:viewportHeight="44"> - <path - android:pathData="M24.897,17.154C24.235,15.821 22.876,15.21 21.374,15.372C19.05,15.622 18.44,17.423 18.722,18.592C19.032,19.872 20.046,20.37 21.839,20.826H29.92C30.517,20.826 31,21.351 31,22C31,22.648 30.517,23.174 29.92,23.174H14.08C13.483,23.174 13,22.648 13,22C13,21.351 13.483,20.826 14.08,20.826H17.355C17.041,20.377 16.791,19.839 16.633,19.189C16.003,16.581 17.554,13.424 21.16,13.036C23.285,12.807 25.615,13.661 26.798,16.038C27.081,16.608 26.886,17.32 26.361,17.629C25.836,17.937 25.181,17.725 24.897,17.154Z" - android:fillColor="@color/blue" /> - <path - android:pathData="M25.427,25.13H27.67C27.888,26.306 27.721,27.56 27.05,28.632C26.114,30.125 24.37,31 21.985,31C18.076,31 16.279,28.584 15.912,26.986C15.768,26.357 16.12,25.72 16.698,25.563C17.277,25.406 17.863,25.788 18.008,26.417C18.119,26.902 19.002,28.652 21.985,28.652C23.907,28.652 24.854,27.965 25.264,27.31C25.642,26.707 25.708,25.909 25.427,25.13Z" - android:fillColor="@color/blue" /> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_underlined.xml b/app/src/main/res/drawable/ic_composer_underlined.xml deleted file mode 100644 index c0b515adff45070dd208c65ef8ee2ebda6bfe451..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_underlined.xml +++ /dev/null @@ -1,13 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:tint="@color/menu_icon_color" - android:viewportWidth="44" - android:viewportHeight="44"> - <group> - <clip-path android:pathData="M10,10h24v24h-24z" /> - <path - android:fillColor="@color/blue" - android:pathData="M22.79,26.95C25.82,26.56 28,23.84 28,20.79V14.25C28,13.56 27.44,13 26.75,13C26.06,13 25.5,13.56 25.5,14.25V20.9C25.5,22.57 24.37,24.09 22.73,24.42C20.48,24.89 18.5,23.17 18.5,21V14.25C18.5,13.56 17.94,13 17.25,13C16.56,13 16,13.56 16,14.25V21C16,24.57 19.13,27.42 22.79,26.95ZM15,30C15,30.55 15.45,31 16,31H28C28.55,31 29,30.55 29,30C29,29.45 28.55,29 28,29H16C15.45,29 15,29.45 15,30Z" /> - </group> -</vector> diff --git a/app/src/main/res/drawable/ic_composer_unindent.xml b/app/src/main/res/drawable/ic_composer_unindent.xml deleted file mode 100644 index a4a7fc69a4890a0e380e051ffe4876d5125672b1..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_composer_unindent.xml +++ /dev/null @@ -1,13 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="44dp" - android:height="44dp" - android:tint="@color/menu_icon_color" - android:viewportWidth="44" - android:viewportHeight="44"> - <group> - <clip-path android:pathData="M10,10h24v24h-24z" /> - <path - android:fillColor="@color/blue" - android:pathData="M22,27H30C30.55,27 31,26.55 31,26C31,25.45 30.55,25 30,25H22C21.45,25 21,25.45 21,26C21,26.55 21.45,27 22,27ZM13.35,22.35L16.14,25.14C16.46,25.46 17,25.24 17,24.79V19.21C17,18.76 16.46,18.54 16.15,18.86L13.36,21.65C13.16,21.84 13.16,22.16 13.35,22.35ZM14,31H30C30.55,31 31,30.55 31,30C31,29.45 30.55,29 30,29H14C13.45,29 13,29.45 13,30C13,30.55 13.45,31 14,31ZM13,14C13,14.55 13.45,15 14,15H30C30.55,15 31,14.55 31,14C31,13.45 30.55,13 30,13H14C13.45,13 13,13.45 13,14ZM22,19H30C30.55,19 31,18.55 31,18C31,17.45 30.55,17 30,17H22C21.45,17 21,17.45 21,18C21,18.55 21.45,19 22,19ZM22,23H30C30.55,23 31,22.55 31,22C31,21.45 30.55,21 30,21H22C21.45,21 21,21.45 21,22C21,22.55 21.45,23 22,23Z" /> - </group> -</vector> diff --git a/app/src/main/res/layout/list_item_style_bar.xml b/app/src/main/res/layout/list_item_style_bar.xml deleted file mode 100644 index 4709beb7bf83c39e6c1878c96ffb76cf9687a82b..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/list_item_style_bar.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:id="@+id/cvOption" - android:layout_width="48dp" - android:layout_height="48dp" - android:clickable="true" - android:elevation="4dp" - android:focusable="true" - android:foreground="?selectableItemBackground" - app:cardCornerRadius="8dp" - app:cardUseCompatPadding="true"> - - <ImageView - android:id="@+id/ivIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:src="@drawable/ic_mention" /> - -</androidx.cardview.widget.CardView> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index ed95017c76f6572d163340f7c993dc9ad6cc3b11..07d86d8a7e7d17a3fd38ce9ccd5251d9198e6d9d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -10,11 +10,9 @@ <color name="status_bar_color">#20111111</color> <color name="green">#34C759</color> - <color name="purple">#AF52DE</color> <color name="yellow">#FFCC00</color> <color name="orange">#FF9500</color> <color name="red">#FF3B30</color> - <color name="pink">#FF2D55</color> <color name="gray">#8E8E93</color> <color name="close_background">#80000000</color> <color name="highlight_color">#4D0E7AFE</color> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ab5bee724941d80d5211c56a9e22e48d95c04876..4e073536a5f31ded2d8192ba00c8317dd78f5720 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -10,7 +10,6 @@ <string name="my_circles">My Circles</string> <string name="share">Share</string> <string name="fix">Fix</string> - <string name="followers">Followers</string> <string name="known_users">Known users</string> <string name="ignored_users">Ignored users</string> <string name="suggestions">Suggestions</string> @@ -27,7 +26,6 @@ <string name="requests_format">Requests %d</string> <string name="create_post">Create post</string> <string name="create_poll">Create poll</string> - <string name="send">Send</string> <string name="enter_your_message_here">Enter your message here</string> <string name="compressing">Compressing</string> <string name="encrypting">Encrypting</string> @@ -187,7 +185,6 @@ <string name="circles_empty_message">Create your first Circle</string> <string name="people_category_empty_message">%s will be shown here</string> <string name="creating_timeline">Creating timeline</string> - <string name="session">Session</string> <string name="help">Help</string> <string name="optional_request_message">Optional: Request message</string> <string name="media_storage">Media storage</string> @@ -200,17 +197,6 @@ <string name="ignored">Ignored</string> <!-- Rich text editor --> - <string name="rich_text_editor_format_bold">Apply bold format</string> - <string name="rich_text_editor_format_italic">Apply italic format</string> - <string name="rich_text_editor_format_strikethrough">Apply strikethrough format</string> - <string name="rich_text_editor_format_underline">Apply underline format</string> - <string name="rich_text_editor_link">Set link</string> - <string name="rich_text_editor_numbered_list">Toggle numbered list</string> - <string name="rich_text_editor_bullet_list">Toggle bullet list</string> - <string name="rich_text_editor_indent">Indent</string> - <string name="rich_text_editor_unindent">Unindent</string> - <string name="rich_text_editor_quote">Toggle quote</string> - <string name="rich_text_editor_code_block">Toggle code block</string> <string name="general">General</string> <string name="empty_media_storage_info">0 MB used</string> <string name="in_timeline_format">(in %1$s / %2$s)</string> diff --git a/auth/build.gradle b/auth/build.gradle index 55d1706ce6f1e0f3376360614ae55ef17df66c9e..43cca46bd6c164203eae60b620d57f538429a94b 100644 --- a/auth/build.gradle +++ b/auth/build.gradle @@ -87,7 +87,7 @@ dependencies { //Hilt implementation "com.google.dagger:hilt-android:$rootProject.ext.hilt_version" kapt "com.google.dagger:hilt-compiler:$rootProject.ext.hilt_version" - implementation "androidx.hilt:hilt-work:1.1.0" + implementation 'androidx.hilt:hilt-work:1.2.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' diff --git a/auth/src/main/java/org/futo/circles/auth/feature/active_sessions/ActiveSessionsViewModel.kt b/auth/src/main/java/org/futo/circles/auth/feature/active_sessions/ActiveSessionsViewModel.kt index 882340381ff3c82e886376dd36c745cd95e8c3be..3e43ea8df1b5352f394cf619e5bdbcc15f18bb83 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/active_sessions/ActiveSessionsViewModel.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/active_sessions/ActiveSessionsViewModel.kt @@ -1,8 +1,13 @@ package org.futo.circles.auth.feature.active_sessions +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData import dagger.hilt.android.lifecycle.HiltViewModel +import org.futo.circles.auth.model.ActiveSession +import org.futo.circles.auth.model.ActiveSessionListItem +import org.futo.circles.auth.model.SessionHeader import org.futo.circles.core.base.SingleEventLiveData import org.futo.circles.core.extensions.Response import org.futo.circles.core.extensions.launchBg @@ -13,18 +18,39 @@ class ActiveSessionsViewModel @Inject constructor( private val dataSource: ActiveSessionsDataSource ) : ViewModel() { - val activeSessionsLiveData = dataSource.getActiveSessionsFlow().asLiveData() val removeSessionLiveData = SingleEventLiveData<Response<Unit?>>() val resetKeysLiveData = SingleEventLiveData<Response<Unit?>>() val startReAuthEventLiveData = dataSource.startReAuthEventLiveData + private val loadingItemsIdsList = MutableLiveData<Set<String>>(emptySet()) + + val activeSessionsLiveData = MediatorLiveData<List<ActiveSessionListItem>>().also { + it.addSource(loadingItemsIdsList) { loadingItemsValue -> + val currentList = it.value ?: emptyList() + it.postValue( + currentList.map { item -> + when (item) { + is ActiveSession -> item.copy(isLoading = loadingItemsValue.contains(item.id)) + is SessionHeader -> item + } + } + ) + } + it.addSource(dataSource.getActiveSessionsFlow().asLiveData()) { value -> + it.postValue(value) + } + } + + fun onSessionClicked(deviceId: String) { dataSource.toggleOptionsVisibilityFor(deviceId) } fun removeSession(deviceId: String) { launchBg { + toggleItemLoading(deviceId) val deactivateResult = dataSource.removeSession(deviceId) + toggleItemLoading(deviceId) removeSessionLiveData.postValue(deactivateResult) } } @@ -35,4 +61,13 @@ class ActiveSessionsViewModel @Inject constructor( resetKeysLiveData.postValue(resetKeysResult) } } + + private fun toggleItemLoading(id: String) { + val currentSet = loadingItemsIdsList.value?.toMutableSet() ?: return + val newLoadingSet = currentSet.apply { + if (this.contains(id)) remove(id) + else add(id) + } + loadingItemsIdsList.postValue(newLoadingSet) + } } \ No newline at end of file diff --git a/auth/src/main/java/org/futo/circles/auth/feature/workspace/data_source/ConfigureWorkspaceDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/workspace/data_source/ConfigureWorkspaceDataSource.kt index aa1eb5d136b7b871956947ff24c789697dfb8584..a46ca87316da03f2b40ef1eeda5694a8420e7a05 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/workspace/data_source/ConfigureWorkspaceDataSource.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/workspace/data_source/ConfigureWorkspaceDataSource.kt @@ -5,6 +5,7 @@ import org.futo.circles.core.feature.room.create.CreateRoomDataSource import org.futo.circles.core.feature.workspace.SpacesTreeAccountDataSource import org.futo.circles.core.model.CIRCLES_SPACE_ACCOUNT_DATA_KEY import org.futo.circles.core.model.CirclesRoom +import org.futo.circles.core.model.PROFILE_SPACE_ACCOUNT_DATA_KEY import org.futo.circles.core.model.SharedCirclesSpace import org.futo.circles.core.provider.MatrixSessionProvider import org.futo.circles.core.utils.getAllJoinedCirclesRoomsAndSpaces @@ -27,7 +28,9 @@ class ConfigureWorkspaceDataSource @Inject constructor( private suspend fun validateAndFixRelationInNeeded(roomId: String, room: CirclesRoom) { try { - getJoinedRoomById(roomId)?.let { validateRelations(room.parentAccountDataKey, it) } + getJoinedRoomById(roomId)?.let { + validateRelations(room.parentAccountDataKey, it, room.accountDataKey) + } } catch (_: Exception) { val parentRoomId = room.parentAccountDataKey?.let { spacesTreeAccountDataSource.getRoomIdByKey(it) } @@ -42,10 +45,14 @@ class ConfigureWorkspaceDataSource @Inject constructor( ?: throw IllegalArgumentException("No account data record for key $accountDataKey") val joinedRoom = getJoinedRoomById(roomId) ?: throw IllegalArgumentException("No joined room for id $roomId found") - validateRelations(room.parentAccountDataKey, joinedRoom) + validateRelations(room.parentAccountDataKey, joinedRoom, accountDataKey) } - private fun validateRelations(parentAccountDataKey: String?, joinedRoom: Room) { + private fun validateRelations( + parentAccountDataKey: String?, + joinedRoom: Room, + accountDataKey: String? + ) { val parentKey = parentAccountDataKey ?: return val parentRoomId = spacesTreeAccountDataSource.getRoomIdByKey(parentKey) ?: throw IllegalArgumentException( @@ -58,7 +65,8 @@ class ConfigureWorkspaceDataSource @Inject constructor( ?.spaceSummary()?.spaceParents?.mapNotNull { it.parentId } ?.contains(parentRoomId) == true - if (!childHasRelationToParent) + //iOS app do not set this relation + if (!childHasRelationToParent && accountDataKey != PROFILE_SPACE_ACCOUNT_DATA_KEY) throw IllegalArgumentException("Missing child to parent relations") val parentHasRelationToChild = joinedParentRoom.asSpace() diff --git a/auth/src/main/java/org/futo/circles/auth/model/ActiveSessionListItem.kt b/auth/src/main/java/org/futo/circles/auth/model/ActiveSessionListItem.kt index 555d5483fd8b0ad9ae7b2a2aa426be6c349c1325..079abecffe94073f409b059b411af5645d3322a3 100644 --- a/auth/src/main/java/org/futo/circles/auth/model/ActiveSessionListItem.kt +++ b/auth/src/main/java/org/futo/circles/auth/model/ActiveSessionListItem.kt @@ -18,7 +18,8 @@ data class ActiveSession( val cryptoDeviceInfo: CryptoDeviceInfo, val canVerify: Boolean, val isResetKeysVisible: Boolean, - val isOptionsVisible: Boolean + val isOptionsVisible: Boolean, + val isLoading: Boolean = false ) : ActiveSessionListItem() { override val id: String = cryptoDeviceInfo.deviceId diff --git a/auth/src/main/java/org/futo/circles/auth/view/ActiveSessionInfoView.kt b/auth/src/main/java/org/futo/circles/auth/view/ActiveSessionInfoView.kt index e63080807e3b14bf47626653d21d3cf1a20d0e97..a7463cf0b5b0b392415499d5f43142e29ee91c9e 100644 --- a/auth/src/main/java/org/futo/circles/auth/view/ActiveSessionInfoView.kt +++ b/auth/src/main/java/org/futo/circles/auth/view/ActiveSessionInfoView.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import androidx.constraintlayout.widget.ConstraintLayout import org.futo.circles.auth.databinding.ViewActiveSessionInfoBinding import org.futo.circles.auth.feature.active_sessions.list.ActiveSessionClickListener +import org.futo.circles.auth.model.ActiveSession import org.futo.circles.core.extensions.setIsVisible class ActiveSessionInfoView( @@ -32,17 +33,18 @@ class ActiveSessionInfoView( } fun setData( - activeSession: org.futo.circles.auth.model.ActiveSession, + activeSession: ActiveSession, listener: ActiveSessionClickListener ) { deviceId = activeSession.id activeSessionClickListener = listener with(binding) { + vLoading.setIsVisible(activeSession.isLoading) tvFingerprint.text = activeSession.cryptoDeviceInfo.fingerprint() ?: "" tvPublicKey.text = activeSession.cryptoDeviceInfo.identityKey() ?: "" - btnVerify.setIsVisible(activeSession.canVerify) - btnRemove.setIsVisible(!activeSession.isCurrentSession()) - btnResetKeys.setIsVisible(activeSession.isResetKeysVisible) + btnVerify.setIsVisible(activeSession.canVerify && !activeSession.isLoading) + btnRemove.setIsVisible(!activeSession.isCurrentSession() && !activeSession.isLoading) + btnResetKeys.setIsVisible(activeSession.isResetKeysVisible && !activeSession.isLoading) } } } \ No newline at end of file diff --git a/auth/src/main/res/layout/view_active_session_info.xml b/auth/src/main/res/layout/view_active_session_info.xml index 18adfc80e412a1f098233b3af8ead7590278755e..d0b08721cf66730fa665ca01cc83ec880a78b2e8 100644 --- a/auth/src/main/res/layout/view_active_session_info.xml +++ b/auth/src/main/res/layout/view_active_session_info.xml @@ -97,4 +97,14 @@ app:layout_constraintStart_toEndOf="@id/btnRemove" app:layout_constraintTop_toBottomOf="@+id/tvPublicKey" /> + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tvPublicKey" /> + </merge> \ No newline at end of file diff --git a/auth/src/main/res/values/color.xml b/auth/src/main/res/values/color.xml index 49fde422f59f7ab5135a3cd34d5745489dff9408..e0ba5413a81aea21a0b06324bed3da07ef238805 100644 --- a/auth/src/main/res/values/color.xml +++ b/auth/src/main/res/values/color.xml @@ -7,7 +7,5 @@ <color name="red">#FF3B30</color> <color name="green">#34C759</color> <color name="teal_700">#FF018786</color> - <color name="purple">#AF52DE</color> - <color name="pink">#FF2D55</color> </resources> \ No newline at end of file diff --git a/auth/src/main/res/values/strings.xml b/auth/src/main/res/values/strings.xml index a0368d8b476996342e9b164c2d473eccd944ca65..d7879e36f2ff17a85793bb7f067f4dc0f44c903e 100644 --- a/auth/src/main/res/values/strings.xml +++ b/auth/src/main/res/values/strings.xml @@ -6,18 +6,14 @@ <string name="b_param_is_missing">B param is missing</string> <string name="initial_device_name">FUTO Circles (Android)</string> <string name="initial_sync">Initial sync</string> - <string name="not_found_login_flow_for_user">Log In flow for user not found</string> + <string name="session_sync">Session sync</string> <string name="unsupported_login_method">Unsupported login method</string> <string name="discard_current_auth_progress">Discard current auth progress?</string> <string name="set_password">Set password</string> <string name="log_in">Log In</string> <string name="wrong_signup_config">Wrong signup config!</string> - <string name="us_server_format"><![CDATA[<b>US</b> - (%s)]]></string> - <string name="eu_server_format"><![CDATA[<b>EU</b> - (%s)]]></string> - <string name="sign_up_using_active_subscription">Sign Up using your active subscription</string> <string name="sign_up">Sign Up</string> <string name="sign_up_stage_subtitle_format">Stage %1$d of %2$d</string> - <string name="no_backup_message">Keys backup not found</string> <string name="username_can_not_be_empty">Username can not be empty.</string> <string name="confirm_auth">Confirm auth</string> <string name="email">Email</string> @@ -67,7 +63,6 @@ <string name="save">Save</string> <string name="skip">Skip</string> <string name="subscriptions">Subscriptions</string> - <string name="subscription">Subscription</string> <string name="manage_subscription">Manage subscription</string> <string name="enter_your_username">Enter your username</string> <string name="set_username">Set username</string> @@ -83,7 +78,6 @@ <string name="upload_recovery_key_file">Upload Recovery Key file</string> <string name="restore">Restore</string> <string name="validate_your_email">Validate your email</string> - <string name="not_supported_navigation_event">Not supported navigation event</string> <string name="feature_not_supported">Feature is not supported</string> <string name="service_unavailable">Service unavailable</string> <string name="item_unavailable">Item is unavailable</string> @@ -111,7 +105,6 @@ <string name="other_sessions">Other sessions</string> <string name="invalid_auth">Invalid auth</string> <string name="scan_with_one_of_devices_message">Scan QR code with one of your devices to finish verification</string> - <string name="cross_signed">cross signed</string> <string name="waiting_for_other_device_verification">Waiting for other device to start verification</string> <string name="session_verified">Session verified</string> <string name="verification_canceled">Verification canceled</string> diff --git a/build.gradle b/build.gradle index 6368cdbe4abc3cf2bade48b56368e4e203c96be1..cdbde14b895359cd37691510381d14dc2a9ae37e 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { sdk_version = 34 min_sdk_version = 24 androidx_nav_version = '2.7.7' - hilt_version = '2.50' + hilt_version = '2.51' modules_version = "1.0.9" modules_groupId = "org.futo.gitlab.circles" } diff --git a/core/build.gradle b/core/build.gradle index 25be662b05a876935384d957d7f90ed66ef9629b..ee51d232f5218600ef14095c64e880ef16faf0df 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -99,6 +99,7 @@ dependencies { implementation 'jp.wasabeef:glide-transformations:4.3.0' //Webp animations + //noinspection GradleDependency api 'com.github.penfeizhou.android.animation:glide-plugin:2.28.0' //QR @@ -111,7 +112,7 @@ dependencies { api "io.noties.markwon:ext-strikethrough:$markwon_version" api "io.noties.markwon:ext-tasklist:$markwon_version" - api 'io.element.android:wysiwyg:2.29.0' + api 'io.element.android:wysiwyg:2.30.0' //Shake detection implementation 'com.squareup:seismic:1.0.3' diff --git a/core/src/main/java/org/futo/circles/core/extensions/ViewExtensions.kt b/core/src/main/java/org/futo/circles/core/extensions/ViewExtensions.kt index e66b2f962304b3c34ed197bc10ba11c50b9e6eee..17090ae2b158298537af7a9209e799c9e98b40ec 100644 --- a/core/src/main/java/org/futo/circles/core/extensions/ViewExtensions.kt +++ b/core/src/main/java/org/futo/circles/core/extensions/ViewExtensions.kt @@ -21,6 +21,10 @@ fun View.gone() { visibility = View.GONE } +fun View.invisible() { + visibility = View.INVISIBLE +} + fun View.setIsVisible(isVisible: Boolean) { visibility = if (isVisible) View.VISIBLE else View.GONE } diff --git a/core/src/main/java/org/futo/circles/core/feature/room/invites/InvitesViewModel.kt b/core/src/main/java/org/futo/circles/core/feature/room/invites/InvitesViewModel.kt index eafb2308fca561599efef7c1e5c35387b1cdacba..aae3081014671d76c3a0f39ee74ca01be9640f05 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/invites/InvitesViewModel.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/invites/InvitesViewModel.kt @@ -1,5 +1,7 @@ package org.futo.circles.core.feature.room.invites +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData @@ -11,7 +13,12 @@ import org.futo.circles.core.extensions.launchBg import org.futo.circles.core.feature.room.invite.ManageInviteRequestsDataSource import org.futo.circles.core.feature.workspace.SharedCircleDataSource import org.futo.circles.core.model.CircleRoomTypeArg +import org.futo.circles.core.model.ConnectionInviteListItem +import org.futo.circles.core.model.FollowRequestListItem +import org.futo.circles.core.model.InviteHeader +import org.futo.circles.core.model.InviteListItem import org.futo.circles.core.model.InviteTypeArg +import org.futo.circles.core.model.RoomInviteListItem import javax.inject.Inject @HiltViewModel @@ -25,29 +32,57 @@ class InvitesViewModel @Inject constructor( private val inviteType: InviteTypeArg = savedStateHandle.getOrThrow("type") val inviteResultLiveData = SingleEventLiveData<Response<Unit?>>() - val invitesLiveData = dataSource.getInvitesFlow(inviteType).asLiveData() + private val loadingItemsIdsList = MutableLiveData<Set<String>>(emptySet()) + val invitesLiveData = MediatorLiveData<List<InviteListItem>>().also { + it.addSource(loadingItemsIdsList) { loadingItemsValue -> + val currentList = it.value ?: emptyList() + it.postValue(currentList.map { item -> + when (item) { + is ConnectionInviteListItem -> item.copy( + isLoading = loadingItemsValue.contains(item.id) + ) + + is FollowRequestListItem -> item.copy( + isLoading = loadingItemsValue.contains(item.id) + ) + + is RoomInviteListItem -> item.copy( + isLoading = loadingItemsValue.contains(item.id) + ) + + is InviteHeader -> item + } + }) + } + it.addSource(dataSource.getInvitesFlow(inviteType).asLiveData()) { value -> + it.postValue(value) + } + } fun getInviteType() = inviteType fun rejectRoomInvite(roomId: String) { launchBg { + toggleItemLoading(roomId) val result = manageInviteRequestsDataSource.rejectInvite(roomId) - inviteResultLiveData.postValue(result) + postInviteResult(result, roomId) } } fun acceptRoomInvite(roomId: String, roomType: CircleRoomTypeArg) { launchBg { + toggleItemLoading(roomId) val result = manageInviteRequestsDataSource.acceptInvite(roomId, roomType) - inviteResultLiveData.postValue(result) + postInviteResult(result, roomId) } } fun onFollowRequestAnswered(userId: String, accepted: Boolean) { launchBg { + toggleItemLoading(userId) val result = if (accepted) dataSource.acceptFollowRequest(userId) else dataSource.declineFollowRequest(userId) - inviteResultLiveData.postValue(result) + postInviteResult(result, userId) } } @@ -58,11 +93,25 @@ class InvitesViewModel @Inject constructor( fun onConnectionInviteAnswered(roomId: String, accepted: Boolean) { if (accepted) launchBg { - val result = sharedCircleDataSource.acceptSharedCircleInvite(roomId) - inviteResultLiveData.postValue(result) + toggleItemLoading(roomId) + val result = sharedCircleDataSource.acceptSharedCircleInvite(roomId) + postInviteResult(result, roomId) } else rejectRoomInvite(roomId) } + private fun postInviteResult(result: Response<Unit?>, id: String) { + inviteResultLiveData.postValue(result) + toggleItemLoading(id) + } + + private fun toggleItemLoading(id: String) { + val currentSet = loadingItemsIdsList.value?.toMutableSet() ?: return + val newLoadingSet = currentSet.apply { + if (this.contains(id)) remove(id) + else add(id) + } + loadingItemsIdsList.postValue(newLoadingSet) + } } \ No newline at end of file diff --git a/core/src/main/java/org/futo/circles/core/feature/room/invites/list/InvitesViewHolder.kt b/core/src/main/java/org/futo/circles/core/feature/room/invites/list/InvitesViewHolder.kt index ce4878c3258a8a24b27122fba1011b24dbb92d95..24b4c012e83f602fb8c28311fa3f733024365c80 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/invites/list/InvitesViewHolder.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/invites/list/InvitesViewHolder.kt @@ -49,6 +49,7 @@ class InvitedGroupViewHolder( if (data !is RoomInviteListItem) return with(binding) { + setLoading(data.isLoading) ivGroup.loadRoomProfileIcon( data.info.avatarUrl, data.info.title, @@ -63,6 +64,14 @@ class InvitedGroupViewHolder( ) } } + + private fun setLoading(isLoading: Boolean) { + with(binding) { + vLoading.setIsVisible(isLoading) + btnAccept.setIsVisible(!isLoading) + btnDecline.setIsVisible(!isLoading) + } + } } class InvitedCircleViewHolder( @@ -85,6 +94,7 @@ class InvitedCircleViewHolder( if (data !is RoomInviteListItem) return with(binding) { + setLoading(data.isLoading) tvShowProfileImage.setIsVisible(data.shouldBlurIcon) ivCircle.loadRoomProfileIcon( data.info.avatarUrl, @@ -99,6 +109,14 @@ class InvitedCircleViewHolder( ) } } + + private fun setLoading(isLoading: Boolean) { + with(binding) { + vLoading.setIsVisible(isLoading) + btnAccept.setIsVisible(!isLoading) + btnDecline.setIsVisible(!isLoading) + } + } } class InvitedGalleryViewHolder( @@ -121,6 +139,7 @@ class InvitedGalleryViewHolder( if (data !is RoomInviteListItem) return with(binding) { + setLoading(data.isLoading) tvGalleryTitle.text = data.info.title ivGallery.loadRoomProfileIcon( data.info.avatarUrl, @@ -131,6 +150,14 @@ class InvitedGalleryViewHolder( tvInviterName.text = context.getString(R.string.invited_by_format, data.inviterName) } } + + private fun setLoading(isLoading: Boolean) { + with(binding) { + vLoading.setIsVisible(isLoading) + btnAccept.setIsVisible(!isLoading) + btnDecline.setIsVisible(!isLoading) + } + } } class FollowRequestViewHolder( @@ -148,8 +175,10 @@ class FollowRequestViewHolder( } override fun bind(data: InviteListItem) { - val user = (data as? FollowRequestListItem)?.user ?: return - bindUser(user) + if (data !is FollowRequestListItem) return + + setLoading(data.isLoading) + bindUser(data.user) binding.tvReasonMessage.apply { setIsVisible(data.reasonMessage != null) text = data.reasonMessage @@ -162,6 +191,14 @@ class FollowRequestViewHolder( ivUserImage.loadUserProfileIcon(user.avatarUrl, user.id) } } + + private fun setLoading(isLoading: Boolean) { + with(binding) { + vLoading.setIsVisible(isLoading) + btnAccept.setIsVisible(!isLoading) + btnDecline.setIsVisible(!isLoading) + } + } } class ConnectionInviteViewHolder( @@ -179,8 +216,10 @@ class ConnectionInviteViewHolder( } override fun bind(data: InviteListItem) { - val user = (data as? ConnectionInviteListItem)?.user ?: return - bindUser(user) + if (data !is ConnectionInviteListItem) return + + setLoading(data.isLoading) + bindUser(data.user) } private fun bindUser(user: CirclesUserSummary) { @@ -189,6 +228,14 @@ class ConnectionInviteViewHolder( ivUserImage.loadUserProfileIcon(user.avatarUrl, user.id) } } + + private fun setLoading(isLoading: Boolean) { + with(binding) { + vLoading.setIsVisible(isLoading) + btnAccept.setIsVisible(!isLoading) + btnDecline.setIsVisible(!isLoading) + } + } } class InviteHeaderViewHolder( diff --git a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestViewModel.kt b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestViewModel.kt index fc6c48a179e3b0290cd1f83f9a174b6d5e048ec8..d979e513cdae1a5a57cbe2558cf461ae71f249c6 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestViewModel.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestViewModel.kt @@ -1,5 +1,7 @@ package org.futo.circles.core.feature.room.knoks +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import dagger.hilt.android.lifecycle.HiltViewModel @@ -20,18 +22,45 @@ class KnockRequestViewModel @Inject constructor( private val roomId: String = savedStateHandle.getOrThrow("roomId") - val knockRequestsLiveData = knockRequestsDataSource.getKnockRequestsListItemsLiveData(roomId) val inviteResultLiveData = SingleEventLiveData<Response<Unit?>>() + private val loadingItemsIdsList = MutableLiveData<Set<String>>(emptySet()) + + val knockRequestsLiveData = MediatorLiveData<List<KnockRequestListItem>>().also { + it.addSource(loadingItemsIdsList) { loadingItemsValue -> + val currentList = it.value ?: emptyList() + it.postValue(currentList.map { item -> + item.copy(isLoading = loadingItemsValue.contains(item.id)) + }) + } + it.addSource(knockRequestsDataSource.getKnockRequestsListItemsLiveData(roomId)) { value -> + it.postValue(value) + } + } fun inviteUser(user: KnockRequestListItem) { launchBg { + toggleItemLoading(user.id) val result = manageInviteRequestsDataSource.inviteUser(roomId, user.requesterId) inviteResultLiveData.postValue(result) + toggleItemLoading(user.id) } } fun kickUser(user: KnockRequestListItem) { - launchBg { manageInviteRequestsDataSource.kickUser(roomId, user.requesterId) } + launchBg { + toggleItemLoading(user.id) + manageInviteRequestsDataSource.kickUser(roomId, user.requesterId) + toggleItemLoading(user.id) + } + } + + private fun toggleItemLoading(id: String) { + val currentSet = loadingItemsIdsList.value?.toMutableSet() ?: return + val newLoadingSet = currentSet.apply { + if (this.contains(id)) remove(id) + else add(id) + } + loadingItemsIdsList.postValue(newLoadingSet) } } diff --git a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDataSource.kt b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDataSource.kt index 9df217009759d90457fcf31e321cefb377c984e1..47767ddaab6ed832d27f801f5b17593f7b60eaa2 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDataSource.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDataSource.kt @@ -1,6 +1,7 @@ package org.futo.circles.core.feature.room.knoks import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.asFlow import androidx.lifecycle.asLiveData import androidx.lifecycle.map @@ -27,7 +28,7 @@ class KnockRequestsDataSource @Inject constructor() { fun getKnockRequestsListItemsLiveData(roomId: String) = getKnockRequestLiveData(roomId)?.map { it.map { user -> user.toKnockRequestListItem(roomId) } - } + } ?: MutableLiveData(emptyList()) fun getKnockRequestCountLiveDataForCurrentUserInRoom(roomId: String): LiveData<Int> { val session = MatrixSessionProvider.getSessionOrThrow() diff --git a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDialogFragment.kt b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDialogFragment.kt index 03b2e2784d0bceb2069b953a842b44433e6ca86d..35eaf04c8d8f4189006dd023e8e3fa9f4c9f27b1 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDialogFragment.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDialogFragment.kt @@ -50,7 +50,7 @@ class KnockRequestsDialogFragment : private fun setupObservers() { viewModel.inviteResultLiveData.observeResponse(this) - viewModel.knockRequestsLiveData?.observeData(this) { + viewModel.knockRequestsLiveData.observeData(this) { knocksListAdapter.submitList(it) } } diff --git a/core/src/main/java/org/futo/circles/core/feature/room/knoks/list/KnockRequestViewHolder.kt b/core/src/main/java/org/futo/circles/core/feature/room/knoks/list/KnockRequestViewHolder.kt index c0634a69700050b11e5cd67d8d19e84bbf8cda08..d505094f84f6756e9a2edcd13703268086a25b58 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/knoks/list/KnockRequestViewHolder.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/knoks/list/KnockRequestViewHolder.kt @@ -25,10 +25,21 @@ class KnockRequestViewHolder( } fun bind(data: KnockRequestListItem) { - binding.tvReason.apply { - setIsVisible(!data.message.isNullOrBlank()) - text = data.message + with(binding) { + setLoading(data.isLoading) + tvReason.apply { + setIsVisible(!data.message.isNullOrBlank()) + text = data.message + } + vUserLayout.bind(data.toCircleUser()) + } + } + + private fun setLoading(isLoading: Boolean) { + with(binding) { + vLoading.setIsVisible(isLoading) + btnInvite.setIsVisible(!isLoading) + btnDecline.setIsVisible(!isLoading) } - binding.vUserLayout.bind(data.toCircleUser()) } } \ No newline at end of file diff --git a/core/src/main/java/org/futo/circles/core/feature/user/UserDialogFragment.kt b/core/src/main/java/org/futo/circles/core/feature/user/UserDialogFragment.kt index 59ed5252535c7e96948c44c7c2e16d8af83b2d00..b35cd9e37fcdf3f79494dfe7b5f4955457cd93bf 100644 --- a/core/src/main/java/org/futo/circles/core/feature/user/UserDialogFragment.kt +++ b/core/src/main/java/org/futo/circles/core/feature/user/UserDialogFragment.kt @@ -13,6 +13,7 @@ import org.futo.circles.core.base.NetworkObserver import org.futo.circles.core.base.fragment.BaseFullscreenDialogFragment import org.futo.circles.core.databinding.DialogFragmentUserBinding import org.futo.circles.core.extensions.gone +import org.futo.circles.core.extensions.invisible import org.futo.circles.core.extensions.loadUserProfileIcon import org.futo.circles.core.extensions.notEmptyDisplayName import org.futo.circles.core.extensions.observeData @@ -20,8 +21,10 @@ import org.futo.circles.core.extensions.observeResponse import org.futo.circles.core.extensions.onBackPressed import org.futo.circles.core.extensions.setEnabledChildren import org.futo.circles.core.extensions.setIsVisible +import org.futo.circles.core.extensions.showError import org.futo.circles.core.extensions.showNoInternetConnection import org.futo.circles.core.extensions.showSuccess +import org.futo.circles.core.extensions.visible import org.futo.circles.core.extensions.withConfirmation import org.futo.circles.core.feature.user.list.UsersCirclesAdapter import org.futo.circles.core.model.IgnoreUser @@ -71,7 +74,11 @@ class UserDialogFragment : BaseFullscreenDialogFragment(DialogFragmentUserBindin } binding.btnInviteToConnect.apply { setIsVisible(!viewModel.isUserMyFollower()) - setOnClickListener { viewModel.inviteToMySharedCircle() } + setOnClickListener { + binding.vInviteToConnectLoading.visible() + binding.btnInviteToConnect.invisible() + viewModel.inviteToMySharedCircle() + } } } @@ -113,16 +120,25 @@ class UserDialogFragment : BaseFullscreenDialogFragment(DialogFragmentUserBindin } } viewModel.userLiveData.observeData(this) { setupUserInfo(it) } - viewModel.timelineLiveDataLiveData.observeData(this) { + viewModel.usersTimelinesLiveData.observeData(this) { usersCirclesAdapter.submitList(it) } viewModel.requestFollowLiveData.observeResponse(this, success = { showSuccess(getString(R.string.request_sent)) }) + viewModel.inviteToConnectLiveData.observeResponse(this, success = { showSuccess(getString(R.string.request_sent)) binding.btnInviteToConnect.gone() - }) + }, + error = { + binding.btnInviteToConnect.visible() + showError(it) + }, + onRequestInvoked = { + binding.vInviteToConnectLoading.gone() + } + ) viewModel.ignoreUserLiveData.observeResponse(this, success = { context?.let { showSuccess(it.getString(R.string.user_ignored)) } diff --git a/core/src/main/java/org/futo/circles/core/feature/user/UserViewModel.kt b/core/src/main/java/org/futo/circles/core/feature/user/UserViewModel.kt index 36ecdbea7bbeea38eb1eecd1c34e1f7bfd8c142c..e3ba56c33f0e85e86032d617521f26de5d0f3f56 100644 --- a/core/src/main/java/org/futo/circles/core/feature/user/UserViewModel.kt +++ b/core/src/main/java/org/futo/circles/core/feature/user/UserViewModel.kt @@ -1,5 +1,6 @@ package org.futo.circles.core.feature.user +import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel @@ -15,7 +16,9 @@ import org.futo.circles.core.extensions.launchUi import org.futo.circles.core.feature.room.RoomRelationsBuilder import org.futo.circles.core.feature.room.invite.ManageInviteRequestsDataSource import org.futo.circles.core.feature.workspace.SharedCircleDataSource +import org.futo.circles.core.model.TimelineHeaderItem import org.futo.circles.core.model.TimelineListItem +import org.futo.circles.core.model.TimelineRoomListItem import org.futo.circles.core.provider.MatrixSessionProvider import org.matrix.android.sdk.api.session.getRoom import javax.inject.Inject @@ -34,7 +37,7 @@ class UserViewModel @Inject constructor( private val profileRoomId = sharedCircleDataSource.getSharedCirclesSpaceId() ?: "" val userLiveData = userDataSource.userLiveData - val timelineLiveDataLiveData = MutableLiveData<List<TimelineListItem>>() + val requestFollowLiveData = SingleEventLiveData<Response<Unit?>>() val inviteToConnectLiveData = SingleEventLiveData<Response<Unit?>>() val ignoreUserLiveData = SingleEventLiveData<Response<Unit?>>() @@ -44,6 +47,29 @@ class UserViewModel @Inject constructor( it.firstOrNull { it.userId == userId } != null } + private val timelineLiveData = MutableLiveData<List<TimelineListItem>>() + private val loadingItemsIdsList = MutableLiveData<Set<String>>(emptySet()) + + val usersTimelinesLiveData = MediatorLiveData<List<TimelineListItem>>().also { + it.addSource(loadingItemsIdsList) { loadingItemsValue -> + val currentList = it.value ?: emptyList() + it.postValue( + currentList.map { item -> + when (item) { + is TimelineRoomListItem -> item.copy( + isLoading = loadingItemsValue.contains(item.id) + ) + + is TimelineHeaderItem -> item + } + } + ) + } + it.addSource(timelineLiveData) { value -> + it.postValue(value) + } + } + init { getUsersTimelines() } @@ -51,16 +77,18 @@ class UserViewModel @Inject constructor( private fun getUsersTimelines() { launchUi { userDataSource.getTimelinesFlow().collectLatest { - timelineLiveDataLiveData.postValue(it) + timelineLiveData.postValue(it) } } } fun requestFollowTimeline(timelineId: String) { launchBg { + toggleItemLoading(timelineId) val result = createResult { MatrixSessionProvider.currentSession?.roomService()?.knock(timelineId) } + toggleItemLoading(timelineId) requestFollowLiveData.postValue(result) } } @@ -68,8 +96,10 @@ class UserViewModel @Inject constructor( fun unFollowTimeline(timelineId: String) { launchBg { createResult { + toggleItemLoading(timelineId) roomRelationsBuilder.removeFromAllParents(timelineId) MatrixSessionProvider.currentSession?.roomService()?.leaveRoom(timelineId) + toggleItemLoading(timelineId) } } } @@ -109,4 +139,13 @@ class UserViewModel @Inject constructor( } } + private fun toggleItemLoading(id: String) { + val currentSet = loadingItemsIdsList.value?.toMutableSet() ?: return + val newLoadingSet = currentSet.apply { + if (this.contains(id)) remove(id) + else add(id) + } + loadingItemsIdsList.postValue(newLoadingSet) + } + } \ No newline at end of file diff --git a/core/src/main/java/org/futo/circles/core/feature/user/list/UsersCircleViewHolder.kt b/core/src/main/java/org/futo/circles/core/feature/user/list/UsersCircleViewHolder.kt index a9158a2cb0260d351dd8f438e7947768c8b0fb1e..543077234d857f84103f421021047c3dfd41320b 100644 --- a/core/src/main/java/org/futo/circles/core/feature/user/list/UsersCircleViewHolder.kt +++ b/core/src/main/java/org/futo/circles/core/feature/user/list/UsersCircleViewHolder.kt @@ -39,8 +39,9 @@ class UsersTimelineRoomViewHolder( with(binding) { tvTimelineName.text = data.info.title ivTimelineImage.loadRoomProfileIcon(data.info.avatarUrl, data.info.title) - btnFollow.setIsVisible(!data.isJoined) - btnUnFollow.setIsVisible(data.isJoined) + vLoading.setIsVisible(data.isLoading) + btnFollow.setIsVisible(!data.isJoined && !data.isLoading) + btnUnFollow.setIsVisible(data.isJoined && !data.isLoading) } } } diff --git a/core/src/main/java/org/futo/circles/core/model/InviteListItem.kt b/core/src/main/java/org/futo/circles/core/model/InviteListItem.kt index 7cd4a690ab9cd53b2b134e99c83132c364d5b7de..be79cb77faac4b4bcba3150e667ba29ff446c2af 100644 --- a/core/src/main/java/org/futo/circles/core/model/InviteListItem.kt +++ b/core/src/main/java/org/futo/circles/core/model/InviteListItem.kt @@ -28,17 +28,20 @@ data class RoomInviteListItem( val info: RoomInfo, val isEncrypted: Boolean, val inviterName: String, - val shouldBlurIcon: Boolean + val shouldBlurIcon: Boolean, + val isLoading: Boolean = false ) : InviteListItem(roomId) data class FollowRequestListItem( val user: CirclesUserSummary, - val reasonMessage: String? + val reasonMessage: String?, + val isLoading: Boolean = false ) : InviteListItem(user.id) data class ConnectionInviteListItem( val roomId: String, val user: CirclesUserSummary, + val isLoading: Boolean = false ) : InviteListItem(roomId) fun RoomSummary.toRoomInviteListItem(roomType: CircleRoomTypeArg, shouldBlurIcon: Boolean) = diff --git a/core/src/main/java/org/futo/circles/core/model/KnockRequestListItem.kt b/core/src/main/java/org/futo/circles/core/model/KnockRequestListItem.kt index 4b7becdc89e219ce92754701ce590cb5b6b570b6..e3efa753ed8212de624a6a6fb5e81dadf51c0e6e 100644 --- a/core/src/main/java/org/futo/circles/core/model/KnockRequestListItem.kt +++ b/core/src/main/java/org/futo/circles/core/model/KnockRequestListItem.kt @@ -6,7 +6,8 @@ data class KnockRequestListItem( val requesterId: String, val requesterName: String, val requesterAvatarUrl: String?, - val message: String? + val message: String?, + val isLoading: Boolean = false ) : IdEntity<String> { override val id: String = requesterId } diff --git a/core/src/main/java/org/futo/circles/core/model/TimelineListItem.kt b/core/src/main/java/org/futo/circles/core/model/TimelineListItem.kt index 8c14a18deab25b56bea9d285a3bba4bfd458376f..54368d5782e641fd077e984d3cf0c1cc7ad284c7 100644 --- a/core/src/main/java/org/futo/circles/core/model/TimelineListItem.kt +++ b/core/src/main/java/org/futo/circles/core/model/TimelineListItem.kt @@ -23,7 +23,8 @@ data class TimelineHeaderItem( data class TimelineRoomListItem( override val id: String, val info: RoomInfo, - val isJoined: Boolean + val isJoined: Boolean, + val isLoading: Boolean = false ) : TimelineListItem() fun RoomSummary.toTimelineRoomListItem() = TimelineRoomListItem( diff --git a/core/src/main/java/org/futo/circles/core/utils/MatrixUtils.kt b/core/src/main/java/org/futo/circles/core/utils/MatrixUtils.kt index fa57f8681f2b7c604bca3af4173d18ed955f8664..1add9d8ea62384afdc80699b69d77b0a0ad11554 100644 --- a/core/src/main/java/org/futo/circles/core/utils/MatrixUtils.kt +++ b/core/src/main/java/org/futo/circles/core/utils/MatrixUtils.kt @@ -22,6 +22,12 @@ private val roomTypes = listOf( GROUP_TYPE ) +val circlesRoomsTypes = listOf( + GALLERY_TYPE, + TIMELINE_TYPE, + GROUP_TYPE +) + private fun getRoomsLiveDataWithType( type: String, membershipFilter: List<Membership> = Membership.activeMemberships() diff --git a/core/src/main/res/layout/dialog_fragment_user.xml b/core/src/main/res/layout/dialog_fragment_user.xml index f0e8b2bdd3326b0b462a46bafd315e3db3e367a1..9cd6eb96ee7992c651779c962e0a771fdb917a9d 100644 --- a/core/src/main/res/layout/dialog_fragment_user.xml +++ b/core/src/main/res/layout/dialog_fragment_user.xml @@ -86,6 +86,18 @@ tools:visibility="visible" /> + <ProgressBar + android:id="@+id/vInviteToConnectLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginTop="8dp" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/tvUserId" /> + + <View android:id="@+id/divider" android:layout_width="0dp" diff --git a/core/src/main/res/layout/list_item_connection_invite.xml b/core/src/main/res/layout/list_item_connection_invite.xml index 1e9d9a3718c80298b10a6da164b3cf8106cb96ea..efcf47b6c62bc2266e2489ca4a14f3ef0069edc9 100644 --- a/core/src/main/res/layout/list_item_connection_invite.xml +++ b/core/src/main/res/layout/list_item_connection_invite.xml @@ -47,7 +47,7 @@ app:layout_constraintStart_toStartOf="@id/tvUserName" app:layout_constraintTop_toBottomOf="@id/tvUserName" /> - + <com.google.android.material.button.MaterialButton android:id="@+id/btnAccept" style="@style/AccentButtonStyle" @@ -78,4 +78,17 @@ app:layout_constraintStart_toEndOf="@id/btnAccept" app:layout_constraintTop_toTopOf="@id/btnAccept" /> + + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginTop="4dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/ivUserImage" + app:layout_constraintTop_toBottomOf="@+id/tvInvitesToConnect" /> + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/core/src/main/res/layout/list_item_invited_circle.xml b/core/src/main/res/layout/list_item_invited_circle.xml index cc1d807904206e73c300bcb23db0cd5a1132bd7c..f3d478ff9c55891ef8eff1a0605c012f78f30a35 100644 --- a/core/src/main/res/layout/list_item_invited_circle.xml +++ b/core/src/main/res/layout/list_item_invited_circle.xml @@ -70,6 +70,7 @@ app:layout_constraintTop_toBottomOf="@id/tvCircleTitle" tools:text="texsdt" /> + <com.google.android.material.button.MaterialButton android:id="@+id/btnAccept" style="@style/AccentButtonStyle" @@ -97,4 +98,16 @@ app:layout_constraintTop_toBottomOf="@+id/tvInvitedBy" /> + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/ivCircle" + app:layout_constraintTop_toBottomOf="@+id/tvInvitedBy" /> + + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/core/src/main/res/layout/list_item_invited_gallery.xml b/core/src/main/res/layout/list_item_invited_gallery.xml index 93c89ce3a0046ecf005fd79743eec174d75f6c5a..63c32784397f4ea9009474402ad55a722269287f 100644 --- a/core/src/main/res/layout/list_item_invited_gallery.xml +++ b/core/src/main/res/layout/list_item_invited_gallery.xml @@ -90,4 +90,16 @@ app:layout_constraintStart_toEndOf="@id/btnAccept" app:layout_constraintTop_toBottomOf="@+id/tvInviterName" /> + + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/ivGallery" + app:layout_constraintTop_toBottomOf="@+id/tvInviterName" /> + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/core/src/main/res/layout/list_item_invited_group.xml b/core/src/main/res/layout/list_item_invited_group.xml index 4cf4a5d99b522967aee185910a1006ab7e5d940e..2ad031dfa3a02e5b575fc72fdbc17757d285d7ea 100644 --- a/core/src/main/res/layout/list_item_invited_group.xml +++ b/core/src/main/res/layout/list_item_invited_group.xml @@ -101,4 +101,17 @@ app:layout_constraintStart_toEndOf="@id/btnAccept" app:layout_constraintTop_toBottomOf="@+id/tvInviterName" /> + + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/ivGroup" + app:layout_constraintTop_toBottomOf="@+id/tvInviterName" /> + + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/core/src/main/res/layout/list_item_knock_request.xml b/core/src/main/res/layout/list_item_knock_request.xml index 60906170fa64e93c211a73cb0ca0ab50f4a8230b..685b91148226d023f7f6311ba03e36b64351f3fa 100644 --- a/core/src/main/res/layout/list_item_knock_request.xml +++ b/core/src/main/res/layout/list_item_knock_request.xml @@ -61,4 +61,15 @@ MessageMessageMessageMessageMessageMessageMessageMessageMessageMessageMessage" app:layout_constraintTop_toTopOf="@id/btnInvite" /> + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tvReason" /> + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/core/src/main/res/layout/list_item_people_request.xml b/core/src/main/res/layout/list_item_people_request.xml index 7315a0483d7eb54de5ca420b9fbab1f1ec389c92..d8f60007d63d042776c7ecc13c35b16042c7d83c 100644 --- a/core/src/main/res/layout/list_item_people_request.xml +++ b/core/src/main/res/layout/list_item_people_request.xml @@ -93,4 +93,18 @@ app:layout_constraintStart_toEndOf="@id/btnAccept" app:layout_constraintTop_toTopOf="@id/btnAccept" /> + + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginTop="4dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/ivUserImage" + app:layout_constraintTop_toBottomOf="@+id/tvReasonMessage" /> + + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/core/src/main/res/layout/list_item_users_timeline.xml b/core/src/main/res/layout/list_item_users_timeline.xml index 89466acb71cfbb2848ea025fb5e6f469d4965567..13107bf01eaaf0673875e28d5119c2de409526db 100644 --- a/core/src/main/res/layout/list_item_users_timeline.xml +++ b/core/src/main/res/layout/list_item_users_timeline.xml @@ -62,4 +62,14 @@ app:layout_constraintTop_toTopOf="parent" tools:visibility="visible" /> + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index f5bbf55662b7636bf3e80ac98b8e0588c2245700..5e2533502b4666a0600a314841f16a9cf22f5042 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -135,9 +135,6 @@ <string name="public_circle_explanation">Other users can ask to join</string> <string name="private_type">Private</string> <string name="private_circle_explanation">Accessible only by invitation</string> - <string name="gallery_name">Gallery name</string> - <string name="group_name">Group name</string> - <string name="group_topic">Group topic</string> <string name="remove_from_this_circle_but_do_not_unfollow">Remove from this circle, but do not unfollow</string> <string name="unfollow_completely_remove_from_all_circles">Unfollow completely (remove from all circles)</string> <string name="no_internet_connection">No Internet connection</string> diff --git a/gallery/build.gradle b/gallery/build.gradle index ed82e73faf148dde02c6d7741ae58f1c2ca04b4a..86b33be244657597c9e168f035d345bc62e7d6c1 100644 --- a/gallery/build.gradle +++ b/gallery/build.gradle @@ -54,14 +54,14 @@ dependencies { implementation 'com.jsibbold:zoomage:1.3.1' //ExoPlayer - def exoplayer_version = '1.2.1' + def exoplayer_version = '1.3.0' implementation "androidx.media3:media3-exoplayer:$exoplayer_version" implementation "androidx.media3:media3-ui:$exoplayer_version" //Hilt implementation "com.google.dagger:hilt-android:$rootProject.ext.hilt_version" kapt "com.google.dagger:hilt-compiler:$rootProject.ext.hilt_version" - implementation "androidx.hilt:hilt-work:1.1.0" + implementation 'androidx.hilt:hilt-work:1.2.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5'