diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/reporting/ReportingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/reporting/ReportingService.kt index a444e2346e..c3ee5d75c1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/reporting/ReportingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/reporting/ReportingService.kt @@ -26,4 +26,9 @@ interface ReportingService { * Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-rooms-roomid-report-eventid */ suspend fun reportContent(eventId: String, score: Int, reason: String) + + /** + * Report a room. + */ + suspend fun reportRoom(reason: String) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index aa4bdb1dd4..33fa1d8ce0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -36,6 +36,7 @@ import org.matrix.android.sdk.internal.session.room.read.ReadBody import org.matrix.android.sdk.internal.session.room.relation.RelationsResponse import org.matrix.android.sdk.internal.session.room.relation.threads.ThreadSummariesResponse import org.matrix.android.sdk.internal.session.room.reporting.ReportContentBody +import org.matrix.android.sdk.internal.session.room.reporting.ReportRoomBody import org.matrix.android.sdk.internal.session.room.send.SendResponse import org.matrix.android.sdk.internal.session.room.send.model.EventRedactBody import org.matrix.android.sdk.internal.session.room.tags.TagBody @@ -375,6 +376,18 @@ internal interface RoomAPI { @Body body: ReportContentBody, ) + /** + * Reports a room as inappropriate to the server, which may then notify the appropriate people. + * + * @param roomId the room id + * @param body body containing the reason + */ + @POST(NetworkConstants.URI_API_PREFIX_PATH_V3 + "rooms/{roomId}/report") + suspend fun reportRoom( + @Path("roomId") roomId: String, + @Body body: ReportRoomBody, + ) + /** * Get a list of aliases maintained by the local server for the given room. * Ref: https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-rooms-roomid-aliases diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt index 673a979633..d14568ebc3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt @@ -114,7 +114,9 @@ import org.matrix.android.sdk.internal.session.room.relation.threads.DefaultFetc import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadSummariesTask import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask import org.matrix.android.sdk.internal.session.room.reporting.DefaultReportContentTask +import org.matrix.android.sdk.internal.session.room.reporting.DefaultReportRoomTask import org.matrix.android.sdk.internal.session.room.reporting.ReportContentTask +import org.matrix.android.sdk.internal.session.room.reporting.ReportRoomTask import org.matrix.android.sdk.internal.session.room.state.DefaultSendStateTask import org.matrix.android.sdk.internal.session.room.state.SendStateTask import org.matrix.android.sdk.internal.session.room.tags.AddTagToRoomTask @@ -281,6 +283,9 @@ internal abstract class RoomModule { @Binds abstract fun bindReportContentTask(task: DefaultReportContentTask): ReportContentTask + @Binds + abstract fun bindReportRoomTask(task: DefaultReportRoomTask): ReportRoomTask + @Binds abstract fun bindGetContextOfEventTask(task: DefaultGetContextOfEventTask): GetContextOfEventTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/DefaultReportingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/DefaultReportingService.kt index 1e32bf5e16..ba8a6cb453 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/DefaultReportingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/DefaultReportingService.kt @@ -23,7 +23,8 @@ import org.matrix.android.sdk.api.session.room.reporting.ReportingService internal class DefaultReportingService @AssistedInject constructor( @Assisted private val roomId: String, - private val reportContentTask: ReportContentTask + private val reportContentTask: ReportContentTask, + private val reportRoomTask: ReportRoomTask, ) : ReportingService { @AssistedFactory @@ -35,4 +36,9 @@ internal class DefaultReportingService @AssistedInject constructor( val params = ReportContentTask.Params(roomId, eventId, score, reason) reportContentTask.execute(params) } + + override suspend fun reportRoom(reason: String) { + val params = ReportRoomTask.Params(roomId, reason) + reportRoomTask.execute(params) + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportRoomBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportRoomBody.kt new file mode 100644 index 0000000000..8e21132063 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportRoomBody.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2025 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.reporting + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class ReportRoomBody( + /** + * Required. The reason the content is being reported. May be blank. + */ + @Json(name = "reason") val reason: String +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportRoomTask.kt new file mode 100644 index 0000000000..54b0efd207 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportRoomTask.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2025 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.reporting + +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver +import org.matrix.android.sdk.internal.network.executeRequest +import org.matrix.android.sdk.internal.session.room.RoomAPI +import org.matrix.android.sdk.internal.task.Task +import javax.inject.Inject + +internal interface ReportRoomTask : Task { + data class Params( + val roomId: String, + val reason: String, + ) +} + +internal class DefaultReportRoomTask @Inject constructor( + private val roomAPI: RoomAPI, + private val globalErrorReceiver: GlobalErrorReceiver +) : ReportRoomTask { + + override suspend fun execute(params: ReportRoomTask.Params) { + return executeRequest(globalErrorReceiver) { + roomAPI.reportRoom(params.roomId, ReportRoomBody(params.reason)) + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt index f54f7314ad..83b1c5a950 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt @@ -184,17 +184,7 @@ class RoomProfileViewModel @AssistedInject constructor( _viewEvents.post(RoomProfileViewEvents.Loading()) session.coroutineScope.launch { try { - // When reporting a user, use the user state event if available (it should always be available) - val createStateEventId = room.stateService() - .getStateEvent(EventType.STATE_ROOM_CREATE, QueryStringValue.IsEmpty) - ?.eventId - ?: throw IllegalStateException("Failure: m.room.create event not found.") - room.reportingService() - .reportContent( - eventId = createStateEventId, - score = -100, - reason = reason, - ) + room.reportingService().reportRoom(reason = reason) _viewEvents.post( RoomProfileViewEvents.Success( stringProvider.getString(CommonStrings.room_profile_section_more_report_success_content)