fix review comments

Co-authored-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
This commit is contained in:
Andy Scherzinger 2022-06-29 18:29:13 +02:00
parent 12f793567e
commit 205292f9b0
No known key found for this signature in database
GPG Key ID: 6CADC7E3523C308B
19 changed files with 291 additions and 399 deletions

View File

@ -37,6 +37,5 @@ class MainActivityTest {
assertNotNull("Error creating user", user)
sut.runOnUiThread { sut.resetConversationsList() }
println("User: " + user!!.id + " / " + user.userId + " / " + user.baseUrl)
}
}

View File

@ -190,16 +190,12 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
}
private fun setupPhoneBookIntegration() {
if (CapabilitiesUtilNew.isPhoneBookIntegrationAvailable(currentUser)) {
activity!!.runOnUiThread {
if (CapabilitiesUtilNew.isPhoneBookIntegrationAvailable(currentUser!!)) {
binding.settingsPhoneBookIntegration.visibility = View.VISIBLE
}
} else {
activity!!.runOnUiThread {
binding.settingsPhoneBookIntegration.visibility = View.GONE
}
}
}
private fun setupSoundSettings() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@ -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<View>(R.id.mp_checkable) as Checkable).isChecked =
!CapabilitiesUtilNew.isReadStatusPrivate(currentUser)
!CapabilitiesUtilNew.isReadStatusPrivate(currentUser!!)
} else {
binding.settingsReadPrivacy.visibility = View.GONE
}

View File

@ -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
)
}
}

View File

@ -42,7 +42,7 @@ abstract class ArbitraryStoragesDao {
): Maybe<ArbitraryStorageEntity>
@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

View File

@ -25,6 +25,6 @@ import io.reactivex.Maybe
interface ArbitraryStoragesRepository {
fun getStorageSetting(accountIdentifier: Long, key: String, objectString: String): Maybe<ArbitraryStorage>
suspend fun deleteArbitraryStorage(accountIdentifier: Long)
fun deleteArbitraryStorage(accountIdentifier: Long)
fun saveArbitraryStorage(arbitraryStorage: ArbitraryStorage): Long
}

View File

@ -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)
}

View File

@ -25,21 +25,13 @@ import com.nextcloud.talk.data.user.model.UserEntity
object UserMapper {
fun toModel(entities: List<UserEntity?>?): List<User> {
return if (entities == null) {
ArrayList()
} else {
val users = ArrayList<User>()
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
}
}

View File

@ -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<UserEntity?>
@Query("DELETE FROM User WHERE id = :id")
abstract fun deleteUserWithId(id: Long)
@ -122,14 +119,10 @@ abstract class UsersDao {
@Transaction
open suspend fun markUserForDeletion(id: Long): Boolean {
val users = getUsers().blockingGet()
for (user in users) {
if (user.id == id) {
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
}

View File

@ -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

View File

@ -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,

View File

@ -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?,

View File

@ -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?,

View File

@ -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 {

View File

@ -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) {

View File

@ -0,0 +1,56 @@
/*
* Nextcloud Talk application
*
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <infoi@andy-scherzinger.de>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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<UserEntity?>?): List<User> {
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
)
}
}
}

View File

@ -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<Persistable> dataStore;

View File

@ -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 <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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<String, String> 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<String, String> 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<String, String> 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<String, String> 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");
}
}

View File

@ -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 <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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<String, String>? = 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
}

View File

@ -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<Persistable> dataStore;
@ -84,7 +87,8 @@ 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();