mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-28 16:59:01 +03:00
Merge pull request #2439 from vector-im/feature/bma/alias
Add room alias management
This commit is contained in:
commit
93ffb116b7
75 changed files with 2244 additions and 220 deletions
.idea/dictionaries
CHANGES.mdmatrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx
matrix-sdk-android/src/main
java/org/matrix/android/sdk
api/session
events/model
room
internal/session
directory
room
DefaultRoom.ktDefaultRoomDirectoryService.ktDefaultRoomService.ktRoomAPI.ktRoomFactory.ktRoomModule.kt
alias
AddRoomAliasTask.ktDefaultAliasService.ktDeleteRoomAliasTask.ktGetAliasesResponse.ktGetRoomIdByAliasTask.ktGetRoomLocalAliasesTask.ktRoomAliasAvailabilityChecker.kt
create
directory
membership
state
res/values
vector/src/main
java/im/vector/app
core
di
epoxy/profiles
features
discovery
form
home/room
detail/timeline
list/actions
roomdirectory/createroom
roomprofile
RoomProfileActivity.ktRoomProfileSharedAction.kt
alias
RoomAliasAction.ktRoomAliasController.ktRoomAliasFragment.ktRoomAliasViewEvents.ktRoomAliasViewModel.ktRoomAliasViewState.kt
detail
banned
RoomBannedMemberListAction.ktRoomBannedMemberListFragment.ktRoomBannedMemberListViewEvents.ktRoomBannedMemberListViewModel.kt
settings
res
1
.idea/dictionaries/bmarty.xml
generated
1
.idea/dictionaries/bmarty.xml
generated
|
@ -31,6 +31,7 @@
|
||||||
<w>ssss</w>
|
<w>ssss</w>
|
||||||
<w>sygnal</w>
|
<w>sygnal</w>
|
||||||
<w>threepid</w>
|
<w>threepid</w>
|
||||||
|
<w>unpublish</w>
|
||||||
<w>unwedging</w>
|
<w>unwedging</w>
|
||||||
</words>
|
</words>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
|
|
|
@ -2,7 +2,7 @@ Changes in Element 1.0.12 (2020-XX-XX)
|
||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
Features ✨:
|
Features ✨:
|
||||||
-
|
- Add room aliases management, and room directory visibility management in a dedicated screen (#1579, #2428)
|
||||||
|
|
||||||
Improvements 🙌:
|
Improvements 🙌:
|
||||||
- Add Setting Item to Change PIN (#2462)
|
- Add Setting Item to Change PIN (#2462)
|
||||||
|
|
|
@ -127,14 +127,6 @@ class RxRoom(private val room: Room) {
|
||||||
room.updateName(name, it)
|
room.updateName(name, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addRoomAlias(alias: String): Completable = completableBuilder<Unit> {
|
|
||||||
room.addRoomAlias(alias, it)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateCanonicalAlias(alias: String): Completable = completableBuilder<Unit> {
|
|
||||||
room.updateCanonicalAlias(alias, it)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateHistoryReadability(readability: RoomHistoryVisibility): Completable = completableBuilder<Unit> {
|
fun updateHistoryReadability(readability: RoomHistoryVisibility): Completable = completableBuilder<Unit> {
|
||||||
room.updateHistoryReadability(readability, it)
|
room.updateHistoryReadability(readability, it)
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,12 @@ object EventType {
|
||||||
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
|
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
|
||||||
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
|
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
|
||||||
const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels"
|
const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note that this Event has been deprecated, see
|
||||||
|
* - https://matrix.org/docs/spec/client_server/r0.6.1#historical-events
|
||||||
|
* - https://github.com/matrix-org/matrix-doc/pull/2432
|
||||||
|
*/
|
||||||
const val STATE_ROOM_ALIASES = "m.room.aliases"
|
const val STATE_ROOM_ALIASES = "m.room.aliases"
|
||||||
const val STATE_ROOM_TOMBSTONE = "m.room.tombstone"
|
const val STATE_ROOM_TOMBSTONE = "m.room.tombstone"
|
||||||
const val STATE_ROOM_CANONICAL_ALIAS = "m.room.canonical_alias"
|
const val STATE_ROOM_CANONICAL_ALIAS = "m.room.canonical_alias"
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.session.room
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import org.matrix.android.sdk.api.MatrixCallback
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.AliasService
|
||||||
import org.matrix.android.sdk.api.session.room.call.RoomCallService
|
import org.matrix.android.sdk.api.session.room.call.RoomCallService
|
||||||
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
|
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
|
||||||
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
||||||
|
@ -46,6 +47,7 @@ interface Room :
|
||||||
DraftService,
|
DraftService,
|
||||||
ReadService,
|
ReadService,
|
||||||
TypingService,
|
TypingService,
|
||||||
|
AliasService,
|
||||||
TagsService,
|
TagsService,
|
||||||
MembershipService,
|
MembershipService,
|
||||||
StateService,
|
StateService,
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.matrix.android.sdk.api.session.room
|
package org.matrix.android.sdk.api.session.room
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.MatrixCallback
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
|
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
|
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
|
||||||
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||||
|
@ -39,4 +40,14 @@ interface RoomDirectoryService {
|
||||||
* Includes both the available protocols and all fields required for queries against each protocol.
|
* Includes both the available protocols and all fields required for queries against each protocol.
|
||||||
*/
|
*/
|
||||||
fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable
|
fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the visibility of a room in the directory
|
||||||
|
*/
|
||||||
|
suspend fun getRoomDirectoryVisibility(roomId: String): RoomDirectoryVisibility
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the visibility of a room in the directory
|
||||||
|
*/
|
||||||
|
suspend fun setRoomDirectoryVisibility(roomId: String, roomDirectoryVisibility: RoomDirectoryVisibility)
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,11 @@ interface RoomService {
|
||||||
searchOnServer: Boolean,
|
searchOnServer: Boolean,
|
||||||
callback: MatrixCallback<Optional<String>>): Cancelable
|
callback: MatrixCallback<Optional<String>>): Cancelable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a room alias
|
||||||
|
*/
|
||||||
|
suspend fun deleteRoomAlias(roomAlias: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a live data of all local changes membership that happened since the session has been opened.
|
* Return a live data of all local changes membership that happened since the session has been opened.
|
||||||
* It allows you to track this in your client to known what is currently being processed by the SDK.
|
* It allows you to track this in your client to known what is currently being processed by the SDK.
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.api.session.room.alias
|
||||||
|
|
||||||
|
interface AliasService {
|
||||||
|
/**
|
||||||
|
* Get list of local alias of the room
|
||||||
|
* @return the list of the aliases (full aliases, not only the local part)
|
||||||
|
*/
|
||||||
|
suspend fun getRoomAliases(): List<String>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add local alias to the room
|
||||||
|
* @param aliasLocalPart the local part of the alias.
|
||||||
|
* Ex: for the alias "#my_alias:example.org", the local part is "my_alias"
|
||||||
|
*/
|
||||||
|
suspend fun addAlias(aliasLocalPart: String)
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.api.session.room.alias
|
||||||
|
|
||||||
|
sealed class RoomAliasError : Throwable() {
|
||||||
|
object AliasEmpty : RoomAliasError()
|
||||||
|
object AliasNotAvailable : RoomAliasError()
|
||||||
|
object AliasInvalid : RoomAliasError()
|
||||||
|
}
|
|
@ -18,13 +18,10 @@ package org.matrix.android.sdk.api.session.room.failure
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
import org.matrix.android.sdk.api.failure.Failure
|
||||||
import org.matrix.android.sdk.api.failure.MatrixError
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
|
||||||
|
|
||||||
sealed class CreateRoomFailure : Failure.FeatureFailure() {
|
sealed class CreateRoomFailure : Failure.FeatureFailure() {
|
||||||
object CreatedWithTimeout : CreateRoomFailure()
|
object CreatedWithTimeout : CreateRoomFailure()
|
||||||
data class CreatedWithFederationFailure(val matrixError: MatrixError) : CreateRoomFailure()
|
data class CreatedWithFederationFailure(val matrixError: MatrixError) : CreateRoomFailure()
|
||||||
sealed class RoomAliasError : CreateRoomFailure() {
|
data class AliasError(val aliasError: RoomAliasError) : CreateRoomFailure()
|
||||||
object AliasEmpty : RoomAliasError()
|
|
||||||
object AliasNotAvailable : RoomAliasError()
|
|
||||||
object AliasInvalid : RoomAliasError()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,9 @@ import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing the EventType.STATE_ROOM_ALIASES state event content
|
* Class representing the EventType.STATE_ROOM_ALIASES state event content
|
||||||
|
* Note that this Event has been deprecated, see
|
||||||
|
* - https://matrix.org/docs/spec/client_server/r0.6.1#historical-events
|
||||||
|
* - https://github.com/matrix-org/matrix-doc/pull/2432
|
||||||
*/
|
*/
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class RoomAliasesContent(
|
data class RoomAliasesContent(
|
||||||
|
|
|
@ -24,5 +24,14 @@ import com.squareup.moshi.JsonClass
|
||||||
*/
|
*/
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class RoomCanonicalAliasContent(
|
data class RoomCanonicalAliasContent(
|
||||||
@Json(name = "alias") val canonicalAlias: String? = null
|
/**
|
||||||
|
* The canonical alias for the room. If not present, null, or empty the room should be considered to have no canonical alias.
|
||||||
|
*/
|
||||||
|
@Json(name = "alias") val canonicalAlias: String? = null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alternative aliases the room advertises.
|
||||||
|
* This list can have aliases despite the alias field being null, empty, or otherwise not present.
|
||||||
|
*/
|
||||||
|
@Json(name = "alt_aliases") val alternativeAliases: List<String>? = null
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,15 +38,12 @@ interface StateService {
|
||||||
*/
|
*/
|
||||||
fun updateName(name: String, callback: MatrixCallback<Unit>): Cancelable
|
fun updateName(name: String, callback: MatrixCallback<Unit>): Cancelable
|
||||||
|
|
||||||
/**
|
|
||||||
* Add new alias to the room.
|
|
||||||
*/
|
|
||||||
fun addRoomAlias(roomAlias: String, callback: MatrixCallback<Unit>): Cancelable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the canonical alias of the room
|
* Update the canonical alias of the room
|
||||||
|
* @param alias the canonical alias, or null to reset the canonical alias of this room
|
||||||
|
* @param altAliases the alternative aliases for this room. It should include the canonical alias if any.
|
||||||
*/
|
*/
|
||||||
fun updateCanonicalAlias(alias: String, callback: MatrixCallback<Unit>): Cancelable
|
fun updateCanonicalAlias(alias: String?, altAliases: List<String>, callback: MatrixCallback<Unit>): Cancelable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the history readability of the room
|
* Update the history readability of the room
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.directory
|
||||||
|
|
||||||
|
import org.matrix.android.sdk.internal.network.NetworkConstants
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.AddRoomAliasBody
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.DELETE
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.PUT
|
||||||
|
import retrofit2.http.Path
|
||||||
|
|
||||||
|
internal interface DirectoryAPI {
|
||||||
|
/**
|
||||||
|
* Get the room ID associated to the room alias.
|
||||||
|
*
|
||||||
|
* @param roomAlias the room alias.
|
||||||
|
*/
|
||||||
|
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/room/{roomAlias}")
|
||||||
|
fun getRoomIdByAlias(@Path("roomAlias") roomAlias: String): Call<RoomAliasDescription>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the room directory visibility.
|
||||||
|
*
|
||||||
|
* @param roomId the room id.
|
||||||
|
*/
|
||||||
|
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/list/room/{roomId}")
|
||||||
|
fun getRoomDirectoryVisibility(@Path("roomId") roomId: String): Call<RoomDirectoryVisibilityJson>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the room directory visibility.
|
||||||
|
*
|
||||||
|
* @param roomId the room id.
|
||||||
|
* @param body the body containing the new directory visibility
|
||||||
|
*/
|
||||||
|
@PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/list/room/{roomId}")
|
||||||
|
fun setRoomDirectoryVisibility(@Path("roomId") roomId: String,
|
||||||
|
@Body body: RoomDirectoryVisibilityJson): Call<Unit>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add alias to the room.
|
||||||
|
* @param roomAlias the room alias.
|
||||||
|
*/
|
||||||
|
@PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/room/{roomAlias}")
|
||||||
|
fun addRoomAlias(@Path("roomAlias") roomAlias: String,
|
||||||
|
@Body body: AddRoomAliasBody): Call<Unit>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a room alias
|
||||||
|
* @param roomAlias the room alias.
|
||||||
|
*/
|
||||||
|
@DELETE(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/room/{roomAlias}")
|
||||||
|
fun deleteRoomAlias(@Path("roomAlias") roomAlias: String): Call<Unit>
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.directory
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
internal data class RoomDirectoryVisibilityJson(
|
||||||
|
/**
|
||||||
|
* The visibility of the room in the directory. One of: ["private", "public"]
|
||||||
|
*/
|
||||||
|
@Json(name = "visibility") val visibility: RoomDirectoryVisibility
|
||||||
|
)
|
|
@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.MatrixCallback
|
||||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.AliasService
|
||||||
import org.matrix.android.sdk.api.session.room.call.RoomCallService
|
import org.matrix.android.sdk.api.session.room.call.RoomCallService
|
||||||
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
@ -58,6 +59,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
|
||||||
private val roomCallService: RoomCallService,
|
private val roomCallService: RoomCallService,
|
||||||
private val readService: ReadService,
|
private val readService: ReadService,
|
||||||
private val typingService: TypingService,
|
private val typingService: TypingService,
|
||||||
|
private val aliasService: AliasService,
|
||||||
private val tagsService: TagsService,
|
private val tagsService: TagsService,
|
||||||
private val cryptoService: CryptoService,
|
private val cryptoService: CryptoService,
|
||||||
private val relationService: RelationService,
|
private val relationService: RelationService,
|
||||||
|
@ -76,6 +78,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
|
||||||
RoomCallService by roomCallService,
|
RoomCallService by roomCallService,
|
||||||
ReadService by readService,
|
ReadService by readService,
|
||||||
TypingService by typingService,
|
TypingService by typingService,
|
||||||
|
AliasService by aliasService,
|
||||||
TagsService by tagsService,
|
TagsService by tagsService,
|
||||||
RelationService by relationService,
|
RelationService by relationService,
|
||||||
MembershipService by roomMembersService,
|
MembershipService by roomMembersService,
|
||||||
|
|
|
@ -18,19 +18,25 @@ package org.matrix.android.sdk.internal.session.room
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.MatrixCallback
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
import org.matrix.android.sdk.api.session.room.RoomDirectoryService
|
import org.matrix.android.sdk.api.session.room.RoomDirectoryService
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
|
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
|
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
|
||||||
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||||
import org.matrix.android.sdk.api.util.Cancelable
|
import org.matrix.android.sdk.api.util.Cancelable
|
||||||
import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
|
import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask
|
||||||
import org.matrix.android.sdk.internal.session.room.directory.GetThirdPartyProtocolsTask
|
import org.matrix.android.sdk.internal.session.room.directory.GetThirdPartyProtocolsTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.directory.SetRoomDirectoryVisibilityTask
|
||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||||
import org.matrix.android.sdk.internal.task.configureWith
|
import org.matrix.android.sdk.internal.task.configureWith
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class DefaultRoomDirectoryService @Inject constructor(private val getPublicRoomTask: GetPublicRoomTask,
|
internal class DefaultRoomDirectoryService @Inject constructor(
|
||||||
private val getThirdPartyProtocolsTask: GetThirdPartyProtocolsTask,
|
private val getPublicRoomTask: GetPublicRoomTask,
|
||||||
private val taskExecutor: TaskExecutor) : RoomDirectoryService {
|
private val getThirdPartyProtocolsTask: GetThirdPartyProtocolsTask,
|
||||||
|
private val getRoomDirectoryVisibilityTask: GetRoomDirectoryVisibilityTask,
|
||||||
|
private val setRoomDirectoryVisibilityTask: SetRoomDirectoryVisibilityTask,
|
||||||
|
private val taskExecutor: TaskExecutor) : RoomDirectoryService {
|
||||||
|
|
||||||
override fun getPublicRooms(server: String?,
|
override fun getPublicRooms(server: String?,
|
||||||
publicRoomsParams: PublicRoomsParams,
|
publicRoomsParams: PublicRoomsParams,
|
||||||
|
@ -49,4 +55,12 @@ internal class DefaultRoomDirectoryService @Inject constructor(private val getPu
|
||||||
}
|
}
|
||||||
.executeBy(taskExecutor)
|
.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getRoomDirectoryVisibility(roomId: String): RoomDirectoryVisibility {
|
||||||
|
return getRoomDirectoryVisibilityTask.execute(GetRoomDirectoryVisibilityTask.Params(roomId))
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setRoomDirectoryVisibility(roomId: String, roomDirectoryVisibility: RoomDirectoryVisibility) {
|
||||||
|
setRoomDirectoryVisibilityTask.execute(SetRoomDirectoryVisibilityTask.Params(roomId, roomDirectoryVisibility))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.util.toOptional
|
||||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.DeleteRoomAliasTask
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask
|
import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask
|
||||||
import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask
|
import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource
|
import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource
|
||||||
|
@ -53,6 +54,7 @@ internal class DefaultRoomService @Inject constructor(
|
||||||
private val markAllRoomsReadTask: MarkAllRoomsReadTask,
|
private val markAllRoomsReadTask: MarkAllRoomsReadTask,
|
||||||
private val updateBreadcrumbsTask: UpdateBreadcrumbsTask,
|
private val updateBreadcrumbsTask: UpdateBreadcrumbsTask,
|
||||||
private val roomIdByAliasTask: GetRoomIdByAliasTask,
|
private val roomIdByAliasTask: GetRoomIdByAliasTask,
|
||||||
|
private val deleteRoomAliasTask: DeleteRoomAliasTask,
|
||||||
private val roomGetter: RoomGetter,
|
private val roomGetter: RoomGetter,
|
||||||
private val roomSummaryDataSource: RoomSummaryDataSource,
|
private val roomSummaryDataSource: RoomSummaryDataSource,
|
||||||
private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource,
|
private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource,
|
||||||
|
@ -125,6 +127,10 @@ internal class DefaultRoomService @Inject constructor(
|
||||||
.executeBy(taskExecutor)
|
.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteRoomAlias(roomAlias: String) {
|
||||||
|
deleteRoomAliasTask.execute(DeleteRoomAliasTask.Params(roomAlias))
|
||||||
|
}
|
||||||
|
|
||||||
override fun getChangeMembershipsLive(): LiveData<Map<String, ChangeMembershipState>> {
|
override fun getChangeMembershipsLive(): LiveData<Map<String, ChangeMembershipState>> {
|
||||||
return roomChangeMembershipStateDataSource.getLiveStates()
|
return roomChangeMembershipStateDataSource.getLiveStates()
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,7 @@ import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsRe
|
||||||
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||||
import org.matrix.android.sdk.api.util.JsonDict
|
import org.matrix.android.sdk.api.util.JsonDict
|
||||||
import org.matrix.android.sdk.internal.network.NetworkConstants
|
import org.matrix.android.sdk.internal.network.NetworkConstants
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.AddRoomAliasBody
|
import org.matrix.android.sdk.internal.session.room.alias.GetAliasesResponse
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription
|
|
||||||
import org.matrix.android.sdk.internal.session.room.create.CreateRoomBody
|
import org.matrix.android.sdk.internal.session.room.create.CreateRoomBody
|
||||||
import org.matrix.android.sdk.internal.session.room.create.CreateRoomResponse
|
import org.matrix.android.sdk.internal.session.room.create.CreateRoomResponse
|
||||||
import org.matrix.android.sdk.internal.session.room.create.JoinRoomResponse
|
import org.matrix.android.sdk.internal.session.room.create.JoinRoomResponse
|
||||||
|
@ -321,20 +320,11 @@ internal interface RoomAPI {
|
||||||
@Body body: ReportContentBody): Call<Unit>
|
@Body body: ReportContentBody): Call<Unit>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the room ID associated to the room alias.
|
* 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
|
||||||
* @param roomAlias the room alias.
|
|
||||||
*/
|
*/
|
||||||
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/room/{roomAlias}")
|
@GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "org.matrix.msc2432/rooms/{roomId}/aliases")
|
||||||
fun getRoomIdByAlias(@Path("roomAlias") roomAlias: String): Call<RoomAliasDescription>
|
fun getAliases(@Path("roomId") roomId: String): Call<GetAliasesResponse>
|
||||||
|
|
||||||
/**
|
|
||||||
* Add alias to the room.
|
|
||||||
* @param roomAlias the room alias.
|
|
||||||
*/
|
|
||||||
@PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/room/{roomAlias}")
|
|
||||||
fun addRoomAlias(@Path("roomAlias") roomAlias: String,
|
|
||||||
@Body body: AddRoomAliasBody): Call<Unit>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inform that the user is starting to type or has stopped typing
|
* Inform that the user is starting to type or has stopped typing
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.room
|
||||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.DefaultAliasService
|
||||||
import org.matrix.android.sdk.internal.session.room.call.DefaultRoomCallService
|
import org.matrix.android.sdk.internal.session.room.call.DefaultRoomCallService
|
||||||
import org.matrix.android.sdk.internal.session.room.draft.DefaultDraftService
|
import org.matrix.android.sdk.internal.session.room.draft.DefaultDraftService
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.DefaultMembershipService
|
import org.matrix.android.sdk.internal.session.room.membership.DefaultMembershipService
|
||||||
|
@ -54,6 +55,7 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService:
|
||||||
private val roomCallServiceFactory: DefaultRoomCallService.Factory,
|
private val roomCallServiceFactory: DefaultRoomCallService.Factory,
|
||||||
private val readServiceFactory: DefaultReadService.Factory,
|
private val readServiceFactory: DefaultReadService.Factory,
|
||||||
private val typingServiceFactory: DefaultTypingService.Factory,
|
private val typingServiceFactory: DefaultTypingService.Factory,
|
||||||
|
private val aliasServiceFactory: DefaultAliasService.Factory,
|
||||||
private val tagsServiceFactory: DefaultTagsService.Factory,
|
private val tagsServiceFactory: DefaultTagsService.Factory,
|
||||||
private val relationServiceFactory: DefaultRelationService.Factory,
|
private val relationServiceFactory: DefaultRelationService.Factory,
|
||||||
private val membershipServiceFactory: DefaultMembershipService.Factory,
|
private val membershipServiceFactory: DefaultMembershipService.Factory,
|
||||||
|
@ -76,6 +78,7 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService:
|
||||||
roomCallService = roomCallServiceFactory.create(roomId),
|
roomCallService = roomCallServiceFactory.create(roomId),
|
||||||
readService = readServiceFactory.create(roomId),
|
readService = readServiceFactory.create(roomId),
|
||||||
typingService = typingServiceFactory.create(roomId),
|
typingService = typingServiceFactory.create(roomId),
|
||||||
|
aliasService = aliasServiceFactory.create(roomId),
|
||||||
tagsService = tagsServiceFactory.create(roomId),
|
tagsService = tagsServiceFactory.create(roomId),
|
||||||
cryptoService = cryptoService,
|
cryptoService = cryptoService,
|
||||||
relationService = relationServiceFactory.create(roomId),
|
relationService = relationServiceFactory.create(roomId),
|
||||||
|
|
|
@ -26,16 +26,25 @@ import org.matrix.android.sdk.api.session.room.RoomDirectoryService
|
||||||
import org.matrix.android.sdk.api.session.room.RoomService
|
import org.matrix.android.sdk.api.session.room.RoomService
|
||||||
import org.matrix.android.sdk.internal.session.DefaultFileService
|
import org.matrix.android.sdk.internal.session.DefaultFileService
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
|
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.AddRoomAliasTask
|
import org.matrix.android.sdk.internal.session.room.alias.AddRoomAliasTask
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.DefaultAddRoomAliasTask
|
import org.matrix.android.sdk.internal.session.room.alias.DefaultAddRoomAliasTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.DefaultDeleteRoomAliasTask
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.DefaultGetRoomIdByAliasTask
|
import org.matrix.android.sdk.internal.session.room.alias.DefaultGetRoomIdByAliasTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.DefaultGetRoomLocalAliasesTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.DeleteRoomAliasTask
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask
|
import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.GetRoomLocalAliasesTask
|
||||||
import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask
|
import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask
|
||||||
import org.matrix.android.sdk.internal.session.room.create.DefaultCreateRoomTask
|
import org.matrix.android.sdk.internal.session.room.create.DefaultCreateRoomTask
|
||||||
import org.matrix.android.sdk.internal.session.room.directory.DefaultGetPublicRoomTask
|
import org.matrix.android.sdk.internal.session.room.directory.DefaultGetPublicRoomTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.directory.DefaultGetRoomDirectoryVisibilityTask
|
||||||
import org.matrix.android.sdk.internal.session.room.directory.DefaultGetThirdPartyProtocolsTask
|
import org.matrix.android.sdk.internal.session.room.directory.DefaultGetThirdPartyProtocolsTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.directory.DefaultSetRoomDirectoryVisibilityTask
|
||||||
import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
|
import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask
|
||||||
import org.matrix.android.sdk.internal.session.room.directory.GetThirdPartyProtocolsTask
|
import org.matrix.android.sdk.internal.session.room.directory.GetThirdPartyProtocolsTask
|
||||||
|
import org.matrix.android.sdk.internal.session.room.directory.SetRoomDirectoryVisibilityTask
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.DefaultLoadRoomMembersTask
|
import org.matrix.android.sdk.internal.session.room.membership.DefaultLoadRoomMembersTask
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.admin.DefaultMembershipAdminTask
|
import org.matrix.android.sdk.internal.session.room.membership.admin.DefaultMembershipAdminTask
|
||||||
|
@ -90,6 +99,13 @@ internal abstract class RoomModule {
|
||||||
return retrofit.create(RoomAPI::class.java)
|
return retrofit.create(RoomAPI::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@JvmStatic
|
||||||
|
@SessionScope
|
||||||
|
fun providesDirectoryAPI(retrofit: Retrofit): DirectoryAPI {
|
||||||
|
return retrofit.create(DirectoryAPI::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun providesParser(): Parser {
|
fun providesParser(): Parser {
|
||||||
|
@ -127,6 +143,12 @@ internal abstract class RoomModule {
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindGetPublicRoomTask(task: DefaultGetPublicRoomTask): GetPublicRoomTask
|
abstract fun bindGetPublicRoomTask(task: DefaultGetPublicRoomTask): GetPublicRoomTask
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindGetRoomDirectoryVisibilityTask(task: DefaultGetRoomDirectoryVisibilityTask): GetRoomDirectoryVisibilityTask
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindSetRoomDirectoryVisibilityTask(task: DefaultSetRoomDirectoryVisibilityTask): SetRoomDirectoryVisibilityTask
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindGetThirdPartyProtocolsTask(task: DefaultGetThirdPartyProtocolsTask): GetThirdPartyProtocolsTask
|
abstract fun bindGetThirdPartyProtocolsTask(task: DefaultGetThirdPartyProtocolsTask): GetThirdPartyProtocolsTask
|
||||||
|
|
||||||
|
@ -181,9 +203,15 @@ internal abstract class RoomModule {
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindGetRoomIdByAliasTask(task: DefaultGetRoomIdByAliasTask): GetRoomIdByAliasTask
|
abstract fun bindGetRoomIdByAliasTask(task: DefaultGetRoomIdByAliasTask): GetRoomIdByAliasTask
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindGetRoomLocalAliasesTask(task: DefaultGetRoomLocalAliasesTask): GetRoomLocalAliasesTask
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindAddRoomAliasTask(task: DefaultAddRoomAliasTask): AddRoomAliasTask
|
abstract fun bindAddRoomAliasTask(task: DefaultAddRoomAliasTask): AddRoomAliasTask
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindDeleteRoomAliasTask(task: DefaultDeleteRoomAliasTask): DeleteRoomAliasTask
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindSendTypingTask(task: DefaultSendTypingTask): SendTypingTask
|
abstract fun bindSendTypingTask(task: DefaultSendTypingTask): SendTypingTask
|
||||||
|
|
||||||
|
|
|
@ -16,28 +16,38 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.session.room.alias
|
package org.matrix.android.sdk.internal.session.room.alias
|
||||||
|
|
||||||
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 org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.matrix.android.sdk.internal.di.UserId
|
||||||
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
|
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
|
||||||
|
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasAvailabilityChecker.Companion.toFullLocalAlias
|
||||||
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal interface AddRoomAliasTask : Task<AddRoomAliasTask.Params, Unit> {
|
internal interface AddRoomAliasTask : Task<AddRoomAliasTask.Params, Unit> {
|
||||||
data class Params(
|
data class Params(
|
||||||
val roomId: String,
|
val roomId: String,
|
||||||
val roomAlias: String
|
/**
|
||||||
|
* the local part of the alias.
|
||||||
|
* Ex: for the alias "#my_alias:example.org", the local part is "my_alias"
|
||||||
|
*/
|
||||||
|
val aliasLocalPart: String
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class DefaultAddRoomAliasTask @Inject constructor(
|
internal class DefaultAddRoomAliasTask @Inject constructor(
|
||||||
private val roomAPI: RoomAPI,
|
@UserId private val userId: String,
|
||||||
|
private val directoryAPI: DirectoryAPI,
|
||||||
|
private val aliasAvailabilityChecker: RoomAliasAvailabilityChecker,
|
||||||
private val eventBus: EventBus
|
private val eventBus: EventBus
|
||||||
) : AddRoomAliasTask {
|
) : AddRoomAliasTask {
|
||||||
|
|
||||||
override suspend fun execute(params: AddRoomAliasTask.Params) {
|
override suspend fun execute(params: AddRoomAliasTask.Params) {
|
||||||
|
aliasAvailabilityChecker.check(params.aliasLocalPart)
|
||||||
|
|
||||||
executeRequest<Unit>(eventBus) {
|
executeRequest<Unit>(eventBus) {
|
||||||
apiCall = roomAPI.addRoomAlias(
|
apiCall = directoryAPI.addRoomAlias(
|
||||||
roomAlias = params.roomAlias,
|
roomAlias = params.aliasLocalPart.toFullLocalAlias(userId),
|
||||||
body = AddRoomAliasBody(
|
body = AddRoomAliasBody(
|
||||||
roomId = params.roomId
|
roomId = params.roomId
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.alias
|
||||||
|
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.AliasService
|
||||||
|
|
||||||
|
internal class DefaultAliasService @AssistedInject constructor(
|
||||||
|
@Assisted private val roomId: String,
|
||||||
|
private val getRoomLocalAliasesTask: GetRoomLocalAliasesTask,
|
||||||
|
private val addRoomAliasTask: AddRoomAliasTask
|
||||||
|
) : AliasService {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(roomId: String): AliasService
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getRoomAliases(): List<String> {
|
||||||
|
return getRoomLocalAliasesTask.execute(GetRoomLocalAliasesTask.Params(roomId))
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun addAlias(aliasLocalPart: String) {
|
||||||
|
addRoomAliasTask.execute(AddRoomAliasTask.Params(roomId, aliasLocalPart))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.alias
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
|
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
|
||||||
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
internal interface DeleteRoomAliasTask : Task<DeleteRoomAliasTask.Params, Unit> {
|
||||||
|
data class Params(
|
||||||
|
val roomAlias: String
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DefaultDeleteRoomAliasTask @Inject constructor(
|
||||||
|
private val directoryAPI: DirectoryAPI,
|
||||||
|
private val eventBus: EventBus
|
||||||
|
) : DeleteRoomAliasTask {
|
||||||
|
|
||||||
|
override suspend fun execute(params: DeleteRoomAliasTask.Params) {
|
||||||
|
executeRequest<Unit>(eventBus) {
|
||||||
|
apiCall = directoryAPI.deleteRoomAlias(
|
||||||
|
roomAlias = params.roomAlias
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.alias
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
internal data class GetAliasesResponse(
|
||||||
|
/**
|
||||||
|
* Required. The server's local aliases on the room. Can be empty.
|
||||||
|
*/
|
||||||
|
@Json(name = "aliases") val aliases: List<String> = emptyList()
|
||||||
|
)
|
|
@ -25,7 +25,7 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.query.findByAlias
|
import org.matrix.android.sdk.internal.database.query.findByAlias
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.network.executeRequest
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
import org.matrix.android.sdk.internal.session.room.RoomAPI
|
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
|
||||||
import org.matrix.android.sdk.internal.task.Task
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ internal interface GetRoomIdByAliasTask : Task<GetRoomIdByAliasTask.Params, Opti
|
||||||
|
|
||||||
internal class DefaultGetRoomIdByAliasTask @Inject constructor(
|
internal class DefaultGetRoomIdByAliasTask @Inject constructor(
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
private val roomAPI: RoomAPI,
|
private val directoryAPI: DirectoryAPI,
|
||||||
private val eventBus: EventBus
|
private val eventBus: EventBus
|
||||||
) : GetRoomIdByAliasTask {
|
) : GetRoomIdByAliasTask {
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ internal class DefaultGetRoomIdByAliasTask @Inject constructor(
|
||||||
} else {
|
} else {
|
||||||
roomId = tryOrNull("## Failed to get roomId from alias") {
|
roomId = tryOrNull("## Failed to get roomId from alias") {
|
||||||
executeRequest<RoomAliasDescription>(eventBus) {
|
executeRequest<RoomAliasDescription>(eventBus) {
|
||||||
apiCall = roomAPI.getRoomIdByAlias(params.roomAlias)
|
apiCall = directoryAPI.getRoomIdByAlias(params.roomAlias)
|
||||||
}
|
}
|
||||||
}?.roomId
|
}?.roomId
|
||||||
Optional.from(roomId)
|
Optional.from(roomId)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.alias
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
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 GetRoomLocalAliasesTask : Task<GetRoomLocalAliasesTask.Params, List<String>> {
|
||||||
|
data class Params(
|
||||||
|
val roomId: String
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DefaultGetRoomLocalAliasesTask @Inject constructor(
|
||||||
|
private val roomAPI: RoomAPI,
|
||||||
|
private val eventBus: EventBus
|
||||||
|
) : GetRoomLocalAliasesTask {
|
||||||
|
|
||||||
|
override suspend fun execute(params: GetRoomLocalAliasesTask.Params): List<String> {
|
||||||
|
// We do not check for "org.matrix.msc2432", so the API may be missing
|
||||||
|
val response = executeRequest<GetAliasesResponse>(eventBus) {
|
||||||
|
apiCall = roomAPI.getAliases(roomId = params.roomId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.aliases
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.alias
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.matrix.android.sdk.api.failure.Failure
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
|
||||||
|
import org.matrix.android.sdk.internal.di.UserId
|
||||||
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
|
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
internal class RoomAliasAvailabilityChecker @Inject constructor(
|
||||||
|
@UserId private val userId: String,
|
||||||
|
private val directoryAPI: DirectoryAPI,
|
||||||
|
private val eventBus: EventBus
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* @param aliasLocalPart the local part of the alias.
|
||||||
|
* Ex: for the alias "#my_alias:example.org", the local part is "my_alias"
|
||||||
|
*/
|
||||||
|
@Throws(RoomAliasError::class)
|
||||||
|
suspend fun check(aliasLocalPart: String?) {
|
||||||
|
if (aliasLocalPart.isNullOrEmpty()) {
|
||||||
|
throw RoomAliasError.AliasEmpty
|
||||||
|
}
|
||||||
|
// Check alias availability
|
||||||
|
val fullAlias = aliasLocalPart.toFullLocalAlias(userId)
|
||||||
|
try {
|
||||||
|
executeRequest<RoomAliasDescription>(eventBus) {
|
||||||
|
apiCall = directoryAPI.getRoomIdByAlias(fullAlias)
|
||||||
|
}
|
||||||
|
} catch (throwable: Throwable) {
|
||||||
|
if (throwable is Failure.ServerError && throwable.httpCode == 404) {
|
||||||
|
// This is a 404, so the alias is available: nominal case
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
// Other error, propagate it
|
||||||
|
throw throwable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?.let {
|
||||||
|
// Alias already exists: error case
|
||||||
|
throw RoomAliasError.AliasNotAvailable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal fun String.toFullLocalAlias(userId: String) = "#" + this + ":" + userId.substringAfter(":")
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import kotlinx.coroutines.TimeoutCancellationException
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
import org.matrix.android.sdk.api.failure.Failure
|
||||||
import org.matrix.android.sdk.api.failure.MatrixError
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
|
||||||
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
|
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
|
||||||
|
@ -31,10 +32,9 @@ import org.matrix.android.sdk.internal.database.model.RoomEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
|
||||||
import org.matrix.android.sdk.internal.network.executeRequest
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
import org.matrix.android.sdk.internal.session.room.RoomAPI
|
import org.matrix.android.sdk.internal.session.room.RoomAPI
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription
|
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasAvailabilityChecker
|
||||||
import org.matrix.android.sdk.internal.session.room.read.SetReadMarkersTask
|
import org.matrix.android.sdk.internal.session.room.read.SetReadMarkersTask
|
||||||
import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper
|
import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper
|
||||||
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
|
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
|
||||||
|
@ -47,8 +47,8 @@ internal interface CreateRoomTask : Task<CreateRoomParams, String>
|
||||||
|
|
||||||
internal class DefaultCreateRoomTask @Inject constructor(
|
internal class DefaultCreateRoomTask @Inject constructor(
|
||||||
private val roomAPI: RoomAPI,
|
private val roomAPI: RoomAPI,
|
||||||
@UserId private val userId: String,
|
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val aliasAvailabilityChecker: RoomAliasAvailabilityChecker,
|
||||||
private val directChatsHelper: DirectChatsHelper,
|
private val directChatsHelper: DirectChatsHelper,
|
||||||
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
|
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
|
||||||
private val readMarkersTask: SetReadMarkersTask,
|
private val readMarkersTask: SetReadMarkersTask,
|
||||||
|
@ -65,28 +65,11 @@ internal class DefaultCreateRoomTask @Inject constructor(
|
||||||
} else null
|
} else null
|
||||||
|
|
||||||
if (params.preset == CreateRoomPreset.PRESET_PUBLIC_CHAT) {
|
if (params.preset == CreateRoomPreset.PRESET_PUBLIC_CHAT) {
|
||||||
if (params.roomAliasName.isNullOrEmpty()) {
|
|
||||||
throw CreateRoomFailure.RoomAliasError.AliasEmpty
|
|
||||||
}
|
|
||||||
// Check alias availability
|
|
||||||
val fullAlias = "#" + params.roomAliasName + ":" + userId.substringAfter(":")
|
|
||||||
try {
|
try {
|
||||||
executeRequest<RoomAliasDescription>(eventBus) {
|
aliasAvailabilityChecker.check(params.roomAliasName)
|
||||||
apiCall = roomAPI.getRoomIdByAlias(fullAlias)
|
} catch (aliasError: RoomAliasError) {
|
||||||
}
|
throw CreateRoomFailure.AliasError(aliasError)
|
||||||
} catch (throwable: Throwable) {
|
|
||||||
if (throwable is Failure.ServerError && throwable.httpCode == 404) {
|
|
||||||
// This is a 404, so the alias is available: nominal case
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
// Other error, propagate it
|
|
||||||
throw throwable
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
?.let {
|
|
||||||
// Alias already exists: error case
|
|
||||||
throw CreateRoomFailure.RoomAliasError.AliasNotAvailable
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val createRoomBody = createRoomBodyBuilder.build(params)
|
val createRoomBody = createRoomBodyBuilder.build(params)
|
||||||
|
@ -104,7 +87,7 @@ internal class DefaultCreateRoomTask @Inject constructor(
|
||||||
} else if (throwable.httpCode == 400
|
} else if (throwable.httpCode == 400
|
||||||
&& throwable.error.code == MatrixError.M_UNKNOWN
|
&& throwable.error.code == MatrixError.M_UNKNOWN
|
||||||
&& throwable.error.message == "Invalid characters in room alias") {
|
&& throwable.error.message == "Invalid characters in room alias") {
|
||||||
throw CreateRoomFailure.RoomAliasError.AliasInvalid
|
throw CreateRoomFailure.AliasError(RoomAliasError.AliasInvalid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw throwable
|
throw throwable
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.directory
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
|
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
|
||||||
|
import org.matrix.android.sdk.internal.session.directory.RoomDirectoryVisibilityJson
|
||||||
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
internal interface GetRoomDirectoryVisibilityTask : Task<GetRoomDirectoryVisibilityTask.Params, RoomDirectoryVisibility> {
|
||||||
|
data class Params(
|
||||||
|
val roomId: String
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DefaultGetRoomDirectoryVisibilityTask @Inject constructor(
|
||||||
|
private val directoryAPI: DirectoryAPI,
|
||||||
|
private val eventBus: EventBus
|
||||||
|
) : GetRoomDirectoryVisibilityTask {
|
||||||
|
|
||||||
|
override suspend fun execute(params: GetRoomDirectoryVisibilityTask.Params): RoomDirectoryVisibility {
|
||||||
|
return executeRequest<RoomDirectoryVisibilityJson>(eventBus) {
|
||||||
|
apiCall = directoryAPI.getRoomDirectoryVisibility(params.roomId)
|
||||||
|
}
|
||||||
|
.visibility
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.directory
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
|
import org.matrix.android.sdk.internal.session.directory.DirectoryAPI
|
||||||
|
import org.matrix.android.sdk.internal.session.directory.RoomDirectoryVisibilityJson
|
||||||
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
internal interface SetRoomDirectoryVisibilityTask : Task<SetRoomDirectoryVisibilityTask.Params, Unit> {
|
||||||
|
data class Params(
|
||||||
|
val roomId: String,
|
||||||
|
val roomDirectoryVisibility: RoomDirectoryVisibility
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DefaultSetRoomDirectoryVisibilityTask @Inject constructor(
|
||||||
|
private val directoryAPI: DirectoryAPI,
|
||||||
|
private val eventBus: EventBus
|
||||||
|
) : SetRoomDirectoryVisibilityTask {
|
||||||
|
|
||||||
|
override suspend fun execute(params: SetRoomDirectoryVisibilityTask.Params) {
|
||||||
|
executeRequest<Unit>(eventBus) {
|
||||||
|
apiCall = directoryAPI.setRoomDirectoryVisibility(
|
||||||
|
params.roomId,
|
||||||
|
RoomDirectoryVisibilityJson(visibility = params.roomDirectoryVisibility)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,7 +21,6 @@ import org.matrix.android.sdk.R
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomAliasesContent
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent
|
import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomNameContent
|
import org.matrix.android.sdk.api.session.room.model.RoomNameContent
|
||||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
||||||
|
@ -71,12 +70,6 @@ internal class RoomDisplayNameResolver @Inject constructor(
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
val aliases = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_ALIASES, stateKey = "")?.root
|
|
||||||
name = ContentMapper.map(aliases?.content).toModel<RoomAliasesContent>()?.aliases?.firstOrNull()
|
|
||||||
if (!name.isNullOrEmpty()) {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
val roomMembers = RoomMemberHelper(realm, roomId)
|
val roomMembers = RoomMemberHelper(realm, roomId)
|
||||||
val activeMembers = roomMembers.queryActiveRoomMembersEvent().findAll()
|
val activeMembers = roomMembers.queryActiveRoomMembersEvent().findAll()
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ import org.matrix.android.sdk.api.MatrixCallback
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
|
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
|
||||||
import org.matrix.android.sdk.api.session.room.state.StateService
|
import org.matrix.android.sdk.api.session.room.state.StateService
|
||||||
import org.matrix.android.sdk.api.util.Cancelable
|
import org.matrix.android.sdk.api.util.Cancelable
|
||||||
|
@ -104,18 +106,19 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addRoomAlias(roomAlias: String, callback: MatrixCallback<Unit>): Cancelable {
|
override fun updateCanonicalAlias(alias: String?, altAliases: List<String>, callback: MatrixCallback<Unit>): Cancelable {
|
||||||
return addRoomAliasTask
|
|
||||||
.configureWith(AddRoomAliasTask.Params(roomId, roomAlias)) {
|
|
||||||
this.callback = callback
|
|
||||||
}
|
|
||||||
.executeBy(taskExecutor)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun updateCanonicalAlias(alias: String, callback: MatrixCallback<Unit>): Cancelable {
|
|
||||||
return sendStateEvent(
|
return sendStateEvent(
|
||||||
eventType = EventType.STATE_ROOM_CANONICAL_ALIAS,
|
eventType = EventType.STATE_ROOM_CANONICAL_ALIAS,
|
||||||
body = mapOf("alias" to alias),
|
body = RoomCanonicalAliasContent(
|
||||||
|
canonicalAlias = alias,
|
||||||
|
alternativeAliases = altAliases
|
||||||
|
// Ensure there is no duplicate
|
||||||
|
.distinct()
|
||||||
|
// Ensure the canonical alias is not also included in the alt alias
|
||||||
|
.minus(listOfNotNull(alias))
|
||||||
|
// Sort for the cleanup
|
||||||
|
.sorted()
|
||||||
|
).toContent(),
|
||||||
callback = callback,
|
callback = callback,
|
||||||
stateKey = null
|
stateKey = null
|
||||||
)
|
)
|
||||||
|
|
|
@ -246,7 +246,7 @@
|
||||||
|
|
||||||
<plurals name="notice_room_aliases_removed">
|
<plurals name="notice_room_aliases_removed">
|
||||||
<item quantity="one">%1$s removed %2$s as an address for this room.</item>
|
<item quantity="one">%1$s removed %2$s as an address for this room.</item>
|
||||||
<item quantity="other">%1$s removed %3$s as addresses for this room.</item>
|
<item quantity="other">%1$s removed %2$s as addresses for this room.</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<plurals name="notice_room_aliases_removed_by_you">
|
<plurals name="notice_room_aliases_removed_by_you">
|
||||||
|
@ -262,6 +262,33 @@
|
||||||
<string name="notice_room_canonical_alias_unset">"%1$s removed the main address for this room."</string>
|
<string name="notice_room_canonical_alias_unset">"%1$s removed the main address for this room."</string>
|
||||||
<string name="notice_room_canonical_alias_unset_by_you">"You removed the main address for this room."</string>
|
<string name="notice_room_canonical_alias_unset_by_you">"You removed the main address for this room."</string>
|
||||||
|
|
||||||
|
<plurals name="notice_room_canonical_alias_alternative_added">
|
||||||
|
<item quantity="one">%1$s added the alternative address %2$s for this room.</item>
|
||||||
|
<item quantity="other">%1$s added the alternative addresses %2$s for this room.</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<plurals name="notice_room_canonical_alias_alternative_added_by_you">
|
||||||
|
<item quantity="one">You added the alternative address %1$s for this room.</item>
|
||||||
|
<item quantity="other">You added the alternative addresses %1$s for this room.</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<plurals name="notice_room_canonical_alias_alternative_removed">
|
||||||
|
<item quantity="one">%1$s removed the alternative address %2$s for this room.</item>
|
||||||
|
<item quantity="other">%1$s removed the alternative addresses %2$s for this room.</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<plurals name="notice_room_canonical_alias_alternative_removed_by_you">
|
||||||
|
<item quantity="one">You removed the alternative address %1$s for this room.</item>
|
||||||
|
<item quantity="other">You removed the alternative addresses %1$s for this room.</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<string name="notice_room_canonical_alias_alternative_changed">%1$s changed the alternative addresses for this room.</string>
|
||||||
|
<string name="notice_room_canonical_alias_alternative_changed_by_you">You changed the alternative addresses for this room.</string>
|
||||||
|
<string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s changed the main and alternative addresses for this room.</string>
|
||||||
|
<string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">You changed the main and alternative addresses for this room.</string>
|
||||||
|
<string name="notice_room_canonical_alias_no_change">%1$s changed the addresses for this room.</string>
|
||||||
|
<string name="notice_room_canonical_alias_no_change_by_you">You changed the addresses for this room.</string>
|
||||||
|
|
||||||
<string name="notice_room_guest_access_can_join">"%1$s has allowed guests to join the room."</string>
|
<string name="notice_room_guest_access_can_join">"%1$s has allowed guests to join the room."</string>
|
||||||
<string name="notice_room_guest_access_can_join_by_you">"You have allowed guests to join the room."</string>
|
<string name="notice_room_guest_access_can_join_by_you">"You have allowed guests to join the room."</string>
|
||||||
<string name="notice_direct_room_guest_access_can_join">"%1$s has allowed guests to join here."</string>
|
<string name="notice_direct_room_guest_access_can_join">"%1$s has allowed guests to join here."</string>
|
||||||
|
|
|
@ -84,6 +84,7 @@ import im.vector.app.features.roomprofile.RoomProfileFragment
|
||||||
import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment
|
import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment
|
||||||
import im.vector.app.features.roomprofile.members.RoomMemberListFragment
|
import im.vector.app.features.roomprofile.members.RoomMemberListFragment
|
||||||
import im.vector.app.features.roomprofile.settings.RoomSettingsFragment
|
import im.vector.app.features.roomprofile.settings.RoomSettingsFragment
|
||||||
|
import im.vector.app.features.roomprofile.alias.RoomAliasFragment
|
||||||
import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment
|
import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment
|
||||||
import im.vector.app.features.roomprofile.uploads.files.RoomUploadsFilesFragment
|
import im.vector.app.features.roomprofile.uploads.files.RoomUploadsFilesFragment
|
||||||
import im.vector.app.features.roomprofile.uploads.media.RoomUploadsMediaFragment
|
import im.vector.app.features.roomprofile.uploads.media.RoomUploadsMediaFragment
|
||||||
|
@ -364,6 +365,11 @@ interface FragmentModule {
|
||||||
@FragmentKey(RoomSettingsFragment::class)
|
@FragmentKey(RoomSettingsFragment::class)
|
||||||
fun bindRoomSettingsFragment(fragment: RoomSettingsFragment): Fragment
|
fun bindRoomSettingsFragment(fragment: RoomSettingsFragment): Fragment
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@FragmentKey(RoomAliasFragment::class)
|
||||||
|
fun bindRoomAliasFragment(fragment: RoomAliasFragment): Fragment
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@FragmentKey(RoomMemberProfileFragment::class)
|
@FragmentKey(RoomMemberProfileFragment::class)
|
||||||
|
|
|
@ -67,6 +67,7 @@ import im.vector.app.features.roomdirectory.createroom.CreateRoomActivity
|
||||||
import im.vector.app.features.roommemberprofile.RoomMemberProfileActivity
|
import im.vector.app.features.roommemberprofile.RoomMemberProfileActivity
|
||||||
import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet
|
import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet
|
||||||
import im.vector.app.features.roomprofile.RoomProfileActivity
|
import im.vector.app.features.roomprofile.RoomProfileActivity
|
||||||
|
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheet
|
||||||
import im.vector.app.features.settings.VectorSettingsActivity
|
import im.vector.app.features.settings.VectorSettingsActivity
|
||||||
import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheet
|
import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheet
|
||||||
import im.vector.app.features.share.IncomingShareActivity
|
import im.vector.app.features.share.IncomingShareActivity
|
||||||
|
@ -153,6 +154,7 @@ interface ScreenComponent {
|
||||||
fun inject(bottomSheet: ViewEditHistoryBottomSheet)
|
fun inject(bottomSheet: ViewEditHistoryBottomSheet)
|
||||||
fun inject(bottomSheet: DisplayReadReceiptsBottomSheet)
|
fun inject(bottomSheet: DisplayReadReceiptsBottomSheet)
|
||||||
fun inject(bottomSheet: RoomListQuickActionsBottomSheet)
|
fun inject(bottomSheet: RoomListQuickActionsBottomSheet)
|
||||||
|
fun inject(bottomSheet: RoomAliasBottomSheet)
|
||||||
fun inject(bottomSheet: VerificationBottomSheet)
|
fun inject(bottomSheet: VerificationBottomSheet)
|
||||||
fun inject(bottomSheet: DeviceVerificationInfoBottomSheet)
|
fun inject(bottomSheet: DeviceVerificationInfoBottomSheet)
|
||||||
fun inject(bottomSheet: DeviceListBottomSheet)
|
fun inject(bottomSheet: DeviceListBottomSheet)
|
||||||
|
|
|
@ -35,6 +35,7 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
|
||||||
import im.vector.app.features.reactions.EmojiChooserViewModel
|
import im.vector.app.features.reactions.EmojiChooserViewModel
|
||||||
import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel
|
import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel
|
||||||
import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel
|
import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel
|
||||||
|
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel
|
||||||
import im.vector.app.features.userdirectory.UserListSharedActionViewModel
|
import im.vector.app.features.userdirectory.UserListSharedActionViewModel
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
@ -105,6 +106,11 @@ interface ViewModelModule {
|
||||||
@ViewModelKey(RoomListQuickActionsSharedActionViewModel::class)
|
@ViewModelKey(RoomListQuickActionsSharedActionViewModel::class)
|
||||||
fun bindRoomListQuickActionsSharedActionViewModel(viewModel: RoomListQuickActionsSharedActionViewModel): ViewModel
|
fun bindRoomListQuickActionsSharedActionViewModel(viewModel: RoomListQuickActionsSharedActionViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(RoomAliasBottomSheetSharedActionViewModel::class)
|
||||||
|
fun bindRoomAliasBottomSheetSharedActionViewModel(viewModel: RoomAliasBottomSheetSharedActionViewModel): ViewModel
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@ViewModelKey(RoomDirectorySharedActionViewModel::class)
|
@ViewModelKey(RoomDirectorySharedActionViewModel::class)
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package im.vector.app.core.epoxy.profiles
|
package im.vector.app.core.epoxy.profiles
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.view.View
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
@ -26,8 +25,10 @@ import androidx.core.widget.ImageViewCompat
|
||||||
import com.airbnb.epoxy.EpoxyAttribute
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
import com.airbnb.epoxy.EpoxyModelClass
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.epoxy.ClickListener
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||||
|
import im.vector.app.core.epoxy.onClick
|
||||||
import im.vector.app.core.extensions.setTextOrHide
|
import im.vector.app.core.extensions.setTextOrHide
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
|
@ -67,11 +68,11 @@ abstract class ProfileActionItem : VectorEpoxyModel<ProfileActionItem.Holder>()
|
||||||
var destructive: Boolean = false
|
var destructive: Boolean = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var listener: View.OnClickListener? = null
|
var listener: ClickListener? = null
|
||||||
|
|
||||||
override fun bind(holder: Holder) {
|
override fun bind(holder: Holder) {
|
||||||
super.bind(holder)
|
super.bind(holder)
|
||||||
holder.view.setOnClickListener(listener)
|
holder.view.onClick(listener)
|
||||||
if (listener == null) {
|
if (listener == null) {
|
||||||
holder.view.isClickable = false
|
holder.view.isClickable = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,9 +59,7 @@ fun EpoxyController.buildProfileAction(
|
||||||
accessoryRes(accessory)
|
accessoryRes(accessory)
|
||||||
accessoryMatrixItem(accessoryMatrixItem)
|
accessoryMatrixItem(accessoryMatrixItem)
|
||||||
avatarRenderer(avatarRenderer)
|
avatarRenderer(avatarRenderer)
|
||||||
listener { _ ->
|
listener(action)
|
||||||
action?.invoke()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (divider) {
|
if (divider) {
|
||||||
|
|
|
@ -27,6 +27,9 @@ import im.vector.app.core.epoxy.onClick
|
||||||
@EpoxyModelClass(layout = R.layout.item_settings_continue_cancel)
|
@EpoxyModelClass(layout = R.layout.item_settings_continue_cancel)
|
||||||
abstract class SettingsContinueCancelItem : EpoxyModelWithHolder<SettingsContinueCancelItem.Holder>() {
|
abstract class SettingsContinueCancelItem : EpoxyModelWithHolder<SettingsContinueCancelItem.Holder>() {
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var continueText: String? = null
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var continueOnClick: ClickListener? = null
|
var continueOnClick: ClickListener? = null
|
||||||
|
|
||||||
|
@ -37,6 +40,8 @@ abstract class SettingsContinueCancelItem : EpoxyModelWithHolder<SettingsContinu
|
||||||
super.bind(holder)
|
super.bind(holder)
|
||||||
|
|
||||||
holder.cancelButton.onClick(cancelOnClick)
|
holder.cancelButton.onClick(cancelOnClick)
|
||||||
|
|
||||||
|
continueText?.let { holder.continueButton.text = it }
|
||||||
holder.continueButton.onClick(continueOnClick)
|
holder.continueButton.onClick(continueOnClick)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,8 @@ abstract class FormSwitchItem : VectorEpoxyModel<FormSwitchItem.Holder>() {
|
||||||
|
|
||||||
holder.switchView.isEnabled = enabled
|
holder.switchView.isEnabled = enabled
|
||||||
|
|
||||||
|
holder.switchView.setOnCheckedChangeListener(null)
|
||||||
holder.switchView.isChecked = switchChecked
|
holder.switchView.isChecked = switchChecked
|
||||||
|
|
||||||
holder.switchView.setOnCheckedChangeListener { _, isChecked ->
|
holder.switchView.setOnCheckedChangeListener { _, isChecked ->
|
||||||
listener?.invoke(isChecked)
|
listener?.invoke(isChecked)
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
|
||||||
EventType.STATE_ROOM_AVATAR,
|
EventType.STATE_ROOM_AVATAR,
|
||||||
EventType.STATE_ROOM_MEMBER,
|
EventType.STATE_ROOM_MEMBER,
|
||||||
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
||||||
EventType.STATE_ROOM_ALIASES,
|
|
||||||
EventType.STATE_ROOM_CANONICAL_ALIAS,
|
EventType.STATE_ROOM_CANONICAL_ALIAS,
|
||||||
EventType.STATE_ROOM_JOIN_RULES,
|
EventType.STATE_ROOM_JOIN_RULES,
|
||||||
EventType.STATE_ROOM_HISTORY_VISIBILITY,
|
EventType.STATE_ROOM_HISTORY_VISIBILITY,
|
||||||
|
@ -79,6 +78,7 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
|
||||||
encryptedItemFactory.create(event, nextEvent, highlight, callback)
|
encryptedItemFactory.create(event, nextEvent, highlight, callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EventType.STATE_ROOM_ALIASES,
|
||||||
EventType.KEY_VERIFICATION_ACCEPT,
|
EventType.KEY_VERIFICATION_ACCEPT,
|
||||||
EventType.KEY_VERIFICATION_START,
|
EventType.KEY_VERIFICATION_START,
|
||||||
EventType.KEY_VERIFICATION_KEY,
|
EventType.KEY_VERIFICATION_KEY,
|
||||||
|
|
|
@ -465,21 +465,72 @@ class NoticeEventFormatter @Inject constructor(
|
||||||
|
|
||||||
private fun formatRoomCanonicalAliasEvent(event: Event, senderName: String?): String? {
|
private fun formatRoomCanonicalAliasEvent(event: Event, senderName: String?): String? {
|
||||||
val eventContent: RoomCanonicalAliasContent? = event.getClearContent().toModel()
|
val eventContent: RoomCanonicalAliasContent? = event.getClearContent().toModel()
|
||||||
val canonicalAlias = eventContent?.canonicalAlias
|
val prevContent: RoomCanonicalAliasContent? = event.resolvedPrevContent().toModel()
|
||||||
return canonicalAlias
|
val canonicalAlias = eventContent?.canonicalAlias?.takeIf { it.isNotEmpty() }
|
||||||
?.takeIf { it.isNotBlank() }
|
val prevCanonicalAlias = prevContent?.canonicalAlias?.takeIf { it.isNotEmpty() }
|
||||||
?.let {
|
val altAliases = eventContent?.alternativeAliases.orEmpty()
|
||||||
|
val prevAltAliases = prevContent?.alternativeAliases.orEmpty()
|
||||||
|
val added = altAliases - prevAltAliases
|
||||||
|
val removed = prevAltAliases - altAliases
|
||||||
|
|
||||||
|
return when {
|
||||||
|
added.isEmpty() && removed.isEmpty() && canonicalAlias == prevCanonicalAlias -> {
|
||||||
|
// No difference between the two events say something as we can't simply hide the event from here
|
||||||
|
if (event.isSentByCurrentUser()) {
|
||||||
|
sp.getString(R.string.notice_room_canonical_alias_no_change_by_you)
|
||||||
|
} else {
|
||||||
|
sp.getString(R.string.notice_room_canonical_alias_no_change, senderName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
added.isEmpty() && removed.isEmpty() -> {
|
||||||
|
// Canonical has changed
|
||||||
|
if (canonicalAlias != null) {
|
||||||
if (event.isSentByCurrentUser()) {
|
if (event.isSentByCurrentUser()) {
|
||||||
sp.getString(R.string.notice_room_canonical_alias_set_by_you, it)
|
sp.getString(R.string.notice_room_canonical_alias_set_by_you, canonicalAlias)
|
||||||
} else {
|
} else {
|
||||||
sp.getString(R.string.notice_room_canonical_alias_set, senderName, it)
|
sp.getString(R.string.notice_room_canonical_alias_set, senderName, canonicalAlias)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (event.isSentByCurrentUser()) {
|
||||||
|
sp.getString(R.string.notice_room_canonical_alias_unset_by_you)
|
||||||
|
} else {
|
||||||
|
sp.getString(R.string.notice_room_canonical_alias_unset, senderName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?: if (event.isSentByCurrentUser()) {
|
}
|
||||||
sp.getString(R.string.notice_room_canonical_alias_unset_by_you)
|
added.isEmpty() && canonicalAlias == prevCanonicalAlias -> {
|
||||||
|
// Some alternative has been removed
|
||||||
|
if (event.isSentByCurrentUser()) {
|
||||||
|
sp.getQuantityString(R.plurals.notice_room_canonical_alias_alternative_removed_by_you, removed.size, removed.joinToString())
|
||||||
} else {
|
} else {
|
||||||
sp.getString(R.string.notice_room_canonical_alias_unset, senderName)
|
sp.getQuantityString(R.plurals.notice_room_canonical_alias_alternative_removed, removed.size, senderName, removed.joinToString())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
removed.isEmpty() && canonicalAlias == prevCanonicalAlias -> {
|
||||||
|
// Some alternative has been added
|
||||||
|
if (event.isSentByCurrentUser()) {
|
||||||
|
sp.getQuantityString(R.plurals.notice_room_canonical_alias_alternative_added_by_you, added.size, added.joinToString())
|
||||||
|
} else {
|
||||||
|
sp.getQuantityString(R.plurals.notice_room_canonical_alias_alternative_added, added.size, senderName, added.joinToString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canonicalAlias == prevCanonicalAlias -> {
|
||||||
|
// Alternative added and removed
|
||||||
|
if (event.isSentByCurrentUser()) {
|
||||||
|
sp.getString(R.string.notice_room_canonical_alias_alternative_changed_by_you)
|
||||||
|
} else {
|
||||||
|
sp.getString(R.string.notice_room_canonical_alias_alternative_changed, senderName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// Main and removed, or main and added, or main and added and removed
|
||||||
|
if (event.isSentByCurrentUser()) {
|
||||||
|
sp.getString(R.string.notice_room_canonical_alias_main_and_alternative_changed_by_you)
|
||||||
|
} else {
|
||||||
|
sp.getString(R.string.notice_room_canonical_alias_main_and_alternative_changed, senderName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun formatRoomGuestAccessEvent(event: Event, senderName: String?, rs: RoomSummary?): String? {
|
private fun formatRoomGuestAccessEvent(event: Event, senderName: String?, rs: RoomSummary?): String? {
|
||||||
|
|
|
@ -77,6 +77,7 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
recyclerView.cleanup()
|
recyclerView.cleanup()
|
||||||
|
roomListActionsEpoxyController.listener = null
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import com.airbnb.epoxy.TypedEpoxyController
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.Loading
|
import com.airbnb.mvrx.Loading
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.error.ErrorFormatter
|
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.discovery.settingsSectionTitleItem
|
import im.vector.app.features.discovery.settingsSectionTitleItem
|
||||||
import im.vector.app.features.form.formAdvancedToggleItem
|
import im.vector.app.features.form.formAdvancedToggleItem
|
||||||
|
@ -31,8 +30,9 @@ import im.vector.app.features.form.formSwitchItem
|
||||||
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CreateRoomController @Inject constructor(private val stringProvider: StringProvider,
|
class CreateRoomController @Inject constructor(
|
||||||
private val errorFormatter: ErrorFormatter
|
private val stringProvider: StringProvider,
|
||||||
|
private val roomAliasErrorFormatter: RoomAliasErrorFormatter
|
||||||
) : TypedEpoxyController<CreateRoomViewState>() {
|
) : TypedEpoxyController<CreateRoomViewState>() {
|
||||||
|
|
||||||
var listener: Listener? = null
|
var listener: Listener? = null
|
||||||
|
@ -104,13 +104,8 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin
|
||||||
value(viewState.roomType.aliasLocalPart)
|
value(viewState.roomType.aliasLocalPart)
|
||||||
homeServer(":" + viewState.homeServerName)
|
homeServer(":" + viewState.homeServerName)
|
||||||
errorMessage(
|
errorMessage(
|
||||||
when ((viewState.asyncCreateRoomRequest as? Fail)?.error) {
|
roomAliasErrorFormatter.format(
|
||||||
is CreateRoomFailure.RoomAliasError.AliasEmpty -> R.string.create_room_alias_empty
|
(((viewState.asyncCreateRoomRequest as? Fail)?.error) as? CreateRoomFailure.AliasError)?.aliasError)
|
||||||
is CreateRoomFailure.RoomAliasError.AliasNotAvailable -> R.string.create_room_alias_already_in_use
|
|
||||||
is CreateRoomFailure.RoomAliasError.AliasInvalid -> R.string.create_room_alias_invalid
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
?.let { stringProvider.getString(it) }
|
|
||||||
)
|
)
|
||||||
onTextChange { value ->
|
onTextChange { value ->
|
||||||
listener?.setAliasLocalPart(value)
|
listener?.setAliasLocalPart(value)
|
||||||
|
|
|
@ -84,7 +84,7 @@ class CreateRoomFragment @Inject constructor(
|
||||||
|
|
||||||
override fun showFailure(throwable: Throwable) {
|
override fun showFailure(throwable: Throwable) {
|
||||||
// Note: RoomAliasError are displayed directly in the form
|
// Note: RoomAliasError are displayed directly in the form
|
||||||
if (throwable !is CreateRoomFailure.RoomAliasError) {
|
if (throwable !is CreateRoomFailure.AliasError) {
|
||||||
super.showFailure(throwable)
|
super.showFailure(throwable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomdirectory.createroom
|
||||||
|
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class RoomAliasErrorFormatter @Inject constructor(
|
||||||
|
private val stringProvider: StringProvider
|
||||||
|
) {
|
||||||
|
fun format(roomAliasError: RoomAliasError?): String? {
|
||||||
|
return when (roomAliasError) {
|
||||||
|
is RoomAliasError.AliasEmpty -> R.string.create_room_alias_empty
|
||||||
|
is RoomAliasError.AliasNotAvailable -> R.string.create_room_alias_already_in_use
|
||||||
|
is RoomAliasError.AliasInvalid -> R.string.create_room_alias_invalid
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
?.let { stringProvider.getString(it) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ import im.vector.app.features.room.RequireActiveMembershipViewState
|
||||||
import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment
|
import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment
|
||||||
import im.vector.app.features.roomprofile.members.RoomMemberListFragment
|
import im.vector.app.features.roomprofile.members.RoomMemberListFragment
|
||||||
import im.vector.app.features.roomprofile.settings.RoomSettingsFragment
|
import im.vector.app.features.roomprofile.settings.RoomSettingsFragment
|
||||||
|
import im.vector.app.features.roomprofile.alias.RoomAliasFragment
|
||||||
import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment
|
import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -98,10 +99,11 @@ class RoomProfileActivity :
|
||||||
.observe()
|
.observe()
|
||||||
.subscribe { sharedAction ->
|
.subscribe { sharedAction ->
|
||||||
when (sharedAction) {
|
when (sharedAction) {
|
||||||
is RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers()
|
is RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers()
|
||||||
is RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings()
|
is RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings()
|
||||||
is RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads()
|
is RoomProfileSharedAction.OpenRoomAliasesSettings -> openRoomAlias()
|
||||||
is RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers()
|
is RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads()
|
||||||
|
is RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.disposeOnDestroy()
|
.disposeOnDestroy()
|
||||||
|
@ -135,6 +137,10 @@ class RoomProfileActivity :
|
||||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomSettingsFragment::class.java, roomProfileArgs)
|
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomSettingsFragment::class.java, roomProfileArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun openRoomAlias() {
|
||||||
|
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomAliasFragment::class.java, roomProfileArgs)
|
||||||
|
}
|
||||||
|
|
||||||
private fun openRoomMembers() {
|
private fun openRoomMembers() {
|
||||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomMemberListFragment::class.java, roomProfileArgs)
|
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomMemberListFragment::class.java, roomProfileArgs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import im.vector.app.core.platform.VectorSharedAction
|
||||||
*/
|
*/
|
||||||
sealed class RoomProfileSharedAction : VectorSharedAction {
|
sealed class RoomProfileSharedAction : VectorSharedAction {
|
||||||
object OpenRoomSettings : RoomProfileSharedAction()
|
object OpenRoomSettings : RoomProfileSharedAction()
|
||||||
|
object OpenRoomAliasesSettings : RoomProfileSharedAction()
|
||||||
object OpenRoomUploads : RoomProfileSharedAction()
|
object OpenRoomUploads : RoomProfileSharedAction()
|
||||||
object OpenRoomMembers : RoomProfileSharedAction()
|
object OpenRoomMembers : RoomProfileSharedAction()
|
||||||
object OpenBannedRoomMembers : RoomProfileSharedAction()
|
object OpenBannedRoomMembers : RoomProfileSharedAction()
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
|
|
||||||
|
sealed class RoomAliasAction : VectorViewModelAction {
|
||||||
|
// Canonical
|
||||||
|
object ToggleManualPublishForm : RoomAliasAction()
|
||||||
|
data class SetNewAlias(val alias: String) : RoomAliasAction()
|
||||||
|
object ManualPublishAlias : RoomAliasAction()
|
||||||
|
data class PublishAlias(val alias: String) : RoomAliasAction()
|
||||||
|
data class UnpublishAlias(val alias: String) : RoomAliasAction()
|
||||||
|
data class SetCanonicalAlias(val canonicalAlias: String?) : RoomAliasAction()
|
||||||
|
|
||||||
|
// Room directory
|
||||||
|
data class SetRoomDirectoryVisibility(val roomDirectoryVisibility: RoomDirectoryVisibility) : RoomAliasAction()
|
||||||
|
|
||||||
|
// Local
|
||||||
|
data class RemoveLocalAlias(val alias: String) : RoomAliasAction()
|
||||||
|
object ToggleAddLocalAliasForm : RoomAliasAction()
|
||||||
|
data class SetNewLocalAliasLocalPart(val aliasLocalPart: String) : RoomAliasAction()
|
||||||
|
object AddLocalAlias : RoomAliasAction()
|
||||||
|
}
|
|
@ -0,0 +1,262 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias
|
||||||
|
|
||||||
|
import android.text.InputType
|
||||||
|
import com.airbnb.epoxy.TypedEpoxyController
|
||||||
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.Loading
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||||
|
import im.vector.app.core.epoxy.loadingItem
|
||||||
|
import im.vector.app.core.epoxy.profiles.buildProfileSection
|
||||||
|
import im.vector.app.core.epoxy.profiles.profileActionItem
|
||||||
|
import im.vector.app.core.error.ErrorFormatter
|
||||||
|
import im.vector.app.core.resources.ColorProvider
|
||||||
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.features.discovery.settingsButtonItem
|
||||||
|
import im.vector.app.features.discovery.settingsContinueCancelItem
|
||||||
|
import im.vector.app.features.discovery.settingsInfoItem
|
||||||
|
import im.vector.app.features.form.formEditTextItem
|
||||||
|
import im.vector.app.features.form.formSwitchItem
|
||||||
|
import im.vector.app.features.roomdirectory.createroom.RoomAliasErrorFormatter
|
||||||
|
import im.vector.app.features.roomdirectory.createroom.roomAliasEditItem
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class RoomAliasController @Inject constructor(
|
||||||
|
private val stringProvider: StringProvider,
|
||||||
|
private val errorFormatter: ErrorFormatter,
|
||||||
|
private val colorProvider: ColorProvider,
|
||||||
|
private val roomAliasErrorFormatter: RoomAliasErrorFormatter
|
||||||
|
) : TypedEpoxyController<RoomAliasViewState>() {
|
||||||
|
|
||||||
|
interface Callback {
|
||||||
|
fun toggleManualPublishForm()
|
||||||
|
fun setNewAlias(alias: String)
|
||||||
|
fun addAlias()
|
||||||
|
fun setRoomDirectoryVisibility(roomDirectoryVisibility: RoomDirectoryVisibility)
|
||||||
|
fun toggleLocalAliasForm()
|
||||||
|
fun setNewLocalAliasLocalPart(aliasLocalPart: String)
|
||||||
|
fun addLocalAlias()
|
||||||
|
fun openAliasDetail(alias: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
var callback: Callback? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
setData(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildModels(data: RoomAliasViewState?) {
|
||||||
|
data ?: return
|
||||||
|
|
||||||
|
// Published alias
|
||||||
|
buildPublishInfo(data)
|
||||||
|
// Room directory visibility
|
||||||
|
buildRoomDirectoryVisibility(data)
|
||||||
|
// Local alias
|
||||||
|
buildLocalInfo(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildRoomDirectoryVisibility(data: RoomAliasViewState) {
|
||||||
|
when (data.roomDirectoryVisibility) {
|
||||||
|
Uninitialized -> Unit
|
||||||
|
is Loading -> Unit
|
||||||
|
is Success -> {
|
||||||
|
formSwitchItem {
|
||||||
|
id("roomVisibility")
|
||||||
|
title(stringProvider.getString(R.string.room_alias_publish_to_directory, data.homeServerName))
|
||||||
|
showDivider(false)
|
||||||
|
switchChecked(data.roomDirectoryVisibility() == RoomDirectoryVisibility.PUBLIC)
|
||||||
|
listener {
|
||||||
|
if (it) {
|
||||||
|
callback?.setRoomDirectoryVisibility(RoomDirectoryVisibility.PUBLIC)
|
||||||
|
} else {
|
||||||
|
callback?.setRoomDirectoryVisibility(RoomDirectoryVisibility.PRIVATE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Fail -> {
|
||||||
|
errorWithRetryItem {
|
||||||
|
text(stringProvider.getString(R.string.room_alias_publish_to_directory_error,
|
||||||
|
errorFormatter.toHumanReadable(data.roomDirectoryVisibility.error)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildPublishInfo(data: RoomAliasViewState) {
|
||||||
|
buildProfileSection(
|
||||||
|
stringProvider.getString(R.string.room_alias_published_alias_title)
|
||||||
|
)
|
||||||
|
settingsInfoItem {
|
||||||
|
id("publishedInfo")
|
||||||
|
helperTextResId(R.string.room_alias_published_alias_subtitle)
|
||||||
|
}
|
||||||
|
|
||||||
|
data.canonicalAlias
|
||||||
|
?.takeIf { it.isNotEmpty() }
|
||||||
|
?.let { canonicalAlias ->
|
||||||
|
|
||||||
|
profileActionItem {
|
||||||
|
id("canonical")
|
||||||
|
title(data.canonicalAlias)
|
||||||
|
subtitle(stringProvider.getString(R.string.room_alias_published_alias_main))
|
||||||
|
listener { callback?.openAliasDetail(canonicalAlias) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.alternativeAliases.isEmpty()) {
|
||||||
|
settingsInfoItem {
|
||||||
|
id("otherPublishedEmpty")
|
||||||
|
if (data.actionPermissions.canChangeCanonicalAlias) {
|
||||||
|
helperTextResId(R.string.room_alias_address_empty_can_add)
|
||||||
|
} else {
|
||||||
|
helperTextResId(R.string.room_alias_address_empty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
settingsInfoItem {
|
||||||
|
id("otherPublished")
|
||||||
|
helperTextResId(R.string.room_alias_published_other)
|
||||||
|
}
|
||||||
|
data.alternativeAliases.forEachIndexed { idx, altAlias ->
|
||||||
|
profileActionItem {
|
||||||
|
id("alt_$idx")
|
||||||
|
title(altAlias)
|
||||||
|
listener { callback?.openAliasDetail(altAlias) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.actionPermissions.canChangeCanonicalAlias) {
|
||||||
|
buildPublishManuallyForm(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildPublishManuallyForm(data: RoomAliasViewState) {
|
||||||
|
when (data.publishManuallyState) {
|
||||||
|
RoomAliasViewState.AddAliasState.Hidden -> Unit
|
||||||
|
RoomAliasViewState.AddAliasState.Closed -> {
|
||||||
|
settingsButtonItem {
|
||||||
|
id("publishManually")
|
||||||
|
colorProvider(colorProvider)
|
||||||
|
buttonTitleId(R.string.room_alias_published_alias_add_manually)
|
||||||
|
buttonClickListener { callback?.toggleManualPublishForm() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is RoomAliasViewState.AddAliasState.Editing -> {
|
||||||
|
formEditTextItem {
|
||||||
|
id("publishManuallyEdit")
|
||||||
|
value(data.publishManuallyState.value)
|
||||||
|
showBottomSeparator(false)
|
||||||
|
hint(stringProvider.getString(R.string.room_alias_address_hint))
|
||||||
|
inputType(InputType.TYPE_CLASS_TEXT)
|
||||||
|
onTextChange { text ->
|
||||||
|
callback?.setNewAlias(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settingsContinueCancelItem {
|
||||||
|
id("publishManuallySubmit")
|
||||||
|
continueText(stringProvider.getString(R.string.room_alias_published_alias_add_manually_submit))
|
||||||
|
continueOnClick { callback?.addAlias() }
|
||||||
|
cancelOnClick { callback?.toggleManualPublishForm() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildLocalInfo(data: RoomAliasViewState) {
|
||||||
|
buildProfileSection(
|
||||||
|
stringProvider.getString(R.string.room_alias_local_address_title)
|
||||||
|
)
|
||||||
|
settingsInfoItem {
|
||||||
|
id("localInfo")
|
||||||
|
helperText(stringProvider.getString(R.string.room_alias_local_address_subtitle, data.homeServerName))
|
||||||
|
}
|
||||||
|
|
||||||
|
when (val localAliases = data.localAliases) {
|
||||||
|
is Uninitialized -> {
|
||||||
|
loadingItem {
|
||||||
|
id("loadingAliases")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Success -> {
|
||||||
|
if (localAliases().isEmpty()) {
|
||||||
|
settingsInfoItem {
|
||||||
|
id("locEmpty")
|
||||||
|
helperTextResId(R.string.room_alias_local_address_empty)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
localAliases().forEachIndexed { idx, localAlias ->
|
||||||
|
profileActionItem {
|
||||||
|
id("loc_$idx")
|
||||||
|
title(localAlias)
|
||||||
|
listener { callback?.openAliasDetail(localAlias) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Fail -> {
|
||||||
|
errorWithRetryItem {
|
||||||
|
id("alt_error")
|
||||||
|
text(errorFormatter.toHumanReadable(localAliases.error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add local
|
||||||
|
buildAddLocalAlias(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildAddLocalAlias(data: RoomAliasViewState) {
|
||||||
|
when (data.newLocalAliasState) {
|
||||||
|
RoomAliasViewState.AddAliasState.Hidden -> Unit
|
||||||
|
RoomAliasViewState.AddAliasState.Closed -> {
|
||||||
|
settingsButtonItem {
|
||||||
|
id("newLocalAliasButton")
|
||||||
|
colorProvider(colorProvider)
|
||||||
|
buttonTitleId(R.string.room_alias_local_address_add)
|
||||||
|
buttonClickListener { callback?.toggleLocalAliasForm() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is RoomAliasViewState.AddAliasState.Editing -> {
|
||||||
|
roomAliasEditItem {
|
||||||
|
id("newLocalAlias")
|
||||||
|
value(data.newLocalAliasState.value)
|
||||||
|
homeServer(":" + data.homeServerName)
|
||||||
|
showBottomSeparator(false)
|
||||||
|
errorMessage(roomAliasErrorFormatter.format((data.newLocalAliasState.asyncRequest as? Fail)?.error as? RoomAliasError))
|
||||||
|
onTextChange { value ->
|
||||||
|
callback?.setNewLocalAliasLocalPart(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settingsContinueCancelItem {
|
||||||
|
id("newLocalAliasSubmit")
|
||||||
|
continueText(stringProvider.getString(R.string.action_add))
|
||||||
|
continueOnClick { callback?.addLocalAlias() }
|
||||||
|
cancelOnClick { callback?.toggleLocalAliasForm() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias
|
||||||
|
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import com.airbnb.mvrx.args
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
|
import com.airbnb.mvrx.withState
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.dialogs.withColoredButton
|
||||||
|
import im.vector.app.core.extensions.cleanup
|
||||||
|
import im.vector.app.core.extensions.configureWith
|
||||||
|
import im.vector.app.core.extensions.exhaustive
|
||||||
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
|
import im.vector.app.core.utils.shareText
|
||||||
|
import im.vector.app.core.utils.toast
|
||||||
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
|
import im.vector.app.features.roomprofile.RoomProfileArgs
|
||||||
|
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheet
|
||||||
|
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedAction
|
||||||
|
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel
|
||||||
|
import kotlinx.android.synthetic.main.fragment_room_setting_generic.*
|
||||||
|
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||||
|
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class RoomAliasFragment @Inject constructor(
|
||||||
|
val viewModelFactory: RoomAliasViewModel.Factory,
|
||||||
|
private val controller: RoomAliasController,
|
||||||
|
private val avatarRenderer: AvatarRenderer
|
||||||
|
) :
|
||||||
|
VectorBaseFragment(),
|
||||||
|
RoomAliasController.Callback {
|
||||||
|
|
||||||
|
private val viewModel: RoomAliasViewModel by fragmentViewModel()
|
||||||
|
private lateinit var sharedActionViewModel: RoomAliasBottomSheetSharedActionViewModel
|
||||||
|
|
||||||
|
private val roomProfileArgs: RoomProfileArgs by args()
|
||||||
|
|
||||||
|
override fun getLayoutResId() = R.layout.fragment_room_setting_generic
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
sharedActionViewModel = activityViewModelProvider.get(RoomAliasBottomSheetSharedActionViewModel::class.java)
|
||||||
|
|
||||||
|
controller.callback = this
|
||||||
|
setupToolbar(roomSettingsToolbar)
|
||||||
|
roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true)
|
||||||
|
waiting_view_status_text.setText(R.string.please_wait)
|
||||||
|
waiting_view_status_text.isVisible = true
|
||||||
|
|
||||||
|
viewModel.observeViewEvents {
|
||||||
|
when (it) {
|
||||||
|
is RoomAliasViewEvents.Failure -> showFailure(it.throwable)
|
||||||
|
RoomAliasViewEvents.Success -> showSuccess()
|
||||||
|
}.exhaustive
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedActionViewModel
|
||||||
|
.observe()
|
||||||
|
.subscribe { handleAliasAction(it) }
|
||||||
|
.disposeOnDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleAliasAction(action: RoomAliasBottomSheetSharedAction?) {
|
||||||
|
when (action) {
|
||||||
|
is RoomAliasBottomSheetSharedAction.ShareAlias -> shareAlias(action.matrixTo)
|
||||||
|
is RoomAliasBottomSheetSharedAction.PublishAlias -> viewModel.handle(RoomAliasAction.PublishAlias(action.alias))
|
||||||
|
is RoomAliasBottomSheetSharedAction.UnPublishAlias -> unpublishAlias(action.alias)
|
||||||
|
is RoomAliasBottomSheetSharedAction.DeleteAlias -> removeLocalAlias(action.alias)
|
||||||
|
is RoomAliasBottomSheetSharedAction.SetMainAlias -> viewModel.handle(RoomAliasAction.SetCanonicalAlias(action.alias))
|
||||||
|
RoomAliasBottomSheetSharedAction.UnsetMainAlias -> viewModel.handle(RoomAliasAction.SetCanonicalAlias(canonicalAlias = null))
|
||||||
|
null -> Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shareAlias(matrixTo: String) {
|
||||||
|
shareText(requireContext(), matrixTo)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showFailure(throwable: Throwable) {
|
||||||
|
if (throwable !is RoomAliasError) {
|
||||||
|
super.showFailure(throwable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showSuccess() {
|
||||||
|
activity?.toast(R.string.room_settings_save_success)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
controller.callback = null
|
||||||
|
roomSettingsRecyclerView.cleanup()
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidate() = withState(viewModel) { state ->
|
||||||
|
waiting_view.isVisible = state.isLoading
|
||||||
|
controller.setData(state)
|
||||||
|
renderRoomSummary(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderRoomSummary(state: RoomAliasViewState) {
|
||||||
|
state.roomSummary()?.let {
|
||||||
|
roomSettingsToolbarTitleView.text = it.displayName
|
||||||
|
avatarRenderer.render(it.toMatrixItem(), roomSettingsToolbarAvatarImageView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unpublishAlias(alias: String) {
|
||||||
|
AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle(R.string.dialog_title_confirmation)
|
||||||
|
.setMessage(getString(R.string.room_alias_unpublish_confirmation, alias))
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.action_unpublish) { _, _ ->
|
||||||
|
viewModel.handle(RoomAliasAction.UnpublishAlias(alias))
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
.withColoredButton(DialogInterface.BUTTON_POSITIVE)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toggleManualPublishForm() {
|
||||||
|
viewModel.handle(RoomAliasAction.ToggleManualPublishForm)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setNewAlias(alias: String) {
|
||||||
|
viewModel.handle(RoomAliasAction.SetNewAlias(alias))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addAlias() {
|
||||||
|
viewModel.handle(RoomAliasAction.ManualPublishAlias)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setRoomDirectoryVisibility(roomDirectoryVisibility: RoomDirectoryVisibility) {
|
||||||
|
viewModel.handle(RoomAliasAction.SetRoomDirectoryVisibility(roomDirectoryVisibility))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toggleLocalAliasForm() {
|
||||||
|
viewModel.handle(RoomAliasAction.ToggleAddLocalAliasForm)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setNewLocalAliasLocalPart(aliasLocalPart: String) {
|
||||||
|
viewModel.handle(RoomAliasAction.SetNewLocalAliasLocalPart(aliasLocalPart))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addLocalAlias() {
|
||||||
|
viewModel.handle(RoomAliasAction.AddLocalAlias)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openAliasDetail(alias: String) = withState(viewModel) { state ->
|
||||||
|
RoomAliasBottomSheet
|
||||||
|
.newInstance(
|
||||||
|
alias = alias,
|
||||||
|
isPublished = alias in state.allPublishedAliases,
|
||||||
|
isMainAlias = alias == state.canonicalAlias,
|
||||||
|
isLocal = alias in state.localAliases().orEmpty(),
|
||||||
|
canEditCanonicalAlias = state.actionPermissions.canChangeCanonicalAlias
|
||||||
|
)
|
||||||
|
.show(childFragmentManager, "ROOM_ALIAS_ACTIONS")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeLocalAlias(alias: String) {
|
||||||
|
AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle(R.string.dialog_title_confirmation)
|
||||||
|
.setMessage(getString(R.string.room_alias_delete_confirmation, alias))
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.delete) { _, _ ->
|
||||||
|
viewModel.handle(RoomAliasAction.RemoveLocalAlias(alias))
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
.withColoredButton(DialogInterface.BUTTON_POSITIVE)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transient events for room settings screen
|
||||||
|
*/
|
||||||
|
sealed class RoomAliasViewEvents : VectorViewEvents {
|
||||||
|
data class Failure(val throwable: Throwable) : RoomAliasViewEvents()
|
||||||
|
object Success : RoomAliasViewEvents()
|
||||||
|
}
|
|
@ -0,0 +1,384 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias
|
||||||
|
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
|
import com.airbnb.mvrx.Loading
|
||||||
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import im.vector.app.core.extensions.exhaustive
|
||||||
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent
|
||||||
|
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||||
|
import org.matrix.android.sdk.rx.mapOptional
|
||||||
|
import org.matrix.android.sdk.rx.rx
|
||||||
|
import org.matrix.android.sdk.rx.unwrap
|
||||||
|
|
||||||
|
class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: RoomAliasViewState,
|
||||||
|
private val session: Session)
|
||||||
|
: VectorViewModel<RoomAliasViewState, RoomAliasAction, RoomAliasViewEvents>(initialState) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: RoomAliasViewState): RoomAliasViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MvRxViewModelFactory<RoomAliasViewModel, RoomAliasViewState> {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: RoomAliasViewState): RoomAliasViewModel? {
|
||||||
|
val fragment: RoomAliasFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
|
return fragment.viewModelFactory.create(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val room = session.getRoom(initialState.roomId)!!
|
||||||
|
|
||||||
|
init {
|
||||||
|
initHomeServerName()
|
||||||
|
observeRoomSummary()
|
||||||
|
observePowerLevel()
|
||||||
|
observeRoomCanonicalAlias()
|
||||||
|
fetchRoomAlias()
|
||||||
|
fetchRoomDirectoryVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchRoomDirectoryVisibility() {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
roomDirectoryVisibility = Loading()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
viewModelScope.launch {
|
||||||
|
runCatching {
|
||||||
|
session.getRoomDirectoryVisibility(room.roomId)
|
||||||
|
}.fold(
|
||||||
|
{
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
roomDirectoryVisibility = Success(it)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
roomDirectoryVisibility = Fail(it)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initHomeServerName() {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
homeServerName = session.myUserId.substringAfter(":")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchRoomAlias() {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
localAliases = Loading()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
|
runCatching { room.getRoomAliases() }
|
||||||
|
.fold(
|
||||||
|
{
|
||||||
|
setState { copy(localAliases = Success(it.sorted())) }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setState { copy(localAliases = Fail(it)) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeRoomSummary() {
|
||||||
|
room.rx().liveRoomSummary()
|
||||||
|
.unwrap()
|
||||||
|
.execute { async ->
|
||||||
|
copy(
|
||||||
|
roomSummary = async
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observePowerLevel() {
|
||||||
|
PowerLevelsObservableFactory(room)
|
||||||
|
.createObservable()
|
||||||
|
.subscribe {
|
||||||
|
val powerLevelsHelper = PowerLevelsHelper(it)
|
||||||
|
val permissions = RoomAliasViewState.ActionPermissions(
|
||||||
|
canChangeCanonicalAlias = powerLevelsHelper.isUserAllowedToSend(
|
||||||
|
userId = session.myUserId,
|
||||||
|
isState = true,
|
||||||
|
eventType = EventType.STATE_ROOM_CANONICAL_ALIAS
|
||||||
|
)
|
||||||
|
)
|
||||||
|
setState {
|
||||||
|
val newPublishManuallyState = if (permissions.canChangeCanonicalAlias) {
|
||||||
|
when (publishManuallyState) {
|
||||||
|
RoomAliasViewState.AddAliasState.Hidden -> RoomAliasViewState.AddAliasState.Closed
|
||||||
|
else -> publishManuallyState
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RoomAliasViewState.AddAliasState.Hidden
|
||||||
|
}
|
||||||
|
copy(
|
||||||
|
actionPermissions = permissions,
|
||||||
|
publishManuallyState = newPublishManuallyState
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.disposeOnClear()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We do not want to use the fallback avatar url, which can be the other user avatar, or the current user avatar.
|
||||||
|
*/
|
||||||
|
private fun observeRoomCanonicalAlias() {
|
||||||
|
room.rx()
|
||||||
|
.liveStateEvent(EventType.STATE_ROOM_CANONICAL_ALIAS, QueryStringValue.NoCondition)
|
||||||
|
.mapOptional { it.content.toModel<RoomCanonicalAliasContent>() }
|
||||||
|
.unwrap()
|
||||||
|
.subscribe {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
canonicalAlias = it.canonicalAlias,
|
||||||
|
alternativeAliases = it.alternativeAliases.orEmpty().sorted()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.disposeOnClear()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handle(action: RoomAliasAction) {
|
||||||
|
when (action) {
|
||||||
|
RoomAliasAction.ToggleManualPublishForm -> handleToggleManualPublishForm()
|
||||||
|
is RoomAliasAction.SetNewAlias -> handleSetNewAlias(action)
|
||||||
|
is RoomAliasAction.ManualPublishAlias -> handleManualPublishAlias()
|
||||||
|
is RoomAliasAction.UnpublishAlias -> handleUnpublishAlias(action)
|
||||||
|
is RoomAliasAction.SetCanonicalAlias -> handleSetCanonicalAlias(action)
|
||||||
|
is RoomAliasAction.SetRoomDirectoryVisibility -> handleSetRoomDirectoryVisibility(action)
|
||||||
|
RoomAliasAction.ToggleAddLocalAliasForm -> handleToggleAddLocalAliasForm()
|
||||||
|
is RoomAliasAction.SetNewLocalAliasLocalPart -> handleSetNewLocalAliasLocalPart(action)
|
||||||
|
RoomAliasAction.AddLocalAlias -> handleAddLocalAlias()
|
||||||
|
is RoomAliasAction.RemoveLocalAlias -> handleRemoveLocalAlias(action)
|
||||||
|
is RoomAliasAction.PublishAlias -> handlePublishAlias(action)
|
||||||
|
}.exhaustive
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSetRoomDirectoryVisibility(action: RoomAliasAction.SetRoomDirectoryVisibility) {
|
||||||
|
postLoading(true)
|
||||||
|
viewModelScope.launch {
|
||||||
|
runCatching {
|
||||||
|
session.setRoomDirectoryVisibility(room.roomId, action.roomDirectoryVisibility)
|
||||||
|
}.fold(
|
||||||
|
{
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
isLoading = false,
|
||||||
|
// Local echo, no need to fetch the data from the server again
|
||||||
|
roomDirectoryVisibility = Success(action.roomDirectoryVisibility)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
postLoading(false)
|
||||||
|
_viewEvents.post(RoomAliasViewEvents.Failure(it))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleToggleAddLocalAliasForm() {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
newLocalAliasState = when (newLocalAliasState) {
|
||||||
|
RoomAliasViewState.AddAliasState.Hidden -> RoomAliasViewState.AddAliasState.Hidden
|
||||||
|
RoomAliasViewState.AddAliasState.Closed -> RoomAliasViewState.AddAliasState.Editing("", Uninitialized)
|
||||||
|
is RoomAliasViewState.AddAliasState.Editing -> RoomAliasViewState.AddAliasState.Closed
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleToggleManualPublishForm() {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
publishManuallyState = when (publishManuallyState) {
|
||||||
|
RoomAliasViewState.AddAliasState.Hidden -> RoomAliasViewState.AddAliasState.Hidden
|
||||||
|
RoomAliasViewState.AddAliasState.Closed -> RoomAliasViewState.AddAliasState.Editing("", Uninitialized)
|
||||||
|
is RoomAliasViewState.AddAliasState.Editing -> RoomAliasViewState.AddAliasState.Closed
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSetNewAlias(action: RoomAliasAction.SetNewAlias) {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
publishManuallyState = RoomAliasViewState.AddAliasState.Editing(action.alias, Uninitialized)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSetNewLocalAliasLocalPart(action: RoomAliasAction.SetNewLocalAliasLocalPart) {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
newLocalAliasState = RoomAliasViewState.AddAliasState.Editing(action.aliasLocalPart, Uninitialized)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleManualPublishAlias() = withState { state ->
|
||||||
|
val newAlias = (state.publishManuallyState as? RoomAliasViewState.AddAliasState.Editing)?.value ?: return@withState
|
||||||
|
updateCanonicalAlias(
|
||||||
|
canonicalAlias = state.canonicalAlias,
|
||||||
|
alternativeAliases = state.alternativeAliases + newAlias,
|
||||||
|
closeForm = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePublishAlias(action: RoomAliasAction.PublishAlias) = withState { state ->
|
||||||
|
updateCanonicalAlias(
|
||||||
|
canonicalAlias = state.canonicalAlias,
|
||||||
|
alternativeAliases = state.alternativeAliases + action.alias,
|
||||||
|
closeForm = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleUnpublishAlias(action: RoomAliasAction.UnpublishAlias) = withState { state ->
|
||||||
|
updateCanonicalAlias(
|
||||||
|
// We can also unpublish the canonical alias
|
||||||
|
canonicalAlias = state.canonicalAlias.takeIf { it != action.alias },
|
||||||
|
alternativeAliases = state.alternativeAliases - action.alias,
|
||||||
|
closeForm = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSetCanonicalAlias(action: RoomAliasAction.SetCanonicalAlias) = withState { state ->
|
||||||
|
updateCanonicalAlias(
|
||||||
|
canonicalAlias = action.canonicalAlias,
|
||||||
|
// Ensure the previous canonical alias is moved to the alt aliases
|
||||||
|
alternativeAliases = state.allPublishedAliases,
|
||||||
|
closeForm = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateCanonicalAlias(canonicalAlias: String?, alternativeAliases: List<String>, closeForm: Boolean) {
|
||||||
|
postLoading(true)
|
||||||
|
room.updateCanonicalAlias(canonicalAlias, alternativeAliases, object : MatrixCallback<Unit> {
|
||||||
|
override fun onSuccess(data: Unit) {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
isLoading = false,
|
||||||
|
publishManuallyState = if (closeForm) RoomAliasViewState.AddAliasState.Closed else publishManuallyState
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(failure: Throwable) {
|
||||||
|
postLoading(false)
|
||||||
|
_viewEvents.post(RoomAliasViewEvents.Failure(failure))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleAddLocalAlias() = withState { state ->
|
||||||
|
val previousState = (state.newLocalAliasState as? RoomAliasViewState.AddAliasState.Editing) ?: return@withState
|
||||||
|
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
isLoading = true,
|
||||||
|
newLocalAliasState = previousState.copy(asyncRequest = Loading())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
viewModelScope.launch {
|
||||||
|
runCatching { room.addAlias(previousState.value) }
|
||||||
|
.onFailure {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
isLoading = false,
|
||||||
|
newLocalAliasState = previousState.copy(asyncRequest = Fail(it))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_viewEvents.post(RoomAliasViewEvents.Failure(it))
|
||||||
|
}
|
||||||
|
.onSuccess {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
isLoading = false,
|
||||||
|
newLocalAliasState = RoomAliasViewState.AddAliasState.Closed,
|
||||||
|
// Local echo
|
||||||
|
localAliases = Success((localAliases().orEmpty() + previousState.value).sorted())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
fetchRoomAlias()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleRemoveLocalAlias(action: RoomAliasAction.RemoveLocalAlias) {
|
||||||
|
postLoading(true)
|
||||||
|
viewModelScope.launch {
|
||||||
|
runCatching { session.deleteRoomAlias(action.alias) }
|
||||||
|
.onFailure {
|
||||||
|
setState {
|
||||||
|
copy(isLoading = false)
|
||||||
|
}
|
||||||
|
_viewEvents.post(RoomAliasViewEvents.Failure(it))
|
||||||
|
}
|
||||||
|
.onSuccess {
|
||||||
|
// Local echo
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
isLoading = false,
|
||||||
|
// Local echo
|
||||||
|
localAliases = Success(localAliases().orEmpty() - action.alias)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
fetchRoomAlias()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun postLoading(isLoading: Boolean) {
|
||||||
|
setState {
|
||||||
|
copy(isLoading = isLoading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.Async
|
||||||
|
import com.airbnb.mvrx.MvRxState
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import im.vector.app.features.roomprofile.RoomProfileArgs
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
|
||||||
|
data class RoomAliasViewState(
|
||||||
|
val roomId: String,
|
||||||
|
val homeServerName: String = "",
|
||||||
|
val roomSummary: Async<RoomSummary> = Uninitialized,
|
||||||
|
val actionPermissions: ActionPermissions = ActionPermissions(),
|
||||||
|
val roomDirectoryVisibility: Async<RoomDirectoryVisibility> = Uninitialized,
|
||||||
|
val isLoading: Boolean = false,
|
||||||
|
val canonicalAlias: String? = null,
|
||||||
|
val alternativeAliases: List<String> = emptyList(),
|
||||||
|
val publishManuallyState: AddAliasState = AddAliasState.Hidden,
|
||||||
|
val localAliases: Async<List<String>> = Uninitialized,
|
||||||
|
val newLocalAliasState: AddAliasState = AddAliasState.Closed
|
||||||
|
) : MvRxState {
|
||||||
|
|
||||||
|
constructor(args: RoomProfileArgs) : this(roomId = args.roomId)
|
||||||
|
|
||||||
|
val allPublishedAliases: List<String>
|
||||||
|
get() = (alternativeAliases + listOfNotNull(canonicalAlias)).distinct()
|
||||||
|
|
||||||
|
data class ActionPermissions(
|
||||||
|
val canChangeCanonicalAlias: Boolean = false
|
||||||
|
)
|
||||||
|
|
||||||
|
sealed class AddAliasState {
|
||||||
|
object Hidden : AddAliasState()
|
||||||
|
object Closed : AddAliasState()
|
||||||
|
data class Editing(val value: String, val asyncRequest: Async<Unit> = Uninitialized) : AddAliasState()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias.detail
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Parcelable
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import butterknife.BindView
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
|
import com.airbnb.mvrx.withState
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.di.ScreenComponent
|
||||||
|
import im.vector.app.core.extensions.cleanup
|
||||||
|
import im.vector.app.core.extensions.configureWith
|
||||||
|
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||||
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class RoomAliasBottomSheetArgs(
|
||||||
|
val alias: String,
|
||||||
|
val isPublished: Boolean,
|
||||||
|
val isMainAlias: Boolean,
|
||||||
|
val isLocal: Boolean,
|
||||||
|
val canEditCanonicalAlias: Boolean
|
||||||
|
) : Parcelable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bottom sheet fragment that shows room alias information with list of contextual actions
|
||||||
|
*/
|
||||||
|
class RoomAliasBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomAliasBottomSheetController.Listener {
|
||||||
|
|
||||||
|
private lateinit var sharedActionViewModel: RoomAliasBottomSheetSharedActionViewModel
|
||||||
|
@Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool
|
||||||
|
@Inject lateinit var roomAliasBottomSheetViewModelFactory: RoomAliasBottomSheetViewModel.Factory
|
||||||
|
@Inject lateinit var controller: RoomAliasBottomSheetController
|
||||||
|
|
||||||
|
private val viewModel: RoomAliasBottomSheetViewModel by fragmentViewModel(RoomAliasBottomSheetViewModel::class)
|
||||||
|
|
||||||
|
@BindView(R.id.bottomSheetRecyclerView)
|
||||||
|
lateinit var recyclerView: RecyclerView
|
||||||
|
|
||||||
|
override val showExpanded = true
|
||||||
|
|
||||||
|
override fun injectWith(injector: ScreenComponent) {
|
||||||
|
injector.inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
sharedActionViewModel = activityViewModelProvider.get(RoomAliasBottomSheetSharedActionViewModel::class.java)
|
||||||
|
recyclerView.configureWith(controller, viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true)
|
||||||
|
controller.listener = this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
recyclerView.cleanup()
|
||||||
|
controller.listener = null
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidate() = withState(viewModel) {
|
||||||
|
controller.setData(it)
|
||||||
|
super.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun didSelectMenuAction(quickAction: RoomAliasBottomSheetSharedAction) {
|
||||||
|
sharedActionViewModel.post(quickAction)
|
||||||
|
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance(alias: String,
|
||||||
|
isPublished: Boolean,
|
||||||
|
isMainAlias: Boolean,
|
||||||
|
isLocal: Boolean,
|
||||||
|
canEditCanonicalAlias: Boolean): RoomAliasBottomSheet {
|
||||||
|
return RoomAliasBottomSheet().apply {
|
||||||
|
setArguments(RoomAliasBottomSheetArgs(
|
||||||
|
alias = alias,
|
||||||
|
isPublished = isPublished,
|
||||||
|
isMainAlias = isMainAlias,
|
||||||
|
isLocal = isLocal,
|
||||||
|
canEditCanonicalAlias = canEditCanonicalAlias
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias.detail
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.airbnb.epoxy.TypedEpoxyController
|
||||||
|
import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem
|
||||||
|
import im.vector.app.core.epoxy.dividerItem
|
||||||
|
import im.vector.app.core.epoxy.profiles.profileActionItem
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Epoxy controller for room alias actions
|
||||||
|
*/
|
||||||
|
class RoomAliasBottomSheetController @Inject constructor() : TypedEpoxyController<RoomAliasBottomSheetState>() {
|
||||||
|
|
||||||
|
var listener: Listener? = null
|
||||||
|
|
||||||
|
override fun buildModels(state: RoomAliasBottomSheetState) {
|
||||||
|
profileActionItem {
|
||||||
|
id("alias")
|
||||||
|
title(state.alias)
|
||||||
|
subtitle(state.matrixToLink)
|
||||||
|
editable(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notifications
|
||||||
|
dividerItem {
|
||||||
|
id("aliasSeparator")
|
||||||
|
}
|
||||||
|
|
||||||
|
var idx = 0
|
||||||
|
// Share
|
||||||
|
state.matrixToLink?.let {
|
||||||
|
RoomAliasBottomSheetSharedAction.ShareAlias(it).toBottomSheetItem(++idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action on published alias
|
||||||
|
if (state.isPublished) {
|
||||||
|
// Published address
|
||||||
|
if (state.canEditCanonicalAlias) {
|
||||||
|
if (state.isMainAlias) {
|
||||||
|
RoomAliasBottomSheetSharedAction.UnsetMainAlias.toBottomSheetItem(++idx)
|
||||||
|
} else {
|
||||||
|
RoomAliasBottomSheetSharedAction.SetMainAlias(state.alias).toBottomSheetItem(++idx)
|
||||||
|
}
|
||||||
|
RoomAliasBottomSheetSharedAction.UnPublishAlias(state.alias).toBottomSheetItem(++idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.isLocal) {
|
||||||
|
// Local address
|
||||||
|
if (state.canEditCanonicalAlias && state.isPublished.not()) {
|
||||||
|
// Publish
|
||||||
|
RoomAliasBottomSheetSharedAction.PublishAlias(state.alias).toBottomSheetItem(++idx)
|
||||||
|
}
|
||||||
|
// Delete
|
||||||
|
RoomAliasBottomSheetSharedAction.DeleteAlias(state.alias).toBottomSheetItem(++idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun RoomAliasBottomSheetSharedAction.toBottomSheetItem(index: Int) {
|
||||||
|
return bottomSheetActionItem {
|
||||||
|
id("action_$index")
|
||||||
|
iconRes(iconResId)
|
||||||
|
textRes(titleRes)
|
||||||
|
destructive(this@toBottomSheetItem.destructive)
|
||||||
|
listener(View.OnClickListener { listener?.didSelectMenuAction(this@toBottomSheetItem) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Listener {
|
||||||
|
fun didSelectMenuAction(quickAction: RoomAliasBottomSheetSharedAction)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias.detail
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.platform.VectorSharedAction
|
||||||
|
|
||||||
|
sealed class RoomAliasBottomSheetSharedAction(
|
||||||
|
@StringRes val titleRes: Int,
|
||||||
|
@DrawableRes val iconResId: Int = 0,
|
||||||
|
val destructive: Boolean = false)
|
||||||
|
: VectorSharedAction {
|
||||||
|
|
||||||
|
data class ShareAlias(val matrixTo: String) : RoomAliasBottomSheetSharedAction(
|
||||||
|
R.string.share,
|
||||||
|
R.drawable.ic_material_share
|
||||||
|
)
|
||||||
|
|
||||||
|
data class PublishAlias(val alias: String) : RoomAliasBottomSheetSharedAction(
|
||||||
|
R.string.room_alias_action_publish
|
||||||
|
)
|
||||||
|
|
||||||
|
data class UnPublishAlias(val alias: String) : RoomAliasBottomSheetSharedAction(
|
||||||
|
R.string.room_alias_action_unpublish
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DeleteAlias(val alias: String) : RoomAliasBottomSheetSharedAction(
|
||||||
|
R.string.delete,
|
||||||
|
R.drawable.ic_trash_24,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
data class SetMainAlias(val alias: String) : RoomAliasBottomSheetSharedAction(
|
||||||
|
R.string.room_settings_set_main_address
|
||||||
|
)
|
||||||
|
|
||||||
|
object UnsetMainAlias : RoomAliasBottomSheetSharedAction(
|
||||||
|
R.string.room_settings_unset_main_address
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias.detail
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorSharedActionViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activity shared view model to handle room alias quick actions
|
||||||
|
*/
|
||||||
|
class RoomAliasBottomSheetSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<RoomAliasBottomSheetSharedAction>()
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias.detail
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.MvRxState
|
||||||
|
|
||||||
|
data class RoomAliasBottomSheetState(
|
||||||
|
val alias: String,
|
||||||
|
val matrixToLink: String? = null,
|
||||||
|
val isPublished: Boolean,
|
||||||
|
val isMainAlias: Boolean,
|
||||||
|
val isLocal: Boolean,
|
||||||
|
val canEditCanonicalAlias: Boolean
|
||||||
|
) : MvRxState {
|
||||||
|
|
||||||
|
constructor(args: RoomAliasBottomSheetArgs) : this(
|
||||||
|
alias = args.alias,
|
||||||
|
isPublished = args.isPublished,
|
||||||
|
isMainAlias = args.isMainAlias,
|
||||||
|
isLocal = args.isLocal,
|
||||||
|
canEditCanonicalAlias = args.canEditCanonicalAlias
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.roomprofile.alias.detail
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import im.vector.app.core.platform.EmptyAction
|
||||||
|
import im.vector.app.core.platform.EmptyViewEvents
|
||||||
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
|
||||||
|
class RoomAliasBottomSheetViewModel @AssistedInject constructor(
|
||||||
|
@Assisted initialState: RoomAliasBottomSheetState,
|
||||||
|
session: Session
|
||||||
|
) : VectorViewModel<RoomAliasBottomSheetState, EmptyAction, EmptyViewEvents>(initialState) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: RoomAliasBottomSheetState): RoomAliasBottomSheetViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MvRxViewModelFactory<RoomAliasBottomSheetViewModel, RoomAliasBottomSheetState> {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: RoomAliasBottomSheetState): RoomAliasBottomSheetViewModel? {
|
||||||
|
val fragment: RoomAliasBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
|
return fragment.roomAliasBottomSheetViewModelFactory.create(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
matrixToLink = session.permalinkService().createPermalink(alias)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handle(action: EmptyAction) {
|
||||||
|
// No op
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,8 +19,8 @@ package im.vector.app.features.roomprofile.banned
|
||||||
import im.vector.app.core.platform.VectorViewModelAction
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||||
|
|
||||||
sealed class RoomBannedListMemberAction : VectorViewModelAction {
|
sealed class RoomBannedMemberListAction : VectorViewModelAction {
|
||||||
data class QueryInfo(val roomMemberSummary: RoomMemberSummary) : RoomBannedListMemberAction()
|
data class QueryInfo(val roomMemberSummary: RoomMemberSummary) : RoomBannedMemberListAction()
|
||||||
data class UnBanUser(val roomMemberSummary: RoomMemberSummary) : RoomBannedListMemberAction()
|
data class UnBanUser(val roomMemberSummary: RoomMemberSummary) : RoomBannedMemberListAction()
|
||||||
data class Filter(val filter: String) : RoomBannedListMemberAction()
|
data class Filter(val filter: String) : RoomBannedMemberListAction()
|
||||||
}
|
}
|
|
@ -37,18 +37,18 @@ import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class RoomBannedMemberListFragment @Inject constructor(
|
class RoomBannedMemberListFragment @Inject constructor(
|
||||||
val viewModelFactory: RoomBannedListMemberViewModel.Factory,
|
val viewModelFactory: RoomBannedMemberListViewModel.Factory,
|
||||||
private val roomMemberListController: RoomBannedMemberListController,
|
private val roomMemberListController: RoomBannedMemberListController,
|
||||||
private val avatarRenderer: AvatarRenderer
|
private val avatarRenderer: AvatarRenderer
|
||||||
) : VectorBaseFragment(), RoomBannedMemberListController.Callback {
|
) : VectorBaseFragment(), RoomBannedMemberListController.Callback {
|
||||||
|
|
||||||
private val viewModel: RoomBannedListMemberViewModel by fragmentViewModel()
|
private val viewModel: RoomBannedMemberListViewModel by fragmentViewModel()
|
||||||
private val roomProfileArgs: RoomProfileArgs by args()
|
private val roomProfileArgs: RoomProfileArgs by args()
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_room_setting_generic
|
override fun getLayoutResId() = R.layout.fragment_room_setting_generic
|
||||||
|
|
||||||
override fun onUnbanClicked(roomMember: RoomMemberSummary) {
|
override fun onUnbanClicked(roomMember: RoomMemberSummary) {
|
||||||
viewModel.handle(RoomBannedListMemberAction.QueryInfo(roomMember))
|
viewModel.handle(RoomBannedMemberListAction.QueryInfo(roomMember))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
@ -60,7 +60,7 @@ class RoomBannedMemberListFragment @Inject constructor(
|
||||||
|
|
||||||
viewModel.observeViewEvents {
|
viewModel.observeViewEvents {
|
||||||
when (it) {
|
when (it) {
|
||||||
is RoomBannedViewEvents.ShowBannedInfo -> {
|
is RoomBannedMemberListViewEvents.ShowBannedInfo -> {
|
||||||
val canBan = withState(viewModel) { state -> state.canUserBan }
|
val canBan = withState(viewModel) { state -> state.canUserBan }
|
||||||
AlertDialog.Builder(requireActivity())
|
AlertDialog.Builder(requireActivity())
|
||||||
.setTitle(getString(R.string.member_banned_by, it.bannedByUserId))
|
.setTitle(getString(R.string.member_banned_by, it.bannedByUserId))
|
||||||
|
@ -69,13 +69,13 @@ class RoomBannedMemberListFragment @Inject constructor(
|
||||||
.apply {
|
.apply {
|
||||||
if (canBan) {
|
if (canBan) {
|
||||||
setNegativeButton(R.string.room_participants_action_unban) { _, _ ->
|
setNegativeButton(R.string.room_participants_action_unban) { _, _ ->
|
||||||
viewModel.handle(RoomBannedListMemberAction.UnBanUser(it.roomMemberSummary))
|
viewModel.handle(RoomBannedMemberListAction.UnBanUser(it.roomMemberSummary))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
is RoomBannedViewEvents.ToastError -> {
|
is RoomBannedMemberListViewEvents.ToastError -> {
|
||||||
requireActivity().toast(it.info)
|
requireActivity().toast(it.info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ class RoomBannedMemberListFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextChange(newText: String): Boolean {
|
override fun onQueryTextChange(newText: String): Boolean {
|
||||||
viewModel.handle(RoomBannedListMemberAction.Filter(newText))
|
viewModel.handle(RoomBannedMemberListAction.Filter(newText))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -19,7 +19,7 @@ package im.vector.app.features.roomprofile.banned
|
||||||
import im.vector.app.core.platform.VectorViewEvents
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||||
|
|
||||||
sealed class RoomBannedViewEvents : VectorViewEvents {
|
sealed class RoomBannedMemberListViewEvents : VectorViewEvents {
|
||||||
data class ShowBannedInfo(val bannedByUserId: String, val banReason: String, val roomMemberSummary: RoomMemberSummary) : RoomBannedViewEvents()
|
data class ShowBannedInfo(val bannedByUserId: String, val banReason: String, val roomMemberSummary: RoomMemberSummary) : RoomBannedMemberListViewEvents()
|
||||||
data class ToastError(val info: String) : RoomBannedViewEvents()
|
data class ToastError(val info: String) : RoomBannedMemberListViewEvents()
|
||||||
}
|
}
|
|
@ -42,14 +42,14 @@ import org.matrix.android.sdk.internal.util.awaitCallback
|
||||||
import org.matrix.android.sdk.rx.rx
|
import org.matrix.android.sdk.rx.rx
|
||||||
import org.matrix.android.sdk.rx.unwrap
|
import org.matrix.android.sdk.rx.unwrap
|
||||||
|
|
||||||
class RoomBannedListMemberViewModel @AssistedInject constructor(@Assisted initialState: RoomBannedMemberListViewState,
|
class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initialState: RoomBannedMemberListViewState,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val session: Session)
|
private val session: Session)
|
||||||
: VectorViewModel<RoomBannedMemberListViewState, RoomBannedListMemberAction, RoomBannedViewEvents>(initialState) {
|
: VectorViewModel<RoomBannedMemberListViewState, RoomBannedMemberListAction, RoomBannedMemberListViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedInject.Factory
|
@AssistedInject.Factory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
fun create(initialState: RoomBannedMemberListViewState): RoomBannedListMemberViewModel
|
fun create(initialState: RoomBannedMemberListViewState): RoomBannedMemberListViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
private val room = session.getRoom(initialState.roomId)!!
|
private val room = session.getRoom(initialState.roomId)!!
|
||||||
|
@ -78,24 +78,24 @@ class RoomBannedListMemberViewModel @AssistedInject constructor(@Assisted initia
|
||||||
}.disposeOnClear()
|
}.disposeOnClear()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<RoomBannedListMemberViewModel, RoomBannedMemberListViewState> {
|
companion object : MvRxViewModelFactory<RoomBannedMemberListViewModel, RoomBannedMemberListViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: RoomBannedMemberListViewState): RoomBannedListMemberViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: RoomBannedMemberListViewState): RoomBannedMemberListViewModel? {
|
||||||
val fragment: RoomBannedMemberListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
val fragment: RoomBannedMemberListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
return fragment.viewModelFactory.create(state)
|
return fragment.viewModelFactory.create(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handle(action: RoomBannedListMemberAction) {
|
override fun handle(action: RoomBannedMemberListAction) {
|
||||||
when (action) {
|
when (action) {
|
||||||
is RoomBannedListMemberAction.QueryInfo -> onQueryBanInfo(action.roomMemberSummary)
|
is RoomBannedMemberListAction.QueryInfo -> onQueryBanInfo(action.roomMemberSummary)
|
||||||
is RoomBannedListMemberAction.UnBanUser -> unBanUser(action.roomMemberSummary)
|
is RoomBannedMemberListAction.UnBanUser -> unBanUser(action.roomMemberSummary)
|
||||||
is RoomBannedListMemberAction.Filter -> handleFilter(action)
|
is RoomBannedMemberListAction.Filter -> handleFilter(action)
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleFilter(action: RoomBannedListMemberAction.Filter) {
|
private fun handleFilter(action: RoomBannedMemberListAction.Filter) {
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
filter = action.filter
|
filter = action.filter
|
||||||
|
@ -114,7 +114,7 @@ class RoomBannedListMemberViewModel @AssistedInject constructor(@Assisted initia
|
||||||
val reason = content.reason
|
val reason = content.reason
|
||||||
val bannedBy = bannedEvent?.senderId ?: return
|
val bannedBy = bannedEvent?.senderId ?: return
|
||||||
|
|
||||||
_viewEvents.post(RoomBannedViewEvents.ShowBannedInfo(bannedBy, reason ?: "", roomMemberSummary))
|
_viewEvents.post(RoomBannedMemberListViewEvents.ShowBannedInfo(bannedBy, reason ?: "", roomMemberSummary))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unBanUser(roomMemberSummary: RoomMemberSummary) {
|
private fun unBanUser(roomMemberSummary: RoomMemberSummary) {
|
||||||
|
@ -127,7 +127,7 @@ class RoomBannedListMemberViewModel @AssistedInject constructor(@Assisted initia
|
||||||
room.unban(roomMemberSummary.userId, null, it)
|
room.unban(roomMemberSummary.userId, null, it)
|
||||||
}
|
}
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomBannedViewEvents.ToastError(stringProvider.getString(R.string.failed_to_unban)))
|
_viewEvents.post(RoomBannedMemberListViewEvents.ToastError(stringProvider.getString(R.string.failed_to_unban)))
|
||||||
} finally {
|
} finally {
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
|
@ -24,7 +24,6 @@ sealed class RoomSettingsAction : VectorViewModelAction {
|
||||||
data class SetRoomName(val newName: String) : RoomSettingsAction()
|
data class SetRoomName(val newName: String) : RoomSettingsAction()
|
||||||
data class SetRoomTopic(val newTopic: String) : RoomSettingsAction()
|
data class SetRoomTopic(val newTopic: String) : RoomSettingsAction()
|
||||||
data class SetRoomHistoryVisibility(val visibility: RoomHistoryVisibility) : RoomSettingsAction()
|
data class SetRoomHistoryVisibility(val visibility: RoomHistoryVisibility) : RoomSettingsAction()
|
||||||
data class SetRoomCanonicalAlias(val newCanonicalAlias: String) : RoomSettingsAction()
|
|
||||||
object Save : RoomSettingsAction()
|
object Save : RoomSettingsAction()
|
||||||
object Cancel : RoomSettingsAction()
|
object Cancel : RoomSettingsAction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ class RoomSettingsController @Inject constructor(
|
||||||
fun onNameChanged(name: String)
|
fun onNameChanged(name: String)
|
||||||
fun onTopicChanged(topic: String)
|
fun onTopicChanged(topic: String)
|
||||||
fun onHistoryVisibilityClicked()
|
fun onHistoryVisibilityClicked()
|
||||||
fun onAliasChanged(alias: String)
|
fun onRoomAliasesClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color)
|
private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color)
|
||||||
|
@ -67,13 +67,13 @@ class RoomSettingsController @Inject constructor(
|
||||||
id("avatar")
|
id("avatar")
|
||||||
enabled(data.actionPermissions.canChangeAvatar)
|
enabled(data.actionPermissions.canChangeAvatar)
|
||||||
when (val avatarAction = data.avatarAction) {
|
when (val avatarAction = data.avatarAction) {
|
||||||
RoomSettingsViewState.AvatarAction.None -> {
|
RoomSettingsViewState.AvatarAction.None -> {
|
||||||
// Use the current value
|
// Use the current value
|
||||||
avatarRenderer(avatarRenderer)
|
avatarRenderer(avatarRenderer)
|
||||||
// We do not want to use the fallback avatar url, which can be the other user avatar, or the current user avatar.
|
// We do not want to use the fallback avatar url, which can be the other user avatar, or the current user avatar.
|
||||||
matrixItem(roomSummary.toMatrixItem().copy(avatarUrl = data.currentRoomAvatarUrl))
|
matrixItem(roomSummary.toMatrixItem().copy(avatarUrl = data.currentRoomAvatarUrl))
|
||||||
}
|
}
|
||||||
RoomSettingsViewState.AvatarAction.DeleteAvatar ->
|
RoomSettingsViewState.AvatarAction.DeleteAvatar ->
|
||||||
imageUri(null)
|
imageUri(null)
|
||||||
is RoomSettingsViewState.AvatarAction.UpdateAvatar ->
|
is RoomSettingsViewState.AvatarAction.UpdateAvatar ->
|
||||||
imageUri(avatarAction.newAvatarUri)
|
imageUri(avatarAction.newAvatarUri)
|
||||||
|
@ -108,16 +108,15 @@ class RoomSettingsController @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formEditTextItem {
|
buildProfileAction(
|
||||||
id("alias")
|
id = "alias",
|
||||||
enabled(data.actionPermissions.canChangeCanonicalAlias)
|
title = stringProvider.getString(R.string.room_settings_alias_title),
|
||||||
value(data.newCanonicalAlias ?: roomSummary.canonicalAlias)
|
subtitle = stringProvider.getString(R.string.room_settings_alias_subtitle),
|
||||||
hint(stringProvider.getString(R.string.room_settings_addresses_add_new_address))
|
dividerColor = dividerColor,
|
||||||
|
divider = true,
|
||||||
onTextChange { text ->
|
editable = true,
|
||||||
callback?.onAliasChanged(text)
|
action = { callback?.onRoomAliasesClicked() }
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
buildProfileAction(
|
buildProfileAction(
|
||||||
id = "historyReadability",
|
id = "historyReadability",
|
||||||
|
|
|
@ -39,6 +39,8 @@ import im.vector.app.core.utils.toast
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.detail.timeline.format.RoomHistoryVisibilityFormatter
|
import im.vector.app.features.home.room.detail.timeline.format.RoomHistoryVisibilityFormatter
|
||||||
import im.vector.app.features.roomprofile.RoomProfileArgs
|
import im.vector.app.features.roomprofile.RoomProfileArgs
|
||||||
|
import im.vector.app.features.roomprofile.RoomProfileSharedAction
|
||||||
|
import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel
|
||||||
import kotlinx.android.synthetic.main.fragment_room_setting_generic.*
|
import kotlinx.android.synthetic.main.fragment_room_setting_generic.*
|
||||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
|
@ -61,6 +63,7 @@ class RoomSettingsFragment @Inject constructor(
|
||||||
GalleryOrCameraDialogHelper.Listener {
|
GalleryOrCameraDialogHelper.Listener {
|
||||||
|
|
||||||
private val viewModel: RoomSettingsViewModel by fragmentViewModel()
|
private val viewModel: RoomSettingsViewModel by fragmentViewModel()
|
||||||
|
private lateinit var roomProfileSharedActionViewModel: RoomProfileSharedActionViewModel
|
||||||
private val roomProfileArgs: RoomProfileArgs by args()
|
private val roomProfileArgs: RoomProfileArgs by args()
|
||||||
private val galleryOrCameraDialogHelper = GalleryOrCameraDialogHelper(this, colorProvider)
|
private val galleryOrCameraDialogHelper = GalleryOrCameraDialogHelper(this, colorProvider)
|
||||||
|
|
||||||
|
@ -70,6 +73,7 @@ class RoomSettingsFragment @Inject constructor(
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
roomProfileSharedActionViewModel = activityViewModelProvider.get(RoomProfileSharedActionViewModel::class.java)
|
||||||
controller.callback = this
|
controller.callback = this
|
||||||
setupToolbar(roomSettingsToolbar)
|
setupToolbar(roomSettingsToolbar)
|
||||||
roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true)
|
roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true)
|
||||||
|
@ -164,8 +168,8 @@ class RoomSettingsFragment @Inject constructor(
|
||||||
return@withState
|
return@withState
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAliasChanged(alias: String) {
|
override fun onRoomAliasesClicked() {
|
||||||
viewModel.handle(RoomSettingsAction.SetRoomCanonicalAlias(alias))
|
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomAliasesSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onImageReady(uri: Uri?) {
|
override fun onImageReady(uri: Uri?) {
|
||||||
|
|
|
@ -68,12 +68,10 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
selectSubscribe(
|
selectSubscribe(
|
||||||
RoomSettingsViewState::avatarAction,
|
RoomSettingsViewState::avatarAction,
|
||||||
RoomSettingsViewState::newName,
|
RoomSettingsViewState::newName,
|
||||||
RoomSettingsViewState::newCanonicalAlias,
|
|
||||||
RoomSettingsViewState::newTopic,
|
RoomSettingsViewState::newTopic,
|
||||||
RoomSettingsViewState::newHistoryVisibility,
|
RoomSettingsViewState::newHistoryVisibility,
|
||||||
RoomSettingsViewState::roomSummary) { avatarAction,
|
RoomSettingsViewState::roomSummary) { avatarAction,
|
||||||
newName,
|
newName,
|
||||||
newCanonicalAlias,
|
|
||||||
newTopic,
|
newTopic,
|
||||||
newHistoryVisibility,
|
newHistoryVisibility,
|
||||||
asyncSummary ->
|
asyncSummary ->
|
||||||
|
@ -83,7 +81,6 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
showSaveAction = avatarAction !is RoomSettingsViewState.AvatarAction.None
|
showSaveAction = avatarAction !is RoomSettingsViewState.AvatarAction.None
|
||||||
|| summary?.name != newName
|
|| summary?.name != newName
|
||||||
|| summary?.topic != newTopic
|
|| summary?.topic != newTopic
|
||||||
|| summary?.canonicalAlias != newCanonicalAlias?.takeIf { it.isNotEmpty() }
|
|
||||||
|| newHistoryVisibility != null
|
|| newHistoryVisibility != null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -99,8 +96,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
historyVisibilityEvent = room.getStateEvent(EventType.STATE_ROOM_HISTORY_VISIBILITY),
|
historyVisibilityEvent = room.getStateEvent(EventType.STATE_ROOM_HISTORY_VISIBILITY),
|
||||||
roomSummary = async,
|
roomSummary = async,
|
||||||
newName = roomSummary?.name,
|
newName = roomSummary?.name,
|
||||||
newTopic = roomSummary?.topic,
|
newTopic = roomSummary?.topic
|
||||||
newCanonicalAlias = roomSummary?.canonicalAlias
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +109,6 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR),
|
canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR),
|
||||||
canChangeName = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME),
|
canChangeName = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME),
|
||||||
canChangeTopic = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC),
|
canChangeTopic = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC),
|
||||||
canChangeCanonicalAlias = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true,
|
|
||||||
EventType.STATE_ROOM_CANONICAL_ALIAS),
|
|
||||||
canChangeHistoryReadability = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true,
|
canChangeHistoryReadability = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true,
|
||||||
EventType.STATE_ROOM_HISTORY_VISIBILITY)
|
EventType.STATE_ROOM_HISTORY_VISIBILITY)
|
||||||
)
|
)
|
||||||
|
@ -143,7 +137,6 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
is RoomSettingsAction.SetRoomName -> setState { copy(newName = action.newName) }
|
is RoomSettingsAction.SetRoomName -> setState { copy(newName = action.newName) }
|
||||||
is RoomSettingsAction.SetRoomTopic -> setState { copy(newTopic = action.newTopic) }
|
is RoomSettingsAction.SetRoomTopic -> setState { copy(newTopic = action.newTopic) }
|
||||||
is RoomSettingsAction.SetRoomHistoryVisibility -> setState { copy(newHistoryVisibility = action.visibility) }
|
is RoomSettingsAction.SetRoomHistoryVisibility -> setState { copy(newHistoryVisibility = action.visibility) }
|
||||||
is RoomSettingsAction.SetRoomCanonicalAlias -> setState { copy(newCanonicalAlias = action.newCanonicalAlias) }
|
|
||||||
is RoomSettingsAction.Save -> saveSettings()
|
is RoomSettingsAction.Save -> saveSettings()
|
||||||
is RoomSettingsAction.Cancel -> cancel()
|
is RoomSettingsAction.Cancel -> cancel()
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
|
@ -191,11 +184,6 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
operationList.add(room.rx().updateTopic(state.newTopic ?: ""))
|
operationList.add(room.rx().updateTopic(state.newTopic ?: ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.newCanonicalAlias != null && summary?.canonicalAlias != state.newCanonicalAlias.takeIf { it.isNotEmpty() }) {
|
|
||||||
operationList.add(room.rx().addRoomAlias(state.newCanonicalAlias))
|
|
||||||
operationList.add(room.rx().updateCanonicalAlias(state.newCanonicalAlias))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.newHistoryVisibility != null) {
|
if (state.newHistoryVisibility != null) {
|
||||||
operationList.add(room.rx().updateHistoryReadability(state.newHistoryVisibility))
|
operationList.add(room.rx().updateHistoryReadability(state.newHistoryVisibility))
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ data class RoomSettingsViewState(
|
||||||
val newName: String? = null,
|
val newName: String? = null,
|
||||||
val newTopic: String? = null,
|
val newTopic: String? = null,
|
||||||
val newHistoryVisibility: RoomHistoryVisibility? = null,
|
val newHistoryVisibility: RoomHistoryVisibility? = null,
|
||||||
val newCanonicalAlias: String? = null,
|
|
||||||
val showSaveAction: Boolean = false,
|
val showSaveAction: Boolean = false,
|
||||||
val actionPermissions: ActionPermissions = ActionPermissions()
|
val actionPermissions: ActionPermissions = ActionPermissions()
|
||||||
) : MvRxState {
|
) : MvRxState {
|
||||||
|
@ -46,7 +45,6 @@ data class RoomSettingsViewState(
|
||||||
val canChangeAvatar: Boolean = false,
|
val canChangeAvatar: Boolean = false,
|
||||||
val canChangeName: Boolean = false,
|
val canChangeName: Boolean = false,
|
||||||
val canChangeTopic: Boolean = false,
|
val canChangeTopic: Boolean = false,
|
||||||
val canChangeCanonicalAlias: Boolean = false,
|
|
||||||
val canChangeHistoryReadability: Boolean = false
|
val canChangeHistoryReadability: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,41 +1,47 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:pathData="M2.25,5.5H5.1667H21.75"
|
android:fillColor="#00000000"
|
||||||
android:strokeLineJoin="round"
|
android:pathData="M2.25,5.5H5.1667H21.75"
|
||||||
android:strokeWidth="2"
|
android:strokeWidth="2"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#2E2F32"
|
||||||
android:strokeColor="#2E2F32"
|
android:strokeLineCap="round"
|
||||||
android:strokeLineCap="round"/>
|
android:strokeLineJoin="round"
|
||||||
<path
|
tools:strokeColor="@color/riotx_destructive_accent" />
|
||||||
android:pathData="M16.5,5.5L15,1H9L7.5,5.5"
|
<path
|
||||||
android:strokeLineJoin="round"
|
android:fillColor="#00000000"
|
||||||
android:strokeWidth="2"
|
android:pathData="M16.5,5.5L15,1H9L7.5,5.5"
|
||||||
android:fillColor="#00000000"
|
android:strokeWidth="2"
|
||||||
android:strokeColor="#2E2F32"
|
android:strokeColor="#2E2F32"
|
||||||
android:strokeLineCap="round"/>
|
android:strokeLineCap="round"
|
||||||
<path
|
android:strokeLineJoin="round"
|
||||||
android:pathData="M5.25,9.25V20.75C5.25,21.8546 6.1454,22.75 7.25,22.75H16.75C17.8546,22.75 18.75,21.8546 18.75,20.75V9.25"
|
tools:strokeColor="@color/riotx_destructive_accent" />
|
||||||
android:strokeLineJoin="round"
|
<path
|
||||||
android:strokeWidth="2"
|
android:fillColor="#00000000"
|
||||||
android:fillColor="#00000000"
|
android:pathData="M5.25,9.25V20.75C5.25,21.8546 6.1454,22.75 7.25,22.75H16.75C17.8546,22.75 18.75,21.8546 18.75,20.75V9.25"
|
||||||
android:strokeColor="#2E2F32"
|
android:strokeWidth="2"
|
||||||
android:strokeLineCap="round"/>
|
android:strokeColor="#2E2F32"
|
||||||
<path
|
android:strokeLineCap="round"
|
||||||
android:pathData="M9.75,9.25V18.25"
|
android:strokeLineJoin="round"
|
||||||
android:strokeLineJoin="round"
|
tools:strokeColor="@color/riotx_destructive_accent" />
|
||||||
android:strokeWidth="2"
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:strokeColor="#2E2F32"
|
android:pathData="M9.75,9.25V18.25"
|
||||||
android:strokeLineCap="round"/>
|
android:strokeWidth="2"
|
||||||
<path
|
android:strokeColor="#2E2F32"
|
||||||
android:pathData="M14.25,9.25V18.25"
|
android:strokeLineCap="round"
|
||||||
android:strokeLineJoin="round"
|
android:strokeLineJoin="round"
|
||||||
android:strokeWidth="2"
|
tools:strokeColor="@color/riotx_destructive_accent" />
|
||||||
android:fillColor="#00000000"
|
<path
|
||||||
android:strokeColor="#2E2F32"
|
android:fillColor="#00000000"
|
||||||
android:strokeLineCap="round"/>
|
android:pathData="M14.25,9.25V18.25"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:strokeColor="#2E2F32"
|
||||||
|
android:strokeLineCap="round"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
tools:strokeColor="@color/riotx_destructive_accent" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -20,10 +20,12 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<!-- android:imeOptions="actionDone" to fix a crash -->
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/formTextInputTextInputEditText"
|
android:id="@+id/formTextInputTextInputEditText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
tools:hint="@string/create_room_name_hint" />
|
tools:hint="@string/create_room_name_hint" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
|
@ -30,11 +30,13 @@
|
||||||
app:layout_constraintStart_toEndOf="@+id/itemRoomAliasHash"
|
app:layout_constraintStart_toEndOf="@+id/itemRoomAliasHash"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<!-- android:imeOptions="actionDone" to fix a crash -->
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/itemRoomAliasTextInputEditText"
|
android:id="@+id/itemRoomAliasTextInputEditText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/create_room_alias_hint"
|
android:hint="@string/create_room_alias_hint"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
android:inputType="text" />
|
android:inputType="text" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?riotx_background"
|
||||||
android:minHeight="64dp"
|
android:minHeight="64dp"
|
||||||
android:paddingStart="@dimen/layout_horizontal_margin"
|
android:paddingStart="@dimen/layout_horizontal_margin"
|
||||||
android:paddingEnd="@dimen/layout_horizontal_margin">
|
android:paddingEnd="@dimen/layout_horizontal_margin">
|
||||||
|
@ -12,19 +13,20 @@
|
||||||
android:id="@+id/item_settings_three_pid_icon"
|
android:id="@+id/item_settings_three_pid_icon"
|
||||||
android:layout_width="16dp"
|
android:layout_width="16dp"
|
||||||
android:layout_height="16dp"
|
android:layout_height="16dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/item_settings_three_pid_title"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:src="@drawable/ic_phone"
|
|
||||||
app:tint="?riotx_text_secondary"
|
app:tint="?riotx_text_secondary"
|
||||||
tools:ignore="MissingPrefix" />
|
tools:ignore="MissingPrefix"
|
||||||
|
tools:src="@drawable/ic_phone" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/item_settings_three_pid_title"
|
android:id="@+id/item_settings_three_pid_title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginBottom="4dp"
|
android:layout_marginBottom="4dp"
|
||||||
android:textColor="?riotx_text_primary"
|
android:textColor="?riotx_text_primary"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
|
|
|
@ -137,6 +137,8 @@
|
||||||
<string name="action_open">Open</string>
|
<string name="action_open">Open</string>
|
||||||
<string name="action_close">Close</string>
|
<string name="action_close">Close</string>
|
||||||
<string name="action_copy">Copy</string>
|
<string name="action_copy">Copy</string>
|
||||||
|
<string name="action_add">Add</string>
|
||||||
|
<string name="action_unpublish">Unpublish</string>
|
||||||
<string name="copied_to_clipboard">Copied to clipboard</string>
|
<string name="copied_to_clipboard">Copied to clipboard</string>
|
||||||
<string name="disable">Disable</string>
|
<string name="disable">Disable</string>
|
||||||
|
|
||||||
|
@ -1022,6 +1024,40 @@
|
||||||
<string name="room_settings_room_read_history_rules_pref_dialog_title">Who can read history?</string>
|
<string name="room_settings_room_read_history_rules_pref_dialog_title">Who can read history?</string>
|
||||||
<string name="room_settings_room_access_rules_pref_dialog_title">Who can access this room?</string>
|
<string name="room_settings_room_access_rules_pref_dialog_title">Who can access this room?</string>
|
||||||
|
|
||||||
|
<!-- room settings : alias -->
|
||||||
|
<string name="room_settings_alias_title">Room addresses</string>
|
||||||
|
<string name="room_settings_alias_subtitle">See and managed addresses of this room, and its visibility in the room directory.</string>
|
||||||
|
|
||||||
|
<string name="room_alias_title">Room Addresses</string>
|
||||||
|
<string name="room_alias_published_alias_title">Published Addresses</string>
|
||||||
|
<string name="room_alias_published_alias_subtitle">Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.</string>
|
||||||
|
<string name="room_alias_published_alias_main">This is the main address</string>
|
||||||
|
<string name="room_alias_main_address_hint">Main address</string>
|
||||||
|
<string name="room_alias_published_other">Other published addresses:</string>
|
||||||
|
<string name="room_alias_published_alias_add_manually">Publish a new address manually</string>
|
||||||
|
<string name="room_alias_published_alias_add_manually_submit">Publish</string>
|
||||||
|
<string name="room_alias_unpublish_confirmation">Unpublish the address \"%1$s\"?</string>
|
||||||
|
<string name="room_alias_delete_confirmation">Delete the address \"%1$s\"?</string>
|
||||||
|
<!-- Parameter will be the url of the homeserver, ex: matrix.org -->
|
||||||
|
<string name="room_alias_publish">Publish this room to the public in %1$s\'s room directory?</string>
|
||||||
|
<string name="room_alias_address_empty_can_add">No other published addresses yet, add one below.</string>
|
||||||
|
<string name="room_alias_address_empty">No other published addresses yet.</string>
|
||||||
|
<string name="room_alias_address_hint">New published address (e.g. #alias:server)</string>
|
||||||
|
|
||||||
|
<string name="room_alias_local_address_title">Local Addresses</string>
|
||||||
|
<!-- Parameter will be the url of the homeserver, ex: matrix.org -->
|
||||||
|
<string name="room_alias_local_address_subtitle">Set addresses for this room so users can find this room through your homeserver (%1$s)</string>
|
||||||
|
<string name="room_alias_local_address_empty">This room has no local addresses</string>
|
||||||
|
<string name="room_alias_local_address_add">Add a local address</string>
|
||||||
|
|
||||||
|
<string name="room_alias_action_publish">Publish this address</string>
|
||||||
|
<string name="room_alias_action_unpublish">Unpublish this address</string>
|
||||||
|
|
||||||
|
<!-- Parameter will be the url of the homeserver, ex: matrix.org -->
|
||||||
|
<string name="room_alias_publish_to_directory">Publish this room to the public in %1$s\'s room directory?</string>
|
||||||
|
<!-- Parameter will be a technical error message -->
|
||||||
|
<string name="room_alias_publish_to_directory_error">Unable to retrieve the current room directory visibility (%1$s).</string>
|
||||||
|
|
||||||
<!-- Room settings, access and visibility : WHO CAN READ HISTORY? (read rule) -->
|
<!-- Room settings, access and visibility : WHO CAN READ HISTORY? (read rule) -->
|
||||||
<string name="room_settings_read_history_entry_anyone">Anyone</string>
|
<string name="room_settings_read_history_entry_anyone">Anyone</string>
|
||||||
<string name="room_settings_read_history_entry_members_only_option_time_shared">Members only (since the point in time of selecting this option)</string>
|
<string name="room_settings_read_history_entry_members_only_option_time_shared">Members only (since the point in time of selecting this option)</string>
|
||||||
|
@ -1068,8 +1104,8 @@
|
||||||
<string name="room_settings_addresses_disable_main_address_prompt_msg">You will have no main address specified for this room."</string>
|
<string name="room_settings_addresses_disable_main_address_prompt_msg">You will have no main address specified for this room."</string>
|
||||||
<string name="room_settings_addresses_disable_main_address_prompt_title">Main address warnings</string>
|
<string name="room_settings_addresses_disable_main_address_prompt_title">Main address warnings</string>
|
||||||
|
|
||||||
<string name="room_settings_set_main_address">Set as Main Address</string>
|
<string name="room_settings_set_main_address">Set as main address</string>
|
||||||
<string name="room_settings_unset_main_address">Unset as Main Address</string>
|
<string name="room_settings_unset_main_address">Unset as main address</string>
|
||||||
<string name="room_settings_copy_room_id">Copy Room ID</string>
|
<string name="room_settings_copy_room_id">Copy Room ID</string>
|
||||||
<string name="room_settings_copy_room_address">Copy Room Address</string>
|
<string name="room_settings_copy_room_address">Copy Room Address</string>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue