mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-27 17:08:34 +03:00
Merge pull request #2326 from nextcloud/feature/2134/allow-guests
Move allow guests preferences to conversation info
This commit is contained in:
commit
cd25a7e14d
22 changed files with 768 additions and 437 deletions
|
@ -1707,8 +1707,8 @@ public class CallActivity extends CallBaseActivity {
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < peerConnectionWrapperList.size(); i++) {
|
||||
endPeerConnection(peerConnectionWrapperList.get(i).getSessionId(), false);
|
||||
for (PeerConnectionWrapper wrapper : peerConnectionWrapperList) {
|
||||
endPeerConnection(wrapper.getSessionId(), false);
|
||||
}
|
||||
|
||||
if (localStream != null) {
|
||||
|
@ -1887,10 +1887,10 @@ public class CallActivity extends CallBaseActivity {
|
|||
}
|
||||
|
||||
private PeerConnectionWrapper getPeerConnectionWrapperForSessionIdAndType(String sessionId, String type) {
|
||||
for (int i = 0; i < peerConnectionWrapperList.size(); i++) {
|
||||
if (peerConnectionWrapperList.get(i).getSessionId().equals(sessionId)
|
||||
&& peerConnectionWrapperList.get(i).getVideoStreamType().equals(type)) {
|
||||
return peerConnectionWrapperList.get(i);
|
||||
for (PeerConnectionWrapper wrapper : peerConnectionWrapperList) {
|
||||
if (wrapper.getSessionId().equals(sessionId)
|
||||
&& wrapper.getVideoStreamType().equals(type)) {
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1980,10 +1980,8 @@ public class CallActivity extends CallBaseActivity {
|
|||
|
||||
private void endPeerConnection(String sessionId, boolean justScreen) {
|
||||
List<PeerConnectionWrapper> peerConnectionWrappers;
|
||||
PeerConnectionWrapper peerConnectionWrapper;
|
||||
if (!(peerConnectionWrappers = getPeerConnectionWrapperListForSessionId(sessionId)).isEmpty()) {
|
||||
for (int i = 0; i < peerConnectionWrappers.size(); i++) {
|
||||
peerConnectionWrapper = peerConnectionWrappers.get(i);
|
||||
for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrappers) {
|
||||
if (peerConnectionWrapper.getSessionId().equals(sessionId)) {
|
||||
if (VIDEO_STREAM_TYPE_SCREEN.equals(peerConnectionWrapper.getVideoStreamType()) || !justScreen) {
|
||||
runOnUiThread(() -> removeMediaStream(sessionId));
|
||||
|
@ -2104,10 +2102,8 @@ public class CallActivity extends CallBaseActivity {
|
|||
nickChangedPayload.put("userid", conversationUser.getUserId());
|
||||
nickChangedPayload.put("name", conversationUser.getDisplayName());
|
||||
dataChannelMessage.setPayload(nickChangedPayload);
|
||||
final PeerConnectionWrapper peerConnectionWrapper;
|
||||
for (int i = 0; i < peerConnectionWrapperList.size(); i++) {
|
||||
if (peerConnectionWrapperList.get(i).isMCUPublisher()) {
|
||||
peerConnectionWrapper = peerConnectionWrapperList.get(i);
|
||||
for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) {
|
||||
if (peerConnectionWrapper.isMCUPublisher()) {
|
||||
Observable
|
||||
.interval(1, TimeUnit.SECONDS)
|
||||
.repeatUntil(() -> (!isConnectionEstablished() || isDestroyed()))
|
||||
|
|
|
@ -142,6 +142,9 @@ public interface NcApi {
|
|||
Observable<AddParticipantOverall> addParticipant(@Header("Authorization") String authorization, @Url String url,
|
||||
@QueryMap Map<String, String> options);
|
||||
|
||||
@POST
|
||||
Observable<GenericOverall> resendParticipantInvitations(@Header("Authorization") String authorization,
|
||||
@Url String url);
|
||||
|
||||
// also used for removing a guest from a conversation
|
||||
@Deprecated
|
||||
|
@ -313,6 +316,12 @@ public interface NcApi {
|
|||
Observable<GenericOverall> setPassword(@Header("Authorization") String authorization, @Url String url,
|
||||
@Field("password") String password);
|
||||
|
||||
@FormUrlEncoded
|
||||
@PUT
|
||||
Observable<Response<GenericOverall>> setPassword2(@Header("Authorization") String authorization,
|
||||
@Url String url,
|
||||
@Field("password") String password);
|
||||
|
||||
@GET
|
||||
Observable<CapabilitiesOverall> getCapabilities(@Header("Authorization") String authorization, @Url String url);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @author Tim Krüger
|
||||
* @author Marcel Hibbe
|
||||
* Copyright (C) 2022 Marcel Hibbe (dev@mhibbe.de)
|
||||
* Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
|
||||
* Copyright (C) 2021-2022 Tim Krüger <t@timkrueger.me>
|
||||
* Copyright (C) 2021 Andy Scherzinger (info@andy-scherzinger.de)
|
||||
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
|
||||
*
|
||||
|
@ -37,6 +37,8 @@ import android.text.TextUtils
|
|||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
|
@ -61,6 +63,7 @@ import com.nextcloud.talk.controllers.base.BaseController
|
|||
import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage
|
||||
import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage
|
||||
import com.nextcloud.talk.controllers.util.viewBinding
|
||||
import com.nextcloud.talk.conversation.info.GuestAccessHelper
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.ControllerConversationInfoBinding
|
||||
import com.nextcloud.talk.events.EventStatus
|
||||
|
@ -75,6 +78,7 @@ import com.nextcloud.talk.models.json.participants.Participant.ActorType.CIRCLES
|
|||
import com.nextcloud.talk.models.json.participants.Participant.ActorType.GROUPS
|
||||
import com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS
|
||||
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.DateConstants
|
||||
|
@ -110,6 +114,9 @@ class ConversationInfoController(args: Bundle) :
|
|||
@Inject
|
||||
lateinit var ncApi: NcApi
|
||||
|
||||
@Inject
|
||||
lateinit var conversationsRepository: ConversationsRepository
|
||||
|
||||
@Inject
|
||||
lateinit var eventBus: EventBus
|
||||
|
||||
|
@ -167,6 +174,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
binding.notificationSettingsView.notificationSettings.setStorageModule(databaseStorageModule)
|
||||
binding.webinarInfoView.webinarSettings.setStorageModule(databaseStorageModule)
|
||||
binding.guestAccessView.guestAccessSettings.setStorageModule(databaseStorageModule)
|
||||
|
||||
binding.deleteConversationAction.setOnClickListener { showDeleteConversationDialog() }
|
||||
binding.leaveConversationAction.setOnClickListener { leaveConversation() }
|
||||
|
@ -176,7 +184,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
|
||||
binding.showSharedItemsAction.setOnClickListener { showSharedItems() }
|
||||
} else {
|
||||
binding.categorySharedItems.visibility = View.GONE
|
||||
binding.categorySharedItems.visibility = GONE
|
||||
}
|
||||
|
||||
fetchRoomInfo()
|
||||
|
@ -190,7 +198,9 @@ class ConversationInfoController(args: Bundle) :
|
|||
listOf(
|
||||
binding.webinarInfoView.conversationInfoLobby,
|
||||
binding.notificationSettingsView.callNotifications,
|
||||
binding.notificationSettingsView.conversationInfoPriorityConversation
|
||||
binding.notificationSettingsView.conversationInfoPriorityConversation,
|
||||
binding.guestAccessView.guestAccessAllowSwitch,
|
||||
binding.guestAccessView.guestAccessPasswordSwitch
|
||||
).forEach(viewThemeUtils::colorSwitchPreference)
|
||||
}
|
||||
}
|
||||
|
@ -205,6 +215,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
ownOptions,
|
||||
categorySharedItems,
|
||||
categoryConversationSettings,
|
||||
binding.guestAccessView.guestAccessCategory,
|
||||
binding.webinarInfoView.conversationInfoWebinar,
|
||||
binding.notificationSettingsView.notificationSettingsCategory
|
||||
).forEach(viewThemeUtils::colorPreferenceCategory)
|
||||
|
@ -225,7 +236,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
override fun onViewBound(view: View) {
|
||||
super.onViewBound(view)
|
||||
|
||||
binding.addParticipantsAction.visibility = View.GONE
|
||||
binding.addParticipantsAction.visibility = GONE
|
||||
|
||||
viewThemeUtils.colorCircularProgressBar(binding.progressBar)
|
||||
}
|
||||
|
@ -235,7 +246,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
webinaryRoomType(conversation!!) &&
|
||||
conversation!!.canModerate(conversationUser!!)
|
||||
) {
|
||||
binding.webinarInfoView.webinarSettings.visibility = View.VISIBLE
|
||||
binding.webinarInfoView.webinarSettings.visibility = VISIBLE
|
||||
|
||||
val isLobbyOpenToModeratorsOnly =
|
||||
conversation!!.lobbyState == Conversation.LobbyState.LOBBY_STATE_MODERATORS_ONLY
|
||||
|
@ -271,7 +282,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
submitLobbyChanges()
|
||||
}
|
||||
} else {
|
||||
binding.webinarInfoView.webinarSettings.visibility = View.GONE
|
||||
binding.webinarInfoView.webinarSettings.visibility = GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,9 +322,9 @@ class ConversationInfoController(args: Bundle) :
|
|||
}
|
||||
|
||||
if (isChecked) {
|
||||
binding.webinarInfoView.startTimePreferences.visibility = View.VISIBLE
|
||||
binding.webinarInfoView.startTimePreferences.visibility = VISIBLE
|
||||
} else {
|
||||
binding.webinarInfoView.startTimePreferences.visibility = View.GONE
|
||||
binding.webinarInfoView.startTimePreferences.visibility = GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,7 +444,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
setupAdapter()
|
||||
|
||||
binding.participantsListCategory.visibility = View.VISIBLE
|
||||
binding.participantsListCategory.visibility = VISIBLE
|
||||
adapter!!.updateDataSet(userItems)
|
||||
}
|
||||
|
||||
|
@ -523,7 +534,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
private fun leaveConversation() {
|
||||
workerData?.let {
|
||||
WorkManager.getInstance().enqueue(
|
||||
WorkManager.getInstance(context).enqueue(
|
||||
OneTimeWorkRequest.Builder(
|
||||
LeaveConversationWorker::class
|
||||
.java
|
||||
|
@ -586,7 +597,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
private fun deleteConversation() {
|
||||
workerData?.let {
|
||||
WorkManager.getInstance().enqueue(
|
||||
WorkManager.getInstance(context).enqueue(
|
||||
OneTimeWorkRequest.Builder(
|
||||
DeleteConversationWorker::class.java
|
||||
).setInputData(it).build()
|
||||
|
@ -624,40 +635,40 @@ class ConversationInfoController(args: Bundle) :
|
|||
val conversationCopy = conversation
|
||||
|
||||
if (conversationCopy!!.canModerate(conversationUser)) {
|
||||
binding.addParticipantsAction.visibility = View.VISIBLE
|
||||
binding.addParticipantsAction.visibility = VISIBLE
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "clear-history")) {
|
||||
binding.clearConversationHistory.visibility = View.VISIBLE
|
||||
binding.clearConversationHistory.visibility = VISIBLE
|
||||
} else {
|
||||
binding.clearConversationHistory.visibility = View.GONE
|
||||
binding.clearConversationHistory.visibility = GONE
|
||||
}
|
||||
} else {
|
||||
binding.addParticipantsAction.visibility = View.GONE
|
||||
binding.clearConversationHistory.visibility = View.GONE
|
||||
binding.addParticipantsAction.visibility = GONE
|
||||
binding.clearConversationHistory.visibility = GONE
|
||||
}
|
||||
|
||||
if (isAttached && (!isBeingDestroyed || !isDestroyed)) {
|
||||
binding.ownOptions.visibility = View.VISIBLE
|
||||
binding.ownOptions.visibility = VISIBLE
|
||||
|
||||
setupWebinaryView()
|
||||
|
||||
if (!conversation!!.canLeave()) {
|
||||
binding.leaveConversationAction.visibility = View.GONE
|
||||
binding.leaveConversationAction.visibility = GONE
|
||||
} else {
|
||||
binding.leaveConversationAction.visibility = View.VISIBLE
|
||||
binding.leaveConversationAction.visibility = VISIBLE
|
||||
}
|
||||
|
||||
if (!conversation!!.canDelete(conversationUser)) {
|
||||
binding.deleteConversationAction.visibility = View.GONE
|
||||
binding.deleteConversationAction.visibility = GONE
|
||||
} else {
|
||||
binding.deleteConversationAction.visibility = View.VISIBLE
|
||||
binding.deleteConversationAction.visibility = VISIBLE
|
||||
}
|
||||
|
||||
if (Conversation.ConversationType.ROOM_SYSTEM == conversation!!.type) {
|
||||
binding.notificationSettingsView.callNotifications.visibility = View.GONE
|
||||
binding.notificationSettingsView.callNotifications.visibility = GONE
|
||||
}
|
||||
|
||||
if (conversation!!.notificationCalls === null) {
|
||||
binding.notificationSettingsView.callNotifications.visibility = View.GONE
|
||||
binding.notificationSettingsView.callNotifications.visibility = GONE
|
||||
} else {
|
||||
binding.notificationSettingsView.callNotifications.value =
|
||||
conversationCopy.notificationCalls == 1
|
||||
|
@ -665,22 +676,29 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
getListOfParticipants()
|
||||
|
||||
binding.progressBar.visibility = View.GONE
|
||||
binding.progressBar.visibility = GONE
|
||||
|
||||
binding.conversationInfoName.visibility = View.VISIBLE
|
||||
binding.conversationInfoName.visibility = VISIBLE
|
||||
|
||||
binding.displayNameText.text = conversation!!.displayName
|
||||
|
||||
if (conversation!!.description != null && !conversation!!.description!!.isEmpty()) {
|
||||
binding.descriptionText.text = conversation!!.description
|
||||
binding.conversationDescription.visibility = View.VISIBLE
|
||||
binding.conversationDescription.visibility = VISIBLE
|
||||
}
|
||||
|
||||
loadConversationAvatar()
|
||||
adjustNotificationLevelUI()
|
||||
initExpiringMessageOption()
|
||||
|
||||
binding.notificationSettingsView.notificationSettings.visibility = View.VISIBLE
|
||||
GuestAccessHelper(
|
||||
this@ConversationInfoController,
|
||||
binding,
|
||||
conversation!!,
|
||||
conversationUser
|
||||
).setupGuestAccess()
|
||||
|
||||
binding.notificationSettingsView.notificationSettings.visibility = VISIBLE
|
||||
}
|
||||
} catch (npe: NullPointerException) {
|
||||
// view binding can be null
|
||||
|
@ -1035,7 +1053,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
cornerRadius(res = R.dimen.corner_radius)
|
||||
|
||||
title(text = participant.displayName)
|
||||
listItemsWithImage(items = items) { dialog, index, _ ->
|
||||
listItemsWithImage(items = items) { _, index, _ ->
|
||||
if (index == 0) {
|
||||
removeAttendeeFromConversation(apiVersion, participant)
|
||||
}
|
||||
|
@ -1061,7 +1079,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
cornerRadius(res = R.dimen.corner_radius)
|
||||
|
||||
title(text = participant.displayName)
|
||||
listItemsWithImage(items = items) { dialog, index, _ ->
|
||||
listItemsWithImage(items = items) { _, index, _ ->
|
||||
if (index == 0) {
|
||||
removeAttendeeFromConversation(apiVersion, participant)
|
||||
}
|
||||
|
@ -1081,7 +1099,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
cornerRadius(res = R.dimen.corner_radius)
|
||||
|
||||
title(text = participant.displayName)
|
||||
listItemsWithImage(items = items) { dialog, index, _ ->
|
||||
listItemsWithImage(items = items) { _, index, _ ->
|
||||
if (index == 0) {
|
||||
removeAttendeeFromConversation(apiVersion, participant)
|
||||
}
|
||||
|
@ -1132,7 +1150,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
cornerRadius(res = R.dimen.corner_radius)
|
||||
|
||||
title(text = participant.displayName)
|
||||
listItemsWithImage(items = items) { dialog, index, _ ->
|
||||
listItemsWithImage(items = items) { _, index, _ ->
|
||||
var actionToTrigger = index
|
||||
if (participant.attendeePin == null || participant.attendeePin!!.isEmpty()) {
|
||||
actionToTrigger++
|
||||
|
|
|
@ -22,12 +22,6 @@ package com.nextcloud.talk.controllers.bottomsheet
|
|||
|
||||
enum class ConversationOperationEnum {
|
||||
OPS_CODE_RENAME_ROOM,
|
||||
OPS_CODE_MAKE_PUBLIC,
|
||||
OPS_CODE_CHANGE_PASSWORD,
|
||||
OPS_CODE_CLEAR_PASSWORD,
|
||||
OPS_CODE_SET_PASSWORD,
|
||||
OPS_CODE_SHARE_LINK,
|
||||
OPS_CODE_MAKE_PRIVATE,
|
||||
OPS_CODE_GET_AND_JOIN_ROOM,
|
||||
OPS_CODE_INVITE_USERS,
|
||||
OPS_CODE_MARK_AS_READ,
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package com.nextcloud.talk.controllers.bottomsheet
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
|
@ -47,7 +46,6 @@ import com.nextcloud.talk.controllers.util.viewBinding
|
|||
import com.nextcloud.talk.databinding.ControllerEntryMenuBinding
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ShareUtils
|
||||
import com.nextcloud.talk.utils.UriUtils
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
|
||||
|
@ -139,13 +137,6 @@ class EntryMenuController(args: Bundle) :
|
|||
)
|
||||
}
|
||||
|
||||
ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD -> {
|
||||
labelText = resources!!.getString(R.string.nc_new_password)
|
||||
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||
}
|
||||
|
||||
ConversationOperationEnum.OPS_CODE_SET_PASSWORD,
|
||||
ConversationOperationEnum.OPS_CODE_SHARE_LINK,
|
||||
ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> {
|
||||
// 99 is joining a conversation via password
|
||||
labelText = resources!!.getString(R.string.nc_password)
|
||||
|
@ -242,18 +233,12 @@ class EntryMenuController(args: Bundle) :
|
|||
private fun onOkButtonClick() {
|
||||
if (operation === ConversationOperationEnum.OPS_CODE_JOIN_ROOM) {
|
||||
joinRoom()
|
||||
} else if (operation !== ConversationOperationEnum.OPS_CODE_SHARE_LINK &&
|
||||
} else if (
|
||||
operation !== ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM &&
|
||||
operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
if (operation === ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD ||
|
||||
operation === ConversationOperationEnum.OPS_CODE_SET_PASSWORD
|
||||
) {
|
||||
conversation!!.password = binding.textEdit.text.toString()
|
||||
} else {
|
||||
conversation!!.name = binding.textEdit.text.toString()
|
||||
}
|
||||
bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation))
|
||||
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
|
||||
router.pushController(
|
||||
|
@ -261,20 +246,6 @@ class EntryMenuController(args: Bundle) :
|
|||
.pushChangeHandler(HorizontalChangeHandler())
|
||||
.popChangeHandler(HorizontalChangeHandler())
|
||||
)
|
||||
} else if (operation === ConversationOperationEnum.OPS_CODE_SHARE_LINK && activity != null) {
|
||||
shareIntent?.putExtra(
|
||||
Intent.EXTRA_TEXT,
|
||||
ShareUtils.getStringForIntent(
|
||||
activity,
|
||||
binding.textEdit.text.toString(),
|
||||
userManager,
|
||||
conversation
|
||||
)
|
||||
)
|
||||
val intent = Intent(shareIntent)
|
||||
intent.component = ComponentName(packageName, name)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
activity?.startActivity(intent)
|
||||
} else if (operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS) {
|
||||
val bundle = Bundle()
|
||||
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
|
||||
|
@ -336,10 +307,7 @@ class EntryMenuController(args: Bundle) :
|
|||
companion object {
|
||||
private val PASSWORD_ENTRY_OPERATIONS: List<ConversationOperationEnum> =
|
||||
immutableListOf(
|
||||
ConversationOperationEnum.OPS_CODE_JOIN_ROOM,
|
||||
ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD,
|
||||
ConversationOperationEnum.OPS_CODE_SET_PASSWORD,
|
||||
ConversationOperationEnum.OPS_CODE_SHARE_LINK
|
||||
ConversationOperationEnum.OPS_CODE_JOIN_ROOM
|
||||
)
|
||||
const val OPACITY_DISABLED = 0.38f
|
||||
const val OPACITY_BUTTON_DISABLED = 0.7f
|
||||
|
|
|
@ -211,11 +211,6 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||
credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
|
||||
when (operation) {
|
||||
ConversationOperationEnum.OPS_CODE_RENAME_ROOM -> operationRenameRoom()
|
||||
ConversationOperationEnum.OPS_CODE_MAKE_PUBLIC -> operationMakePublic()
|
||||
ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD,
|
||||
ConversationOperationEnum.OPS_CODE_CLEAR_PASSWORD,
|
||||
ConversationOperationEnum.OPS_CODE_SET_PASSWORD -> operationChangePassword()
|
||||
ConversationOperationEnum.OPS_CODE_MAKE_PRIVATE -> operationMakePrivate()
|
||||
ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM -> operationGetAndJoinRoom()
|
||||
ConversationOperationEnum.OPS_CODE_INVITE_USERS -> operationInviteUsers()
|
||||
ConversationOperationEnum.OPS_CODE_MARK_AS_READ -> operationMarkAsRead()
|
||||
|
@ -267,56 +262,6 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||
.subscribe(GenericOperationsObserver())
|
||||
}
|
||||
|
||||
private fun operationMakePrivate() {
|
||||
ncApi.makeRoomPrivate(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomPublic(
|
||||
apiVersion(),
|
||||
currentUser!!.baseUrl,
|
||||
conversation!!.token
|
||||
)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.retry(1)
|
||||
.subscribe(GenericOperationsObserver())
|
||||
}
|
||||
|
||||
private fun operationChangePassword() {
|
||||
var pass: String? = ""
|
||||
if (conversation!!.password != null) {
|
||||
pass = conversation!!.password
|
||||
}
|
||||
ncApi.setPassword(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomPassword(
|
||||
apiVersion(),
|
||||
currentUser!!.baseUrl,
|
||||
conversation!!.token
|
||||
),
|
||||
pass
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.retry(1)
|
||||
.subscribe(GenericOperationsObserver())
|
||||
}
|
||||
|
||||
private fun operationMakePublic() {
|
||||
ncApi.makeRoomPublic(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomPublic(
|
||||
apiVersion(),
|
||||
currentUser!!.baseUrl,
|
||||
conversation!!.token
|
||||
)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.retry(1)
|
||||
.subscribe(GenericOperationsObserver())
|
||||
}
|
||||
|
||||
private fun operationRenameRoom() {
|
||||
ncApi.renameRoom(
|
||||
credentials,
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
package com.nextcloud.talk.conversation.info
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.controllers.ConversationInfoController
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.ControllerConversationInfoBinding
|
||||
import com.nextcloud.talk.databinding.DialogPasswordBinding
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepository
|
||||
import com.nextcloud.talk.utils.Mimetype
|
||||
import com.nextcloud.talk.utils.ShareUtils
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
class GuestAccessHelper(
|
||||
controller: ConversationInfoController,
|
||||
private val binding: ControllerConversationInfoBinding,
|
||||
private val conversation: Conversation,
|
||||
private val conversationUser: User
|
||||
) {
|
||||
|
||||
private val activity = controller.activity!!
|
||||
private val conversationsRepository = controller.conversationsRepository
|
||||
private val viewThemeUtils = controller.viewThemeUtils
|
||||
private val context = controller.context
|
||||
|
||||
fun setupGuestAccess() {
|
||||
|
||||
val guestAccessAllowSwitch = (
|
||||
binding.guestAccessView.guestAccessAllowSwitch.findViewById<View>(R.id.mp_checkable)
|
||||
as SwitchCompat
|
||||
)
|
||||
val guestAccessPasswordSwitch = (
|
||||
binding.guestAccessView.guestAccessPasswordSwitch.findViewById<View>(R.id.mp_checkable)
|
||||
as SwitchCompat
|
||||
)
|
||||
|
||||
if (conversation.canModerate(conversationUser)) {
|
||||
binding.guestAccessView.guestAccessSettings.visibility = View.VISIBLE
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
if (conversation.type == Conversation.ConversationType.ROOM_PUBLIC_CALL) {
|
||||
guestAccessAllowSwitch.isChecked = true
|
||||
showAllOptions()
|
||||
if (conversation.hasPassword) {
|
||||
guestAccessPasswordSwitch.isChecked = true
|
||||
}
|
||||
}
|
||||
|
||||
binding.guestAccessView.guestAccessAllowSwitch.setOnClickListener {
|
||||
conversationsRepository.allowGuests(
|
||||
conversation.token!!,
|
||||
!guestAccessAllowSwitch.isChecked
|
||||
).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread()).subscribe(AllowGuestsResultObserver())
|
||||
}
|
||||
|
||||
binding.guestAccessView.guestAccessPasswordSwitch.setOnClickListener {
|
||||
|
||||
if (guestAccessPasswordSwitch.isChecked) {
|
||||
conversationsRepository.password("", conversation.token!!).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread()).subscribe(PasswordResultObserver(false))
|
||||
} else {
|
||||
showPasswordDialog(guestAccessPasswordSwitch)
|
||||
}
|
||||
}
|
||||
|
||||
binding.guestAccessView.guestAccessCopyUrl.setOnClickListener {
|
||||
shareUrl()
|
||||
}
|
||||
|
||||
binding.guestAccessView.guestAccessResendInvitations.setOnClickListener {
|
||||
conversationsRepository.resendInvitations(conversation.token!!).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread()).subscribe(ResendInvitationsObserver())
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
private fun showPasswordDialog(guestAccessPasswordSwitch: SwitchCompat) {
|
||||
val builder = MaterialAlertDialogBuilder(activity)
|
||||
builder.apply {
|
||||
val dialogPassword = DialogPasswordBinding.inflate(LayoutInflater.from(context))
|
||||
viewThemeUtils.colorEditText(dialogPassword.password)
|
||||
setView(dialogPassword.root)
|
||||
setTitle(R.string.nc_guest_access_password_dialog_title)
|
||||
setPositiveButton(R.string.nc_ok) { _, _ ->
|
||||
val password = dialogPassword.password.text.toString()
|
||||
conversationsRepository.password(password, conversation.token!!)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(PasswordResultObserver(true))
|
||||
}
|
||||
setNegativeButton(R.string.nc_cancel) { _, _ ->
|
||||
guestAccessPasswordSwitch.isChecked = false
|
||||
}
|
||||
}
|
||||
createDialog(builder)
|
||||
}
|
||||
|
||||
private fun createDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder.create()
|
||||
viewThemeUtils.colorMaterialAlertDialogBackground(binding.conversationInfoName.context, builder)
|
||||
val dialog = builder.show()
|
||||
viewThemeUtils.colorTextButtons(
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
|
||||
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
|
||||
)
|
||||
}
|
||||
|
||||
private fun shareUrl() {
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
type = Mimetype.TEXT_PLAIN
|
||||
putExtra(
|
||||
Intent.EXTRA_SUBJECT,
|
||||
String.format(
|
||||
activity.resources.getString(R.string.nc_share_subject),
|
||||
activity.resources.getString(R.string.nc_app_product_name)
|
||||
)
|
||||
)
|
||||
|
||||
putExtra(
|
||||
Intent.EXTRA_TEXT,
|
||||
ShareUtils.getStringForIntent(activity, conversationUser, conversation)
|
||||
)
|
||||
}
|
||||
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
activity.startActivity(shareIntent)
|
||||
}
|
||||
|
||||
inner class ResendInvitationsObserver : Observer<ConversationsRepository.ResendInvitationsResult> {
|
||||
|
||||
private lateinit var resendInvitationsResult: ConversationsRepository.ResendInvitationsResult
|
||||
|
||||
override fun onSubscribe(d: Disposable) = Unit
|
||||
|
||||
override fun onNext(t: ConversationsRepository.ResendInvitationsResult) {
|
||||
resendInvitationsResult = t
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
val message = context.getString(R.string.nc_guest_access_resend_invitations_failed)
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||
Log.e(TAG, message, e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
if (resendInvitationsResult.successful) {
|
||||
Toast.makeText(context, R.string.nc_guest_access_resend_invitations_successful, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class AllowGuestsResultObserver : Observer<ConversationsRepository.AllowGuestsResult> {
|
||||
|
||||
private lateinit var allowGuestsResult: ConversationsRepository.AllowGuestsResult
|
||||
|
||||
override fun onNext(t: ConversationsRepository.AllowGuestsResult) {
|
||||
allowGuestsResult = t
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
val message = context.getString(R.string.nc_guest_access_allow_failed)
|
||||
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
|
||||
Log.e(TAG, message, e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
(
|
||||
binding.guestAccessView.guestAccessAllowSwitch.findViewById<View>(R.id.mp_checkable)
|
||||
as SwitchCompat
|
||||
).isChecked = allowGuestsResult.allow
|
||||
if (allowGuestsResult.allow) {
|
||||
showAllOptions()
|
||||
} else {
|
||||
hideAllOptions()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSubscribe(d: Disposable) = Unit
|
||||
}
|
||||
|
||||
private fun showAllOptions() {
|
||||
binding.guestAccessView.guestAccessPasswordSwitch.visibility = View.VISIBLE
|
||||
binding.guestAccessView.guestAccessCopyUrl.visibility = View.VISIBLE
|
||||
if (conversationUser.capabilities?.spreedCapability?.features?.contains("sip-support") == true) {
|
||||
binding.guestAccessView.guestAccessResendInvitations.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideAllOptions() {
|
||||
binding.guestAccessView.guestAccessPasswordSwitch.visibility = View.GONE
|
||||
binding.guestAccessView.guestAccessCopyUrl.visibility = View.GONE
|
||||
binding.guestAccessView.guestAccessResendInvitations.visibility = View.GONE
|
||||
}
|
||||
|
||||
inner class PasswordResultObserver(private val setPassword: Boolean) :
|
||||
Observer<ConversationsRepository.PasswordResult> {
|
||||
|
||||
private lateinit var passwordResult: ConversationsRepository.PasswordResult
|
||||
|
||||
override fun onSubscribe(d: Disposable) = Unit
|
||||
|
||||
override fun onNext(t: ConversationsRepository.PasswordResult) {
|
||||
passwordResult = t
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
val message = context.getString(R.string.nc_guest_access_password_failed)
|
||||
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
|
||||
Log.e(TAG, message, e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
val guestAccessPasswordSwitch = (
|
||||
binding.guestAccessView.guestAccessPasswordSwitch.findViewById<View>(R.id.mp_checkable)
|
||||
as SwitchCompat
|
||||
)
|
||||
guestAccessPasswordSwitch.isChecked = passwordResult.passwordSet && setPassword
|
||||
|
||||
if (passwordResult.passwordIsWeak) {
|
||||
val builder = MaterialAlertDialogBuilder(activity)
|
||||
builder.apply {
|
||||
setTitle(R.string.nc_guest_access_password_weak_alert_title)
|
||||
setMessage(passwordResult.message)
|
||||
setPositiveButton("OK") { _, _ -> }
|
||||
}
|
||||
createDialog(builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = GuestAccessHelper::class.simpleName
|
||||
}
|
||||
}
|
|
@ -33,6 +33,8 @@ import com.nextcloud.talk.polls.repositories.PollRepository
|
|||
import com.nextcloud.talk.polls.repositories.PollRepositoryImpl
|
||||
import com.nextcloud.talk.remotefilebrowser.repositories.RemoteFileBrowserItemsRepository
|
||||
import com.nextcloud.talk.remotefilebrowser.repositories.RemoteFileBrowserItemsRepositoryImpl
|
||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepository
|
||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepositoryImpl
|
||||
import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository
|
||||
import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepositoryImpl
|
||||
import com.nextcloud.talk.shareditems.repositories.SharedItemsRepository
|
||||
|
@ -44,6 +46,12 @@ import okhttp3.OkHttpClient
|
|||
|
||||
@Module
|
||||
class RepositoryModule {
|
||||
|
||||
@Provides
|
||||
fun provideConversationsRepository(ncApi: NcApi, userProvider: CurrentUserProviderNew): ConversationsRepository {
|
||||
return ConversationsRepositoryImpl(ncApi, userProvider)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideSharedItemsRepository(ncApi: NcApi): SharedItemsRepository {
|
||||
return SharedItemsRepositoryImpl(ncApi)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Tim Krüger
|
||||
* Copyright (C) 2022 Tim Krüger
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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.conversations.password
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@JsonObject
|
||||
@Parcelize
|
||||
data class PasswordData(
|
||||
@JsonField(name = ["message"])
|
||||
var message: String? = null
|
||||
) : Parcelable {
|
||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||
constructor() : this(null)
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Tim Krüger
|
||||
* Copyright (C) 2022 Tim Krüger
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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.conversations.password
|
||||
|
||||
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.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@JsonObject
|
||||
data class PasswordOCS(
|
||||
@JsonField(name = ["meta"])
|
||||
var meta: GenericMeta? = null,
|
||||
|
||||
@JsonField(name = ["data"])
|
||||
var data: PasswordData? = null
|
||||
) : Parcelable {
|
||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||
constructor() : this(null, null)
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Tim Krüger
|
||||
* Copyright (C) 2022 Tim Krüger
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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.conversations.password
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@JsonObject
|
||||
data class PasswordOverall(
|
||||
@JsonField(name = ["ocs"])
|
||||
var ocs: PasswordOCS? = null
|
||||
) : Parcelable {
|
||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||
constructor() : this(null)
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Tim Krüger
|
||||
* Copyright (C) 2022 Tim Krüger
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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.repositories.conversations
|
||||
|
||||
import io.reactivex.Observable
|
||||
|
||||
interface ConversationsRepository {
|
||||
|
||||
data class AllowGuestsResult(
|
||||
val allow: Boolean
|
||||
)
|
||||
|
||||
fun allowGuests(token: String, allow: Boolean): Observable<AllowGuestsResult>
|
||||
|
||||
data class PasswordResult(
|
||||
val passwordSet: Boolean,
|
||||
val passwordIsWeak: Boolean,
|
||||
val message: String
|
||||
)
|
||||
|
||||
fun password(password: String, token: String): Observable<PasswordResult>
|
||||
|
||||
data class ResendInvitationsResult(
|
||||
val successful: Boolean
|
||||
)
|
||||
fun resendInvitations(token: String): Observable<ResendInvitationsResult>
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Tim Krüger
|
||||
* Copyright (C) 2022 Tim Krüger
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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.repositories.conversations
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare
|
||||
import com.nextcloud.talk.api.NcApi
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.json.conversations.password.PasswordOverall
|
||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepository.AllowGuestsResult
|
||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepository.PasswordResult
|
||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepository.ResendInvitationsResult
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import io.reactivex.Observable
|
||||
|
||||
class ConversationsRepositoryImpl(private val api: NcApi, private val userProvider: CurrentUserProviderNew) :
|
||||
ConversationsRepository {
|
||||
|
||||
private val user: User
|
||||
get() = userProvider.currentUser.blockingGet()
|
||||
|
||||
private val credentials: String
|
||||
get() = ApiUtils.getCredentials(user.username, user.token)
|
||||
|
||||
override fun allowGuests(token: String, allow: Boolean): Observable<AllowGuestsResult> {
|
||||
|
||||
val url = ApiUtils.getUrlForRoomPublic(
|
||||
apiVersion(),
|
||||
user.baseUrl,
|
||||
token
|
||||
)
|
||||
|
||||
val apiObservable = if (allow) {
|
||||
api.makeRoomPublic(
|
||||
credentials,
|
||||
url
|
||||
)
|
||||
} else {
|
||||
api.makeRoomPrivate(
|
||||
credentials,
|
||||
url
|
||||
)
|
||||
}
|
||||
|
||||
return apiObservable.map { AllowGuestsResult(it.ocs!!.meta!!.statusCode == STATUS_CODE_OK && allow) }
|
||||
}
|
||||
|
||||
override fun password(password: String, token: String): Observable<PasswordResult> {
|
||||
val apiObservable = api.setPassword2(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomPassword(
|
||||
apiVersion(),
|
||||
user.baseUrl!!,
|
||||
token
|
||||
),
|
||||
password
|
||||
)
|
||||
return apiObservable.map {
|
||||
|
||||
val passwordPolicyMessage = if (it.code() == STATUS_CODE_BAD_REQUEST) {
|
||||
LoganSquare.parse(it.errorBody()!!.string(), PasswordOverall::class.java).ocs!!.data!!
|
||||
.message!!
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
PasswordResult(it.isSuccessful, passwordPolicyMessage.isNotEmpty(), passwordPolicyMessage)
|
||||
}
|
||||
}
|
||||
|
||||
override fun resendInvitations(token: String): Observable<ResendInvitationsResult> {
|
||||
|
||||
val apiObservable = api.resendParticipantInvitations(
|
||||
credentials,
|
||||
ApiUtils.getUrlForParticipantsResendInvitations(
|
||||
apiVersion(),
|
||||
user.baseUrl!!,
|
||||
token
|
||||
)
|
||||
)
|
||||
|
||||
return apiObservable.map {
|
||||
ResendInvitationsResult(true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun apiVersion(): Int {
|
||||
return ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.APIv4))
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val STATUS_CODE_OK = 200
|
||||
const val STATUS_CODE_BAD_REQUEST = 400
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@
|
|||
package com.nextcloud.talk.ui.dialog
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
|
@ -42,14 +41,9 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
|
|||
import com.nextcloud.talk.controllers.ConversationsListController
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_ADD_FAVORITE
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_CLEAR_PASSWORD
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_MAKE_PRIVATE
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_MAKE_PUBLIC
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_MARK_AS_READ
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_REMOVE_FAVORITE
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_RENAME_ROOM
|
||||
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_SET_PASSWORD
|
||||
import com.nextcloud.talk.controllers.bottomsheet.EntryMenuController
|
||||
import com.nextcloud.talk.controllers.bottomsheet.OperationsMenuController
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
|
@ -58,8 +52,6 @@ import com.nextcloud.talk.jobs.LeaveConversationWorker
|
|||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.Mimetype.TEXT_PLAIN
|
||||
import com.nextcloud.talk.utils.ShareUtils
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPERATION_CODE
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
|
||||
|
@ -130,34 +122,10 @@ class ConversationsListBottomDialog(
|
|||
conversation.isNameEditable(currentUser)
|
||||
)
|
||||
|
||||
binding.conversationOperationMakePublic.visibility = setVisibleIf(
|
||||
canModerate && !conversation.isPublic
|
||||
)
|
||||
|
||||
binding.conversationOperationChangePassword.visibility = setVisibleIf(
|
||||
canModerate && conversation.hasPassword && conversation.isPublic
|
||||
)
|
||||
|
||||
binding.conversationOperationClearPassword.visibility = setVisibleIf(
|
||||
canModerate && conversation.hasPassword && conversation.isPublic
|
||||
)
|
||||
|
||||
binding.conversationOperationSetPassword.visibility = setVisibleIf(
|
||||
canModerate && !conversation.hasPassword && conversation.isPublic
|
||||
)
|
||||
|
||||
binding.conversationOperationDelete.visibility = setVisibleIf(
|
||||
canModerate
|
||||
)
|
||||
|
||||
binding.conversationOperationShareLink.visibility = setVisibleIf(
|
||||
conversation.isPublic
|
||||
)
|
||||
|
||||
binding.conversationOperationMakePrivate.visibility = setVisibleIf(
|
||||
conversation.isPublic && canModerate
|
||||
)
|
||||
|
||||
binding.conversationOperationLeave.visibility = setVisibleIf(
|
||||
conversation.canLeave() &&
|
||||
// leaving is by api not possible for the last user with moderator permissions.
|
||||
|
@ -210,26 +178,6 @@ class ConversationsListBottomDialog(
|
|||
dismiss()
|
||||
}
|
||||
|
||||
binding.conversationOperationMakePublic.setOnClickListener {
|
||||
executeOperationsMenuController(OPS_CODE_MAKE_PUBLIC)
|
||||
}
|
||||
|
||||
binding.conversationOperationMakePrivate.setOnClickListener {
|
||||
executeOperationsMenuController(OPS_CODE_MAKE_PRIVATE)
|
||||
}
|
||||
|
||||
binding.conversationOperationChangePassword.setOnClickListener {
|
||||
executeEntryMenuController(OPS_CODE_CHANGE_PASSWORD)
|
||||
}
|
||||
|
||||
binding.conversationOperationClearPassword.setOnClickListener {
|
||||
executeOperationsMenuController(OPS_CODE_CLEAR_PASSWORD)
|
||||
}
|
||||
|
||||
binding.conversationOperationSetPassword.setOnClickListener {
|
||||
executeEntryMenuController(OPS_CODE_SET_PASSWORD)
|
||||
}
|
||||
|
||||
binding.conversationOperationRename.setOnClickListener {
|
||||
executeEntryMenuController(OPS_CODE_RENAME_ROOM)
|
||||
}
|
||||
|
@ -237,30 +185,6 @@ class ConversationsListBottomDialog(
|
|||
binding.conversationOperationMarkAsRead.setOnClickListener {
|
||||
executeOperationsMenuController(OPS_CODE_MARK_AS_READ)
|
||||
}
|
||||
|
||||
binding.conversationOperationShareLink.setOnClickListener {
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
type = TEXT_PLAIN
|
||||
putExtra(
|
||||
Intent.EXTRA_SUBJECT,
|
||||
String.format(
|
||||
activity.resources.getString(R.string.nc_share_subject),
|
||||
activity.resources.getString(R.string.nc_app_product_name)
|
||||
)
|
||||
)
|
||||
// password should not be shared!!
|
||||
putExtra(
|
||||
Intent.EXTRA_TEXT,
|
||||
ShareUtils.getStringForIntent(activity, null, userManager, conversation)
|
||||
)
|
||||
}
|
||||
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
activity.startActivity(shareIntent)
|
||||
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun executeOperationsMenuController(operation: ConversationOperationEnum) {
|
||||
|
|
|
@ -218,6 +218,10 @@ public class ApiUtils {
|
|||
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";
|
||||
}
|
||||
|
|
|
@ -21,28 +21,20 @@ 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.users.UserManager
|
||||
|
||||
object ShareUtils {
|
||||
fun getStringForIntent(
|
||||
context: Context?,
|
||||
password: String?,
|
||||
userManager: UserManager,
|
||||
context: Context,
|
||||
user: User,
|
||||
conversation: Conversation?
|
||||
): String {
|
||||
val userEntity = userManager.currentUser.blockingGet()
|
||||
var shareString = ""
|
||||
if (userEntity != null && context != null) {
|
||||
shareString = String.format(
|
||||
|
||||
return String.format(
|
||||
context.resources.getString(R.string.nc_share_text),
|
||||
userEntity.baseUrl,
|
||||
user.baseUrl,
|
||||
conversation?.token
|
||||
)
|
||||
if (!password.isNullOrEmpty()) {
|
||||
shareString += String.format(context.resources.getString(R.string.nc_share_text_pass), password)
|
||||
}
|
||||
}
|
||||
return shareString
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
~ @author Mario Danic
|
||||
~ @author Andy Scherzinger
|
||||
~ @author Marcel Hibbe
|
||||
~ @author Tim Krüger
|
||||
~ Copyright (C) 2022 Tim Krüger <t@timkrueger.me>
|
||||
~ Copyright (C) 2022 Marcel Hibbe <dev@mhibbe.de>
|
||||
~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
|
||||
|
@ -25,10 +27,10 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:apc="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:background="@color/white"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
tools:background="@color/white">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
|
@ -80,8 +82,8 @@
|
|||
android:layout_width="@dimen/avatar_size_big"
|
||||
android:layout_height="@dimen/avatar_size_big"
|
||||
android:layout_centerHorizontal="true"
|
||||
tools:background="@color/hwSecurityRed"
|
||||
apc:roundAsCircle="true" />
|
||||
apc:roundAsCircle="true"
|
||||
tools:background="@color/hwSecurityRed" />
|
||||
|
||||
</RelativeLayout>
|
||||
</com.yarolegovich.mp.MaterialPreferenceCategory>
|
||||
|
@ -150,6 +152,14 @@
|
|||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
android:id="@+id/guest_access_view"
|
||||
layout="@layout/guest_access_settings_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
|
|
|
@ -166,126 +166,6 @@
|
|||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/conversation_operation_make_public"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_item_height"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_padding"
|
||||
android:paddingEnd="@dimen/standard_padding"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_link_grey600_24px"
|
||||
app:tint="@color/high_emphasis_menu_icon" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingStart="40dp"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:text="@string/nc_make_call_public"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/high_emphasis_text"
|
||||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/conversation_operation_change_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_item_height"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_padding"
|
||||
android:paddingEnd="@dimen/standard_padding"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_lock_grey600_24px"
|
||||
app:tint="@color/high_emphasis_menu_icon" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingStart="40dp"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:text="@string/nc_change_password"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/high_emphasis_text"
|
||||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/conversation_operation_clear_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_item_height"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_padding"
|
||||
android:paddingEnd="@dimen/standard_padding"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_lock_open_grey600_24dp"
|
||||
app:tint="@color/high_emphasis_menu_icon" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingStart="40dp"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:text="@string/nc_clear_password"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/high_emphasis_text"
|
||||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/conversation_operation_set_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_item_height"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_padding"
|
||||
android:paddingEnd="@dimen/standard_padding"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_lock_plus_grey600_24dp"
|
||||
app:tint="@color/high_emphasis_menu_icon" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingStart="40dp"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:text="@string/nc_set_password"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/high_emphasis_text"
|
||||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/conversation_operation_delete"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -316,66 +196,6 @@
|
|||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/conversation_operation_share_link"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_item_height"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_padding"
|
||||
android:paddingEnd="@dimen/standard_padding"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_link_grey600_24px"
|
||||
app:tint="@color/high_emphasis_menu_icon" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingStart="40dp"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:text="@string/nc_share_link"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/high_emphasis_text"
|
||||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/conversation_operation_make_private"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_item_height"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_padding"
|
||||
android:paddingEnd="@dimen/standard_padding"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_group_grey600_24px"
|
||||
app:tint="@color/high_emphasis_menu_icon" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingStart="40dp"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:text="@string/nc_make_call_private"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/high_emphasis_text"
|
||||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/conversation_operation_leave"
|
||||
android:layout_width="match_parent"
|
||||
|
|
42
app/src/main/res/layout/dialog_password.xml
Normal file
42
app/src/main/res/layout/dialog_password.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Nextcloud Talk application
|
||||
|
||||
@author Andy Scherzinger
|
||||
@author Tim Krüger
|
||||
Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
Copyright (C) 2022 Tim Krüger
|
||||
Copyright (C) 2022 Nextcloud GmbH
|
||||
|
||||
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/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:background="@color/white">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dialog_padding"
|
||||
android:layout_marginTop="@dimen/standard_margin"
|
||||
android:layout_marginEnd="@dimen/dialog_padding"
|
||||
android:layout_marginBottom="@dimen/standard_margin"
|
||||
android:hint="@string/nc_guest_access_password_dialog_hint"
|
||||
android:inputType="textPassword"
|
||||
android:importantForAutofill="no" />
|
||||
</LinearLayout>
|
81
app/src/main/res/layout/guest_access_settings_item.xml
Normal file
81
app/src/main/res/layout/guest_access_settings_item.xml
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Nextcloud Talk application
|
||||
|
||||
@author Tim Krüger
|
||||
Copyright (C) 2022 Tim Krüger
|
||||
Copyright (C) 2022 Nextcloud GmbH
|
||||
|
||||
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/>.
|
||||
-->
|
||||
<com.yarolegovich.mp.MaterialPreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:apc="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/guest_access_settings"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
android:id="@+id/guest_access_category"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
apc:cardBackgroundColor="@color/bg_default"
|
||||
apc:cardElevation="0dp"
|
||||
apc:mpc_title="@string/nc_guest_access">
|
||||
|
||||
<com.yarolegovich.mp.MaterialSwitchPreference
|
||||
android:id="@+id/guest_access_allow_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
apc:mp_default_value="false"
|
||||
apc:mp_key="guest_access_allowed"
|
||||
apc:mp_summary="@string/nc_guest_access_allow_summary"
|
||||
apc:mp_title="@string/nc_guest_access_allow_title" />
|
||||
|
||||
<com.yarolegovich.mp.MaterialSwitchPreference
|
||||
android:id="@+id/guest_access_password_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
apc:mp_default_value="false"
|
||||
apc:mp_key="guest_access_password"
|
||||
apc:mp_summary="@string/nc_guest_access_password_summary"
|
||||
apc:mp_title="@string/nc_guest_access_password_title"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.yarolegovich.mp.MaterialStandardPreference
|
||||
android:id="@+id/guest_access_copy_url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
apc:mp_icon="@drawable/ic_share_variant"
|
||||
apc:mp_icon_tint="@color/grey_600"
|
||||
apc:mp_title="@string/nc_guest_access_share_link"
|
||||
tools:visibility="visible" >
|
||||
|
||||
</com.yarolegovich.mp.MaterialStandardPreference>
|
||||
|
||||
<com.yarolegovich.mp.MaterialStandardPreference
|
||||
android:id="@+id/guest_access_resend_invitations"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
apc:mp_icon="@drawable/ic_email"
|
||||
apc:mp_icon_tint="@color/grey_600"
|
||||
apc:mp_title="@string/nc_guest_access_resend_invitations"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</com.yarolegovich.mp.MaterialPreferenceCategory>
|
||||
|
||||
</com.yarolegovich.mp.MaterialPreferenceScreen>
|
|
@ -168,12 +168,6 @@
|
|||
<string name="nc_clear_history_warning">Do you really want to delete all messages in this conversation?</string>
|
||||
<string name="nc_clear_history_success">All messages were deleted</string>
|
||||
<string name="nc_rename">Rename conversation</string>
|
||||
<string name="nc_set_password">Set a password</string>
|
||||
<string name="nc_change_password">Change password</string>
|
||||
<string name="nc_clear_password">Clear password</string>
|
||||
<string name="nc_share_link">Share link</string>
|
||||
<string name="nc_make_call_public">Make conversation public</string>
|
||||
<string name="nc_make_call_private">Make conversation private</string>
|
||||
<string name="nc_delete_call">Delete conversation</string>
|
||||
<string name="nc_delete">Delete</string>
|
||||
<string name="nc_delete_all">Delete all</string>
|
||||
|
@ -337,6 +331,22 @@
|
|||
<string name="emoji_backspace">Backspace</string>
|
||||
<string name="emoji_search">Search emoji</string>
|
||||
|
||||
<!-- Conversation info guest access -->
|
||||
<string name="nc_guest_access">Guest access</string>
|
||||
<string name="nc_guest_access_allow_title">Allow guests</string>
|
||||
<string name="nc_guest_access_allow_summary">Allow guests to share a public link to join this conversation.</string>
|
||||
<string name="nc_guest_access_allow_failed">Can\'t en-/disable guest access.</string>
|
||||
<string name="nc_guest_access_password_title">Password protection</string>
|
||||
<string name="nc_guest_access_password_summary">Set a password to restrict who can use the public link.</string>
|
||||
<string name="nc_guest_access_password_dialog_title">Guest access password</string>
|
||||
<string name="nc_guest_access_password_dialog_hint">Enter a password</string>
|
||||
<string name="nc_guest_access_password_failed">Error during setting/disabling the password.</string>
|
||||
<string name="nc_guest_access_password_weak_alert_title">Weak password</string>
|
||||
<string name="nc_guest_access_share_link">Share conversation link</string>
|
||||
<string name="nc_guest_access_resend_invitations">Resend invitations</string>
|
||||
<string name="nc_guest_access_resend_invitations_successful">Invitations were sent out again.</string>
|
||||
<string name="nc_guest_access_resend_invitations_failed">Invitations were not send due to an error.</string>
|
||||
|
||||
<!-- Content descriptions -->
|
||||
<string name="nc_description_send_message_button">Send message</string>
|
||||
|
||||
|
|
|
@ -72,20 +72,8 @@ class ShareUtilsTest {
|
|||
)
|
||||
Assert.assertEquals(
|
||||
"Intent string was not as expected",
|
||||
expectedResult, ShareUtils.getStringForIntent(context, "", userManager!!, conversation)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun stringForIntent_passwordGiven_correctStringWithPasswordReturned() {
|
||||
val password = "superSecret"
|
||||
val expectedResult = String.format(
|
||||
"Join the conversation at %s/index.php/call/%s\nPassword: %s",
|
||||
baseUrl, token, password
|
||||
)
|
||||
Assert.assertEquals(
|
||||
"Intent string was not as expected",
|
||||
expectedResult, ShareUtils.getStringForIntent(context, password, userManager!!, conversation)
|
||||
expectedResult,
|
||||
ShareUtils.getStringForIntent(context!!, userManager!!.currentUser.blockingGet(), conversation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue