From 71f8ce001d682468a2021f64ae087df68d7b4e14 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 22 May 2019 15:23:36 +0200 Subject: [PATCH 01/12] Fix Crash when connecting to a homeserver URL with a subpath (Fixes #133) --- .../api/auth/data/HomeServerConnectionConfig.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/HomeServerConnectionConfig.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/HomeServerConnectionConfig.kt index bca7d480..f231d3f1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/HomeServerConnectionConfig.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/HomeServerConnectionConfig.kt @@ -70,11 +70,11 @@ data class HomeServerConnectionConfig( if (hsUri.scheme != "http" && hsUri.scheme != "https") { throw RuntimeException("Invalid home server URI: " + hsUri) } - // remove trailing / - homeServerUri = if (hsUri.toString().endsWith("/")) { + // ensure trailing / + homeServerUri = if (!hsUri.toString().endsWith("/")) { try { val url = hsUri.toString() - Uri.parse(url.substring(0, url.length - 1)) + Uri.parse("$url/") } catch (e: Exception) { throw RuntimeException("Invalid home server URI: $hsUri") } @@ -96,11 +96,11 @@ data class HomeServerConnectionConfig( if (identityServerUri.scheme != "http" && identityServerUri.scheme != "https") { throw RuntimeException("Invalid identity server URI: $identityServerUri") } - // remove trailing / - if (identityServerUri.toString().endsWith("/")) { + // ensure trailing / + if (!identityServerUri.toString().endsWith("/")) { try { val url = identityServerUri.toString() - this.identityServerUri = Uri.parse(url.substring(0, url.length - 1)) + this.identityServerUri = Uri.parse("$url/") } catch (e: Exception) { throw RuntimeException("Invalid identity server URI: $identityServerUri") } From 99087019d25bed8b7a768b1e0e66730058350ce0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 22 May 2019 15:33:22 +0200 Subject: [PATCH 02/12] Input type on message text field (Fixes #129) --- vector/src/main/res/layout/fragment_room_detail.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/layout/fragment_room_detail.xml b/vector/src/main/res/layout/fragment_room_detail.xml index a5711bce..c65ae0e0 100644 --- a/vector/src/main/res/layout/fragment_room_detail.xml +++ b/vector/src/main/res/layout/fragment_room_detail.xml @@ -80,7 +80,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/toolbar" - tools:listitem="@layout/item_timeline_event_text_message" /> + tools:listitem="@layout/item_timeline_event_base" /> + app:layout_constraintVertical_bias="1.0" + tools:visibility="visible" /> \ No newline at end of file From 5da29e806305f0403c859abddfc14f63064e3ced Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 22 May 2019 16:36:31 +0200 Subject: [PATCH 03/12] Update MxRx library from 0.7.0 to 1.0.1 --- vector/build.gradle | 2 +- .../riotredesign/core/platform/StateView.kt | 1 + .../core/platform/VectorBaseFragment.kt | 1 + .../timeline/action/BaseMvRxBottomSheetDialog.kt | 15 +++++++++++++-- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index e75bbd32..b9e01ed0 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -156,7 +156,7 @@ dependencies { implementation("com.airbnb.android:epoxy:$epoxy_version") kapt "com.airbnb.android:epoxy-processor:$epoxy_version" - implementation 'com.airbnb.android:mvrx:0.7.0' + implementation 'com.airbnb.android:mvrx:1.0.1' // Work implementation "android.arch.work:work-runtime-ktx:1.0.0" diff --git a/vector/src/main/java/im/vector/riotredesign/core/platform/StateView.kt b/vector/src/main/java/im/vector/riotredesign/core/platform/StateView.kt index e75fb26c..6c4bc8cd 100755 --- a/vector/src/main/java/im/vector/riotredesign/core/platform/StateView.kt +++ b/vector/src/main/java/im/vector/riotredesign/core/platform/StateView.kt @@ -27,6 +27,7 @@ import kotlinx.android.synthetic.main.view_state.view.* class StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : FrameLayout(context, attrs, defStyle) { + // TODO Use Async from MvRx? sealed class State { object Content : State() object Loading : State() diff --git a/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseFragment.kt index 4db140f8..43dec625 100644 --- a/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseFragment.kt @@ -100,6 +100,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed { override fun invalidate() { //no-ops by default + // TODO Remove default implementation? } protected fun setArguments(args: Parcelable? = null) { diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/BaseMvRxBottomSheetDialog.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/BaseMvRxBottomSheetDialog.kt index 504e99c0..a37a5eaf 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/BaseMvRxBottomSheetDialog.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/BaseMvRxBottomSheetDialog.kt @@ -19,21 +19,30 @@ import android.os.Bundle import com.airbnb.mvrx.MvRxView import com.airbnb.mvrx.MvRxViewModelStore import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import java.util.* /** * Add MvRx capabilities to bottomsheetdialog (like BaseMvRxFragment) */ -abstract class BaseMvRxBottomSheetDialog() : BottomSheetDialogFragment(), MvRxView { +abstract class BaseMvRxBottomSheetDialog : BottomSheetDialogFragment(), MvRxView { + override val mvrxViewModelStore by lazy { MvRxViewModelStore(viewModelStore) } + private lateinit var mvrxPersistedViewId: String + + final override val mvrxViewId: String by lazy { mvrxPersistedViewId } override fun onCreate(savedInstanceState: Bundle?) { mvrxViewModelStore.restoreViewModels(this, savedInstanceState) + mvrxPersistedViewId = savedInstanceState?.getString(PERSISTED_VIEW_ID_KEY) + ?: this::class.java.simpleName + "_" + UUID.randomUUID().toString() + super.onCreate(savedInstanceState) } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) mvrxViewModelStore.saveViewModels(outState) + outState.putString(PERSISTED_VIEW_ID_KEY, mvrxViewId) } override fun onStart() { @@ -42,4 +51,6 @@ abstract class BaseMvRxBottomSheetDialog() : BottomSheetDialogFragment(), MvRxVi // subscribe to a ViewModel. postInvalidate() } -} \ No newline at end of file +} + +private const val PERSISTED_VIEW_ID_KEY = "mvrx:bottomsheet_persisted_view_id" \ No newline at end of file From 877de1f5973083b97c54bd04519ab53f193529da Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 24 May 2019 11:35:46 +0200 Subject: [PATCH 04/12] Get Public rooms and join public room --- matrix-sdk-android/build.gradle | 4 +- .../matrix/android/api/session/Session.kt | 2 + .../api/session/room/RoomDirectoryService.kt | 42 ++++ .../room/model/roomdirectory/PublicRoom.kt | 87 +++++++++ .../model/roomdirectory/PublicRoomsFilter.kt | 31 +++ .../model/roomdirectory/PublicRoomsParams.kt | 57 ++++++ .../roomdirectory/PublicRoomsResponse.kt | 50 +++++ .../internal/session/DefaultSession.kt | 17 ++ .../android/internal/session/SessionModule.kt | 16 +- .../content/DefaultContentUrlResolver.kt | 2 +- .../room/DefaultRoomDirectoryService.kt | 48 +++++ .../android/internal/session/room/RoomAPI.kt | 22 ++- .../room/directory/GetPublicRoomTask.kt | 40 ++++ vector/src/main/AndroidManifest.xml | 2 + .../core/epoxy/ErrorWithRetryItem.kt | 46 +++++ .../riotredesign/core/epoxy/NoResultItem.kt | 40 ++++ .../features/home/HomeActivity.kt | 15 +- .../roomdirectory/RoomDirectoryActivity.kt | 34 ++++ .../roomdirectory/RoomDirectoryController.kt | 104 ++++++++++ .../roomdirectory/RoomDirectoryFragment.kt | 113 +++++++++++ .../roomdirectory/RoomDirectoryItem.kt | 97 +++++++++ .../roomdirectory/RoomDirectoryViewModel.kt | 184 ++++++++++++++++++ .../roomdirectory/RoomDirectoryViewState.kt | 35 ++++ .../src/main/res/drawable/ic_plus_circle.xml | 13 ++ vector/src/main/res/drawable/ic_tick.xml | 9 + vector/src/main/res/drawable/ic_user.xml | 11 ++ .../src/main/res/layout/activity_simple.xml | 5 + .../res/layout/fragment_room_directory.xml | 65 +++++++ .../src/main/res/layout/item_error_retry.xml | 30 +++ vector/src/main/res/layout/item_no_result.xml | 8 + .../main/res/layout/item_room_directory.xml | 105 ++++++++++ vector/src/main/res/menu/home.xml | 5 + vector/src/main/res/values/strings_riotX.xml | 3 + 33 files changed, 1324 insertions(+), 18 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoom.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsFilter.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsParams.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsResponse.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomDirectoryService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/directory/GetPublicRoomTask.kt create mode 100644 vector/src/main/java/im/vector/riotredesign/core/epoxy/ErrorWithRetryItem.kt create mode 100644 vector/src/main/java/im/vector/riotredesign/core/epoxy/NoResultItem.kt create mode 100644 vector/src/main/java/im/vector/riotredesign/features/roomdirectory/RoomDirectoryActivity.kt create mode 100644 vector/src/main/java/im/vector/riotredesign/features/roomdirectory/RoomDirectoryController.kt create mode 100644 vector/src/main/java/im/vector/riotredesign/features/roomdirectory/RoomDirectoryFragment.kt create mode 100644 vector/src/main/java/im/vector/riotredesign/features/roomdirectory/RoomDirectoryItem.kt create mode 100644 vector/src/main/java/im/vector/riotredesign/features/roomdirectory/RoomDirectoryViewModel.kt create mode 100644 vector/src/main/java/im/vector/riotredesign/features/roomdirectory/RoomDirectoryViewState.kt create mode 100644 vector/src/main/res/drawable/ic_plus_circle.xml create mode 100644 vector/src/main/res/drawable/ic_tick.xml create mode 100644 vector/src/main/res/drawable/ic_user.xml create mode 100644 vector/src/main/res/layout/activity_simple.xml create mode 100644 vector/src/main/res/layout/fragment_room_directory.xml create mode 100644 vector/src/main/res/layout/item_error_retry.xml create mode 100644 vector/src/main/res/layout/item_no_result.xml create mode 100644 vector/src/main/res/layout/item_room_directory.xml diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index c04907ab..8fcc1a25 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -45,10 +45,10 @@ android { debug { // Set to true to log privacy or sensible data, such as token - buildConfigField "boolean", "LOG_PRIVATE_DATA", "false" + buildConfigField "boolean", "LOG_PRIVATE_DATA", "true" // Set to BODY instead of NONE to enable logging - buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.NONE" + buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.BODY" } release { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt index 742adb90..82264306 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt @@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.content.ContentUploadStateTracker import im.vector.matrix.android.api.session.content.ContentUrlResolver import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.group.GroupService +import im.vector.matrix.android.api.session.room.RoomDirectoryService import im.vector.matrix.android.api.session.room.RoomService import im.vector.matrix.android.api.session.signout.SignOutService import im.vector.matrix.android.api.session.sync.FilterService @@ -34,6 +35,7 @@ import im.vector.matrix.android.api.session.user.UserService */ interface Session : RoomService, + RoomDirectoryService, GroupService, UserService, CryptoService, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt new file mode 100644 index 00000000..4df58ffc --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.api.session.room + +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse +import im.vector.matrix.android.api.util.Cancelable + +/** + * This interface defines methods to get and join public rooms. It's implemented at the session level. + */ +interface RoomDirectoryService { + + /** + * Get rooms from directory + */ + fun getPublicRooms(server: String?, + publicRoomsParams: PublicRoomsParams, + callback: MatrixCallback): Cancelable + + /** + * Join a room by id + */ + fun joinRoom(roomId: String, + callback: MatrixCallback) + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoom.kt new file mode 100644 index 00000000..3ed3ec0c --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoom.kt @@ -0,0 +1,87 @@ +/* + * Copyright 2014 OpenMarket Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.matrix.android.api.session.room.model.roomdirectory + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Class representing the objects returned by /publicRooms call. + */ +@JsonClass(generateAdapter = true) +data class PublicRoom( + + /** + * Aliases of the room. May be empty. + */ + @Json(name = "aliases") + var aliases: List? = null, + + /** + * The canonical alias of the room, if any. + */ + @Json(name = "canonical_alias") + var canonicalAlias: String? = null, + + /** + * The name of the room, if any. + */ + @Json(name = "name") + var name: String? = null, + + /** + * Required. The number of members joined to the room. + */ + @Json(name = "num_joined_members") + var numJoinedMembers: Int = 0, + + /** + * Required. The ID of the room. + */ + @Json(name = "room_id") + var roomId: String, + + /** + * The topic of the room, if any. + */ + @Json(name = "topic") + var topic: String? = null, + + /** + * Required. Whether the room may be viewed by guest users without joining. + */ + @Json(name = "world_readable") + var worldReadable: Boolean = false, + + /** + * Required. Whether guest users may join the room and participate in it. If they can, they will be subject to ordinary power level rules like any other user. + */ + @Json(name = "guest_can_join") + var guestCanJoin: Boolean = false, + + /** + * The URL for the room's avatar, if one is set. + */ + @Json(name = "avatar_url") + var avatarUrl: String? = null, + + /** + * Undocumented item + */ + @Json(name = "m.federate") + var isFederated: Boolean = false + +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsFilter.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsFilter.kt new file mode 100644 index 00000000..b4de72e4 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsFilter.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2014 OpenMarket Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.matrix.android.api.session.room.model.roomdirectory + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Class to define a filter to retrieve public rooms + */ +@JsonClass(generateAdapter = true) +data class PublicRoomsFilter( + /** + * A string to search for in the room metadata, e.g. name, topic, canonical alias etc. (Optional). + */ + @Json(name = "generic_search_term") + var searchTerm: String? = null +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsParams.kt new file mode 100644 index 00000000..7b584fe6 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsParams.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2016 OpenMarket Ltd + * Copyright 2017 Vector Creations Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.matrix.android.api.session.room.model.roomdirectory + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Class to pass parameters to get the public rooms list + */ +@JsonClass(generateAdapter = true) +data class PublicRoomsParams( + /** + * Limit the number of results returned. + */ + @Json(name = "limit") + var limit: Int? = null, + + /** + * A pagination token from a previous request, allowing clients to get the next (or previous) batch of rooms. + * The direction of pagination is specified solely by which token is supplied, rather than via an explicit flag. + */ + @Json(name = "since") + var since: String? = null, + + /** + * Filter to apply to the results. + */ + @Json(name = "filter") + var filter: PublicRoomsFilter? = null, + + /** + * Whether or not to include all known networks/protocols from application services on the homeserver. Defaults to false. + */ + @Json(name = "includeAllNetworks") + var includeAllNetworks: Boolean = false, + + /** + * The specific third party network/protocol to request from the homeserver. Can only be used if include_all_networks is false. + */ + @Json(name = "thirdPartyInstanceId") + var thirdPartyInstanceId: String? = null +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsResponse.kt new file mode 100644 index 00000000..3799d097 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsResponse.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2014 OpenMarket Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.matrix.android.api.session.room.model.roomdirectory + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Class representing the public rooms request response + */ +@JsonClass(generateAdapter = true) +data class PublicRoomsResponse( + /** + * A pagination token for the response. The absence of this token means there are no more results to fetch and the client should stop paginating. + */ + @Json(name = "next_batch") + var nextBatch: String? = null, + + /** + * A pagination token that allows fetching previous results. The absence of this token means there are no results before this batch, + * i.e. this is the first batch. + */ + @Json(name = "prev_batch") + var prevBatch: String? = null, + + /** + * A paginated chunk of public rooms. + */ + @Json(name = "chunk") + var chunk: List? = null, + + /** + * An estimate on the total number of public rooms, if the server has an estimate. + */ + @Json(name = "total_room_count_estimate") + var totalRoomCountEstimate: Int? = null +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index 42e5d8ed..501ae450 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -30,13 +30,17 @@ import im.vector.matrix.android.api.session.group.Group import im.vector.matrix.android.api.session.group.GroupService import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.matrix.android.api.session.room.Room +import im.vector.matrix.android.api.session.room.RoomDirectoryService import im.vector.matrix.android.api.session.room.RoomService import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse import im.vector.matrix.android.api.session.signout.SignOutService import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.user.model.User +import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.MatrixCallbackDelegate import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.di.MatrixKoinComponent @@ -64,6 +68,7 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi private val liveEntityUpdaters by inject>() private val sessionListeners by inject() private val roomService by inject() + private val roomDirectoryService by inject() private val groupService by inject() private val userService by inject() private val filterService by inject() @@ -171,6 +176,18 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi return roomService.liveRoomSummaries() } + // ROOM DIRECTORY SERVICE + + override fun getPublicRooms(server: String?, publicRoomsParams: PublicRoomsParams, callback: MatrixCallback): Cancelable { + assert(isOpen) + return roomDirectoryService.getPublicRooms(server, publicRoomsParams, callback) + } + + override fun joinRoom(roomId: String, callback: MatrixCallback) { + assert(isOpen) + return roomDirectoryService.joinRoom(roomId, callback) + } + // GROUP SERVICE override fun getGroup(groupId: String): Group? { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index 6640cb2a..ab6b46ca 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -21,6 +21,7 @@ import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.session.cache.CacheService import im.vector.matrix.android.api.session.group.GroupService +import im.vector.matrix.android.api.session.room.RoomDirectoryService import im.vector.matrix.android.api.session.room.RoomService import im.vector.matrix.android.api.session.signout.SignOutService import im.vector.matrix.android.api.session.sync.FilterService @@ -33,10 +34,9 @@ import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask import im.vector.matrix.android.internal.session.filter.* import im.vector.matrix.android.internal.session.group.DefaultGroupService import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater -import im.vector.matrix.android.internal.session.room.DefaultRoomService -import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater -import im.vector.matrix.android.internal.session.room.RoomAvatarResolver -import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater +import im.vector.matrix.android.internal.session.room.* +import im.vector.matrix.android.internal.session.room.directory.DefaultGetPublicRoomTask +import im.vector.matrix.android.internal.session.room.directory.GetPublicRoomTask import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver import im.vector.matrix.android.internal.session.room.membership.RoomMemberDisplayNameResolver import im.vector.matrix.android.internal.session.room.prune.EventsPruner @@ -111,6 +111,14 @@ internal class SessionModule(private val sessionParams: SessionParams) { DefaultRoomService(get(), get(), get(), get()) as RoomService } + scope(DefaultSession.SCOPE) { + DefaultGetPublicRoomTask(get()) as GetPublicRoomTask + } + + scope(DefaultSession.SCOPE) { + DefaultRoomDirectoryService(get(), get(), get()) as RoomDirectoryService + } + scope(DefaultSession.SCOPE) { DefaultGroupService(get()) as GroupService } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUrlResolver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUrlResolver.kt index cb8896e7..8845c372 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUrlResolver.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUrlResolver.kt @@ -21,7 +21,7 @@ import im.vector.matrix.android.api.session.content.ContentUrlResolver private const val MATRIX_CONTENT_URI_SCHEME = "mxc://" -internal const val URI_PREFIX_CONTENT_API = "/_matrix/media/v1/" +internal const val URI_PREFIX_CONTENT_API = "_matrix/media/v1/" internal class DefaultContentUrlResolver(private val homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomDirectoryService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomDirectoryService.kt new file mode 100644 index 00000000..9534f169 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomDirectoryService.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.room + +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.room.RoomDirectoryService +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse +import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.internal.session.room.directory.GetPublicRoomTask +import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.configureWith + +internal class DefaultRoomDirectoryService(private val getPublicRoomTask: GetPublicRoomTask, + private val joinRoomTask: JoinRoomTask, + private val taskExecutor: TaskExecutor) : RoomDirectoryService { + + override fun getPublicRooms(server: String?, + publicRoomsParams: PublicRoomsParams, + callback: MatrixCallback): Cancelable { + return getPublicRoomTask + .configureWith(GetPublicRoomTask.Params(server, publicRoomsParams)) + .dispatchTo(callback) + .executeBy(taskExecutor) + } + + override fun joinRoom(roomId: String, callback: MatrixCallback) { + joinRoomTask + .configureWith(JoinRoomTask.Params(roomId)) + .dispatchTo(callback) + .executeBy(taskExecutor) + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt index 39d9c4d3..9aed926d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt @@ -20,6 +20,8 @@ import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams import im.vector.matrix.android.api.session.room.model.create.CreateRoomResponse +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse import im.vector.matrix.android.internal.network.NetworkConstants import im.vector.matrix.android.internal.session.room.membership.RoomMembersResponse import im.vector.matrix.android.internal.session.room.membership.joining.InviteBody @@ -27,15 +29,21 @@ import im.vector.matrix.android.internal.session.room.send.SendResponse import im.vector.matrix.android.internal.session.room.timeline.EventContextResponse import im.vector.matrix.android.internal.session.room.timeline.PaginationResponse import retrofit2.Call -import retrofit2.http.Body -import retrofit2.http.GET -import retrofit2.http.POST -import retrofit2.http.PUT -import retrofit2.http.Path -import retrofit2.http.Query +import retrofit2.http.* internal interface RoomAPI { + /** + * Lists the public rooms on the server, with optional filter. + * This API returns paginated responses. The rooms are ordered by the number of joined members, with the largest rooms first. + * + * Ref: https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-publicrooms + */ + @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "publicRooms") + fun publicRooms(@Query("server") server: String?, + @Body publicRoomsParams: PublicRoomsParams + ): Call + /** * Create a room. * Ref: https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-createroom @@ -213,6 +221,6 @@ internal interface RoomAPI { @Path("txnId") txId: String, @Path("roomId") roomId: String, @Path("eventId") parent_id: String, - @Body reason: Map + @Body reason: Map ): Call } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/directory/GetPublicRoomTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/directory/GetPublicRoomTask.kt new file mode 100644 index 00000000..4cf72285 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/directory/GetPublicRoomTask.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.room.directory + +import arrow.core.Try +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse +import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.session.room.RoomAPI +import im.vector.matrix.android.internal.task.Task + +internal interface GetPublicRoomTask : Task { + data class Params( + val server: String?, + val publicRoomsParams: PublicRoomsParams + ) +} + +internal class DefaultGetPublicRoomTask(private val roomAPI: RoomAPI) : GetPublicRoomTask { + + override fun execute(params: GetPublicRoomTask.Params): Try { + return executeRequest { + apiCall = roomAPI.publicRooms(params.server, params.publicRoomsParams) + } + } +} diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 2860cf9a..591b1885 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -43,6 +43,8 @@ android:name="im.vector.riotredesign.features.reactions.EmojiReactionPickerActivity" android:label="@string/title_activity_emoji_reaction_picker" /> + + diff --git a/vector/src/main/java/im/vector/riotredesign/core/epoxy/ErrorWithRetryItem.kt b/vector/src/main/java/im/vector/riotredesign/core/epoxy/ErrorWithRetryItem.kt new file mode 100644 index 00000000..c6bfb13a --- /dev/null +++ b/vector/src/main/java/im/vector/riotredesign/core/epoxy/ErrorWithRetryItem.kt @@ -0,0 +1,46 @@ +/* + * + * * Copyright 2019 New Vector Ltd + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package im.vector.riotredesign.core.epoxy + +import android.widget.Button +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.riotredesign.R + +@EpoxyModelClass(layout = R.layout.item_error_retry) +abstract class ErrorWithRetryItem : VectorEpoxyModel() { + + @EpoxyAttribute + var text: String? = null + + @EpoxyAttribute + var listener: (() -> Unit)? = null + + override fun bind(holder: Holder) { + holder.textView.text = text + holder.buttonView.setOnClickListener { listener?.invoke() } + } + + + class Holder : VectorEpoxyHolder() { + val textView by bind(R.id.itemErrorRetryText) + val buttonView by bind