diff --git a/app/src/androidTest/java/com/nextcloud/talk/activities/MainActivityTest.kt b/app/src/androidTest/java/com/nextcloud/talk/activities/MainActivityTest.kt index ebbdca247..cd34ac884 100644 --- a/app/src/androidTest/java/com/nextcloud/talk/activities/MainActivityTest.kt +++ b/app/src/androidTest/java/com/nextcloud/talk/activities/MainActivityTest.kt @@ -37,6 +37,5 @@ class MainActivityTest { assertNotNull("Error creating user", user) sut.runOnUiThread { sut.resetConversationsList() } - println("User: " + user!!.id + " / " + user.userId + " / " + user.baseUrl) } } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt index afbc02e8c..185ad0b4b 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt @@ -190,14 +190,10 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { } private fun setupPhoneBookIntegration() { - if (CapabilitiesUtilNew.isPhoneBookIntegrationAvailable(currentUser)) { - activity!!.runOnUiThread { - binding.settingsPhoneBookIntegration.visibility = View.VISIBLE - } + if (CapabilitiesUtilNew.isPhoneBookIntegrationAvailable(currentUser!!)) { + binding.settingsPhoneBookIntegration.visibility = View.VISIBLE } else { - activity!!.runOnUiThread { - binding.settingsPhoneBookIntegration.visibility = View.GONE - } + binding.settingsPhoneBookIntegration.visibility = View.GONE } } @@ -648,7 +644,7 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { private fun setupServerAgeWarning() { when { - CapabilitiesUtilNew.isServerEOL(currentUser) -> { + CapabilitiesUtilNew.isServerEOL(currentUser!!) -> { binding.serverAgeWarningText.setTextColor(ContextCompat.getColor((context)!!, R.color.nc_darkRed)) binding.serverAgeWarningText.setText(R.string.nc_settings_server_eol) binding.serverAgeWarningIcon.setColorFilter( @@ -656,7 +652,7 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { PorterDuff.Mode.SRC_IN ) } - CapabilitiesUtilNew.isServerAlmostEOL(currentUser) -> { + CapabilitiesUtilNew.isServerAlmostEOL(currentUser!!) -> { binding.serverAgeWarningText.setTextColor( ContextCompat.getColor((context)!!, R.color.nc_darkYellow) ) @@ -688,7 +684,7 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { if (CapabilitiesUtil.isReadStatusAvailable(userUtils.currentUser)) { (binding.settingsReadPrivacy.findViewById(R.id.mp_checkable) as Checkable).isChecked = - !CapabilitiesUtilNew.isReadStatusPrivate(currentUser) + !CapabilitiesUtilNew.isReadStatusPrivate(currentUser!!) } else { binding.settingsReadPrivacy.visibility = View.GONE } diff --git a/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStorageMapper.kt b/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStorageMapper.kt index fe31df592..cd99dda9b 100644 --- a/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStorageMapper.kt +++ b/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStorageMapper.kt @@ -25,14 +25,12 @@ import com.nextcloud.talk.data.storage.model.ArbitraryStorageEntity object ArbitraryStorageMapper { fun toModel(entity: ArbitraryStorageEntity?): ArbitraryStorage? { - return if (entity == null) { - null - } else { + return entity?.let { ArbitraryStorage( - entity.accountIdentifier, - entity.key, - entity.storageObject, - entity.value + it.accountIdentifier, + it.key, + it.storageObject, + it.value ) } } diff --git a/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesDao.kt b/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesDao.kt index c74e08a82..0bcbe2d7e 100644 --- a/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesDao.kt +++ b/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesDao.kt @@ -42,7 +42,7 @@ abstract class ArbitraryStoragesDao { ): Maybe @Query("DELETE FROM ArbitraryStorage WHERE accountIdentifier = :accountIdentifier") - abstract suspend fun deleteArbitraryStorage(accountIdentifier: Long) + abstract fun deleteArbitraryStorage(accountIdentifier: Long) @Insert(onConflict = OnConflictStrategy.REPLACE) abstract fun saveArbitraryStorage(arbitraryStorage: ArbitraryStorageEntity): Long diff --git a/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesRepository.kt b/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesRepository.kt index 157cfeb4f..e97080967 100644 --- a/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesRepository.kt @@ -25,6 +25,6 @@ import io.reactivex.Maybe interface ArbitraryStoragesRepository { fun getStorageSetting(accountIdentifier: Long, key: String, objectString: String): Maybe - suspend fun deleteArbitraryStorage(accountIdentifier: Long) + fun deleteArbitraryStorage(accountIdentifier: Long) fun saveArbitraryStorage(arbitraryStorage: ArbitraryStorage): Long } diff --git a/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesRepositoryImpl.kt index 88203add1..264b29756 100644 --- a/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/data/storage/ArbitraryStoragesRepositoryImpl.kt @@ -35,7 +35,7 @@ class ArbitraryStoragesRepositoryImpl(private val arbitraryStoragesDao: Arbitrar .map { ArbitraryStorageMapper.toModel(it) } } - override suspend fun deleteArbitraryStorage(accountIdentifier: Long) { + override fun deleteArbitraryStorage(accountIdentifier: Long) { arbitraryStoragesDao.deleteArbitraryStorage(accountIdentifier) } diff --git a/app/src/main/java/com/nextcloud/talk/data/user/UserMapper.kt b/app/src/main/java/com/nextcloud/talk/data/user/UserMapper.kt index 7ef24b74b..f6a88ac77 100644 --- a/app/src/main/java/com/nextcloud/talk/data/user/UserMapper.kt +++ b/app/src/main/java/com/nextcloud/talk/data/user/UserMapper.kt @@ -25,21 +25,13 @@ import com.nextcloud.talk.data.user.model.UserEntity object UserMapper { fun toModel(entities: List?): List { - return if (entities == null) { - ArrayList() - } else { - val users = ArrayList() - for (entity in entities) { - users.add(toModel(entity)!!) - } - users - } + return entities?.map { user: UserEntity? -> + toModel(user)!! + } ?: emptyList() } fun toModel(entity: UserEntity?): User? { - return if (entity == null) { - null - } else { + return entity?.let { User( entity.id, entity.userId, @@ -58,22 +50,20 @@ object UserMapper { } fun toEntity(model: User): UserEntity { - var UserEntity: UserEntity? = null - model.id?.let { - UserEntity = UserEntity(it, model.userId, model.username, model.baseUrl) - } ?: run { - UserEntity = UserEntity(userId = model.userId, username = model.username, baseUrl = model.baseUrl) + val userEntity = when (val id = model.id) { + null -> UserEntity(userId = model.userId, username = model.username, baseUrl = model.baseUrl) + else -> UserEntity(id, model.userId, model.username, model.baseUrl) } - - UserEntity!!.token = model.token - UserEntity!!.displayName = model.displayName - UserEntity!!.pushConfigurationState = model.pushConfigurationState - UserEntity!!.capabilities = model.capabilities - UserEntity!!.clientCertificate = model.clientCertificate - UserEntity!!.externalSignalingServer = model.externalSignalingServer - UserEntity!!.current = model.current - UserEntity!!.scheduledForDeletion = model.scheduledForDeletion - - return UserEntity!! + userEntity.apply { + token = model.token + displayName = model.displayName + pushConfigurationState = model.pushConfigurationState + capabilities = model.capabilities + clientCertificate = model.clientCertificate + externalSignalingServer = model.externalSignalingServer + current = model.current + scheduledForDeletion = model.scheduledForDeletion + } + return userEntity } } diff --git a/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt b/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt index 37a89ce82..329c309e7 100644 --- a/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt +++ b/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt @@ -47,9 +47,6 @@ abstract class UsersDao { @Query("SELECT * FROM User where current = 1") abstract fun getActiveUserSynchronously(): UserEntity? - @Query("SELECT * FROM User WHERE current = 1") - abstract fun getActiveUserLiveData(): Single - @Query("DELETE FROM User WHERE id = :id") abstract fun deleteUserWithId(id: Long) @@ -122,13 +119,9 @@ abstract class UsersDao { @Transaction open suspend fun markUserForDeletion(id: Long): Boolean { - val users = getUsers().blockingGet() - - for (user in users) { - if (user.id == id) { - user.current = FALSE - updateUser(user) - } + getUserWithId(id).blockingGet()?.let { user -> + user.current = FALSE + updateUser(user) } return setAnyUserAsActive() @@ -137,14 +130,12 @@ abstract class UsersDao { @Transaction open suspend fun setAnyUserAsActive(): Boolean { val users = getUsers().blockingGet() - var result = FALSE - for (user in users) { + val result = users.firstOrNull()?.let { user -> user.current = TRUE updateUser(user) - result = TRUE - break - } + TRUE + } ?: FALSE return result } diff --git a/app/src/main/java/com/nextcloud/talk/data/user/model/UserEntity.kt b/app/src/main/java/com/nextcloud/talk/data/user/model/UserEntity.kt index 41d62708f..555bdebcd 100644 --- a/app/src/main/java/com/nextcloud/talk/data/user/model/UserEntity.kt +++ b/app/src/main/java/com/nextcloud/talk/data/user/model/UserEntity.kt @@ -29,7 +29,6 @@ import androidx.room.PrimaryKey import com.nextcloud.talk.models.ExternalSignalingServer import com.nextcloud.talk.models.json.capabilities.Capabilities import com.nextcloud.talk.models.json.push.PushConfigurationState -import com.nextcloud.talk.utils.ApiUtils import kotlinx.android.parcel.Parcelize import java.lang.Boolean.FALSE @@ -48,19 +47,4 @@ data class UserEntity( @ColumnInfo(name = "externalSignalingServer") var externalSignalingServer: ExternalSignalingServer? = null, @ColumnInfo(name = "current") var current: Boolean = FALSE, @ColumnInfo(name = "scheduledForDeletion") var scheduledForDeletion: Boolean = FALSE, -) : Parcelable { - - fun hasSpreedFeatureCapability(capabilityName: String): Boolean { - return capabilities?.spreedCapability?.features?.contains(capabilityName) ?: false - } - - fun canUserCreateGroupConversations(): Boolean { - val canCreateValue = capabilities?.spreedCapability?.config?.get("conversations")?.get("can-create") - canCreateValue?.let { - return it.toBoolean() - } - return true - } - - fun getCredentials(): String = ApiUtils.getCredentials(username, token) -} +) : Parcelable diff --git a/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt b/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt index cf5907d9f..c1b476e76 100644 --- a/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt +++ b/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt @@ -25,11 +25,9 @@ import android.os.Parcelable import com.bluelinelabs.logansquare.annotation.JsonField import com.bluelinelabs.logansquare.annotation.JsonObject import kotlinx.android.parcel.Parcelize -import kotlinx.serialization.Serializable @Parcelize @JsonObject -@Serializable data class ExternalSignalingServer( @JsonField(name = ["externalSignalingServer"]) var externalSignalingServer: String? = null, diff --git a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.kt b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.kt index e1ca8d043..6682469b5 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.kt @@ -25,11 +25,9 @@ import android.os.Parcelable import com.bluelinelabs.logansquare.annotation.JsonField import com.bluelinelabs.logansquare.annotation.JsonObject import kotlinx.android.parcel.Parcelize -import kotlinx.serialization.Serializable @Parcelize @JsonObject -@Serializable data class Capabilities( @JsonField(name = ["spreed"]) var spreedCapability: SpreedCapability?, diff --git a/app/src/main/java/com/nextcloud/talk/models/json/push/PushConfigurationState.kt b/app/src/main/java/com/nextcloud/talk/models/json/push/PushConfigurationState.kt index c4eed4464..ff68fd87f 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/push/PushConfigurationState.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/push/PushConfigurationState.kt @@ -25,11 +25,9 @@ import android.os.Parcelable import com.bluelinelabs.logansquare.annotation.JsonField import com.bluelinelabs.logansquare.annotation.JsonObject import kotlinx.android.parcel.Parcelize -import kotlinx.serialization.Serializable @Parcelize @JsonObject -@Serializable data class PushConfigurationState( @JsonField(name = ["pushToken"]) var pushToken: String?, diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java index a1a7d025c..a493dc785 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java @@ -157,34 +157,7 @@ public class ApiUtils { @Deprecated public static int getConversationApiVersion(UserEntity user, int[] versions) throws NoSupportedApiException { - boolean hasApiV4 = false; - for (int version : versions) { - hasApiV4 |= version == APIv4; - } - - if (!hasApiV4) { - Exception e = new Exception("Api call did not try conversation-v4 api"); - Log.d(TAG, e.getMessage(), e); - } - - for (int version : versions) { - if (CapabilitiesUtil.hasSpreedFeatureCapability(user, "conversation-v" + version)) { - return version; - } - - // Fallback for old API versions - if ((version == APIv1 || version == APIv2)) { - if (CapabilitiesUtil.hasSpreedFeatureCapability(user, "conversation-v2")) { - return version; - } - if (version == APIv1 && - CapabilitiesUtil.hasSpreedFeatureCapability(user, "mention-flag") && - !CapabilitiesUtil.hasSpreedFeatureCapability(user, "conversation-v4")) { - return version; - } - } - } - throw new NoSupportedApiException(); + return getConversationApiVersion(LegacyUserEntityMapper.toModel(user), versions); } public static int getSignalingApiVersion(UserEntity user, int[] versions) throws NoSupportedApiException { diff --git a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java index 11c69253f..ed52c1f44 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java @@ -93,6 +93,7 @@ import java.text.DateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -572,31 +573,7 @@ public class DisplayUtils { @Deprecated public static void loadAvatarImage(UserEntity user, SimpleDraweeView avatarImageView, boolean deleteCache) { - String avatarId; - if (!TextUtils.isEmpty(user.getUserId())) { - avatarId = user.getUserId(); - } else { - avatarId = user.getUsername(); - } - - String avatarString = ApiUtils.getUrlForAvatar(user.getBaseUrl(), avatarId, true); - - // clear cache - if (deleteCache) { - Uri avatarUri = Uri.parse(avatarString); - - ImagePipeline imagePipeline = Fresco.getImagePipeline(); - imagePipeline.evictFromMemoryCache(avatarUri); - imagePipeline.evictFromDiskCache(avatarUri); - imagePipeline.evictFromCache(avatarUri); - } - - DraweeController draweeController = Fresco.newDraweeControllerBuilder() - .setOldController(avatarImageView.getController()) - .setAutoPlayAnimations(true) - .setImageRequest(DisplayUtils.getImageRequestForUrl(avatarString, null)) - .build(); - avatarImageView.setController(draweeController); + loadAvatarImage(Objects.requireNonNull(LegacyUserEntityMapper.toModel(user)), avatarImageView, deleteCache); } public static void loadAvatarImage(User user, SimpleDraweeView avatarImageView, boolean deleteCache) { diff --git a/app/src/main/java/com/nextcloud/talk/utils/LegacyUserEntityMapper.kt b/app/src/main/java/com/nextcloud/talk/utils/LegacyUserEntityMapper.kt new file mode 100644 index 000000000..554a1ebf1 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/utils/LegacyUserEntityMapper.kt @@ -0,0 +1,56 @@ +/* + * Nextcloud Talk application + * + * @author Andy Scherzinger + * Copyright (C) 2022 Andy Scherzinger + * + * model program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * model program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with model program. If not, see . + */ + +package com.nextcloud.talk.utils + +import com.bluelinelabs.logansquare.LoganSquare +import com.nextcloud.talk.data.user.model.User +import com.nextcloud.talk.models.ExternalSignalingServer +import com.nextcloud.talk.models.database.UserEntity +import com.nextcloud.talk.models.json.capabilities.Capabilities +import com.nextcloud.talk.models.json.push.PushConfigurationState + +object LegacyUserEntityMapper { + fun toModel(entities: List?): List { + return entities?.map { user: UserEntity? -> + toModel(user)!! + } ?: emptyList() + } + + @JvmStatic + fun toModel(entity: UserEntity?): User? { + return entity?.let { + User( + entity.id, + entity.userId, + entity.username, + entity.baseUrl, + entity.token, + entity.displayName, + LoganSquare.parse(entity.pushConfigurationState, PushConfigurationState::class.java), + LoganSquare.parse(entity.capabilities, Capabilities::class.java), + entity.clientCertificate, + LoganSquare.parse(entity.externalSignalingServer, ExternalSignalingServer::class.java), + entity.current, + entity.scheduledForDeletion + ) + } + } +} diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/arbitrarystorage/ArbitraryStorageUtils.java b/app/src/main/java/com/nextcloud/talk/utils/database/arbitrarystorage/ArbitraryStorageUtils.java index 2fb0f4e4f..92abd42ec 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/database/arbitrarystorage/ArbitraryStorageUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/database/arbitrarystorage/ArbitraryStorageUtils.java @@ -20,8 +20,10 @@ package com.nextcloud.talk.utils.database.arbitrarystorage; import androidx.annotation.Nullable; + import com.nextcloud.talk.models.database.ArbitraryStorage; import com.nextcloud.talk.models.database.ArbitraryStorageEntity; + import io.reactivex.Observable; import io.reactivex.schedulers.Schedulers; import io.requery.Persistable; @@ -29,6 +31,9 @@ import io.requery.query.Result; import io.requery.reactivex.ReactiveEntityStore; import io.requery.reactivex.ReactiveScalar; +/** + * @deprecated use {@link com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager} instead. + */ @Deprecated public class ArbitraryStorageUtils { private ReactiveEntityStore dataStore; @@ -46,16 +51,16 @@ public class ArbitraryStorageUtils { arbitraryStorageEntity.setObject(object); dataStore.upsert(arbitraryStorageEntity) - .toObservable() - .subscribeOn(Schedulers.io()) - .subscribe(); + .toObservable() + .subscribeOn(Schedulers.io()) + .subscribe(); } public ArbitraryStorageEntity getStorageSetting(long accountIdentifier, String key, @Nullable String object) { Result findStorageQueryResult = dataStore.select(ArbitraryStorage.class) - .where(ArbitraryStorageEntity.ACCOUNT_IDENTIFIER.eq(accountIdentifier) - .and(ArbitraryStorageEntity.KEY.eq(key)).and(ArbitraryStorageEntity.OBJECT.eq(object))) - .limit(1).get(); + .where(ArbitraryStorageEntity.ACCOUNT_IDENTIFIER.eq(accountIdentifier) + .and(ArbitraryStorageEntity.KEY.eq(key)).and(ArbitraryStorageEntity.OBJECT.eq(object))) + .limit(1).get(); return (ArbitraryStorageEntity) findStorageQueryResult.firstOrNull(); } @@ -64,6 +69,6 @@ public class ArbitraryStorageUtils { ReactiveScalar deleteResult = dataStore.delete(ArbitraryStorage.class).where(ArbitraryStorageEntity.ACCOUNT_IDENTIFIER.eq(accountIdentifier)).get(); return deleteResult.single().toObservable() - .subscribeOn(Schedulers.io()); + .subscribeOn(Schedulers.io()); } } diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.java b/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.java deleted file mode 100644 index f87ff4ca4..000000000 --- a/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Nextcloud Talk application - * - * @author Andy Scherzinger - * @author Mario Danic - * Copyright (C) 2021 Andy Scherzinger (info@andy-scherzinger.de) - * Copyright (C) 2017-2018 Mario Danic - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.nextcloud.talk.utils.database.user; - -import com.nextcloud.talk.data.user.model.User; -import com.nextcloud.talk.models.json.capabilities.Capabilities; - -import java.util.HashMap; -import java.util.Map; - -import androidx.annotation.Nullable; - -public abstract class CapabilitiesUtilNew { - - public static boolean hasNotificationsCapability(@Nullable User user, String capabilityName) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities.getNotificationsCapability() != null && - capabilities.getNotificationsCapability().getFeatures() != null) { - return capabilities.getSpreedCapability().getFeatures().contains(capabilityName); - } - } - return false; - } - - public static boolean hasExternalCapability(@Nullable User user, String capabilityName) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities.getExternalCapability() != null && - capabilities.getExternalCapability().containsKey("v1")) { - return capabilities.getExternalCapability().get("v1").contains(capabilityName); - } - } - return false; - } - - public static boolean isServerEOL(@Nullable User user) { - // Capability is available since Talk 4 => Nextcloud 14 => Autmn 2018 - return !hasSpreedFeatureCapability(user, "no-ping"); - } - - public static boolean isServerAlmostEOL(@Nullable User user) { - // Capability is available since Talk 8 => Nextcloud 18 => January 2020 - return !hasSpreedFeatureCapability(user, "chat-replies"); - } - - public static boolean canSetChatReadMarker(@Nullable User user) { - return hasSpreedFeatureCapability(user, "chat-read-marker"); - } - - public static boolean hasSpreedFeatureCapability(@Nullable User user, String capabilityName) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities != null && capabilities.getSpreedCapability() != null && - capabilities.getSpreedCapability().getFeatures() != null) { - return capabilities.getSpreedCapability().getFeatures().contains(capabilityName); - } - } - return false; - } - - public static Integer getMessageMaxLength(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities != null && - capabilities.getSpreedCapability() != null && - capabilities.getSpreedCapability().getConfig() != null && - capabilities.getSpreedCapability().getConfig().containsKey("chat")) { - HashMap chatConfigHashMap = capabilities - .getSpreedCapability() - .getConfig() - .get("chat"); - if (chatConfigHashMap != null && chatConfigHashMap.containsKey("max-length")) { - int chatSize = Integer.parseInt(chatConfigHashMap.get("max-length")); - if (chatSize > 0) { - return chatSize; - } else { - return 1000; - } - } - } - } - return 1000; - } - - public static boolean isPhoneBookIntegrationAvailable(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - return capabilities != null && - capabilities.getSpreedCapability() != null && - capabilities.getSpreedCapability().getFeatures() != null && - capabilities.getSpreedCapability().getFeatures().contains("phonebook-search"); - } - return false; - } - - public static boolean isReadStatusAvailable(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities != null && - capabilities.getSpreedCapability() != null && - capabilities.getSpreedCapability().getConfig() != null && - capabilities.getSpreedCapability().getConfig().containsKey("chat")) { - Map map = capabilities.getSpreedCapability().getConfig().get("chat"); - return map != null && map.containsKey("read-privacy"); - } - } - return false; - } - - public static boolean isReadStatusPrivate(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities != null && - capabilities.getSpreedCapability() != null && - capabilities.getSpreedCapability().getConfig() != null && - capabilities.getSpreedCapability().getConfig().containsKey("chat")) { - HashMap map = capabilities.getSpreedCapability().getConfig().get("chat"); - if (map != null && map.containsKey("read-privacy")) { - return Integer.parseInt(map.get("read-privacy")) == 1; - } - } - } - return false; - } - - public static boolean isUserStatusAvailable(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities.getUserStatusCapability() != null && - capabilities.getUserStatusCapability().getEnabled() && - capabilities.getUserStatusCapability().getSupportsEmoji()) { - return true; - } - } - return false; - } - - public static String getAttachmentFolder(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities != null && - capabilities.getSpreedCapability() != null && - capabilities.getSpreedCapability().getConfig() != null && - capabilities.getSpreedCapability().getConfig().containsKey("attachments")) { - HashMap map = capabilities.getSpreedCapability().getConfig().get("attachments"); - if (map != null && map.containsKey("folder")) { - return map.get("folder"); - } - } - } - return "/Talk"; - } - - public static String getServerName(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities != null && capabilities.getThemingCapability() != null) { - return capabilities.getThemingCapability().getName(); - } - } - return ""; - } - - // TODO later avatar can also be checked via user fields, for now it is in Talk capability - public static boolean isAvatarEndpointAvailable(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - return (capabilities != null && - capabilities.getSpreedCapability() != null && - capabilities.getSpreedCapability().getFeatures() != null && - capabilities.getSpreedCapability().getFeatures().contains("temp-user-avatar-api")); - } - return false; - } - - public static boolean canEditScopes(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - return (capabilities != null && - capabilities.getProvisioningCapability() != null && - capabilities.getProvisioningCapability().getAccountPropertyScopesVersion() != null && - capabilities.getProvisioningCapability().getAccountPropertyScopesVersion() > 1); - } - return false; - } - - public static boolean isAbleToCall(@Nullable User user) { - if (user != null && user.getCapabilities() != null) { - Capabilities capabilities = user.getCapabilities(); - if (capabilities != null && - capabilities.getSpreedCapability() != null && - capabilities.getSpreedCapability().getConfig() != null && - capabilities.getSpreedCapability().getConfig().containsKey("call") && - capabilities.getSpreedCapability().getConfig().get("call") != null && - capabilities.getSpreedCapability().getConfig().get("call").containsKey("enabled")) { - return Boolean.parseBoolean( - capabilities.getSpreedCapability().getConfig().get("call").get("enabled")); - } else { - // older nextcloud versions without the capability can't disable the calls - return true; - } - } - return false; - } - - public static boolean isUnifiedSearchAvailable(@Nullable final User user) { - return hasSpreedFeatureCapability(user, "unified-search"); - } -} diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.kt b/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.kt new file mode 100644 index 000000000..175753bb3 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.kt @@ -0,0 +1,154 @@ +/* + * Nextcloud Talk application + * + * @author Andy Scherzinger + * @author Mario Danic + * Copyright (C) 2021 Andy Scherzinger (info@andy-scherzinger.de) + * Copyright (C) 2017-2018 Mario Danic + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.nextcloud.talk.utils.database.user + +import com.nextcloud.talk.data.user.model.User + +@Suppress("TooManyFunctions") +object CapabilitiesUtilNew { + fun hasNotificationsCapability(user: User, capabilityName: String): Boolean { + return user.capabilities?.spreedCapability?.features?.contains(capabilityName) == true + } + + fun hasExternalCapability(user: User, capabilityName: String?): Boolean { + if (user.capabilities?.externalCapability?.containsKey("v1") == true) { + return user.capabilities!!.externalCapability!!["v1"]?.contains(capabilityName!!) == true + } + return false + } + + fun isServerEOL(user: User): Boolean { + // Capability is available since Talk 4 => Nextcloud 14 => Autmn 2018 + return !hasSpreedFeatureCapability(user, "no-ping") + } + + fun isServerAlmostEOL(user: User): Boolean { + // Capability is available since Talk 8 => Nextcloud 18 => January 2020 + return !hasSpreedFeatureCapability(user, "chat-replies") + } + + fun canSetChatReadMarker(user: User): Boolean { + return hasSpreedFeatureCapability(user, "chat-read-marker") + } + + fun hasSpreedFeatureCapability(user: User, capabilityName: String): Boolean { + if (user.capabilities?.spreedCapability?.features != null) { + return user.capabilities!!.spreedCapability!!.features!!.contains(capabilityName) + } + return false + } + + fun getMessageMaxLength(user: User): Int { + val capabilities = user.capabilities!! + if (user.capabilities?.spreedCapability?.config?.containsKey("chat") == true) { + val chatConfigHashMap = user.capabilities!!.spreedCapability!!.config!!["chat"] + if (chatConfigHashMap?.containsKey("max-length") == true) { + val chatSize = chatConfigHashMap["max-length"]!!.toInt() + return if (chatSize > 0) { + chatSize + } else { + DEFAULT_CHAT_SIZE + } + } + } + + return DEFAULT_CHAT_SIZE + } + + fun isPhoneBookIntegrationAvailable(user: User): Boolean { + return user.capabilities?.spreedCapability?.features?.contains("phonebook-search") == true + } + + fun isReadStatusAvailable(user: User): Boolean { + if (user.capabilities?.spreedCapability?.config?.containsKey("chat") == true) { + val map: Map? = user.capabilities!!.spreedCapability!!.config!!["chat"] + return map != null && map.containsKey("read-privacy") + } + return false + } + + fun isReadStatusPrivate(user: User): Boolean { + if (user.capabilities?.spreedCapability?.config?.containsKey("chat") == true) { + val map = user.capabilities!!.spreedCapability!!.config!!["chat"] + if (map?.containsKey("read-privacy") == true) { + return map["read-privacy"]!!.toInt() == 1 + } + } + + return false + } + + fun isUserStatusAvailable(user: User): Boolean { + return user.capabilities?.userStatusCapability?.enabled == true && + user.capabilities?.userStatusCapability?.supportsEmoji == true + } + + fun getAttachmentFolder(user: User): String? { + if (user.capabilities?.spreedCapability?.config?.containsKey("attachments") == true) { + val map = user.capabilities!!.spreedCapability!!.config!!["attachments"] + if (map?.containsKey("folder") == true) { + return map["folder"] + } + } + return "/Talk" + } + + fun getServerName(user: User): String? { + if (user.capabilities?.themingCapability != null) { + return user.capabilities!!.themingCapability!!.name + } + return "" + } + + // TODO later avatar can also be checked via user fields, for now it is in Talk capability + fun isAvatarEndpointAvailable(user: User): Boolean { + return user.capabilities?.spreedCapability?.features?.contains("temp-user-avatar-api") == true + } + + fun canEditScopes(user: User): Boolean { + return user.capabilities?.provisioningCapability?.accountPropertyScopesVersion != null && + user.capabilities!!.provisioningCapability!!.accountPropertyScopesVersion!! > 1 + } + + fun isAbleToCall(user: User): Boolean { + if (user.capabilities != null) { + val capabilities = user.capabilities + return if ( + capabilities?.spreedCapability?.config?.containsKey("call") == true && + capabilities.spreedCapability!!.config!!["call"] != null && + capabilities.spreedCapability!!.config!!["call"]!!.containsKey("enabled") + ) { + java.lang.Boolean.parseBoolean(capabilities.spreedCapability!!.config!!["call"]!!["enabled"]) + } else { + // older nextcloud versions without the capability can't disable the calls + true + } + } + return false + } + + fun isUnifiedSearchAvailable(user: User): Boolean { + return hasSpreedFeatureCapability(user, "unified-search") + } + + const val DEFAULT_CHAT_SIZE = 1000 +} diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/user/UserUtils.java b/app/src/main/java/com/nextcloud/talk/utils/database/user/UserUtils.java index 5adc51e43..dc97b6ea0 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/database/user/UserUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/database/user/UserUtils.java @@ -35,6 +35,9 @@ import io.requery.Persistable; import io.requery.query.Result; import io.requery.reactivex.ReactiveEntityStore; +/** + * @deprecated use {@link com.nextcloud.talk.users.UserManager} instead. + */ @Deprecated public class UserUtils implements CurrentUserProvider { private ReactiveEntityStore dataStore; @@ -45,24 +48,24 @@ public class UserUtils implements CurrentUserProvider { public boolean anyUserExists() { return (dataStore.count(User.class).where(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE)) - .limit(1).get().value() > 0); + .limit(1).get().value() > 0); } public boolean hasMultipleUsers() { return (dataStore.count(User.class).where(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE)) - .get().value() > 1); + .get().value() > 1); } public List getUsers() { Result findUsersQueryResult = dataStore.select(User.class).where - (UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE)).get(); + (UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE)).get(); return findUsersQueryResult.toList(); } public List getUsersScheduledForDeletion() { Result findUsersQueryResult = dataStore.select(User.class) - .where(UserEntity.SCHEDULED_FOR_DELETION.eq(Boolean.TRUE)).get(); + .where(UserEntity.SCHEDULED_FOR_DELETION.eq(Boolean.TRUE)).get(); return findUsersQueryResult.toList(); } @@ -70,8 +73,8 @@ public class UserUtils implements CurrentUserProvider { public UserEntity getAnyUserAndSetAsActive() { Result findUserQueryResult = dataStore.select(User.class) - .where(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE)) - .limit(1).get(); + .where(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE)) + .limit(1).get(); UserEntity userEntity; if ((userEntity = (UserEntity) findUserQueryResult.firstOrNull()) != null) { @@ -84,10 +87,11 @@ public class UserUtils implements CurrentUserProvider { } @Override - public @Nullable UserEntity getCurrentUser() { + public @Nullable + UserEntity getCurrentUser() { Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.CURRENT.eq(Boolean.TRUE) - .and(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE))) - .limit(1).get(); + .and(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE))) + .limit(1).get(); return (UserEntity) findUserQueryResult.firstOrNull(); } @@ -98,8 +102,8 @@ public class UserUtils implements CurrentUserProvider { UserEntity user = (UserEntity) findUserQueryResult.firstOrNull(); return dataStore.delete(user) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()); + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); } @@ -109,20 +113,20 @@ public class UserUtils implements CurrentUserProvider { UserEntity user = (UserEntity) findUserQueryResult.firstOrNull(); return dataStore.delete(user) - .subscribeOn(Schedulers.io()); + .subscribeOn(Schedulers.io()); } public UserEntity getUserById(String id) { Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.USER_ID.eq(id)) - .limit(1).get(); + .limit(1).get(); return (UserEntity) findUserQueryResult.firstOrNull(); } public UserEntity getUserWithId(long id) { Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.ID.eq(id)) - .limit(1).get(); + .limit(1).get(); return (UserEntity) findUserQueryResult.firstOrNull(); } @@ -140,8 +144,8 @@ public class UserUtils implements CurrentUserProvider { public boolean checkIfUserIsScheduledForDeletion(String username, String server) { Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.USERNAME.eq(username)) - .and(UserEntity.BASE_URL.eq(server)) - .limit(1).get(); + .and(UserEntity.BASE_URL.eq(server)) + .limit(1).get(); UserEntity userEntity; if ((userEntity = (UserEntity) findUserQueryResult.firstOrNull()) != null) { @@ -153,23 +157,23 @@ public class UserUtils implements CurrentUserProvider { public UserEntity getUserWithInternalId(long internalId) { Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.ID.eq(internalId) - .and(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE))) - .limit(1).get(); + .and(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE))) + .limit(1).get(); return (UserEntity) findUserQueryResult.firstOrNull(); } public boolean getIfUserWithUsernameAndServer(String username, String server) { Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.USERNAME.eq(username) - .and(UserEntity.BASE_URL.eq(server))) - .limit(1).get(); + .and(UserEntity.BASE_URL.eq(server))) + .limit(1).get(); return findUserQueryResult.firstOrNull() != null; } public boolean scheduleUserForDeletionWithId(long id) { Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.ID.eq(id)) - .limit(1).get(); + .limit(1).get(); UserEntity userEntity; if ((userEntity = (UserEntity) findUserQueryResult.firstOrNull()) != null) { @@ -194,7 +198,7 @@ public class UserUtils implements CurrentUserProvider { Result findUserQueryResult; if (internalId == null) { findUserQueryResult = dataStore.select(User.class).where(UserEntity.USERNAME.eq(username). - and(UserEntity.BASE_URL.eq(serverUrl))).limit(1).get(); + and(UserEntity.BASE_URL.eq(serverUrl))).limit(1).get(); } else { findUserQueryResult = dataStore.select(User.class).where(UserEntity.ID.eq(internalId)).get(); } @@ -243,7 +247,7 @@ public class UserUtils implements CurrentUserProvider { } if ((displayName != null && user.getDisplayName() == null) || (displayName != null && user.getDisplayName() - != null && !displayName.equals(user.getDisplayName()))) { + != null && !displayName.equals(user.getDisplayName()))) { user.setDisplayName(displayName); }