Skip to content

Commit 4c469e0

Browse files
committed
Add/Remove local alias (#2428)
1 parent 5b027be commit 4c469e0

File tree

19 files changed

+262
-94
lines changed

19 files changed

+262
-94
lines changed

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/alias/AliasService.kt

+5
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ interface AliasService {
2121
* Get list of local alias of the room
2222
*/
2323
suspend fun getRoomAliases(): List<String>
24+
25+
/**
26+
* Add local alias to the room
27+
*/
28+
suspend fun addAlias(aliasLocalPart: String)
2429
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2020 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.api.session.room.alias
18+
19+
sealed class RoomAliasError : Throwable() {
20+
object AliasEmpty : RoomAliasError()
21+
object AliasNotAvailable : RoomAliasError()
22+
object AliasInvalid : RoomAliasError()
23+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/failure/CreateRoomFailure.kt

+2-5
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@ package org.matrix.android.sdk.api.session.room.failure
1818

1919
import org.matrix.android.sdk.api.failure.Failure
2020
import org.matrix.android.sdk.api.failure.MatrixError
21+
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
2122

2223
sealed class CreateRoomFailure : Failure.FeatureFailure() {
2324
object CreatedWithTimeout : CreateRoomFailure()
2425
data class CreatedWithFederationFailure(val matrixError: MatrixError) : CreateRoomFailure()
25-
sealed class RoomAliasError : CreateRoomFailure() {
26-
object AliasEmpty : RoomAliasError()
27-
object AliasNotAvailable : RoomAliasError()
28-
object AliasInvalid : RoomAliasError()
29-
}
26+
data class AliasError(val aliasError: RoomAliasError) : CreateRoomFailure()
3027
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt

-5
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ interface StateService {
3838
*/
3939
fun updateName(name: String, callback: MatrixCallback<Unit>): Cancelable
4040

41-
/**
42-
* Add new alias to the room.
43-
*/
44-
fun addRoomAlias(roomAlias: String, callback: MatrixCallback<Unit>): Cancelable
45-
4641
/**
4742
* Update the canonical alias of the room
4843
*/

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ internal interface DirectoryAPI {
3939
* Add alias to the room.
4040
* @param roomAlias the room alias.
4141
*/
42-
// TODO Remove (https://github.com/matrix-org/matrix-doc/blob/rav/proposal/alt_canonical_aliases/proposals/2432-revised-alias-publishing.md)
4342
@PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/room/{roomAlias}")
4443
fun addRoomAlias(@Path("roomAlias") roomAlias: String,
4544
@Body body: AddRoomAliasBody): Call<Unit>

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/AddRoomAliasTask.kt

+8-2
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,33 @@
1717
package org.matrix.android.sdk.internal.session.room.alias
1818

1919
import org.greenrobot.eventbus.EventBus
20+
import org.matrix.android.sdk.internal.di.UserId
2021
import org.matrix.android.sdk.internal.network.executeRequest
2122
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
23+
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasAvailabilityChecker.Companion.toFullAlias
2224
import org.matrix.android.sdk.internal.task.Task
2325
import javax.inject.Inject
2426

2527
internal interface AddRoomAliasTask : Task<AddRoomAliasTask.Params, Unit> {
2628
data class Params(
2729
val roomId: String,
28-
val roomAlias: String
30+
val aliasLocalPart: String
2931
)
3032
}
3133

3234
internal class DefaultAddRoomAliasTask @Inject constructor(
35+
@UserId private val userId: String,
3336
private val directoryAPI: DirectoryAPI,
37+
private val aliasAvailabilityChecker: RoomAliasAvailabilityChecker,
3438
private val eventBus: EventBus
3539
) : AddRoomAliasTask {
3640

3741
override suspend fun execute(params: AddRoomAliasTask.Params) {
42+
aliasAvailabilityChecker.check(params.aliasLocalPart)
43+
3844
executeRequest<Unit>(eventBus) {
3945
apiCall = directoryAPI.addRoomAlias(
40-
roomAlias = params.roomAlias,
46+
roomAlias = params.aliasLocalPart.toFullAlias(userId),
4147
body = AddRoomAliasBody(
4248
roomId = params.roomId
4349
)

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DefaultAliasService.kt

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ import org.matrix.android.sdk.api.session.room.alias.AliasService
2222

2323
internal class DefaultAliasService @AssistedInject constructor(
2424
@Assisted private val roomId: String,
25-
private val getRoomLocalAliasesTask: GetRoomLocalAliasesTask
25+
private val getRoomLocalAliasesTask: GetRoomLocalAliasesTask,
26+
private val addRoomAliasTask: AddRoomAliasTask
2627
) : AliasService {
2728

2829
@AssistedInject.Factory
@@ -33,4 +34,8 @@ internal class DefaultAliasService @AssistedInject constructor(
3334
override suspend fun getRoomAliases(): List<String> {
3435
return getRoomLocalAliasesTask.execute(GetRoomLocalAliasesTask.Params(roomId))
3536
}
37+
38+
override suspend fun addAlias(aliasLocalPart: String) {
39+
addRoomAliasTask.execute(AddRoomAliasTask.Params(roomId, aliasLocalPart))
40+
}
3641
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2020 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.internal.session.room.alias
18+
19+
import org.greenrobot.eventbus.EventBus
20+
import org.matrix.android.sdk.api.failure.Failure
21+
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
22+
import org.matrix.android.sdk.internal.di.UserId
23+
import org.matrix.android.sdk.internal.network.executeRequest
24+
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
25+
import javax.inject.Inject
26+
27+
internal class RoomAliasAvailabilityChecker @Inject constructor(
28+
@UserId private val userId: String,
29+
private val directoryAPI: DirectoryAPI,
30+
private val eventBus: EventBus
31+
) {
32+
@Throws(RoomAliasError::class)
33+
suspend fun check(aliasLocalPart: String?) {
34+
if (aliasLocalPart.isNullOrEmpty()) {
35+
throw RoomAliasError.AliasEmpty
36+
}
37+
// Check alias availability
38+
val fullAlias = aliasLocalPart.toFullAlias(userId)
39+
try {
40+
executeRequest<RoomAliasDescription>(eventBus) {
41+
apiCall = directoryAPI.getRoomIdByAlias(fullAlias)
42+
}
43+
} catch (throwable: Throwable) {
44+
if (throwable is Failure.ServerError && throwable.httpCode == 404) {
45+
// This is a 404, so the alias is available: nominal case
46+
null
47+
} else {
48+
// Other error, propagate it
49+
throw throwable
50+
}
51+
}
52+
?.let {
53+
// Alias already exists: error case
54+
throw RoomAliasError.AliasNotAvailable
55+
}
56+
}
57+
58+
companion object {
59+
internal fun String.toFullAlias(userId: String) = "#" + this + ":" + userId.substringAfter(":")
60+
}
61+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt

+7-26
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import kotlinx.coroutines.TimeoutCancellationException
2222
import org.greenrobot.eventbus.EventBus
2323
import org.matrix.android.sdk.api.failure.Failure
2424
import org.matrix.android.sdk.api.failure.MatrixError
25+
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
2526
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
2627
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
2728
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
@@ -31,11 +32,9 @@ import org.matrix.android.sdk.internal.database.model.RoomEntityFields
3132
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
3233
import org.matrix.android.sdk.internal.database.query.where
3334
import org.matrix.android.sdk.internal.di.SessionDatabase
34-
import org.matrix.android.sdk.internal.di.UserId
3535
import org.matrix.android.sdk.internal.network.executeRequest
36-
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
3736
import org.matrix.android.sdk.internal.session.room.RoomAPI
38-
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription
37+
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasAvailabilityChecker
3938
import org.matrix.android.sdk.internal.session.room.read.SetReadMarkersTask
4039
import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper
4140
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
@@ -48,9 +47,8 @@ internal interface CreateRoomTask : Task<CreateRoomParams, String>
4847

4948
internal class DefaultCreateRoomTask @Inject constructor(
5049
private val roomAPI: RoomAPI,
51-
private val directoryAPI: DirectoryAPI,
52-
@UserId private val userId: String,
5350
@SessionDatabase private val monarchy: Monarchy,
51+
private val aliasAvailabilityChecker: RoomAliasAvailabilityChecker,
5452
private val directChatsHelper: DirectChatsHelper,
5553
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
5654
private val readMarkersTask: SetReadMarkersTask,
@@ -67,28 +65,11 @@ internal class DefaultCreateRoomTask @Inject constructor(
6765
} else null
6866

6967
if (params.preset == CreateRoomPreset.PRESET_PUBLIC_CHAT) {
70-
if (params.roomAliasName.isNullOrEmpty()) {
71-
throw CreateRoomFailure.RoomAliasError.AliasEmpty
72-
}
73-
// Check alias availability
74-
val fullAlias = "#" + params.roomAliasName + ":" + userId.substringAfter(":")
7568
try {
76-
executeRequest<RoomAliasDescription>(eventBus) {
77-
apiCall = directoryAPI.getRoomIdByAlias(fullAlias)
78-
}
79-
} catch (throwable: Throwable) {
80-
if (throwable is Failure.ServerError && throwable.httpCode == 404) {
81-
// This is a 404, so the alias is available: nominal case
82-
null
83-
} else {
84-
// Other error, propagate it
85-
throw throwable
86-
}
69+
aliasAvailabilityChecker.check(params.roomAliasName)
70+
} catch (aliasError: RoomAliasError) {
71+
throw CreateRoomFailure.AliasError(aliasError)
8772
}
88-
?.let {
89-
// Alias already exists: error case
90-
throw CreateRoomFailure.RoomAliasError.AliasNotAvailable
91-
}
9273
}
9374

9475
val createRoomBody = createRoomBodyBuilder.build(params)
@@ -106,7 +87,7 @@ internal class DefaultCreateRoomTask @Inject constructor(
10687
} else if (throwable.httpCode == 400
10788
&& throwable.error.code == MatrixError.M_UNKNOWN
10889
&& throwable.error.message == "Invalid characters in room alias") {
109-
throw CreateRoomFailure.RoomAliasError.AliasInvalid
90+
throw CreateRoomFailure.AliasError(RoomAliasError.AliasInvalid)
11091
}
11192
}
11293
throw throwable

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt

-8
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,6 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private
104104
)
105105
}
106106

107-
override fun addRoomAlias(roomAlias: String, callback: MatrixCallback<Unit>): Cancelable {
108-
return addRoomAliasTask
109-
.configureWith(AddRoomAliasTask.Params(roomId, roomAlias)) {
110-
this.callback = callback
111-
}
112-
.executeBy(taskExecutor)
113-
}
114-
115107
override fun updateCanonicalAlias(alias: String, callback: MatrixCallback<Unit>): Cancelable {
116108
return sendStateEvent(
117109
eventType = EventType.STATE_ROOM_CANONICAL_ALIAS,

vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt

+5-12
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,20 @@ import com.airbnb.epoxy.TypedEpoxyController
2020
import com.airbnb.mvrx.Fail
2121
import com.airbnb.mvrx.Loading
2222
import im.vector.app.R
23-
import im.vector.app.core.error.ErrorFormatter
2423
import im.vector.app.core.resources.StringProvider
2524
import im.vector.app.features.discovery.settingsSectionTitleItem
2625
import im.vector.app.features.form.formAdvancedToggleItem
2726
import im.vector.app.features.form.formEditTextItem
2827
import im.vector.app.features.form.formEditableAvatarItem
2928
import im.vector.app.features.form.formSubmitButtonItem
3029
import im.vector.app.features.form.formSwitchItem
30+
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
3131
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
3232
import javax.inject.Inject
3333

34-
class CreateRoomController @Inject constructor(private val stringProvider: StringProvider,
35-
private val errorFormatter: ErrorFormatter
34+
class CreateRoomController @Inject constructor(
35+
private val stringProvider: StringProvider,
36+
private val roomAliasErrorFormatter: RoomAliasErrorFormatter
3637
) : TypedEpoxyController<CreateRoomViewState>() {
3738

3839
var listener: Listener? = null
@@ -103,15 +104,7 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin
103104
enabled(enableFormElement)
104105
value(viewState.roomType.aliasLocalPart)
105106
homeServer(":" + viewState.homeServerName)
106-
errorMessage(
107-
when ((viewState.asyncCreateRoomRequest as? Fail)?.error) {
108-
is CreateRoomFailure.RoomAliasError.AliasEmpty -> R.string.create_room_alias_empty
109-
is CreateRoomFailure.RoomAliasError.AliasNotAvailable -> R.string.create_room_alias_already_in_use
110-
is CreateRoomFailure.RoomAliasError.AliasInvalid -> R.string.create_room_alias_invalid
111-
else -> null
112-
}
113-
?.let { stringProvider.getString(it) }
114-
)
107+
errorMessage(roomAliasErrorFormatter.format((((viewState.asyncCreateRoomRequest as? Fail)?.error) as? CreateRoomFailure.AliasError)?.aliasError))
115108
onTextChange { value ->
116109
listener?.setAliasLocalPart(value)
117110
}

vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class CreateRoomFragment @Inject constructor(
8484

8585
override fun showFailure(throwable: Throwable) {
8686
// Note: RoomAliasError are displayed directly in the form
87-
if (throwable !is CreateRoomFailure.RoomAliasError) {
87+
if (throwable !is CreateRoomFailure.AliasError) {
8888
super.showFailure(throwable)
8989
}
9090
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2020 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.features.roomdirectory.createroom
18+
19+
import im.vector.app.R
20+
import im.vector.app.core.resources.StringProvider
21+
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
22+
import javax.inject.Inject
23+
24+
class RoomAliasErrorFormatter @Inject constructor(
25+
private val stringProvider: StringProvider
26+
) {
27+
fun format(roomAliasError: RoomAliasError?): String? {
28+
return when (roomAliasError) {
29+
is RoomAliasError.AliasEmpty -> R.string.create_room_alias_empty
30+
is RoomAliasError.AliasNotAvailable -> R.string.create_room_alias_already_in_use
31+
is RoomAliasError.AliasInvalid -> R.string.create_room_alias_invalid
32+
else -> null
33+
}
34+
?.let { stringProvider.getString(it) }
35+
}
36+
}

vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasAction.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ sealed class RoomAliasAction : VectorViewModelAction {
2626
object UnSetCanonicalAlias : RoomAliasAction()
2727

2828
// Local
29-
data class AddLocalAlias(val aliasLocalPart: String) : RoomAliasAction()
3029
data class RemoveLocalAlias(val alias: String) : RoomAliasAction()
30+
data class SetNewLocalAliasLocalPart(val aliasLocalPart: String) : RoomAliasAction()
31+
object AddLocalAlias : RoomAliasAction()
3132
}

0 commit comments

Comments
 (0)