diff --git a/matrix-sdk-android-flow/.gitignore b/matrix-sdk-android-flow/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/matrix-sdk-android-flow/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/matrix-sdk-android-flow/build.gradle b/matrix-sdk-android-flow/build.gradle new file mode 100644 index 0000000000..4aecec169b --- /dev/null +++ b/matrix-sdk-android-flow/build.gradle @@ -0,0 +1,49 @@ + +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' +} + +android { + compileSdk 31 + + defaultConfig { + minSdk 21 + targetSdk 31 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + + implementation project(":matrix-sdk-android") + implementation libs.androidx.appCompat + + implementation libs.jetbrains.kotlinStdlibJdk7 + implementation libs.jetbrains.coroutinesCore + implementation libs.jetbrains.coroutinesAndroid + implementation libs.androidx.lifecycleLivedata + + // Paging + implementation libs.androidx.pagingRuntimeKtx + + // Logging + implementation libs.jakewharton.timber + +} \ No newline at end of file diff --git a/matrix-sdk-android-flow/consumer-rules.pro b/matrix-sdk-android-flow/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/matrix-sdk-android-flow/proguard-rules.pro b/matrix-sdk-android-flow/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/matrix-sdk-android-flow/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/matrix-sdk-android-flow/src/androidTest/java/org/matrix/android/sdk/flow/ExampleInstrumentedTest.kt b/matrix-sdk-android-flow/src/androidTest/java/org/matrix/android/sdk/flow/ExampleInstrumentedTest.kt new file mode 100644 index 0000000000..41799955a4 --- /dev/null +++ b/matrix-sdk-android-flow/src/androidTest/java/org/matrix/android/sdk/flow/ExampleInstrumentedTest.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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.flow + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("org.matrix.android.sdk.flow.test", appContext.packageName) + } +} diff --git a/matrix-sdk-android-flow/src/main/AndroidManifest.xml b/matrix-sdk-android-flow/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..2392c0bfcb --- /dev/null +++ b/matrix-sdk-android-flow/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowRoom.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowRoom.kt new file mode 100644 index 0000000000..a3e476ce08 --- /dev/null +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowRoom.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.flow + +import androidx.lifecycle.asFlow +import kotlinx.coroutines.flow.Flow +import org.matrix.android.sdk.api.query.QueryStringValue +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.room.Room +import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams +import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary +import org.matrix.android.sdk.api.session.room.model.ReadReceipt +import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary +import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState +import org.matrix.android.sdk.api.session.room.send.UserDraft +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import org.matrix.android.sdk.api.util.Optional + +class FlowRoom(private val room: Room) { + + fun liveRoomSummary(): Flow> { + return room.getRoomSummaryLive().asFlow() + } + + fun liveRoomMembers(queryParams: RoomMemberQueryParams): Flow> { + return room.getRoomMembersLive(queryParams).asFlow() + } + + fun liveAnnotationSummary(eventId: String): Flow> { + return room.getEventAnnotationsSummaryLive(eventId).asFlow() + } + + fun liveTimelineEvent(eventId: String): Flow> { + return room.getTimeLineEventLive(eventId).asFlow() + } + + fun liveStateEvent(eventType: String, stateKey: QueryStringValue): Flow> { + return room.getStateEventLive(eventType, stateKey).asFlow() + } + + fun liveStateEvents(eventTypes: Set): Flow> { + return room.getStateEventsLive(eventTypes).asFlow() + } + + fun liveReadMarker(): Flow> { + return room.getReadMarkerLive().asFlow() + } + + fun liveReadReceipt(): Flow> { + return room.getMyReadReceiptLive().asFlow() + } + + fun liveEventReadReceipts(eventId: String): Flow> { + return room.getEventReadReceiptsLive(eventId).asFlow() + } + + fun liveDraft(): Flow> { + return room.getDraftLive().asFlow() + } + + fun liveNotificationState(): Flow { + return room.getLiveRoomNotificationState().asFlow() + } +} + +fun Room.flow(): FlowRoom { + return FlowRoom(this) +} diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt new file mode 100644 index 0000000000..affcd4a65d --- /dev/null +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt @@ -0,0 +1,138 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.flow + +import androidx.lifecycle.asFlow +import androidx.paging.PagedList +import kotlinx.coroutines.flow.Flow +import org.matrix.android.sdk.api.query.QueryStringValue +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.group.GroupSummaryQueryParams +import org.matrix.android.sdk.api.session.group.model.GroupSummary +import org.matrix.android.sdk.api.session.identity.ThreePid +import org.matrix.android.sdk.api.session.pushers.Pusher +import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams +import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataEvent +import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState +import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary +import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.space.SpaceSummaryQueryParams +import org.matrix.android.sdk.api.session.sync.SyncState +import org.matrix.android.sdk.api.session.user.model.User +import org.matrix.android.sdk.api.session.widgets.model.Widget +import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo +import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo + +class RxFlow(private val session: Session) { + + fun liveRoomSummaries(queryParams: RoomSummaryQueryParams): Flow> { + return session.getRoomSummariesLive(queryParams).asFlow() + } + + fun liveGroupSummaries(queryParams: GroupSummaryQueryParams): Flow> { + return session.getGroupSummariesLive(queryParams).asFlow() + } + + fun liveSpaceSummaries(queryParams: SpaceSummaryQueryParams): Flow> { + return session.spaceService().getSpaceSummariesLive(queryParams).asFlow() + } + + fun liveBreadcrumbs(queryParams: RoomSummaryQueryParams): Flow> { + return session.getBreadcrumbsLive(queryParams).asFlow() + } + + fun liveMyDevicesInfo(): Flow> { + return session.cryptoService().getLiveMyDevicesInfo().asFlow() + } + + fun liveSyncState(): Flow { + return session.getSyncStateLive().asFlow() + } + + fun livePushers(): Flow> { + return session.getPushersLive().asFlow() + } + + fun liveUser(userId: String): Flow> { + return session.getUserLive(userId).asFlow() + } + + fun liveRoomMember(userId: String, roomId: String): Flow> { + return session.getRoomMemberLive(userId, roomId).asFlow() + } + + fun liveUsers(): Flow> { + return session.getUsersLive().asFlow() + } + + fun liveIgnoredUsers(): Flow> { + return session.getIgnoredUsersLive().asFlow() + } + + fun livePagedUsers(filter: String? = null, excludedUserIds: Set? = null): Flow> { + return session.getPagedUsersLive(filter, excludedUserIds).asFlow() + } + + fun liveThreePIds(refreshData: Boolean): Flow> { + return session.getThreePidsLive(refreshData).asFlow() + } + + fun livePendingThreePIds(): Flow> { + return session.getPendingThreePidsLive().asFlow() + } + + fun liveUserCryptoDevices(userId: String): Flow> { + return session.cryptoService().getLiveCryptoDeviceInfo(userId).asFlow() + } + + fun liveCrossSigningInfo(userId: String): Flow> { + return session.cryptoService().crossSigningService().getLiveCrossSigningKeys(userId).asFlow() + } + + fun liveCrossSigningPrivateKeys(): Flow> { + return session.cryptoService().crossSigningService().getLiveCrossSigningPrivateKeys().asFlow() + } + + fun liveUserAccountData(types: Set): Flow> { + return session.accountDataService().getLiveUserAccountDataEvents(types).asFlow() + } + + fun liveRoomAccountData(types: Set): Flow> { + return session.accountDataService().getLiveRoomAccountDataEvents(types).asFlow() + } + + fun liveRoomWidgets( + roomId: String, + widgetId: QueryStringValue, + widgetTypes: Set? = null, + excludedTypes: Set? = null + ): Flow> { + return session.widgetService().getRoomWidgetsLive(roomId, widgetId, widgetTypes, excludedTypes).asFlow() + } + + fun liveRoomChangeMembershipState(): Flow> { + return session.getChangeMembershipsLive().asFlow() + } +} + +fun Session.flow(): RxFlow { + return RxFlow(this) +} diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt new file mode 100644 index 0000000000..a9f062f379 --- /dev/null +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 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.flow + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.map +import org.matrix.android.sdk.api.util.Optional + +fun Flow>.unwrap(): Flow { + return filter { it.hasValue() }.map { it.get() } +} + +fun Flow>.mapOptional(fn: (T) -> U?): Flow> { + return map { + it.map(fn) + } +} diff --git a/matrix-sdk-android-flow/src/test/java/org/matrix/android/sdk/flow/ExampleUnitTest.kt b/matrix-sdk-android-flow/src/test/java/org/matrix/android/sdk/flow/ExampleUnitTest.kt new file mode 100644 index 0000000000..bd627b2041 --- /dev/null +++ b/matrix-sdk-android-flow/src/test/java/org/matrix/android/sdk/flow/ExampleUnitTest.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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.flow + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/settings.gradle b/settings.gradle index b88ea99b05..e3b84b4733 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,3 +5,4 @@ include ':diff-match-patch' include ':attachment-viewer' include ':multipicker' include ':library:ui-styles' +include ':matrix-sdk-android-flow' diff --git a/vector/build.gradle b/vector/build.gradle index a9c6a407d8..76bc71b2d4 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -323,6 +323,7 @@ dependencies { implementation project(":matrix-sdk-android") implementation project(":matrix-sdk-android-rx") + implementation project(":matrix-sdk-android-flow") implementation project(":diff-match-patch") implementation project(":multipicker") implementation project(":attachment-viewer")