mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Merge pull request #8019 from vector-im/feature/bma/startSync
Start sync
This commit is contained in:
commit
f2ca2c6502
@ -10,6 +10,8 @@
|
|||||||
<!-- onboarding english only word play -->
|
<!-- onboarding english only word play -->
|
||||||
<string name="cut_the_slack_from_teams" translatable="false">Cut the slack from teams.</string>
|
<string name="cut_the_slack_from_teams" translatable="false">Cut the slack from teams.</string>
|
||||||
|
|
||||||
|
<string name="command_description_crash_application" translatable="false">Crash the application.</string>
|
||||||
|
|
||||||
<!-- WIP -->
|
<!-- WIP -->
|
||||||
<string name="location_map_view_copyright" translatable="false">© MapTiler © OpenStreetMap contributors</string>
|
<string name="location_map_view_copyright" translatable="false">© MapTiler © OpenStreetMap contributors</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -80,6 +80,9 @@ class FlowSession(private val session: Session) {
|
|||||||
|
|
||||||
fun liveSyncState(): Flow<SyncState> {
|
fun liveSyncState(): Flow<SyncState> {
|
||||||
return session.syncService().getSyncStateLive().asFlow()
|
return session.syncService().getSyncStateLive().asFlow()
|
||||||
|
.startWith(session.coroutineDispatchers.io) {
|
||||||
|
session.syncService().getSyncState()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun livePushers(): Flow<List<Pusher>> {
|
fun livePushers(): Flow<List<Pusher>> {
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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 im.vector.app.core.session
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.core.extensions.startSyncing
|
||||||
|
import org.matrix.android.sdk.api.session.sync.SyncState
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class EnsureSessionSyncingUseCase @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
|
) {
|
||||||
|
fun execute() {
|
||||||
|
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||||
|
if (session.syncService().getSyncState() == SyncState.Idle) {
|
||||||
|
Timber.w("EnsureSessionSyncingUseCase: start syncing")
|
||||||
|
session.startSyncing(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,7 @@ enum class Command(
|
|||||||
val isDevCommand: Boolean,
|
val isDevCommand: Boolean,
|
||||||
val isThreadCommand: Boolean
|
val isThreadCommand: Boolean
|
||||||
) {
|
) {
|
||||||
|
CRASH_APP("/crash", null, "", R.string.command_description_crash_application, true, true),
|
||||||
EMOTE("/me", null, "<message>", R.string.command_description_emote, false, true),
|
EMOTE("/me", null, "<message>", R.string.command_description_emote, false, true),
|
||||||
BAN_USER("/ban", null, "<user-id> [reason]", R.string.command_description_ban_user, false, false),
|
BAN_USER("/ban", null, "<user-id> [reason]", R.string.command_description_ban_user, false, false),
|
||||||
UNBAN_USER("/unban", null, "<user-id> [reason]", R.string.command_description_unban_user, false, false),
|
UNBAN_USER("/unban", null, "<user-id> [reason]", R.string.command_description_unban_user, false, false),
|
||||||
|
@ -20,13 +20,16 @@ import im.vector.app.core.extensions.isEmail
|
|||||||
import im.vector.app.core.extensions.isMsisdn
|
import im.vector.app.core.extensions.isMsisdn
|
||||||
import im.vector.app.core.extensions.orEmpty
|
import im.vector.app.core.extensions.orEmpty
|
||||||
import im.vector.app.features.home.room.detail.ChatEffect
|
import im.vector.app.features.home.room.detail.ChatEffect
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import org.matrix.android.sdk.api.MatrixPatterns
|
import org.matrix.android.sdk.api.MatrixPatterns
|
||||||
import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl
|
import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl
|
||||||
import org.matrix.android.sdk.api.session.identity.ThreePid
|
import org.matrix.android.sdk.api.session.identity.ThreePid
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CommandParser @Inject constructor() {
|
class CommandParser @Inject constructor(
|
||||||
|
private val vectorPreferences: VectorPreferences
|
||||||
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the text message into a Slash command.
|
* Convert the text message into a Slash command.
|
||||||
@ -404,6 +407,9 @@ class CommandParser @Inject constructor() {
|
|||||||
ParsedCommand.ErrorSyntax(Command.UPGRADE_ROOM)
|
ParsedCommand.ErrorSyntax(Command.UPGRADE_ROOM)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Command.CRASH_APP.matches(slashCommand) && vectorPreferences.developerMode() -> {
|
||||||
|
throw RuntimeException("Application crashed from user demand")
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// Unknown command
|
// Unknown command
|
||||||
ParsedCommand.ErrorUnknownSlashCommand(slashCommand)
|
ParsedCommand.ErrorUnknownSlashCommand(slashCommand)
|
||||||
|
@ -30,6 +30,7 @@ import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
|||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
|
import im.vector.app.core.session.EnsureSessionSyncingUseCase
|
||||||
import im.vector.app.features.analytics.AnalyticsConfig
|
import im.vector.app.features.analytics.AnalyticsConfig
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.extensions.toAnalyticsType
|
import im.vector.app.features.analytics.extensions.toAnalyticsType
|
||||||
@ -95,6 +96,7 @@ class HomeActivityViewModel @AssistedInject constructor(
|
|||||||
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
||||||
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
|
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
|
||||||
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
||||||
|
private val ensureSessionSyncingUseCase: EnsureSessionSyncingUseCase,
|
||||||
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
@ -118,6 +120,8 @@ class HomeActivityViewModel @AssistedInject constructor(
|
|||||||
private fun initialize() {
|
private fun initialize() {
|
||||||
if (isInitialized) return
|
if (isInitialized) return
|
||||||
isInitialized = true
|
isInitialized = true
|
||||||
|
// Ensure Session is syncing
|
||||||
|
ensureSessionSyncingUseCase.execute()
|
||||||
registerUnifiedPushIfNeeded()
|
registerUnifiedPushIfNeeded()
|
||||||
cleanupFiles()
|
cleanupFiles()
|
||||||
observeInitialSync()
|
observeInitialSync()
|
||||||
|
@ -38,8 +38,8 @@ data class HomeDetailViewState(
|
|||||||
val notificationCountRooms: Int = 0,
|
val notificationCountRooms: Int = 0,
|
||||||
val notificationHighlightRooms: Boolean = false,
|
val notificationHighlightRooms: Boolean = false,
|
||||||
val hasUnreadMessages: Boolean = false,
|
val hasUnreadMessages: Boolean = false,
|
||||||
val syncState: SyncState = SyncState.Idle,
|
val syncState: SyncState? = null,
|
||||||
val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState = SyncRequestState.IncrementalSyncIdle,
|
val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState? = null,
|
||||||
val pushCounter: Int = 0,
|
val pushCounter: Int = 0,
|
||||||
val pstnSupportFlag: Boolean = false,
|
val pstnSupportFlag: Boolean = false,
|
||||||
val forceDialPadTab: Boolean = false
|
val forceDialPadTab: Boolean = false
|
||||||
|
@ -60,8 +60,8 @@ data class RoomDetailViewState(
|
|||||||
val formattedTypingUsers: String? = null,
|
val formattedTypingUsers: String? = null,
|
||||||
val tombstoneEvent: Event? = null,
|
val tombstoneEvent: Event? = null,
|
||||||
val joinUpgradedRoomAsync: Async<String> = Uninitialized,
|
val joinUpgradedRoomAsync: Async<String> = Uninitialized,
|
||||||
val syncState: SyncState = SyncState.Idle,
|
val syncState: SyncState? = null,
|
||||||
val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState = SyncRequestState.IncrementalSyncIdle,
|
val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState? = null,
|
||||||
val pushCounter: Int = 0,
|
val pushCounter: Int = 0,
|
||||||
val highlightedEventId: String? = null,
|
val highlightedEventId: String? = null,
|
||||||
val unreadState: UnreadState = UnreadState.Unknown,
|
val unreadState: UnreadState = UnreadState.Unknown,
|
||||||
|
@ -40,8 +40,8 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
|
|||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun render(
|
fun render(
|
||||||
newState: SyncState,
|
newState: SyncState?,
|
||||||
incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState,
|
incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState?,
|
||||||
pushCounter: Int,
|
pushCounter: Int,
|
||||||
showDebugInfo: Boolean
|
showDebugInfo: Boolean
|
||||||
) {
|
) {
|
||||||
@ -64,8 +64,9 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SyncState.toHumanReadable(): String {
|
private fun SyncState?.toHumanReadable(): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
null -> "Unknown"
|
||||||
SyncState.Idle -> "Idle"
|
SyncState.Idle -> "Idle"
|
||||||
SyncState.InvalidToken -> "InvalidToken"
|
SyncState.InvalidToken -> "InvalidToken"
|
||||||
SyncState.Killed -> "Killed"
|
SyncState.Killed -> "Killed"
|
||||||
@ -76,8 +77,9 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SyncRequestState.IncrementalSyncRequestState.toHumanReadable(): String {
|
private fun SyncRequestState.IncrementalSyncRequestState?.toHumanReadable(): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
null -> "Unknown"
|
||||||
SyncRequestState.IncrementalSyncIdle -> "Idle"
|
SyncRequestState.IncrementalSyncIdle -> "Idle"
|
||||||
is SyncRequestState.IncrementalSyncParsing -> "Parsing ${this.rooms} room(s) ${this.toDevice} toDevice(s)"
|
is SyncRequestState.IncrementalSyncParsing -> "Parsing ${this.rooms} room(s) ${this.toDevice} toDevice(s)"
|
||||||
SyncRequestState.IncrementalSyncError -> "Error"
|
SyncRequestState.IncrementalSyncError -> "Error"
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
android:visibility="gone" />
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/roomToolbar"
|
android:id="@+id/roomToolbar"
|
||||||
@ -38,9 +39,9 @@
|
|||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/rootConstraintLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:id="@+id/rootConstraintLayout">
|
|
||||||
|
|
||||||
<im.vector.app.features.sync.widget.SyncStateView
|
<im.vector.app.features.sync.widget.SyncStateView
|
||||||
android:id="@+id/syncStateView"
|
android:id="@+id/syncStateView"
|
||||||
@ -75,7 +76,7 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:overScrollMode="always"
|
android:overScrollMode="always"
|
||||||
app:layout_constraintBottom_toTopOf="@id/notificationAreaView"
|
app:layout_constraintBottom_toTopOf="@id/failedMessagesWarningStub"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/removeJitsiWidgetView"
|
app:layout_constraintTop_toBottomOf="@id/removeJitsiWidgetView"
|
||||||
@ -95,7 +96,19 @@
|
|||||||
app:closeIcon="@drawable/ic_close_24dp"
|
app:closeIcon="@drawable/ic_close_24dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/removeJitsiWidgetView" />
|
app:layout_constraintTop_toBottomOf="@id/removeJitsiWidgetView"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<ViewStub
|
||||||
|
android:id="@+id/failedMessagesWarningStub"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inflatedId="@+id/failedMessagesWarningStub"
|
||||||
|
android:layout="@layout/view_stub_failed_message_warning_layout"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/notificationAreaView"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:layout_height="300dp" />
|
||||||
|
|
||||||
<im.vector.app.core.ui.views.NotificationAreaView
|
<im.vector.app.core.ui.views.NotificationAreaView
|
||||||
android:id="@+id/notificationAreaView"
|
android:id="@+id/notificationAreaView"
|
||||||
@ -107,17 +120,6 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<ViewStub
|
|
||||||
android:id="@+id/failedMessagesWarningStub"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inflatedId="@+id/failedMessagesWarningStub"
|
|
||||||
android:layout="@layout/view_stub_failed_message_warning_layout"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
tools:layout_height="300dp" />
|
|
||||||
|
|
||||||
<ViewStub
|
<ViewStub
|
||||||
android:id="@+id/inviteViewStub"
|
android:id="@+id/inviteViewStub"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@ -208,8 +210,8 @@
|
|||||||
android:id="@+id/composerContainer"
|
android:id="@+id/composerContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:translationZ="10dp"
|
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
|
android:translationZ="10dp"
|
||||||
app:layout_behavior="im.vector.app.core.utils.ExpandingBottomSheetBehavior" />
|
app:layout_behavior="im.vector.app.core.utils.ExpandingBottomSheetBehavior" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
@ -217,7 +219,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:visibility="visible"
|
android:translationZ="10dp"
|
||||||
android:translationZ="10dp" />
|
android:visibility="visible" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
@ -16,12 +16,15 @@
|
|||||||
|
|
||||||
package im.vector.app.features.command
|
package im.vector.app.features.command
|
||||||
|
|
||||||
|
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||||
import org.amshove.kluent.shouldBeEqualTo
|
import org.amshove.kluent.shouldBeEqualTo
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
private const val A_SPACE_ID = "!my-space-id"
|
private const val A_SPACE_ID = "!my-space-id"
|
||||||
|
|
||||||
class CommandParserTest {
|
class CommandParserTest {
|
||||||
|
private val fakeVectorPreferences = FakeVectorPreferences()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun parseSlashCommandEmpty() {
|
fun parseSlashCommandEmpty() {
|
||||||
test("/", ParsedCommand.ErrorEmptySlashCommand)
|
test("/", ParsedCommand.ErrorEmptySlashCommand)
|
||||||
@ -70,7 +73,7 @@ class CommandParserTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun test(message: String, expectedResult: ParsedCommand) {
|
private fun test(message: String, expectedResult: ParsedCommand) {
|
||||||
val commandParser = CommandParser()
|
val commandParser = CommandParser(fakeVectorPreferences.instance)
|
||||||
val result = commandParser.parseSlashCommand(message, null, false)
|
val result = commandParser.parseSlashCommand(message, null, false)
|
||||||
result shouldBeEqualTo expectedResult
|
result shouldBeEqualTo expectedResult
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user