From 9b6c45e112c47de2fb0ee3bcda1e3bcbef157aa8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 19 Aug 2020 15:54:46 +0200 Subject: [PATCH 1/7] A Kick appears has "someone has made no change" (Fixes #1959) --- CHANGES.md | 1 + .../home/room/detail/timeline/format/NoticeEventFormatter.kt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index b43ff50308..b266dc78a5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ Bugfix 🐛: - Fix crash reported by RageShake - Fix refreshing of sessions list when another session is logged out - Failed to build unique file (#1954) + - A Kick appears has "someone has made no change" (#1959) Translations 🗣: - Add PlayStore description resources in the Triple-T format, to let Weblate handle them diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index b2709d1e1f..9a4729abee 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -327,6 +327,7 @@ class NoticeEventFormatter @Inject constructor(private val activeSessionDataSour val eventContent: RoomMemberContent? = event.getClearContent().toModel() val prevEventContent: RoomMemberContent? = event.resolvedPrevContent().toModel() val isMembershipEvent = prevEventContent?.membership != eventContent?.membership + || eventContent?.membership == Membership.LEAVE return if (isMembershipEvent) { buildMembershipNotice(event, senderName, eventContent, prevEventContent) } else { @@ -569,6 +570,7 @@ class NoticeEventFormatter @Inject constructor(private val activeSessionDataSour sp.getString(R.string.notice_room_withdraw_with_reason, senderDisplayName, targetDisplayName, reason) } ?: sp.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName) } + Membership.LEAVE, Membership.JOIN -> if (event.isSentByCurrentUser()) { eventContent.safeReason?.let { reason -> From af10344b6be8d3b209acedf439dd12814f9efdf3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Aug 2020 12:28:25 +0200 Subject: [PATCH 2/7] Share button in rooms gives room ID link without via parameters (#1927) Following the algorithm described in #1927 Create a PermalinkService --- CHANGES.md | 1 + .../sdk/api/permalinks/PermalinkParser.kt | 2 +- ...ermalinkFactory.kt => PermalinkService.kt} | 69 ++++------ .../matrix/android/sdk/api/session/Session.kt | 6 + .../sdk/internal/session/DefaultSession.kt | 4 + .../sdk/internal/session/SessionModule.kt | 5 + .../permalinks/DefaultPermalinkService.kt | 119 ++++++++++++++++++ .../room/relation/DefaultRelationService.kt | 14 ++- .../room/send/LocalEchoEventFactory.kt | 21 ++-- .../home/room/detail/RoomDetailFragment.kt | 3 +- .../timeline/factory/RoomCreateItemFactory.kt | 7 +- .../RoomMemberProfileViewModel.kt | 21 ++-- .../roomprofile/RoomProfileViewModel.kt | 16 +-- 13 files changed, 202 insertions(+), 86 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/{PermalinkFactory.kt => PermalinkService.kt} (58%) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt diff --git a/CHANGES.md b/CHANGES.md index 34ffdbcfd6..26f3e2883b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ Features ✨: - Conference with Jitsi support (#43) Improvements 🙌: + - Share button in rooms gives room ID link without via parameters (#1927) - Give user the possibility to prevent accidental call (#1869) - Display device information (name, id and key) in Cryptography setting screen (#1784) - Ensure users do not accidentally ignore other users (#1890) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkParser.kt index 4cf9331f0e..397ab3b020 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkParser.kt @@ -37,7 +37,7 @@ object PermalinkParser { * Turns an uri to a [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) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkService.kt similarity index 58% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkFactory.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkService.kt index 87b42f5ae8..8a780f59be 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkService.kt @@ -22,48 +22,51 @@ import org.matrix.android.sdk.api.session.events.model.Event /** * 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. * Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org" * * @param event the event + * * @return the permalink, or null in case of error */ - fun createPermalink(event: Event): String? { - if (event.roomId.isNullOrEmpty() || event.eventId.isNullOrEmpty()) { - return null - } - return createPermalink(event.roomId, event.eventId) - } + fun createPermalink(event: Event): String? /** - * 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" * * @param id the id * @return the permalink, or null in case of error */ - fun createPermalink(id: String): String? { - return if (id.isEmpty()) { - null - } else MATRIX_TO_URL_BASE + escape(id) - } + fun createPermalink(id: 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" + * Creates a permalink for a roomId, including the via parameters + * + * @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 eventId the id of the event + * * @return the permalink */ - fun createPermalink(roomId: String, eventId: String): String { - return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) - } + fun createPermalink(roomId: String, eventId: String): String /** * 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" * @return the id from the url, ex: "@benoit:matrix.org", or null if the url is not a permalink */ - 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", "/") - } + fun getLinkedId(url: String): String? } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt index 95370c0188..54192e8125 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt @@ -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.widgets.WidgetService import okhttp3.OkHttpClient +import org.matrix.android.sdk.api.permalinks.PermalinkService /** * This interface defines interactions with a session. @@ -195,6 +196,11 @@ interface Session : */ fun fileService(): FileService + /** + * Returns the permalink service associated with the session + */ + fun permalinkService(): PermalinkService + /** * Add a listener to the session. * @param listener the listener to add. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index eb4b475b4d..523eb6c9c8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -70,6 +70,7 @@ import okhttp3.OkHttpClient import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode +import org.matrix.android.sdk.api.permalinks.PermalinkService import timber.log.Timber import javax.inject.Inject import javax.inject.Provider @@ -96,6 +97,7 @@ internal class DefaultSession @Inject constructor( private val termsService: Lazy, private val cryptoService: Lazy, private val defaultFileService: Lazy, + private val permalinkService: Lazy, private val secureStorageService: Lazy, private val profileService: Lazy, private val widgetService: Lazy, @@ -254,6 +256,8 @@ internal class DefaultSession @Inject constructor( override fun fileService(): FileService = defaultFileService.get() + override fun permalinkService(): PermalinkService = permalinkService.get() + override fun widgetService(): WidgetService = widgetService.get() override fun integrationManagerService() = integrationManagerService diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index 1c1804ba5f..43d38d72e7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -84,6 +84,8 @@ import org.matrix.android.sdk.internal.util.md5 import io.realm.RealmConfiguration import okhttp3.OkHttpClient 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 java.io.File import javax.inject.Provider @@ -356,6 +358,9 @@ internal abstract class SessionModule { @Binds abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService + @Binds + abstract fun bindPermalinkService(service: DefaultPermalinkService): PermalinkService + @Binds abstract fun bindTypingUsersTracker(tracker: DefaultTypingUsersTracker): TypingUsersTracker } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt new file mode 100644 index 0000000000..20543ddc4e --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -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 +) : 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 { + return roomGetterProvider.get().getRoom(roomId) + ?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) }) + ?.map { it.userId } + .orEmpty() + .toSet() + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt index 458d98bd52..2199193de0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt @@ -156,11 +156,15 @@ internal class DefaultRelationService @AssistedInject constructor( originalTimelineEvent: TimelineEvent, newBodyText: String, compatibilityBodyText: String): Cancelable { - val event = eventFactory - .createReplaceTextOfReply(roomId, - replyToEdit, - originalTimelineEvent, - newBodyText, true, MessageType.MSGTYPE_TEXT, compatibilityBodyText) + val event = eventFactory.createReplaceTextOfReply( + roomId, + replyToEdit, + originalTimelineEvent, + newBodyText, + true, + MessageType.MSGTYPE_TEXT, + compatibilityBodyText + ) .also { saveLocalEcho(it) } return if (cryptoService.isRoomEncrypted(roomId)) { val encryptWork = createEncryptEventWork(event, listOf("m.relates_to")) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index fe6daad3b0..9364553fc5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -22,7 +22,7 @@ import android.graphics.Bitmap import android.media.MediaMetadataRetriever import androidx.exifinterface.media.ExifInterface 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.events.model.Content 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.session.content.ThumbnailExtractor 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 javax.inject.Inject @@ -79,8 +78,8 @@ internal class LocalEchoEventFactory @Inject constructor( private val stringProvider: StringProvider, private val markdownParser: MarkdownParser, 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 { if (msgType == MessageType.MSGTYPE_TEXT || msgType == MessageType.MSGTYPE_EMOTE) { @@ -169,9 +168,8 @@ internal class LocalEchoEventFactory @Inject constructor( newBodyAutoMarkdown: Boolean, msgType: String, compatibilityText: String): Event { - val permalink = PermalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "") - val userLink = originalEvent.root.senderId?.let { PermalinkFactory.createPermalink(it) } - ?: "" + val permalink = permalinkService.createPermalink(roomId, originalEvent.root.eventId ?: "") + val userLink = originalEvent.root.senderId?.let { permalinkService.createPermalink(it) } ?: "" val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.isReply()) val replyFormatted = REPLY_PATTERN.format( @@ -361,12 +359,15 @@ internal class LocalEchoEventFactory @Inject constructor( 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 // 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 userLink = PermalinkFactory.createPermalink(userId) ?: return null + val userLink = permalinkService.createPermalink(userId) ?: return null val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply()) val replyFormatted = REPLY_PATTERN.format( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index e94feebdaa..040a5191e4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -163,7 +163,6 @@ import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.commonmark.parser.Parser 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.content.ContentAttachmentData 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())) } is EventSharedAction.CopyPermalink -> { - val permalink = PermalinkFactory.createPermalink(roomDetailArgs.roomId, action.eventId) + val permalink = session.permalinkService().createPermalink(roomDetailArgs.roomId, action.eventId) copyToClipboard(requireContext(), permalink, false) showSnackWithMessage(getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/RoomCreateItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/RoomCreateItemFactory.kt index 290eb2cff5..31adbdb8a6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/RoomCreateItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/RoomCreateItemFactory.kt @@ -22,21 +22,22 @@ import im.vector.app.core.resources.StringProvider 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.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.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent -import me.gujun.android.span.span import javax.inject.Inject class RoomCreateItemFactory @Inject constructor(private val stringProvider: StringProvider, private val userPreferencesProvider: UserPreferencesProvider, + private val session: Session, private val noticeItemFactory: NoticeItemFactory) { fun create(event: TimelineEvent, callback: TimelineEventController.Callback?): VectorEpoxyModel<*>? { val createRoomContent = event.root.getClearContent().toModel() ?: return null 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 { +stringProvider.getString(R.string.room_tombstone_continuation_description) +"\n" diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index 99efd17d0a..f2c85c96c7 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -27,8 +27,16 @@ 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.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.permalinks.PermalinkFactory 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 @@ -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.rx.rx 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, private val stringProvider: StringProvider, @@ -337,7 +336,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v } private fun handleShareRoomMemberProfile() { - PermalinkFactory.createPermalink(initialState.userId)?.let { permalink -> + session.permalinkService().createPermalink(initialState.userId)?.let { permalink -> _viewEvents.post(RoomMemberProfileViewEvents.ShareRoomMemberProfile(permalink)) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt index 49d10d5129..2d409888e9 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt @@ -22,8 +22,11 @@ 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.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.permalinks.PermalinkFactory 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.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.rx.rx 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 class RoomProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomProfileViewState, @@ -118,9 +117,10 @@ class RoomProfileViewModel @AssistedInject constructor(@Assisted private val ini } private fun handleShareRoomProfile() { - PermalinkFactory.createPermalink(initialState.roomId)?.let { permalink -> - _viewEvents.post(RoomProfileViewEvents.ShareRoomProfile(permalink)) - } + session.permalinkService().createRoomPermalink(initialState.roomId) + ?.let { permalink -> + _viewEvents.post(RoomProfileViewEvents.ShareRoomProfile(permalink)) + } } private fun handleChangeAvatar(action: RoomProfileAction.ChangeRoomAvatar) { From 2c90e33ceb883d76e45f5548315d277977f9e284 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Aug 2020 12:32:12 +0200 Subject: [PATCH 3/7] Move package --- .../matrix/android/sdk/api/session/Session.kt | 4 ++-- .../{ => session}/permalinks/MatrixLinkify.kt | 2 +- .../permalinks/MatrixPermalinkSpan.kt | 4 ++-- .../{ => session}/permalinks/PermalinkData.kt | 2 +- .../{ => session}/permalinks/PermalinkParser.kt | 2 +- .../{ => session}/permalinks/PermalinkService.kt | 2 +- .../sdk/internal/session/DefaultSession.kt | 16 ++++++++-------- .../sdk/internal/session/SessionModule.kt | 10 +++++----- .../permalinks/DefaultPermalinkService.kt | 4 ++-- .../session/room/send/LocalEchoEventFactory.kt | 2 +- .../detail/timeline/tools/EventRenderingTools.kt | 4 ++-- .../vector/app/features/html/MxLinkTagHandler.kt | 8 ++++---- .../app/features/permalink/PermalinkHandler.kt | 6 +++--- 13 files changed, 33 insertions(+), 33 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/{ => session}/permalinks/MatrixLinkify.kt (97%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/{ => session}/permalinks/MatrixPermalinkSpan.kt (89%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/{ => session}/permalinks/PermalinkData.kt (95%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/{ => session}/permalinks/PermalinkParser.kt (98%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/{ => session}/permalinks/PermalinkService.kt (97%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt index 54192e8125..cfddf73363 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.session import androidx.annotation.MainThread import androidx.lifecycle.LiveData +import okhttp3.OkHttpClient import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.pushrules.PushRuleService @@ -35,6 +36,7 @@ import org.matrix.android.sdk.api.session.group.GroupService import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.identity.IdentityService import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService +import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.session.pushers.PushersService import org.matrix.android.sdk.api.session.room.RoomDirectoryService @@ -48,8 +50,6 @@ import org.matrix.android.sdk.api.session.terms.TermsService 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.widgets.WidgetService -import okhttp3.OkHttpClient -import org.matrix.android.sdk.api.permalinks.PermalinkService /** * This interface defines interactions with a session. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/MatrixLinkify.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt similarity index 97% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/MatrixLinkify.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt index b7e719d6db..8927f06c77 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/MatrixLinkify.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.permalinks +package org.matrix.android.sdk.api.session.permalinks import android.text.Spannable diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/MatrixPermalinkSpan.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixPermalinkSpan.kt similarity index 89% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/MatrixPermalinkSpan.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixPermalinkSpan.kt index 15957d359a..a660930646 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/MatrixPermalinkSpan.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixPermalinkSpan.kt @@ -15,11 +15,11 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.permalinks +package org.matrix.android.sdk.api.session.permalinks import android.text.style.ClickableSpan import android.view.View -import org.matrix.android.sdk.api.permalinks.MatrixPermalinkSpan.Callback +import org.matrix.android.sdk.api.session.permalinks.MatrixPermalinkSpan.Callback /** * This MatrixPermalinkSpan is a clickable span which use a [Callback] to communicate back. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkData.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt index 3955c850c5..85632d6e83 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.permalinks +package org.matrix.android.sdk.api.session.permalinks import android.net.Uri diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt similarity index 98% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkParser.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt index 397ab3b020..dd6847f1e3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.permalinks +package org.matrix.android.sdk.api.session.permalinks import android.net.Uri import org.matrix.android.sdk.api.MatrixPatterns diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt similarity index 97% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkService.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index 8a780f59be..804cde5b30 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.permalinks +package org.matrix.android.sdk.api.session.permalinks import org.matrix.android.sdk.api.session.events.model.Event diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index 523eb6c9c8..f8ba625947 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -19,6 +19,13 @@ package org.matrix.android.sdk.internal.session import androidx.annotation.MainThread import dagger.Lazy +import io.realm.RealmConfiguration +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.failure.GlobalError @@ -37,6 +44,7 @@ import org.matrix.android.sdk.api.session.file.FileService import org.matrix.android.sdk.api.session.group.GroupService import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService +import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.session.pushers.PushersService import org.matrix.android.sdk.api.session.room.RoomDirectoryService @@ -63,14 +71,6 @@ import org.matrix.android.sdk.internal.session.sync.job.SyncWorker import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.util.createUIHandler -import io.realm.RealmConfiguration -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import okhttp3.OkHttpClient -import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode -import org.matrix.android.sdk.api.permalinks.PermalinkService import timber.log.Timber import javax.inject.Inject import javax.inject.Provider diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index 43d38d72e7..d404cecc51 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -25,6 +25,9 @@ import dagger.Lazy import dagger.Module import dagger.Provides import dagger.multibindings.IntoSet +import io.realm.RealmConfiguration +import okhttp3.OkHttpClient +import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig @@ -35,6 +38,7 @@ import org.matrix.android.sdk.api.session.InitialSyncProgressService import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.accountdata.AccountDataService import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService +import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.securestorage.SecureStorageService import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService import org.matrix.android.sdk.api.session.typing.TypingUsersTracker @@ -72,6 +76,7 @@ import org.matrix.android.sdk.internal.session.download.DownloadProgressIntercep import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapabilitiesService import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager +import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService import org.matrix.android.sdk.internal.session.room.EventRelationsAggregationProcessor import org.matrix.android.sdk.internal.session.room.create.RoomCreateEventProcessor import org.matrix.android.sdk.internal.session.room.prune.RedactionEventProcessor @@ -81,11 +86,6 @@ import org.matrix.android.sdk.internal.session.typing.DefaultTypingUsersTracker import org.matrix.android.sdk.internal.session.user.accountdata.DefaultAccountDataService import org.matrix.android.sdk.internal.session.widgets.DefaultWidgetURLFormatter import org.matrix.android.sdk.internal.util.md5 -import io.realm.RealmConfiguration -import okhttp3.OkHttpClient -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 java.io.File import javax.inject.Provider diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index 20543ddc4e..c69266b47c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -16,9 +16,9 @@ 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.permalinks.PermalinkService +import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE 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 diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index 9364553fc5..1a2f7a711a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -22,7 +22,6 @@ import android.graphics.Bitmap import android.media.MediaMetadataRetriever import androidx.exifinterface.media.ExifInterface import org.matrix.android.sdk.R -import org.matrix.android.sdk.api.permalinks.PermalinkService 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.Event @@ -31,6 +30,7 @@ import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.RelationType import org.matrix.android.sdk.api.session.events.model.UnsignedData import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.room.model.message.AudioInfo import org.matrix.android.sdk.api.session.room.model.message.FileInfo import org.matrix.android.sdk.api.session.room.model.message.ImageInfo diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/tools/EventRenderingTools.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/tools/EventRenderingTools.kt index d09874c24a..4abaa4fae4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/tools/EventRenderingTools.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/tools/EventRenderingTools.kt @@ -26,12 +26,12 @@ import im.vector.app.core.utils.EvenBetterLinkMovementMethod import im.vector.app.core.utils.isValidUrl import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.html.PillImageSpan -import org.matrix.android.sdk.api.permalinks.MatrixLinkify -import org.matrix.android.sdk.api.permalinks.MatrixPermalinkSpan import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.permalinks.MatrixLinkify +import org.matrix.android.sdk.api.session.permalinks.MatrixPermalinkSpan fun CharSequence.findPillsAndProcess(scope: CoroutineScope, processBlock: (PillImageSpan) -> Unit) { scope.launch(Dispatchers.Main) { diff --git a/vector/src/main/java/im/vector/app/features/html/MxLinkTagHandler.kt b/vector/src/main/java/im/vector/app/features/html/MxLinkTagHandler.kt index 4eccfbb95c..368fdd27ff 100644 --- a/vector/src/main/java/im/vector/app/features/html/MxLinkTagHandler.kt +++ b/vector/src/main/java/im/vector/app/features/html/MxLinkTagHandler.kt @@ -21,15 +21,15 @@ import android.text.style.URLSpan import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.glide.GlideRequests import im.vector.app.features.home.AvatarRenderer -import org.matrix.android.sdk.api.permalinks.PermalinkData -import org.matrix.android.sdk.api.permalinks.PermalinkParser -import org.matrix.android.sdk.api.session.room.model.RoomSummary -import org.matrix.android.sdk.api.util.MatrixItem import io.noties.markwon.MarkwonVisitor import io.noties.markwon.SpannableBuilder import io.noties.markwon.html.HtmlTag import io.noties.markwon.html.MarkwonHtmlRenderer import io.noties.markwon.html.tag.LinkHandler +import org.matrix.android.sdk.api.session.permalinks.PermalinkData +import org.matrix.android.sdk.api.session.permalinks.PermalinkParser +import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.util.MatrixItem class MxLinkTagHandler(private val glideRequests: GlideRequests, private val context: Context, diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index a23c67a8e9..87d114c01b 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -20,12 +20,12 @@ import android.content.Context import android.net.Uri import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.features.navigation.Navigator -import org.matrix.android.sdk.api.permalinks.PermalinkData -import org.matrix.android.sdk.api.permalinks.PermalinkParser -import org.matrix.android.sdk.api.util.Optional import io.reactivex.Single import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers +import org.matrix.android.sdk.api.session.permalinks.PermalinkData +import org.matrix.android.sdk.api.session.permalinks.PermalinkParser +import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.rx.rx import javax.inject.Inject From fde2bdf3048bf06c8767ad8820ed5b8038f5580f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Aug 2020 17:41:01 +0200 Subject: [PATCH 4/7] Create a PermalinkFactory to avoid injecting the service in SDK classes --- .../permalinks/DefaultPermalinkService.kt | 78 +----------- .../session/permalinks/PermalinkFactory.kt | 118 ++++++++++++++++++ .../room/send/LocalEchoEventFactory.kt | 14 +-- 3 files changed, 130 insertions(+), 80 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index c69266b47c..df6dd2a12c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -19,44 +19,26 @@ package org.matrix.android.sdk.internal.session.permalinks import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE -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 + private val permalinkFactory: PermalinkFactory ) : PermalinkService { override fun createPermalink(event: Event): String? { - if (event.roomId.isNullOrEmpty() || event.eventId.isNullOrEmpty()) { - return null - } - return createPermalink(event.roomId, event.eventId) + return permalinkFactory.createPermalink(event) } override fun createPermalink(id: String): String? { - return if (id.isEmpty()) { - null - } else MATRIX_TO_URL_BASE + escape(id) + return permalinkFactory.createPermalink(id) } override fun createRoomPermalink(roomId: String): String? { - return if (roomId.isEmpty()) { - null - } else { - MATRIX_TO_URL_BASE + escape(roomId) + computeViaParams(userId, roomId) - } + return permalinkFactory.createRoomPermalink(roomId) } override fun createPermalink(roomId: String, eventId: String): String { - return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + computeViaParams(userId, roomId) + return permalinkFactory.createPermalink(roomId, eventId) } override fun getLinkedId(url: String): String? { @@ -66,54 +48,4 @@ internal class DefaultPermalinkService @Inject constructor( 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 { - return roomGetterProvider.get().getRoom(roomId) - ?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) }) - ?.map { it.userId } - .orEmpty() - .toSet() - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt new file mode 100644 index 0000000000..5043a32353 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt @@ -0,0 +1,118 @@ +/* + * 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.session.events.model.Event +import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE +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 PermalinkFactory @Inject constructor( + @UserId + private val userId: String, + // Use a provider to fix circular Dagger dependency + private val roomGetterProvider: Provider +) { + + fun createPermalink(event: Event): String? { + if (event.roomId.isNullOrEmpty() || event.eventId.isNullOrEmpty()) { + return null + } + return createPermalink(event.roomId, event.eventId) + } + + fun createPermalink(id: String): String? { + return if (id.isEmpty()) { + null + } else MATRIX_TO_URL_BASE + escape(id) + } + + fun createRoomPermalink(roomId: String): String? { + return if (roomId.isEmpty()) { + null + } else { + MATRIX_TO_URL_BASE + escape(roomId) + computeViaParams(userId, roomId) + } + } + + fun createPermalink(roomId: String, eventId: String): String { + return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + computeViaParams(userId, roomId) + } + + 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 { + return roomGetterProvider.get().getRoom(roomId) + ?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) }) + ?.map { it.userId } + .orEmpty() + .toSet() + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index 1a2f7a711a..ac92e526a8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -30,7 +30,6 @@ import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.RelationType import org.matrix.android.sdk.api.session.events.model.UnsignedData import org.matrix.android.sdk.api.session.events.model.toContent -import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.room.model.message.AudioInfo import org.matrix.android.sdk.api.session.room.model.message.FileInfo import org.matrix.android.sdk.api.session.room.model.message.ImageInfo @@ -59,6 +58,7 @@ import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent import org.matrix.android.sdk.api.session.room.timeline.isReply import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.content.ThumbnailExtractor +import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils import org.matrix.android.sdk.internal.util.StringProvider import javax.inject.Inject @@ -79,7 +79,7 @@ internal class LocalEchoEventFactory @Inject constructor( private val markdownParser: MarkdownParser, private val textPillsUtils: TextPillsUtils, private val localEchoRepository: LocalEchoRepository, - private val permalinkService: PermalinkService + private val permalinkFactory: PermalinkFactory ) { fun createTextEvent(roomId: String, msgType: String, text: CharSequence, autoMarkdown: Boolean): Event { if (msgType == MessageType.MSGTYPE_TEXT || msgType == MessageType.MSGTYPE_EMOTE) { @@ -168,8 +168,8 @@ internal class LocalEchoEventFactory @Inject constructor( newBodyAutoMarkdown: Boolean, msgType: String, compatibilityText: String): Event { - val permalink = permalinkService.createPermalink(roomId, originalEvent.root.eventId ?: "") - val userLink = originalEvent.root.senderId?.let { permalinkService.createPermalink(it) } ?: "" + val permalink = permalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "") + val userLink = originalEvent.root.senderId?.let { permalinkFactory.createPermalink(it) } ?: "" val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.isReply()) val replyFormatted = REPLY_PATTERN.format( @@ -205,7 +205,7 @@ internal class LocalEchoEventFactory @Inject constructor( ContentAttachmentData.Type.IMAGE -> createImageEvent(roomId, attachment) ContentAttachmentData.Type.VIDEO -> createVideoEvent(roomId, attachment) ContentAttachmentData.Type.AUDIO -> createAudioEvent(roomId, attachment) - ContentAttachmentData.Type.FILE -> createFileEvent(roomId, attachment) + ContentAttachmentData.Type.FILE -> createFileEvent(roomId, attachment) } } @@ -365,9 +365,9 @@ internal class LocalEchoEventFactory @Inject constructor( autoMarkdown: Boolean): Event? { // Fallbacks and event representation // TODO Add error/warning logs when any of this is null - val permalink = permalinkService.createPermalink(eventReplied.root) ?: return null + val permalink = permalinkFactory.createPermalink(eventReplied.root) ?: return null val userId = eventReplied.root.senderId ?: return null - val userLink = permalinkService.createPermalink(userId) ?: return null + val userLink = permalinkFactory.createPermalink(userId) ?: return null val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply()) val replyFormatted = REPLY_PATTERN.format( From cab447e44e508136122e9ad520ee82fcf633b9a1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Aug 2020 17:50:43 +0200 Subject: [PATCH 5/7] Add missing copyright --- .../sdk/internal/session/permalinks/DefaultPermalinkService.kt | 1 + .../android/sdk/internal/session/permalinks/PermalinkFactory.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index df6dd2a12c..04736303fe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 New Vector Ltd + * 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. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt index 5043a32353..3ec8fe8397 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 New Vector Ltd + * 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. From 112a7913d4b4f700fc066b85c7aa65be4221336c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Aug 2020 17:57:48 +0200 Subject: [PATCH 6/7] Improve (unused) code --- .../session/permalinks/DefaultPermalinkService.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index 04736303fe..cef1fce05c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -43,10 +43,9 @@ internal class DefaultPermalinkService @Inject constructor( } 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 + return url + .takeIf { it.startsWith(MATRIX_TO_URL_BASE) } + ?.substring(MATRIX_TO_URL_BASE.length) + ?.substringBeforeLast("?") } } From 80551fc0c224e2342687216d46e0745e7dcc83c6 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 20 Aug 2020 19:31:03 +0300 Subject: [PATCH 7/7] Fix IllegalArgumentException: Receiver not registered: NetworkInfoReceiver (#1961) Fix IllegalArgumentException: Receiver not registered: NetworkInfoReceiver (#1961) Co-authored-by: Onuray Sahin --- CHANGES.md | 1 + .../sdk/internal/network/NetworkConnectivityChecker.kt | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 898327cab2..e511d277d5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Bugfix 🐛: - Fix relative date time formatting (#822) - Fix crash reported by RageShake - Fix refreshing of sessions list when another session is logged out + - Fix IllegalArgumentException: Receiver not registered: NetworkInfoReceiver (#1960) - Failed to build unique file (#1954) - A Kick appears has "someone has made no change" (#1959) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt index 1f3e77d800..ae55324d53 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt @@ -75,9 +75,7 @@ internal class DefaultNetworkConnectivityChecker @Inject constructor(private val override fun register(listener: NetworkConnectivityChecker.Listener) { if (listeners.isEmpty()) { - if (backgroundDetectionObserver.isInBackground) { - unbind() - } else { + if (!backgroundDetectionObserver.isInBackground) { bind() } backgroundDetectionObserver.register(backgroundDetectionObserverListener)