Skip to content

Commit

Permalink
Allows Banning
Browse files Browse the repository at this point in the history
- New option to ban participant if your a moderator and not in one-2-one
- New fragment to see previous bans, unban if wanted

Signed-off-by: rapterjet2004 <juliuslinus1@gmail.com>
  • Loading branch information
rapterjet2004 committed May 15, 2024
1 parent 073587b commit d396d40
Show file tree
Hide file tree
Showing 18 changed files with 810 additions and 15 deletions.
19 changes: 19 additions & 0 deletions app/src/main/java/com/nextcloud/talk/api/NcApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.nextcloud.talk.models.json.opengraph.OpenGraphOverall;
import com.nextcloud.talk.models.json.participants.AddParticipantOverall;
import com.nextcloud.talk.models.json.participants.ParticipantsOverall;
import com.nextcloud.talk.models.json.participants.TalkBan;
import com.nextcloud.talk.models.json.participants.TalkBanOverall;
import com.nextcloud.talk.models.json.push.PushRegistrationOverall;
import com.nextcloud.talk.models.json.reactions.ReactionsOverall;
import com.nextcloud.talk.models.json.reminder.ReminderOverall;
Expand Down Expand Up @@ -709,4 +711,21 @@ Observable<GenericOverall> acceptInvitation(@Header("Authorization") String auth
@DELETE
Observable<GenericOverall> rejectInvitation(@Header("Authorization") String authorization,
@Url String url);

@GET
Observable<TalkBanOverall> listBans(@Header("Authorization") String authorization,
@Url String url);

@FormUrlEncoded
@POST
Observable<TalkBan> banActor(@Header("Authorization") String authorization,
@Url String url,
@Field("actorType") String actorType,
@Field("actorId") String actorId,
@Field("internalNote") String internalNote);

@DELETE
Observable<GenericOverall> unbanActor(@Header("Authorization") String authorization,
@Url String url,
@Query("banId") int banId);
}
10 changes: 10 additions & 0 deletions app/src/main/java/com/nextcloud/talk/chat/data/ChatRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.conversations.RoomsOverall
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.participants.TalkBan
import com.nextcloud.talk.models.json.reminder.Reminder
import io.reactivex.Observable
import retrofit2.Response
Expand Down Expand Up @@ -59,4 +60,13 @@ interface ChatRepository {
fun createRoom(credentials: String, url: String, map: Map<String, String>): Observable<RoomOverall>
fun setChatReadMarker(credentials: String, url: String, previousMessageId: Int): Observable<GenericOverall>
fun editChatMessage(credentials: String, url: String, text: String): Observable<ChatOverallSingleMessage>
fun listBans(credentials: String, url: String): Observable<List<TalkBan>>
fun banActor(
credentials: String,
url: String,
actorType: String,
actorId: String,
internalNote: String
): Observable<TalkBan>
fun unbanActor(credentials: String, url: String, banId: Int): Observable<GenericOverall>
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.conversations.RoomsOverall
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.participants.TalkBan
import com.nextcloud.talk.models.json.reminder.Reminder
import com.nextcloud.talk.utils.ApiUtils
import io.reactivex.Observable
Expand Down Expand Up @@ -179,4 +180,22 @@ class NetworkChatRepositoryImpl(private val ncApi: NcApi) : ChatRepository {
override fun editChatMessage(credentials: String, url: String, text: String): Observable<ChatOverallSingleMessage> {
return ncApi.editChatMessage(credentials, url, text).map { it }
}

override fun listBans(credentials: String, url: String): Observable<List<TalkBan>> {
return ncApi.listBans(credentials, url).map { it.ocs?.data }
}

override fun banActor(
credentials: String,
url: String,
actorType: String,
actorId: String,
internalNote: String
): Observable<TalkBan> {
return ncApi.banActor(credentials, url, actorType, actorId, internalNote)
}

override fun unbanActor(credentials: String, url: String, banId: Int): Observable<GenericOverall> {
return ncApi.unbanActor(credentials, url, banId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.ViewModelProvider
import androidx.work.Data
import androidx.work.OneTimeWorkRequest
Expand All @@ -47,6 +48,7 @@ import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel
import com.nextcloud.talk.conversationinfoedit.ConversationInfoEditActivity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ActivityConversationInfoBinding
import com.nextcloud.talk.databinding.DialogBanActorBinding
import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.extensions.loadConversationAvatar
import com.nextcloud.talk.extensions.loadNoteToSelfAvatar
Expand All @@ -60,6 +62,7 @@ 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.converters.EnumActorTypeConverter
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
Expand All @@ -68,6 +71,7 @@ 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.ui.dialog.DialogBanListFragment
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.CapabilitiesUtil
import com.nextcloud.talk.utils.ConversationUtils
Expand Down Expand Up @@ -186,6 +190,7 @@ class ConversationInfoActivity :
binding.leaveConversationAction.setOnClickListener { leaveConversation() }
binding.clearConversationHistory.setOnClickListener { showClearHistoryDialog() }
binding.addParticipantsAction.setOnClickListener { addParticipants() }
binding.listBansButton.setOnClickListener { listBans() }

viewModel.getRoom(conversationUser, conversationToken)

Expand Down Expand Up @@ -235,6 +240,20 @@ class ConversationInfoActivity :
else -> {}
}
}

viewModel.getBanActorState.observe(this) { state ->
when (state) {
is ConversationInfoViewModel.BanActorSuccessState -> {
getListOfParticipants() // Refresh the list of participants
}

ConversationInfoViewModel.BanActorErrorState -> {
Snackbar.make(binding.root, "Error banning actor", Snackbar.LENGTH_SHORT).show()
}

else -> {}
}
}
}

private fun setupActionBar() {
Expand Down Expand Up @@ -571,6 +590,17 @@ class ConversationInfoActivity :
})
}

private fun listBans() {
val fragmentManager = supportFragmentManager
val newFragment = DialogBanListFragment(conversationToken)
val transaction = fragmentManager.beginTransaction()
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
transaction
.add(android.R.id.content, newFragment)
.addToBackStack(null)
.commit()
}

private fun addParticipants() {
val bundle = Bundle()
val existingParticipantsId = arrayListOf<String>()
Expand Down Expand Up @@ -736,6 +766,15 @@ class ConversationInfoActivity :
binding.notificationSettingsView.callNotificationsSwitch.visibility = GONE
}

binding.listBansButton.visibility =
if (ConversationUtils.canModerate(conversationCopy, spreedCapabilities) &&
ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != conversation!!.type
) {
VISIBLE
} else {
GONE
}

if (conversation!!.notificationCalls === null) {
binding.notificationSettingsView.callNotificationsSwitch.visibility = GONE
} else {
Expand Down Expand Up @@ -1070,6 +1109,10 @@ class ConversationInfoActivity :
}
}

private fun banActor(actorType: String, actorId: String, internalNote: String) {
viewModel.banActor(conversationUser, conversationToken, actorType, actorId, internalNote)
}

private fun removeAttendeeFromConversation(apiVersion: Int, participant: Participant) {
if (apiVersion >= ApiUtils.API_V4) {
ncApi.removeAttendeeFromConversation(
Expand Down Expand Up @@ -1266,6 +1309,15 @@ class ConversationInfoActivity :
)
)

if (CapabilitiesUtil.isBanningAvailable(conversationUser.capabilities?.spreedCapability!!)) {
items.add(
BasicListItemWithImage(
R.drawable.baseline_block_24,
"Ban Participant"
)
)
}

if (participant.type == Participant.ParticipantType.MODERATOR ||
participant.type == Participant.ParticipantType.GUEST_MODERATOR
) {
Expand Down Expand Up @@ -1298,25 +1350,59 @@ class ConversationInfoActivity :
actionToTrigger++
}

if (actionToTrigger == 0) {
// Pin, nothing to do
} else if (actionToTrigger == 1) {
// Promote/demote
if (apiVersion >= ApiUtils.API_V4) {
toggleModeratorStatus(apiVersion, participant)
} else {
toggleModeratorStatusLegacy(apiVersion, participant)
when (actionToTrigger) {
DEMOTE_OR_PROMOTE -> {
if (apiVersion >= ApiUtils.API_V4) {
toggleModeratorStatus(apiVersion, participant)
} else {
toggleModeratorStatusLegacy(apiVersion, participant)
}
}
} else if (actionToTrigger == 2) {
// Remove from conversation
removeAttendeeFromConversation(apiVersion, participant)

REMOVE_FROM_CONVERSATION -> {
removeAttendeeFromConversation(apiVersion, participant)
}

BAN_FROM_CONVERSATION -> {
handleBan(participant)
}

else -> {}
}
}
}
}
return true
}

private fun MaterialDialog.handleBan(participant: Participant) {
val binding = DialogBanActorBinding.inflate(layoutInflater)
val actorTypeConverter = EnumActorTypeConverter()
val dialog = MaterialAlertDialogBuilder(context)
.setView(binding.root)
.create()
binding.avatarImage.loadUserAvatar(
conversationUser,
participant.actorId!!,
true,
false
)
binding.displayNameText.text = participant.actorId
binding.buttonBan.setOnClickListener {
banActor(
actorTypeConverter.convertToString(participant.actorType!!),
participant.actorId!!,
binding.banActorEdit.text.toString()
)
dialog.dismiss()
}
binding.buttonClose.setOnClickListener { dialog.dismiss() }
viewThemeUtils.material.colorTextInputLayout(binding.banActorEditLayout)
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(binding.buttonBan)
viewThemeUtils.material.colorMaterialButtonText(binding.buttonClose)
dialog.show()
}

private fun setUpNotificationSettings(module: DatabaseStorageModule) {
binding.notificationSettingsView.notificationSettingsImportantConversation.setOnClickListener {
val isChecked = binding.notificationSettingsView.importantConversationSwitch.isChecked
Expand Down Expand Up @@ -1355,6 +1441,9 @@ class ConversationInfoActivity :
private const val LOW_EMPHASIS_OPACITY: Float = 0.38f
private const val RECORDING_CONSENT_NOT_REQUIRED_FOR_CONVERSATION: Int = 0
private const val RECORDING_CONSENT_REQUIRED_FOR_CONVERSATION: Int = 1
private const val DEMOTE_OR_PROMOTE = 1
private const val REMOVE_FROM_CONVERSATION = 2
private const val BAN_FROM_CONVERSATION = 3
}

/**
Expand Down
Loading

0 comments on commit d396d40

Please sign in to comment.