mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-21 12:35:30 +03:00
pass spreedCapabilities instead user to CapabilitiesUtil
To support federated rooms, capabilities have to be checked from the room which now also has capabilities. If room is not federated, capabilities fromuser are still checked. This is why CapabilitiesUtil had to be refactored to accept SpreedCapabilities which can come from room or user. Other than that, many other changes were made as a result of this change. Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
513127e481
commit
754b825096
101 changed files with 2115 additions and 1556 deletions
|
@ -199,7 +199,7 @@ class AccountVerificationActivity : BaseActivity() {
|
|||
val credentials = ApiUtils.getCredentials(username, token)
|
||||
cookieManager.cookieStore.removeAll()
|
||||
|
||||
ncApi.getCapabilities(credentials, ApiUtils.getUrlForCapabilities(baseUrl))
|
||||
ncApi.getCapabilities(credentials, ApiUtils.getUrlForCapabilities(baseUrl!!))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : Observer<CapabilitiesOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
|
@ -213,7 +213,7 @@ class AccountVerificationActivity : BaseActivity() {
|
|||
capabilitiesOverall.ocs!!.data!!.capabilities!!.spreedCapability!!.features != null &&
|
||||
!capabilitiesOverall.ocs!!.data!!.capabilities!!.spreedCapability!!.features!!.isEmpty()
|
||||
if (hasTalk) {
|
||||
fetchProfile(credentials, capabilitiesOverall)
|
||||
fetchProfile(credentials!!, capabilitiesOverall)
|
||||
} else {
|
||||
if (resources != null) {
|
||||
runOnUiThread {
|
||||
|
@ -305,7 +305,7 @@ class AccountVerificationActivity : BaseActivity() {
|
|||
private fun fetchProfile(credentials: String, capabilitiesOverall: CapabilitiesOverall) {
|
||||
ncApi.getUserProfile(
|
||||
credentials,
|
||||
ApiUtils.getUrlForUserProfile(baseUrl)
|
||||
ApiUtils.getUrlForUserProfile(baseUrl!!)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : Observer<UserProfileOverall> {
|
||||
|
|
|
@ -52,7 +52,7 @@ import com.nextcloud.talk.utils.UriUtils
|
|||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.ADD_ADDITIONAL_ACCOUNT
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
|
@ -336,7 +336,7 @@ class ServerSelectionActivity : BaseActivity() {
|
|||
|
||||
if (hasTalk) {
|
||||
runOnUiThread {
|
||||
if (CapabilitiesUtilNew.isServerEOL(capabilities)) {
|
||||
if (CapabilitiesUtil.isServerEOL(capabilitiesOverall.ocs?.data?.serverVersion?.major!!)) {
|
||||
if (resources != null) {
|
||||
runOnUiThread {
|
||||
setErrorText(resources!!.getString(R.string.nc_settings_server_eol))
|
||||
|
|
|
@ -110,6 +110,7 @@ import com.nextcloud.talk.ui.dialog.AudioOutputDialog
|
|||
import com.nextcloud.talk.ui.dialog.MoreCallActionsDialog
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.NotificationUtils.cancelExistingNotificationsForRoom
|
||||
import com.nextcloud.talk.utils.NotificationUtils.getCallRingtoneUri
|
||||
|
@ -131,9 +132,9 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
|||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_START_CALL_AFTER_ROOM_SWITCH
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SWITCH_TO_ROOM
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isCallRecordingAvailable
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.isCallRecordingAvailable
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
||||
import com.nextcloud.talk.utils.power.PowerManagerUtils
|
||||
|
@ -234,7 +235,7 @@ class CallActivity : CallBaseActivity() {
|
|||
private var iceServers: MutableList<PeerConnection.IceServer>? = null
|
||||
private var cameraEnumerator: CameraEnumerator? = null
|
||||
private var roomToken: String? = null
|
||||
var conversationUser: User? = null
|
||||
lateinit var conversationUser: User
|
||||
private var conversationName: String? = null
|
||||
private var callSession: String? = null
|
||||
private var localStream: MediaStream? = null
|
||||
|
@ -530,13 +531,13 @@ class CallActivity : CallBaseActivity() {
|
|||
)
|
||||
}
|
||||
|
||||
when (CapabilitiesUtilNew.getRecordingConsentType(conversationUser)) {
|
||||
CapabilitiesUtilNew.RECORDING_CONSENT_NOT_REQUIRED -> initiateCall()
|
||||
CapabilitiesUtilNew.RECORDING_CONSENT_REQUIRED -> askForRecordingConsent()
|
||||
CapabilitiesUtilNew.RECORDING_CONSENT_DEPEND_ON_CONVERSATION -> {
|
||||
when (CapabilitiesUtil.getRecordingConsentType(conversationUser!!.capabilities!!.spreedCapability!!)) {
|
||||
CapabilitiesUtil.RECORDING_CONSENT_NOT_REQUIRED -> initiateCall()
|
||||
CapabilitiesUtil.RECORDING_CONSENT_REQUIRED -> askForRecordingConsent()
|
||||
CapabilitiesUtil.RECORDING_CONSENT_DEPEND_ON_CONVERSATION -> {
|
||||
val getRoomApiVersion = ApiUtils.getConversationApiVersion(
|
||||
conversationUser,
|
||||
intArrayOf(ApiUtils.APIv4, 1)
|
||||
conversationUser!!,
|
||||
intArrayOf(ApiUtils.API_V4, 1)
|
||||
)
|
||||
ncApi!!.getRoom(credentials, ApiUtils.getUrlForRoom(getRoomApiVersion, baseUrl, roomToken))
|
||||
.retry(API_RETRIES)
|
||||
|
@ -571,7 +572,10 @@ class CallActivity : CallBaseActivity() {
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (hasSpreedFeatureCapability(conversationUser, "recording-v1") &&
|
||||
if (hasSpreedFeatureCapability(
|
||||
conversationUser.capabilities!!.spreedCapability!!,
|
||||
SpreedFeatures.RECORDING_V1
|
||||
) &&
|
||||
othersInCall &&
|
||||
elapsedSeconds.toInt() >= CALL_TIME_ONE_HOUR
|
||||
) {
|
||||
|
@ -1468,7 +1472,7 @@ class CallActivity : CallBaseActivity() {
|
|||
|
||||
private fun fetchSignalingSettings() {
|
||||
Log.d(TAG, "fetchSignalingSettings")
|
||||
val apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, intArrayOf(ApiUtils.APIv3, 2, 1))
|
||||
val apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, intArrayOf(ApiUtils.API_V3, 2, 1))
|
||||
ncApi!!.getSignalingSettings(credentials, ApiUtils.getUrlForSignalingSettings(apiVersion, baseUrl))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.retry(API_RETRIES)
|
||||
|
@ -1531,7 +1535,7 @@ class CallActivity : CallBaseActivity() {
|
|||
private fun addIceServers(signalingSettingsOverall: SignalingSettingsOverall, apiVersion: Int) {
|
||||
if (signalingSettingsOverall.ocs!!.settings!!.stunServers != null) {
|
||||
val stunServers = signalingSettingsOverall.ocs!!.settings!!.stunServers
|
||||
if (apiVersion == ApiUtils.APIv3) {
|
||||
if (apiVersion == ApiUtils.API_V3) {
|
||||
for ((_, urls) in stunServers!!) {
|
||||
if (urls != null) {
|
||||
for (url in urls) {
|
||||
|
@ -1564,7 +1568,7 @@ class CallActivity : CallBaseActivity() {
|
|||
}
|
||||
|
||||
private fun checkCapabilities() {
|
||||
ncApi!!.getCapabilities(credentials, ApiUtils.getUrlForCapabilities(baseUrl))
|
||||
ncApi!!.getCapabilities(credentials, ApiUtils.getUrlForCapabilities(baseUrl!!))
|
||||
.retry(API_RETRIES)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -1600,7 +1604,7 @@ class CallActivity : CallBaseActivity() {
|
|||
|
||||
private fun joinRoomAndCall() {
|
||||
callSession = ApplicationWideCurrentRoomHolder.getInstance().session
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||
Log.d(TAG, "joinRoomAndCall")
|
||||
Log.d(TAG, " baseUrl= $baseUrl")
|
||||
Log.d(TAG, " roomToken= $roomToken")
|
||||
|
@ -1656,7 +1660,7 @@ class CallActivity : CallBaseActivity() {
|
|||
fun getRoomAndContinue() {
|
||||
val getRoomApiVersion = ApiUtils.getConversationApiVersion(
|
||||
conversationUser,
|
||||
intArrayOf(ApiUtils.APIv4, 1)
|
||||
intArrayOf(ApiUtils.API_V4, 1)
|
||||
)
|
||||
ncApi!!.getRoom(credentials, ApiUtils.getUrlForRoom(getRoomApiVersion, baseUrl, roomToken))
|
||||
.retry(API_RETRIES)
|
||||
|
@ -1715,10 +1719,10 @@ class CallActivity : CallBaseActivity() {
|
|||
callParticipantList = CallParticipantList(signalingMessageReceiver)
|
||||
callParticipantList!!.addObserver(callParticipantListObserver)
|
||||
|
||||
val apiVersion = ApiUtils.getCallApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion = ApiUtils.getCallApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||
ncApi!!.joinCall(
|
||||
credentials,
|
||||
ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken),
|
||||
ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken!!),
|
||||
inCallFlag,
|
||||
isCallWithoutNotification,
|
||||
recordingConsentGiven
|
||||
|
@ -1756,7 +1760,10 @@ class CallActivity : CallBaseActivity() {
|
|||
}
|
||||
|
||||
private fun startCallTimeCounter(callStartTime: Long?) {
|
||||
if (callStartTime != null && hasSpreedFeatureCapability(conversationUser, "recording-v1")) {
|
||||
if (callStartTime != null && hasSpreedFeatureCapability(
|
||||
conversationUser!!.capabilities!!.spreedCapability!!, SpreedFeatures.RECORDING_V1
|
||||
)
|
||||
) {
|
||||
binding!!.callDuration.visibility = View.VISIBLE
|
||||
val currentTimeInSec = System.currentTimeMillis() / SECOND_IN_MILLIES
|
||||
elapsedSeconds = currentTimeInSec - callStartTime
|
||||
|
@ -1793,7 +1800,7 @@ class CallActivity : CallBaseActivity() {
|
|||
}
|
||||
|
||||
private fun pullSignalingMessages() {
|
||||
val signalingApiVersion = ApiUtils.getSignalingApiVersion(conversationUser, intArrayOf(ApiUtils.APIv3, 2, 1))
|
||||
val signalingApiVersion = ApiUtils.getSignalingApiVersion(conversationUser, intArrayOf(ApiUtils.API_V3, 2, 1))
|
||||
val delayOnError = AtomicInteger(0)
|
||||
|
||||
ncApi!!.pullSignalingMessages(
|
||||
|
@ -1801,7 +1808,7 @@ class CallActivity : CallBaseActivity() {
|
|||
ApiUtils.getUrlForSignaling(
|
||||
signalingApiVersion,
|
||||
baseUrl,
|
||||
roomToken
|
||||
roomToken!!
|
||||
)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
@ -2031,12 +2038,12 @@ class CallActivity : CallBaseActivity() {
|
|||
|
||||
private fun hangupNetworkCalls(shutDownView: Boolean) {
|
||||
Log.d(TAG, "hangupNetworkCalls. shutDownView=$shutDownView")
|
||||
val apiVersion = ApiUtils.getCallApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion = ApiUtils.getCallApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||
if (callParticipantList != null) {
|
||||
callParticipantList!!.removeObserver(callParticipantListObserver)
|
||||
callParticipantList!!.destroy()
|
||||
}
|
||||
ncApi!!.leaveCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken))
|
||||
ncApi!!.leaveCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken!!))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<GenericOverall> {
|
||||
|
@ -2919,10 +2926,10 @@ class CallActivity : CallBaseActivity() {
|
|||
val strings: MutableList<String> = ArrayList()
|
||||
val stringToSend = stringBuilder.toString()
|
||||
strings.add(stringToSend)
|
||||
val apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, intArrayOf(ApiUtils.APIv3, 2, 1))
|
||||
val apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, intArrayOf(ApiUtils.API_V3, 2, 1))
|
||||
ncApi!!.sendSignalingMessages(
|
||||
credentials,
|
||||
ApiUtils.getUrlForSignaling(apiVersion, baseUrl, roomToken),
|
||||
ApiUtils.getUrlForSignaling(apiVersion, baseUrl, roomToken!!),
|
||||
strings.toString()
|
||||
)
|
||||
.retry(API_RETRIES)
|
||||
|
@ -3099,12 +3106,14 @@ class CallActivity : CallBaseActivity() {
|
|||
|
||||
val isAllowedToStartOrStopRecording: Boolean
|
||||
get() = (
|
||||
isCallRecordingAvailable(conversationUser!!) &&
|
||||
isCallRecordingAvailable(conversationUser!!.capabilities!!.spreedCapability!!) &&
|
||||
isModerator
|
||||
)
|
||||
val isAllowedToRaiseHand: Boolean
|
||||
get() = hasSpreedFeatureCapability(conversationUser, "raise-hand") ||
|
||||
isBreakoutRoom
|
||||
get() = hasSpreedFeatureCapability(
|
||||
conversationUser.capabilities!!.spreedCapability!!,
|
||||
SpreedFeatures.RAISE_HAND
|
||||
) || isBreakoutRoom
|
||||
|
||||
private inner class SelfVideoTouchListener : OnTouchListener {
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
|
|
|
@ -181,7 +181,7 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||
val user = userId.substringBeforeLast("@")
|
||||
val baseUrl = userId.substringAfterLast("@")
|
||||
|
||||
if (userManager.currentUser.blockingGet()?.baseUrl?.endsWith(baseUrl) == true) {
|
||||
if (userManager.currentUser.blockingGet()?.baseUrl!!.endsWith(baseUrl) == true) {
|
||||
startConversation(user)
|
||||
} else {
|
||||
Snackbar.make(
|
||||
|
@ -200,11 +200,11 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||
|
||||
val currentUser = userManager.currentUser.blockingGet()
|
||||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||
val credentials = ApiUtils.getCredentials(currentUser?.username, currentUser?.token)
|
||||
val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
currentUser?.baseUrl,
|
||||
currentUser?.baseUrl!!,
|
||||
roomType,
|
||||
null,
|
||||
userId,
|
||||
|
|
|
@ -50,9 +50,10 @@ import com.nextcloud.talk.models.json.conversations.Conversation
|
|||
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType
|
||||
import com.nextcloud.talk.ui.StatusDrawable
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.ConversationUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFilterable
|
||||
|
@ -312,7 +313,7 @@ class ConversationItem(
|
|||
if (model.type === ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
|
||||
viewThemeUtils.material.colorChipBackground(holder.binding.dialogUnreadBubble)
|
||||
} else if (model.unreadMention) {
|
||||
if (hasSpreedFeatureCapability(user, "direct-mention-flag")) {
|
||||
if (hasSpreedFeatureCapability(user.capabilities?.spreedCapability!!, SpreedFeatures.DIRECT_MENTION_FLAG)) {
|
||||
if (model.unreadMentionDirect!!) {
|
||||
viewThemeUtils.material.colorChipBackground(holder.binding.dialogUnreadBubble)
|
||||
} else {
|
||||
|
|
|
@ -77,12 +77,12 @@ class CallStartedViewHolder(incomingView: View, payload: Any) :
|
|||
val user = userManager.currentUser.blockingGet()
|
||||
val url: String = if (message.actorType == "guests" || message.actorType == "guest") {
|
||||
ApiUtils.getUrlForGuestAvatar(
|
||||
user!!.baseUrl,
|
||||
user!!.baseUrl!!,
|
||||
message.actorDisplayName,
|
||||
true
|
||||
)
|
||||
} else {
|
||||
ApiUtils.getUrlForAvatar(user!!.baseUrl, message.actorDisplayName, false)
|
||||
ApiUtils.getUrlForAvatar(user!!.baseUrl!!, message.actorDisplayName, false)
|
||||
}
|
||||
|
||||
val imageRequest: ImageRequest = ImageRequest.Builder(context)
|
||||
|
|
|
@ -188,7 +188,7 @@ class IncomingLinkPreviewMessageViewHolder(incomingView: View, payload: Any) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -172,7 +172,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -195,7 +195,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -197,7 +197,7 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -301,7 +301,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -45,8 +45,8 @@ class LinkPreview {
|
|||
binding.referenceThumbImage.setImageDrawable(null)
|
||||
|
||||
if (!message.extractedUrlToPreview.isNullOrEmpty()) {
|
||||
val credentials: String = ApiUtils.getCredentials(message.activeUser?.username, message.activeUser?.token)
|
||||
val openGraphLink = ApiUtils.getUrlForOpenGraph(message.activeUser?.baseUrl)
|
||||
val credentials: String = ApiUtils.getCredentials(message.activeUser?.username, message.activeUser?.token)!!
|
||||
val openGraphLink = ApiUtils.getUrlForOpenGraph(message.activeUser?.baseUrl!!)
|
||||
ncApi.getOpenGraph(
|
||||
credentials,
|
||||
openGraphLink,
|
||||
|
|
|
@ -161,7 +161,7 @@ class OutcomingLinkPreviewMessageViewHolder(outcomingView: View, payload: Any) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -213,7 +213,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -175,7 +175,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -170,7 +170,7 @@ class OutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewH
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -285,7 +285,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) :
|
|||
binding.messageQuote.quotedMessageImage.load(it) {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
|
||||
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
|
||||
)
|
||||
}
|
||||
} ?: run {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package com.nextcloud.talk.api;
|
||||
|
||||
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall;
|
||||
import com.nextcloud.talk.models.json.capabilities.RoomCapabilitiesOverall;
|
||||
import com.nextcloud.talk.models.json.chat.ChatOverall;
|
||||
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage;
|
||||
import com.nextcloud.talk.models.json.chat.ChatShareOverall;
|
||||
|
@ -367,6 +368,10 @@ public interface NcApi {
|
|||
@GET
|
||||
Observable<CapabilitiesOverall> getCapabilities(@Url String url);
|
||||
|
||||
@GET
|
||||
Observable<RoomCapabilitiesOverall> getRoomCapabilities(@Header("Authorization") String authorization,
|
||||
@Url String url);
|
||||
|
||||
/*
|
||||
QueryMap items are as follows:
|
||||
- "lookIntoFuture": int (0 or 1),
|
||||
|
|
|
@ -50,6 +50,7 @@ import com.nextcloud.talk.models.domain.ConversationType
|
|||
import com.nextcloud.talk.models.json.participants.Participant
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.ConversationUtils
|
||||
import com.nextcloud.talk.utils.NotificationUtils
|
||||
import com.nextcloud.talk.utils.ParticipantPermissions
|
||||
|
@ -57,7 +58,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys
|
|||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_VOICE_ONLY
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
|
||||
import io.reactivex.disposables.Disposable
|
||||
import okhttp3.Cache
|
||||
import java.io.IOException
|
||||
|
@ -148,10 +149,10 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
|
||||
private fun initObservers() {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||
userBeingCalled,
|
||||
userBeingCalled!!,
|
||||
intArrayOf(
|
||||
ApiUtils.APIv4,
|
||||
ApiUtils.APIv3,
|
||||
ApiUtils.API_V4,
|
||||
ApiUtils.API_V3,
|
||||
1
|
||||
)
|
||||
)
|
||||
|
@ -186,10 +187,10 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
|
||||
showAnswerControls()
|
||||
|
||||
if (apiVersion >= ApiUtils.APIv3) {
|
||||
if (apiVersion >= ApiUtils.API_V3) {
|
||||
val hasCallFlags = hasSpreedFeatureCapability(
|
||||
userBeingCalled,
|
||||
"conversation-call-flags"
|
||||
userBeingCalled?.capabilities?.spreedCapability!!,
|
||||
SpreedFeatures.CONVERSATION_CALL_FLAGS
|
||||
)
|
||||
if (hasCallFlags) {
|
||||
if (isInCallWithVideo(currentConversation!!.callFlag)) {
|
||||
|
@ -243,7 +244,7 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
originalBundle!!.putString(KEY_CONVERSATION_NAME, currentConversation!!.displayName)
|
||||
|
||||
val participantPermission = ParticipantPermissions(
|
||||
userBeingCalled!!,
|
||||
userBeingCalled!!.capabilities!!.spreedCapability!!,
|
||||
currentConversation!!
|
||||
)
|
||||
originalBundle!!.putBoolean(
|
||||
|
|
|
@ -167,6 +167,7 @@ import com.nextcloud.talk.models.domain.ConversationReadOnlyState
|
|||
import com.nextcloud.talk.models.domain.ConversationType
|
||||
import com.nextcloud.talk.models.domain.LobbyState
|
||||
import com.nextcloud.talk.models.domain.ObjectType
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||
import com.nextcloud.talk.models.json.chat.ChatOverall
|
||||
import com.nextcloud.talk.models.json.chat.ReadStatus
|
||||
|
@ -192,6 +193,7 @@ import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions
|
|||
import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.AudioUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.ContactUtils
|
||||
import com.nextcloud.talk.utils.ConversationUtils
|
||||
import com.nextcloud.talk.utils.DateConstants
|
||||
|
@ -218,7 +220,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
|||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_START_CALL_AFTER_ROOM_SWITCH
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SWITCH_TO_ROOM
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
||||
import com.nextcloud.talk.utils.rx.DisposableSet
|
||||
|
@ -301,6 +303,8 @@ class ChatActivity :
|
|||
var sessionIdAfterRoomJoined: String? = null
|
||||
lateinit var roomToken: String
|
||||
var conversationUser: User? = null
|
||||
lateinit var spreedCapabilities: SpreedCapability
|
||||
var chatApiVersion: Int = 1
|
||||
private var roomPassword: String = ""
|
||||
var credentials: String? = null
|
||||
var currentConversation: ConversationModel? = null
|
||||
|
@ -351,6 +355,7 @@ class ChatActivity :
|
|||
RELEASED,
|
||||
ERROR
|
||||
}
|
||||
|
||||
private val editableBehaviorSubject = BehaviorSubject.createDefault(false)
|
||||
private val editedTextBehaviorSubject = BehaviorSubject.createDefault("")
|
||||
|
||||
|
@ -541,14 +546,6 @@ class ChatActivity :
|
|||
}
|
||||
this.lifecycle.addObserver(AudioUtils)
|
||||
this.lifecycle.addObserver(ChatViewModel.LifeCycleObserver)
|
||||
|
||||
chatViewModel.refreshChatParams(
|
||||
setupFieldsForPullChatMessages(
|
||||
false,
|
||||
0,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
|
@ -587,6 +584,30 @@ class ChatActivity :
|
|||
is ChatViewModel.GetRoomSuccessState -> {
|
||||
currentConversation = state.conversationModel
|
||||
logConversationInfos("GetRoomSuccessState")
|
||||
chatViewModel.getCapabilities(conversationUser!!, roomToken, currentConversation!!)
|
||||
}
|
||||
|
||||
is ChatViewModel.GetRoomErrorState -> {
|
||||
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
chatViewModel.getCapabilitiesViewState.observe(this) { state ->
|
||||
when (state) {
|
||||
is ChatViewModel.GetCapabilitiesSuccessState -> {
|
||||
spreedCapabilities = state.spreedCapabilities
|
||||
chatApiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
|
||||
|
||||
initMessageInputView()
|
||||
|
||||
if (conversationUser?.userId != "?" &&
|
||||
CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.MENTION_FLAG)
|
||||
) {
|
||||
binding.chatToolbar.setOnClickListener { v -> showConversationInfoScreen() }
|
||||
}
|
||||
|
||||
if (adapter == null) {
|
||||
initAdapter()
|
||||
|
@ -597,7 +618,7 @@ class ChatActivity :
|
|||
|
||||
loadAvatarForStatusBar()
|
||||
setActionBarTitle()
|
||||
participantPermissions = ParticipantPermissions(conversationUser!!, currentConversation!!)
|
||||
participantPermissions = ParticipantPermissions(spreedCapabilities, currentConversation!!)
|
||||
|
||||
setupSwipeToReply()
|
||||
setupMentionAutocomplete()
|
||||
|
@ -626,9 +647,17 @@ class ChatActivity :
|
|||
},
|
||||
delayForRecursiveCall
|
||||
)
|
||||
|
||||
chatViewModel.refreshChatParams(
|
||||
setupFieldsForPullChatMessages(
|
||||
false,
|
||||
0,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is ChatViewModel.GetRoomErrorState -> {
|
||||
is ChatViewModel.GetCapabilitiesErrorState -> {
|
||||
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
|
@ -716,6 +745,7 @@ class ChatActivity :
|
|||
}
|
||||
binding.messagesListView.smoothScrollToPosition(0)
|
||||
}
|
||||
|
||||
is ChatViewModel.SendChatMessageErrorState -> {
|
||||
if (state.e is HttpException) {
|
||||
val code = state.e.code()
|
||||
|
@ -730,6 +760,7 @@ class ChatActivity :
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -753,9 +784,11 @@ class ChatActivity :
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
is ChatViewModel.DeleteChatMessageErrorState -> {
|
||||
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -774,24 +807,22 @@ class ChatActivity :
|
|||
startActivity(chatIntent)
|
||||
}
|
||||
}
|
||||
|
||||
is ChatViewModel.CreateRoomErrorState -> {
|
||||
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
var apiVersion = 1
|
||||
// FIXME this is a best guess, guests would need to get the capabilities themselves
|
||||
if (conversationUser != null) {
|
||||
apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
||||
}
|
||||
|
||||
chatViewModel.getFieldMapForChat.observe(this) { _ ->
|
||||
chatViewModel.pullChatMessages(
|
||||
credentials!!,
|
||||
ApiUtils.getUrlForChat(apiVersion, conversationUser?.baseUrl, roomToken)
|
||||
)
|
||||
chatViewModel.getFieldMapForChat.observe(this) { fieldMap ->
|
||||
if (fieldMap.isNotEmpty()) {
|
||||
chatViewModel.pullChatMessages(
|
||||
credentials!!,
|
||||
ApiUtils.getUrlForChat(chatApiVersion, conversationUser?.baseUrl, roomToken)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
chatViewModel.pullChatMessageViewState.observe(this) { state ->
|
||||
|
@ -865,6 +896,7 @@ class ChatActivity :
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
HTTP_CODE_NOT_MODIFIED -> {
|
||||
processHeaderChatLastGiven(state.response, state.lookIntoFuture)
|
||||
chatViewModel.refreshChatParams(
|
||||
|
@ -875,6 +907,7 @@ class ChatActivity :
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
HTTP_CODE_PRECONDITION_FAILED -> {
|
||||
processHeaderChatLastGiven(state.response, state.lookIntoFuture)
|
||||
chatViewModel.refreshChatParams(
|
||||
|
@ -885,6 +918,7 @@ class ChatActivity :
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
|
||||
|
@ -898,12 +932,15 @@ class ChatActivity :
|
|||
collapseSystemMessages()
|
||||
}
|
||||
}
|
||||
|
||||
is ChatViewModel.PullChatMessageCompleteState -> {
|
||||
Log.d(TAG, "PullChatMessageCompleted")
|
||||
}
|
||||
|
||||
is ChatViewModel.PullChatMessageErrorState -> {
|
||||
Log.d(TAG, "PullChatMessageError")
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -916,6 +953,7 @@ class ChatActivity :
|
|||
state.reactionDeletedModel.emoji
|
||||
)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -928,6 +966,7 @@ class ChatActivity :
|
|||
state.reactionAddedModel.emoji
|
||||
)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -943,6 +982,7 @@ class ChatActivity :
|
|||
Snackbar.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
|
||||
HTTP_FORBIDDEN -> {
|
||||
Snackbar.make(
|
||||
binding.root,
|
||||
|
@ -950,6 +990,7 @@ class ChatActivity :
|
|||
Snackbar.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
|
||||
HTTP_NOT_FOUND -> {
|
||||
Snackbar.make(
|
||||
binding.root,
|
||||
|
@ -960,9 +1001,11 @@ class ChatActivity :
|
|||
}
|
||||
clearEditUI()
|
||||
}
|
||||
|
||||
is ChatViewModel.EditMessageErrorState -> {
|
||||
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -980,12 +1023,6 @@ class ChatActivity :
|
|||
webSocketInstance?.getSignalingMessageReceiver()?.addListener(localParticipantMessageListener)
|
||||
webSocketInstance?.getSignalingMessageReceiver()?.addListener(conversationMessageListener)
|
||||
|
||||
if (conversationUser?.userId != "?" &&
|
||||
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag")
|
||||
) {
|
||||
binding.chatToolbar.setOnClickListener { v -> showConversationInfoScreen() }
|
||||
}
|
||||
|
||||
initSmileyKeyboardToggler()
|
||||
|
||||
themeMessageInputView()
|
||||
|
@ -1053,7 +1090,6 @@ class ChatActivity :
|
|||
}
|
||||
})
|
||||
|
||||
initMessageInputView()
|
||||
loadAvatarForStatusBar()
|
||||
setActionBarTitle()
|
||||
viewThemeUtils.material.colorToolbarOverflowIcon(binding.chatToolbar)
|
||||
|
@ -1061,7 +1097,7 @@ class ChatActivity :
|
|||
|
||||
private fun initMessageInputView() {
|
||||
val filters = arrayOfNulls<InputFilter>(1)
|
||||
val lengthFilter = CapabilitiesUtilNew.getMessageMaxLength(conversationUser)
|
||||
val lengthFilter = CapabilitiesUtil.getMessageMaxLength(spreedCapabilities)
|
||||
|
||||
binding.editView.editMessageView.visibility = View.GONE
|
||||
|
||||
|
@ -1160,7 +1196,7 @@ class ChatActivity :
|
|||
clearEditUI()
|
||||
}
|
||||
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-send")) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.SILENT_SEND)) {
|
||||
binding.messageInputView.button?.setOnLongClickListener {
|
||||
showSendButtonMenu()
|
||||
true
|
||||
|
@ -1175,14 +1211,14 @@ class ChatActivity :
|
|||
var apiVersion = 1
|
||||
// FIXME Fix API checking with guests?
|
||||
if (conversationUser != null) {
|
||||
apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
||||
apiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
|
||||
}
|
||||
|
||||
chatViewModel.editChatMessage(
|
||||
credentials!!,
|
||||
ApiUtils.getUrlForChatMessage(
|
||||
apiVersion,
|
||||
conversationUser?.baseUrl,
|
||||
conversationUser?.baseUrl!!,
|
||||
roomToken,
|
||||
message.id
|
||||
),
|
||||
|
@ -2016,7 +2052,7 @@ class ChatActivity :
|
|||
|
||||
private fun isTypingStatusEnabled(): Boolean {
|
||||
return webSocketInstance != null &&
|
||||
!CapabilitiesUtilNew.isTypingStatusPrivate(conversationUser!!)
|
||||
!CapabilitiesUtil.isTypingStatusPrivate(conversationUser!!)
|
||||
}
|
||||
|
||||
private fun setupSwipeToReply() {
|
||||
|
@ -2048,7 +2084,7 @@ class ChatActivity :
|
|||
|
||||
if (isOneToOneConversation()) {
|
||||
var url = ApiUtils.getUrlForAvatar(
|
||||
conversationUser!!.baseUrl,
|
||||
conversationUser!!.baseUrl!!,
|
||||
currentConversation!!.name,
|
||||
true
|
||||
)
|
||||
|
@ -2097,18 +2133,19 @@ class ChatActivity :
|
|||
}
|
||||
|
||||
val credentials = ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token)
|
||||
|
||||
context.imageLoader.enqueue(
|
||||
ImageRequest.Builder(context)
|
||||
.data(url)
|
||||
.addHeader("Authorization", credentials)
|
||||
.transformations(CircleCropTransformation())
|
||||
.crossfade(true)
|
||||
.target(target)
|
||||
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||
.diskCachePolicy(CachePolicy.DISABLED)
|
||||
.build()
|
||||
)
|
||||
if (credentials != null) {
|
||||
context.imageLoader.enqueue(
|
||||
ImageRequest.Builder(context)
|
||||
.data(url)
|
||||
.addHeader("Authorization", credentials)
|
||||
.transformations(CircleCropTransformation())
|
||||
.crossfade(true)
|
||||
.target(target)
|
||||
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||
.diskCachePolicy(CachePolicy.DISABLED)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
binding.chatToolbar.findViewById<FrameLayout>(R.id.chat_toolbar_avatar_container).visibility = View.GONE
|
||||
}
|
||||
|
@ -2463,7 +2500,10 @@ class ChatActivity :
|
|||
|
||||
val baseUrl = message.activeUser!!.baseUrl
|
||||
val userId = message.activeUser!!.userId
|
||||
val attachmentFolder = CapabilitiesUtilNew.getAttachmentFolder(message.activeUser!!)
|
||||
val attachmentFolder = CapabilitiesUtil.getAttachmentFolder(
|
||||
message.activeUser!!.capabilities!!
|
||||
.spreedCapability!!
|
||||
)
|
||||
val fileName = message.selectedIndividualHashMap!!["name"]
|
||||
var size = message.selectedIndividualHashMap!!["size"]
|
||||
if (size == null) {
|
||||
|
@ -2801,16 +2841,16 @@ class ChatActivity :
|
|||
|
||||
private fun shouldShowLobby(): Boolean {
|
||||
if (currentConversation != null) {
|
||||
return CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "webinary-lobby") &&
|
||||
return CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.WEBINARY_LOBBY) &&
|
||||
currentConversation?.lobbyState == LobbyState.LOBBY_STATE_MODERATORS_ONLY &&
|
||||
!ConversationUtils.canModerate(currentConversation!!, conversationUser!!) &&
|
||||
!ConversationUtils.canModerate(currentConversation!!, spreedCapabilities) &&
|
||||
!participantPermissions.canIgnoreLobby()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun disableCallButtons() {
|
||||
if (CapabilitiesUtilNew.isAbleToCall(conversationUser)) {
|
||||
if (CapabilitiesUtil.isAbleToCall(spreedCapabilities)) {
|
||||
if (conversationVoiceCallMenuItem != null && conversationVideoMenuItem != null) {
|
||||
conversationVoiceCallMenuItem?.icon?.alpha = SEMI_TRANSPARENT_INT
|
||||
conversationVideoMenuItem?.icon?.alpha = SEMI_TRANSPARENT_INT
|
||||
|
@ -2823,7 +2863,7 @@ class ChatActivity :
|
|||
}
|
||||
|
||||
private fun enableCallButtons() {
|
||||
if (CapabilitiesUtilNew.isAbleToCall(conversationUser)) {
|
||||
if (CapabilitiesUtil.isAbleToCall(spreedCapabilities)) {
|
||||
if (conversationVoiceCallMenuItem != null && conversationVideoMenuItem != null) {
|
||||
conversationVoiceCallMenuItem?.icon?.alpha = FULLY_OPAQUE_INT
|
||||
conversationVideoMenuItem?.icon?.alpha = FULLY_OPAQUE_INT
|
||||
|
@ -2843,7 +2883,7 @@ class ChatActivity :
|
|||
|
||||
private fun checkLobbyState() {
|
||||
if (currentConversation != null &&
|
||||
ConversationUtils.isLobbyViewApplicable(currentConversation!!, conversationUser!!)
|
||||
ConversationUtils.isLobbyViewApplicable(currentConversation!!, spreedCapabilities)
|
||||
) {
|
||||
if (shouldShowLobby()) {
|
||||
binding.lobby.lobbyView.visibility = View.VISIBLE
|
||||
|
@ -3252,6 +3292,7 @@ class ChatActivity :
|
|||
|
||||
val intent = Intent(this, LocationPickerActivity::class.java)
|
||||
intent.putExtra(KEY_ROOM_TOKEN, roomToken)
|
||||
intent.putExtra(BundleKeys.KEY_CHAT_API_VERSION, chatApiVersion)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
|
@ -3270,7 +3311,7 @@ class ChatActivity :
|
|||
val elevation = MENTION_AUTO_COMPLETE_ELEVATION
|
||||
resources?.let {
|
||||
val backgroundDrawable = ColorDrawable(it.getColor(R.color.bg_default, null))
|
||||
val presenter = MentionAutocompletePresenter(this, roomToken)
|
||||
val presenter = MentionAutocompletePresenter(this, roomToken, chatApiVersion)
|
||||
val callback = MentionAutocompleteCallback(
|
||||
this,
|
||||
conversationUser!!,
|
||||
|
@ -3430,12 +3471,6 @@ class ChatActivity :
|
|||
|
||||
if (!validSessionId()) {
|
||||
Log.d(TAG, "sessionID was not valid -> joinRoom")
|
||||
var apiVersion = 1
|
||||
// FIXME Fix API checking with guests?
|
||||
if (conversationUser != null) {
|
||||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
}
|
||||
|
||||
val startNanoTime = System.nanoTime()
|
||||
Log.d(TAG, "joinRoomWithPassword - joinRoom - calling: $startNanoTime")
|
||||
|
||||
|
@ -3458,7 +3493,7 @@ class ChatActivity :
|
|||
var apiVersion = 1
|
||||
// FIXME Fix API checking with guests?
|
||||
if (conversationUser != null) {
|
||||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser!!, intArrayOf(ApiUtils.API_V4, 1))
|
||||
}
|
||||
|
||||
val startNanoTime = System.nanoTime()
|
||||
|
@ -3467,7 +3502,7 @@ class ChatActivity :
|
|||
credentials!!,
|
||||
ApiUtils.getUrlForParticipantsActive(
|
||||
apiVersion,
|
||||
conversationUser?.baseUrl,
|
||||
conversationUser?.baseUrl!!,
|
||||
roomToken
|
||||
),
|
||||
funToCallWhenLeaveSuccessful
|
||||
|
@ -3513,11 +3548,9 @@ class ChatActivity :
|
|||
|
||||
private fun sendMessage(message: CharSequence, replyTo: Int?, sendWithoutNotification: Boolean) {
|
||||
if (conversationUser != null) {
|
||||
val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
||||
|
||||
chatViewModel.sendChatMessage(
|
||||
credentials!!,
|
||||
ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl, roomToken),
|
||||
ApiUtils.getUrlForChat(chatApiVersion, conversationUser!!.baseUrl!!, roomToken),
|
||||
message,
|
||||
conversationUser!!.displayName ?: "",
|
||||
replyTo ?: 0,
|
||||
|
@ -3637,7 +3670,7 @@ class ChatActivity :
|
|||
}
|
||||
}
|
||||
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "message-expiration")) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.MESSAGE_EXPIRATION)) {
|
||||
deleteExpiredMessages()
|
||||
}
|
||||
}
|
||||
|
@ -3871,53 +3904,58 @@ class ChatActivity :
|
|||
if (conversationUser?.userId == "?") {
|
||||
menu.removeItem(R.id.conversation_info)
|
||||
} else {
|
||||
conversationInfoMenuItem = menu.findItem(R.id.conversation_info)
|
||||
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
|
||||
conversationSharedItemsItem = menu.findItem(R.id.shared_items)
|
||||
} else {
|
||||
menu.removeItem(R.id.shared_items)
|
||||
}
|
||||
|
||||
loadAvatarForStatusBar()
|
||||
setActionBarTitle()
|
||||
}
|
||||
|
||||
if (CapabilitiesUtilNew.isAbleToCall(conversationUser)) {
|
||||
conversationVoiceCallMenuItem = menu.findItem(R.id.conversation_voice_call)
|
||||
conversationVideoMenuItem = menu.findItem(R.id.conversation_video_call)
|
||||
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-call")) {
|
||||
Handler().post {
|
||||
findViewById<View?>(R.id.conversation_voice_call)?.setOnLongClickListener {
|
||||
showCallButtonMenu(true)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
Handler().post {
|
||||
findViewById<View?>(R.id.conversation_video_call)?.setOnLongClickListener {
|
||||
showCallButtonMenu(false)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
menu.removeItem(R.id.conversation_video_call)
|
||||
menu.removeItem(R.id.conversation_voice_call)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
conversationUser?.let {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(it, "read-only-rooms")) {
|
||||
|
||||
if (this::spreedCapabilities.isInitialized) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.READ_ONLY_ROOMS)) {
|
||||
checkShowCallButtons()
|
||||
}
|
||||
|
||||
val searchItem = menu.findItem(R.id.conversation_search)
|
||||
searchItem.isVisible = CapabilitiesUtilNew.isUnifiedSearchAvailable(it)
|
||||
searchItem.isVisible = CapabilitiesUtil.isUnifiedSearchAvailable(spreedCapabilities)
|
||||
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
spreedCapabilities,
|
||||
SpreedFeatures.RICH_OBJECT_LIST_MEDIA
|
||||
)
|
||||
) {
|
||||
conversationSharedItemsItem = menu.findItem(R.id.shared_items)
|
||||
} else {
|
||||
menu.removeItem(R.id.shared_items)
|
||||
}
|
||||
|
||||
if (CapabilitiesUtil.isAbleToCall(spreedCapabilities)) {
|
||||
conversationVoiceCallMenuItem = menu.findItem(R.id.conversation_voice_call)
|
||||
conversationVideoMenuItem = menu.findItem(R.id.conversation_video_call)
|
||||
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.SILENT_CALL)) {
|
||||
Handler().post {
|
||||
findViewById<View?>(R.id.conversation_voice_call)?.setOnLongClickListener {
|
||||
showCallButtonMenu(true)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
Handler().post {
|
||||
findViewById<View?>(R.id.conversation_video_call)?.setOnLongClickListener {
|
||||
showCallButtonMenu(false)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
menu.removeItem(R.id.conversation_video_call)
|
||||
menu.removeItem(R.id.conversation_voice_call)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -4054,7 +4092,7 @@ class ChatActivity :
|
|||
private fun startACall(isVoiceOnlyCall: Boolean, callWithoutNotification: Boolean) {
|
||||
currentConversation?.let {
|
||||
if (conversationUser != null) {
|
||||
val pp = ParticipantPermissions(conversationUser!!, it)
|
||||
val pp = ParticipantPermissions(spreedCapabilities, it)
|
||||
if (!pp.canStartCall() && currentConversation?.hasCall == false) {
|
||||
Snackbar.make(binding.root, R.string.startCallForbidden, Snackbar.LENGTH_LONG).show()
|
||||
} else {
|
||||
|
@ -4074,7 +4112,7 @@ class ChatActivity :
|
|||
bundle.putString(KEY_ROOM_TOKEN, roomToken)
|
||||
bundle.putString(KEY_ROOM_ID, roomId)
|
||||
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, roomPassword)
|
||||
bundle.putString(BundleKeys.KEY_MODIFIED_BASE_URL, conversationUser?.baseUrl)
|
||||
bundle.putString(BundleKeys.KEY_MODIFIED_BASE_URL, conversationUser?.baseUrl!!)
|
||||
bundle.putString(KEY_CONVERSATION_NAME, it.displayName)
|
||||
bundle.putInt(KEY_RECORDING_STATE, it.callRecording)
|
||||
bundle.putBoolean(KEY_IS_MODERATOR, ConversationUtils.isParticipantOwnerOrModerator(it))
|
||||
|
@ -4147,7 +4185,8 @@ class ChatActivity :
|
|||
conversationUser,
|
||||
currentConversation,
|
||||
isShowMessageDeletionButton(message),
|
||||
participantPermissions.hasChatPermission()
|
||||
participantPermissions.hasChatPermission(),
|
||||
spreedCapabilities
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
@ -4156,7 +4195,7 @@ class ChatActivity :
|
|||
return ChatMessage.MessageType.SYSTEM_MESSAGE == message.getCalculateMessageType()
|
||||
}
|
||||
|
||||
fun deleteMessage(message: IMessage?) {
|
||||
fun deleteMessage(message: IMessage) {
|
||||
if (!participantPermissions.hasChatPermission()) {
|
||||
Log.w(
|
||||
TAG,
|
||||
|
@ -4168,28 +4207,28 @@ class ChatActivity :
|
|||
var apiVersion = 1
|
||||
// FIXME Fix API checking with guests?
|
||||
if (conversationUser != null) {
|
||||
apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
||||
apiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
|
||||
}
|
||||
|
||||
chatViewModel.deleteChatMessages(
|
||||
credentials!!,
|
||||
ApiUtils.getUrlForChatMessage(
|
||||
apiVersion,
|
||||
conversationUser?.baseUrl,
|
||||
conversationUser?.baseUrl!!,
|
||||
roomToken,
|
||||
message?.id
|
||||
message.id!!
|
||||
),
|
||||
message?.id!!
|
||||
message.id!!
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun replyPrivately(message: IMessage?) {
|
||||
val apiVersion =
|
||||
ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
ApiUtils.getConversationApiVersion(conversationUser!!, intArrayOf(ApiUtils.API_V4, 1))
|
||||
val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
conversationUser?.baseUrl,
|
||||
conversationUser?.baseUrl!!,
|
||||
"1",
|
||||
null,
|
||||
message?.user?.id?.substring(INVITE_LENGTH),
|
||||
|
@ -4215,10 +4254,14 @@ class ChatActivity :
|
|||
|
||||
fun remindMeLater(message: ChatMessage?) {
|
||||
Log.d(TAG, "remindMeLater called")
|
||||
|
||||
val chatApiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(ApiUtils.API_V1, 1))
|
||||
|
||||
val newFragment: DialogFragment = DateTimePickerFragment.newInstance(
|
||||
roomToken,
|
||||
message!!.id,
|
||||
chatViewModel
|
||||
chatViewModel,
|
||||
chatApiVersion
|
||||
)
|
||||
newFragment.show(supportFragmentManager, DateTimePickerFragment.TAG)
|
||||
}
|
||||
|
@ -4229,8 +4272,8 @@ class ChatActivity :
|
|||
chatViewModel.setChatReadMarker(
|
||||
credentials!!,
|
||||
ApiUtils.getUrlForChatReadMarker(
|
||||
ApiUtils.getChatApiVersion(conversationUser, intArrayOf(ApiUtils.APIv1)),
|
||||
conversationUser?.baseUrl,
|
||||
ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(ApiUtils.API_V1)),
|
||||
conversationUser?.baseUrl!!,
|
||||
roomToken
|
||||
),
|
||||
chatMessage.previousMessageId
|
||||
|
@ -4312,10 +4355,10 @@ class ChatActivity :
|
|||
}
|
||||
|
||||
fun shareToNotes(message: ChatMessage, roomToken: String) {
|
||||
val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
||||
val apiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
|
||||
val type = message.getCalculateMessageType()
|
||||
var shareUri: Uri? = null
|
||||
var data: HashMap<String?, String?>?
|
||||
val data: HashMap<String?, String?>?
|
||||
var metaData: String = ""
|
||||
var objectId: String = ""
|
||||
if (message.hasFileAttachment()) {
|
||||
|
@ -4335,9 +4378,9 @@ class ChatActivity :
|
|||
} else if (message.hasGeoLocation()) {
|
||||
data = message.messageParameters?.get("object")
|
||||
objectId = data?.get("id")!!
|
||||
val name = data.get("name")!!
|
||||
val lat = data.get("latitude")!!
|
||||
val lon = data.get("longitude")!!
|
||||
val name = data["name"]!!
|
||||
val lat = data["latitude"]!!
|
||||
val lon = data["longitude"]!!
|
||||
metaData =
|
||||
"{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," +
|
||||
"\"longitude\":\"$lon\",\"name\":\"$name\"}"
|
||||
|
@ -4348,6 +4391,7 @@ class ChatActivity :
|
|||
uploadFile(shareUri.toString(), true, token = roomToken)
|
||||
Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE -> {
|
||||
val caption = if (message.message != "{file}") message.message else ""
|
||||
if (null != shareUri) {
|
||||
|
@ -4364,25 +4408,28 @@ class ChatActivity :
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChatMessage.MessageType.SINGLE_NC_GEOLOCATION_MESSAGE -> {
|
||||
chatViewModel.shareLocationToNotes(
|
||||
credentials!!,
|
||||
ApiUtils.getUrlToSendLocation(apiVersion, conversationUser!!.baseUrl, roomToken),
|
||||
ApiUtils.getUrlToSendLocation(apiVersion, conversationUser!!.baseUrl!!, roomToken),
|
||||
"geo-location",
|
||||
objectId,
|
||||
metaData
|
||||
)
|
||||
Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE -> {
|
||||
chatViewModel.shareToNotes(
|
||||
credentials!!,
|
||||
ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl, roomToken),
|
||||
ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl!!, roomToken),
|
||||
message.message!!,
|
||||
conversationUser!!.displayName!!
|
||||
)
|
||||
Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -4456,7 +4503,10 @@ class ChatActivity :
|
|||
}
|
||||
|
||||
private fun showMicrophoneButton(show: Boolean) {
|
||||
if (show && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) {
|
||||
if (show && CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
spreedCapabilities, SpreedFeatures.VOICE_MESSAGE_SHARING
|
||||
)
|
||||
) {
|
||||
Log.d(TAG, "Microphone shown")
|
||||
binding.messageInputView.messageSendButton.visibility = View.GONE
|
||||
binding.messageInputView.recordAudioButton.visibility = View.VISIBLE
|
||||
|
@ -4542,7 +4592,7 @@ class ChatActivity :
|
|||
!isUserAllowedByPrivileges -> false
|
||||
message.systemMessageType != ChatMessage.SystemMessageType.DUMMY -> false
|
||||
message.isDeleted -> false
|
||||
!CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "delete-messages") -> false
|
||||
!CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.DELETE_MESSAGES) -> false
|
||||
!participantPermissions.hasChatPermission() -> false
|
||||
else -> true
|
||||
}
|
||||
|
@ -4554,7 +4604,7 @@ class ChatActivity :
|
|||
val isUserAllowedByPrivileges = if (message.actorId == conversationUser!!.userId) {
|
||||
true
|
||||
} else {
|
||||
ConversationUtils.canModerate(currentConversation!!, conversationUser!!)
|
||||
ConversationUtils.canModerate(currentConversation!!, spreedCapabilities)
|
||||
}
|
||||
return isUserAllowedByPrivileges
|
||||
}
|
||||
|
@ -4628,12 +4678,12 @@ class ChatActivity :
|
|||
var apiVersion = 1
|
||||
// FIXME Fix API checking with guests?
|
||||
if (conversationUser != null) {
|
||||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser!!, intArrayOf(ApiUtils.API_V4, 1))
|
||||
}
|
||||
|
||||
val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
conversationUser?.baseUrl,
|
||||
conversationUser?.baseUrl!!,
|
||||
"1",
|
||||
null,
|
||||
userMentionClickEvent.userId,
|
||||
|
|
|
@ -22,6 +22,7 @@ package com.nextcloud.talk.chat.data
|
|||
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
||||
|
@ -33,10 +34,17 @@ import retrofit2.Response
|
|||
@Suppress("LongParameterList", "TooManyFunctions")
|
||||
interface ChatRepository {
|
||||
fun getRoom(user: User, roomToken: String): Observable<ConversationModel>
|
||||
fun getCapabilities(user: User, roomToken: String): Observable<SpreedCapability>
|
||||
fun joinRoom(user: User, roomToken: String, roomPassword: String): Observable<ConversationModel>
|
||||
fun setReminder(user: User, roomToken: String, messageId: String, timeStamp: Int): Observable<Reminder>
|
||||
fun getReminder(user: User, roomToken: String, messageId: String): Observable<Reminder>
|
||||
fun deleteReminder(user: User, roomToken: String, messageId: String): Observable<GenericOverall>
|
||||
fun setReminder(
|
||||
user: User,
|
||||
roomToken: String,
|
||||
messageId: String,
|
||||
timeStamp: Int,
|
||||
chatApiVersion: Int
|
||||
): Observable<Reminder>
|
||||
fun getReminder(user: User, roomToken: String, messageId: String, apiVersion: Int): Observable<Reminder>
|
||||
fun deleteReminder(user: User, roomToken: String, messageId: String, apiVersion: Int): Observable<GenericOverall>
|
||||
fun shareToNotes(
|
||||
credentials: String,
|
||||
url: String,
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.nextcloud.talk.api.NcApi
|
|||
import com.nextcloud.talk.chat.data.ChatRepository
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
||||
|
@ -35,55 +36,78 @@ import retrofit2.Response
|
|||
|
||||
class NetworkChatRepositoryImpl(private val ncApi: NcApi) : ChatRepository {
|
||||
override fun getRoom(user: User, roomToken: String): Observable<ConversationModel> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv3, 1))
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))
|
||||
|
||||
return ncApi.getRoom(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoom(apiVersion, user.baseUrl, roomToken)
|
||||
ApiUtils.getUrlForRoom(apiVersion, user.baseUrl!!, roomToken)
|
||||
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!) }
|
||||
}
|
||||
|
||||
override fun getCapabilities(user: User, roomToken: String): Observable<SpreedCapability> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))
|
||||
|
||||
return ncApi.getRoomCapabilities(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomCapabilities(apiVersion, user.baseUrl!!, roomToken)
|
||||
).map { it.ocs?.data }
|
||||
}
|
||||
|
||||
override fun joinRoom(user: User, roomToken: String, roomPassword: String): Observable<ConversationModel> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, 1))
|
||||
|
||||
return ncApi.joinRoom(
|
||||
credentials,
|
||||
ApiUtils.getUrlForParticipantsActive(apiVersion, user.baseUrl, roomToken),
|
||||
ApiUtils.getUrlForParticipantsActive(apiVersion, user.baseUrl!!, roomToken),
|
||||
roomPassword
|
||||
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!) }
|
||||
}
|
||||
|
||||
override fun setReminder(user: User, roomToken: String, messageId: String, timeStamp: Int): Observable<Reminder> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||
val apiVersion = ApiUtils.getChatApiVersion(user, intArrayOf(ApiUtils.APIv1, 1))
|
||||
override fun setReminder(
|
||||
user: User,
|
||||
roomToken: String,
|
||||
messageId: String,
|
||||
timeStamp: Int,
|
||||
chatApiVersion: Int
|
||||
): Observable<Reminder> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
return ncApi.setReminder(
|
||||
credentials,
|
||||
ApiUtils.getUrlForReminder(user, roomToken, messageId, apiVersion),
|
||||
ApiUtils.getUrlForReminder(user, roomToken, messageId, chatApiVersion),
|
||||
timeStamp
|
||||
).map {
|
||||
it.ocs!!.data
|
||||
}
|
||||
}
|
||||
|
||||
override fun getReminder(user: User, roomToken: String, messageId: String): Observable<Reminder> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||
val apiVersion = ApiUtils.getChatApiVersion(user, intArrayOf(ApiUtils.APIv1, 1))
|
||||
override fun getReminder(
|
||||
user: User,
|
||||
roomToken: String,
|
||||
messageId: String,
|
||||
chatApiVersion: Int
|
||||
): Observable<Reminder> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
return ncApi.getReminder(
|
||||
credentials,
|
||||
ApiUtils.getUrlForReminder(user, roomToken, messageId, apiVersion)
|
||||
ApiUtils.getUrlForReminder(user, roomToken, messageId, chatApiVersion)
|
||||
).map {
|
||||
it.ocs!!.data
|
||||
}
|
||||
}
|
||||
|
||||
override fun deleteReminder(user: User, roomToken: String, messageId: String): Observable<GenericOverall> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||
val apiVersion = ApiUtils.getChatApiVersion(user, intArrayOf(ApiUtils.APIv1, 1))
|
||||
override fun deleteReminder(
|
||||
user: User,
|
||||
roomToken: String,
|
||||
messageId: String,
|
||||
chatApiVersion: Int
|
||||
): Observable<GenericOverall> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
return ncApi.deleteReminder(
|
||||
credentials,
|
||||
ApiUtils.getUrlForReminder(user, roomToken, messageId, apiVersion)
|
||||
ApiUtils.getUrlForReminder(user, roomToken, messageId, chatApiVersion)
|
||||
).map {
|
||||
it
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import com.nextcloud.talk.data.user.model.User
|
|||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
||||
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
|
@ -105,6 +106,14 @@ class ChatViewModel @Inject constructor(
|
|||
val getRoomViewState: LiveData<ViewState>
|
||||
get() = _getRoomViewState
|
||||
|
||||
object GetCapabilitiesStartState : ViewState
|
||||
object GetCapabilitiesErrorState : ViewState
|
||||
open class GetCapabilitiesSuccessState(val spreedCapabilities: SpreedCapability) : ViewState
|
||||
|
||||
private val _getCapabilitiesViewState: MutableLiveData<ViewState> = MutableLiveData(GetCapabilitiesStartState)
|
||||
val getCapabilitiesViewState: LiveData<ViewState>
|
||||
get() = _getCapabilitiesViewState
|
||||
|
||||
object JoinRoomStartState : ViewState
|
||||
object JoinRoomErrorState : ViewState
|
||||
open class JoinRoomSuccessState(val conversationModel: ConversationModel) : ViewState
|
||||
|
@ -184,6 +193,36 @@ class ChatViewModel @Inject constructor(
|
|||
?.subscribe(GetRoomObserver())
|
||||
}
|
||||
|
||||
fun getCapabilities(user: User, token: String, conversationModel: ConversationModel) {
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesStartState
|
||||
|
||||
if (conversationModel.remoteServer.isNullOrEmpty()) {
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesSuccessState(user.capabilities!!.spreedCapability!!)
|
||||
} else {
|
||||
chatRepository.getCapabilities(user, token)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<SpreedCapability> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
LifeCycleObserver.disposableSet.add(d)
|
||||
}
|
||||
|
||||
override fun onNext(spreedCapabilities: SpreedCapability) {
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesSuccessState(spreedCapabilities)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e(TAG, "Error when fetching spreed capabilities", e)
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesErrorState
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
// unused atm
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun joinRoom(user: User, token: String, roomPassword: String) {
|
||||
_joinRoomViewState.value = JoinRoomStartState
|
||||
chatRepository.joinRoom(user, token, roomPassword)
|
||||
|
@ -193,6 +232,43 @@ class ChatViewModel @Inject constructor(
|
|||
?.subscribe(JoinRoomObserver())
|
||||
}
|
||||
|
||||
fun setReminder(user: User, roomToken: String, messageId: String, timestamp: Int, chatApiVersion: Int) {
|
||||
chatRepository.setReminder(user, roomToken, messageId, timestamp, chatApiVersion)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(SetReminderObserver())
|
||||
}
|
||||
|
||||
fun getReminder(user: User, roomToken: String, messageId: String, chatApiVersion: Int) {
|
||||
chatRepository.getReminder(user, roomToken, messageId, chatApiVersion)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(GetReminderObserver())
|
||||
}
|
||||
|
||||
fun deleteReminder(user: User, roomToken: String, messageId: String, chatApiVersion: Int) {
|
||||
chatRepository.deleteReminder(user, roomToken, messageId, chatApiVersion)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<GenericOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
LifeCycleObserver.disposableSet.add(d)
|
||||
}
|
||||
|
||||
override fun onNext(genericOverall: GenericOverall) {
|
||||
_getReminderExistState.value = GetReminderStartState
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.d(TAG, "Error when deleting reminder", e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
// unused atm
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun leaveRoom(credentials: String, url: String, funToCallWhenLeaveSuccessful: (() -> Unit)?) {
|
||||
val startNanoTime = System.nanoTime()
|
||||
chatRepository.leaveRoom(credentials, url)
|
||||
|
@ -357,43 +433,6 @@ class ChatViewModel @Inject constructor(
|
|||
})
|
||||
}
|
||||
|
||||
fun setReminder(user: User, roomToken: String, messageId: String, timestamp: Int) {
|
||||
chatRepository.setReminder(user, roomToken, messageId, timestamp)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(SetReminderObserver())
|
||||
}
|
||||
|
||||
fun getReminder(user: User, roomToken: String, messageId: String) {
|
||||
chatRepository.getReminder(user, roomToken, messageId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(GetReminderObserver())
|
||||
}
|
||||
|
||||
fun deleteReminder(user: User, roomToken: String, messageId: String) {
|
||||
chatRepository.deleteReminder(user, roomToken, messageId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<GenericOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
LifeCycleObserver.disposableSet.add(d)
|
||||
}
|
||||
|
||||
override fun onNext(genericOverall: GenericOverall) {
|
||||
_getReminderExistState.value = GetReminderStartState
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.d(TAG, "Error when deleting reminder $e")
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
// unused atm
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun shareToNotes(credentials: String, url: String, message: String, displayName: String) {
|
||||
chatRepository.shareToNotes(credentials, url, message, displayName)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
@ -522,7 +561,7 @@ class ChatViewModel @Inject constructor(
|
|||
|
||||
inner class GetRoomObserver : Observer<ConversationModel> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
LifeCycleObserver.disposableSet.add(d)
|
||||
// unused atm
|
||||
}
|
||||
|
||||
override fun onNext(conversationModel: ConversationModel) {
|
||||
|
|
|
@ -65,7 +65,7 @@ class ReadFolderListingOperation(okHttpClient: OkHttpClient, currentUser: User,
|
|||
ApiUtils.getCredentials(
|
||||
currentUser.username,
|
||||
currentUser.token
|
||||
),
|
||||
)!!,
|
||||
"Authorization"
|
||||
)
|
||||
)
|
||||
|
|
|
@ -68,9 +68,10 @@ import com.nextcloud.talk.models.json.participants.Participant
|
|||
import com.nextcloud.talk.openconversations.ListOpenConversationsActivity
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.UserIdUtils.getIdForUser
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||
|
@ -318,10 +319,10 @@ class ContactsActivity :
|
|||
}
|
||||
|
||||
private fun createRoom(roomType: String, sourceType: String?, userId: String) {
|
||||
val apiVersion: Int = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion: Int = ApiUtils.getConversationApiVersion(currentUser!!, intArrayOf(ApiUtils.API_V4, 1))
|
||||
val retrofitBucket: RetrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
currentUser!!.baseUrl,
|
||||
currentUser!!.baseUrl!!,
|
||||
roomType,
|
||||
sourceType,
|
||||
userId,
|
||||
|
@ -438,7 +439,7 @@ class ContactsActivity :
|
|||
userHeaderItems = HashMap()
|
||||
val query = adapter!!.getFilter(String::class.java)
|
||||
val retrofitBucket: RetrofitBucket =
|
||||
ApiUtils.getRetrofitBucketForContactsSearchFor14(currentUser!!.baseUrl, query)
|
||||
ApiUtils.getRetrofitBucketForContactsSearchFor14(currentUser!!.baseUrl!!, query)
|
||||
val modifiedQueryMap: HashMap<String, Any?> = HashMap(retrofitBucket.queryMap)
|
||||
modifiedQueryMap["limit"] = CONTACTS_BATCH_SIZE
|
||||
if (isAddingParticipantsView) {
|
||||
|
@ -450,13 +451,21 @@ class ContactsActivity :
|
|||
if (!isAddingParticipantsView) {
|
||||
// groups
|
||||
shareTypesList.add("1")
|
||||
} else if (CapabilitiesUtilNew.hasSpreedFeatureCapability(currentUser, "invite-groups-and-mails")) {
|
||||
} else if (CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser?.capabilities?.spreedCapability!!,
|
||||
SpreedFeatures.INVITE_GROUPS_AND_MAILS
|
||||
)
|
||||
) {
|
||||
// groups
|
||||
shareTypesList.add("1")
|
||||
// emails
|
||||
shareTypesList.add("4")
|
||||
}
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(currentUser, "circles-support")) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser?.capabilities?.spreedCapability!!,
|
||||
SpreedFeatures.CIRCLES_SUPPORT
|
||||
)
|
||||
) {
|
||||
// circles
|
||||
shareTypesList.add("7")
|
||||
}
|
||||
|
@ -745,8 +754,12 @@ class ContactsActivity :
|
|||
private fun updateSelection(contactItem: ContactItem) {
|
||||
contactItem.model.selected = !contactItem.model.selected
|
||||
updateSelectionLists(contactItem.model)
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(currentUser, "last-room-activity") &&
|
||||
!CapabilitiesUtilNew.hasSpreedFeatureCapability(currentUser, "invite-groups-and-mails") &&
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser?.capabilities?.spreedCapability!!, SpreedFeatures.LAST_ROOM_ACTIVITY
|
||||
) &&
|
||||
!CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser?.capabilities?.spreedCapability!!, SpreedFeatures.INVITE_GROUPS_AND_MAILS
|
||||
) &&
|
||||
isValidGroupSelection(contactItem, contactItem.model, adapter)
|
||||
) {
|
||||
val currentItems: List<ContactItem> = adapter?.currentItems as List<ContactItem>
|
||||
|
@ -771,10 +784,10 @@ class ContactsActivity :
|
|||
if ("groups" == contactItem.model.source) {
|
||||
roomType = "2"
|
||||
}
|
||||
val apiVersion: Int = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion: Int = ApiUtils.getConversationApiVersion(currentUser!!, intArrayOf(ApiUtils.API_V4, 1))
|
||||
val retrofitBucket: RetrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
currentUser!!.baseUrl,
|
||||
currentUser!!.baseUrl!!,
|
||||
roomType,
|
||||
null,
|
||||
contactItem.model.calculatedActorId,
|
||||
|
|
|
@ -36,16 +36,16 @@ class ConversationRepositoryImpl(private val ncApi: NcApi, currentUserProvider:
|
|||
ConversationRepository {
|
||||
|
||||
val currentUser: User = currentUserProvider.currentUser.blockingGet()
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
|
||||
override fun renameConversation(roomToken: String, roomNameNew: String): Observable<GenericOverall> {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
|
||||
|
||||
return ncApi.renameRoom(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoom(
|
||||
apiVersion,
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken
|
||||
),
|
||||
roomNameNew
|
||||
|
@ -59,12 +59,12 @@ class ConversationRepositoryImpl(private val ncApi: NcApi, currentUserProvider:
|
|||
roomName: String,
|
||||
conversationType: Conversation.ConversationType?
|
||||
): Observable<RoomOverall> {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
|
||||
|
||||
val retrofitBucket: RetrofitBucket = if (conversationType == Conversation.ConversationType.ROOM_PUBLIC_CALL) {
|
||||
ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
ROOM_TYPE_PUBLIC,
|
||||
null,
|
||||
null,
|
||||
|
@ -73,7 +73,7 @@ class ConversationRepositoryImpl(private val ncApi: NcApi, currentUserProvider:
|
|||
} else {
|
||||
ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
ROOM_TYPE_GROUP,
|
||||
null,
|
||||
null,
|
||||
|
|
|
@ -40,6 +40,7 @@ import android.view.View
|
|||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.work.Data
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.WorkManager
|
||||
|
@ -61,6 +62,7 @@ import com.nextcloud.talk.bottomsheet.items.BasicListItemWithImage
|
|||
import com.nextcloud.talk.bottomsheet.items.listItemsWithImage
|
||||
import com.nextcloud.talk.contacts.ContactsActivity
|
||||
import com.nextcloud.talk.conversationinfoedit.ConversationInfoEditActivity
|
||||
import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.ActivityConversationInfoBinding
|
||||
import com.nextcloud.talk.events.EventStatus
|
||||
|
@ -71,9 +73,11 @@ import com.nextcloud.talk.extensions.loadUserAvatar
|
|||
import com.nextcloud.talk.jobs.DeleteConversationWorker
|
||||
import com.nextcloud.talk.jobs.LeaveConversationWorker
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter
|
||||
import com.nextcloud.talk.models.domain.ConversationType
|
||||
import com.nextcloud.talk.models.domain.LobbyState
|
||||
import com.nextcloud.talk.models.domain.NotificationLevel
|
||||
import com.nextcloud.talk.models.domain.converters.DomainEnumNotificationLevelConverter
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||
import com.nextcloud.talk.models.json.participants.Participant
|
||||
import com.nextcloud.talk.models.json.participants.Participant.ActorType.CIRCLES
|
||||
|
@ -83,11 +87,12 @@ import com.nextcloud.talk.models.json.participants.ParticipantsOverall
|
|||
import com.nextcloud.talk.repositories.conversations.ConversationsRepository
|
||||
import com.nextcloud.talk.shareditems.activities.SharedItemsActivity
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.ConversationUtils
|
||||
import com.nextcloud.talk.utils.DateConstants
|
||||
import com.nextcloud.talk.utils.DateUtils
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import com.nextcloud.talk.utils.preferences.preferencestorage.DatabaseStorageModule
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
|
@ -109,6 +114,9 @@ class ConversationInfoActivity :
|
|||
FlexibleAdapter.OnItemClickListener {
|
||||
private lateinit var binding: ActivityConversationInfoBinding
|
||||
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
@Inject
|
||||
lateinit var ncApi: NcApi
|
||||
|
||||
|
@ -121,6 +129,10 @@ class ConversationInfoActivity :
|
|||
@Inject
|
||||
lateinit var dateUtils: DateUtils
|
||||
|
||||
lateinit var viewModel: ConversationInfoViewModel
|
||||
|
||||
private lateinit var spreedCapabilities: SpreedCapability
|
||||
|
||||
private lateinit var conversationToken: String
|
||||
private lateinit var conversationUser: User
|
||||
private var hasAvatarSpacing: Boolean = false
|
||||
|
@ -129,7 +141,9 @@ class ConversationInfoActivity :
|
|||
private var participantsDisposable: Disposable? = null
|
||||
|
||||
private var databaseStorageModule: DatabaseStorageModule? = null
|
||||
private var conversation: Conversation? = null
|
||||
|
||||
// private var conversation: Conversation? = null
|
||||
private var conversation: ConversationModel? = null
|
||||
|
||||
private var adapter: FlexibleAdapter<ParticipantItem>? = null
|
||||
private var userItems: MutableList<ParticipantItem> = ArrayList()
|
||||
|
@ -157,11 +171,26 @@ class ConversationInfoActivity :
|
|||
setContentView(binding.root)
|
||||
setupSystemColors()
|
||||
|
||||
viewModel =
|
||||
ViewModelProvider(this, viewModelFactory)[ConversationInfoViewModel::class.java]
|
||||
|
||||
conversationUser = currentUserProvider.currentUser.blockingGet()
|
||||
|
||||
conversationToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)!!
|
||||
hasAvatarSpacing = intent.getBooleanExtra(BundleKeys.KEY_ROOM_ONE_TO_ONE, false)
|
||||
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)
|
||||
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)!!
|
||||
|
||||
initObservers()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
this.lifecycle.addObserver(ConversationInfoViewModel.LifeCycleObserver)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
this.lifecycle.removeObserver(ConversationInfoViewModel.LifeCycleObserver)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -176,13 +205,7 @@ class ConversationInfoActivity :
|
|||
binding.clearConversationHistory.setOnClickListener { showClearHistoryDialog() }
|
||||
binding.addParticipantsAction.setOnClickListener { addParticipants() }
|
||||
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
|
||||
binding.sharedItemsButton.setOnClickListener { showSharedItems() }
|
||||
} else {
|
||||
binding.sharedItems.visibility = GONE
|
||||
}
|
||||
|
||||
fetchRoomInfo()
|
||||
viewModel.getRoom(conversationUser, conversationToken)
|
||||
|
||||
themeTextViews()
|
||||
themeSwitchPreferences()
|
||||
|
@ -192,6 +215,35 @@ class ConversationInfoActivity :
|
|||
binding.progressBar.let { viewThemeUtils.platform.colorCircularProgressBar(it, ColorRole.PRIMARY) }
|
||||
}
|
||||
|
||||
private fun initObservers() {
|
||||
viewModel.viewState.observe(this) { state ->
|
||||
when (state) {
|
||||
is ConversationInfoViewModel.GetRoomSuccessState -> {
|
||||
conversation = state.conversationModel
|
||||
viewModel.getCapabilities(conversationUser, conversationToken, conversation!!)
|
||||
}
|
||||
|
||||
is ConversationInfoViewModel.GetRoomErrorState -> {
|
||||
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.getCapabilitiesViewState.observe(this) { state ->
|
||||
when (state) {
|
||||
is ConversationInfoViewModel.GetCapabilitiesSuccessState -> {
|
||||
spreedCapabilities = state.spreedCapabilities
|
||||
|
||||
handleConversation()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupActionBar() {
|
||||
setSupportActionBar(binding.conversationInfoToolbar)
|
||||
binding.conversationInfoToolbar.setNavigationOnClickListener {
|
||||
|
@ -217,7 +269,7 @@ class ConversationInfoActivity :
|
|||
fun showOptionsMenu() {
|
||||
if (::optionsMenu.isInitialized) {
|
||||
optionsMenu.clear()
|
||||
if (CapabilitiesUtilNew.isConversationAvatarEndpointAvailable(conversationUser)) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.AVATAR)) {
|
||||
menuInflater.inflate(R.menu.menu_conversation_info, optionsMenu)
|
||||
}
|
||||
}
|
||||
|
@ -273,19 +325,22 @@ class ConversationInfoActivity :
|
|||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
intent.putExtra(BundleKeys.KEY_CONVERSATION_NAME, conversation?.displayName)
|
||||
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, conversationToken)
|
||||
intent.putExtra(SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR, conversation?.isParticipantOwnerOrModerator)
|
||||
intent.putExtra(
|
||||
SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR,
|
||||
ConversationUtils.isParticipantOwnerOrModerator(conversation!!)
|
||||
)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
private fun setupWebinaryView() {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "webinary-lobby") &&
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.WEBINARY_LOBBY) &&
|
||||
webinaryRoomType(conversation!!) &&
|
||||
conversation!!.canModerate(conversationUser)
|
||||
ConversationUtils.canModerate(conversation!!, spreedCapabilities)
|
||||
) {
|
||||
binding.webinarInfoView.webinarSettings.visibility = VISIBLE
|
||||
|
||||
val isLobbyOpenToModeratorsOnly =
|
||||
conversation!!.lobbyState == Conversation.LobbyState.LOBBY_STATE_MODERATORS_ONLY
|
||||
conversation!!.lobbyState == LobbyState.LOBBY_STATE_MODERATORS_ONLY
|
||||
binding.webinarInfoView.lobbySwitch.isChecked = isLobbyOpenToModeratorsOnly
|
||||
|
||||
reconfigureLobbyTimerView()
|
||||
|
@ -320,9 +375,9 @@ class ConversationInfoActivity :
|
|||
}
|
||||
}
|
||||
|
||||
private fun webinaryRoomType(conversation: Conversation): Boolean {
|
||||
return conversation.type == Conversation.ConversationType.ROOM_GROUP_CALL ||
|
||||
conversation.type == Conversation.ConversationType.ROOM_PUBLIC_CALL
|
||||
private fun webinaryRoomType(conversation: ConversationModel): Boolean {
|
||||
return conversation.type == ConversationType.ROOM_GROUP_CALL ||
|
||||
conversation.type == ConversationType.ROOM_PUBLIC_CALL
|
||||
}
|
||||
|
||||
private fun reconfigureLobbyTimerView(dateTime: Calendar? = null) {
|
||||
|
@ -337,9 +392,9 @@ class ConversationInfoActivity :
|
|||
}
|
||||
|
||||
conversation!!.lobbyState = if (isChecked) {
|
||||
Conversation.LobbyState.LOBBY_STATE_MODERATORS_ONLY
|
||||
LobbyState.LOBBY_STATE_MODERATORS_ONLY
|
||||
} else {
|
||||
Conversation.LobbyState.LOBBY_STATE_ALL_PARTICIPANTS
|
||||
LobbyState.LOBBY_STATE_ALL_PARTICIPANTS
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -370,11 +425,11 @@ class ConversationInfoActivity :
|
|||
0
|
||||
}
|
||||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||
|
||||
ncApi.setLobbyForConversation(
|
||||
ApiUtils.getCredentials(conversationUser.username, conversationUser.token),
|
||||
ApiUtils.getUrlForRoomWebinaryLobby(apiVersion, conversationUser.baseUrl, conversation!!.token),
|
||||
ApiUtils.getUrlForRoomWebinaryLobby(apiVersion, conversationUser.baseUrl!!, conversation!!.token),
|
||||
state,
|
||||
conversation!!.lobbyTimer
|
||||
)
|
||||
|
@ -487,7 +542,7 @@ class ConversationInfoActivity :
|
|||
|
||||
private fun getListOfParticipants() {
|
||||
// FIXME Fix API checking with guests?
|
||||
val apiVersion: Int = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion: Int = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||
|
||||
val fieldMap = HashMap<String, Boolean>()
|
||||
fieldMap["includeStatus"] = true
|
||||
|
@ -496,7 +551,7 @@ class ConversationInfoActivity :
|
|||
credentials,
|
||||
ApiUtils.getUrlForParticipants(
|
||||
apiVersion,
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversationToken
|
||||
),
|
||||
fieldMap
|
||||
|
@ -586,11 +641,11 @@ class ConversationInfoActivity :
|
|||
}
|
||||
|
||||
private fun clearHistory() {
|
||||
val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
||||
val apiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
|
||||
|
||||
ncApi.clearChatHistory(
|
||||
credentials,
|
||||
ApiUtils.getUrlForChat(apiVersion, conversationUser.baseUrl, conversationToken)
|
||||
ApiUtils.getUrlForChat(apiVersion, conversationUser.baseUrl!!, conversationToken)
|
||||
)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -631,123 +686,99 @@ class ConversationInfoActivity :
|
|||
}
|
||||
}
|
||||
|
||||
private fun fetchRoomInfo() {
|
||||
val apiVersion: Int
|
||||
// FIXME Fix API checking with guests?
|
||||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
@Suppress("LongMethod")
|
||||
private fun handleConversation() {
|
||||
val conversationCopy = conversation!!
|
||||
|
||||
ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser.baseUrl, conversationToken))
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<RoomOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
roomDisposable = d
|
||||
}
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.RICH_OBJECT_LIST_MEDIA)) {
|
||||
binding.sharedItemsButton.setOnClickListener { showSharedItems() }
|
||||
} else {
|
||||
binding.sharedItems.visibility = GONE
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
override fun onNext(roomOverall: RoomOverall) {
|
||||
conversation = roomOverall.ocs!!.data
|
||||
if (ConversationUtils.canModerate(conversationCopy, spreedCapabilities)) {
|
||||
binding.addParticipantsAction.visibility = VISIBLE
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
spreedCapabilities,
|
||||
SpreedFeatures.CLEAR_HISTORY
|
||||
)
|
||||
) {
|
||||
binding.clearConversationHistory.visibility = VISIBLE
|
||||
} else {
|
||||
binding.clearConversationHistory.visibility = GONE
|
||||
}
|
||||
showOptionsMenu()
|
||||
} else {
|
||||
binding.addParticipantsAction.visibility = GONE
|
||||
|
||||
val conversationCopy = conversation
|
||||
if (ConversationUtils.isNoteToSelfConversation(conversation)) {
|
||||
binding.notificationSettingsView.notificationSettings.visibility = VISIBLE
|
||||
} else {
|
||||
binding.clearConversationHistory.visibility = GONE
|
||||
}
|
||||
}
|
||||
|
||||
if (conversationCopy!!.canModerate(conversationUser)) {
|
||||
binding.addParticipantsAction.visibility = VISIBLE
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(
|
||||
conversationUser,
|
||||
"clear-history"
|
||||
)
|
||||
) {
|
||||
binding.clearConversationHistory.visibility = VISIBLE
|
||||
} else {
|
||||
binding.clearConversationHistory.visibility = GONE
|
||||
}
|
||||
showOptionsMenu()
|
||||
} else {
|
||||
binding.addParticipantsAction.visibility = GONE
|
||||
if (!isDestroyed) {
|
||||
binding.dangerZoneOptions.visibility = VISIBLE
|
||||
|
||||
if (ConversationUtils.isNoteToSelfConversation(
|
||||
ConversationModel.mapToConversationModel(conversation!!)
|
||||
)
|
||||
) {
|
||||
binding.notificationSettingsView.notificationSettings.visibility = VISIBLE
|
||||
} else {
|
||||
binding.clearConversationHistory.visibility = GONE
|
||||
}
|
||||
}
|
||||
setupWebinaryView()
|
||||
|
||||
if (!isDestroyed) {
|
||||
binding.dangerZoneOptions.visibility = VISIBLE
|
||||
if (ConversationUtils.canLeave(conversation!!)) {
|
||||
binding.leaveConversationAction.visibility = GONE
|
||||
} else {
|
||||
binding.leaveConversationAction.visibility = VISIBLE
|
||||
}
|
||||
|
||||
setupWebinaryView()
|
||||
if (ConversationUtils.canDelete(conversation!!, spreedCapabilities)) {
|
||||
binding.deleteConversationAction.visibility = GONE
|
||||
} else {
|
||||
binding.deleteConversationAction.visibility = VISIBLE
|
||||
}
|
||||
|
||||
if (!conversation!!.canLeave()) {
|
||||
binding.leaveConversationAction.visibility = GONE
|
||||
} else {
|
||||
binding.leaveConversationAction.visibility = VISIBLE
|
||||
}
|
||||
if (ConversationType.ROOM_SYSTEM == conversation!!.type) {
|
||||
binding.notificationSettingsView.callNotificationsSwitch.visibility = GONE
|
||||
}
|
||||
|
||||
if (!conversation!!.canDelete(conversationUser)) {
|
||||
binding.deleteConversationAction.visibility = GONE
|
||||
} else {
|
||||
binding.deleteConversationAction.visibility = VISIBLE
|
||||
}
|
||||
if (conversation!!.notificationCalls === null) {
|
||||
binding.notificationSettingsView.callNotificationsSwitch.visibility = GONE
|
||||
} else {
|
||||
binding.notificationSettingsView.callNotificationsSwitch.isChecked =
|
||||
(conversationCopy.notificationCalls == 1)
|
||||
}
|
||||
|
||||
if (Conversation.ConversationType.ROOM_SYSTEM == conversation!!.type) {
|
||||
binding.notificationSettingsView.callNotificationsSwitch.visibility = GONE
|
||||
}
|
||||
getListOfParticipants()
|
||||
|
||||
if (conversation!!.notificationCalls === null) {
|
||||
binding.notificationSettingsView.callNotificationsSwitch.visibility = GONE
|
||||
} else {
|
||||
binding.notificationSettingsView.callNotificationsSwitch.isChecked =
|
||||
(conversationCopy.notificationCalls == 1)
|
||||
}
|
||||
binding.progressBar.visibility = GONE
|
||||
|
||||
getListOfParticipants()
|
||||
binding.conversationInfoName.visibility = VISIBLE
|
||||
|
||||
binding.progressBar.visibility = GONE
|
||||
binding.displayNameText.text = conversation!!.displayName
|
||||
|
||||
binding.conversationInfoName.visibility = VISIBLE
|
||||
if (conversation!!.description != null && conversation!!.description!!.isNotEmpty()) {
|
||||
binding.descriptionText.text = conversation!!.description
|
||||
binding.conversationDescription.visibility = VISIBLE
|
||||
}
|
||||
|
||||
binding.displayNameText.text = conversation!!.displayName
|
||||
loadConversationAvatar()
|
||||
adjustNotificationLevelUI()
|
||||
initRecordingConsentOption()
|
||||
initExpiringMessageOption()
|
||||
|
||||
if (conversation!!.description != null && conversation!!.description!!.isNotEmpty()) {
|
||||
binding.descriptionText.text = conversation!!.description
|
||||
binding.conversationDescription.visibility = VISIBLE
|
||||
}
|
||||
|
||||
loadConversationAvatar()
|
||||
adjustNotificationLevelUI()
|
||||
initRecordingConsentOption()
|
||||
initExpiringMessageOption()
|
||||
|
||||
binding.let {
|
||||
GuestAccessHelper(
|
||||
this@ConversationInfoActivity,
|
||||
it,
|
||||
conversation!!,
|
||||
conversationUser
|
||||
).setupGuestAccess()
|
||||
}
|
||||
if (ConversationUtils.isNoteToSelfConversation(
|
||||
ConversationModel.mapToConversationModel(conversation!!)
|
||||
)
|
||||
) {
|
||||
binding.notificationSettingsView.notificationSettings.visibility = GONE
|
||||
} else {
|
||||
binding.notificationSettingsView.notificationSettings.visibility = VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e(TAG, "failed to fetch room info", e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
roomDisposable!!.dispose()
|
||||
}
|
||||
})
|
||||
binding.let {
|
||||
GuestAccessHelper(
|
||||
this@ConversationInfoActivity,
|
||||
it,
|
||||
conversation!!,
|
||||
spreedCapabilities,
|
||||
conversationUser
|
||||
).setupGuestAccess()
|
||||
}
|
||||
if (ConversationUtils.isNoteToSelfConversation(conversation!!)) {
|
||||
binding.notificationSettingsView.notificationSettings.visibility = GONE
|
||||
} else {
|
||||
binding.notificationSettingsView.notificationSettings.visibility = VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initRecordingConsentOption() {
|
||||
|
@ -781,13 +812,13 @@ class ConversationInfoActivity :
|
|||
}
|
||||
}
|
||||
|
||||
if (conversation!!.isParticipantOwnerOrModerator &&
|
||||
!ConversationUtils.isNoteToSelfConversation(ConversationModel.mapToConversationModel(conversation!!))
|
||||
if (ConversationUtils.isParticipantOwnerOrModerator(conversation!!) &&
|
||||
!ConversationUtils.isNoteToSelfConversation(conversation!!)
|
||||
) {
|
||||
when (CapabilitiesUtilNew.getRecordingConsentType(conversationUser)) {
|
||||
CapabilitiesUtilNew.RECORDING_CONSENT_NOT_REQUIRED -> hide()
|
||||
CapabilitiesUtilNew.RECORDING_CONSENT_REQUIRED -> showAlwaysRequiredInfo()
|
||||
CapabilitiesUtilNew.RECORDING_CONSENT_DEPEND_ON_CONVERSATION -> showSwitch()
|
||||
when (CapabilitiesUtil.getRecordingConsentType(spreedCapabilities)) {
|
||||
CapabilitiesUtil.RECORDING_CONSENT_NOT_REQUIRED -> hide()
|
||||
CapabilitiesUtil.RECORDING_CONSENT_REQUIRED -> showAlwaysRequiredInfo()
|
||||
CapabilitiesUtil.RECORDING_CONSENT_DEPEND_ON_CONVERSATION -> showSwitch()
|
||||
}
|
||||
} else {
|
||||
hide()
|
||||
|
@ -801,11 +832,11 @@ class ConversationInfoActivity :
|
|||
RECORDING_CONSENT_NOT_REQUIRED_FOR_CONVERSATION
|
||||
}
|
||||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||
|
||||
ncApi.setRecordingConsent(
|
||||
ApiUtils.getCredentials(conversationUser.username, conversationUser.token),
|
||||
ApiUtils.getUrlForRecordingConsent(apiVersion, conversationUser.baseUrl, conversation!!.token),
|
||||
ApiUtils.getUrlForRecordingConsent(apiVersion, conversationUser.baseUrl!!, conversation!!.token),
|
||||
state
|
||||
)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
|
@ -831,8 +862,8 @@ class ConversationInfoActivity :
|
|||
}
|
||||
|
||||
private fun initExpiringMessageOption() {
|
||||
if (conversation!!.isParticipantOwnerOrModerator &&
|
||||
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "message-expiration")
|
||||
if (ConversationUtils.isParticipantOwnerOrModerator(conversation!!) &&
|
||||
CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.MESSAGE_EXPIRATION)
|
||||
) {
|
||||
databaseStorageModule?.setMessageExpiration(conversation!!.messageExpiration)
|
||||
val value = databaseStorageModule!!.getString("conversation_settings_dropdown", "")
|
||||
|
@ -855,13 +886,16 @@ class ConversationInfoActivity :
|
|||
|
||||
private fun adjustNotificationLevelUI() {
|
||||
if (conversation != null) {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels")) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.NOTIFICATION_LEVELS)) {
|
||||
binding.notificationSettingsView.conversationInfoMessageNotificationsDropdown.isEnabled = true
|
||||
binding.notificationSettingsView.conversationInfoMessageNotificationsDropdown.alpha = 1.0f
|
||||
|
||||
if (conversation!!.notificationLevel != Conversation.NotificationLevel.DEFAULT) {
|
||||
if (conversation!!.notificationLevel != NotificationLevel.DEFAULT) {
|
||||
val stringValue: String =
|
||||
when (EnumNotificationLevelConverter().convertToInt(conversation!!.notificationLevel)) {
|
||||
when (
|
||||
DomainEnumNotificationLevelConverter()
|
||||
.convertToInt(conversation!!.notificationLevel!!)
|
||||
) {
|
||||
NOTIFICATION_LEVEL_ALWAYS -> resources.getString(R.string.nc_notify_me_always)
|
||||
NOTIFICATION_LEVEL_MENTION -> resources.getString(R.string.nc_notify_me_mention)
|
||||
NOTIFICATION_LEVEL_NEVER -> resources.getString(R.string.nc_notify_me_never)
|
||||
|
@ -885,9 +919,9 @@ class ConversationInfoActivity :
|
|||
}
|
||||
}
|
||||
|
||||
private fun setProperNotificationValue(conversation: Conversation?) {
|
||||
if (conversation!!.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag")) {
|
||||
private fun setProperNotificationValue(conversation: ConversationModel?) {
|
||||
if (conversation!!.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.MENTION_FLAG)) {
|
||||
binding.notificationSettingsView.conversationInfoMessageNotificationsDropdown.setText(
|
||||
resources.getString(R.string.nc_notify_me_always)
|
||||
)
|
||||
|
@ -905,7 +939,7 @@ class ConversationInfoActivity :
|
|||
|
||||
private fun loadConversationAvatar() {
|
||||
when (conversation!!.type) {
|
||||
Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL -> if (!TextUtils.isEmpty(conversation!!.name)) {
|
||||
ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL -> if (!TextUtils.isEmpty(conversation!!.name)) {
|
||||
conversation!!.name?.let {
|
||||
binding.avatarImage.loadUserAvatar(
|
||||
conversationUser,
|
||||
|
@ -916,7 +950,7 @@ class ConversationInfoActivity :
|
|||
}
|
||||
}
|
||||
|
||||
Conversation.ConversationType.ROOM_GROUP_CALL, Conversation.ConversationType.ROOM_PUBLIC_CALL -> {
|
||||
ConversationType.ROOM_GROUP_CALL, ConversationType.ROOM_PUBLIC_CALL -> {
|
||||
binding.avatarImage.loadConversationAvatar(
|
||||
conversationUser,
|
||||
conversation!!,
|
||||
|
@ -925,15 +959,12 @@ class ConversationInfoActivity :
|
|||
)
|
||||
}
|
||||
|
||||
Conversation.ConversationType.ROOM_SYSTEM -> {
|
||||
ConversationType.ROOM_SYSTEM -> {
|
||||
binding.avatarImage.loadSystemAvatar()
|
||||
}
|
||||
|
||||
Conversation.ConversationType.DUMMY -> {
|
||||
if (ConversationUtils.isNoteToSelfConversation(
|
||||
ConversationModel.mapToConversationModel(conversation!!)
|
||||
)
|
||||
) {
|
||||
ConversationType.DUMMY -> {
|
||||
if (ConversationUtils.isNoteToSelfConversation(conversation!!)) {
|
||||
binding.avatarImage.loadNoteToSelfAvatar()
|
||||
}
|
||||
}
|
||||
|
@ -971,7 +1002,7 @@ class ConversationInfoActivity :
|
|||
credentials,
|
||||
ApiUtils.getUrlForRoomModerators(
|
||||
apiVersion,
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token
|
||||
),
|
||||
participant.attendeeId
|
||||
|
@ -986,7 +1017,7 @@ class ConversationInfoActivity :
|
|||
credentials,
|
||||
ApiUtils.getUrlForRoomModerators(
|
||||
apiVersion,
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token
|
||||
),
|
||||
participant.attendeeId
|
||||
|
@ -1022,7 +1053,7 @@ class ConversationInfoActivity :
|
|||
credentials,
|
||||
ApiUtils.getUrlForRoomModerators(
|
||||
apiVersion,
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token
|
||||
),
|
||||
participant.userId
|
||||
|
@ -1035,7 +1066,7 @@ class ConversationInfoActivity :
|
|||
credentials,
|
||||
ApiUtils.getUrlForRoomModerators(
|
||||
apiVersion,
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token
|
||||
),
|
||||
participant.userId
|
||||
|
@ -1047,12 +1078,12 @@ class ConversationInfoActivity :
|
|||
}
|
||||
|
||||
private fun removeAttendeeFromConversation(apiVersion: Int, participant: Participant) {
|
||||
if (apiVersion >= ApiUtils.APIv4) {
|
||||
if (apiVersion >= ApiUtils.API_V4) {
|
||||
ncApi.removeAttendeeFromConversation(
|
||||
credentials,
|
||||
ApiUtils.getUrlForAttendees(
|
||||
apiVersion,
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token
|
||||
),
|
||||
participant.attendeeId
|
||||
|
@ -1084,7 +1115,7 @@ class ConversationInfoActivity :
|
|||
ncApi.removeParticipantFromConversation(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRemovingParticipantFromConversation(
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token,
|
||||
true
|
||||
),
|
||||
|
@ -1114,7 +1145,7 @@ class ConversationInfoActivity :
|
|||
ncApi.removeParticipantFromConversation(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRemovingParticipantFromConversation(
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token,
|
||||
false
|
||||
),
|
||||
|
@ -1146,14 +1177,14 @@ class ConversationInfoActivity :
|
|||
|
||||
@SuppressLint("CheckResult")
|
||||
override fun onItemClick(view: View?, position: Int): Boolean {
|
||||
if (!conversation!!.canModerate(conversationUser)) {
|
||||
if (ConversationUtils.canModerate(conversation!!, spreedCapabilities)) {
|
||||
return true
|
||||
}
|
||||
|
||||
val userItem = adapter?.getItem(position) as ParticipantItem
|
||||
val participant = userItem.model
|
||||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||
|
||||
if (participant.calculatedActorType == USERS && participant.calculatedActorId == conversationUser.userId) {
|
||||
if (participant.attendeePin?.isNotEmpty() == true) {
|
||||
|
@ -1277,7 +1308,7 @@ class ConversationInfoActivity :
|
|||
// Pin, nothing to do
|
||||
} else if (actionToTrigger == 1) {
|
||||
// Promote/demote
|
||||
if (apiVersion >= ApiUtils.APIv4) {
|
||||
if (apiVersion >= ApiUtils.API_V4) {
|
||||
toggleModeratorStatus(apiVersion, participant)
|
||||
} else {
|
||||
toggleModeratorStatusLegacy(apiVersion, participant)
|
||||
|
|
|
@ -11,8 +11,11 @@ import com.nextcloud.talk.R
|
|||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.ActivityConversationInfoBinding
|
||||
import com.nextcloud.talk.databinding.DialogPasswordBinding
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.domain.ConversationType
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepository
|
||||
import com.nextcloud.talk.utils.ConversationUtils
|
||||
import com.nextcloud.talk.utils.Mimetype
|
||||
import com.nextcloud.talk.utils.ShareUtils
|
||||
import io.reactivex.Observer
|
||||
|
@ -23,7 +26,8 @@ import io.reactivex.schedulers.Schedulers
|
|||
class GuestAccessHelper(
|
||||
private val activity: ConversationInfoActivity,
|
||||
private val binding: ActivityConversationInfoBinding,
|
||||
private val conversation: Conversation,
|
||||
private val conversation: ConversationModel,
|
||||
private val spreedCapabilities: SpreedCapability,
|
||||
private val conversationUser: User
|
||||
) {
|
||||
|
||||
|
@ -32,13 +36,13 @@ class GuestAccessHelper(
|
|||
private val context = activity.context
|
||||
|
||||
fun setupGuestAccess() {
|
||||
if (conversation.canModerate(conversationUser)) {
|
||||
if (ConversationUtils.canModerate(conversation, spreedCapabilities)) {
|
||||
binding.guestAccessView.guestAccessSettings.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.guestAccessView.guestAccessSettings.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (conversation.type == Conversation.ConversationType.ROOM_PUBLIC_CALL) {
|
||||
if (conversation.type == ConversationType.ROOM_PUBLIC_CALL) {
|
||||
binding.guestAccessView.allowGuestsSwitch.isChecked = true
|
||||
showAllOptions()
|
||||
if (conversation.hasPassword) {
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Marcel Hibbe
|
||||
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||
*
|
||||
* 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.conversationinfo.viewmodel
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.nextcloud.talk.chat.data.ChatRepository
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import javax.inject.Inject
|
||||
|
||||
class ConversationInfoViewModel @Inject constructor(
|
||||
private val chatRepository: ChatRepository
|
||||
) : ViewModel() {
|
||||
|
||||
object LifeCycleObserver : DefaultLifecycleObserver {
|
||||
enum class LifeCycleFlag {
|
||||
PAUSED,
|
||||
RESUMED
|
||||
}
|
||||
lateinit var currentLifeCycleFlag: LifeCycleFlag
|
||||
public val disposableSet = mutableSetOf<Disposable>()
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
super.onResume(owner)
|
||||
currentLifeCycleFlag = LifeCycleFlag.RESUMED
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
super.onPause(owner)
|
||||
currentLifeCycleFlag = LifeCycleFlag.PAUSED
|
||||
disposableSet.forEach { disposable -> disposable.dispose() }
|
||||
disposableSet.clear()
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface ViewState
|
||||
|
||||
object GetRoomStartState : ViewState
|
||||
object GetRoomErrorState : ViewState
|
||||
open class GetRoomSuccessState(val conversationModel: ConversationModel) : ViewState
|
||||
|
||||
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(GetRoomStartState)
|
||||
val viewState: LiveData<ViewState>
|
||||
get() = _viewState
|
||||
|
||||
object GetCapabilitiesStartState : ViewState
|
||||
object GetCapabilitiesErrorState : ViewState
|
||||
open class GetCapabilitiesSuccessState(val spreedCapabilities: SpreedCapability) : ViewState
|
||||
|
||||
private val _getCapabilitiesViewState: MutableLiveData<ViewState> = MutableLiveData(GetCapabilitiesStartState)
|
||||
val getCapabilitiesViewState: LiveData<ViewState>
|
||||
get() = _getCapabilitiesViewState
|
||||
|
||||
fun getRoom(user: User, token: String) {
|
||||
_viewState.value = GetRoomStartState
|
||||
chatRepository.getRoom(user, token)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(GetRoomObserver())
|
||||
}
|
||||
|
||||
fun getCapabilities(user: User, token: String, conversationModel: ConversationModel) {
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesStartState
|
||||
|
||||
if (conversationModel.remoteServer.isNullOrEmpty()) {
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesSuccessState(user.capabilities!!.spreedCapability!!)
|
||||
} else {
|
||||
chatRepository.getCapabilities(user, token)
|
||||
.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<SpreedCapability> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
LifeCycleObserver.disposableSet.add(d)
|
||||
}
|
||||
|
||||
override fun onNext(spreedCapabilities: SpreedCapability) {
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesSuccessState(spreedCapabilities)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e(TAG, "Error when fetching spreed capabilities", e)
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesErrorState
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
// unused atm
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
inner class GetRoomObserver : Observer<ConversationModel> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
// unused atm
|
||||
}
|
||||
|
||||
override fun onNext(conversationModel: ConversationModel) {
|
||||
_viewState.value = GetRoomSuccessState(conversationModel)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e(TAG, "Error when fetching room")
|
||||
_viewState.value = GetRoomErrorState
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
// unused atm
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = ConversationInfoViewModel::class.simpleName
|
||||
}
|
||||
}
|
|
@ -49,11 +49,12 @@ import com.nextcloud.talk.extensions.loadSystemAvatar
|
|||
import com.nextcloud.talk.extensions.loadUserAvatar
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.domain.ConversationType
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.utils.PickImage
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
|
@ -87,6 +88,8 @@ class ConversationInfoEditActivity :
|
|||
|
||||
private lateinit var pickImage: PickImage
|
||||
|
||||
private lateinit var spreedCapabilities: SpreedCapability
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||
|
@ -110,7 +113,7 @@ class ConversationInfoEditActivity :
|
|||
viewThemeUtils.material.colorTextInputLayout(binding.conversationNameInputLayout)
|
||||
viewThemeUtils.material.colorTextInputLayout(binding.conversationDescriptionInputLayout)
|
||||
|
||||
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)
|
||||
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)!!
|
||||
|
||||
pickImage = PickImage(this, conversationUser)
|
||||
|
||||
|
@ -127,13 +130,15 @@ class ConversationInfoEditActivity :
|
|||
is ConversationInfoEditViewModel.GetRoomSuccessState -> {
|
||||
conversation = state.conversationModel
|
||||
|
||||
spreedCapabilities = conversationUser.capabilities!!.spreedCapability!!
|
||||
|
||||
binding.conversationName.setText(conversation!!.displayName)
|
||||
|
||||
if (conversation!!.description != null && conversation!!.description!!.isNotEmpty()) {
|
||||
binding.conversationDescription.setText(conversation!!.description)
|
||||
}
|
||||
|
||||
if (!CapabilitiesUtilNew.isConversationDescriptionEndpointAvailable(conversationUser)) {
|
||||
if (!CapabilitiesUtil.isConversationDescriptionEndpointAvailable(spreedCapabilities)) {
|
||||
binding.conversationDescription.isEnabled = false
|
||||
}
|
||||
|
||||
|
@ -221,13 +226,13 @@ class ConversationInfoEditActivity :
|
|||
|
||||
private fun saveConversationNameAndDescription() {
|
||||
val apiVersion =
|
||||
ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1))
|
||||
ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
|
||||
|
||||
ncApi.renameRoom(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoom(
|
||||
apiVersion,
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token
|
||||
),
|
||||
binding.conversationName.text.toString()
|
||||
|
@ -241,7 +246,7 @@ class ConversationInfoEditActivity :
|
|||
}
|
||||
|
||||
override fun onNext(genericOverall: GenericOverall) {
|
||||
if (CapabilitiesUtilNew.isConversationDescriptionEndpointAvailable(conversationUser)) {
|
||||
if (CapabilitiesUtil.isConversationDescriptionEndpointAvailable(spreedCapabilities)) {
|
||||
saveConversationDescription()
|
||||
} else {
|
||||
finish()
|
||||
|
@ -265,13 +270,13 @@ class ConversationInfoEditActivity :
|
|||
|
||||
fun saveConversationDescription() {
|
||||
val apiVersion =
|
||||
ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1))
|
||||
ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
|
||||
|
||||
ncApi.setConversationDescription(
|
||||
credentials,
|
||||
ApiUtils.getUrlForConversationDescription(
|
||||
apiVersion,
|
||||
conversationUser.baseUrl,
|
||||
conversationUser.baseUrl!!,
|
||||
conversation!!.token
|
||||
),
|
||||
binding.conversationDescription.text.toString()
|
||||
|
|
|
@ -36,9 +36,9 @@ class ConversationInfoEditRepositoryImpl(private val ncApi: NcApi, currentUserPr
|
|||
ConversationInfoEditRepository {
|
||||
|
||||
val currentUser: User = currentUserProvider.currentUser.blockingGet()
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv3, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))
|
||||
|
||||
override fun uploadConversationAvatar(user: User, file: File, roomToken: String): Observable<ConversationModel> {
|
||||
val builder = MultipartBody.Builder()
|
||||
|
@ -56,7 +56,7 @@ class ConversationInfoEditRepositoryImpl(private val ncApi: NcApi, currentUserPr
|
|||
|
||||
return ncApi.uploadConversationAvatar(
|
||||
credentials,
|
||||
ApiUtils.getUrlForConversationAvatar(1, user.baseUrl, roomToken),
|
||||
ApiUtils.getUrlForConversationAvatar(1, user.baseUrl!!, roomToken),
|
||||
filePart
|
||||
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!) }
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class ConversationInfoEditRepositoryImpl(private val ncApi: NcApi, currentUserPr
|
|||
override fun deleteConversationAvatar(user: User, roomToken: String): Observable<ConversationModel> {
|
||||
return ncApi.deleteConversationAvatar(
|
||||
credentials,
|
||||
ApiUtils.getUrlForConversationAvatar(1, user.baseUrl, roomToken)
|
||||
ApiUtils.getUrlForConversationAvatar(1, user.baseUrl!!, roomToken)
|
||||
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ import com.nextcloud.talk.ui.dialog.ConversationsListBottomDialog
|
|||
import com.nextcloud.talk.ui.dialog.FilterConversationFragment
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.ClosedInterfaceImpl
|
||||
import com.nextcloud.talk.utils.FileUtils
|
||||
import com.nextcloud.talk.utils.Mimetype
|
||||
|
@ -130,10 +131,10 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NEW_CONVERSATION
|
|||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SHARED_TEXT
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isServerEOL
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isUnifiedSearchAvailable
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isUserStatusAvailable
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.isServerEOL
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.isUnifiedSearchAvailable
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.isUserStatusAvailable
|
||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
||||
import com.nextcloud.talk.utils.power.PowerManagerUtils
|
||||
import com.nextcloud.talk.utils.rx.SearchViewObservable.Companion.observeSearchView
|
||||
|
@ -283,11 +284,11 @@ class ConversationsListActivity :
|
|||
}
|
||||
currentUser = userManager.currentUser.blockingGet()
|
||||
if (currentUser != null) {
|
||||
if (isServerEOL(currentUser!!.capabilities)) {
|
||||
if (isServerEOL(currentUser!!.serverVersion!!.major)) {
|
||||
showServerEOLDialog()
|
||||
return
|
||||
}
|
||||
if (isUnifiedSearchAvailable(currentUser!!)) {
|
||||
if (isUnifiedSearchAvailable(currentUser!!.capabilities!!.spreedCapability!!)) {
|
||||
searchHelper = MessageSearchHelper(unifiedSearchRepository)
|
||||
}
|
||||
credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
|
||||
|
@ -423,7 +424,7 @@ class ConversationsListActivity :
|
|||
private fun loadUserAvatar(target: Target) {
|
||||
if (currentUser != null) {
|
||||
val url = ApiUtils.getUrlForAvatar(
|
||||
currentUser!!.baseUrl,
|
||||
currentUser!!.baseUrl!!,
|
||||
currentUser!!.userId,
|
||||
true
|
||||
)
|
||||
|
@ -433,7 +434,7 @@ class ConversationsListActivity :
|
|||
context.imageLoader.enqueue(
|
||||
ImageRequest.Builder(context)
|
||||
.data(url)
|
||||
.addHeader("Authorization", credentials)
|
||||
.addHeader("Authorization", credentials!!)
|
||||
.placeholder(R.drawable.ic_user)
|
||||
.transformations(CircleCropTransformation())
|
||||
.crossfade(true)
|
||||
|
@ -698,7 +699,10 @@ class ConversationsListActivity :
|
|||
isRefreshing = true
|
||||
conversationItems = ArrayList()
|
||||
conversationItemsWithHeader = ArrayList()
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv3, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||
currentUser!!,
|
||||
intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1)
|
||||
)
|
||||
val startNanoTime = System.nanoTime()
|
||||
Log.d(TAG, "fetchData - getRooms - calling: $startNanoTime")
|
||||
roomsQueryDisposable = ncApi.getRooms(
|
||||
|
@ -868,11 +872,15 @@ class ConversationsListActivity :
|
|||
private fun fetchOpenConversations(apiVersion: Int) {
|
||||
searchableConversationItems.clear()
|
||||
searchableConversationItems.addAll(conversationItemsWithHeader)
|
||||
if (hasSpreedFeatureCapability(currentUser, "listable-rooms")) {
|
||||
if (hasSpreedFeatureCapability(
|
||||
currentUser!!.capabilities!!.spreedCapability!!,
|
||||
SpreedFeatures.LISTABLE_ROOMS
|
||||
)
|
||||
) {
|
||||
val openConversationItems: MutableList<AbstractFlexibleItem<*>> = ArrayList()
|
||||
openConversationsQueryDisposable = ncApi.getOpenConversations(
|
||||
credentials,
|
||||
ApiUtils.getUrlForOpenConversations(apiVersion, currentUser!!.baseUrl)
|
||||
ApiUtils.getUrlForOpenConversations(apiVersion, currentUser!!.baseUrl!!)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -1087,7 +1095,7 @@ class ConversationsListActivity :
|
|||
clearMessageSearchResults()
|
||||
adapter!!.setFilter(filter)
|
||||
adapter!!.filterItems()
|
||||
if (isUnifiedSearchAvailable(currentUser!!)) {
|
||||
if (isUnifiedSearchAvailable(currentUser!!.capabilities!!.spreedCapability!!)) {
|
||||
startMessageSearch(filter)
|
||||
}
|
||||
} else {
|
||||
|
@ -1173,7 +1181,11 @@ class ConversationsListActivity :
|
|||
private fun handleConversation(conversation: Conversation?) {
|
||||
selectedConversation = conversation
|
||||
if (selectedConversation != null) {
|
||||
val hasChatPermission = ParticipantPermissions(currentUser!!, selectedConversation!!).hasChatPermission()
|
||||
val hasChatPermission = ParticipantPermissions(
|
||||
currentUser!!.capabilities!!.spreedCapability!!,
|
||||
selectedConversation!!
|
||||
)
|
||||
.hasChatPermission()
|
||||
if (showShareToScreen) {
|
||||
if (hasChatPermission &&
|
||||
!isReadOnlyConversation(selectedConversation!!) &&
|
||||
|
@ -1197,7 +1209,10 @@ class ConversationsListActivity :
|
|||
}
|
||||
|
||||
private fun shouldShowLobby(conversation: Conversation): Boolean {
|
||||
val participantPermissions = ParticipantPermissions(currentUser!!, conversation)
|
||||
val participantPermissions = ParticipantPermissions(
|
||||
currentUser!!.capabilities?.spreedCapability!!,
|
||||
conversation
|
||||
)
|
||||
return conversation.lobbyState == Conversation.LobbyState.LOBBY_STATE_MODERATORS_ONLY &&
|
||||
!conversation.canModerate(currentUser!!) &&
|
||||
!participantPermissions.canIgnoreLobby()
|
||||
|
@ -1511,7 +1526,7 @@ class ConversationsListActivity :
|
|||
.setNegativeButton(R.string.nc_settings_reauthorize) { _, _ ->
|
||||
val intent = Intent(context, WebViewLoginActivity::class.java)
|
||||
val bundle = Bundle()
|
||||
bundle.putString(BundleKeys.KEY_BASE_URL, currentUser!!.baseUrl)
|
||||
bundle.putString(BundleKeys.KEY_BASE_URL, currentUser!!.baseUrl!!)
|
||||
bundle.putBoolean(BundleKeys.KEY_REAUTHORIZE_ACCOUNT, true)
|
||||
intent.putExtras(bundle)
|
||||
startActivity(intent)
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.nextcloud.talk.callnotification.viewmodel.CallNotificationViewModel
|
|||
import com.nextcloud.talk.chat.viewmodels.ChatViewModel
|
||||
import com.nextcloud.talk.conversation.viewmodel.ConversationViewModel
|
||||
import com.nextcloud.talk.conversation.viewmodel.RenameConversationViewModel
|
||||
import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel
|
||||
import com.nextcloud.talk.conversationinfoedit.viewmodel.ConversationInfoEditViewModel
|
||||
import com.nextcloud.talk.conversationlist.viewmodels.ConversationsListViewModel
|
||||
import com.nextcloud.talk.invitation.viewmodels.InvitationsViewModel
|
||||
|
@ -137,6 +138,11 @@ abstract class ViewModelModule {
|
|||
@ViewModelKey(CallNotificationViewModel::class)
|
||||
abstract fun callNotificationViewModel(viewModel: CallNotificationViewModel): ViewModel
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(ConversationInfoViewModel::class)
|
||||
abstract fun conversationInfoViewModel(viewModel: ConversationInfoViewModel): ViewModel
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(ConversationInfoEditViewModel::class)
|
||||
|
|
|
@ -36,7 +36,7 @@ object UserMapper {
|
|||
entity.id,
|
||||
entity.userId,
|
||||
entity.username,
|
||||
entity.baseUrl,
|
||||
entity.baseUrl!!,
|
||||
entity.token,
|
||||
entity.displayName,
|
||||
entity.pushConfigurationState,
|
||||
|
@ -52,8 +52,8 @@ object UserMapper {
|
|||
|
||||
fun toEntity(model: User): UserEntity {
|
||||
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)
|
||||
null -> UserEntity(userId = model.userId, username = model.username, baseUrl = model.baseUrl!!)
|
||||
else -> UserEntity(id, model.userId, model.username, model.baseUrl!!)
|
||||
}
|
||||
userEntity.apply {
|
||||
token = model.token
|
||||
|
|
|
@ -45,7 +45,7 @@ data class User(
|
|||
var scheduledForDeletion: Boolean = FALSE
|
||||
) : Parcelable {
|
||||
|
||||
fun getCredentials(): String = ApiUtils.getCredentials(username, token)
|
||||
fun getCredentials(): String = ApiUtils.getCredentials(username, token)!!
|
||||
|
||||
fun hasSpreedFeatureCapability(capabilityName: String): Boolean {
|
||||
return capabilities?.spreedCapability?.features?.contains(capabilityName) ?: false
|
||||
|
|
|
@ -118,7 +118,7 @@ fun ImageView.loadUserAvatar(
|
|||
ignoreCache: Boolean
|
||||
): io.reactivex.disposables.Disposable {
|
||||
val imageRequestUri = ApiUtils.getUrlForAvatar(
|
||||
user.baseUrl,
|
||||
user.baseUrl!!,
|
||||
avatarId,
|
||||
requestBigSize
|
||||
)
|
||||
|
@ -155,7 +155,7 @@ private fun ImageView.loadAvatarInternal(
|
|||
user?.let {
|
||||
addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(user.username, user.token)
|
||||
ApiUtils.getCredentials(user.username, user.token)!!
|
||||
)
|
||||
}
|
||||
transformations(CircleCropTransformation())
|
||||
|
@ -196,7 +196,7 @@ fun ImageView.loadThumbnail(url: String, user: User): io.reactivex.disposables.D
|
|||
) {
|
||||
requestBuilder.addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(user.username, user.token)
|
||||
ApiUtils.getCredentials(user.username, user.token)!!
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ fun ImageView.loadImage(url: String, user: User, placeholder: Drawable? = null):
|
|||
) {
|
||||
requestBuilder.addHeader(
|
||||
"Authorization",
|
||||
ApiUtils.getCredentials(user.username, user.token)
|
||||
ApiUtils.getCredentials(user.username, user.token)!!
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -29,29 +29,29 @@ class InvitationsRepositoryImpl(private val ncApi: NcApi) :
|
|||
InvitationsRepository {
|
||||
|
||||
override fun fetchInvitations(user: User): Observable<InvitationsModel> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
|
||||
return ncApi.getInvitations(
|
||||
credentials,
|
||||
ApiUtils.getUrlForInvitation(user.baseUrl)
|
||||
ApiUtils.getUrlForInvitation(user.baseUrl!!)
|
||||
).map { mapToInvitationsModel(user, it.ocs?.data!!) }
|
||||
}
|
||||
|
||||
override fun acceptInvitation(user: User, invitation: Invitation): Observable<InvitationActionModel> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
|
||||
return ncApi.acceptInvitation(
|
||||
credentials,
|
||||
ApiUtils.getUrlForInvitationAccept(user.baseUrl, invitation.id)
|
||||
ApiUtils.getUrlForInvitationAccept(user.baseUrl!!, invitation.id)
|
||||
).map { InvitationActionModel(ActionEnum.ACCEPT, it.ocs?.meta?.statusCode!!, invitation) }
|
||||
}
|
||||
|
||||
override fun rejectInvitation(user: User, invitation: Invitation): Observable<InvitationActionModel> {
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
|
||||
return ncApi.rejectInvitation(
|
||||
credentials,
|
||||
ApiUtils.getUrlForInvitationReject(user.baseUrl, invitation.id)
|
||||
ApiUtils.getUrlForInvitationReject(user.baseUrl!!, invitation.id)
|
||||
).map { InvitationActionModel(ActionEnum.REJECT, it.ocs?.meta?.statusCode!!, invitation) }
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ public class AddParticipantsToConversation extends Worker {
|
|||
data.getLong(BundleKeys.KEY_INTERNAL_USER_ID, -1))
|
||||
.blockingGet();
|
||||
|
||||
int apiVersion = ApiUtils.getConversationApiVersion(user, new int[] {ApiUtils.APIv4, 1});
|
||||
int apiVersion = ApiUtils.getConversationApiVersion(user, new int[] {ApiUtils.API_V4, 1});
|
||||
|
||||
String conversationToken = data.getString(BundleKeys.KEY_TOKEN);
|
||||
String credentials = ApiUtils.getCredentials(user.getUsername(), user.getToken());
|
||||
|
|
|
@ -129,7 +129,7 @@ class ContactAddressBookWorker(val context: Context, workerParameters: WorkerPar
|
|||
|
||||
ncApi.searchContactsByPhoneNumber(
|
||||
ApiUtils.getCredentials(currentUser.username, currentUser.token),
|
||||
ApiUtils.getUrlForSearchByNumber(currentUser.baseUrl),
|
||||
ApiUtils.getUrlForSearchByNumber(currentUser.baseUrl!!),
|
||||
json.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
|
|
@ -80,7 +80,7 @@ public class DeleteConversationWorker extends Worker {
|
|||
User operationUser = userManager.getUserWithId(operationUserId).blockingGet();
|
||||
|
||||
if (operationUser != null) {
|
||||
int apiVersion = ApiUtils.getConversationApiVersion(operationUser, new int[]{ApiUtils.APIv4, 1});
|
||||
int apiVersion = ApiUtils.getConversationApiVersion(operationUser, new int[]{ApiUtils.API_V4, 1});
|
||||
|
||||
String credentials = ApiUtils.getCredentials(operationUser.getUsername(), operationUser.getToken());
|
||||
ncApi = retrofit
|
||||
|
|
|
@ -92,7 +92,7 @@ public class LeaveConversationWorker extends Worker {
|
|||
EventStatus.EventType.CONVERSATION_UPDATE,
|
||||
true);
|
||||
|
||||
int apiVersion = ApiUtils.getConversationApiVersion(operationUser, new int[] {ApiUtils.APIv4, 1});
|
||||
int apiVersion = ApiUtils.getConversationApiVersion(operationUser, new int[] {ApiUtils.API_V4, 1});
|
||||
|
||||
ncApi.removeSelfFromRoom(credentials, ApiUtils.getUrlForParticipantsSelf(apiVersion,
|
||||
operationUser.getBaseUrl(),
|
||||
|
|
|
@ -248,7 +248,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
|
||||
val soundUri = getCallRingtoneUri(applicationContext, appPreferences)
|
||||
val notificationChannelId = NotificationUtils.NotificationChannels.NOTIFICATION_CHANNEL_CALLS_V4.name
|
||||
val uri = Uri.parse(signatureVerification.user!!.baseUrl)
|
||||
val uri = Uri.parse(signatureVerification.user!!.baseUrl!!)
|
||||
val baseUrl = uri.host
|
||||
|
||||
val notification =
|
||||
|
@ -279,7 +279,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
credentials = ApiUtils.getCredentials(
|
||||
signatureVerification.user!!.username,
|
||||
signatureVerification.user!!.token
|
||||
)
|
||||
)!!
|
||||
ncApi = retrofit!!.newBuilder().client(
|
||||
okHttpClient!!.newBuilder().cookieJar(
|
||||
JavaNetCookieJar(
|
||||
|
@ -338,7 +338,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
ncApi.getNcNotification(
|
||||
credentials,
|
||||
ApiUtils.getUrlForNcNotificationWithId(
|
||||
user!!.baseUrl,
|
||||
user!!.baseUrl!!,
|
||||
(pushMessage.notificationId!!).toString()
|
||||
)
|
||||
)
|
||||
|
@ -451,7 +451,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
0
|
||||
}
|
||||
val pendingIntent = PendingIntent.getActivity(context, requestCode, intent, intentFlag)
|
||||
val uri = Uri.parse(signatureVerification.user!!.baseUrl)
|
||||
val uri = Uri.parse(signatureVerification.user!!.baseUrl!!)
|
||||
val baseUrl = uri.host
|
||||
|
||||
var contentTitle: CharSequence? = ""
|
||||
|
@ -601,12 +601,12 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
val baseUrl = signatureVerification.user!!.baseUrl
|
||||
val avatarUrl = if ("user" == userType) {
|
||||
ApiUtils.getUrlForAvatar(
|
||||
baseUrl,
|
||||
baseUrl!!,
|
||||
notificationUser.id,
|
||||
false
|
||||
)
|
||||
} else {
|
||||
ApiUtils.getUrlForGuestAvatar(baseUrl, notificationUser.name, false)
|
||||
ApiUtils.getUrlForGuestAvatar(baseUrl!!, notificationUser.name, false)
|
||||
}
|
||||
person.setIcon(loadAvatarSync(avatarUrl, context!!))
|
||||
}
|
||||
|
@ -840,8 +840,8 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
var inCallOnDifferentDevice = false
|
||||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||
signatureVerification.user,
|
||||
intArrayOf(ApiUtils.APIv4, 1)
|
||||
signatureVerification.user!!,
|
||||
intArrayOf(ApiUtils.API_V4, 1)
|
||||
)
|
||||
|
||||
var isCallNotificationVisible = true
|
||||
|
@ -850,8 +850,8 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
credentials,
|
||||
ApiUtils.getUrlForCall(
|
||||
apiVersion,
|
||||
signatureVerification.user!!.baseUrl,
|
||||
pushMessage.id
|
||||
signatureVerification.user!!.baseUrl!!,
|
||||
pushMessage.id!!
|
||||
)
|
||||
)
|
||||
.repeatWhen { completed ->
|
||||
|
@ -920,10 +920,10 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
|
||||
if (isOngoingCallNotificationVisible) {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||
signatureVerification.user,
|
||||
signatureVerification.user!!,
|
||||
intArrayOf(
|
||||
ApiUtils.APIv4,
|
||||
ApiUtils.APIv3,
|
||||
ApiUtils.API_V4,
|
||||
ApiUtils.API_V3,
|
||||
1
|
||||
)
|
||||
)
|
||||
|
@ -931,7 +931,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
credentials,
|
||||
ApiUtils.getUrlForRoom(
|
||||
apiVersion,
|
||||
signatureVerification.user?.baseUrl,
|
||||
signatureVerification.user?.baseUrl!!,
|
||||
pushMessage.id
|
||||
)
|
||||
)
|
||||
|
|
|
@ -62,7 +62,7 @@ class ShareOperationWorker(context: Context, workerParams: WorkerParameters) : W
|
|||
for (filePath in filesArray) {
|
||||
ncApi.createRemoteShare(
|
||||
credentials,
|
||||
ApiUtils.getSharingUrl(baseUrl),
|
||||
ApiUtils.getSharingUrl(baseUrl!!),
|
||||
filePath,
|
||||
roomToken,
|
||||
"10",
|
||||
|
@ -87,7 +87,7 @@ class ShareOperationWorker(context: Context, workerParams: WorkerParameters) : W
|
|||
|
||||
val operationsUser = userManager.getUserWithId(userId).blockingGet()
|
||||
baseUrl = operationsUser.baseUrl
|
||||
credentials = ApiUtils.getCredentials(operationsUser.username, operationsUser.token)
|
||||
credentials = ApiUtils.getCredentials(operationsUser.username, operationsUser.token)!!
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -85,7 +85,7 @@ public class SignalingSettingsWorker extends Worker {
|
|||
|
||||
for (User user : userEntityObjectList) {
|
||||
|
||||
int apiVersion = ApiUtils.getSignalingApiVersion(user, new int[] {ApiUtils.APIv3, 2, 1});
|
||||
int apiVersion = ApiUtils.getSignalingApiVersion(user, new int[] {ApiUtils.API_V3, 2, 1});
|
||||
|
||||
ncApi.getSignalingSettings(
|
||||
ApiUtils.getCredentials(user.getUsername(), user.getToken()),
|
||||
|
|
|
@ -56,7 +56,7 @@ import com.nextcloud.talk.utils.RemoteFileUtils
|
|||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
|
@ -186,7 +186,9 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
}
|
||||
|
||||
private fun getRemotePath(currentUser: User): String {
|
||||
var remotePath = CapabilitiesUtilNew.getAttachmentFolder(currentUser)!! + "/" + fileName
|
||||
var remotePath = CapabilitiesUtil.getAttachmentFolder(
|
||||
currentUser.capabilities!!.spreedCapability!!
|
||||
) + "/" + fileName
|
||||
remotePath = RemoteFileUtils.getNewPathIfFileExists(
|
||||
ncApi,
|
||||
currentUser,
|
||||
|
|
|
@ -64,6 +64,7 @@ class GeocodingActivity :
|
|||
lateinit var okHttpClient: OkHttpClient
|
||||
|
||||
lateinit var roomToken: String
|
||||
private var chatApiVersion: Int = 1
|
||||
private var nominatimClient: TalkJsonNominatimClient? = null
|
||||
|
||||
private var searchItem: MenuItem? = null
|
||||
|
@ -86,6 +87,7 @@ class GeocodingActivity :
|
|||
Configuration.getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context))
|
||||
|
||||
roomToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)!!
|
||||
chatApiVersion = intent.getIntExtra(BundleKeys.KEY_CHAT_API_VERSION, 1)
|
||||
|
||||
recyclerView = findViewById(R.id.geocoding_results)
|
||||
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
|
@ -130,6 +132,7 @@ class GeocodingActivity :
|
|||
val intent = Intent(this@GeocodingActivity, LocationPickerActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken)
|
||||
intent.putExtra(BundleKeys.KEY_CHAT_API_VERSION, chatApiVersion)
|
||||
intent.putExtra(BundleKeys.KEY_GEOCODING_RESULT, geocodingResult)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
@ -158,6 +161,7 @@ class GeocodingActivity :
|
|||
val intent = Intent(this@GeocodingActivity, LocationPickerActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken)
|
||||
intent.putExtra(BundleKeys.KEY_CHAT_API_VERSION, chatApiVersion)
|
||||
intent.putExtra(BundleKeys.KEY_GEOCODING_RESULT, geocodingResult)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
@ -217,6 +221,7 @@ class GeocodingActivity :
|
|||
val intent = Intent(context, LocationPickerActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken)
|
||||
intent.putExtra(BundleKeys.KEY_CHAT_API_VERSION, chatApiVersion)
|
||||
startActivity(intent)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ import com.nextcloud.talk.users.UserManager
|
|||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CHAT_API_VERSION
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_GEOCODING_RESULT
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import fr.dudie.nominatim.client.TalkJsonNominatimClient
|
||||
|
@ -103,6 +104,7 @@ class LocationPickerActivity :
|
|||
var nominatimClient: TalkJsonNominatimClient? = null
|
||||
|
||||
lateinit var roomToken: String
|
||||
private var chatApiVersion: Int = 1
|
||||
var geocodingResult: GeocodingResult? = null
|
||||
|
||||
var myLocation: GeoPoint = GeoPoint(COORDINATE_ZERO, COORDINATE_ZERO)
|
||||
|
@ -130,6 +132,7 @@ class LocationPickerActivity :
|
|||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||
|
||||
roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!!
|
||||
chatApiVersion = intent.getIntExtra(KEY_CHAT_API_VERSION, 1)
|
||||
geocodingResult = intent.getParcelableExtra(KEY_GEOCODING_RESULT)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
|
@ -244,6 +247,7 @@ class LocationPickerActivity :
|
|||
val intent = Intent(this, GeocodingActivity::class.java)
|
||||
intent.putExtra(BundleKeys.KEY_GEOCODING_QUERY, query)
|
||||
intent.putExtra(KEY_ROOM_TOKEN, roomToken)
|
||||
intent.putExtra(KEY_CHAT_API_VERSION, chatApiVersion)
|
||||
startActivity(intent)
|
||||
}
|
||||
return true
|
||||
|
@ -465,11 +469,10 @@ class LocationPickerActivity :
|
|||
"\"longitude\":\"$selectedLon\",\"name\":\"$locationNameToShare\"}"
|
||||
|
||||
val currentUser = userManager.currentUser.blockingGet()
|
||||
val apiVersion = ApiUtils.getChatApiVersion(currentUser, intArrayOf(1))
|
||||
|
||||
ncApi.sendLocation(
|
||||
ApiUtils.getCredentials(currentUser.username, currentUser.token),
|
||||
ApiUtils.getUrlToSendLocation(apiVersion, currentUser.baseUrl, roomToken),
|
||||
ApiUtils.getUrlToSendLocation(chatApiVersion, currentUser.baseUrl!!, roomToken),
|
||||
"geo-location",
|
||||
objectId,
|
||||
metaData
|
||||
|
|
|
@ -27,5 +27,5 @@ import kotlinx.parcelize.Parcelize
|
|||
@Parcelize
|
||||
data class RetrofitBucket(
|
||||
var url: String? = null,
|
||||
var queryMap: Map<String, String>? = null
|
||||
var queryMap: MutableMap<String, String>? = null
|
||||
) : Parcelable
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.nextcloud.talk.models.domain
|
|||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
|
||||
class ConversationModel(
|
||||
var roomId: String?,
|
||||
var roomId: String? = null,
|
||||
var token: String? = null,
|
||||
var name: String? = null,
|
||||
var displayName: String? = null,
|
||||
|
@ -42,7 +42,11 @@ class ConversationModel(
|
|||
var statusClearAt: Long? = 0,
|
||||
var callRecording: Int = 0,
|
||||
var avatarVersion: String? = null,
|
||||
var hasCustomAvatar: Boolean? = null
|
||||
var hasCustomAvatar: Boolean? = null,
|
||||
var callStartTime: Long? = null,
|
||||
var recordingConsentRequired: Int = 0,
|
||||
var remoteServer: String? = null,
|
||||
var remoteToken: String? = null
|
||||
) {
|
||||
|
||||
companion object {
|
||||
|
@ -95,7 +99,11 @@ class ConversationModel(
|
|||
statusClearAt = conversation.statusClearAt,
|
||||
callRecording = conversation.callRecording,
|
||||
avatarVersion = conversation.avatarVersion,
|
||||
hasCustomAvatar = conversation.hasCustomAvatar
|
||||
hasCustomAvatar = conversation.hasCustomAvatar,
|
||||
callStartTime = conversation.callStartTime,
|
||||
recordingConsentRequired = conversation.recordingConsentRequired,
|
||||
remoteServer = conversation.remoteServer,
|
||||
remoteToken = conversation.remoteToken
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* 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.models.domain.converters
|
||||
|
||||
import com.bluelinelabs.logansquare.typeconverters.IntBasedTypeConverter
|
||||
import com.nextcloud.talk.models.domain.NotificationLevel
|
||||
|
||||
class DomainEnumNotificationLevelConverter : IntBasedTypeConverter<NotificationLevel>() {
|
||||
override fun getFromInt(i: Int): NotificationLevel {
|
||||
return when (i) {
|
||||
0 -> NotificationLevel.DEFAULT
|
||||
1 -> NotificationLevel.ALWAYS
|
||||
2 -> NotificationLevel.MENTION
|
||||
3 -> NotificationLevel.NEVER
|
||||
else -> NotificationLevel.DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
override fun convertToInt(`object`: NotificationLevel): Int {
|
||||
return when (`object`) {
|
||||
NotificationLevel.DEFAULT -> 0
|
||||
NotificationLevel.ALWAYS -> 1
|
||||
NotificationLevel.MENTION -> 2
|
||||
NotificationLevel.NEVER -> 3
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* @author Tim Krüger
|
||||
* @author Andy Scherzinger
|
||||
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* Copyright (C) 2022 Tim Krüger <t@timkrueger.me>
|
||||
* 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.models.json.capabilities
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
||||
import com.nextcloud.talk.models.json.generic.GenericMeta
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@JsonObject
|
||||
data class RoomCapabilitiesOCS(
|
||||
@JsonField(name = ["meta"])
|
||||
var meta: GenericMeta?,
|
||||
@JsonField(name = ["data"])
|
||||
var data: SpreedCapability?
|
||||
) : Parcelable {
|
||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||
constructor() : this(null, null)
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* @author Tim Krüger
|
||||
* Copyright (C) 2022 Tim Krüger <t@timkrueger.me>
|
||||
* 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.models.json.capabilities
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@JsonObject
|
||||
data class RoomCapabilitiesOverall(
|
||||
@JsonField(name = ["ocs"])
|
||||
var ocs: RoomCapabilitiesOCS? = null
|
||||
) : Parcelable {
|
||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||
constructor() : this(null)
|
||||
}
|
|
@ -37,7 +37,7 @@ import com.nextcloud.talk.data.user.model.User
|
|||
import com.nextcloud.talk.models.json.chat.ChatUtils.Companion.getParsedMessage
|
||||
import com.nextcloud.talk.models.json.converters.EnumSystemMessageTypeConverter
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.stfalcon.chatkit.commons.models.IUser
|
||||
import com.stfalcon.chatkit.commons.models.MessageContentType
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
@ -213,7 +213,7 @@ data class ChatMessage(
|
|||
|
||||
@Suppress("ReturnCount")
|
||||
fun isLinkPreview(): Boolean {
|
||||
if (CapabilitiesUtilNew.isLinkPreviewAvailable(activeUser!!)) {
|
||||
if (CapabilitiesUtil.isLinkPreviewAvailable(activeUser!!)) {
|
||||
val regexStringFromServer = activeUser?.capabilities?.coreCapability?.referenceRegex
|
||||
|
||||
val regexFromServer = regexStringFromServer?.toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))
|
||||
|
@ -249,8 +249,8 @@ data class ChatMessage(
|
|||
if (!isVoiceMessage) {
|
||||
if (activeUser != null && activeUser!!.baseUrl != null) {
|
||||
return ApiUtils.getUrlForFilePreviewWithFileId(
|
||||
activeUser!!.baseUrl,
|
||||
individualHashMap["id"],
|
||||
activeUser!!.baseUrl!!,
|
||||
individualHashMap["id"]!!,
|
||||
sharedApplication!!.resources.getDimensionPixelSize(R.dimen.maximum_file_preview_size)
|
||||
)
|
||||
} else {
|
||||
|
@ -413,11 +413,11 @@ data class ChatMessage(
|
|||
null
|
||||
}
|
||||
actorType == "users" -> {
|
||||
ApiUtils.getUrlForAvatar(activeUser!!.baseUrl, actorId, true)
|
||||
ApiUtils.getUrlForAvatar(activeUser!!.baseUrl!!, actorId, true)
|
||||
}
|
||||
actorType == "bridged" -> {
|
||||
ApiUtils.getUrlForAvatar(
|
||||
activeUser!!.baseUrl,
|
||||
activeUser!!.baseUrl!!,
|
||||
"bridge-bot",
|
||||
true
|
||||
)
|
||||
|
@ -427,7 +427,7 @@ data class ChatMessage(
|
|||
if (!TextUtils.isEmpty(actorDisplayName)) {
|
||||
apiId = actorDisplayName
|
||||
}
|
||||
ApiUtils.getUrlForGuestAvatar(activeUser!!.baseUrl, apiId, true)
|
||||
ApiUtils.getUrlForGuestAvatar(activeUser!!.baseUrl!!, apiId, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,9 @@ import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter
|
|||
import com.nextcloud.talk.models.json.converters.EnumReadOnlyConversationConverter
|
||||
import com.nextcloud.talk.models.json.converters.EnumRoomTypeConverter
|
||||
import com.nextcloud.talk.models.json.participants.Participant.ParticipantType
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.ConversationUtils
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
|
@ -160,7 +161,13 @@ data class Conversation(
|
|||
var callStartTime: Long? = null,
|
||||
|
||||
@JsonField(name = ["recordingConsent"])
|
||||
var recordingConsentRequired: Int = 0
|
||||
var recordingConsentRequired: Int = 0,
|
||||
|
||||
@JsonField(name = ["remoteServer"])
|
||||
var remoteServer: String? = null,
|
||||
|
||||
@JsonField(name = ["remoteToken"])
|
||||
var remoteToken: String? = null
|
||||
|
||||
) : Parcelable {
|
||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||
|
@ -185,13 +192,20 @@ data class Conversation(
|
|||
@Deprecated("Use ConversationUtil")
|
||||
private fun isLockedOneToOne(conversationUser: User): Boolean {
|
||||
return type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
|
||||
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms")
|
||||
CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
conversationUser.capabilities?.spreedCapability!!,
|
||||
SpreedFeatures.LOCKED_ONE_TO_ONE_ROOMS
|
||||
)
|
||||
}
|
||||
|
||||
@Deprecated("Use ConversationUtil")
|
||||
fun canModerate(conversationUser: User): Boolean {
|
||||
return isParticipantOwnerOrModerator &&
|
||||
!isLockedOneToOne(conversationUser) &&
|
||||
ConversationUtils.isLockedOneToOne(
|
||||
ConversationModel.mapToConversationModel(this),
|
||||
conversationUser
|
||||
.capabilities?.spreedCapability!!
|
||||
) &&
|
||||
type != ConversationType.FORMER_ONE_TO_ONE &&
|
||||
!ConversationUtils.isNoteToSelfConversation(ConversationModel.mapToConversationModel(this))
|
||||
}
|
||||
|
|
|
@ -31,14 +31,14 @@ class OpenConversationsRepositoryImpl(private val ncApi: NcApi, currentUserProvi
|
|||
OpenConversationsRepository {
|
||||
|
||||
val currentUser: User = currentUserProvider.currentUser.blockingGet()
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv3, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))
|
||||
|
||||
override fun fetchConversations(): Observable<OpenConversationsModel> {
|
||||
return ncApi.getOpenConversations(
|
||||
credentials,
|
||||
ApiUtils.getUrlForOpenConversations(apiVersion, currentUser.baseUrl)
|
||||
ApiUtils.getUrlForOpenConversations(apiVersion, currentUser.baseUrl!!)
|
||||
).map { mapToOpenConversationsModel(it.ocs?.data!!) }
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvid
|
|||
PollRepository {
|
||||
|
||||
val currentUser: User = currentUserProvider.currentUser.blockingGet()
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
|
||||
override fun createPoll(
|
||||
roomToken: String,
|
||||
|
@ -49,7 +49,7 @@ class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvid
|
|||
return ncApi.createPoll(
|
||||
credentials,
|
||||
ApiUtils.getUrlForPoll(
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken
|
||||
),
|
||||
question,
|
||||
|
@ -63,7 +63,7 @@ class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvid
|
|||
return ncApi.getPoll(
|
||||
credentials,
|
||||
ApiUtils.getUrlForPoll(
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken,
|
||||
pollId
|
||||
)
|
||||
|
@ -74,7 +74,7 @@ class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvid
|
|||
return ncApi.votePoll(
|
||||
credentials,
|
||||
ApiUtils.getUrlForPoll(
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken,
|
||||
pollId
|
||||
),
|
||||
|
@ -86,7 +86,7 @@ class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvid
|
|||
return ncApi.closePoll(
|
||||
credentials,
|
||||
ApiUtils.getUrlForPoll(
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken,
|
||||
pollId
|
||||
)
|
||||
|
|
|
@ -77,6 +77,7 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
|
|||
private Context context;
|
||||
|
||||
private String roomToken;
|
||||
private int chatApiVersion;
|
||||
|
||||
private List<AbstractFlexibleItem> abstractFlexibleItemList = new ArrayList<>();
|
||||
|
||||
|
@ -87,10 +88,11 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
|
|||
currentUser = userManager.getCurrentUser().blockingGet();
|
||||
}
|
||||
|
||||
public MentionAutocompletePresenter(Context context, String roomToken) {
|
||||
public MentionAutocompletePresenter(Context context, String roomToken, int chatApiVersion) {
|
||||
super(context);
|
||||
this.roomToken = roomToken;
|
||||
this.context = context;
|
||||
this.chatApiVersion = chatApiVersion;
|
||||
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
|
||||
currentUser = userManager.getCurrentUser().blockingGet();
|
||||
}
|
||||
|
@ -120,8 +122,6 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
|
|||
queryString = "";
|
||||
}
|
||||
|
||||
int apiVersion = ApiUtils.getChatApiVersion(currentUser, new int[] {1});
|
||||
|
||||
adapter.setFilter(queryString);
|
||||
|
||||
Map<String, String> queryMap = new HashMap<>();
|
||||
|
@ -129,7 +129,7 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
|
|||
|
||||
ncApi.getMentionAutocompleteSuggestions(
|
||||
ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()),
|
||||
ApiUtils.getUrlForMentionSuggestions(apiVersion, currentUser.getBaseUrl(), roomToken),
|
||||
ApiUtils.getUrlForMentionSuggestions(chatApiVersion, currentUser.getBaseUrl(), roomToken),
|
||||
queryString, 5, queryMap)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
|
@ -66,12 +66,13 @@ import com.nextcloud.talk.ui.dialog.ScopeDialog
|
|||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.Mimetype.IMAGE_JPG
|
||||
import com.nextcloud.talk.utils.Mimetype.IMAGE_PREFIX_GENERIC
|
||||
import com.nextcloud.talk.utils.PickImage
|
||||
import com.nextcloud.talk.utils.PickImage.Companion.REQUEST_PERMISSION_CAMERA
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
|
@ -127,7 +128,7 @@ class ProfileActivity : BaseActivity() {
|
|||
binding.avatarDelete.setOnClickListener {
|
||||
ncApi.deleteAvatar(
|
||||
credentials,
|
||||
ApiUtils.getUrlForTempAvatar(currentUser!!.baseUrl)
|
||||
ApiUtils.getUrlForTempAvatar(currentUser!!.baseUrl!!)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -154,7 +155,7 @@ class ProfileActivity : BaseActivity() {
|
|||
})
|
||||
}
|
||||
binding.avatarImage.let { ViewCompat.setTransitionName(it, "userAvatar.transitionTag") }
|
||||
ncApi.getUserProfile(credentials, ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl))
|
||||
ncApi.getUserProfile(credentials, ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl!!))
|
||||
.retry(DEFAULT_RETRIES)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -226,13 +227,17 @@ class ProfileActivity : BaseActivity() {
|
|||
item.icon = ContextCompat.getDrawable(this, R.drawable.ic_check)
|
||||
binding.emptyList.root.visibility = View.GONE
|
||||
binding.userinfoList.visibility = View.VISIBLE
|
||||
if (CapabilitiesUtilNew.isAvatarEndpointAvailable(currentUser!!)) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser!!.capabilities!!.spreedCapability!!,
|
||||
SpreedFeatures.TEMP_USER_AVATAR_API
|
||||
)
|
||||
) {
|
||||
// TODO later avatar can also be checked via user fields, for now it is in Talk capability
|
||||
binding.avatarButtons.visibility = View.VISIBLE
|
||||
}
|
||||
ncApi.getEditableUserProfileFields(
|
||||
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||
ApiUtils.getUrlForUserFields(currentUser!!.baseUrl)
|
||||
ApiUtils.getUrlForUserFields(currentUser!!.baseUrl!!)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -292,7 +297,7 @@ class ProfileActivity : BaseActivity() {
|
|||
|
||||
private fun showUserProfile() {
|
||||
if (currentUser!!.baseUrl != null) {
|
||||
binding.userinfoBaseurl.text = Uri.parse(currentUser!!.baseUrl).host
|
||||
binding.userinfoBaseurl.text = Uri.parse(currentUser!!.baseUrl!!).host
|
||||
}
|
||||
DisplayUtils.loadAvatarImage(currentUser, binding.avatarImage, false)
|
||||
if (!TextUtils.isEmpty(userInfo?.displayName)) {
|
||||
|
@ -327,10 +332,10 @@ class ProfileActivity : BaseActivity() {
|
|||
}
|
||||
|
||||
// show edit button
|
||||
if (CapabilitiesUtilNew.canEditScopes(currentUser!!)) {
|
||||
if (CapabilitiesUtil.canEditScopes(currentUser!!)) {
|
||||
ncApi.getEditableUserProfileFields(
|
||||
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||
ApiUtils.getUrlForUserFields(currentUser!!.baseUrl)
|
||||
ApiUtils.getUrlForUserFields(currentUser!!.baseUrl!!)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -438,7 +443,7 @@ class ProfileActivity : BaseActivity() {
|
|||
val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
|
||||
ncApi.setUserData(
|
||||
credentials,
|
||||
ApiUtils.getUrlForUserData(currentUser!!.baseUrl, currentUser!!.userId),
|
||||
ApiUtils.getUrlForUserData(currentUser!!.baseUrl!!, currentUser!!.userId!!),
|
||||
item.field.fieldName,
|
||||
item.text
|
||||
)
|
||||
|
@ -535,7 +540,7 @@ class ProfileActivity : BaseActivity() {
|
|||
// upload file
|
||||
ncApi.uploadAvatar(
|
||||
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||
ApiUtils.getUrlForTempAvatar(currentUser!!.baseUrl),
|
||||
ApiUtils.getUrlForTempAvatar(currentUser!!.baseUrl!!),
|
||||
filePart
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
@ -569,7 +574,7 @@ class ProfileActivity : BaseActivity() {
|
|||
val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
|
||||
ncApi.setUserData(
|
||||
credentials,
|
||||
ApiUtils.getUrlForUserData(currentUser!!.baseUrl, currentUser!!.userId),
|
||||
ApiUtils.getUrlForUserData(currentUser!!.baseUrl!!, currentUser!!.userId!!),
|
||||
item.field.scopeName,
|
||||
item.scope!!.name
|
||||
)
|
||||
|
|
|
@ -31,7 +31,7 @@ class RequestAssistanceRepositoryImpl(private val ncApi: NcApi, currentUserProvi
|
|||
RequestAssistanceRepository {
|
||||
|
||||
val currentUser: User = currentUserProvider.currentUser.blockingGet()
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
|
||||
var apiVersion = 1
|
||||
|
||||
|
|
|
@ -91,8 +91,8 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
|||
|
||||
private fun sendDirectReply() {
|
||||
val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val apiVersion = ApiUtils.getChatApiVersion(currentUser, intArrayOf(1))
|
||||
val url = ApiUtils.getUrlForChat(apiVersion, currentUser.baseUrl, roomToken)
|
||||
val apiVersion = ApiUtils.getChatApiVersion(currentUser.capabilities!!.spreedCapability!!, intArrayOf(1))
|
||||
val url = ApiUtils.getUrlForChat(apiVersion, currentUser.baseUrl!!, roomToken!!)
|
||||
|
||||
ncApi.sendChatMessage(credentials, url, replyMessage, currentUser.displayName, null, false)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
|
@ -153,7 +153,7 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
|||
|
||||
// Add reply
|
||||
Single.fromCallable {
|
||||
val avatarUrl = ApiUtils.getUrlForAvatar(currentUser.baseUrl, currentUser.userId, false)
|
||||
val avatarUrl = ApiUtils.getUrlForAvatar(currentUser.baseUrl!!, currentUser.userId, false)
|
||||
val me = Person.Builder()
|
||||
.setName(currentUser.displayName)
|
||||
.setIcon(NotificationUtils.loadAvatarSync(avatarUrl, context))
|
||||
|
|
|
@ -80,11 +80,11 @@ class MarkAsReadReceiver : BroadcastReceiver() {
|
|||
|
||||
private fun markAsRead() {
|
||||
val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val apiVersion = ApiUtils.getChatApiVersion(currentUser, intArrayOf(1))
|
||||
val apiVersion = ApiUtils.getChatApiVersion(currentUser.capabilities!!.spreedCapability!!, intArrayOf(1))
|
||||
val url = ApiUtils.getUrlForChatReadMarker(
|
||||
apiVersion,
|
||||
currentUser.baseUrl,
|
||||
roomToken
|
||||
currentUser.baseUrl!!,
|
||||
roomToken!!
|
||||
)
|
||||
|
||||
ncApi.setChatReadMarker(credentials, url, messageId)
|
||||
|
|
|
@ -94,7 +94,7 @@ class RemoteFileBrowserItemsListViewHolder(
|
|||
|
||||
if (item.hasPreview) {
|
||||
val path = ApiUtils.getUrlForFilePreviewWithRemotePath(
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
item.path,
|
||||
fileIcon.context.resources.getDimensionPixelSize(R.dimen.small_item_height)
|
||||
)
|
||||
|
|
|
@ -33,7 +33,7 @@ class CallRecordingRepositoryImpl(private val ncApi: NcApi, currentUserProvider:
|
|||
CallRecordingRepository {
|
||||
|
||||
val currentUser: User = currentUserProvider.currentUser.blockingGet()
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
|
||||
var apiVersion = 1
|
||||
|
||||
|
@ -42,7 +42,7 @@ class CallRecordingRepositoryImpl(private val ncApi: NcApi, currentUserProvider:
|
|||
credentials,
|
||||
ApiUtils.getUrlForRecording(
|
||||
apiVersion,
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken
|
||||
),
|
||||
1
|
||||
|
@ -54,7 +54,7 @@ class CallRecordingRepositoryImpl(private val ncApi: NcApi, currentUserProvider:
|
|||
credentials,
|
||||
ApiUtils.getUrlForRecording(
|
||||
apiVersion,
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken
|
||||
)
|
||||
).map { mapToStopCallRecordingModel(it.ocs?.meta!!) }
|
||||
|
|
|
@ -38,12 +38,12 @@ class ConversationsRepositoryImpl(private val api: NcApi, private val userProvid
|
|||
get() = userProvider.currentUser.blockingGet()
|
||||
|
||||
private val credentials: String
|
||||
get() = ApiUtils.getCredentials(user.username, user.token)
|
||||
get() = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
|
||||
override fun allowGuests(token: String, allow: Boolean): Observable<AllowGuestsResult> {
|
||||
val url = ApiUtils.getUrlForRoomPublic(
|
||||
apiVersion(),
|
||||
user.baseUrl,
|
||||
user.baseUrl!!,
|
||||
token
|
||||
)
|
||||
|
||||
|
@ -100,7 +100,7 @@ class ConversationsRepositoryImpl(private val api: NcApi, private val userProvid
|
|||
}
|
||||
|
||||
private fun apiVersion(): Int {
|
||||
return ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.APIv4))
|
||||
return ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -34,13 +34,13 @@ class ReactionsRepositoryImpl(private val ncApi: NcApi, currentUserProvider: Cur
|
|||
ReactionsRepository {
|
||||
|
||||
val currentUser: User = currentUserProvider.currentUser.blockingGet()
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
|
||||
override fun addReaction(roomToken: String, message: ChatMessage, emoji: String): Observable<ReactionAddedModel> {
|
||||
return ncApi.sendReaction(
|
||||
credentials,
|
||||
ApiUtils.getUrlForMessageReaction(
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken,
|
||||
message.id
|
||||
),
|
||||
|
@ -56,7 +56,7 @@ class ReactionsRepositoryImpl(private val ncApi: NcApi, currentUserProvider: Cur
|
|||
return ncApi.deleteReaction(
|
||||
credentials,
|
||||
ApiUtils.getUrlForMessageReaction(
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
roomToken,
|
||||
message.id
|
||||
),
|
||||
|
|
|
@ -37,7 +37,7 @@ class UnifiedSearchRepositoryImpl(private val api: NcApi, private val userProvid
|
|||
get() = userProvider.currentUser.blockingGet()
|
||||
|
||||
private val credentials: String
|
||||
get() = ApiUtils.getCredentials(user.username, user.token)
|
||||
get() = ApiUtils.getCredentials(user.username, user.token)!!
|
||||
|
||||
override fun searchMessages(
|
||||
searchTerm: String,
|
||||
|
|
|
@ -90,6 +90,7 @@ import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
|
|||
import com.nextcloud.talk.profile.ProfileActivity
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.ClosedInterfaceImpl
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.LoggingUtils.sendMailWithAttachment
|
||||
|
@ -97,7 +98,7 @@ import com.nextcloud.talk.utils.NotificationUtils
|
|||
import com.nextcloud.talk.utils.NotificationUtils.getCallRingtoneUri
|
||||
import com.nextcloud.talk.utils.NotificationUtils.getMessageRingtoneUri
|
||||
import com.nextcloud.talk.utils.SecurityUtils
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
||||
import com.nextcloud.talk.utils.power.PowerManagerUtils
|
||||
|
@ -266,7 +267,11 @@ class SettingsActivity : BaseActivity() {
|
|||
}
|
||||
|
||||
private fun setupPhoneBookIntegration() {
|
||||
if (CapabilitiesUtilNew.isPhoneBookIntegrationAvailable(currentUser!!)) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser?.capabilities?.spreedCapability!!,
|
||||
SpreedFeatures.PHONEBOOK_SEARCH
|
||||
)
|
||||
) {
|
||||
binding.settingsPhoneBookIntegration.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.settingsPhoneBookIntegration.visibility = View.GONE
|
||||
|
@ -507,7 +512,7 @@ class SettingsActivity : BaseActivity() {
|
|||
var port = -1
|
||||
val uri: URI
|
||||
try {
|
||||
uri = URI(currentUser!!.baseUrl)
|
||||
uri = URI(currentUser!!.baseUrl!!)
|
||||
host = uri.host
|
||||
port = uri.port
|
||||
Log.d(TAG, "uri is $uri")
|
||||
|
@ -823,7 +828,7 @@ class SettingsActivity : BaseActivity() {
|
|||
private fun setupProfileQueryDisposable() {
|
||||
profileQueryDisposable = ncApi.getUserProfile(
|
||||
credentials,
|
||||
ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl)
|
||||
ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl!!)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -854,7 +859,7 @@ class SettingsActivity : BaseActivity() {
|
|||
|
||||
private fun setupServerAgeWarning() {
|
||||
when {
|
||||
CapabilitiesUtilNew.isServerEOL(currentUser!!.capabilities) -> {
|
||||
CapabilitiesUtil.isServerEOL(currentUser!!.serverVersion!!.major) -> {
|
||||
binding.serverAgeWarningText.setTextColor(ContextCompat.getColor((context), R.color.nc_darkRed))
|
||||
binding.serverAgeWarningText.setText(R.string.nc_settings_server_eol)
|
||||
binding.serverAgeWarningIcon.setColorFilter(
|
||||
|
@ -863,7 +868,7 @@ class SettingsActivity : BaseActivity() {
|
|||
)
|
||||
}
|
||||
|
||||
CapabilitiesUtilNew.isServerAlmostEOL(currentUser!!) -> {
|
||||
CapabilitiesUtil.isServerAlmostEOL(currentUser!!.serverVersion!!.major) -> {
|
||||
binding.serverAgeWarningText.setTextColor(
|
||||
ContextCompat.getColor((context), R.color.nc_darkYellow)
|
||||
)
|
||||
|
@ -889,8 +894,8 @@ class SettingsActivity : BaseActivity() {
|
|||
binding.settingsIncognitoKeyboardSwitch.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (CapabilitiesUtilNew.isReadStatusAvailable(currentUser!!)) {
|
||||
binding.settingsReadPrivacySwitch.isChecked = !CapabilitiesUtilNew.isReadStatusPrivate(currentUser!!)
|
||||
if (CapabilitiesUtil.isReadStatusAvailable(currentUser!!.capabilities!!.spreedCapability!!)) {
|
||||
binding.settingsReadPrivacySwitch.isChecked = !CapabilitiesUtil.isReadStatusPrivate(currentUser!!)
|
||||
} else {
|
||||
binding.settingsReadPrivacy.visibility = View.GONE
|
||||
}
|
||||
|
@ -954,10 +959,10 @@ class SettingsActivity : BaseActivity() {
|
|||
private fun setupTypingStatusSetting() {
|
||||
if (currentUser!!.externalSignalingServer?.externalSignalingServer?.isNotEmpty() == true) {
|
||||
binding.settingsTypingStatusOnlyWithHpb.visibility = View.GONE
|
||||
Log.i(TAG, "Typing Status Available: ${CapabilitiesUtilNew.isTypingStatusAvailable(currentUser!!)}")
|
||||
Log.i(TAG, "Typing Status Available: ${CapabilitiesUtil.isTypingStatusAvailable(currentUser!!)}")
|
||||
|
||||
if (CapabilitiesUtilNew.isTypingStatusAvailable(currentUser!!)) {
|
||||
binding.settingsTypingStatusSwitch.isChecked = !CapabilitiesUtilNew.isTypingStatusPrivate(currentUser!!)
|
||||
if (CapabilitiesUtil.isTypingStatusAvailable(currentUser!!)) {
|
||||
binding.settingsTypingStatusSwitch.isChecked = !CapabilitiesUtil.isTypingStatusPrivate(currentUser!!)
|
||||
} else {
|
||||
binding.settingsTypingStatus.visibility = View.GONE
|
||||
}
|
||||
|
@ -1209,7 +1214,7 @@ class SettingsActivity : BaseActivity() {
|
|||
private fun checkForPhoneNumber() {
|
||||
ncApi.getUserData(
|
||||
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||
ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl)
|
||||
ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl!!)
|
||||
).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<UserProfileOverall> {
|
||||
|
@ -1294,7 +1299,7 @@ class SettingsActivity : BaseActivity() {
|
|||
val phoneNumber = textInputLayout.editText!!.text.toString()
|
||||
ncApi.setUserData(
|
||||
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||
ApiUtils.getUrlForUserData(currentUser!!.baseUrl, currentUser!!.userId),
|
||||
ApiUtils.getUrlForUserData(currentUser!!.baseUrl!!, currentUser!!.userId!!),
|
||||
"phone",
|
||||
phoneNumber
|
||||
).subscribeOn(Schedulers.io())
|
||||
|
@ -1349,7 +1354,7 @@ class SettingsActivity : BaseActivity() {
|
|||
val json = "{\"key\": \"read_status_privacy\", \"value\" : $booleanValue}"
|
||||
ncApi.setReadStatusPrivacy(
|
||||
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl),
|
||||
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!),
|
||||
json.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
@ -1387,7 +1392,7 @@ class SettingsActivity : BaseActivity() {
|
|||
val json = "{\"key\": \"typing_privacy\", \"value\" : $booleanValue}"
|
||||
ncApi.setTypingStatusPrivacy(
|
||||
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl),
|
||||
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!),
|
||||
json.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
|
|
@ -105,7 +105,7 @@ class SharedItemsRepositoryImpl @Inject constructor(private val ncApi: NcApi, pr
|
|||
fileParameters["link"]!!,
|
||||
fileParameters["mimetype"]!!,
|
||||
previewAvailable,
|
||||
previewLink(fileParameters["id"], parameters.baseUrl)
|
||||
previewLink(fileParameters["id"], parameters.baseUrl!!)
|
||||
)
|
||||
} else if (it.value.messageParameters?.containsKey("object") == true) {
|
||||
val objectParameters = it.value.messageParameters!!["object"]!!
|
||||
|
@ -184,7 +184,7 @@ class SharedItemsRepositoryImpl @Inject constructor(private val ncApi: NcApi, pr
|
|||
|
||||
return ncApi.getSharedItemsOverview(
|
||||
credentials,
|
||||
ApiUtils.getUrlForChatSharedItemsOverview(1, parameters.baseUrl, parameters.roomToken),
|
||||
ApiUtils.getUrlForChatSharedItemsOverview(1, parameters.baseUrl!!, parameters.roomToken),
|
||||
1
|
||||
).map {
|
||||
val types = mutableSetOf<SharedItemType>()
|
||||
|
@ -206,7 +206,7 @@ class SharedItemsRepositoryImpl @Inject constructor(private val ncApi: NcApi, pr
|
|||
private fun previewLink(fileId: String?, baseUrl: String): String {
|
||||
return ApiUtils.getUrlForFilePreviewWithFileId(
|
||||
baseUrl,
|
||||
fileId,
|
||||
fileId!!,
|
||||
sharedApplication!!.resources.getDimensionPixelSize(R.dimen.maximum_file_preview_size)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ class TranslateViewModel @Inject constructor(
|
|||
|
||||
fun translateMessage(toLanguage: String, fromLanguage: String?, text: String) {
|
||||
val currentUser: User = userManager.currentUser.blockingGet()
|
||||
val authorization: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val url: String = ApiUtils.getUrlForTranslation(currentUser.baseUrl)
|
||||
val authorization: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
val url: String = ApiUtils.getUrlForTranslation(currentUser.baseUrl!!)
|
||||
val calculatedFromLanguage =
|
||||
if (fromLanguage == null || fromLanguage == "") {
|
||||
null
|
||||
|
@ -60,8 +60,8 @@ class TranslateViewModel @Inject constructor(
|
|||
|
||||
fun getLanguages() {
|
||||
val currentUser: User = userManager.currentUser.blockingGet()
|
||||
val authorization: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
val url: String = ApiUtils.getUrlForLanguages(currentUser.baseUrl)
|
||||
val authorization: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
val url: String = ApiUtils.getUrlForLanguages(currentUser.baseUrl!!)
|
||||
Log.d(TAG, "URL is: $url")
|
||||
repository.getLanguages(authorization, url)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
|
|
@ -57,7 +57,7 @@ class ProfileBottomSheet(val ncApi: NcApi, val userModel: User, val viewThemeUti
|
|||
fun showFor(user: String, context: Context) {
|
||||
ncApi.hoverCard(
|
||||
ApiUtils.getCredentials(userModel.username, userModel.token),
|
||||
ApiUtils.getUrlForHoverCard(userModel.baseUrl, user)
|
||||
ApiUtils.getUrlForHoverCard(userModel.baseUrl!!, user)
|
||||
).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<HoverCardOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
|
@ -121,10 +121,10 @@ class ProfileBottomSheet(val ncApi: NcApi, val userModel: User, val viewThemeUti
|
|||
|
||||
private fun talkTo(userId: String, context: Context) {
|
||||
val apiVersion =
|
||||
ApiUtils.getConversationApiVersion(userModel, intArrayOf(ApiUtils.APIv4, 1))
|
||||
ApiUtils.getConversationApiVersion(userModel, intArrayOf(ApiUtils.API_V4, 1))
|
||||
val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
userModel.baseUrl,
|
||||
userModel.baseUrl!!,
|
||||
"1",
|
||||
null,
|
||||
userId,
|
||||
|
|
|
@ -35,7 +35,8 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
|
|||
import com.nextcloud.talk.chat.ChatActivity
|
||||
import com.nextcloud.talk.databinding.DialogAttachmentBinding
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
|
@ -61,7 +62,7 @@ class AttachmentDialog(val activity: Activity, var chatActivity: ChatActivity) :
|
|||
}
|
||||
|
||||
private fun initItemsStrings() {
|
||||
var serverName = CapabilitiesUtilNew.getServerName(chatActivity.conversationUser)
|
||||
var serverName = CapabilitiesUtil.getServerName(chatActivity.conversationUser)
|
||||
dialogAttachmentBinding.txtAttachFileFromCloud.text = chatActivity.resources?.let {
|
||||
if (serverName.isNullOrEmpty()) {
|
||||
serverName = it.getString(R.string.nc_server_product_name)
|
||||
|
@ -71,15 +72,15 @@ class AttachmentDialog(val activity: Activity, var chatActivity: ChatActivity) :
|
|||
}
|
||||
|
||||
private fun initItemsVisibility() {
|
||||
if (!CapabilitiesUtilNew.hasSpreedFeatureCapability(
|
||||
chatActivity.conversationUser,
|
||||
"geo-location-sharing"
|
||||
if (!CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
chatActivity.spreedCapabilities,
|
||||
SpreedFeatures.GEO_LOCATION_SHARING
|
||||
)
|
||||
) {
|
||||
dialogAttachmentBinding.menuShareLocation.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (!CapabilitiesUtilNew.hasSpreedFeatureCapability(chatActivity.conversationUser, "talk-polls") ||
|
||||
if (!CapabilitiesUtil.hasSpreedFeatureCapability(chatActivity.spreedCapabilities, SpreedFeatures.TALK_POLLS) ||
|
||||
chatActivity.isOneToOneConversation()
|
||||
) {
|
||||
dialogAttachmentBinding.menuAttachPoll.visibility = View.GONE
|
||||
|
|
|
@ -54,7 +54,7 @@ import com.nextcloud.talk.ui.theme.ViewThemeUtils;
|
|||
import com.nextcloud.talk.users.UserManager;
|
||||
import com.nextcloud.talk.utils.ApiUtils;
|
||||
import com.nextcloud.talk.utils.DisplayUtils;
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil;
|
||||
|
||||
import java.net.CookieManager;
|
||||
import java.util.ArrayList;
|
||||
|
@ -262,7 +262,7 @@ public class ChooseAccountDialogFragment extends DialogFragment {
|
|||
private void loadCurrentStatus(User user) {
|
||||
String credentials = ApiUtils.getCredentials(user.getUsername(), user.getToken());
|
||||
|
||||
if (CapabilitiesUtilNew.isUserStatusAvailable(userManager.getCurrentUser().blockingGet())) {
|
||||
if (CapabilitiesUtil.isUserStatusAvailable(userManager.getCurrentUser().blockingGet())) {
|
||||
binding.statusView.setVisibility(View.VISIBLE);
|
||||
|
||||
ncApi.status(credentials, ApiUtils.getUrlForStatus(user.getBaseUrl())).
|
||||
|
|
|
@ -89,7 +89,7 @@ class ChooseAccountShareToDialogFragment : DialogFragment() {
|
|||
if (user != null) {
|
||||
binding!!.currentAccount.userName.text = user.displayName
|
||||
binding!!.currentAccount.ticker.visibility = View.GONE
|
||||
binding!!.currentAccount.account.text = Uri.parse(user.baseUrl).host
|
||||
binding!!.currentAccount.account.text = Uri.parse(user.baseUrl!!).host
|
||||
viewThemeUtils!!.platform.colorImageView(binding!!.currentAccount.accountMenu, ColorRole.PRIMARY)
|
||||
if (user.baseUrl != null &&
|
||||
(user.baseUrl!!.startsWith("http://") || user.baseUrl!!.startsWith("https://"))
|
||||
|
|
|
@ -46,7 +46,7 @@ import com.nextcloud.talk.users.UserManager
|
|||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
|
@ -86,7 +86,7 @@ class ConversationsListBottomDialog(
|
|||
initItemsVisibility()
|
||||
initClickListeners()
|
||||
|
||||
credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||
credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
@ -105,7 +105,10 @@ class ConversationsListBottomDialog(
|
|||
}
|
||||
|
||||
private fun initItemsVisibility() {
|
||||
val hasFavoritesCapability = CapabilitiesUtilNew.hasSpreedFeatureCapability(currentUser, "favorites")
|
||||
val hasFavoritesCapability = CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser.capabilities?.spreedCapability!!,
|
||||
"favorites"
|
||||
)
|
||||
val canModerate = conversation.canModerate(currentUser)
|
||||
|
||||
binding.conversationRemoveFromFavorites.visibility = setVisibleIf(
|
||||
|
@ -116,11 +119,19 @@ class ConversationsListBottomDialog(
|
|||
)
|
||||
|
||||
binding.conversationMarkAsRead.visibility = setVisibleIf(
|
||||
conversation.unreadMessages > 0 && CapabilitiesUtilNew.canSetChatReadMarker(currentUser)
|
||||
conversation.unreadMessages > 0 && CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser
|
||||
.capabilities?.spreedCapability!!,
|
||||
"chat-read-marker"
|
||||
)
|
||||
)
|
||||
|
||||
binding.conversationMarkAsUnread.visibility = setVisibleIf(
|
||||
conversation.unreadMessages <= 0 && CapabilitiesUtilNew.canMarkRoomAsUnread(currentUser)
|
||||
conversation.unreadMessages <= 0 && CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
currentUser
|
||||
.capabilities?.spreedCapability!!,
|
||||
"chat-unread"
|
||||
)
|
||||
)
|
||||
|
||||
binding.conversationOperationRename.visibility = setVisibleIf(
|
||||
|
@ -178,12 +189,12 @@ class ConversationsListBottomDialog(
|
|||
}
|
||||
|
||||
private fun addConversationToFavorites() {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
|
||||
ncApi.addConversationToFavorites(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomFavorite(
|
||||
apiVersion,
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
conversation.token
|
||||
)
|
||||
)
|
||||
|
@ -218,12 +229,12 @@ class ConversationsListBottomDialog(
|
|||
}
|
||||
|
||||
private fun removeConversationFromFavorites() {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
|
||||
ncApi.removeConversationFromFavorites(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomFavorite(
|
||||
apiVersion,
|
||||
currentUser.baseUrl,
|
||||
currentUser.baseUrl!!,
|
||||
conversation.token
|
||||
)
|
||||
)
|
||||
|
@ -262,8 +273,8 @@ class ConversationsListBottomDialog(
|
|||
credentials,
|
||||
ApiUtils.getUrlForChatReadMarker(
|
||||
chatApiVersion(),
|
||||
currentUser.baseUrl,
|
||||
conversation.token
|
||||
currentUser.baseUrl!!,
|
||||
conversation.token!!
|
||||
)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
@ -301,8 +312,8 @@ class ConversationsListBottomDialog(
|
|||
credentials,
|
||||
ApiUtils.getUrlForChatReadMarker(
|
||||
chatApiVersion(),
|
||||
currentUser.baseUrl,
|
||||
conversation.token
|
||||
currentUser.baseUrl!!,
|
||||
conversation.token!!
|
||||
),
|
||||
conversation.lastMessage!!.jsonMessageId
|
||||
)
|
||||
|
@ -396,7 +407,7 @@ class ConversationsListBottomDialog(
|
|||
}
|
||||
|
||||
private fun chatApiVersion(): Int {
|
||||
return ApiUtils.getChatApiVersion(currentUser, intArrayOf(ApiUtils.APIv1))
|
||||
return ApiUtils.getChatApiVersion(currentUser.capabilities!!.spreedCapability!!, intArrayOf(ApiUtils.API_V1))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -50,7 +50,8 @@ import javax.inject.Inject
|
|||
class DateTimePickerFragment(
|
||||
token: String,
|
||||
id: String,
|
||||
chatViewModel: ChatViewModel
|
||||
chatViewModel: ChatViewModel,
|
||||
private val chatApiVersion: Int
|
||||
) : DialogFragment() {
|
||||
lateinit var binding: DialogDateTimePickerBinding
|
||||
private var dialogView: View? = null
|
||||
|
@ -144,7 +145,7 @@ class DateTimePickerFragment(
|
|||
}
|
||||
|
||||
private fun getReminder() {
|
||||
viewModel.getReminder(userManager.currentUser.blockingGet(), roomToken, messageId)
|
||||
viewModel.getReminder(userManager.currentUser.blockingGet(), roomToken, messageId, chatApiVersion)
|
||||
}
|
||||
|
||||
private fun showDelete(value: Boolean) {
|
||||
|
@ -221,12 +222,18 @@ class DateTimePickerFragment(
|
|||
binding.buttonClose.setOnClickListener { dismiss() }
|
||||
binding.buttonSet.setOnClickListener {
|
||||
currentTimeStamp?.let { time ->
|
||||
viewModel.setReminder(userManager.currentUser.blockingGet(), roomToken, messageId, time.toInt())
|
||||
viewModel.setReminder(
|
||||
userManager.currentUser.blockingGet(),
|
||||
roomToken,
|
||||
messageId,
|
||||
time.toInt(),
|
||||
chatApiVersion
|
||||
)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
binding.buttonDelete.setOnClickListener {
|
||||
viewModel.deleteReminder(userManager.currentUser.blockingGet(), roomToken, messageId)
|
||||
viewModel.deleteReminder(userManager.currentUser.blockingGet(), roomToken, messageId, chatApiVersion)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,11 +306,12 @@ class DateTimePickerFragment(
|
|||
private const val HOUR_SIX_PM = 18
|
||||
|
||||
@JvmStatic
|
||||
fun newInstance(token: String, id: String, chatViewModel: ChatViewModel) =
|
||||
fun newInstance(token: String, id: String, chatViewModel: ChatViewModel, chatApiVersion: Int) =
|
||||
DateTimePickerFragment(
|
||||
token,
|
||||
id,
|
||||
chatViewModel
|
||||
chatViewModel,
|
||||
chatApiVersion
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,14 +46,17 @@ import com.nextcloud.talk.models.domain.ConversationReadOnlyState
|
|||
import com.nextcloud.talk.models.domain.ConversationType
|
||||
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
||||
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||
import com.nextcloud.talk.repositories.reactions.ReactionsRepository
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.SpreedFeatures
|
||||
import com.nextcloud.talk.utils.ConversationUtils
|
||||
import com.nextcloud.talk.utils.DateConstants
|
||||
import com.nextcloud.talk.utils.DateUtils
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
|
||||
import com.vanniktech.emoji.EmojiPopup
|
||||
import com.vanniktech.emoji.EmojiTextView
|
||||
import com.vanniktech.emoji.installDisableKeyboardInput
|
||||
|
@ -72,7 +75,8 @@ class MessageActionsDialog(
|
|||
private val user: User?,
|
||||
private val currentConversation: ConversationModel?,
|
||||
private val showMessageDeletionButton: Boolean,
|
||||
private val hasChatPermission: Boolean
|
||||
private val hasChatPermission: Boolean,
|
||||
private val spreedCapabilities: SpreedCapability
|
||||
) : BottomSheetDialog(chatActivity) {
|
||||
|
||||
@Inject
|
||||
|
@ -100,8 +104,8 @@ class MessageActionsDialog(
|
|||
|
||||
private val isUserAllowedToEdit = chatActivity.userAllowedByPrivilages(message)
|
||||
|
||||
private val isMessageEditable = CapabilitiesUtilNew.hasSpreedFeatureCapability(
|
||||
user,
|
||||
private val isMessageEditable = CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
spreedCapabilities,
|
||||
"edit-messages"
|
||||
) && messageHasRegularText && !isOlderThanTwentyFourHours && isUserAllowedToEdit
|
||||
|
||||
|
@ -116,9 +120,9 @@ class MessageActionsDialog(
|
|||
viewThemeUtils.platform.themeDialog(dialogMessageActionsBinding.root)
|
||||
initEmojiBar(hasChatPermission)
|
||||
initMenuItemCopy(!message.isDeleted)
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv3, 1))
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(user!!, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))
|
||||
chatActivity.chatViewModel.checkForNoteToSelf(
|
||||
ApiUtils.getCredentials(user!!.username, user.token),
|
||||
ApiUtils.getCredentials(user!!.username, user.token)!!,
|
||||
ApiUtils.getUrlForRooms(
|
||||
apiVersion,
|
||||
user.baseUrl
|
||||
|
@ -144,7 +148,7 @@ class MessageActionsDialog(
|
|||
initMenuItemTranslate(
|
||||
!message.isDeleted &&
|
||||
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() &&
|
||||
CapabilitiesUtilNew.isTranslationsSupported(user)
|
||||
CapabilitiesUtil.isTranslationsSupported(spreedCapabilities)
|
||||
)
|
||||
initMenuEditorDetails(message.lastEditTimestamp != 0L && !message.isDeleted)
|
||||
initMenuReplyToMessage(message.replyable && hasChatPermission)
|
||||
|
@ -160,7 +164,10 @@ class MessageActionsDialog(
|
|||
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() &&
|
||||
!(message.isDeletedCommentMessage || message.isDeleted)
|
||||
)
|
||||
initMenuRemindMessage(!message.isDeleted && CapabilitiesUtilNew.isRemindSupported(user))
|
||||
initMenuRemindMessage(
|
||||
!message.isDeleted && CapabilitiesUtil.hasSpreedFeatureCapability
|
||||
(spreedCapabilities, "remind-me-later")
|
||||
)
|
||||
initMenuMarkAsUnread(
|
||||
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID &&
|
||||
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getCalculateMessageType()
|
||||
|
@ -242,7 +249,7 @@ class MessageActionsDialog(
|
|||
}
|
||||
|
||||
private fun initEmojiBar(hasChatPermission: Boolean) {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "reactions") &&
|
||||
if (hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.REACTIONS) &&
|
||||
isPermitted(hasChatPermission) &&
|
||||
isReactableMessageType(message)
|
||||
) {
|
||||
|
|
|
@ -35,7 +35,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
|
|||
import com.nextcloud.talk.databinding.DialogMoreCallActionsBinding
|
||||
import com.nextcloud.talk.raisehand.viewmodel.RaiseHandViewModel
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||
import com.nextcloud.talk.viewmodels.CallRecordingViewModel
|
||||
import com.vanniktech.emoji.EmojiTextView
|
||||
import javax.inject.Inject
|
||||
|
@ -72,7 +72,7 @@ class MoreCallActionsDialog(private val callActivity: CallActivity) : BottomShee
|
|||
}
|
||||
|
||||
private fun initItemsVisibility() {
|
||||
if (CapabilitiesUtilNew.isCallReactionsSupported(callActivity.conversationUser)) {
|
||||
if (CapabilitiesUtil.isCallReactionsSupported(callActivity.conversationUser)) {
|
||||
binding.callEmojiBar.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.callEmojiBar.visibility = View.GONE
|
||||
|
@ -102,7 +102,7 @@ class MoreCallActionsDialog(private val callActivity: CallActivity) : BottomShee
|
|||
}
|
||||
|
||||
private fun initEmojiBar() {
|
||||
if (CapabilitiesUtilNew.isCallReactionsSupported(callActivity.conversationUser)) {
|
||||
if (CapabilitiesUtil.isCallReactionsSupported(callActivity.conversationUser)) {
|
||||
binding.advancedCallOptionsTitle.visibility = View.GONE
|
||||
|
||||
val capabilities = callActivity.conversationUser?.capabilities
|
||||
|
|
|
@ -128,8 +128,8 @@ class SetStatusDialogFragment :
|
|||
currentUser = currentUserProvider?.currentUser?.blockingGet()
|
||||
currentStatus = it.getParcelable(ARG_CURRENT_STATUS_PARAM)
|
||||
|
||||
credentials = ApiUtils.getCredentials(currentUser?.username, currentUser?.token)
|
||||
ncApi.getPredefinedStatuses(credentials, ApiUtils.getUrlForPredefinedStatuses(currentUser?.baseUrl))
|
||||
credentials = ApiUtils.getCredentials(currentUser?.username, currentUser?.token)!!
|
||||
ncApi.getPredefinedStatuses(credentials, ApiUtils.getUrlForPredefinedStatuses(currentUser?.baseUrl!!))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<ResponseBody> {
|
||||
|
@ -369,7 +369,7 @@ class SetStatusDialogFragment :
|
|||
|
||||
private fun clearStatus() {
|
||||
val credentials = ApiUtils.getCredentials(currentUser?.username, currentUser?.token)
|
||||
ncApi.statusDeleteMessage(credentials, ApiUtils.getUrlForStatusMessage(currentUser?.baseUrl))
|
||||
ncApi.statusDeleteMessage(credentials, ApiUtils.getUrlForStatusMessage(currentUser?.baseUrl!!))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread()).subscribe(object : Observer<GenericOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
|
@ -393,7 +393,7 @@ class SetStatusDialogFragment :
|
|||
private fun setStatus(statusType: StatusType) {
|
||||
visualizeStatus(statusType)
|
||||
|
||||
ncApi.setStatusType(credentials, ApiUtils.getUrlForSetStatusType(currentUser?.baseUrl), statusType.string)
|
||||
ncApi.setStatusType(credentials, ApiUtils.getUrlForSetStatusType(currentUser?.baseUrl!!), statusType.string)
|
||||
.subscribeOn(
|
||||
Schedulers
|
||||
.io()
|
||||
|
@ -468,7 +468,7 @@ class SetStatusDialogFragment :
|
|||
) {
|
||||
ncApi.setCustomStatusMessage(
|
||||
credentials,
|
||||
ApiUtils.getUrlForSetCustomStatus(currentUser?.baseUrl),
|
||||
ApiUtils.getUrlForSetCustomStatus(currentUser?.baseUrl!!),
|
||||
statusIcon,
|
||||
inputText,
|
||||
clearAt
|
||||
|
@ -499,7 +499,7 @@ class SetStatusDialogFragment :
|
|||
|
||||
ncApi.setPredefinedStatusMessage(
|
||||
credentials,
|
||||
ApiUtils.getUrlForSetPredefinedStatus(currentUser?.baseUrl),
|
||||
ApiUtils.getUrlForSetPredefinedStatus(currentUser?.baseUrl!!),
|
||||
selectedPredefinedStatus!!.id,
|
||||
if (clearAt == -1L) null else clearAt
|
||||
)
|
||||
|
|
|
@ -154,7 +154,7 @@ class ShowReactionsDialog(
|
|||
ncApi.getReactions(
|
||||
credentials,
|
||||
ApiUtils.getUrlForMessageReaction(
|
||||
user?.baseUrl,
|
||||
user?.baseUrl!!,
|
||||
roomToken,
|
||||
chatMessage.id
|
||||
),
|
||||
|
@ -209,7 +209,7 @@ class ShowReactionsDialog(
|
|||
ncApi.deleteReaction(
|
||||
credentials,
|
||||
ApiUtils.getUrlForMessageReaction(
|
||||
user?.baseUrl,
|
||||
user?.baseUrl!!,
|
||||
roomToken,
|
||||
message.id
|
||||
),
|
||||
|
|
|
@ -81,7 +81,7 @@ class ChunkedFileUploader(
|
|||
|
||||
init {
|
||||
initHttpClient(okHttpClient, currentUser)
|
||||
remoteChunkUrl = ApiUtils.getUrlForChunkedUpload(currentUser.baseUrl, currentUser.userId)
|
||||
remoteChunkUrl = ApiUtils.getUrlForChunkedUpload(currentUser.baseUrl!!, currentUser.userId!!)
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
|
@ -295,7 +295,7 @@ class ChunkedFileUploader(
|
|||
ApiUtils.getCredentials(
|
||||
currentUser.username,
|
||||
currentUser.token
|
||||
),
|
||||
)!!,
|
||||
"Authorization"
|
||||
)
|
||||
)
|
||||
|
@ -304,8 +304,8 @@ class ChunkedFileUploader(
|
|||
|
||||
private fun assembleChunks(uploadFolderUri: String, targetPath: String) {
|
||||
val destinationUri: String = ApiUtils.getUrlForFileUpload(
|
||||
currentUser.baseUrl,
|
||||
currentUser.userId,
|
||||
currentUser.baseUrl!!,
|
||||
currentUser.userId!!,
|
||||
targetPath
|
||||
)
|
||||
val originUri = "$uploadFolderUri/.file"
|
||||
|
|
|
@ -24,7 +24,7 @@ class FileUploader(
|
|||
fun upload(sourceFileUri: Uri, fileName: String, remotePath: String, metaData: String?): Observable<Boolean> {
|
||||
return ncApi.uploadFile(
|
||||
ApiUtils.getCredentials(currentUser.username, currentUser.token),
|
||||
ApiUtils.getUrlForFileUpload(currentUser.baseUrl, currentUser.userId, remotePath),
|
||||
ApiUtils.getUrlForFileUpload(currentUser.baseUrl!!, currentUser.userId!!, remotePath),
|
||||
createRequestBody(sourceFileUri)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
|
|
@ -69,7 +69,7 @@ object AccountUtils {
|
|||
private fun matchAccounts(importAccount: ImportAccount, user: User): Boolean {
|
||||
var accountFound = false
|
||||
if (importAccount.token != null) {
|
||||
if (UriUtils.hasHttpProtocolPrefixed(importAccount.baseUrl)) {
|
||||
if (UriUtils.hasHttpProtocolPrefixed(importAccount.baseUrl!!)) {
|
||||
if (
|
||||
user.username == importAccount.username &&
|
||||
user.baseUrl == importAccount.baseUrl
|
||||
|
|
|
@ -1,559 +0,0 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* @author Marcel Hibbe
|
||||
* @author Tim Krüger
|
||||
* Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
|
||||
* Copyright (C) 2021-2022 Marcel Hibbe <dev@mhibbe.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;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.nextcloud.talk.BuildConfig;
|
||||
import com.nextcloud.talk.R;
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||
import com.nextcloud.talk.data.user.model.User;
|
||||
import com.nextcloud.talk.models.RetrofitBucket;
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import okhttp3.Credentials;
|
||||
|
||||
public class ApiUtils {
|
||||
public static final int APIv1 = 1;
|
||||
public static final int APIv2 = 2;
|
||||
public static final int APIv3 = 3;
|
||||
public static final int APIv4 = 4;
|
||||
public static final int AVATAR_SIZE_BIG = 512;
|
||||
public static final int AVATAR_SIZE_SMALL = 64;
|
||||
private static final String TAG = "ApiUtils";
|
||||
private static final String ocsApiVersion = "/ocs/v2.php";
|
||||
private static final String spreedApiVersion = "/apps/spreed/api/v1";
|
||||
private static final String spreedApiBase = ocsApiVersion + "/apps/spreed/api/v";
|
||||
|
||||
private static final String userAgent = "Mozilla/5.0 (Android) Nextcloud-Talk v";
|
||||
|
||||
public static String getUserAgent() {
|
||||
return userAgent + BuildConfig.VERSION_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This is only supported on API v1-3, in API v4+ please use
|
||||
* {@link ApiUtils#getUrlForAttendees(int, String, String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getUrlForRemovingParticipantFromConversation(String baseUrl, String roomToken, boolean isGuest) {
|
||||
String url = getUrlForParticipants(APIv1, baseUrl, roomToken);
|
||||
|
||||
if (isGuest) {
|
||||
url += "/guests";
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public static RetrofitBucket getRetrofitBucketForContactsSearch(String baseUrl, @Nullable String searchQuery) {
|
||||
RetrofitBucket retrofitBucket = new RetrofitBucket();
|
||||
retrofitBucket.setUrl(baseUrl + ocsApiVersion + "/apps/files_sharing/api/v1/sharees");
|
||||
|
||||
Map<String, String> queryMap = new HashMap<>();
|
||||
|
||||
if (searchQuery == null) {
|
||||
searchQuery = "";
|
||||
}
|
||||
queryMap.put("format", "json");
|
||||
queryMap.put("search", searchQuery);
|
||||
queryMap.put("itemType", "call");
|
||||
|
||||
retrofitBucket.setQueryMap(queryMap);
|
||||
|
||||
return retrofitBucket;
|
||||
}
|
||||
|
||||
public static String getUrlForFilePreviewWithRemotePath(String baseUrl, String remotePath, int px) {
|
||||
return baseUrl + "/index.php/core/preview.png?file="
|
||||
+ Uri.encode(remotePath, "UTF-8")
|
||||
+ "&x=" + px + "&y=" + px + "&a=1&mode=cover&forceIcon=1";
|
||||
}
|
||||
|
||||
public static String getUrlForFilePreviewWithFileId(String baseUrl, String fileId, int px) {
|
||||
return baseUrl + "/index.php/core/preview?fileId="
|
||||
+ fileId + "&x=" + px + "&y=" + px + "&a=1&mode=cover&forceIcon=1";
|
||||
}
|
||||
|
||||
public static String getSharingUrl(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/apps/files_sharing/api/v1/shares";
|
||||
}
|
||||
|
||||
public static RetrofitBucket getRetrofitBucketForContactsSearchFor14(String baseUrl, @Nullable String searchQuery) {
|
||||
RetrofitBucket retrofitBucket = getRetrofitBucketForContactsSearch(baseUrl, searchQuery);
|
||||
retrofitBucket.setUrl(baseUrl + ocsApiVersion + "/core/autocomplete/get");
|
||||
|
||||
retrofitBucket.getQueryMap().put("itemId", "new");
|
||||
|
||||
return retrofitBucket;
|
||||
}
|
||||
|
||||
public static String getUrlForCapabilities(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/cloud/capabilities";
|
||||
}
|
||||
|
||||
public static int getCallApiVersion(User capabilities, int[] versions) throws NoSupportedApiException {
|
||||
return getConversationApiVersion(capabilities, versions);
|
||||
}
|
||||
|
||||
public static int getConversationApiVersion(User 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 (user.hasSpreedFeatureCapability("conversation-v" + version)) {
|
||||
return version;
|
||||
}
|
||||
|
||||
// Fallback for old API versions
|
||||
if ((version == APIv1 || version == APIv2)) {
|
||||
if (user.hasSpreedFeatureCapability("conversation-v2")) {
|
||||
return version;
|
||||
}
|
||||
if (version == APIv1 &&
|
||||
user.hasSpreedFeatureCapability("mention-flag") &&
|
||||
!user.hasSpreedFeatureCapability("conversation-v4")) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new NoSupportedApiException();
|
||||
}
|
||||
|
||||
public static int getSignalingApiVersion(User user, int[] versions) throws NoSupportedApiException {
|
||||
for (int version : versions) {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "signaling-v" + version)) {
|
||||
return version;
|
||||
}
|
||||
|
||||
if (version == APIv2 &&
|
||||
CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "sip-support") &&
|
||||
!CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "signaling-v3")) {
|
||||
return version;
|
||||
}
|
||||
|
||||
if (version == APIv1 &&
|
||||
!CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "signaling-v3")) {
|
||||
// Has no capability, we just assume it is always there when there is no v3 or later
|
||||
return version;
|
||||
}
|
||||
}
|
||||
throw new NoSupportedApiException();
|
||||
}
|
||||
|
||||
public static int getChatApiVersion(User user, int[] versions) throws NoSupportedApiException {
|
||||
for (int version : versions) {
|
||||
if (version == APIv1 && CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "chat-v2")) {
|
||||
// Do not question that chat-v2 capability shows the availability of api/v1/ endpoint *see no evil*
|
||||
return version;
|
||||
}
|
||||
}
|
||||
throw new NoSupportedApiException();
|
||||
}
|
||||
|
||||
protected static String getUrlForApi(int version, String baseUrl) {
|
||||
return baseUrl + spreedApiBase + version;
|
||||
}
|
||||
|
||||
public static String getUrlForRooms(int version, String baseUrl) {
|
||||
return getUrlForApi(version, baseUrl) + "/room";
|
||||
}
|
||||
|
||||
public static String getUrlForRoom(int version, String baseUrl, String token) {
|
||||
return getUrlForRooms(version, baseUrl) + "/" + token;
|
||||
}
|
||||
|
||||
public static String getUrlForAttendees(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/attendees";
|
||||
}
|
||||
|
||||
public static String getUrlForParticipants(int version, String baseUrl, String token) {
|
||||
if (token == null || token.isEmpty()) {
|
||||
Log.e(TAG, "token was null or empty");
|
||||
}
|
||||
return getUrlForRoom(version, baseUrl, token) + "/participants";
|
||||
}
|
||||
|
||||
public static String getUrlForParticipantsActive(int version, String baseUrl, String token) {
|
||||
return getUrlForParticipants(version, baseUrl, token) + "/active";
|
||||
}
|
||||
|
||||
public static String getUrlForParticipantsSelf(int version, String baseUrl, String token) {
|
||||
return getUrlForParticipants(version, baseUrl, token) + "/self";
|
||||
}
|
||||
|
||||
public static String getUrlForParticipantsResendInvitations(int version, String baseUrl, String token) {
|
||||
return getUrlForParticipants(version, baseUrl, token) + "/resend-invitations";
|
||||
}
|
||||
|
||||
public static String getUrlForRoomFavorite(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/favorite";
|
||||
}
|
||||
|
||||
public static String getUrlForRoomModerators(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/moderators";
|
||||
}
|
||||
|
||||
public static String getUrlForRoomNotificationLevel(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/notify";
|
||||
}
|
||||
|
||||
public static String getUrlForRoomPublic(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/public";
|
||||
}
|
||||
|
||||
public static String getUrlForRoomPassword(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/password";
|
||||
}
|
||||
|
||||
public static String getUrlForRoomReadOnlyState(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/read-only";
|
||||
}
|
||||
|
||||
public static String getUrlForRoomWebinaryLobby(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/webinar/lobby";
|
||||
}
|
||||
|
||||
public static String getUrlForRoomNotificationCalls(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/notify-calls";
|
||||
}
|
||||
|
||||
public static String getUrlForCall(int version, String baseUrl, String token) {
|
||||
return getUrlForApi(version, baseUrl) + "/call/" + token;
|
||||
}
|
||||
|
||||
public static String getUrlForChat(int version, String baseUrl, String token) {
|
||||
return getUrlForApi(version, baseUrl) + "/chat/" + token;
|
||||
}
|
||||
|
||||
public static String getUrlForMentionSuggestions(int version, String baseUrl, String token) {
|
||||
return getUrlForChat(version, baseUrl, token) + "/mentions";
|
||||
}
|
||||
|
||||
public static String getUrlForChatMessage(int version, String baseUrl, String token, String messageId) {
|
||||
return getUrlForChat(version, baseUrl, token) + "/" + messageId;
|
||||
}
|
||||
|
||||
public static String getUrlForChatSharedItems(int version, String baseUrl, String token) {
|
||||
return getUrlForChat(version, baseUrl, token) + "/share";
|
||||
}
|
||||
|
||||
public static String getUrlForChatSharedItemsOverview(int version, String baseUrl, String token) {
|
||||
return getUrlForChatSharedItems(version, baseUrl, token) + "/overview";
|
||||
}
|
||||
|
||||
public static String getUrlForSignaling(int version, String baseUrl) {
|
||||
return getUrlForApi(version, baseUrl) + "/signaling";
|
||||
}
|
||||
|
||||
public static String getUrlForSignalingBackend(int version, String baseUrl) {
|
||||
return getUrlForSignaling(version, baseUrl) + "/backend";
|
||||
}
|
||||
|
||||
public static String getUrlForSignalingSettings(int version, String baseUrl) {
|
||||
return getUrlForSignaling(version, baseUrl) + "/settings";
|
||||
}
|
||||
|
||||
public static String getUrlForSignaling(int version, String baseUrl, String token) {
|
||||
return getUrlForSignaling(version, baseUrl) + "/" + token;
|
||||
}
|
||||
|
||||
public static String getUrlForOpenConversations(int version, String baseUrl) {
|
||||
return getUrlForApi(version, baseUrl) + "/listed-room";
|
||||
}
|
||||
|
||||
public static RetrofitBucket getRetrofitBucketForCreateRoom(int version, String baseUrl, String roomType,
|
||||
@Nullable String source,
|
||||
@Nullable String invite,
|
||||
@Nullable String conversationName) {
|
||||
RetrofitBucket retrofitBucket = new RetrofitBucket();
|
||||
retrofitBucket.setUrl(getUrlForRooms(version, baseUrl));
|
||||
Map<String, String> queryMap = new HashMap<>();
|
||||
|
||||
queryMap.put("roomType", roomType);
|
||||
if (invite != null) {
|
||||
queryMap.put("invite", invite);
|
||||
}
|
||||
if (source != null) {
|
||||
queryMap.put("source", source);
|
||||
}
|
||||
|
||||
if (conversationName != null) {
|
||||
queryMap.put("roomName", conversationName);
|
||||
}
|
||||
|
||||
retrofitBucket.setQueryMap(queryMap);
|
||||
|
||||
return retrofitBucket;
|
||||
}
|
||||
|
||||
public static RetrofitBucket getRetrofitBucketForAddParticipant(int version, String baseUrl, String token, String user) {
|
||||
RetrofitBucket retrofitBucket = new RetrofitBucket();
|
||||
retrofitBucket.setUrl(getUrlForParticipants(version, baseUrl, token));
|
||||
|
||||
Map<String, String> queryMap = new HashMap<>();
|
||||
|
||||
queryMap.put("newParticipant", user);
|
||||
|
||||
retrofitBucket.setQueryMap(queryMap);
|
||||
|
||||
return retrofitBucket;
|
||||
|
||||
}
|
||||
|
||||
public static RetrofitBucket getRetrofitBucketForAddParticipantWithSource(
|
||||
int version,
|
||||
String baseUrl,
|
||||
String token,
|
||||
String source,
|
||||
String id
|
||||
) {
|
||||
RetrofitBucket retrofitBucket = getRetrofitBucketForAddParticipant(version, baseUrl, token, id);
|
||||
retrofitBucket.getQueryMap().put("source", source);
|
||||
return retrofitBucket;
|
||||
}
|
||||
|
||||
public static String getUrlForUserProfile(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/cloud/user";
|
||||
}
|
||||
|
||||
public static String getUrlForUserData(String baseUrl, String userId) {
|
||||
return baseUrl + ocsApiVersion + "/cloud/users/" + userId;
|
||||
}
|
||||
|
||||
public static String getUrlForUserSettings(String baseUrl) {
|
||||
// FIXME Introduce API version
|
||||
return baseUrl + ocsApiVersion + spreedApiVersion + "/settings/user";
|
||||
}
|
||||
|
||||
public static String getUrlPostfixForStatus() {
|
||||
return "/status.php";
|
||||
}
|
||||
|
||||
public static String getUrlForAvatar(String baseUrl, String name, boolean requestBigSize) {
|
||||
int avatarSize = requestBigSize ? AVATAR_SIZE_BIG : AVATAR_SIZE_SMALL;
|
||||
return baseUrl + "/index.php/avatar/" + Uri.encode(name) + "/" + avatarSize;
|
||||
}
|
||||
|
||||
public static String getUrlForGuestAvatar(String baseUrl, String name, boolean requestBigSize) {
|
||||
int avatarSize = requestBigSize ? AVATAR_SIZE_BIG : AVATAR_SIZE_SMALL;
|
||||
return baseUrl + "/index.php/avatar/guest/" + Uri.encode(name) + "/" + avatarSize;
|
||||
}
|
||||
|
||||
public static String getUrlForConversationAvatar(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/avatar";
|
||||
}
|
||||
|
||||
public static String getUrlForConversationAvatarWithVersion(int version, String baseUrl, String token,
|
||||
boolean isDark,
|
||||
String avatarVersion) {
|
||||
String isDarkString = "";
|
||||
if (isDark) {
|
||||
isDarkString = "/dark";
|
||||
}
|
||||
|
||||
String avatarVersionString = "";
|
||||
if (avatarVersion != null) {
|
||||
avatarVersionString = "?avatarVersion=" + avatarVersion;
|
||||
}
|
||||
|
||||
return getUrlForRoom(version, baseUrl, token) + "/avatar" + isDarkString + avatarVersionString;
|
||||
}
|
||||
|
||||
public static String getCredentials(String username, String token) {
|
||||
if (TextUtils.isEmpty(username) && TextUtils.isEmpty(token)) {
|
||||
return null;
|
||||
}
|
||||
return Credentials.basic(username, token, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static String getUrlNextcloudPush(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/apps/notifications/api/v2/push";
|
||||
}
|
||||
|
||||
public static String getUrlPushProxy() {
|
||||
return NextcloudTalkApplication.Companion.getSharedApplication().
|
||||
getApplicationContext().getResources().getString(R.string.nc_push_server_url) + "/devices";
|
||||
}
|
||||
|
||||
// see https://github.com/nextcloud/notifications/blob/master/docs/ocs-endpoint-v2.md
|
||||
public static String getUrlForNcNotificationWithId(String baseUrl, String notificationId) {
|
||||
return baseUrl + ocsApiVersion + "/apps/notifications/api/v2/notifications/" + notificationId;
|
||||
}
|
||||
|
||||
public static String getUrlForSearchByNumber(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/cloud/users/search/by-phone";
|
||||
}
|
||||
|
||||
public static String getUrlForFileUpload(String baseUrl, String user, String remotePath) {
|
||||
return baseUrl + "/remote.php/dav/files/" + user + remotePath;
|
||||
}
|
||||
|
||||
public static String getUrlForChunkedUpload(String baseUrl, String user) {
|
||||
return baseUrl + "/remote.php/dav/uploads/" + user;
|
||||
}
|
||||
|
||||
public static String getUrlForFileDownload(String baseUrl, String user, String remotePath) {
|
||||
return baseUrl + "/remote.php/dav/files/" + user + "/" + remotePath;
|
||||
}
|
||||
|
||||
public static String getUrlForTempAvatar(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/apps/spreed/temp-user-avatar";
|
||||
}
|
||||
|
||||
public static String getUrlForUserFields(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/cloud/user/fields";
|
||||
}
|
||||
|
||||
public static String getUrlToSendLocation(int version, String baseUrl, String roomToken) {
|
||||
return getUrlForChat(version, baseUrl, roomToken) + "/share";
|
||||
}
|
||||
|
||||
public static String getUrlForHoverCard(String baseUrl, String userId) {
|
||||
return baseUrl + ocsApiVersion +
|
||||
"/hovercard/v1/" + userId;
|
||||
}
|
||||
|
||||
public static String getUrlForChatReadMarker(int version, String baseUrl, String roomToken) {
|
||||
return getUrlForChat(version, baseUrl, roomToken) + "/read";
|
||||
}
|
||||
|
||||
/*
|
||||
* OCS Status API
|
||||
*/
|
||||
|
||||
public static String getUrlForStatus(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/apps/user_status/api/v1/user_status";
|
||||
}
|
||||
|
||||
public static String getUrlForSetStatusType(String baseUrl) {
|
||||
return getUrlForStatus(baseUrl) + "/status";
|
||||
}
|
||||
|
||||
public static String getUrlForPredefinedStatuses(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/apps/user_status/api/v1/predefined_statuses";
|
||||
}
|
||||
|
||||
public static String getUrlForStatusMessage(String baseUrl) {
|
||||
return getUrlForStatus(baseUrl) + "/message";
|
||||
}
|
||||
|
||||
public static String getUrlForSetCustomStatus(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/apps/user_status/api/v1/user_status/message/custom";
|
||||
}
|
||||
|
||||
public static String getUrlForSetPredefinedStatus(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/apps/user_status/api/v1/user_status/message/predefined";
|
||||
}
|
||||
|
||||
public static String getUrlForUserStatuses(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/apps/user_status/api/v1/statuses";
|
||||
}
|
||||
|
||||
public static String getUrlForMessageReaction(String baseUrl,
|
||||
String roomToken,
|
||||
String messageId) {
|
||||
return baseUrl + ocsApiVersion + spreedApiVersion + "/reaction/" + roomToken + "/" + messageId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getUrlForUnifiedSearch(@NonNull String baseUrl, @NonNull String providerId) {
|
||||
return baseUrl + ocsApiVersion + "/search/providers/" + providerId + "/search";
|
||||
}
|
||||
|
||||
public static String getUrlForPoll(String baseUrl,
|
||||
String roomToken,
|
||||
String pollId) {
|
||||
return getUrlForPoll(baseUrl, roomToken) + "/" + pollId;
|
||||
}
|
||||
|
||||
public static String getUrlForPoll(String baseUrl,
|
||||
String roomToken) {
|
||||
return baseUrl + ocsApiVersion + spreedApiVersion + "/poll/" + roomToken;
|
||||
}
|
||||
|
||||
public static String getUrlForMessageExpiration(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/message-expiration";
|
||||
}
|
||||
|
||||
public static String getUrlForOpenGraph(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/references/resolve";
|
||||
}
|
||||
|
||||
public static String getUrlForRecording(int version, String baseUrl, String token) {
|
||||
return getUrlForApi(version, baseUrl) + "/recording/" + token;
|
||||
}
|
||||
|
||||
public static String getUrlForRequestAssistance(int version, String baseUrl, String token) {
|
||||
return getUrlForApi(version, baseUrl) + "/breakout-rooms/" + token + "/request-assistance";
|
||||
}
|
||||
|
||||
public static String getUrlForConversationDescription(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/description";
|
||||
}
|
||||
|
||||
public static String getUrlForTranslation(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/translation/translate";
|
||||
}
|
||||
|
||||
public static String getUrlForLanguages(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + "/translation/languages";
|
||||
}
|
||||
|
||||
public static String getUrlForReminder(User user, String roomToken, String messageId, int version) {
|
||||
String url = ApiUtils.getUrlForChatMessage(version, user.getBaseUrl(), roomToken, messageId);
|
||||
return url + "/reminder";
|
||||
}
|
||||
|
||||
public static String getUrlForRecordingConsent(int version, String baseUrl, String token) {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/recording-consent";
|
||||
}
|
||||
|
||||
public static String getUrlForInvitation(String baseUrl) {
|
||||
return baseUrl + ocsApiVersion + spreedApiVersion + "/federation/invitation";
|
||||
}
|
||||
|
||||
public static String getUrlForInvitationAccept(String baseUrl, int id) {
|
||||
return getUrlForInvitation(baseUrl) + "/" + id;
|
||||
}
|
||||
|
||||
public static String getUrlForInvitationReject(String baseUrl, int id) {
|
||||
return getUrlForInvitation(baseUrl) + "/" + id;
|
||||
}
|
||||
}
|
577
app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt
Normal file
577
app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt
Normal file
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* @author Marcel Hibbe
|
||||
* @author Tim Krüger
|
||||
* Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
|
||||
* Copyright (C) 2021-2022 Marcel Hibbe <dev@mhibbe.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
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import com.nextcloud.talk.BuildConfig
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.RetrofitBucket
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
|
||||
import okhttp3.Credentials.basic
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
object ApiUtils {
|
||||
private val TAG = ApiUtils::class.java.simpleName
|
||||
const val API_V1 = 1
|
||||
private const val API_V2 = 2
|
||||
const val API_V3 = 3
|
||||
const val API_V4 = 4
|
||||
private const val AVATAR_SIZE_BIG = 512
|
||||
private const val AVATAR_SIZE_SMALL = 64
|
||||
private const val OCS_API_VERSION = "/ocs/v2.php"
|
||||
private const val SPREED_API_VERSION = "/apps/spreed/api/v1"
|
||||
private const val SPREED_API_BASE = "$OCS_API_VERSION/apps/spreed/api/v"
|
||||
|
||||
@JvmStatic
|
||||
val userAgent = "Mozilla/5.0 (Android) Nextcloud-Talk v"
|
||||
get() = field + BuildConfig.VERSION_NAME
|
||||
|
||||
@Deprecated(
|
||||
"This is only supported on API v1-3, in API v4+ please use " +
|
||||
"{@link ApiUtils#getUrlForAttendees(int, String, String)} instead."
|
||||
)
|
||||
fun getUrlForRemovingParticipantFromConversation(baseUrl: String?, roomToken: String?, isGuest: Boolean): String {
|
||||
var url = getUrlForParticipants(API_V1, baseUrl, roomToken)
|
||||
if (isGuest) {
|
||||
url += "/guests"
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
private fun getRetrofitBucketForContactsSearch(baseUrl: String, searchQuery: String?): RetrofitBucket {
|
||||
var query = searchQuery
|
||||
val retrofitBucket = RetrofitBucket()
|
||||
retrofitBucket.url = "$baseUrl$OCS_API_VERSION/apps/files_sharing/api/v1/sharees"
|
||||
val queryMap: MutableMap<String, String> = HashMap()
|
||||
if (query == null) {
|
||||
query = ""
|
||||
}
|
||||
queryMap["format"] = "json"
|
||||
queryMap["search"] = query
|
||||
queryMap["itemType"] = "call"
|
||||
retrofitBucket.queryMap = queryMap
|
||||
return retrofitBucket
|
||||
}
|
||||
|
||||
fun getUrlForFilePreviewWithRemotePath(baseUrl: String, remotePath: String?, px: Int): String {
|
||||
return (
|
||||
baseUrl + "/index.php/core/preview.png?file=" +
|
||||
Uri.encode(remotePath, "UTF-8") +
|
||||
"&x=" + px + "&y=" + px + "&a=1&mode=cover&forceIcon=1"
|
||||
)
|
||||
}
|
||||
|
||||
fun getUrlForFilePreviewWithFileId(baseUrl: String, fileId: String, px: Int): String {
|
||||
return (
|
||||
baseUrl + "/index.php/core/preview?fileId=" +
|
||||
fileId + "&x=" + px + "&y=" + px + "&a=1&mode=cover&forceIcon=1"
|
||||
)
|
||||
}
|
||||
|
||||
fun getSharingUrl(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/files_sharing/api/v1/shares"
|
||||
}
|
||||
|
||||
fun getRetrofitBucketForContactsSearchFor14(baseUrl: String, searchQuery: String?): RetrofitBucket {
|
||||
val retrofitBucket = getRetrofitBucketForContactsSearch(baseUrl, searchQuery)
|
||||
retrofitBucket.url = "$baseUrl$OCS_API_VERSION/core/autocomplete/get"
|
||||
retrofitBucket.queryMap?.put("itemId", "new")
|
||||
return retrofitBucket
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForCapabilities(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/cloud/capabilities"
|
||||
}
|
||||
|
||||
@Throws(NoSupportedApiException::class)
|
||||
fun getCallApiVersion(capabilities: User, versions: IntArray): Int {
|
||||
return getConversationApiVersion(capabilities, versions)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Throws(NoSupportedApiException::class)
|
||||
@Suppress("ReturnCount")
|
||||
fun getConversationApiVersion(user: User, versions: IntArray): Int {
|
||||
var hasApiV4 = false
|
||||
for (version in versions) {
|
||||
hasApiV4 = hasApiV4 or (version == API_V4)
|
||||
}
|
||||
if (!hasApiV4) {
|
||||
val e = Exception("Api call did not try conversation-v4 api")
|
||||
Log.d(TAG, e.message, e)
|
||||
}
|
||||
for (version in versions) {
|
||||
if (user.hasSpreedFeatureCapability("conversation-v$version")) {
|
||||
return version
|
||||
}
|
||||
|
||||
// Fallback for old API versions
|
||||
if (version == API_V1 || version == API_V2) {
|
||||
if (user.hasSpreedFeatureCapability("conversation-v2")) {
|
||||
return version
|
||||
}
|
||||
if (version == API_V1 &&
|
||||
user.hasSpreedFeatureCapability("mention-flag") &&
|
||||
!user.hasSpreedFeatureCapability("conversation-v4")
|
||||
) {
|
||||
return version
|
||||
}
|
||||
}
|
||||
}
|
||||
throw NoSupportedApiException()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Throws(NoSupportedApiException::class)
|
||||
@Suppress("ReturnCount")
|
||||
fun getSignalingApiVersion(user: User, versions: IntArray): Int {
|
||||
val spreedCapabilities = user.capabilities!!.spreedCapability
|
||||
for (version in versions) {
|
||||
if (spreedCapabilities != null) {
|
||||
if (hasSpreedFeatureCapability(spreedCapabilities, "signaling-v$version")) {
|
||||
return version
|
||||
}
|
||||
if (version == API_V2 &&
|
||||
hasSpreedFeatureCapability(spreedCapabilities, "sip-support") &&
|
||||
!hasSpreedFeatureCapability(spreedCapabilities, "signaling-v3")
|
||||
) {
|
||||
return version
|
||||
}
|
||||
if (version == API_V1 &&
|
||||
!hasSpreedFeatureCapability(spreedCapabilities, "signaling-v3")
|
||||
) {
|
||||
// Has no capability, we just assume it is always there when there is no v3 or later
|
||||
return version
|
||||
}
|
||||
}
|
||||
}
|
||||
throw NoSupportedApiException()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Throws(NoSupportedApiException::class)
|
||||
fun getChatApiVersion(spreedCapabilities: SpreedCapability, versions: IntArray): Int {
|
||||
for (version in versions) {
|
||||
if (version == API_V1 && hasSpreedFeatureCapability(spreedCapabilities, "chat-v2")) {
|
||||
// Do not question that chat-v2 capability shows the availability of api/v1/ endpoint *see no evil*
|
||||
return version
|
||||
}
|
||||
}
|
||||
throw NoSupportedApiException()
|
||||
}
|
||||
|
||||
private fun getUrlForApi(version: Int, baseUrl: String?): String {
|
||||
return baseUrl + SPREED_API_BASE + version
|
||||
}
|
||||
|
||||
fun getUrlForRooms(version: Int, baseUrl: String?): String {
|
||||
return getUrlForApi(version, baseUrl) + "/room"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForRoom(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRooms(version, baseUrl) + "/" + token
|
||||
}
|
||||
|
||||
fun getUrlForAttendees(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/attendees"
|
||||
}
|
||||
|
||||
fun getUrlForParticipants(version: Int, baseUrl: String?, token: String?): String {
|
||||
if (token.isNullOrEmpty()) {
|
||||
Log.e(TAG, "token was null or empty")
|
||||
}
|
||||
return getUrlForRoom(version, baseUrl, token) + "/participants"
|
||||
}
|
||||
|
||||
fun getUrlForParticipantsActive(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForParticipants(version, baseUrl, token) + "/active"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForParticipantsSelf(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForParticipants(version, baseUrl, token) + "/self"
|
||||
}
|
||||
|
||||
fun getUrlForParticipantsResendInvitations(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForParticipants(version, baseUrl, token) + "/resend-invitations"
|
||||
}
|
||||
|
||||
fun getUrlForRoomFavorite(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/favorite"
|
||||
}
|
||||
|
||||
fun getUrlForRoomModerators(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/moderators"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForRoomNotificationLevel(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/notify"
|
||||
}
|
||||
|
||||
fun getUrlForRoomPublic(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/public"
|
||||
}
|
||||
|
||||
fun getUrlForRoomPassword(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/password"
|
||||
}
|
||||
|
||||
fun getUrlForRoomReadOnlyState(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/read-only"
|
||||
}
|
||||
|
||||
fun getUrlForRoomWebinaryLobby(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/webinar/lobby"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForRoomNotificationCalls(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/notify-calls"
|
||||
}
|
||||
|
||||
fun getUrlForCall(version: Int, baseUrl: String?, token: String): String {
|
||||
return getUrlForApi(version, baseUrl) + "/call/" + token
|
||||
}
|
||||
|
||||
fun getUrlForChat(version: Int, baseUrl: String?, token: String): String {
|
||||
return getUrlForApi(version, baseUrl) + "/chat/" + token
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForMentionSuggestions(version: Int, baseUrl: String?, token: String): String {
|
||||
return getUrlForChat(version, baseUrl, token) + "/mentions"
|
||||
}
|
||||
|
||||
fun getUrlForChatMessage(version: Int, baseUrl: String?, token: String, messageId: String): String {
|
||||
return getUrlForChat(version, baseUrl, token) + "/" + messageId
|
||||
}
|
||||
|
||||
fun getUrlForChatSharedItems(version: Int, baseUrl: String?, token: String): String {
|
||||
return getUrlForChat(version, baseUrl, token) + "/share"
|
||||
}
|
||||
|
||||
fun getUrlForChatSharedItemsOverview(version: Int, baseUrl: String?, token: String): String {
|
||||
return getUrlForChatSharedItems(version, baseUrl, token) + "/overview"
|
||||
}
|
||||
|
||||
fun getUrlForSignaling(version: Int, baseUrl: String?): String {
|
||||
return getUrlForApi(version, baseUrl) + "/signaling"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForSignalingBackend(version: Int, baseUrl: String?): String {
|
||||
return getUrlForSignaling(version, baseUrl) + "/backend"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForSignalingSettings(version: Int, baseUrl: String?): String {
|
||||
return getUrlForSignaling(version, baseUrl) + "/settings"
|
||||
}
|
||||
|
||||
fun getUrlForSignaling(version: Int, baseUrl: String?, token: String): String {
|
||||
return getUrlForSignaling(version, baseUrl) + "/" + token
|
||||
}
|
||||
|
||||
fun getUrlForOpenConversations(version: Int, baseUrl: String?): String {
|
||||
return getUrlForApi(version, baseUrl) + "/listed-room"
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
fun getRetrofitBucketForCreateRoom(
|
||||
version: Int,
|
||||
baseUrl: String?,
|
||||
roomType: String,
|
||||
source: String?,
|
||||
invite: String?,
|
||||
conversationName: String?
|
||||
): RetrofitBucket {
|
||||
val retrofitBucket = RetrofitBucket()
|
||||
retrofitBucket.url = getUrlForRooms(version, baseUrl)
|
||||
val queryMap: MutableMap<String, String> = HashMap()
|
||||
queryMap["roomType"] = roomType
|
||||
if (invite != null) {
|
||||
queryMap["invite"] = invite
|
||||
}
|
||||
if (source != null) {
|
||||
queryMap["source"] = source
|
||||
}
|
||||
if (conversationName != null) {
|
||||
queryMap["roomName"] = conversationName
|
||||
}
|
||||
retrofitBucket.queryMap = queryMap
|
||||
return retrofitBucket
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getRetrofitBucketForAddParticipant(
|
||||
version: Int,
|
||||
baseUrl: String?,
|
||||
token: String?,
|
||||
user: String
|
||||
): RetrofitBucket {
|
||||
val retrofitBucket = RetrofitBucket()
|
||||
retrofitBucket.url = getUrlForParticipants(version, baseUrl, token)
|
||||
val queryMap: MutableMap<String, String> = HashMap()
|
||||
queryMap["newParticipant"] = user
|
||||
retrofitBucket.queryMap = queryMap
|
||||
return retrofitBucket
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getRetrofitBucketForAddParticipantWithSource(
|
||||
version: Int,
|
||||
baseUrl: String?,
|
||||
token: String?,
|
||||
source: String,
|
||||
id: String
|
||||
): RetrofitBucket {
|
||||
val retrofitBucket = getRetrofitBucketForAddParticipant(version, baseUrl, token, id)
|
||||
retrofitBucket.queryMap?.put("source", source)
|
||||
return retrofitBucket
|
||||
}
|
||||
|
||||
fun getUrlForUserProfile(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/cloud/user"
|
||||
}
|
||||
|
||||
fun getUrlForUserData(baseUrl: String, userId: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/cloud/users/$userId"
|
||||
}
|
||||
|
||||
fun getUrlForUserSettings(baseUrl: String): String {
|
||||
// FIXME Introduce API version
|
||||
return "$baseUrl$OCS_API_VERSION$SPREED_API_VERSION/settings/user"
|
||||
}
|
||||
|
||||
fun getUrlPostfixForStatus(): String {
|
||||
return "/status.php"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForAvatar(baseUrl: String?, name: String?, requestBigSize: Boolean): String {
|
||||
val avatarSize = if (requestBigSize) AVATAR_SIZE_BIG else AVATAR_SIZE_SMALL
|
||||
return baseUrl + "/index.php/avatar/" + Uri.encode(name) + "/" + avatarSize
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForGuestAvatar(baseUrl: String?, name: String?, requestBigSize: Boolean): String {
|
||||
val avatarSize = if (requestBigSize) AVATAR_SIZE_BIG else AVATAR_SIZE_SMALL
|
||||
return baseUrl + "/index.php/avatar/guest/" + Uri.encode(name) + "/" + avatarSize
|
||||
}
|
||||
|
||||
fun getUrlForConversationAvatar(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/avatar"
|
||||
}
|
||||
|
||||
fun getUrlForConversationAvatarWithVersion(
|
||||
version: Int,
|
||||
baseUrl: String?,
|
||||
token: String?,
|
||||
isDark: Boolean,
|
||||
avatarVersion: String?
|
||||
): String {
|
||||
var isDarkString = ""
|
||||
if (isDark) {
|
||||
isDarkString = "/dark"
|
||||
}
|
||||
var avatarVersionString = ""
|
||||
if (avatarVersion != null) {
|
||||
avatarVersionString = "?avatarVersion=$avatarVersion"
|
||||
}
|
||||
return getUrlForRoom(version, baseUrl, token) + "/avatar" + isDarkString + avatarVersionString
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getCredentials(username: String?, token: String?): String? {
|
||||
return if (TextUtils.isEmpty(username) && TextUtils.isEmpty(token)) {
|
||||
null
|
||||
} else {
|
||||
basic(username!!, token!!, StandardCharsets.UTF_8)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlNextcloudPush(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/notifications/api/v2/push"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlPushProxy(): String {
|
||||
return sharedApplication!!.applicationContext.resources.getString(R.string.nc_push_server_url) + "/devices"
|
||||
}
|
||||
|
||||
// see https://github.com/nextcloud/notifications/blob/master/docs/ocs-endpoint-v2.md
|
||||
fun getUrlForNcNotificationWithId(baseUrl: String, notificationId: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/notifications/api/v2/notifications/$notificationId"
|
||||
}
|
||||
|
||||
fun getUrlForSearchByNumber(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/cloud/users/search/by-phone"
|
||||
}
|
||||
|
||||
fun getUrlForFileUpload(baseUrl: String, user: String, remotePath: String): String {
|
||||
return "$baseUrl/remote.php/dav/files/$user$remotePath"
|
||||
}
|
||||
|
||||
fun getUrlForChunkedUpload(baseUrl: String, user: String): String {
|
||||
return "$baseUrl/remote.php/dav/uploads/$user"
|
||||
}
|
||||
|
||||
fun getUrlForFileDownload(baseUrl: String, user: String, remotePath: String): String {
|
||||
return "$baseUrl/remote.php/dav/files/$user/$remotePath"
|
||||
}
|
||||
|
||||
fun getUrlForTempAvatar(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/spreed/temp-user-avatar"
|
||||
}
|
||||
|
||||
fun getUrlForUserFields(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/cloud/user/fields"
|
||||
}
|
||||
|
||||
fun getUrlToSendLocation(version: Int, baseUrl: String?, roomToken: String): String {
|
||||
return getUrlForChat(version, baseUrl, roomToken) + "/share"
|
||||
}
|
||||
|
||||
fun getUrlForHoverCard(baseUrl: String, userId: String): String {
|
||||
return baseUrl + OCS_API_VERSION +
|
||||
"/hovercard/v1/" + userId
|
||||
}
|
||||
|
||||
fun getUrlForChatReadMarker(version: Int, baseUrl: String?, roomToken: String): String {
|
||||
return getUrlForChat(version, baseUrl, roomToken) + "/read"
|
||||
}
|
||||
|
||||
/*
|
||||
* OCS Status API
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getUrlForStatus(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/user_status/api/v1/user_status"
|
||||
}
|
||||
|
||||
fun getUrlForSetStatusType(baseUrl: String): String {
|
||||
return getUrlForStatus(baseUrl) + "/status"
|
||||
}
|
||||
|
||||
fun getUrlForPredefinedStatuses(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/user_status/api/v1/predefined_statuses"
|
||||
}
|
||||
|
||||
fun getUrlForStatusMessage(baseUrl: String): String {
|
||||
return getUrlForStatus(baseUrl) + "/message"
|
||||
}
|
||||
|
||||
fun getUrlForSetCustomStatus(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/user_status/api/v1/user_status/message/custom"
|
||||
}
|
||||
|
||||
fun getUrlForSetPredefinedStatus(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/user_status/api/v1/user_status/message/predefined"
|
||||
}
|
||||
|
||||
fun getUrlForUserStatuses(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/apps/user_status/api/v1/statuses"
|
||||
}
|
||||
|
||||
fun getUrlForMessageReaction(baseUrl: String, roomToken: String, messageId: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION$SPREED_API_VERSION/reaction/$roomToken/$messageId"
|
||||
}
|
||||
|
||||
fun getUrlForUnifiedSearch(baseUrl: String, providerId: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/search/providers/$providerId/search"
|
||||
}
|
||||
|
||||
fun getUrlForPoll(baseUrl: String, roomToken: String, pollId: String): String {
|
||||
return getUrlForPoll(baseUrl, roomToken) + "/" + pollId
|
||||
}
|
||||
|
||||
fun getUrlForPoll(baseUrl: String, roomToken: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION$SPREED_API_VERSION/poll/$roomToken"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForMessageExpiration(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/message-expiration"
|
||||
}
|
||||
|
||||
fun getUrlForOpenGraph(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/references/resolve"
|
||||
}
|
||||
|
||||
fun getUrlForRecording(version: Int, baseUrl: String?, token: String): String {
|
||||
return getUrlForApi(version, baseUrl) + "/recording/" + token
|
||||
}
|
||||
|
||||
fun getUrlForRequestAssistance(version: Int, baseUrl: String?, token: String): String {
|
||||
return getUrlForApi(version, baseUrl) + "/breakout-rooms/" + token + "/request-assistance"
|
||||
}
|
||||
|
||||
fun getUrlForConversationDescription(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/description"
|
||||
}
|
||||
|
||||
fun getUrlForTranslation(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/translation/translate"
|
||||
}
|
||||
|
||||
fun getUrlForLanguages(baseUrl: String): String {
|
||||
return "$baseUrl$OCS_API_VERSION/translation/languages"
|
||||
}
|
||||
|
||||
fun getUrlForReminder(user: User, roomToken: String, messageId: String, version: Int): String {
|
||||
val url = getUrlForChatMessage(version, user.baseUrl!!, roomToken, messageId)
|
||||
return "$url/reminder"
|
||||
}
|
||||
|
||||
fun getUrlForRecordingConsent(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRoom(version, baseUrl, token) + "/recording-consent"
|
||||
}
|
||||
|
||||
fun getUrlForInvitation(baseUrl: String): String {
|
||||
return baseUrl + OCS_API_VERSION + SPREED_API_VERSION + "/federation/invitation"
|
||||
}
|
||||
|
||||
fun getUrlForInvitationAccept(baseUrl: String, id: Int): String {
|
||||
return getUrlForInvitation(baseUrl) + "/" + id
|
||||
}
|
||||
|
||||
fun getUrlForInvitationReject(baseUrl: String, id: Int): String {
|
||||
return getUrlForInvitation(baseUrl) + "/" + id
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUrlForRoomCapabilities(version: Int, baseUrl: String?, token: String?): String {
|
||||
return getUrlForRooms(version, baseUrl) + "/" + token + "/capabilities"
|
||||
}
|
||||
}
|
275
app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt
Normal file
275
app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt
Normal file
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Andy Scherzinger
|
||||
* @author Mario Danic
|
||||
* @author Marcel Hibbe
|
||||
* Copyright (C) 2023-2024 Marcel Hibbe <dev@mhibbe.de>
|
||||
* 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
|
||||
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
|
||||
enum class SpreedFeatures(val value: String) {
|
||||
RECORDING_V1("recording-v1"),
|
||||
REACTIONS("reactions"),
|
||||
RAISE_HAND("raise-hand"),
|
||||
DIRECT_MENTION_FLAG("direct-mention-flag"),
|
||||
CONVERSATION_CALL_FLAGS("conversation-call-flags"),
|
||||
SILENT_SEND("silent-send"),
|
||||
MENTION_FLAG("mention-flag"),
|
||||
DELETE_MESSAGES("delete-messages"),
|
||||
READ_ONLY_ROOMS("read-only-rooms"),
|
||||
RICH_OBJECT_LIST_MEDIA("rich-object-list-media"),
|
||||
SILENT_CALL("silent-call"),
|
||||
MESSAGE_EXPIRATION("message-expiration"),
|
||||
WEBINARY_LOBBY("webinary-lobby"),
|
||||
VOICE_MESSAGE_SHARING("voice-message-sharing"),
|
||||
INVITE_GROUPS_AND_MAILS("invite-groups-and-mails"),
|
||||
CIRCLES_SUPPORT("circles-support"),
|
||||
LAST_ROOM_ACTIVITY("last-room-activity"),
|
||||
NOTIFICATION_LEVELS("notification-levels"),
|
||||
CLEAR_HISTORY("clear-history"),
|
||||
AVATAR("avatar"),
|
||||
LISTABLE_ROOMS("listable-rooms"),
|
||||
LOCKED_ONE_TO_ONE_ROOMS("locked-one-to-one-rooms"),
|
||||
TEMP_USER_AVATAR_API("temp-user-avatar-api"),
|
||||
PHONEBOOK_SEARCH("phonebook-search"),
|
||||
GEO_LOCATION_SHARING("geo-location-sharing"),
|
||||
TALK_POLLS("talk-polls")
|
||||
}
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
object CapabilitiesUtil {
|
||||
|
||||
//region Version checks
|
||||
fun isServerEOL(serverVersion: Int): Boolean {
|
||||
return (serverVersion < SERVER_VERSION_MIN_SUPPORTED)
|
||||
}
|
||||
|
||||
fun isServerAlmostEOL(serverVersion: Int): Boolean {
|
||||
return (serverVersion < SERVER_VERSION_SUPPORT_WARNING)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
//region CoreCapabilities
|
||||
|
||||
@JvmStatic
|
||||
fun isLinkPreviewAvailable(user: User): Boolean {
|
||||
return user.capabilities?.coreCapability?.referenceApi != null &&
|
||||
user.capabilities?.coreCapability?.referenceApi == "true"
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
//region SpreedCapabilities
|
||||
|
||||
@JvmStatic
|
||||
fun hasSpreedFeatureCapability(spreedCapabilities: SpreedCapability, spreedFeatures: SpreedFeatures): Boolean {
|
||||
if (spreedCapabilities.features != null) {
|
||||
return spreedCapabilities.features!!.contains(spreedFeatures.value)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Deprecated("Add your capability to Capability enums and use hasSpreedFeatureCapability with enum.")
|
||||
fun hasSpreedFeatureCapability(spreedCapabilities: SpreedCapability, capabilityName: String): Boolean {
|
||||
if (spreedCapabilities.features != null) {
|
||||
return spreedCapabilities.features!!.contains(capabilityName)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getMessageMaxLength(spreedCapabilities: SpreedCapability): Int {
|
||||
if (spreedCapabilities.config?.containsKey("chat") == true) {
|
||||
val chatConfigHashMap = spreedCapabilities.config!!["chat"]
|
||||
if (chatConfigHashMap?.containsKey("max-length") == true) {
|
||||
val chatSize = (chatConfigHashMap["max-length"]!!.toString()).toInt()
|
||||
return if (chatSize > 0) {
|
||||
chatSize
|
||||
} else {
|
||||
DEFAULT_CHAT_SIZE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DEFAULT_CHAT_SIZE
|
||||
}
|
||||
|
||||
fun isReadStatusAvailable(spreedCapabilities: SpreedCapability): Boolean {
|
||||
if (spreedCapabilities.config?.containsKey("chat") == true) {
|
||||
val map: Map<String, Any>? = spreedCapabilities.config!!["chat"]
|
||||
return map != null && map.containsKey("read-privacy")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isCallRecordingAvailable(spreedCapabilities: SpreedCapability): Boolean {
|
||||
if (hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.RECORDING_V1) &&
|
||||
spreedCapabilities.config?.containsKey("call") == true
|
||||
) {
|
||||
val map: Map<String, Any>? = spreedCapabilities.config!!["call"]
|
||||
if (map != null && map.containsKey("recording")) {
|
||||
return (map["recording"].toString()).toBoolean()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getAttachmentFolder(spreedCapabilities: SpreedCapability): String {
|
||||
if (spreedCapabilities.config?.containsKey("attachments") == true) {
|
||||
val map = spreedCapabilities.config!!["attachments"]
|
||||
if (map?.containsKey("folder") == true) {
|
||||
return map["folder"].toString()
|
||||
}
|
||||
}
|
||||
return "/Talk"
|
||||
}
|
||||
|
||||
fun isConversationDescriptionEndpointAvailable(spreedCapabilities: SpreedCapability): Boolean {
|
||||
return hasSpreedFeatureCapability(spreedCapabilities, "room-description")
|
||||
}
|
||||
|
||||
fun isUnifiedSearchAvailable(spreedCapabilities: SpreedCapability): Boolean {
|
||||
return hasSpreedFeatureCapability(spreedCapabilities, "unified-search")
|
||||
}
|
||||
|
||||
fun isAbleToCall(spreedCapabilities: SpreedCapability): Boolean {
|
||||
return if (
|
||||
spreedCapabilities.config?.containsKey("call") == true &&
|
||||
spreedCapabilities.config!!["call"] != null &&
|
||||
spreedCapabilities.config!!["call"]!!.containsKey("enabled")
|
||||
) {
|
||||
java.lang.Boolean.parseBoolean(spreedCapabilities.config!!["call"]!!["enabled"].toString())
|
||||
} else {
|
||||
// older nextcloud versions without the capability can't disable the calls
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun isCallReactionsSupported(user: User?): Boolean {
|
||||
if (user?.capabilities != null) {
|
||||
val capabilities = user.capabilities
|
||||
return capabilities?.spreedCapability?.config?.containsKey("call") == true &&
|
||||
capabilities.spreedCapability!!.config!!["call"] != null &&
|
||||
capabilities.spreedCapability!!.config!!["call"]!!.containsKey("supported-reactions")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isTranslationsSupported(spreedCapabilities: SpreedCapability): Boolean {
|
||||
return spreedCapabilities.config?.containsKey("chat") == true &&
|
||||
spreedCapabilities.config!!["chat"] != null &&
|
||||
spreedCapabilities.config!!["chat"]!!.containsKey("has-translation-providers") &&
|
||||
spreedCapabilities.config!!["chat"]!!["has-translation-providers"] == true
|
||||
}
|
||||
|
||||
fun getRecordingConsentType(spreedCapabilities: SpreedCapability): Int {
|
||||
if (
|
||||
spreedCapabilities.config?.containsKey("call") == true &&
|
||||
spreedCapabilities.config!!["call"] != null &&
|
||||
spreedCapabilities.config!!["call"]!!.containsKey("recording-consent")
|
||||
) {
|
||||
return when (
|
||||
spreedCapabilities.config!!["call"]!!["recording-consent"].toString()
|
||||
.toInt()
|
||||
) {
|
||||
1 -> RECORDING_CONSENT_REQUIRED
|
||||
2 -> RECORDING_CONSENT_DEPEND_ON_CONVERSATION
|
||||
else -> RECORDING_CONSENT_NOT_REQUIRED
|
||||
}
|
||||
}
|
||||
return RECORDING_CONSENT_NOT_REQUIRED
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
//region SpreedCapabilities that can't be used with federation as the settings for them are global
|
||||
|
||||
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"]!!.toString()).toInt() == 1
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isTypingStatusAvailable(user: User): Boolean {
|
||||
if (user.capabilities?.spreedCapability?.config?.containsKey("chat") == true) {
|
||||
val map = user.capabilities!!.spreedCapability!!.config!!["chat"]
|
||||
return map != null && map.containsKey("typing-privacy")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isTypingStatusPrivate(user: User): Boolean {
|
||||
if (user.capabilities?.spreedCapability?.config?.containsKey("chat") == true) {
|
||||
val map = user.capabilities!!.spreedCapability!!.config!!["chat"]
|
||||
if (map?.containsKey("typing-privacy") == true) {
|
||||
return (map["typing-privacy"]!!.toString()).toInt() == 1
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
//region ThemingCapabilities
|
||||
|
||||
fun getServerName(user: User?): String? {
|
||||
if (user?.capabilities?.themingCapability != null) {
|
||||
return user.capabilities!!.themingCapability!!.name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
//region ProvisioningCapabilities
|
||||
|
||||
fun canEditScopes(user: User): Boolean {
|
||||
return user.capabilities?.provisioningCapability?.accountPropertyScopesVersion != null &&
|
||||
user.capabilities!!.provisioningCapability!!.accountPropertyScopesVersion!! > 1
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
//region UserStatusCapabilities
|
||||
|
||||
@JvmStatic
|
||||
fun isUserStatusAvailable(user: User): Boolean {
|
||||
return user.capabilities?.userStatusCapability?.enabled == true &&
|
||||
user.capabilities?.userStatusCapability?.supportsEmoji == true
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
const val DEFAULT_CHAT_SIZE = 1000
|
||||
const val RECORDING_CONSENT_NOT_REQUIRED = 0
|
||||
const val RECORDING_CONSENT_REQUIRED = 1
|
||||
const val RECORDING_CONSENT_DEPEND_ON_CONVERSATION = 2
|
||||
private const val SERVER_VERSION_MIN_SUPPORTED = 14
|
||||
private const val SERVER_VERSION_SUPPORT_WARNING = 18
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
package com.nextcloud.talk.utils
|
||||
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.domain.ConversationType
|
||||
import com.nextcloud.talk.models.domain.ParticipantType
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
|
@ -45,28 +44,28 @@ object ConversationUtils {
|
|||
ParticipantType.MODERATOR == conversation.participantType
|
||||
}
|
||||
|
||||
private fun isLockedOneToOne(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||
fun isLockedOneToOne(conversation: ConversationModel, spreedCapabilities: SpreedCapability): Boolean {
|
||||
return conversation.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
|
||||
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms")
|
||||
CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, "locked-one-to-one-rooms")
|
||||
}
|
||||
|
||||
fun canModerate(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||
fun canModerate(conversation: ConversationModel, spreedCapabilities: SpreedCapability): Boolean {
|
||||
return isParticipantOwnerOrModerator(conversation) &&
|
||||
!isLockedOneToOne(conversation, conversationUser) &&
|
||||
!isLockedOneToOne(conversation, spreedCapabilities) &&
|
||||
conversation.type != ConversationType.FORMER_ONE_TO_ONE &&
|
||||
!isNoteToSelfConversation(conversation)
|
||||
}
|
||||
|
||||
fun isLobbyViewApplicable(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||
return !canModerate(conversation, conversationUser) &&
|
||||
fun isLobbyViewApplicable(conversation: ConversationModel, spreedCapabilities: SpreedCapability): Boolean {
|
||||
return !canModerate(conversation, spreedCapabilities) &&
|
||||
(
|
||||
conversation.type == ConversationType.ROOM_GROUP_CALL ||
|
||||
conversation.type == ConversationType.ROOM_PUBLIC_CALL
|
||||
)
|
||||
}
|
||||
|
||||
fun isNameEditable(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||
return canModerate(conversation, conversationUser) &&
|
||||
fun isNameEditable(conversation: ConversationModel, spreedCapabilities: SpreedCapability): Boolean {
|
||||
return canModerate(conversation, spreedCapabilities) &&
|
||||
ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != conversation.type
|
||||
}
|
||||
|
||||
|
@ -79,12 +78,12 @@ object ConversationUtils {
|
|||
}
|
||||
}
|
||||
|
||||
fun canDelete(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||
fun canDelete(conversation: ConversationModel, spreedCapability: SpreedCapability): Boolean {
|
||||
return if (conversation.canDeleteConversation != null) {
|
||||
// Available since APIv2
|
||||
conversation.canDeleteConversation!!
|
||||
} else {
|
||||
canModerate(conversation, conversationUser)
|
||||
canModerate(conversation, spreedCapability)
|
||||
// Fallback for APIv1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,6 @@ import com.nextcloud.talk.utils.MimetypeUtils.isGif
|
|||
import com.nextcloud.talk.utils.MimetypeUtils.isMarkdown
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACCOUNT
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_ID
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
import java.io.File
|
||||
import java.util.concurrent.ExecutionException
|
||||
|
||||
|
@ -308,7 +307,7 @@ class FileViewerUtils(private val context: Context, private val user: User) {
|
|||
.putString(DownloadFileToCacheWorker.KEY_USER_ID, user.userId)
|
||||
.putString(
|
||||
DownloadFileToCacheWorker.KEY_ATTACHMENT_FOLDER,
|
||||
CapabilitiesUtilNew.getAttachmentFolder(user)
|
||||
CapabilitiesUtil.getAttachmentFolder(user.capabilities!!.spreedCapability!!)
|
||||
)
|
||||
.putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileInfo.fileName)
|
||||
.putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path)
|
||||
|
|
|
@ -22,22 +22,21 @@
|
|||
|
||||
package com.nextcloud.talk.utils
|
||||
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||
|
||||
/**
|
||||
* see https://nextcloud-talk.readthedocs.io/en/latest/constants/#attendee-permissions
|
||||
*/
|
||||
class ParticipantPermissions(
|
||||
private val user: User,
|
||||
private val spreedCapabilities: SpreedCapability,
|
||||
private val conversation: ConversationModel
|
||||
) {
|
||||
|
||||
@Deprecated("Use ChatRepository.ConversationModel")
|
||||
constructor(user: User, conversation: Conversation) : this(
|
||||
user,
|
||||
constructor(spreedCapabilities: SpreedCapability, conversation: Conversation) : this(
|
||||
spreedCapabilities,
|
||||
ConversationModel.mapToConversationModel(conversation)
|
||||
)
|
||||
|
||||
|
@ -52,8 +51,8 @@ class ParticipantPermissions(
|
|||
private val hasChatPermission = (conversation.permissions and CHAT) == CHAT
|
||||
|
||||
private fun hasConversationPermissions(): Boolean {
|
||||
return CapabilitiesUtilNew.hasSpreedFeatureCapability(
|
||||
user,
|
||||
return CapabilitiesUtil.hasSpreedFeatureCapability(
|
||||
spreedCapabilities,
|
||||
"conversation-permissions"
|
||||
)
|
||||
}
|
||||
|
@ -91,7 +90,7 @@ class ParticipantPermissions(
|
|||
}
|
||||
|
||||
fun hasChatPermission(): Boolean {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "chat-permission")) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, "chat-permission")) {
|
||||
return hasChatPermission
|
||||
}
|
||||
// if capability is not available then the spreed version doesn't support to restrict this
|
||||
|
|
|
@ -238,7 +238,7 @@ class PushUtils {
|
|||
val credentials = ApiUtils.getCredentials(user.username, user.token)
|
||||
ncApi.registerDeviceForNotificationsWithNextcloud(
|
||||
credentials,
|
||||
ApiUtils.getUrlNextcloudPush(user.baseUrl),
|
||||
ApiUtils.getUrlNextcloudPush(user.baseUrl!!),
|
||||
nextcloudRegisterPushMap
|
||||
)
|
||||
.subscribe(object : Observer<PushRegistrationOverall> {
|
||||
|
|
|
@ -53,8 +53,8 @@ object RemoteFileUtils {
|
|||
return ncApi.checkIfFileExists(
|
||||
ApiUtils.getCredentials(currentUser.username, currentUser.token),
|
||||
ApiUtils.getUrlForFileUpload(
|
||||
currentUser.baseUrl,
|
||||
currentUser.userId,
|
||||
currentUser.baseUrl!!,
|
||||
currentUser.userId!!,
|
||||
remotePath
|
||||
)
|
||||
)
|
||||
|
|
|
@ -22,10 +22,10 @@ package com.nextcloud.talk.utils
|
|||
import android.content.Context
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
|
||||
object ShareUtils {
|
||||
fun getStringForIntent(context: Context, user: User, conversation: Conversation?): String {
|
||||
fun getStringForIntent(context: Context, user: User, conversation: ConversationModel?): String {
|
||||
return String.format(
|
||||
context.resources.getString(R.string.nc_share_text),
|
||||
user.baseUrl,
|
||||
|
|
|
@ -89,4 +89,5 @@ object BundleKeys {
|
|||
const val KEY_REAUTHORIZE_ACCOUNT = "KEY_REAUTHORIZE_ACCOUNT"
|
||||
const val KEY_PASSWORD = "KEY_PASSWORD"
|
||||
const val KEY_REMOTE_TALK_SHARE = "KEY_REMOTE_TALK_SHARE"
|
||||
const val KEY_CHAT_API_VERSION = "KEY_CHAT_API_VERSION"
|
||||
}
|
||||
|
|
|
@ -1,267 +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
|
||||
|
||||
@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
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isServerEOL(capabilities: Capabilities?): Boolean {
|
||||
// Capability is available since Talk 4 => Nextcloud 14 => Autmn 2018
|
||||
return !hasSpreedFeatureCapability(capabilities, "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 canMarkRoomAsUnread(user: User): Boolean {
|
||||
return hasSpreedFeatureCapability(user, "chat-unread")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun hasSpreedFeatureCapability(user: User?, capabilityName: String): Boolean {
|
||||
return hasSpreedFeatureCapability(user?.capabilities, capabilityName)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun hasSpreedFeatureCapability(capabilities: Capabilities?, capabilityName: String): Boolean {
|
||||
if (capabilities?.spreedCapability?.features != null) {
|
||||
return capabilities.spreedCapability!!.features!!.contains(capabilityName)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getMessageMaxLength(user: User?): Int {
|
||||
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"]!!.toString()).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, Any>? = 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"]!!.toString()).toInt() == 1
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isTypingStatusAvailable(user: User): Boolean {
|
||||
if (user.capabilities?.spreedCapability?.config?.containsKey("chat") == true) {
|
||||
val map = user.capabilities!!.spreedCapability!!.config!!["chat"]
|
||||
return map != null && map.containsKey("typing-privacy")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isTypingStatusPrivate(user: User): Boolean {
|
||||
if (user.capabilities?.spreedCapability?.config?.containsKey("chat") == true) {
|
||||
val map = user.capabilities!!.spreedCapability!!.config!!["chat"]
|
||||
if (map?.containsKey("typing-privacy") == true) {
|
||||
return (map["typing-privacy"]!!.toString()).toInt() == 1
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isCallRecordingAvailable(user: User): Boolean {
|
||||
if (hasSpreedFeatureCapability(user, "recording-v1") &&
|
||||
user.capabilities?.spreedCapability?.config?.containsKey("call") == true
|
||||
) {
|
||||
val map: Map<String, Any>? = user.capabilities!!.spreedCapability!!.config!!["call"]
|
||||
if (map != null && map.containsKey("recording")) {
|
||||
return (map["recording"].toString()).toBoolean()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isUserStatusAvailable(user: User): Boolean {
|
||||
return user.capabilities?.userStatusCapability?.enabled == true &&
|
||||
user.capabilities?.userStatusCapability?.supportsEmoji == true
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
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"].toString()
|
||||
}
|
||||
}
|
||||
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 isConversationAvatarEndpointAvailable(user: User): Boolean {
|
||||
return user.capabilities?.spreedCapability?.features?.contains("avatar") == true
|
||||
}
|
||||
|
||||
fun isConversationDescriptionEndpointAvailable(user: User): Boolean {
|
||||
return user.capabilities?.spreedCapability?.features?.contains("room-description") == 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"].toString())
|
||||
} else {
|
||||
// older nextcloud versions without the capability can't disable the calls
|
||||
true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isCallReactionsSupported(user: User?): Boolean {
|
||||
if (user?.capabilities != null) {
|
||||
val capabilities = user.capabilities
|
||||
return capabilities?.spreedCapability?.config?.containsKey("call") == true &&
|
||||
capabilities.spreedCapability!!.config!!["call"] != null &&
|
||||
capabilities.spreedCapability!!.config!!["call"]!!.containsKey("supported-reactions")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isUnifiedSearchAvailable(user: User): Boolean {
|
||||
return hasSpreedFeatureCapability(user, "unified-search")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isLinkPreviewAvailable(user: User): Boolean {
|
||||
return user.capabilities?.coreCapability?.referenceApi != null &&
|
||||
user.capabilities?.coreCapability?.referenceApi == "true"
|
||||
}
|
||||
|
||||
fun isTranslationsSupported(user: User?): Boolean {
|
||||
if (user?.capabilities != null) {
|
||||
val capabilities = user.capabilities
|
||||
return capabilities?.spreedCapability?.config?.containsKey("chat") == true &&
|
||||
capabilities.spreedCapability!!.config!!["chat"] != null &&
|
||||
capabilities.spreedCapability!!.config!!["chat"]!!.containsKey("has-translation-providers") &&
|
||||
capabilities.spreedCapability!!.config!!["chat"]!!["has-translation-providers"] == true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun isRemindSupported(user: User?): Boolean {
|
||||
if (user?.capabilities != null) {
|
||||
val capabilities = user.capabilities
|
||||
return capabilities?.spreedCapability?.features?.contains("remind-me-later") == true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun getRecordingConsentType(user: User?): Int {
|
||||
if (user?.capabilities != null) {
|
||||
val capabilities = user.capabilities
|
||||
if (
|
||||
capabilities?.spreedCapability?.config?.containsKey("call") == true &&
|
||||
capabilities.spreedCapability!!.config!!["call"] != null &&
|
||||
capabilities.spreedCapability!!.config!!["call"]!!.containsKey("recording-consent")
|
||||
) {
|
||||
return when (
|
||||
capabilities.spreedCapability!!.config!!["call"]!!["recording-consent"].toString()
|
||||
.toInt()
|
||||
) {
|
||||
1 -> RECORDING_CONSENT_REQUIRED
|
||||
2 -> RECORDING_CONSENT_DEPEND_ON_CONVERSATION
|
||||
else -> RECORDING_CONSENT_NOT_REQUIRED
|
||||
}
|
||||
}
|
||||
}
|
||||
return RECORDING_CONSENT_NOT_REQUIRED
|
||||
}
|
||||
|
||||
const val DEFAULT_CHAT_SIZE = 1000
|
||||
const val RECORDING_CONSENT_NOT_REQUIRED = 0
|
||||
const val RECORDING_CONSENT_REQUIRED = 1
|
||||
const val RECORDING_CONSENT_DEPEND_ON_CONVERSATION = 2
|
||||
}
|
|
@ -35,7 +35,7 @@ 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.UserIdUtils;
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
|
||||
import com.nextcloud.talk.utils.CapabilitiesUtil;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -158,7 +158,8 @@ public class DatabaseStorageModule {
|
|||
});
|
||||
|
||||
} else if ("conversation_info_message_notifications_dropdown".equals(key)) {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels")) {
|
||||
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser.getCapabilities().getSpreedCapability(), "notification" +
|
||||
"-levels")) {
|
||||
if (TextUtils.isEmpty(messageNotificationLevel) || !messageNotificationLevel.equals(value)) {
|
||||
int intValue;
|
||||
switch (value) {
|
||||
|
@ -175,7 +176,7 @@ public class DatabaseStorageModule {
|
|||
intValue = 0;
|
||||
}
|
||||
|
||||
int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
|
||||
int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{ApiUtils.API_V4, 1});
|
||||
|
||||
ncApi.setNotificationLevel(ApiUtils.getCredentials(conversationUser.getUsername(),
|
||||
conversationUser.getToken()),
|
||||
|
|
|
@ -25,7 +25,6 @@ import androidx.lifecycle.LiveData
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.nextcloud.talk.activities.CallActivity.Companion.TAG
|
||||
import com.nextcloud.talk.location.GeocodingActivity
|
||||
import fr.dudie.nominatim.client.TalkJsonNominatimClient
|
||||
import fr.dudie.nominatim.model.Address
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
@ -70,9 +69,9 @@ class GeoCodingViewModel : ViewModel() {
|
|||
try {
|
||||
val results = nominatimClient.search(query) as ArrayList<Address>
|
||||
for (address in results) {
|
||||
Log.d(GeocodingActivity.TAG, address.displayName)
|
||||
Log.d(GeocodingActivity.TAG, address.latitude.toString())
|
||||
Log.d(GeocodingActivity.TAG, address.longitude.toString())
|
||||
Log.d(TAG, address.displayName)
|
||||
Log.d(TAG, address.latitude.toString())
|
||||
Log.d(TAG, address.longitude.toString())
|
||||
}
|
||||
geocodingResults = results
|
||||
geocodingResultsLiveData.postValue(results)
|
||||
|
|
|
@ -113,7 +113,7 @@ public class WebSocketConnectionHelper {
|
|||
}
|
||||
|
||||
HelloOverallWebSocketMessage getAssembledHelloModel(User user, String ticket) {
|
||||
int apiVersion = ApiUtils.getSignalingApiVersion(user, new int[]{ApiUtils.APIv3, 2, 1});
|
||||
int apiVersion = ApiUtils.getSignalingApiVersion(user, new int[]{ApiUtils.API_V3, 2, 1});
|
||||
|
||||
HelloOverallWebSocketMessage helloOverallWebSocketMessage = new HelloOverallWebSocketMessage();
|
||||
helloOverallWebSocketMessage.setType("hello");
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
package com.nextcloud.talk.utils
|
||||
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.json.capabilities.SpreedCapability
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import junit.framework.TestCase
|
||||
import org.junit.Test
|
||||
|
@ -31,7 +31,7 @@ class ParticipantPermissionsTest : TestCase() {
|
|||
|
||||
@Test
|
||||
fun test_areFlagsSet() {
|
||||
val user = User()
|
||||
val spreedCapability = SpreedCapability()
|
||||
val conversation = Conversation()
|
||||
conversation.permissions = ParticipantPermissions.PUBLISH_SCREEN or
|
||||
ParticipantPermissions.JOIN_CALL or
|
||||
|
@ -39,7 +39,7 @@ class ParticipantPermissionsTest : TestCase() {
|
|||
|
||||
val attendeePermissions =
|
||||
ParticipantPermissions(
|
||||
user,
|
||||
spreedCapability,
|
||||
conversation
|
||||
)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import android.content.Context
|
|||
import android.content.res.Resources
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.models.domain.ConversationModel
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import io.reactivex.Maybe
|
||||
import org.junit.Assert
|
||||
|
@ -49,19 +49,19 @@ class ShareUtilsTest {
|
|||
private val baseUrl = "https://my.nextcloud.com"
|
||||
private val token = "2aotbrjr"
|
||||
|
||||
private lateinit var conversation: Conversation
|
||||
private lateinit var conversation: ConversationModel
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.openMocks(this)
|
||||
Mockito.`when`(userManager!!.currentUser).thenReturn(Maybe.just(user))
|
||||
Mockito.`when`(user!!.baseUrl).thenReturn(baseUrl)
|
||||
Mockito.`when`(user!!.baseUrl!!).thenReturn(baseUrl)
|
||||
Mockito.`when`(context!!.resources).thenReturn(resources)
|
||||
Mockito.`when`(resources!!.getString(R.string.nc_share_text))
|
||||
.thenReturn("Join the conversation at %1\$s/index.php/call/%2\$s")
|
||||
Mockito.`when`(resources.getString(R.string.nc_share_text_pass)).thenReturn("\nPassword: %1\$s")
|
||||
|
||||
conversation = Conversation(token = token)
|
||||
conversation = ConversationModel(token = token)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
build:
|
||||
maxIssues: 116
|
||||
maxIssues: 122
|
||||
weights:
|
||||
# complexity: 2
|
||||
# LongParameterList: 1
|
||||
|
|
|
@ -1313,8 +1313,6 @@ lQyC8nl8P5PgkEZ5CHcGymZlpzihR3ECrPJTk39Sb7D3SxCW4WrChV3kVfmLgvc=
|
|||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
pub C21CE653B639E41A
|
||||
uid Eric Kuck <eric@bluelinelabs.com>
|
||||
|
||||
sub 4F80368F9034B8D0
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: BCPG v1.68
|
||||
|
@ -1324,21 +1322,20 @@ aBF7dud1bzw7voZo5ieGK923wUB+R9vQYd5DYfNLBHj9/TrTVCfKfUIeeEQRZYBz
|
|||
ufYcDwi4uVx9VPj2wRhkK+lzxphvosJCNFK8Vn82oY7eHQ1RA4AEhCeE/hz8maq6
|
||||
NPoOPjpEN0DVnPIYdjPsdqd4UKQzkX/wMOxghz8SdcVROzUoL+9pZzx968OFuGrV
|
||||
lUD0su37S6To1IUn6WNEuy1uJTzT3Zqi0hfm31AqPxlLWDOwnuKvUJl3RObyli2k
|
||||
CBtDa5xPE6GU6ZUEFUZ7qbk7iV5p8uTchKVbABEBAAG0IUVyaWMgS3VjayA8ZXJp
|
||||
Y0BibHVlbGluZWxhYnMuY29tPrkBDQRU5ChoAQgAxC44rEZjgnJevvrzdL5vCVqC
|
||||
1WI9cZ7L8DwF/pvm7NbRKC5GgXigul18UET80q4E3WIi0tTMG+pVWO+1v0dEu/Re
|
||||
B/l+hc76iwJjOlwSiQ1jvq6/q0Nhne0/0khSYNWyd0AwJ2VZktcD93dJV4EqTm1O
|
||||
Ck1gigAd/GN5wslQkMST/nUYUGm4cA/RZVSA8PSFZDZ2CxHyRyHgaOQNBUmWG2gf
|
||||
ExUrrJA26iKowkNqZXWegnzYwlf8ZRE6MZM0JPLOUw/+r4ybI8ny+/U55s2sm0XZ
|
||||
CcJvNda5N3SoaC/OgGWZFx1s9UksN7MmvhznaSUMeaeVFbGC3nu9dsQhV9RxMwAR
|
||||
AQABiQEfBBgBAgAJBQJU5ChoAhsMAAoJEMIc5lO2OeQadSwH/07x1foZKkFRGMlj
|
||||
wCmofKGSqZ9fu6ueOIV6fwHjrhlfkSyKN+96xbjhwIvWhKdSmWP/AsUqRDD/mTHw
|
||||
ZMdlgmdXkGEvvCuJDL5FlQzl9OWeeplfVhLysx6dzj/G8AUXlfEIGBvb8Q56d5dK
|
||||
MpId4H4vt+YIzS8x/ry+QTTDJAOu1cVJfwoX34yMcZ+IHTzly2XKi4zQ41DyfrgY
|
||||
lCodWna10RtBdPZY41Jf4xSezX2q7KZBXXRgyVNYu3dDuNzhJAJ6jy7eMcb6urK6
|
||||
n73cz5uZPmWIbp4cAecZB0BfMj/PW37dK0oYdWKLxaDwpxvIV7T45Y64Md2FCC+d
|
||||
nC2Xh7c=
|
||||
=kzY9
|
||||
CBtDa5xPE6GU6ZUEFUZ7qbk7iV5p8uTchKVbABEBAAG5AQ0EVOQoaAEIAMQuOKxG
|
||||
Y4JyXr7683S+bwlagtViPXGey/A8Bf6b5uzW0SguRoF4oLpdfFBE/NKuBN1iItLU
|
||||
zBvqVVjvtb9HRLv0Xgf5foXO+osCYzpcEokNY76uv6tDYZ3tP9JIUmDVsndAMCdl
|
||||
WZLXA/d3SVeBKk5tTgpNYIoAHfxjecLJUJDEk/51GFBpuHAP0WVUgPD0hWQ2dgsR
|
||||
8kch4GjkDQVJlhtoHxMVK6yQNuoiqMJDamV1noJ82MJX/GUROjGTNCTyzlMP/q+M
|
||||
myPJ8vv1OebNrJtF2QnCbzXWuTd0qGgvzoBlmRcdbPVJLDezJr4c52klDHmnlRWx
|
||||
gt57vXbEIVfUcTMAEQEAAYkBHwQYAQIACQUCVOQoaAIbDAAKCRDCHOZTtjnkGnUs
|
||||
B/9O8dX6GSpBURjJY8ApqHyhkqmfX7urnjiFen8B464ZX5EsijfvesW44cCL1oSn
|
||||
Uplj/wLFKkQw/5kx8GTHZYJnV5BhL7wriQy+RZUM5fTlnnqZX1YS8rMenc4/xvAF
|
||||
F5XxCBgb2/EOeneXSjKSHeB+L7fmCM0vMf68vkE0wyQDrtXFSX8KF9+MjHGfiB08
|
||||
5ctlyouM0ONQ8n64GJQqHVp2tdEbQXT2WONSX+MUns19quymQV10YMlTWLt3Q7jc
|
||||
4SQCeo8u3jHG+rqyup+93M+bmT5liG6eHAHnGQdAXzI/z1t+3StKGHVii8Wg8Kcb
|
||||
yFe0+OWOuDHdhQgvnZwtl4e3
|
||||
=DwNF
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
pub C488A74FCAE540C6
|
||||
|
@ -1674,43 +1671,6 @@ fW1AkBVEk6siyL8PXfxmj9ev3H9xiQVLyJ6HpdHTLVjHjFkgNOLd
|
|||
=R7zg
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
pub D041CAD2E452550F
|
||||
uid Deanna <deannagarcia@google.com>
|
||||
|
||||
sub 5199F3DAE89C332D
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: BCPG v1.68
|
||||
|
||||
mQGNBGCtdhoBDADdopjDt4eUNEqLJSw1ZICSR0oq09SOVtJSaSYdF8UiXjBfL1Ds
|
||||
fhTDqSv5pT2a2gLj0OU3tFhWHvINLaKKCjQnHVcFXi2LTxt+XBOjRYkFjHVisbaZ
|
||||
PZ6HnTMStPrvs+hQ168vU3VfYOsOLN22j53I/Ba+FA7E0G0bqkratuT5L7BTR1mC
|
||||
fqDaeisWSCllfe6EEysaFF+/1RcRy+Yt+8ZWV0FZEF7UwQvqKHcYmlkqPIn3v/8y
|
||||
J/yvmzIEtCQ1F+bvJbzaROmeJf254G2Uh7IfMYEm9WlqnGwNdbIhil7bdxq8Y/0H
|
||||
XbQPaESxkki7yL5JTfH/+UzdklMe+Dga273L/cgzfjV3zJJ9vR94W5ABAbGYh4ZW
|
||||
aKvNnT1m4vTbEMfo4r3NF2zc+K9Ly/JNaHqkR5M4SVElvN2lsC5KNUiRvExhg+h0
|
||||
mKyx61mu3gUIrC1UOmqhtx7RzQQf7ESMdzmNHY0P93lR0Ic10fyli0wfl7A6q7+q
|
||||
zV2a1V2k9Yg6B9sAEQEAAbQgRGVhbm5hIDxkZWFubmFnYXJjaWFAZ29vZ2xlLmNv
|
||||
bT65AY0EYK12GgEMAMgP3//QeBsTS3IrfSp3m44el96X6BWona2yo4DvVyuwqfUL
|
||||
ZE+Nhj7I+kEZLrA29AOySOD/6quJ4MIJZfq/Do920Di8/10WQ00OdCM1wH7bMz2U
|
||||
vcSqsr0iOgQtycuUf7JOHSTME9vqk+C3Lhn0r59AVaRdXEe6zBgNZyzZJeCr5F8w
|
||||
RhglPlwvhOGs2aLEqlCxFnY4pLayQFoQyw1lDjHIXHg5JtfOHvqiNXVDcGpyKLG8
|
||||
SzImp62iL4sfuA0weVIQeS9kZiQabSYKvSf3TvNXYTgmFz/vjPbYhv9LTkBroTlV
|
||||
g3l+UmAxLrHVuXMx0zX3jfNNHAqUjVhPYZhnifMkmGJgLeMIVqr5Q/tx8pzyYiiO
|
||||
cqQ1zDg8ubJDGRue1JjlUGdw19OvhFDs+lydukt8Mmhb0gPkBLi2syZHgYHtEooX
|
||||
PLwEsJ+SynZCFhZiWj8BsWNFJpaDd8ynNeWhMAcwi3B5ZeQiZaAlV0sItxsrzvbu
|
||||
4ZYZtkjAkQdsaaTWSwARAQABiQG8BBgBCgAmFiEEaWthmaKp2MKc54zA0EHK0uRS
|
||||
VQ8FAmCtdhoCGwwFCQPCZwAACgkQ0EHK0uRSVQ+G7wwAvaVPDgnM+i2pGQPwq6Mk
|
||||
SzhKEG4H1pvBWyYR8H9D3p/dE33IjVu3EEy1h37Nzdyp46KtASGNe3KBodSsh6gv
|
||||
PlV5pNGxMNbX6fo8ZGtS83C+6uTF1cYmuO1nmi8P4+7qtcNZg4xv/ujAZIC20kem
|
||||
YKDth3FvPxEXsoxY+Ns7sxgd3SqoyLhjcyoczI8uyhim5nfvvbnEd6WrdiBPBtb/
|
||||
F1h/nfqdFj2TcZkAlnzGnlVlgU8J60u6zE+9VvBm0lJR73Ar55mQEwarGFPL1a3/
|
||||
A7ZEeNa0Dc3Oa5sKMYtxMlGKZ0WGUoGcDWiaDEsv5YyRnaSOaXKM1NkJCR013QAr
|
||||
RcHrRBPo+0/RIZVE+b8oEcmGzdL8HNwnm7e06ruZryF9LQA5YBmCKE0urigmgEvC
|
||||
zZsj/fMJ+OIZcAhE7UVae48GpW2kLATxmK01oSzvizIlmN3rVz2EnjOun2iuuEpF
|
||||
/lmDbjK5n1r3f8npB1l1fT5cozzQJkPVYzhBWH1KXP5X
|
||||
=nh9O
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
pub D364ABAA39A47320
|
||||
sub 3F606403DCA455C8
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue