Threads - first iteration (#5165)
* Initial threads support: parse `ThreadSummary`. Replace several `isThreaded` values with `EventThreadInfo`, which contains the info about the event either being the root of a thread or part of it. * Add `Threaded` timeline mode * Add a `liveTimeline` parameter to `TimelineController`'s constructor. This way we can customise which timeline will be used as the 'live' one. Also add `@LiveTimeline` DI qualifier for the actual live timeline of the room. * Create `ThreadedMessagesNode`. Allow opening a thread in a separate screen. * Add the callbacks for the list menu actions - even if they're the wrong ones and will send the data to the room instead * Send attachments and location in threads * Fix polls in threads, add support for sending voice messages in threads * Display thread summaries only when the feature flag is enabled * Use 'Reply' instead of 'Reply in thread' when in threaded timeline mode * Remove incorrect usage of `Timeline` in `MessageComposerPresenter`. This led to replies to threaded events not appearing as actual replies. --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
parent
8675bf5215
commit
285066c206
119 changed files with 1520 additions and 339 deletions
|
|
@ -15,7 +15,12 @@ android {
|
|||
|
||||
dependencies {
|
||||
api(projects.features.messages.impl)
|
||||
implementation(projects.libraries.matrix.api)
|
||||
implementation(projects.libraries.matrix.test)
|
||||
implementation(projects.libraries.mediaplayer.test)
|
||||
implementation(projects.libraries.mediaupload.test)
|
||||
implementation(projects.libraries.mediaviewer.api)
|
||||
implementation(projects.libraries.permissions.test)
|
||||
implementation(projects.libraries.preferences.api)
|
||||
implementation(projects.libraries.voicerecorder.test)
|
||||
implementation(projects.services.analytics.test)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.messages.test.timeline.voicemessages.composer
|
||||
|
||||
import io.element.android.features.messages.impl.voicemessages.composer.DefaultVoiceMessageComposerPresenter
|
||||
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerPlayer
|
||||
import io.element.android.features.messages.test.FakeMessageComposerContext
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||
import io.element.android.libraries.mediaupload.api.MediaSender
|
||||
import io.element.android.libraries.mediaupload.test.FakeMediaOptimizationConfigProvider
|
||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||
import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory
|
||||
import io.element.android.libraries.voicerecorder.test.FakeVoiceRecorder
|
||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
class FakeDefaultVoiceMessageComposerPresenterFactory(
|
||||
private val sessionCoroutineScope: CoroutineScope,
|
||||
private val mediaSender: MediaSender = MediaSender(
|
||||
preProcessor = FakeMediaPreProcessor(),
|
||||
room = FakeJoinedRoom(),
|
||||
timelineMode = Timeline.Mode.Live,
|
||||
mediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(),
|
||||
),
|
||||
) : DefaultVoiceMessageComposerPresenter.Factory {
|
||||
override fun create(timelineMode: Timeline.Mode): DefaultVoiceMessageComposerPresenter {
|
||||
return DefaultVoiceMessageComposerPresenter(
|
||||
sessionCoroutineScope = sessionCoroutineScope,
|
||||
timelineMode = timelineMode,
|
||||
voiceRecorder = FakeVoiceRecorder(),
|
||||
analyticsService = FakeAnalyticsService(),
|
||||
mediaSenderFactory = object : MediaSender.Factory {
|
||||
override fun create(timelineMode: Timeline.Mode): MediaSender {
|
||||
return mediaSender
|
||||
}
|
||||
},
|
||||
player = VoiceMessageComposerPlayer(
|
||||
mediaPlayer = FakeMediaPlayer(),
|
||||
sessionCoroutineScope = sessionCoroutineScope,
|
||||
),
|
||||
messageComposerContext = FakeMessageComposerContext(),
|
||||
permissionsPresenterFactory = FakePermissionsPresenterFactory(),
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue