mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 03:29:28 +01:00
Merge pull request #3663 from nextcloud/feature/noid/handleFederationRoomCapabilities
Feature/noid/handle federation room capabilities
This commit is contained in:
commit
f11b426421
@ -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 New Issue
Block a user