ganfra
2 years ago
committed by
GitHub
35 changed files with 629 additions and 185 deletions
@ -0,0 +1,46 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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 io.element.android.x.features.roomlist |
||||||
|
|
||||||
|
import app.cash.molecule.RecompositionClock |
||||||
|
import app.cash.molecule.moleculeFlow |
||||||
|
import app.cash.turbine.test |
||||||
|
import com.google.common.truth.Truth.assertThat |
||||||
|
import io.element.android.x.libraries.matrixtest.FakeMatrixClient |
||||||
|
import io.element.android.x.matrix.core.SessionId |
||||||
|
import kotlinx.coroutines.test.runTest |
||||||
|
import org.junit.Test |
||||||
|
|
||||||
|
class RoomListPresenterTests { |
||||||
|
|
||||||
|
@Test |
||||||
|
fun `present - should start with no user and then load user with success`() = runTest { |
||||||
|
|
||||||
|
val presenter = RoomListPresenter( |
||||||
|
FakeMatrixClient( |
||||||
|
SessionId("sessionId") |
||||||
|
), LastMessageFormatter()) |
||||||
|
moleculeFlow(RecompositionClock.Immediate) { |
||||||
|
presenter.present() |
||||||
|
}.test { |
||||||
|
val initialState = awaitItem() |
||||||
|
assertThat(initialState.matrixUser).isNull() |
||||||
|
val withUserState = awaitItem() |
||||||
|
assertThat(withUserState).isNotNull() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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 io.element.android.x.matrix.auth |
||||||
|
|
||||||
|
import io.element.android.x.matrix.MatrixClient |
||||||
|
import io.element.android.x.matrix.core.SessionId |
||||||
|
import kotlinx.coroutines.flow.Flow |
||||||
|
|
||||||
|
interface MatrixAuthenticationService { |
||||||
|
fun isLoggedIn(): Flow<Boolean> |
||||||
|
suspend fun getLatestSessionId(): SessionId? |
||||||
|
suspend fun restoreSession(): MatrixClient? |
||||||
|
fun getHomeserver(): String? |
||||||
|
fun getHomeserverOrDefault(): String |
||||||
|
suspend fun setHomeserver(homeserver: String) |
||||||
|
suspend fun login(username: String, password: String): SessionId |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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 io.element.android.x.matrix.di |
||||||
|
|
||||||
|
import com.squareup.anvil.annotations.ContributesTo |
||||||
|
import dagger.Module |
||||||
|
import dagger.Provides |
||||||
|
import io.element.android.x.di.AppScope |
||||||
|
import io.element.android.x.di.SingleIn |
||||||
|
import org.matrix.rustcomponents.sdk.AuthenticationService |
||||||
|
import java.io.File |
||||||
|
|
||||||
|
@Module |
||||||
|
@ContributesTo(AppScope::class) |
||||||
|
object MatrixModule { |
||||||
|
|
||||||
|
@Provides |
||||||
|
@SingleIn(AppScope::class) |
||||||
|
fun providesRustAuthenticationService(baseDirectory: File): AuthenticationService { |
||||||
|
return AuthenticationService(baseDirectory.absolutePath) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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 io.element.android.x.matrix.media |
||||||
|
|
||||||
|
import io.element.android.x.matrix.MatrixClient |
||||||
|
import org.matrix.rustcomponents.sdk.mediaSourceFromUrl |
||||||
|
|
||||||
|
internal class RustMediaResolver(private val client: MatrixClient) : MediaResolver { |
||||||
|
|
||||||
|
override suspend fun resolve(url: String?, kind: MediaResolver.Kind): ByteArray? { |
||||||
|
if (url.isNullOrEmpty()) return null |
||||||
|
val mediaSource = mediaSourceFromUrl(url) |
||||||
|
return resolve(MediaResolver.Meta(mediaSource, kind)) |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun resolve(meta: MediaResolver.Meta): ByteArray? { |
||||||
|
return when (meta.kind) { |
||||||
|
is MediaResolver.Kind.Content -> client.loadMediaContentForSource(meta.source) |
||||||
|
is MediaResolver.Kind.Thumbnail -> client.loadMediaThumbnailForSource( |
||||||
|
meta.source, |
||||||
|
meta.kind.width.toLong(), |
||||||
|
meta.kind.height.toLong() |
||||||
|
) |
||||||
|
}.getOrNull() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2022 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 io.element.android.x.matrix.session |
||||||
|
|
||||||
|
import android.content.Context |
||||||
|
import androidx.datastore.core.DataStore |
||||||
|
import androidx.datastore.preferences.core.Preferences |
||||||
|
import androidx.datastore.preferences.core.edit |
||||||
|
import androidx.datastore.preferences.core.stringPreferencesKey |
||||||
|
import androidx.datastore.preferences.preferencesDataStore |
||||||
|
import com.squareup.anvil.annotations.ContributesBinding |
||||||
|
import io.element.android.x.di.AppScope |
||||||
|
import io.element.android.x.di.ApplicationContext |
||||||
|
import io.element.android.x.di.SingleIn |
||||||
|
import kotlinx.coroutines.flow.Flow |
||||||
|
import kotlinx.coroutines.flow.firstOrNull |
||||||
|
import kotlinx.coroutines.flow.map |
||||||
|
import kotlinx.serialization.Serializable |
||||||
|
import kotlinx.serialization.decodeFromString |
||||||
|
import kotlinx.serialization.encodeToString |
||||||
|
import kotlinx.serialization.json.Json |
||||||
|
import org.matrix.rustcomponents.sdk.Session |
||||||
|
import javax.inject.Inject |
||||||
|
|
||||||
|
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "elementx_sessions") |
||||||
|
|
||||||
|
// TODO It contains the access token, so it has to be stored in a more secured storage. |
||||||
|
private val sessionKey = stringPreferencesKey("session") |
||||||
|
|
||||||
|
@SingleIn(AppScope::class) |
||||||
|
@ContributesBinding(AppScope::class) |
||||||
|
class PreferencesSessionStore @Inject constructor( |
||||||
|
@ApplicationContext context: Context |
||||||
|
) : SessionStore { |
||||||
|
@Serializable |
||||||
|
data class SessionData( |
||||||
|
val accessToken: String, |
||||||
|
val deviceId: String, |
||||||
|
val homeserverUrl: String, |
||||||
|
val isSoftLogout: Boolean, |
||||||
|
val refreshToken: String?, |
||||||
|
val userId: String |
||||||
|
) |
||||||
|
|
||||||
|
private val store = context.dataStore |
||||||
|
|
||||||
|
override fun isLoggedIn(): Flow<Boolean> { |
||||||
|
return store.data.map { prefs -> |
||||||
|
prefs[sessionKey] != null |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun storeData(session: Session) { |
||||||
|
store.edit { prefs -> |
||||||
|
val sessionData = SessionData( |
||||||
|
accessToken = session.accessToken, |
||||||
|
deviceId = session.deviceId, |
||||||
|
homeserverUrl = session.homeserverUrl, |
||||||
|
isSoftLogout = session.isSoftLogout, |
||||||
|
refreshToken = session.refreshToken, |
||||||
|
userId = session.userId |
||||||
|
) |
||||||
|
val encodedSession = Json.encodeToString(sessionData) |
||||||
|
prefs[sessionKey] = encodedSession |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun getLatestSession(): Session? { |
||||||
|
return store.data.firstOrNull()?.let { prefs -> |
||||||
|
val encodedSession = prefs[sessionKey] ?: return@let null |
||||||
|
val sessionData = Json.decodeFromString<SessionData>(encodedSession) |
||||||
|
Session( |
||||||
|
accessToken = sessionData.accessToken, |
||||||
|
deviceId = sessionData.deviceId, |
||||||
|
homeserverUrl = sessionData.homeserverUrl, |
||||||
|
isSoftLogout = sessionData.isSoftLogout, |
||||||
|
refreshToken = sessionData.refreshToken, |
||||||
|
userId = sessionData.userId |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun reset() { |
||||||
|
store.edit { it.clear() } |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed |
||||||
|
@Suppress("DSL_SCOPE_VIOLATION") |
||||||
|
plugins { |
||||||
|
id("io.element.android-library") |
||||||
|
} |
||||||
|
|
||||||
|
android { |
||||||
|
namespace = "io.element.android.x.libraries.matrix.test" |
||||||
|
} |
||||||
|
|
||||||
|
dependencies { |
||||||
|
api(project(":libraries:matrix")) |
||||||
|
api(libs.coroutines.core) |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright (c) 2023 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<manifest/> |
@ -0,0 +1,70 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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 io.element.android.x.libraries.matrixtest |
||||||
|
|
||||||
|
import io.element.android.x.matrix.MatrixClient |
||||||
|
import io.element.android.x.matrix.core.RoomId |
||||||
|
import io.element.android.x.matrix.core.SessionId |
||||||
|
import io.element.android.x.matrix.core.UserId |
||||||
|
import io.element.android.x.libraries.matrixtest.media.FakeMediaResolver |
||||||
|
import io.element.android.x.matrix.media.MediaResolver |
||||||
|
import io.element.android.x.libraries.matrixtest.room.FakeMatrixRoom |
||||||
|
import io.element.android.x.libraries.matrixtest.room.InMemoryRoomSummaryDataSource |
||||||
|
import io.element.android.x.matrix.room.MatrixRoom |
||||||
|
import io.element.android.x.matrix.room.RoomSummaryDataSource |
||||||
|
import org.matrix.rustcomponents.sdk.MediaSource |
||||||
|
|
||||||
|
class FakeMatrixClient(override val sessionId: SessionId) : MatrixClient { |
||||||
|
|
||||||
|
override fun getRoom(roomId: RoomId): MatrixRoom? { |
||||||
|
return FakeMatrixRoom(roomId) |
||||||
|
} |
||||||
|
|
||||||
|
override fun startSync() = Unit |
||||||
|
|
||||||
|
override fun stopSync() = Unit |
||||||
|
|
||||||
|
override fun roomSummaryDataSource(): RoomSummaryDataSource { |
||||||
|
return InMemoryRoomSummaryDataSource() |
||||||
|
} |
||||||
|
|
||||||
|
override fun mediaResolver(): MediaResolver { |
||||||
|
return FakeMediaResolver() |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun logout() = Unit |
||||||
|
|
||||||
|
override fun userId(): UserId = UserId("") |
||||||
|
|
||||||
|
override suspend fun loadUserDisplayName(): Result<String> { |
||||||
|
return Result.success("") |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun loadUserAvatarURLString(): Result<String> { |
||||||
|
return Result.success("") |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun loadMediaContentForSource(source: MediaSource): Result<ByteArray> { |
||||||
|
return Result.success(ByteArray(0)) |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun loadMediaThumbnailForSource(source: MediaSource, width: Long, height: Long): Result<ByteArray> { |
||||||
|
return Result.success(ByteArray(0)) |
||||||
|
} |
||||||
|
|
||||||
|
override fun close() = Unit |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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 io.element.android.x.libraries.matrixtest.room |
||||||
|
|
||||||
|
import io.element.android.x.matrix.core.EventId |
||||||
|
import io.element.android.x.matrix.core.RoomId |
||||||
|
import io.element.android.x.matrix.room.MatrixRoom |
||||||
|
import io.element.android.x.libraries.matrixtest.timeline.FakeMatrixTimeline |
||||||
|
import io.element.android.x.matrix.timeline.MatrixTimeline |
||||||
|
import kotlinx.coroutines.flow.Flow |
||||||
|
import kotlinx.coroutines.flow.emptyFlow |
||||||
|
|
||||||
|
class FakeMatrixRoom( |
||||||
|
override val roomId: RoomId, |
||||||
|
override val name: String? = null, |
||||||
|
override val bestName: String = "", |
||||||
|
override val displayName: String = "", |
||||||
|
override val topic: String? = null, |
||||||
|
override val avatarUrl: String? = null |
||||||
|
) : MatrixRoom { |
||||||
|
|
||||||
|
override fun syncUpdateFlow(): Flow<Long> { |
||||||
|
return emptyFlow() |
||||||
|
} |
||||||
|
|
||||||
|
override fun timeline(): MatrixTimeline { |
||||||
|
return FakeMatrixTimeline() |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun userDisplayName(userId: String): Result<String?> { |
||||||
|
return Result.success("") |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun userAvatarUrl(userId: String): Result<String?> { |
||||||
|
TODO("Not yet implemented") |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun sendMessage(message: String): Result<Unit> { |
||||||
|
TODO("Not yet implemented") |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun editMessage(originalEventId: EventId, message: String): Result<Unit> { |
||||||
|
TODO("Not yet implemented") |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun replyMessage(eventId: EventId, message: String): Result<Unit> { |
||||||
|
TODO("Not yet implemented") |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun redactEvent(eventId: EventId, reason: String?): Result<Unit> { |
||||||
|
TODO("Not yet implemented") |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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 io.element.android.x.libraries.matrixtest.room |
||||||
|
|
||||||
|
import io.element.android.x.matrix.room.RoomSummary |
||||||
|
import io.element.android.x.matrix.room.RoomSummaryDataSource |
||||||
|
import kotlinx.coroutines.flow.Flow |
||||||
|
import kotlinx.coroutines.flow.emptyFlow |
||||||
|
|
||||||
|
class InMemoryRoomSummaryDataSource : RoomSummaryDataSource { |
||||||
|
|
||||||
|
override fun roomSummaries(): Flow<List<RoomSummary>> { |
||||||
|
return emptyFlow() |
||||||
|
} |
||||||
|
|
||||||
|
override fun setSlidingSyncRange(range: IntRange) = Unit |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 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 io.element.android.x.libraries.matrixtest.timeline |
||||||
|
|
||||||
|
import io.element.android.x.matrix.core.EventId |
||||||
|
import io.element.android.x.matrix.timeline.MatrixTimeline |
||||||
|
import io.element.android.x.matrix.timeline.MatrixTimelineItem |
||||||
|
import kotlinx.coroutines.flow.Flow |
||||||
|
import kotlinx.coroutines.flow.emptyFlow |
||||||
|
import org.matrix.rustcomponents.sdk.TimelineListener |
||||||
|
|
||||||
|
class FakeMatrixTimeline : MatrixTimeline { |
||||||
|
|
||||||
|
override var callback: MatrixTimeline.Callback? |
||||||
|
get() = null |
||||||
|
set(value) {} |
||||||
|
|
||||||
|
override val hasMoreToLoad: Boolean |
||||||
|
get() = true |
||||||
|
|
||||||
|
override fun timelineItems(): Flow<List<MatrixTimelineItem>> { |
||||||
|
return emptyFlow() |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun paginateBackwards(count: Int): Result<Unit> { |
||||||
|
return Result.success(Unit) |
||||||
|
} |
||||||
|
|
||||||
|
override fun addListener(timelineListener: TimelineListener) = Unit |
||||||
|
|
||||||
|
override fun initialize() = Unit |
||||||
|
|
||||||
|
override fun dispose() = Unit |
||||||
|
|
||||||
|
override suspend fun sendMessage(message: String): Result<Unit> { |
||||||
|
return Result.success(Unit) |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun editMessage(originalEventId: EventId, message: String): Result<Unit> { |
||||||
|
return Result.success(Unit) |
||||||
|
} |
||||||
|
|
||||||
|
override suspend fun replyMessage(inReplyToEventId: EventId, message: String): Result<Unit> { |
||||||
|
return Result.success(Unit) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue