Merge pull request #4461 from nextcloud/coroutine_4

Migrating from Rxjava to coroutines #4
This commit is contained in:
Marcel Hibbe 2024-11-21 10:59:04 +01:00 committed by GitHub
commit 8fa3c7bf05
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 322 additions and 325 deletions

View File

@ -309,6 +309,12 @@ public interface NcApi {
Observable<Void> unregisterDeviceForNotificationsWithProxy(@Url String url, Observable<Void> unregisterDeviceForNotificationsWithProxy(@Url String url,
@QueryMap Map<String, String> fields); @QueryMap Map<String, String> fields);
@FormUrlEncoded
@PUT
Observable<Response<GenericOverall>> setPassword2(@Header("Authorization") String authorization,
@Url String url,
@Field("password") String password);
@GET @GET
Observable<CapabilitiesOverall> getCapabilities(@Header("Authorization") String authorization, @Url String url); Observable<CapabilitiesOverall> getCapabilities(@Header("Authorization") String authorization, @Url String url);
@ -373,16 +379,6 @@ public interface NcApi {
@Nullable @Query("limit") Integer limit, @Nullable @Query("limit") Integer limit,
@QueryMap Map<String, String> fields); @QueryMap Map<String, String> fields);
// Url is: /api/{apiVersion}/room/{token}/pin
@POST
Observable<GenericOverall> addConversationToFavorites(@Header("Authorization") String authorization,
@Url String url);
// Url is: /api/{apiVersion}/room/{token}/favorites
@DELETE
Observable<GenericOverall> removeConversationFromFavorites(@Header("Authorization") String authorization,
@Url String url);
@GET @GET
Observable<NotificationOverall> getNcNotification(@Header("Authorization") String authorization, Observable<NotificationOverall> getNcNotification(@Header("Authorization") String authorization,
@Url String url); @Url String url);
@ -393,6 +389,12 @@ public interface NcApi {
@Url String url, @Url String url,
@Field("level") int level); @Field("level") int level);
@FormUrlEncoded
@PUT
Observable<GenericOverall> setConversationReadOnly(@Header("Authorization") String authorization,
@Url String url,
@Field("state") int state);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> createRemoteShare(@Nullable @Header("Authorization") String authorization, Observable<GenericOverall> createRemoteShare(@Nullable @Header("Authorization") String authorization,
@ -472,6 +474,9 @@ public interface NcApi {
@Url String url, @Url String url,
@Field("level") Integer level); @Field("level") Integer level);
@DELETE
Observable<GenericOverall> clearChatHistory(@Header("Authorization") String authorization, @Url String url);
@GET @GET
Observable<HoverCardOverall> hoverCard(@Header("Authorization") String authorization, @Url String url); Observable<HoverCardOverall> hoverCard(@Header("Authorization") String authorization, @Url String url);
@ -573,12 +578,6 @@ public interface NcApi {
Observable<PollOverall> closePoll(@Header("Authorization") String authorization, Observable<PollOverall> closePoll(@Header("Authorization") String authorization,
@Url String url); @Url String url);
@FormUrlEncoded
@POST
Observable<GenericOverall> setMessageExpiration(@Header("Authorization") String authorization,
@Url String url,
@Field("seconds") Integer seconds);
@GET @GET
Observable<OpenGraphOverall> getOpenGraph(@Header("Authorization") String authorization, Observable<OpenGraphOverall> getOpenGraph(@Header("Authorization") String authorization,
@Url String url, @Url String url,

View File

@ -119,6 +119,26 @@ interface NcApiCoroutines {
@DELETE @DELETE
suspend fun unarchiveConversation(@Header("Authorization") authorization: String, @Url url: String): GenericOverall suspend fun unarchiveConversation(@Header("Authorization") authorization: String, @Url url: String): GenericOverall
@POST
suspend fun addConversationToFavorites(
@Header("Authorization") authorization: String,
@Url url: String
): GenericOverall
@DELETE
suspend fun removeConversationFromFavorites(
@Header("Authorization") authorization: String,
@Url url: String
): GenericOverall
@FormUrlEncoded
@POST
suspend fun notificationCalls(
@Header("Authorization") authorization: String,
@Url url: String,
@Field("level") level: Int
): GenericOverall
@POST @POST
suspend fun setReadStatusPrivacy( suspend fun setReadStatusPrivacy(
@Header("Authorization") authorization: String, @Header("Authorization") authorization: String,
@ -143,4 +163,20 @@ interface NcApiCoroutines {
@Url url: String, @Url url: String,
@Field("state") state: Int @Field("state") state: Int
): GenericOverall ): GenericOverall
@FormUrlEncoded
@POST
suspend fun setNotificationLevel(
@Header("Authorization") authorization: String,
@Url url: String,
@Field("level") level: Int
): GenericOverall
@FormUrlEncoded
@POST
suspend fun setMessageExpiration(
@Header("Authorization") authorization: String,
@Url url: String,
@Field("seconds") seconds: Int
): GenericOverall
} }

View File

@ -835,7 +835,9 @@ class ConversationInfoActivity :
binding.lockConversation.setOnClickListener { binding.lockConversation.setOnClickListener {
val isLocked = binding.lockConversationSwitch.isChecked val isLocked = binding.lockConversationSwitch.isChecked
binding.lockConversationSwitch.isChecked = !isLocked binding.lockConversationSwitch.isChecked = !isLocked
databaseStorageModule!!.saveBoolean("lock_switch", !isLocked) lifecycleScope.launch {
databaseStorageModule!!.saveBoolean("lock_switch", !isLocked)
}
val state = if (isLocked) 0 else 1 val state = if (isLocked) 0 else 1
makeConversationReadOnly(conversationToken, state) makeConversationReadOnly(conversationToken, state)
} }
@ -1014,7 +1016,9 @@ class ConversationInfoActivity :
.setSimpleItems(resources.getStringArray(R.array.message_expiring_descriptions)) .setSimpleItems(resources.getStringArray(R.array.message_expiring_descriptions))
binding.conversationSettingsDropdown.setOnItemClickListener { _, _, position, _ -> binding.conversationSettingsDropdown.setOnItemClickListener { _, _, position, _ ->
val v: String = resources.getStringArray(R.array.message_expiring_values)[position] val v: String = resources.getStringArray(R.array.message_expiring_values)[position]
databaseStorageModule!!.saveString("conversation_settings_dropdown", v) lifecycleScope.launch {
databaseStorageModule!!.saveString("conversation_settings_dropdown", v)
}
} }
binding.messageExpirationSettings.visibility = VISIBLE binding.messageExpirationSettings.visibility = VISIBLE
} else { } else {
@ -1516,18 +1520,24 @@ class ConversationInfoActivity :
binding.notificationSettingsView.notificationSettingsImportantConversation.setOnClickListener { binding.notificationSettingsView.notificationSettingsImportantConversation.setOnClickListener {
val isChecked = binding.notificationSettingsView.importantConversationSwitch.isChecked val isChecked = binding.notificationSettingsView.importantConversationSwitch.isChecked
binding.notificationSettingsView.importantConversationSwitch.isChecked = !isChecked binding.notificationSettingsView.importantConversationSwitch.isChecked = !isChecked
module.saveBoolean("important_conversation_switch", !isChecked) lifecycleScope.launch {
module.saveBoolean("important_conversation_switch", !isChecked)
}
} }
binding.notificationSettingsView.notificationSettingsCallNotifications.setOnClickListener { binding.notificationSettingsView.notificationSettingsCallNotifications.setOnClickListener {
val isChecked = binding.notificationSettingsView.callNotificationsSwitch.isChecked val isChecked = binding.notificationSettingsView.callNotificationsSwitch.isChecked
binding.notificationSettingsView.callNotificationsSwitch.isChecked = !isChecked binding.notificationSettingsView.callNotificationsSwitch.isChecked = !isChecked
module.saveBoolean("call_notifications_switch", !isChecked) lifecycleScope.launch {
module.saveBoolean("call_notifications_switch", !isChecked)
}
} }
binding.notificationSettingsView.conversationInfoMessageNotificationsDropdown binding.notificationSettingsView.conversationInfoMessageNotificationsDropdown
.setOnItemClickListener { _, _, position, _ -> .setOnItemClickListener { _, _, position, _ ->
val value = resources.getStringArray(R.array.message_notification_levels_entry_values)[position] val value = resources.getStringArray(R.array.message_notification_levels_entry_values)[position]
Log.i(TAG, "saved $value to module from $position") Log.i(TAG, "saved $value to module from $position")
module.saveString("conversation_info_message_notifications_dropdown", value) lifecycleScope.launch {
module.saveString("conversation_info_message_notifications_dropdown", value)
}
} }
binding.notificationSettingsView.importantConversationSwitch.isChecked = module binding.notificationSettingsView.importantConversationSwitch.isChecked = module

View File

@ -6,11 +6,13 @@
*/ */
package com.nextcloud.talk.ui.dialog package com.nextcloud.talk.ui.dialog
import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import androidx.work.Data import androidx.work.Data
import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequest
import androidx.work.WorkInfo import androidx.work.WorkInfo
@ -21,6 +23,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.activities.MainActivity import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.api.NcApiCoroutines
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.conversation.RenameConversationDialogFragment import com.nextcloud.talk.conversation.RenameConversationDialogFragment
import com.nextcloud.talk.conversationlist.ConversationsListActivity import com.nextcloud.talk.conversationlist.ConversationsListActivity
@ -42,6 +45,9 @@ import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
@ -56,6 +62,9 @@ class ConversationsListBottomDialog(
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@Inject
lateinit var ncApiCoroutines: NcApiCoroutines
@Inject @Inject
lateinit var viewThemeUtils: ViewThemeUtils lateinit var viewThemeUtils: ViewThemeUtils
@ -193,84 +202,56 @@ class ConversationsListBottomDialog(
} }
} }
@SuppressLint("StringFormatInvalid", "TooGenericExceptionCaught")
private fun addConversationToFavorites() { private fun addConversationToFavorites() {
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
ncApi.addConversationToFavorites( val url = ApiUtils.getUrlForRoomFavorite(apiVersion, currentUser.baseUrl!!, conversation.token)
credentials, lifecycleScope.launch {
ApiUtils.getUrlForRoomFavorite( try {
apiVersion, withContext(Dispatchers.IO) {
currentUser.baseUrl!!, ncApiCoroutines.addConversationToFavorites(credentials, url)
conversation.token
)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retry(1)
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
} }
activity.fetchRooms()
override fun onNext(genericOverall: GenericOverall) { activity.showSnackbar(
activity.fetchRooms() String.format(
activity.showSnackbar( context.resources.getString(R.string.added_to_favorites),
String.format( conversation.displayName
context.resources.getString(R.string.added_to_favorites),
conversation.displayName
)
) )
dismiss() )
} dismiss()
} catch (e: Exception) {
override fun onError(e: Throwable) { withContext(Dispatchers.Main) {
activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry)) activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry))
dismiss() dismiss()
} }
}
override fun onComplete() { }
// unused atm
}
})
} }
@SuppressLint("StringFormatInvalid", "TooGenericExceptionCaught")
private fun removeConversationFromFavorites() { private fun removeConversationFromFavorites() {
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
ncApi.removeConversationFromFavorites( val url = ApiUtils.getUrlForRoomFavorite(apiVersion, currentUser.baseUrl!!, conversation.token)
credentials, lifecycleScope.launch {
ApiUtils.getUrlForRoomFavorite( try {
apiVersion, withContext(Dispatchers.IO) {
currentUser.baseUrl!!, ncApiCoroutines.removeConversationFromFavorites(credentials, url)
conversation.token
)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retry(1)
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
} }
activity.fetchRooms()
override fun onNext(genericOverall: GenericOverall) { activity.showSnackbar(
activity.fetchRooms() String.format(
activity.showSnackbar( context.resources.getString(R.string.removed_from_favorites),
String.format( conversation.displayName
context.resources.getString(R.string.removed_from_favorites),
conversation.displayName
)
) )
dismiss() )
} dismiss()
} catch (e: Exception) {
override fun onError(e: Throwable) { withContext(Dispatchers.Main) {
activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry)) activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry))
dismiss() dismiss()
} }
}
override fun onComplete() { }
// unused atm
}
})
} }
private fun markConversationAsUnread() { private fun markConversationAsUnread() {
@ -290,6 +271,7 @@ class ConversationsListBottomDialog(
// unused atm // unused atm
} }
@SuppressLint("StringFormatInvalid")
override fun onNext(genericOverall: GenericOverall) { override fun onNext(genericOverall: GenericOverall) {
activity.fetchRooms() activity.fetchRooms()
activity.showSnackbar( activity.showSnackbar(
@ -336,6 +318,7 @@ class ConversationsListBottomDialog(
// unused atm // unused atm
} }
@SuppressLint("StringFormatInvalid")
override fun onNext(genericOverall: GenericOverall) { override fun onNext(genericOverall: GenericOverall) {
activity.fetchRooms() activity.fetchRooms()
activity.showSnackbar( activity.showSnackbar(
@ -372,6 +355,7 @@ class ConversationsListBottomDialog(
} }
} }
@SuppressLint("StringFormatInvalid")
private fun leaveConversation() { private fun leaveConversation() {
val dataBuilder = Data.Builder() val dataBuilder = Data.Builder()
dataBuilder.putString(KEY_ROOM_TOKEN, conversation.token) dataBuilder.putString(KEY_ROOM_TOKEN, conversation.token)

View File

@ -1,242 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2022 Andy Scherzinger <info@andy-scherzinger.de>
* SPDX-FileCopyrightText: 2021 Tim Krüger <t@timkrueger.me>
* SPDX-FileCopyrightText: 2017-2018 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.utils.preferences.preferencestorage;
import android.text.TextUtils;
import android.util.Log;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager;
import com.nextcloud.talk.data.storage.model.ArbitraryStorage;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.models.json.generic.GenericOverall;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.SpreedFeatures;
import com.nextcloud.talk.utils.UserIdUtils;
import com.nextcloud.talk.utils.CapabilitiesUtil;
import javax.inject.Inject;
import autodagger.AutoInjector;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
@AutoInjector(NextcloudTalkApplication.class)
public class DatabaseStorageModule {
private static final String TAG = "DatabaseStorageModule";
@Inject
ArbitraryStorageManager arbitraryStorageManager;
@Inject
NcApi ncApi;
private int messageExpiration;
private final User conversationUser;
private final String conversationToken;
private final long accountIdentifier;
private boolean lobbyValue;
private String messageNotificationLevel;
public DatabaseStorageModule(User conversationUser, String conversationToken) {
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
this.conversationUser = conversationUser;
this.accountIdentifier = UserIdUtils.INSTANCE.getIdForUser(conversationUser);
this.conversationToken = conversationToken;
}
public void saveBoolean(String key, boolean value) {
if ("call_notifications_switch".equals(key)) {
int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{4});
ncApi.notificationCalls(ApiUtils.getCredentials(conversationUser.getUsername(),
conversationUser.getToken()),
ApiUtils.getUrlForRoomNotificationCalls(apiVersion,
conversationUser.getBaseUrl(),
conversationToken),
value ? 1 : 0)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<GenericOverall>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
// unused atm
}
@Override
public void onNext(@NonNull GenericOverall genericOverall) {
Log.d(TAG, "Toggled notification calls");
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "Error when trying to toggle notification calls", e);
}
@Override
public void onComplete() {
// unused atm
}
}
);
}
if (!"lobby_switch".equals(key)) {
arbitraryStorageManager.storeStorageSetting(accountIdentifier,
key,
Boolean.toString(value),
conversationToken);
} else {
lobbyValue = value;
}
}
public void saveString(String key, String value) {
if ("conversation_settings_dropdown".equals(key)) {
int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{4});
String trimmedValue = value.replace("expire_", "");
int valueInt = Integer.parseInt(trimmedValue);
ncApi.setMessageExpiration(
ApiUtils.getCredentials(
conversationUser.getUsername(),
conversationUser.getToken()),
ApiUtils.getUrlForMessageExpiration(
apiVersion,
conversationUser.getBaseUrl(),
conversationToken),
valueInt)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<GenericOverall>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
// unused atm
}
@Override
public void onNext(@NonNull GenericOverall genericOverall) {
messageExpiration = valueInt;
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "Error when trying to set message expiration", e);
}
@Override
public void onComplete() {
// unused atm
}
});
} else if ("conversation_info_message_notifications_dropdown".equals(key)) {
if (CapabilitiesUtil.hasSpreedFeatureCapability(
conversationUser.getCapabilities().getSpreedCapability(),
SpreedFeatures.NOTIFICATION_LEVELS)
) {
if (TextUtils.isEmpty(messageNotificationLevel) || !messageNotificationLevel.equals(value)) {
int intValue;
switch (value) {
case "never":
intValue = 3;
break;
case "mention":
intValue = 2;
break;
case "always":
intValue = 1;
break;
default:
intValue = 0;
}
int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{ApiUtils.API_V4, 1});
ncApi.setNotificationLevel(ApiUtils.getCredentials(conversationUser.getUsername(),
conversationUser.getToken()),
ApiUtils.getUrlForRoomNotificationLevel(apiVersion,
conversationUser.getBaseUrl(),
conversationToken),
intValue)
.subscribeOn(Schedulers.io())
.subscribe(new Observer<GenericOverall>() {
@Override
public void onSubscribe(Disposable d) {
// unused atm
}
@Override
public void onNext(GenericOverall genericOverall) {messageNotificationLevel = value;}
@Override
public void onError(Throwable e) {
// unused atm
}
@Override
public void onComplete() {
// unused atm
}
});
} else {
messageNotificationLevel = value;
}
}
} else {
arbitraryStorageManager.storeStorageSetting(accountIdentifier, key, value, conversationToken);
}
}
public boolean getBoolean(String key, boolean defaultVal) {
if ("lobby_switch".equals(key)) {
return lobbyValue;
} else {
return arbitraryStorageManager
.getStorageSetting(accountIdentifier, key, conversationToken)
.map(arbitraryStorage -> Boolean.parseBoolean(arbitraryStorage.getValue()))
.blockingGet(defaultVal);
}
}
public String getString(String key, String defaultVal) {
if ("conversation_settings_dropdown".equals(key)) {
switch (messageExpiration) {
case 2419200:
return "expire_2419200";
case 604800:
return "expire_604800";
case 86400:
return "expire_86400";
case 28800:
return "expire_28800";
case 3600:
return "expire_3600";
default:
return "expire_0";
}
} else if ("conversation_info_message_notifications_dropdown".equals(key)) {
return messageNotificationLevel;
} else {
return arbitraryStorageManager
.getStorageSetting(accountIdentifier, key, conversationToken)
.map(ArbitraryStorage::getValue)
.blockingGet(defaultVal);
}
}
public void setMessageExpiration(int messageExpiration) {
this.messageExpiration = messageExpiration;
}
}

View File

@ -0,0 +1,210 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2022 Andy Scherzinger <info@andy-scherzinger.de>
* SPDX-FileCopyrightText: 2021 Tim Krüger <t@timkrueger.me>
* SPDX-FileCopyrightText: 2017-2018 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.utils.preferences.preferencestorage
import android.annotation.SuppressLint
import android.text.TextUtils
import android.util.Log
import autodagger.AutoInjector
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.api.NcApiCoroutines
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager
import com.nextcloud.talk.data.storage.model.ArbitraryStorage
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ApiUtils.getConversationApiVersion
import com.nextcloud.talk.utils.ApiUtils.getCredentials
import com.nextcloud.talk.utils.ApiUtils.getUrlForMessageExpiration
import com.nextcloud.talk.utils.ApiUtils.getUrlForRoomNotificationCalls
import com.nextcloud.talk.utils.ApiUtils.getUrlForRoomNotificationLevel
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
import com.nextcloud.talk.utils.SpreedFeatures
import com.nextcloud.talk.utils.UserIdUtils.getIdForUser
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class DatabaseStorageModule(conversationUser: User, conversationToken: String) {
@JvmField
@Inject
var arbitraryStorageManager: ArbitraryStorageManager? = null
@JvmField
@Inject
var ncApi: NcApi? = null
@JvmField
@Inject
var ncApiCoroutines: NcApiCoroutines? = null
private var messageExpiration = 0
private val conversationUser: User
private val conversationToken: String
private val accountIdentifier: Long
private var lobbyValue = false
private var messageNotificationLevel: String? = null
init {
sharedApplication!!.componentApplication.inject(this)
this.conversationUser = conversationUser
this.accountIdentifier = getIdForUser(conversationUser)
this.conversationToken = conversationToken
}
@SuppressLint("TooGenericExceptionCaught")
suspend fun saveBoolean(key: String, value: Boolean) {
if ("call_notifications_switch" == key) {
val apiVersion = getConversationApiVersion(conversationUser, intArrayOf(4))
val url = getUrlForRoomNotificationCalls(apiVersion, conversationUser.baseUrl, conversationToken)
val credentials = getCredentials(conversationUser.username, conversationUser.token)
val notificationLevel = if (value) 1 else 0
withContext(Dispatchers.IO) {
try {
ncApiCoroutines!!.notificationCalls(credentials!!, url, notificationLevel)
Log.d(TAG, "Toggled notification calls")
} catch (e: Exception) {
Log.e(TAG, "Error when trying to toggle notification calls", e)
}
}
}
if ("lobby_switch" != key) {
arbitraryStorageManager!!.storeStorageSetting(
accountIdentifier,
key,
value.toString(),
conversationToken
)
} else {
lobbyValue = value
}
}
@SuppressLint("TooGenericExceptionCaught")
suspend fun saveString(key: String, value: String) {
when (key) {
"conversation_settings_dropdown" -> {
try {
val apiVersion = getConversationApiVersion(conversationUser, intArrayOf(API_VERSION_4))
val trimmedValue = value.replace("expire_", "")
val valueInt = trimmedValue.toInt()
withContext(Dispatchers.IO) {
ncApiCoroutines!!.setMessageExpiration(
getCredentials(conversationUser.username, conversationUser.token)!!,
getUrlForMessageExpiration(
apiVersion,
conversationUser.baseUrl,
conversationToken
),
valueInt
)
messageExpiration = valueInt
}
} catch (exception: Exception) {
Log.e(TAG, "Error when trying to set message expiration", exception)
}
}
"conversation_info_message_notifications_dropdown" -> {
try {
if (hasSpreedFeatureCapability(
conversationUser.capabilities!!.spreedCapability!!,
SpreedFeatures.NOTIFICATION_LEVELS
)
) {
if (TextUtils.isEmpty(messageNotificationLevel) || messageNotificationLevel != value) {
val intValue = when (value) {
"never" -> NOTIFICATION_NEVER
"mention" -> NOTIFICATION_MENTION
"always" -> NOTIFICATION_ALWAYS
else -> 0
}
val apiVersion = getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
withContext(Dispatchers.IO) {
ncApiCoroutines!!.setNotificationLevel(
getCredentials(
conversationUser.username,
conversationUser.token
)!!,
getUrlForRoomNotificationLevel(
apiVersion,
conversationUser.baseUrl,
conversationToken
),
intValue
)
messageNotificationLevel = value
}
} else {
messageNotificationLevel = value
}
}
} catch (exception: Exception) {
Log.e(TAG, "Error trying to set notification level", exception)
}
}
else -> {
arbitraryStorageManager!!.storeStorageSetting(accountIdentifier, key, value, conversationToken)
}
}
}
fun getBoolean(key: String, defaultVal: Boolean): Boolean {
return if ("lobby_switch" == key) {
lobbyValue
} else {
arbitraryStorageManager!!
.getStorageSetting(accountIdentifier, key, conversationToken)
.map { arbitraryStorage: ArbitraryStorage -> arbitraryStorage.value.toBoolean() }
.blockingGet(defaultVal)
}
}
fun getString(key: String, defaultVal: String): String? {
return if ("conversation_settings_dropdown" == key) {
when (messageExpiration) {
EXPIRE_4_WEEKS -> "expire_2419200"
EXPIRE_7_DAYS -> "expire_604800"
EXPIRE_1_DAY -> "expire_86400"
EXPIRE_8_HOURS -> "expire_28800"
EXPIRE_1_HOUR -> "expire_3600"
else -> "expire_0"
}
} else if ("conversation_info_message_notifications_dropdown" == key) {
messageNotificationLevel
} else {
arbitraryStorageManager!!
.getStorageSetting(accountIdentifier, key, conversationToken)
.map(ArbitraryStorage::value)
.blockingGet(defaultVal)
}
}
fun setMessageExpiration(messageExpiration: Int) {
this.messageExpiration = messageExpiration
}
companion object {
private const val TAG = "DatabaseStorageModule"
private const val EXPIRE_1_HOUR = 3600
private const val EXPIRE_8_HOURS = 28800
private const val EXPIRE_1_DAY = 86400
private const val EXPIRE_7_DAYS = 604800
private const val EXPIRE_4_WEEKS = 2419200
private const val NOTIFICATION_NEVER = 3
private const val NOTIFICATION_MENTION = 2
private const val NOTIFICATION_ALWAYS = 1
private const val API_VERSION_4 = 4
}
}