Fixes after rebase
This commit is contained in:
parent
ddf9e5055e
commit
e8328858ab
117 changed files with 310 additions and 295 deletions
|
|
@ -14,7 +14,7 @@ import dev.zacsweers.metro.AppScope
|
|||
import dev.zacsweers.metro.ContributesBinding
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.deeplink.api.DeepLinkCreator
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.libraries.di.annotations.ApplicationContext
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultAnalyticsEntryPoint() : AnalyticsEntryPoint {
|
||||
class DefaultAnalyticsEntryPoint : AnalyticsEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
|
||||
return parentNode.createNode<AnalyticsOptInNode>(buildContext)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ interface LanguageTagProvider {
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultLanguageTagProvider() : LanguageTagProvider {
|
||||
class DefaultLanguageTagProvider : LanguageTagProvider {
|
||||
@Composable
|
||||
override fun provideLanguageTag(): String? {
|
||||
return LocalConfiguration.current.locales.get(0)?.toLanguageTag()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import androidx.core.net.toUri
|
|||
import dev.zacsweers.metro.Inject
|
||||
|
||||
@Inject
|
||||
class CallIntentDataParser() {
|
||||
class CallIntentDataParser {
|
||||
private val validHttpSchemes = sequenceOf("https")
|
||||
private val knownHosts = sequenceOf(
|
||||
"call.element.io",
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.widget.CallAnalyticCredentialsPro
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultCallAnalyticCredentialsProvider() : CallAnalyticCredentialsProvider {
|
||||
class DefaultCallAnalyticCredentialsProvider : CallAnalyticCredentialsProvider {
|
||||
override val posthogUserId: String? = BuildConfig.POSTHOG_USER_ID.takeIf { it.isNotBlank() }
|
||||
override val posthogApiHost: String? = BuildConfig.POSTHOG_API_HOST.takeIf { it.isNotBlank() }
|
||||
override val posthogApiKey: String? = BuildConfig.POSTHOG_API_KEY.takeIf { it.isNotBlank() }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
@SingleIn(AppScope::class)
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultCurrentCallService() : CurrentCallService {
|
||||
class DefaultCurrentCallService : CurrentCallService {
|
||||
override val currentCall = MutableStateFlow<CurrentCall>(CurrentCall.None)
|
||||
|
||||
fun onCallStarted(call: CurrentCall) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class DefaultChangeRoomMemberRolesEntyPoint() : ChangeRoomMemberRolesEntryPoint {
|
||||
class DefaultChangeRoomMemberRolesEntyPoint : ChangeRoomMemberRolesEntryPoint {
|
||||
override fun builder(parentNode: Node, buildContext: BuildContext): ChangeRoomMemberRolesEntryPoint.Builder {
|
||||
return object : ChangeRoomMemberRolesEntryPoint.Builder {
|
||||
private lateinit var changeRoomMemberRolesListType: ChangeRoomMemberRolesListType
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.di.SessionScope
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class DefaultCreateRoomEntryPoint() : CreateRoomEntryPoint {
|
||||
class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): CreateRoomEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultAccountDeactivationEntryPoint() : AccountDeactivationEntryPoint {
|
||||
class DefaultAccountDeactivationEntryPoint : AccountDeactivationEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
|
||||
return parentNode.createNode<AccountDeactivationNode>(buildContext)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import kotlinx.coroutines.flow.flowOf
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultEnterpriseService() : EnterpriseService {
|
||||
class DefaultEnterpriseService : EnterpriseService {
|
||||
override val isEnterpriseBuild = false
|
||||
|
||||
override suspend fun isEnterpriseUser(sessionId: SessionId) = false
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import io.element.android.libraries.di.SessionScope
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class DefaultSessionEnterpriseService() : SessionEnterpriseService {
|
||||
class DefaultSessionEnterpriseService : SessionEnterpriseService {
|
||||
override suspend fun init() = Unit
|
||||
override suspend fun isElementCallAvailable(): Boolean = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultFtueEntryPoint() : FtueEntryPoint {
|
||||
class DefaultFtueEntryPoint : FtueEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): FtueEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultHomeEntryPoint() : HomeEntryPoint {
|
||||
class DefaultHomeEntryPoint : HomeEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): HomeEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class DefaultFilterSelectionStrategy() : FilterSelectionStrategy {
|
||||
class DefaultFilterSelectionStrategy : FilterSelectionStrategy {
|
||||
private val selectedFilters = LinkedHashSet<RoomListFilter>()
|
||||
|
||||
override val filterSelectionStates = MutableStateFlow(buildFilters())
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class DefaultAcceptDeclineInviteView() : AcceptDeclineInviteView {
|
||||
class DefaultAcceptDeclineInviteView : AcceptDeclineInviteView {
|
||||
@Composable
|
||||
override fun Render(
|
||||
state: AcceptDeclineInviteState,
|
||||
|
|
|
|||
|
|
@ -25,20 +25,20 @@ import io.element.android.libraries.di.SessionScope
|
|||
class DeclineAndBlockNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
// presenterFactory: DeclineAndBlockPresenter.Factory,
|
||||
presenterFactory: DeclineAndBlockPresenter.Factory,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
data class Inputs(val inviteData: InviteData) : NodeInputs
|
||||
|
||||
private val inviteData = inputs<Inputs>().inviteData
|
||||
// private val presenter = presenterFactory.create(inviteData)
|
||||
private val presenter = presenterFactory.create(inviteData)
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
// val state = presenter.present()
|
||||
// DeclineAndBlockView(
|
||||
// state = state,
|
||||
// onBackClick = ::navigateUp,
|
||||
// modifier = modifier
|
||||
// )
|
||||
val state = presenter.present()
|
||||
DeclineAndBlockView(
|
||||
state = state,
|
||||
onBackClick = ::navigateUp,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultDeclineAndBlockEntryPoint() : DeclineInviteAndBlockEntryPoint {
|
||||
class DefaultDeclineAndBlockEntryPoint : DeclineInviteAndBlockEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, inviteData: InviteData): Node {
|
||||
val inputs = DeclineAndBlockNode.Inputs(inviteData)
|
||||
return parentNode.createNode<DeclineAndBlockNode>(buildContext, plugins = listOf(inputs))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.libraries.di.SessionScope
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class DefaultInvitePeopleRenderer() : InvitePeopleRenderer {
|
||||
class DefaultInvitePeopleRenderer : InvitePeopleRenderer {
|
||||
@Composable
|
||||
override fun Render(state: InvitePeopleState, modifier: Modifier) {
|
||||
if (state is DefaultInvitePeopleState) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultJoinRoomEntryPoint() : JoinRoomEntryPoint {
|
||||
class DefaultJoinRoomEntryPoint : JoinRoomEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, inputs: JoinRoomEntryPoint.Inputs): Node {
|
||||
return parentNode.createNode<JoinRoomFlowNode>(
|
||||
buildContext = buildContext,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultKnockRequestsListEntryPoint() : KnockRequestsListEntryPoint {
|
||||
class DefaultKnockRequestsListEntryPoint : KnockRequestsListEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
|
||||
return parentNode.createNode<KnockRequestsListNode>(buildContext)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class InternalLeaveRoomRenderer() : LeaveRoomRenderer {
|
||||
class InternalLeaveRoomRenderer : LeaveRoomRenderer {
|
||||
@Composable
|
||||
override fun Render(state: LeaveRoomState, onSelectNewOwners: (RoomId) -> Unit, modifier: Modifier) {
|
||||
if (state is InternalLeaveRoomState) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultOpenSourcesLicensesEntryPoint() : OpenSourceLicensesEntryPoint {
|
||||
class DefaultOpenSourcesLicensesEntryPoint : OpenSourceLicensesEntryPoint {
|
||||
override fun getNode(node: Node, buildContext: BuildContext): Node {
|
||||
return node.createNode<DependenciesFlowNode>(buildContext)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import io.element.android.features.location.api.LocationService
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultLocationService() : LocationService {
|
||||
class DefaultLocationService : LocationService {
|
||||
override fun isServiceAvailable(): Boolean {
|
||||
return BuildConfig.MAPTILER_API_KEY.isNotEmpty()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultSendLocationEntryPoint() : SendLocationEntryPoint {
|
||||
class DefaultSendLocationEntryPoint : SendLocationEntryPoint {
|
||||
override fun builder(timelineMode: Timeline.Mode): SendLocationEntryPoint.Builder {
|
||||
return Builder(timelineMode)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultShowLocationEntryPoint() : ShowLocationEntryPoint {
|
||||
class DefaultShowLocationEntryPoint : ShowLocationEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, inputs: ShowLocationEntryPoint.Inputs): Node {
|
||||
return parentNode.createNode<ShowLocationNode>(buildContext, listOf(inputs))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultLockScreenEntryPoint() : LockScreenEntryPoint {
|
||||
class DefaultLockScreenEntryPoint : LockScreenEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext, navTarget: LockScreenEntryPoint.Target): LockScreenEntryPoint.NodeBuilder {
|
||||
val callbacks = mutableListOf<LockScreenEntryPoint.Callback>()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultLoginEntryPoint() : LoginEntryPoint {
|
||||
class DefaultLoginEntryPoint : LoginEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): LoginEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import io.element.android.features.login.api.LoginParams
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultLoginIntentResolver() : LoginIntentResolver {
|
||||
class DefaultLoginIntentResolver : LoginIntentResolver {
|
||||
override fun parse(uriString: String): LoginParams? {
|
||||
val uri = uriString.toUri()
|
||||
if (uri.host != "mobile.element.io") return null
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.features.login.impl.DefaultLoginUserStory
|
||||
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
|
|
|
|||
|
|
@ -9,17 +9,18 @@ package io.element.android.features.login.impl.screens.onboarding
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import javax.inject.Inject
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.ContributesBinding
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.di.annotations.ApplicationContext
|
||||
|
||||
fun interface OnBoardingLogoResIdProvider {
|
||||
fun get(): Int?
|
||||
}
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultOnBoardingLogoResIdProvider @Inject constructor(
|
||||
@Inject
|
||||
class DefaultOnBoardingLogoResIdProvider(
|
||||
@ApplicationContext private val context: Context,
|
||||
) : OnBoardingLogoResIdProvider {
|
||||
@SuppressLint("DiscouragedApi")
|
||||
|
|
|
|||
|
|
@ -10,11 +10,10 @@ package io.element.android.features.login.impl.di
|
|||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import io.element.android.features.login.impl.qrcode.FakeQrCodeLoginManager
|
||||
import io.element.android.features.login.impl.qrcode.QrCodeLoginFlowNode
|
||||
import io.element.android.features.login.impl.qrcode.QrCodeLoginManager
|
||||
import io.element.android.libraries.architecture.AssistedNodeFactory
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
internal class FakeQrCodeLoginGraph(
|
||||
private val qrCodeLoginManager: QrCodeLoginManager,
|
||||
|
|
@ -23,7 +22,7 @@ internal class FakeQrCodeLoginGraph(
|
|||
return mapOf(
|
||||
QrCodeLoginFlowNode::class to object : AssistedNodeFactory<QrCodeLoginFlowNode> {
|
||||
override fun create(buildContext: BuildContext, plugins: List<Plugin>): QrCodeLoginFlowNode {
|
||||
return createNode<QrCodeLoginFlowNode>(buildContext, plugins)
|
||||
error("This factory should not be called in tests")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -33,9 +32,9 @@ internal class FakeQrCodeLoginGraph(
|
|||
|
||||
internal class Builder(
|
||||
private val qrCodeLoginManager: QrCodeLoginManager,
|
||||
) : QrCodeLoginComponent.Factory {
|
||||
override fun create(): QrCodeLoginComponent {
|
||||
return FakeQrCodeLoginComponent(qrCodeLoginManager)
|
||||
) : QrCodeLoginGraph.Factory {
|
||||
override fun create(): QrCodeLoginGraph {
|
||||
return FakeQrCodeLoginGraph(qrCodeLoginManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultLogoutEntryPoint() : LogoutEntryPoint {
|
||||
class DefaultLogoutEntryPoint : LogoutEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): LogoutEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import io.element.android.libraries.di.SessionScope
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class DefaultDirectLogoutView() : DirectLogoutView {
|
||||
class DefaultDirectLogoutView : DirectLogoutView {
|
||||
@Composable
|
||||
override fun Render(state: DirectLogoutState) {
|
||||
val eventSink = state.eventSink
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
|
|||
* Currently it's used to store draft message when moving to edit mode.
|
||||
*/
|
||||
@Inject
|
||||
class VolatileComposerDraftStore() : ComposerDraftStore {
|
||||
class VolatileComposerDraftStore : ComposerDraftStore {
|
||||
private val drafts: MutableMap<String, ComposerDraft> = mutableMapOf()
|
||||
|
||||
override suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?): ComposerDraft? {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ interface LinkChecker {
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultLinkChecker() : LinkChecker {
|
||||
class DefaultLinkChecker : LinkChecker {
|
||||
override fun isSafe(link: Link): Boolean {
|
||||
return if (link.url.containsRtLOverride()) {
|
||||
false
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
|||
@SingleIn(RoomScope::class)
|
||||
@ContributesBinding(RoomScope::class)
|
||||
@Inject
|
||||
class DefaultMessageComposerContext() : MessageComposerContext {
|
||||
class DefaultMessageComposerContext : MessageComposerContext {
|
||||
override var composerMode: MessageComposerMode by mutableStateOf(MessageComposerMode.Normal)
|
||||
internal set
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ interface RichTextEditorStateFactory {
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultRichTextEditorStateFactory() : RichTextEditorStateFactory {
|
||||
class DefaultRichTextEditorStateFactory : RichTextEditorStateFactory {
|
||||
@Composable
|
||||
override fun remember(): RichTextEditorState {
|
||||
return rememberRichTextEditorState()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import io.element.android.libraries.textcomposer.model.SuggestionType
|
|||
* This class is responsible for processing suggestions when `@`, `/` or `#` are type in the composer.
|
||||
*/
|
||||
@Inject
|
||||
class SuggestionsProcessor() {
|
||||
class SuggestionsProcessor {
|
||||
/**
|
||||
* Process the suggestion.
|
||||
* @param suggestion The current suggestion input
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import kotlinx.coroutines.sync.withLock
|
|||
import timber.log.Timber
|
||||
|
||||
@Inject
|
||||
class TimelineItemIndexer() {
|
||||
class TimelineItemIndexer {
|
||||
// This is a latch to wait for the first process call
|
||||
private val firstProcessLatch = CompletableDeferred<Unit>()
|
||||
private val timelineEventsIndexes = mutableMapOf<EventId, Int>()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
|||
import io.element.android.libraries.architecture.Presenter
|
||||
|
||||
@Inject
|
||||
class ReadReceiptBottomSheetPresenter() : Presenter<ReadReceiptBottomSheetState> {
|
||||
class ReadReceiptBottomSheetPresenter : Presenter<ReadReceiptBottomSheetState> {
|
||||
@Composable
|
||||
override fun present(): ReadReceiptBottomSheetState {
|
||||
var selectedEvent: TimelineItem.Event? by remember { mutableStateOf(null) }
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent
|
||||
|
||||
@Inject
|
||||
class TimelineItemContentFailedToParseMessageFactory() {
|
||||
class TimelineItemContentFailedToParseMessageFactory {
|
||||
fun create(@Suppress("UNUSED_PARAMETER") failedToParseMessageLike: FailedToParseMessageLikeContent): TimelineItemEventContent {
|
||||
return TimelineItemUnknownContent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent
|
||||
|
||||
@Inject
|
||||
class TimelineItemContentFailedToParseStateFactory() {
|
||||
class TimelineItemContentFailedToParseStateFactory {
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun create(failedToParseState: FailedToParseStateContent): TimelineItemEventContent {
|
||||
return TimelineItemUnknownContent
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
|
||||
|
||||
@Inject
|
||||
class TimelineItemContentRedactedFactory() {
|
||||
class TimelineItemContentRedactedFactory {
|
||||
fun create(@Suppress("UNUSED_PARAMETER") content: RedactedContent): TimelineItemEventContent {
|
||||
return TimelineItemRedactedContent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||
|
||||
@Inject
|
||||
class TimelineItemContentUTDFactory() {
|
||||
class TimelineItemContentUTDFactory {
|
||||
fun create(content: UnableToDecryptContent): TimelineItemEventContent {
|
||||
return TimelineItemEncryptedContent(content.data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
|
||||
@SingleIn(RoomScope::class)
|
||||
@Inject
|
||||
class TimelineItemGrouper() {
|
||||
class TimelineItemGrouper {
|
||||
/**
|
||||
* Keys are identifier of items in a group, only one by group will be kept.
|
||||
* Values are the actual groupIds.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultCreatePollEntryPoint() : CreatePollEntryPoint {
|
||||
class DefaultCreatePollEntryPoint : CreatePollEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): CreatePollEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultPollHistoryEntryPoint() : PollHistoryEntryPoint {
|
||||
class DefaultPollHistoryEntryPoint : PollHistoryEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
|
||||
return parentNode.createNode<PollHistoryFlowNode>(buildContext)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
|||
@SingleIn(AppScope::class)
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultCacheService() : CacheService {
|
||||
class DefaultCacheService : CacheService {
|
||||
private val _clearedCacheEventFlow = MutableSharedFlow<SessionId>(0)
|
||||
override val clearedCacheEventFlow: Flow<SessionId> = _clearedCacheEventFlow
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultPreferencesEntryPoint() : PreferencesEntryPoint {
|
||||
class DefaultPreferencesEntryPoint : PreferencesEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): PreferencesEntryPoint.NodeBuilder {
|
||||
return object : PreferencesEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import dev.zacsweers.metro.Inject
|
|||
import io.element.android.libraries.architecture.Presenter
|
||||
|
||||
@Inject
|
||||
class AboutPresenter() : Presenter<AboutState> {
|
||||
class AboutPresenter : Presenter<AboutState> {
|
||||
@Composable
|
||||
override fun present(): AboutState {
|
||||
return AboutState(
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultBugReportEntryPoint() : BugReportEntryPoint {
|
||||
class DefaultBugReportEntryPoint : BugReportEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): BugReportEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
package io.element.android.features.rageshake.impl.di
|
||||
|
||||
import com.squareup.anvil.annotations.ContributesTo
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import io.element.android.features.rageshake.impl.crash.PreferencesCrashDataStore
|
||||
import io.element.android.libraries.di.AppScope
|
||||
|
||||
@ContributesTo(AppScope::class)
|
||||
interface RageshakeBindings {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,6 @@ fun interface BugReportAppNameProvider {
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultBugReportAppNameProvider() : BugReportAppNameProvider {
|
||||
class DefaultBugReportAppNameProvider : BugReportAppNameProvider {
|
||||
override fun provide(): String = RageshakeConfig.BUG_REPORT_APP_NAME
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultReportRoomEntryPoint() : ReportRoomEntryPoint {
|
||||
class DefaultReportRoomEntryPoint : ReportRoomEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, roomId: RoomId): Node {
|
||||
return parentNode.createNode<ReportRoomNode>(buildContext, plugins = listOf(ReportRoomNode.Inputs(roomId)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultRoomAliasResolverEntryPoint() : RoomAliasResolverEntryPoint {
|
||||
class DefaultRoomAliasResolverEntryPoint : RoomAliasResolverEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomAliasResolverEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultRoomDetailsEntryPoint() : RoomDetailsEntryPoint {
|
||||
class DefaultRoomDetailsEntryPoint : RoomDetailsEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomDetailsEntryPoint.NodeBuilder {
|
||||
return object : RoomDetailsEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultRoomDirectoryEntryPoint() : RoomDirectoryEntryPoint {
|
||||
class DefaultRoomDirectoryEntryPoint : RoomDirectoryEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomDirectoryEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import timber.log.Timber
|
|||
|
||||
@ContributesBinding(RoomScope::class)
|
||||
@Inject
|
||||
class DefaultRoomMemberModerationRenderer() : RoomMemberModerationRenderer {
|
||||
class DefaultRoomMemberModerationRenderer : RoomMemberModerationRenderer {
|
||||
@Composable
|
||||
override fun Render(
|
||||
state: RoomMemberModerationState,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultSecureBackupEntryPoint() : SecureBackupEntryPoint {
|
||||
class DefaultSecureBackupEntryPoint : SecureBackupEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): SecureBackupEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|||
import com.freeletics.flowredux.dsl.State as MachineState
|
||||
|
||||
@Inject
|
||||
class SecureBackupSetupStateMachine() : FlowReduxStateMachine<SecureBackupSetupStateMachine.State, SecureBackupSetupStateMachine.Event>(
|
||||
class SecureBackupSetupStateMachine : FlowReduxStateMachine<SecureBackupSetupStateMachine.State, SecureBackupSetupStateMachine.Event>(
|
||||
initialState = State.Initial
|
||||
) {
|
||||
init {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ private const val RECOVERY_KEY_LENGTH = 48
|
|||
private const val BASE_58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
@Inject
|
||||
class RecoveryKeyTools() {
|
||||
class RecoveryKeyTools {
|
||||
fun isRecoveryKeyFormatValid(recoveryKey: String): Boolean {
|
||||
val recoveryKeyWithoutSpace = recoveryKey.replace("\\s+".toRegex(), "")
|
||||
return recoveryKeyWithoutSpace.length == RECOVERY_KEY_LENGTH && recoveryKeyWithoutSpace.all { BASE_58_ALPHABET.contains(it) }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.di.SessionScope
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@Inject
|
||||
class DefaultShareEntryPoint() : ShareEntryPoint {
|
||||
class DefaultShareEntryPoint : ShareEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): ShareEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultSignedOutEntryPoint() : SignedOutEntryPoint {
|
||||
class DefaultSignedOutEntryPoint : SignedOutEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): SignedOutEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultStartChatEntryPoint() : StartChatEntryPoint {
|
||||
class DefaultStartChatEntryPoint : StartChatEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): StartChatEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
@Inject
|
||||
class UserListDataStore() {
|
||||
class UserListDataStore {
|
||||
private val _selectedUsers: MutableStateFlow<List<MatrixUser>> = MutableStateFlow(emptyList())
|
||||
|
||||
fun selectUser(user: MatrixUser) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultUserProfileEntryPoint() : UserProfileEntryPoint {
|
||||
class DefaultUserProfileEntryPoint : UserProfileEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): UserProfileEntryPoint.NodeBuilder {
|
||||
return object : UserProfileEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultIncomingVerificationEntryPoint() : IncomingVerificationEntryPoint {
|
||||
class DefaultIncomingVerificationEntryPoint : IncomingVerificationEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): IncomingVerificationEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultOutgoingVerificationEntryPoint() : OutgoingVerificationEntryPoint {
|
||||
class DefaultOutgoingVerificationEntryPoint : OutgoingVerificationEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): OutgoingVerificationEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -25,26 +25,26 @@ import io.element.android.libraries.di.SessionScope
|
|||
class OutgoingVerificationNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
// presenterFactory: OutgoingVerificationPresenter.Factory,
|
||||
presenterFactory: OutgoingVerificationPresenter.Factory,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
private val callback = plugins<OutgoingVerificationEntryPoint.Callback>().first()
|
||||
|
||||
private val inputs = inputs<OutgoingVerificationEntryPoint.Params>()
|
||||
|
||||
// private val presenter = presenterFactory.create(
|
||||
// showDeviceVerifiedScreen = inputs.showDeviceVerifiedScreen,
|
||||
// verificationRequest = inputs.verificationRequest,
|
||||
// )
|
||||
private val presenter = presenterFactory.create(
|
||||
showDeviceVerifiedScreen = inputs.showDeviceVerifiedScreen,
|
||||
verificationRequest = inputs.verificationRequest,
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
// val state = presenter.present()
|
||||
// OutgoingVerificationView(
|
||||
// state = state,
|
||||
// modifier = modifier,
|
||||
// onLearnMoreClick = callback::onLearnMoreAboutEncryption,
|
||||
// onFinish = callback::onDone,
|
||||
// onBack = callback::onBack,
|
||||
// )
|
||||
val state = presenter.present()
|
||||
OutgoingVerificationView(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
onLearnMoreClick = callback::onLearnMoreAboutEncryption,
|
||||
onFinish = callback::onDone,
|
||||
onBack = callback::onBack,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,150 +9,172 @@
|
|||
|
||||
package io.element.android.features.verifysession.impl.outgoing
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import com.freeletics.flowredux.compose.rememberStateAndDispatch
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationRequest
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationStateMachine.Event as StateMachineEvent
|
||||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationStateMachine.State as StateMachineState
|
||||
|
||||
// @Inject
|
||||
// class OutgoingVerificationPresenter(
|
||||
// @Assisted private val showDeviceVerifiedScreen: Boolean,
|
||||
// @Assisted private val verificationRequest: VerificationRequest.Outgoing,
|
||||
// private val sessionVerificationService: SessionVerificationService,
|
||||
// private val encryptionService: EncryptionService,
|
||||
// ) : Presenter<OutgoingVerificationState> {
|
||||
// @AssistedFactory
|
||||
// interface Factory {
|
||||
// fun create(
|
||||
// verificationRequest: VerificationRequest.Outgoing,
|
||||
// showDeviceVerifiedScreen: Boolean,
|
||||
// ): OutgoingVerificationPresenter
|
||||
// }
|
||||
//
|
||||
// private val stateMachine = OutgoingVerificationStateMachine(
|
||||
// sessionVerificationService = sessionVerificationService,
|
||||
// encryptionService = encryptionService,
|
||||
// )
|
||||
//
|
||||
// @Composable
|
||||
// override fun present(): OutgoingVerificationState {
|
||||
// val stateAndDispatch = stateMachine.rememberStateAndDispatch()
|
||||
//
|
||||
// val sessionVerifiedStatus by sessionVerificationService.sessionVerifiedStatus.collectAsState()
|
||||
// val step by remember {
|
||||
// derivedStateOf {
|
||||
// when (verificationRequest) {
|
||||
// is VerificationRequest.Outgoing.CurrentSession -> {
|
||||
// when (sessionVerifiedStatus) {
|
||||
// SessionVerifiedStatus.Unknown -> OutgoingVerificationState.Step.Loading
|
||||
// SessionVerifiedStatus.NotVerified -> {
|
||||
// stateAndDispatch.state.value.toVerificationStep()
|
||||
// }
|
||||
// SessionVerifiedStatus.Verified -> {
|
||||
// if (stateAndDispatch.state.value != StateMachineState.Initial || showDeviceVerifiedScreen) {
|
||||
// // The user has verified the session, we need to show the success screen
|
||||
// OutgoingVerificationState.Step.Completed
|
||||
// } else {
|
||||
// // Automatic verification, which can happen on freshly created account, in this case, skip the screen
|
||||
// OutgoingVerificationState.Step.Exit
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// is VerificationRequest.Outgoing.User -> stateAndDispatch.state.value.toVerificationStep()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Start this after observing state machine
|
||||
// LaunchedEffect(Unit) {
|
||||
// // Force reset, just in case the service was left in a broken state
|
||||
// sessionVerificationService.reset(cancelAnyPendingVerificationAttempt = true)
|
||||
//
|
||||
// observeVerificationService()
|
||||
// }
|
||||
//
|
||||
// fun handleEvents(event: OutgoingVerificationViewEvents) {
|
||||
// Timber.d("Verification user action: ${event::class.simpleName}")
|
||||
// when (event) {
|
||||
// // Just relay the event to the state machine
|
||||
// OutgoingVerificationViewEvents.RequestVerification -> StateMachineEvent.RequestVerification(verificationRequest)
|
||||
// OutgoingVerificationViewEvents.StartSasVerification -> StateMachineEvent.StartSasVerification
|
||||
// OutgoingVerificationViewEvents.ConfirmVerification -> StateMachineEvent.AcceptChallenge
|
||||
// OutgoingVerificationViewEvents.DeclineVerification -> StateMachineEvent.DeclineChallenge
|
||||
// OutgoingVerificationViewEvents.Cancel -> StateMachineEvent.Cancel
|
||||
// OutgoingVerificationViewEvents.Reset -> StateMachineEvent.Reset
|
||||
// }.let { stateMachineEvent ->
|
||||
// stateAndDispatch.dispatchAction(stateMachineEvent)
|
||||
// }
|
||||
// }
|
||||
// return OutgoingVerificationState(
|
||||
// step = step,
|
||||
// request = verificationRequest,
|
||||
// eventSink = ::handleEvents,
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// private fun StateMachineState?.toVerificationStep(): OutgoingVerificationState.Step =
|
||||
// when (val machineState = this) {
|
||||
// StateMachineState.Initial, null -> {
|
||||
// OutgoingVerificationState.Step.Initial
|
||||
// }
|
||||
// is StateMachineState.RequestingVerification,
|
||||
// is StateMachineState.StartingSasVerification,
|
||||
// StateMachineState.SasVerificationStarted -> {
|
||||
// OutgoingVerificationState.Step.AwaitingOtherDeviceResponse
|
||||
// }
|
||||
//
|
||||
// StateMachineState.VerificationRequestAccepted -> {
|
||||
// OutgoingVerificationState.Step.Ready
|
||||
// }
|
||||
//
|
||||
// is StateMachineState.Canceled -> {
|
||||
// OutgoingVerificationState.Step.Canceled
|
||||
// }
|
||||
//
|
||||
// is StateMachineState.Verifying -> {
|
||||
// val async = when (machineState) {
|
||||
// is StateMachineState.Verifying.Replying -> AsyncData.Loading()
|
||||
// else -> AsyncData.Uninitialized
|
||||
// }
|
||||
// OutgoingVerificationState.Step.Verifying(machineState.data, async)
|
||||
// }
|
||||
//
|
||||
// StateMachineState.Completed -> {
|
||||
// OutgoingVerificationState.Step.Completed
|
||||
// }
|
||||
//
|
||||
// StateMachineState.Exit -> {
|
||||
// OutgoingVerificationState.Step.Exit
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun CoroutineScope.observeVerificationService() {
|
||||
// sessionVerificationService.verificationFlowState
|
||||
// .onEach { Timber.d("Verification flow state: ${it::class.simpleName}") }
|
||||
// .onEach { verificationAttemptState ->
|
||||
// when (verificationAttemptState) {
|
||||
// VerificationFlowState.Initial -> stateMachine.dispatch(StateMachineEvent.Reset)
|
||||
// VerificationFlowState.DidAcceptVerificationRequest -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidAcceptVerificationRequest)
|
||||
// }
|
||||
// VerificationFlowState.DidStartSasVerification -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidStartSasVerification)
|
||||
// }
|
||||
// is VerificationFlowState.DidReceiveVerificationData -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidReceiveChallenge(verificationAttemptState.data))
|
||||
// }
|
||||
// VerificationFlowState.DidFinish -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidAcceptChallenge)
|
||||
// }
|
||||
// VerificationFlowState.DidCancel -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidCancel)
|
||||
// }
|
||||
// VerificationFlowState.DidFail -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidFail)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .launchIn(this)
|
||||
// }
|
||||
// }
|
||||
@Inject
|
||||
class OutgoingVerificationPresenter(
|
||||
@Assisted private val showDeviceVerifiedScreen: Boolean,
|
||||
@Assisted private val verificationRequest: VerificationRequest.Outgoing,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
private val encryptionService: EncryptionService,
|
||||
) : Presenter<OutgoingVerificationState> {
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(
|
||||
verificationRequest: VerificationRequest.Outgoing,
|
||||
showDeviceVerifiedScreen: Boolean,
|
||||
): OutgoingVerificationPresenter
|
||||
}
|
||||
|
||||
private val stateMachine = OutgoingVerificationStateMachine(
|
||||
sessionVerificationService = sessionVerificationService,
|
||||
encryptionService = encryptionService,
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun present(): OutgoingVerificationState {
|
||||
val stateAndDispatch = stateMachine.rememberStateAndDispatch()
|
||||
|
||||
val sessionVerifiedStatus by sessionVerificationService.sessionVerifiedStatus.collectAsState()
|
||||
val step by remember {
|
||||
derivedStateOf {
|
||||
when (verificationRequest) {
|
||||
is VerificationRequest.Outgoing.CurrentSession -> {
|
||||
when (sessionVerifiedStatus) {
|
||||
SessionVerifiedStatus.Unknown -> OutgoingVerificationState.Step.Loading
|
||||
SessionVerifiedStatus.NotVerified -> {
|
||||
stateAndDispatch.state.value.toVerificationStep()
|
||||
}
|
||||
SessionVerifiedStatus.Verified -> {
|
||||
if (stateAndDispatch.state.value != StateMachineState.Initial || showDeviceVerifiedScreen) {
|
||||
// The user has verified the session, we need to show the success screen
|
||||
OutgoingVerificationState.Step.Completed
|
||||
} else {
|
||||
// Automatic verification, which can happen on freshly created account, in this case, skip the screen
|
||||
OutgoingVerificationState.Step.Exit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is VerificationRequest.Outgoing.User -> stateAndDispatch.state.value.toVerificationStep()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start this after observing state machine
|
||||
LaunchedEffect(Unit) {
|
||||
// Force reset, just in case the service was left in a broken state
|
||||
sessionVerificationService.reset(cancelAnyPendingVerificationAttempt = true)
|
||||
|
||||
observeVerificationService()
|
||||
}
|
||||
|
||||
fun handleEvents(event: OutgoingVerificationViewEvents) {
|
||||
Timber.d("Verification user action: ${event::class.simpleName}")
|
||||
when (event) {
|
||||
// Just relay the event to the state machine
|
||||
OutgoingVerificationViewEvents.RequestVerification -> StateMachineEvent.RequestVerification(verificationRequest)
|
||||
OutgoingVerificationViewEvents.StartSasVerification -> StateMachineEvent.StartSasVerification
|
||||
OutgoingVerificationViewEvents.ConfirmVerification -> StateMachineEvent.AcceptChallenge
|
||||
OutgoingVerificationViewEvents.DeclineVerification -> StateMachineEvent.DeclineChallenge
|
||||
OutgoingVerificationViewEvents.Cancel -> StateMachineEvent.Cancel
|
||||
OutgoingVerificationViewEvents.Reset -> StateMachineEvent.Reset
|
||||
}.let { stateMachineEvent ->
|
||||
stateAndDispatch.dispatchAction(stateMachineEvent)
|
||||
}
|
||||
}
|
||||
return OutgoingVerificationState(
|
||||
step = step,
|
||||
request = verificationRequest,
|
||||
eventSink = ::handleEvents,
|
||||
)
|
||||
}
|
||||
|
||||
private fun StateMachineState?.toVerificationStep(): OutgoingVerificationState.Step =
|
||||
when (val machineState = this) {
|
||||
StateMachineState.Initial, null -> {
|
||||
OutgoingVerificationState.Step.Initial
|
||||
}
|
||||
is StateMachineState.RequestingVerification,
|
||||
is StateMachineState.StartingSasVerification,
|
||||
StateMachineState.SasVerificationStarted -> {
|
||||
OutgoingVerificationState.Step.AwaitingOtherDeviceResponse
|
||||
}
|
||||
|
||||
StateMachineState.VerificationRequestAccepted -> {
|
||||
OutgoingVerificationState.Step.Ready
|
||||
}
|
||||
|
||||
is StateMachineState.Canceled -> {
|
||||
OutgoingVerificationState.Step.Canceled
|
||||
}
|
||||
|
||||
is StateMachineState.Verifying -> {
|
||||
val async = when (machineState) {
|
||||
is StateMachineState.Verifying.Replying -> AsyncData.Loading()
|
||||
else -> AsyncData.Uninitialized
|
||||
}
|
||||
OutgoingVerificationState.Step.Verifying(machineState.data, async)
|
||||
}
|
||||
|
||||
StateMachineState.Completed -> {
|
||||
OutgoingVerificationState.Step.Completed
|
||||
}
|
||||
|
||||
StateMachineState.Exit -> {
|
||||
OutgoingVerificationState.Step.Exit
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.observeVerificationService() {
|
||||
sessionVerificationService.verificationFlowState
|
||||
.onEach { Timber.d("Verification flow state: ${it::class.simpleName}") }
|
||||
.onEach { verificationAttemptState ->
|
||||
when (verificationAttemptState) {
|
||||
VerificationFlowState.Initial -> stateMachine.dispatch(StateMachineEvent.Reset)
|
||||
VerificationFlowState.DidAcceptVerificationRequest -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidAcceptVerificationRequest)
|
||||
}
|
||||
VerificationFlowState.DidStartSasVerification -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidStartSasVerification)
|
||||
}
|
||||
is VerificationFlowState.DidReceiveVerificationData -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidReceiveChallenge(verificationAttemptState.data))
|
||||
}
|
||||
VerificationFlowState.DidFinish -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidAcceptChallenge)
|
||||
}
|
||||
VerificationFlowState.DidCancel -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidCancel)
|
||||
}
|
||||
VerificationFlowState.DidFail -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidFail)
|
||||
}
|
||||
}
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultTextFileViewer() : TextFileViewer {
|
||||
class DefaultTextFileViewer : TextFileViewer {
|
||||
@Composable
|
||||
override fun Render(
|
||||
lines: ImmutableList<String>,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import io.element.android.libraries.architecture.createNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultViewFolderEntryPoint() : ViewFolderEntryPoint {
|
||||
class DefaultViewFolderEntryPoint : ViewFolderEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): ViewFolderEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import javax.crypto.spec.GCMParameterSpec
|
|||
*/
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class AESEncryptionDecryptionService() : EncryptionDecryptionService {
|
||||
class AESEncryptionDecryptionService : EncryptionDecryptionService {
|
||||
override fun createEncryptionCipher(key: SecretKey): Cipher {
|
||||
return Cipher.getInstance(AESEncryptionSpecs.CIPHER_TRANSFORMATION).apply {
|
||||
init(Cipher.ENCRYPT_MODE, key)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ import io.element.android.libraries.matrix.api.core.SessionId
|
|||
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultDeepLinkCreator @Inject constructor() : DeepLinkCreator {
|
||||
@Inject
|
||||
class DefaultDeepLinkCreator : DeepLinkCreator {
|
||||
override fun create(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String {
|
||||
return buildString {
|
||||
append("$SCHEME://$HOST/")
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import io.element.android.libraries.matrix.api.core.ThreadId
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultDeeplinkParser: DeeplinkParser {
|
||||
class DefaultDeeplinkParser : DeeplinkParser {
|
||||
override fun getFromIntent(intent: Intent): DeeplinkData? {
|
||||
return intent
|
||||
.takeIf { it.action == Intent.ACTION_VIEW }
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
/*
|
||||
* Copyright 2022-2024 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.libraries.di
|
||||
|
||||
abstract class AppScope private constructor()
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import config.BuildTimeConfig
|
||||
import extension.buildConfigFieldStr
|
||||
import extension.setupDependencyInjection
|
||||
|
||||
/*
|
||||
* Copyright 2022-2024 New Vector Ltd.
|
||||
|
|
@ -14,6 +15,8 @@ plugins {
|
|||
alias(libs.plugins.kotlin.serialization)
|
||||
}
|
||||
|
||||
setupDependencyInjection()
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.libraries.matrix.api"
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ package io.element.android.libraries.matrix.api.mxc
|
|||
import dev.zacsweers.metro.Inject
|
||||
|
||||
@Inject
|
||||
class MxcTools() {
|
||||
class MxcTools {
|
||||
/**
|
||||
* Regex to match a Matrix Content (mxc://) URI.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ interface ClientBuilderProvider {
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class RustClientBuilderProvider() : ClientBuilderProvider {
|
||||
class RustClientBuilderProvider : ClientBuilderProvider {
|
||||
override fun provide(): ClientBuilder {
|
||||
return ClientBuilder()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import org.matrix.rustcomponents.sdk.sdkGitSha
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class RustSdkMetadata() : SdkMetadata {
|
||||
class RustSdkMetadata : SdkMetadata {
|
||||
override val sdkGitSha: String
|
||||
get() = sdkGitSha()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import org.matrix.rustcomponents.sdk.QrCodeData
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class RustQrCodeLoginDataFactory() : MatrixQrCodeLoginDataFactory {
|
||||
class RustQrCodeLoginDataFactory : MatrixQrCodeLoginDataFactory {
|
||||
override fun parseQrCodeData(data: ByteArray): Result<MatrixQrCodeLoginData> {
|
||||
return runCatchingExceptions { SdkQrCodeLoginData(QrCodeData.fromBytes(data)) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import java.security.KeyStoreException
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultUserCertificatesProvider() : UserCertificatesProvider {
|
||||
class DefaultUserCertificatesProvider : UserCertificatesProvider {
|
||||
/**
|
||||
* Get additional user-installed certificates from the `AndroidCAStore` `Keystore`.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ private const val SECRET_SIZE = 256
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultPassphraseGenerator() : PassphraseGenerator {
|
||||
class DefaultPassphraseGenerator : PassphraseGenerator {
|
||||
override fun generatePassphrase(): String? {
|
||||
val key = ByteArray(size = SECRET_SIZE)
|
||||
SecureRandom().nextBytes(key)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import io.element.android.libraries.matrix.api.permalink.MatrixToConverter
|
|||
*/
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultMatrixToConverter() : MatrixToConverter {
|
||||
class DefaultMatrixToConverter : MatrixToConverter {
|
||||
/**
|
||||
* Try to convert a URL from an element web instance or from a client permalink to a matrix.to url.
|
||||
* To be successfully converted, URL path should contain one of the [SUPPORTED_PATHS].
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import org.matrix.rustcomponents.sdk.matrixToUserPermalink
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultPermalinkBuilder() : PermalinkBuilder {
|
||||
class DefaultPermalinkBuilder : PermalinkBuilder {
|
||||
override fun permalinkForUser(userId: UserId): Result<String> {
|
||||
if (!MatrixPatterns.isUserId(userId.value)) {
|
||||
return Result.failure(PermalinkBuilderError.InvalidData)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import org.matrix.rustcomponents.sdk.initPlatform
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class RustInitPlatformService() : InitPlatformService {
|
||||
class RustInitPlatformService : InitPlatformService {
|
||||
override fun init(tracingConfiguration: TracingConfiguration) {
|
||||
initPlatform(
|
||||
config = tracingConfiguration.map(),
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ interface TimelineEventTypeFilterFactory {
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class RustTimelineEventTypeFilterFactory() : TimelineEventTypeFilterFactory {
|
||||
class RustTimelineEventTypeFilterFactory : TimelineEventTypeFilterFactory {
|
||||
override fun create(listStateEventType: List<StateEventType>): TimelineEventTypeFilter {
|
||||
return TimelineEventTypeFilter.exclude(
|
||||
listStateEventType.map { stateEventType ->
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultRoomAliasHelper() : RoomAliasHelper {
|
||||
class DefaultRoomAliasHelper : RoomAliasHelper {
|
||||
override fun roomAliasNameFromRoomDisplayName(name: String): String {
|
||||
return org.matrix.rustcomponents.sdk.roomAliasNameFromRoomDisplayName(name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import kotlinx.coroutines.flow.runningFold
|
|||
|
||||
@SingleIn(RoomScope::class)
|
||||
@Inject
|
||||
class RoomMemberProfilesCache() {
|
||||
class RoomMemberProfilesCache {
|
||||
private val cache = MutableStateFlow(mapOf<UserId, RoomMember>())
|
||||
val updateFlow = cache.drop(1).runningFold(0) { acc, _ -> acc + 1 }
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import kotlinx.coroutines.flow.runningFold
|
|||
|
||||
@SingleIn(RoomScope::class)
|
||||
@Inject
|
||||
class RoomNamesCache() {
|
||||
class RoomNamesCache {
|
||||
private val cache = MutableStateFlow(mapOf<RoomIdOrAlias, String?>())
|
||||
val updateFlow = cache.drop(1).runningFold(0) { acc, _ -> acc + 1 }
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import io.element.android.libraries.mediaviewer.impl.gallery.root.MediaGalleryRo
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultMediaGalleryEntryPoint() : MediaGalleryEntryPoint {
|
||||
class DefaultMediaGalleryEntryPoint : MediaGalleryEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): MediaGalleryEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import io.element.android.libraries.mediaviewer.impl.viewer.MediaViewerNode
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class DefaultMediaViewerEntryPoint() : MediaViewerEntryPoint {
|
||||
class DefaultMediaViewerEntryPoint : MediaViewerEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): MediaViewerEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
|||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@Inject
|
||||
class MediaItemsPostProcessor() {
|
||||
class MediaItemsPostProcessor {
|
||||
fun process(
|
||||
mediaItems: List<MediaItem>,
|
||||
): GroupedMediaItems {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import io.element.android.libraries.mediaviewer.api.util.FileExtensionExtractor
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class FileExtensionExtractorWithValidation() : FileExtensionExtractor {
|
||||
class FileExtensionExtractorWithValidation : FileExtensionExtractor {
|
||||
override fun extractFromName(name: String): String {
|
||||
val fileExtension = name.substringAfterLast('.', "")
|
||||
// Makes sure the extension is known by the system, otherwise default to binary extension.
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import io.element.android.libraries.mediaviewer.impl.model.eventId
|
|||
* (keyOffset = -1)
|
||||
*/
|
||||
@Inject
|
||||
class PagerKeysHandler() {
|
||||
class PagerKeysHandler {
|
||||
private data class Data(
|
||||
val mediaItems: List<MediaItem>,
|
||||
val keyOffset: Long,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
@ContributesBinding(AppScope::class)
|
||||
@SingleIn(AppScope::class)
|
||||
@Inject
|
||||
class DefaultOidcActionFlow() : OidcActionFlow {
|
||||
class DefaultOidcActionFlow : OidcActionFlow {
|
||||
private val mutableStateFlow = MutableStateFlow<OidcAction?>(null)
|
||||
|
||||
override fun post(oidcAction: OidcAction) {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ interface ComposablePermissionStateProvider {
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
@Inject
|
||||
class AccompanistPermissionStateProvider() : ComposablePermissionStateProvider {
|
||||
class AccompanistPermissionStateProvider : ComposablePermissionStateProvider {
|
||||
@Composable
|
||||
override fun provide(permission: String, onPermissionResult: (Boolean) -> Unit): PermissionState {
|
||||
return rememberPermissionState(
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import dev.zacsweers.metro.ContributesBinding
|
|||
import dev.zacsweers.metro.Inject
|
||||
import dev.zacsweers.metro.SingleIn
|
||||
import io.element.android.libraries.androidutils.preferences.DefaultPreferencesCorruptionHandlerFactory
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.libraries.di.annotations.ApplicationContext
|
||||
import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue