Share button in rooms gives room ID link without via parameters (#1927)

Following the algorithm described in #1927
Create a PermalinkService
This commit is contained in:
Benoit Marty 2020-08-20 12:28:25 +02:00
parent 187edbd32a
commit af10344b6b
13 changed files with 202 additions and 86 deletions

View File

@ -6,6 +6,7 @@ Features ✨:
- Conference with Jitsi support (#43) - Conference with Jitsi support (#43)
Improvements 🙌: Improvements 🙌:
- Share button in rooms gives room ID link without via parameters (#1927)
- Give user the possibility to prevent accidental call (#1869) - Give user the possibility to prevent accidental call (#1869)
- Display device information (name, id and key) in Cryptography setting screen (#1784) - Display device information (name, id and key) in Cryptography setting screen (#1784)
- Ensure users do not accidentally ignore other users (#1890) - Ensure users do not accidentally ignore other users (#1890)

View File

@ -37,7 +37,7 @@ object PermalinkParser {
* Turns an uri to a [PermalinkData] * Turns an uri to a [PermalinkData]
*/ */
fun parse(uri: Uri): PermalinkData { fun parse(uri: Uri): PermalinkData {
if (!uri.toString().startsWith(PermalinkFactory.MATRIX_TO_URL_BASE)) { if (!uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE)) {
return PermalinkData.FallbackLink(uri) return PermalinkData.FallbackLink(uri)
} }

View File

@ -22,48 +22,51 @@ import org.matrix.android.sdk.api.session.events.model.Event
/** /**
* Useful methods to create Matrix permalink (matrix.to links). * Useful methods to create Matrix permalink (matrix.to links).
*/ */
object PermalinkFactory { interface PermalinkService {
const val MATRIX_TO_URL_BASE = "https://matrix.to/#/" companion object {
const val MATRIX_TO_URL_BASE = "https://matrix.to/#/"
}
/** /**
* Creates a permalink for an event. * Creates a permalink for an event.
* Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org" * Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org"
* *
* @param event the event * @param event the event
*
* @return the permalink, or null in case of error * @return the permalink, or null in case of error
*/ */
fun createPermalink(event: Event): String? { fun createPermalink(event: Event): String?
if (event.roomId.isNullOrEmpty() || event.eventId.isNullOrEmpty()) {
return null
}
return createPermalink(event.roomId, event.eventId)
}
/** /**
* Creates a permalink for an id (can be a user Id, Room Id, etc.). * Creates a permalink for an id (can be a user Id, etc.).
* For a roomId, consider using [createRoomPermalink]
* Ex: "https://matrix.to/#/@benoit:matrix.org" * Ex: "https://matrix.to/#/@benoit:matrix.org"
* *
* @param id the id * @param id the id
* @return the permalink, or null in case of error * @return the permalink, or null in case of error
*/ */
fun createPermalink(id: String): String? { fun createPermalink(id: String): String?
return if (id.isEmpty()) {
null
} else MATRIX_TO_URL_BASE + escape(id)
}
/** /**
* Creates a permalink for an event. If you have an event you can use [.createPermalink] * Creates a permalink for a roomId, including the via parameters
* Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org" *
* @param roomId the room id
*
* @return the permalink, or null in case of error
*/
fun createRoomPermalink(roomId: String): String?
/**
* Creates a permalink for an event. If you have an event you can use [createPermalink]
* Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org?via=matrix.org"
* *
* @param roomId the id of the room * @param roomId the id of the room
* @param eventId the id of the event * @param eventId the id of the event
*
* @return the permalink * @return the permalink
*/ */
fun createPermalink(roomId: String, eventId: String): String { fun createPermalink(roomId: String, eventId: String): String
return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId)
}
/** /**
* Extract the linked id from the universal link * Extract the linked id from the universal link
@ -71,31 +74,5 @@ object PermalinkFactory {
* @param url the universal link, Ex: "https://matrix.to/#/@benoit:matrix.org" * @param url the universal link, Ex: "https://matrix.to/#/@benoit:matrix.org"
* @return the id from the url, ex: "@benoit:matrix.org", or null if the url is not a permalink * @return the id from the url, ex: "@benoit:matrix.org", or null if the url is not a permalink
*/ */
fun getLinkedId(url: String): String? { fun getLinkedId(url: String): String?
val isSupported = url.startsWith(MATRIX_TO_URL_BASE)
return if (isSupported) {
url.substring(MATRIX_TO_URL_BASE.length)
} else null
}
/**
* Escape '/' in id, because it is used as a separator
*
* @param id the id to escape
* @return the escaped id
*/
internal fun escape(id: String): String {
return id.replace("/", "%2F")
}
/**
* Unescape '/' in id
*
* @param id the id to escape
* @return the escaped id
*/
internal fun unescape(id: String): String {
return id.replace("%2F", "/")
}
} }

View File

@ -49,6 +49,7 @@ import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
import org.matrix.android.sdk.api.session.user.UserService import org.matrix.android.sdk.api.session.user.UserService
import org.matrix.android.sdk.api.session.widgets.WidgetService import org.matrix.android.sdk.api.session.widgets.WidgetService
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import org.matrix.android.sdk.api.permalinks.PermalinkService
/** /**
* This interface defines interactions with a session. * This interface defines interactions with a session.
@ -195,6 +196,11 @@ interface Session :
*/ */
fun fileService(): FileService fun fileService(): FileService
/**
* Returns the permalink service associated with the session
*/
fun permalinkService(): PermalinkService
/** /**
* Add a listener to the session. * Add a listener to the session.
* @param listener the listener to add. * @param listener the listener to add.

View File

@ -70,6 +70,7 @@ import okhttp3.OkHttpClient
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import org.matrix.android.sdk.api.permalinks.PermalinkService
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Provider import javax.inject.Provider
@ -96,6 +97,7 @@ internal class DefaultSession @Inject constructor(
private val termsService: Lazy<TermsService>, private val termsService: Lazy<TermsService>,
private val cryptoService: Lazy<DefaultCryptoService>, private val cryptoService: Lazy<DefaultCryptoService>,
private val defaultFileService: Lazy<FileService>, private val defaultFileService: Lazy<FileService>,
private val permalinkService: Lazy<PermalinkService>,
private val secureStorageService: Lazy<SecureStorageService>, private val secureStorageService: Lazy<SecureStorageService>,
private val profileService: Lazy<ProfileService>, private val profileService: Lazy<ProfileService>,
private val widgetService: Lazy<WidgetService>, private val widgetService: Lazy<WidgetService>,
@ -254,6 +256,8 @@ internal class DefaultSession @Inject constructor(
override fun fileService(): FileService = defaultFileService.get() override fun fileService(): FileService = defaultFileService.get()
override fun permalinkService(): PermalinkService = permalinkService.get()
override fun widgetService(): WidgetService = widgetService.get() override fun widgetService(): WidgetService = widgetService.get()
override fun integrationManagerService() = integrationManagerService override fun integrationManagerService() = integrationManagerService

View File

@ -84,6 +84,8 @@ import org.matrix.android.sdk.internal.util.md5
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.matrix.android.sdk.api.permalinks.PermalinkService
import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService
import retrofit2.Retrofit import retrofit2.Retrofit
import java.io.File import java.io.File
import javax.inject.Provider import javax.inject.Provider
@ -356,6 +358,9 @@ internal abstract class SessionModule {
@Binds @Binds
abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService
@Binds
abstract fun bindPermalinkService(service: DefaultPermalinkService): PermalinkService
@Binds @Binds
abstract fun bindTypingUsersTracker(tracker: DefaultTypingUsersTracker): TypingUsersTracker abstract fun bindTypingUsersTracker(tracker: DefaultTypingUsersTracker): TypingUsersTracker
} }

View File

@ -0,0 +1,119 @@
/*
* 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 org.matrix.android.sdk.internal.session.permalinks
import org.matrix.android.sdk.api.permalinks.PermalinkService
import org.matrix.android.sdk.api.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.room.RoomGetter
import java.net.URLEncoder
import javax.inject.Inject
import javax.inject.Provider
internal class DefaultPermalinkService @Inject constructor(
@UserId
private val userId: String,
// Use a provider to fix circular Dagger dependency
private val roomGetterProvider: Provider<RoomGetter>
) : PermalinkService {
override fun createPermalink(event: Event): String? {
if (event.roomId.isNullOrEmpty() || event.eventId.isNullOrEmpty()) {
return null
}
return createPermalink(event.roomId, event.eventId)
}
override fun createPermalink(id: String): String? {
return if (id.isEmpty()) {
null
} else MATRIX_TO_URL_BASE + escape(id)
}
override fun createRoomPermalink(roomId: String): String? {
return if (roomId.isEmpty()) {
null
} else {
MATRIX_TO_URL_BASE + escape(roomId) + computeViaParams(userId, roomId)
}
}
override fun createPermalink(roomId: String, eventId: String): String {
return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + computeViaParams(userId, roomId)
}
override fun getLinkedId(url: String): String? {
val isSupported = url.startsWith(MATRIX_TO_URL_BASE)
return if (isSupported) {
url.substring(MATRIX_TO_URL_BASE.length)
} else null
}
/**
* Compute the via parameters.
* Take up to 3 homeserver domains, taking the most representative one regarding room members and including the
* current user one.
*/
private fun computeViaParams(userId: String, roomId: String): String {
val userHomeserver = userId.substringAfter(":")
return getUserIdsOfJoinedMembers(roomId)
.map { it.substringAfter(":") }
.groupBy { it }
.mapValues { it.value.size }
.toMutableMap()
// Ensure the user homeserver will be included
.apply { this[userHomeserver] = Int.MAX_VALUE }
.let { map -> map.keys.sortedByDescending { map[it] } }
.take(3)
.joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") }
}
/**
* Escape '/' in id, because it is used as a separator
*
* @param id the id to escape
* @return the escaped id
*/
private fun escape(id: String): String {
return id.replace("/", "%2F")
}
/**
* Unescape '/' in id
*
* @param id the id to escape
* @return the escaped id
*/
private fun unescape(id: String): String {
return id.replace("%2F", "/")
}
/**
* Get a set of userIds of joined members of a room
*/
private fun getUserIdsOfJoinedMembers(roomId: String): Set<String> {
return roomGetterProvider.get().getRoom(roomId)
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
?.map { it.userId }
.orEmpty()
.toSet()
}
}

View File

@ -156,11 +156,15 @@ internal class DefaultRelationService @AssistedInject constructor(
originalTimelineEvent: TimelineEvent, originalTimelineEvent: TimelineEvent,
newBodyText: String, newBodyText: String,
compatibilityBodyText: String): Cancelable { compatibilityBodyText: String): Cancelable {
val event = eventFactory val event = eventFactory.createReplaceTextOfReply(
.createReplaceTextOfReply(roomId, roomId,
replyToEdit, replyToEdit,
originalTimelineEvent, originalTimelineEvent,
newBodyText, true, MessageType.MSGTYPE_TEXT, compatibilityBodyText) newBodyText,
true,
MessageType.MSGTYPE_TEXT,
compatibilityBodyText
)
.also { saveLocalEcho(it) } .also { saveLocalEcho(it) }
return if (cryptoService.isRoomEncrypted(roomId)) { return if (cryptoService.isRoomEncrypted(roomId)) {
val encryptWork = createEncryptEventWork(event, listOf("m.relates_to")) val encryptWork = createEncryptEventWork(event, listOf("m.relates_to"))

View File

@ -22,7 +22,7 @@ import android.graphics.Bitmap
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import androidx.exifinterface.media.ExifInterface import androidx.exifinterface.media.ExifInterface
import org.matrix.android.sdk.R import org.matrix.android.sdk.R
import org.matrix.android.sdk.api.permalinks.PermalinkFactory import org.matrix.android.sdk.api.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.content.ContentAttachmentData
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
@ -60,7 +60,6 @@ import org.matrix.android.sdk.api.session.room.timeline.isReply
import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.content.ThumbnailExtractor import org.matrix.android.sdk.internal.session.content.ThumbnailExtractor
import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils
import org.matrix.android.sdk.internal.task.TaskExecutor
import org.matrix.android.sdk.internal.util.StringProvider import org.matrix.android.sdk.internal.util.StringProvider
import javax.inject.Inject import javax.inject.Inject
@ -79,8 +78,8 @@ internal class LocalEchoEventFactory @Inject constructor(
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
private val markdownParser: MarkdownParser, private val markdownParser: MarkdownParser,
private val textPillsUtils: TextPillsUtils, private val textPillsUtils: TextPillsUtils,
private val taskExecutor: TaskExecutor, private val localEchoRepository: LocalEchoRepository,
private val localEchoRepository: LocalEchoRepository private val permalinkService: PermalinkService
) { ) {
fun createTextEvent(roomId: String, msgType: String, text: CharSequence, autoMarkdown: Boolean): Event { fun createTextEvent(roomId: String, msgType: String, text: CharSequence, autoMarkdown: Boolean): Event {
if (msgType == MessageType.MSGTYPE_TEXT || msgType == MessageType.MSGTYPE_EMOTE) { if (msgType == MessageType.MSGTYPE_TEXT || msgType == MessageType.MSGTYPE_EMOTE) {
@ -169,9 +168,8 @@ internal class LocalEchoEventFactory @Inject constructor(
newBodyAutoMarkdown: Boolean, newBodyAutoMarkdown: Boolean,
msgType: String, msgType: String,
compatibilityText: String): Event { compatibilityText: String): Event {
val permalink = PermalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "") val permalink = permalinkService.createPermalink(roomId, originalEvent.root.eventId ?: "")
val userLink = originalEvent.root.senderId?.let { PermalinkFactory.createPermalink(it) } val userLink = originalEvent.root.senderId?.let { permalinkService.createPermalink(it) } ?: ""
?: ""
val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.isReply()) val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.isReply())
val replyFormatted = REPLY_PATTERN.format( val replyFormatted = REPLY_PATTERN.format(
@ -361,12 +359,15 @@ internal class LocalEchoEventFactory @Inject constructor(
return System.currentTimeMillis() return System.currentTimeMillis()
} }
fun createReplyTextEvent(roomId: String, eventReplied: TimelineEvent, replyText: CharSequence, autoMarkdown: Boolean): Event? { fun createReplyTextEvent(roomId: String,
eventReplied: TimelineEvent,
replyText: CharSequence,
autoMarkdown: Boolean): Event? {
// Fallbacks and event representation // Fallbacks and event representation
// TODO Add error/warning logs when any of this is null // TODO Add error/warning logs when any of this is null
val permalink = PermalinkFactory.createPermalink(eventReplied.root) ?: return null val permalink = permalinkService.createPermalink(eventReplied.root) ?: return null
val userId = eventReplied.root.senderId ?: return null val userId = eventReplied.root.senderId ?: return null
val userLink = PermalinkFactory.createPermalink(userId) ?: return null val userLink = permalinkService.createPermalink(userId) ?: return null
val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply()) val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply())
val replyFormatted = REPLY_PATTERN.format( val replyFormatted = REPLY_PATTERN.format(

View File

@ -163,7 +163,6 @@ import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.billcarsonfr.jsonviewer.JSonViewerDialog
import org.commonmark.parser.Parser import org.commonmark.parser.Parser
import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.permalinks.PermalinkFactory
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.content.ContentAttachmentData
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
@ -1608,7 +1607,7 @@ class RoomDetailFragment @Inject constructor(
roomDetailViewModel.handle(RoomDetailAction.EnterReplyMode(action.eventId, composerLayout.text.toString())) roomDetailViewModel.handle(RoomDetailAction.EnterReplyMode(action.eventId, composerLayout.text.toString()))
} }
is EventSharedAction.CopyPermalink -> { is EventSharedAction.CopyPermalink -> {
val permalink = PermalinkFactory.createPermalink(roomDetailArgs.roomId, action.eventId) val permalink = session.permalinkService().createPermalink(roomDetailArgs.roomId, action.eventId)
copyToClipboard(requireContext(), permalink, false) copyToClipboard(requireContext(), permalink, false)
showSnackWithMessage(getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT) showSnackWithMessage(getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT)
} }

View File

@ -22,21 +22,22 @@ import im.vector.app.core.resources.StringProvider
import im.vector.app.core.resources.UserPreferencesProvider import im.vector.app.core.resources.UserPreferencesProvider
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.home.room.detail.timeline.item.RoomCreateItem_ import im.vector.app.features.home.room.detail.timeline.item.RoomCreateItem_
import org.matrix.android.sdk.api.permalinks.PermalinkFactory import me.gujun.android.span.span
import org.matrix.android.sdk.api.session.Session
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.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import me.gujun.android.span.span
import javax.inject.Inject import javax.inject.Inject
class RoomCreateItemFactory @Inject constructor(private val stringProvider: StringProvider, class RoomCreateItemFactory @Inject constructor(private val stringProvider: StringProvider,
private val userPreferencesProvider: UserPreferencesProvider, private val userPreferencesProvider: UserPreferencesProvider,
private val session: Session,
private val noticeItemFactory: NoticeItemFactory) { private val noticeItemFactory: NoticeItemFactory) {
fun create(event: TimelineEvent, callback: TimelineEventController.Callback?): VectorEpoxyModel<*>? { fun create(event: TimelineEvent, callback: TimelineEventController.Callback?): VectorEpoxyModel<*>? {
val createRoomContent = event.root.getClearContent().toModel<RoomCreateContent>() ?: return null val createRoomContent = event.root.getClearContent().toModel<RoomCreateContent>() ?: return null
val predecessorId = createRoomContent.predecessor?.roomId ?: return defaultRendering(event, callback) val predecessorId = createRoomContent.predecessor?.roomId ?: return defaultRendering(event, callback)
val roomLink = PermalinkFactory.createPermalink(predecessorId) ?: return null val roomLink = session.permalinkService().createRoomPermalink(predecessorId) ?: return null
val text = span { val text = span {
+stringProvider.getString(R.string.room_tombstone_continuation_description) +stringProvider.getString(R.string.room_tombstone_continuation_description)
+"\n" +"\n"

View File

@ -27,8 +27,16 @@ import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject import com.squareup.inject.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
import io.reactivex.Observable
import io.reactivex.functions.BiFunction
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.permalinks.PermalinkFactory
import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.Session 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.EventType
@ -47,15 +55,6 @@ import org.matrix.android.sdk.api.util.toOptional
import org.matrix.android.sdk.internal.util.awaitCallback 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
import im.vector.app.R
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
import io.reactivex.Observable
import io.reactivex.functions.BiFunction
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomMemberProfileViewState, class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomMemberProfileViewState,
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
@ -337,7 +336,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
} }
private fun handleShareRoomMemberProfile() { private fun handleShareRoomMemberProfile() {
PermalinkFactory.createPermalink(initialState.userId)?.let { permalink -> session.permalinkService().createPermalink(initialState.userId)?.let { permalink ->
_viewEvents.post(RoomMemberProfileViewEvents.ShareRoomMemberProfile(permalink)) _viewEvents.post(RoomMemberProfileViewEvents.ShareRoomMemberProfile(permalink))
} }
} }

View File

@ -22,8 +22,11 @@ import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject import com.squareup.inject.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.permalinks.PermalinkFactory
import org.matrix.android.sdk.api.session.Session 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.EventType
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
@ -31,10 +34,6 @@ import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
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
import im.vector.app.R
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
import java.util.UUID import java.util.UUID
class RoomProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomProfileViewState, class RoomProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomProfileViewState,
@ -118,9 +117,10 @@ class RoomProfileViewModel @AssistedInject constructor(@Assisted private val ini
} }
private fun handleShareRoomProfile() { private fun handleShareRoomProfile() {
PermalinkFactory.createPermalink(initialState.roomId)?.let { permalink -> session.permalinkService().createRoomPermalink(initialState.roomId)
_viewEvents.post(RoomProfileViewEvents.ShareRoomProfile(permalink)) ?.let { permalink ->
} _viewEvents.post(RoomProfileViewEvents.ShareRoomProfile(permalink))
}
} }
private fun handleChangeAvatar(action: RoomProfileAction.ChangeRoomAvatar) { private fun handleChangeAvatar(action: RoomProfileAction.ChangeRoomAvatar) {