Merge pull request #107 from vector-im/feature/cache

Clear cache and rework Signout
This commit is contained in:
Benoit Marty 2019-04-17 16:26:48 +02:00 committed by GitHub
commit 0818c55b6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 289 additions and 44 deletions

View File

@ -19,7 +19,7 @@ package im.vector.matrix.android.api.failure
import java.io.IOException import java.io.IOException
/** /**
* This class allows to expose differents kind of error to be then handled by the application. * This class allows to expose different kinds of error to be then handled by the application.
* As it is a sealed class, you typically use it like that : * As it is a sealed class, you typically use it like that :
* when(failure) { * when(failure) {
* is NetworkConnection -> Unit * is NetworkConnection -> Unit

View File

@ -33,6 +33,7 @@ data class MatrixError(
const val FORBIDDEN = "M_FORBIDDEN" const val FORBIDDEN = "M_FORBIDDEN"
const val UNKNOWN = "M_UNKNOWN" const val UNKNOWN = "M_UNKNOWN"
const val UNKNOWN_TOKEN = "M_UNKNOWN_TOKEN" const val UNKNOWN_TOKEN = "M_UNKNOWN_TOKEN"
const val MISSING_TOKEN = "M_MISSING_TOKEN"
const val BAD_JSON = "M_BAD_JSON" const val BAD_JSON = "M_BAD_JSON"
const val NOT_JSON = "M_NOT_JSON" const val NOT_JSON = "M_NOT_JSON"
const val NOT_FOUND = "M_NOT_FOUND" const val NOT_FOUND = "M_NOT_FOUND"

View File

@ -18,6 +18,7 @@ package im.vector.matrix.android.api.session
import androidx.annotation.MainThread import androidx.annotation.MainThread
import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
import im.vector.matrix.android.api.session.content.ContentUrlResolver import im.vector.matrix.android.api.session.content.ContentUrlResolver
import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.crypto.CryptoService
@ -36,6 +37,7 @@ interface Session :
GroupService, GroupService,
UserService, UserService,
CryptoService, CryptoService,
CacheService,
SignOutService, SignOutService,
FilterService { FilterService {
@ -93,7 +95,11 @@ interface Session :
/** /**
* A global session listener to get notified for some events. * A global session listener to get notified for some events.
*/ */
// Not used at the moment interface Listener {
interface Listener /**
* The access token is not valid anymore
*/
fun onInvalidToken()
}
} }

View File

@ -0,0 +1,31 @@
/*
* Copyright 2019 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.matrix.android.api.session.cache
import im.vector.matrix.android.api.MatrixCallback
/**
* This interface defines a method to sign out. It's implemented at the session level.
*/
interface CacheService {
/**
* Clear the whole cached data, except credentials. Once done, the session is closed and has to be opened again
*/
fun clearCache(callback: MatrixCallback<Unit>)
}

View File

@ -28,7 +28,7 @@ data class RoomSummary(
val displayName: String = "", val displayName: String = "",
val topic: String = "", val topic: String = "",
val avatarUrl: String = "", val avatarUrl: String = "",
val isDirect: Boolean, val isDirect: Boolean = false,
val lastMessage: Event? = null, val lastMessage: Event? = null,
val otherMemberIds: List<String> = emptyList(), val otherMemberIds: List<String> = emptyList(),
var notificationCount: Int = 0, var notificationCount: Int = 0,

View File

@ -0,0 +1,33 @@
/*
* Copyright 2019 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.matrix.android.api.util
import im.vector.matrix.android.api.MatrixCallback
/**
* Simple MatrixCallback implementation which delegate its calls to another callback
*/
open class MatrixCallbackDelegate<T>(private val callback: MatrixCallback<T>) : MatrixCallback<T> {
override fun onSuccess(data: T) {
callback.onSuccess(data)
}
override fun onFailure(failure: Throwable) {
callback.onFailure(failure)
}
}

View File

@ -23,6 +23,7 @@ import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
import im.vector.matrix.android.api.session.content.ContentUrlResolver import im.vector.matrix.android.api.session.content.ContentUrlResolver
import im.vector.matrix.android.api.session.group.Group import im.vector.matrix.android.api.session.group.Group
@ -36,6 +37,7 @@ import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.api.session.user.model.User import im.vector.matrix.android.api.session.user.model.User
import im.vector.matrix.android.api.util.MatrixCallbackDelegate
import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.di.MatrixKoinComponent import im.vector.matrix.android.internal.di.MatrixKoinComponent
import im.vector.matrix.android.internal.di.MatrixKoinHolder import im.vector.matrix.android.internal.di.MatrixKoinHolder
@ -65,6 +67,7 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
private val groupService by inject<GroupService>() private val groupService by inject<GroupService>()
private val userService by inject<UserService>() private val userService by inject<UserService>()
private val filterService by inject<FilterService>() private val filterService by inject<FilterService>()
private val cacheService by inject<CacheService>()
private val signOutService by inject<SignOutService>() private val signOutService by inject<SignOutService>()
private val syncThread by inject<SyncThread>() private val syncThread by inject<SyncThread>()
private val contentUrlResolver by inject<ContentUrlResolver>() private val contentUrlResolver by inject<ContentUrlResolver>()
@ -118,17 +121,18 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
@MainThread @MainThread
override fun signOut(callback: MatrixCallback<Unit>) { override fun signOut(callback: MatrixCallback<Unit>) {
assert(isOpen) assert(isOpen)
syncThread.kill()
return signOutService.signOut(object : MatrixCallback<Unit> { return signOutService.signOut(object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) { override fun onSuccess(data: Unit) {
// Close the session // Clear the cache
stopSync() cacheService.clearCache(object : MatrixCallbackDelegate<Unit>(callback) {})
close()
callback.onSuccess(data)
} }
override fun onFailure(failure: Throwable) { override fun onFailure(failure: Throwable) {
callback.onFailure(failure) // Ignore failure
onSuccess(Unit)
// callback.onFailure(failure)
} }
}) })
} }
@ -184,6 +188,19 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
return filterService.setFilter(filterPreset) return filterService.setFilter(filterPreset)
} }
override fun clearCache(callback: MatrixCallback<Unit>) {
assert(isOpen)
syncThread.pause()
cacheService.clearCache(object : MatrixCallbackDelegate<Unit>(callback) {
override fun onSuccess(data: Unit) {
// Restart the sync
syncThread.restart()
super.onSuccess(data)
}
})
}
// USER SERVICE // USER SERVICE
override fun getUser(userId: String): User? { override fun getUser(userId: String): User? {

View File

@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session
import android.content.Context import android.content.Context
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.api.session.group.GroupService import im.vector.matrix.android.api.session.group.GroupService
import im.vector.matrix.android.api.session.room.RoomService import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.api.session.signout.SignOutService import im.vector.matrix.android.api.session.signout.SignOutService
@ -26,6 +27,9 @@ import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.database.model.SessionRealmModule import im.vector.matrix.android.internal.database.model.SessionRealmModule
import im.vector.matrix.android.internal.session.cache.ClearCacheTask
import im.vector.matrix.android.internal.session.cache.RealmCacheService
import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask
import im.vector.matrix.android.internal.session.filter.* import im.vector.matrix.android.internal.session.filter.*
import im.vector.matrix.android.internal.session.group.DefaultGroupService import im.vector.matrix.android.internal.session.group.DefaultGroupService
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
@ -110,6 +114,14 @@ internal class SessionModule(private val sessionParams: SessionParams) {
DefaultSignOutService(get(), get()) as SignOutService DefaultSignOutService(get(), get()) as SignOutService
} }
scope(DefaultSession.SCOPE) {
RealmCacheService(get(), get()) as CacheService
}
scope(DefaultSession.SCOPE) {
RealmClearCacheTask(get()) as ClearCacheTask
}
scope(DefaultSession.SCOPE) { scope(DefaultSession.SCOPE) {
DefaultUserService(get()) as UserService DefaultUserService(get()) as UserService
} }

View File

@ -0,0 +1,33 @@
/*
* Copyright 2019 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.matrix.android.internal.session.cache
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
internal class RealmCacheService(private val clearCacheTask: ClearCacheTask,
private val taskExecutor: TaskExecutor) : CacheService {
override fun clearCache(callback: MatrixCallback<Unit>) {
clearCacheTask
.configureWith(Unit)
.dispatchTo(callback)
.executeBy(taskExecutor)
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2019 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.matrix.android.internal.session.cache
import arrow.core.Try
import im.vector.matrix.android.internal.task.Task
import io.realm.Realm
import io.realm.RealmConfiguration
internal interface ClearCacheTask : Task<Unit, Unit>
internal class RealmClearCacheTask(val realmConfiguration: RealmConfiguration) : ClearCacheTask {
override fun execute(params: Unit): Try<Unit> {
return Try {
val realm = Realm.getInstance(realmConfiguration)
realm.executeTransaction {
it.deleteAll()
}
realm.close()
}
}
}

View File

@ -52,7 +52,14 @@ internal class DefaultRoom(
RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME)
} }
Transformations.map(liveRealmData) { results -> Transformations.map(liveRealmData) { results ->
results.map { it.asDomain() }.first() val roomSummaries = results.map { it.asDomain() }
if (roomSummaries.isEmpty()) {
// Create a dummy RoomSummary to avoid Crash during Sign Out or clear cache
RoomSummary(roomId)
} else {
roomSummaries.first()
}
} }
} }

View File

@ -31,7 +31,6 @@ internal class DefaultSignOutTask(private val signOutAPI: SignOutAPI,
return executeRequest<Unit> { return executeRequest<Unit> {
apiCall = signOutAPI.signOut() apiCall = signOutAPI.signOut()
}.flatMap { }.flatMap {
// TODO Clear DB, media cache, etc.
sessionParamsStore.delete() sessionParamsStore.delete()
} }
} }

View File

@ -56,7 +56,7 @@ internal class SyncModule {
} }
scope(DefaultSession.SCOPE) { scope(DefaultSession.SCOPE) {
DefaultSyncTask(get(), get(), get()) as SyncTask DefaultSyncTask(get(), get(), get(), get()) as SyncTask
} }
scope(DefaultSession.SCOPE) { scope(DefaultSession.SCOPE) {

View File

@ -17,6 +17,11 @@
package im.vector.matrix.android.internal.session.sync package im.vector.matrix.android.internal.session.sync
import arrow.core.Try import arrow.core.Try
import arrow.core.failure
import arrow.core.recoverWith
import im.vector.matrix.android.api.failure.Failure
import im.vector.matrix.android.api.failure.MatrixError
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.filter.FilterRepository import im.vector.matrix.android.internal.session.filter.FilterRepository
import im.vector.matrix.android.internal.session.sync.model.SyncResponse import im.vector.matrix.android.internal.session.sync.model.SyncResponse
@ -30,7 +35,8 @@ internal interface SyncTask : Task<SyncTask.Params, SyncResponse> {
internal class DefaultSyncTask(private val syncAPI: SyncAPI, internal class DefaultSyncTask(private val syncAPI: SyncAPI,
private val filterRepository: FilterRepository, private val filterRepository: FilterRepository,
private val syncResponseHandler: SyncResponseHandler private val syncResponseHandler: SyncResponseHandler,
private val sessionParamsStore: SessionParamsStore
) : SyncTask { ) : SyncTask {
@ -46,6 +52,15 @@ internal class DefaultSyncTask(private val syncAPI: SyncAPI,
return executeRequest<SyncResponse> { return executeRequest<SyncResponse> {
apiCall = syncAPI.sync(requestParams) apiCall = syncAPI.sync(requestParams)
}.recoverWith { throwable ->
// Intercept 401
if (throwable is Failure.ServerError
&& throwable.error.code == MatrixError.UNKNOWN_TOKEN) {
sessionParamsStore.delete()
}
// Transmit the throwable
throwable.failure()
}.flatMap { syncResponse -> }.flatMap { syncResponse ->
syncResponseHandler.handleResponse(syncResponse, params.token, false) syncResponseHandler.handleResponse(syncResponse, params.token, false)
} }

View File

@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.sync.job
import com.squareup.moshi.JsonEncodingException import com.squareup.moshi.JsonEncodingException
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.failure.Failure
import im.vector.matrix.android.api.failure.MatrixError
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
import im.vector.matrix.android.internal.session.sync.SyncTask import im.vector.matrix.android.internal.session.sync.SyncTask
@ -59,7 +60,11 @@ internal class SyncThread(private val syncTask: SyncTask,
if (state != State.PAUSED) { if (state != State.PAUSED) {
return@synchronized return@synchronized
} }
Timber.v("Unpause sync...") Timber.v("Resume sync...")
// Retrieve the last token, it may have been deleted in case of a clear cache
nextBatch = syncTokenStore.getLastToken()
state = State.RUNNING state = State.RUNNING
lock.notify() lock.notify()
} }
@ -97,7 +102,7 @@ internal class SyncThread(private val syncTask: SyncTask,
lock.wait() lock.wait()
} }
} else { } else {
Timber.v("Execute sync request...") Timber.v("Execute sync request with token $nextBatch")
val latch = CountDownLatch(1) val latch = CountDownLatch(1)
val params = SyncTask.Params(nextBatch) val params = SyncTask.Params(nextBatch)
cancelableTask = syncTask.configureWith(params) cancelableTask = syncTask.configureWith(params)
@ -124,6 +129,13 @@ internal class SyncThread(private val syncTask: SyncTask,
// Wait 10s before retrying // Wait 10s before retrying
sleep(RETRY_WAIT_TIME_MS) sleep(RETRY_WAIT_TIME_MS)
} }
if (failure is Failure.ServerError
&& (failure.error.code == MatrixError.UNKNOWN_TOKEN || failure.error.code == MatrixError.MISSING_TOKEN)) {
// No token or invalid token, stop the thread
state = State.KILLING
}
latch.countDown() latch.countDown()
} }

View File

@ -16,8 +16,11 @@
package im.vector.riotredesign.features package im.vector.riotredesign.features
import android.app.Activity
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.api.MatrixCallback
import im.vector.riotredesign.core.platform.VectorBaseActivity import im.vector.riotredesign.core.platform.VectorBaseActivity
import im.vector.riotredesign.features.home.HomeActivity import im.vector.riotredesign.features.home.HomeActivity
import im.vector.riotredesign.features.login.LoginActivity import im.vector.riotredesign.features.login.LoginActivity
@ -25,10 +28,52 @@ import im.vector.riotredesign.features.login.LoginActivity
class MainActivity : VectorBaseActivity() { class MainActivity : VectorBaseActivity() {
companion object {
private const val EXTRA_CLEAR_CACHE = "EXTRA_CLEAR_CACHE"
private const val EXTRA_CLEAR_CREDENTIALS = "EXTRA_CLEAR_CREDENTIALS"
// Special action to clear cache and/or clear credentials
fun restartApp(activity: Activity, clearCache: Boolean = false, clearCredentials: Boolean = false) {
val intent = Intent(activity, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.putExtra(EXTRA_CLEAR_CACHE, clearCache)
intent.putExtra(EXTRA_CLEAR_CREDENTIALS, clearCredentials)
activity.startActivity(intent)
}
}
private val authenticator = Matrix.getInstance().authenticator() private val authenticator = Matrix.getInstance().authenticator()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val session = Matrix.getInstance().currentSession
val clearCache = intent.getBooleanExtra(EXTRA_CLEAR_CACHE, false)
val clearCredentials = intent.getBooleanExtra(EXTRA_CLEAR_CREDENTIALS, false)
if (session == null) {
start()
} else {
// Handle some wanted cleanup
when {
clearCredentials -> session.signOut(object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
start()
}
})
clearCache -> session.clearCache(object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
start()
}
})
else -> start()
}
}
}
private fun start() {
val intent = if (authenticator.hasActiveSessions()) { val intent = if (authenticator.hasActiveSessions()) {
HomeActivity.newIntent(this) HomeActivity.newIntent(this)
} else { } else {
@ -37,5 +82,4 @@ class MainActivity : VectorBaseActivity() {
startActivity(intent) startActivity(intent)
finish() finish()
} }
} }

View File

@ -38,7 +38,7 @@ class EmptyState : MvRxState
class HomeActivityViewModel(state: EmptyState, class HomeActivityViewModel(state: EmptyState,
private val session: Session, private val session: Session,
roomSelectionRepository: RoomSelectionRepository roomSelectionRepository: RoomSelectionRepository
) : VectorViewModel<EmptyState>(state) { ) : VectorViewModel<EmptyState>(state), Session.Listener {
companion object : MvRxViewModelFactory<HomeActivityViewModel, EmptyState> { companion object : MvRxViewModelFactory<HomeActivityViewModel, EmptyState> {
@ -59,6 +59,8 @@ class HomeActivityViewModel(state: EmptyState,
get() = _openRoomLiveData get() = _openRoomLiveData
init { init {
session.addListener(this)
// TODO Move this else where, it's too late when we are here to change the filter // TODO Move this else where, it's too late when we are here to change the filter
session.setFilter(FilterService.FilterPreset.RiotFilter) session.setFilter(FilterService.FilterPreset.RiotFilter)
@ -100,5 +102,18 @@ class HomeActivityViewModel(state: EmptyState,
}) })
} }
override fun onCleared() {
super.onCleared()
session.removeListener(this)
}
/* ==========================================================================================
* Session listener
* ========================================================================================== */
override fun onInvalidToken() {
}
} }

View File

@ -53,6 +53,7 @@ import im.vector.riotredesign.core.preference.ProgressBarPreference
import im.vector.riotredesign.core.preference.UserAvatarPreference import im.vector.riotredesign.core.preference.UserAvatarPreference
import im.vector.riotredesign.core.preference.VectorPreference import im.vector.riotredesign.core.preference.VectorPreference
import im.vector.riotredesign.core.utils.* import im.vector.riotredesign.core.utils.*
import im.vector.riotredesign.features.MainActivity
import im.vector.riotredesign.features.themes.ThemeUtils import im.vector.riotredesign.features.themes.ThemeUtils
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -751,9 +752,8 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
*/ */
it.onPreferenceClickListener = Preference.OnPreferenceClickListener { it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
notImplemented() displayLoadingView()
// displayLoadingView() MainActivity.restartApp(activity!!, clearCache = true, clearCredentials = false)
// TODO Matrix.getInstance(appContext).reloadSessions(appContext)
false false
} }
} }

View File

@ -16,9 +16,7 @@
package im.vector.riotredesign.features.workers.signout package im.vector.riotredesign.features.workers.signout
import android.content.Intent
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.riotredesign.R import im.vector.riotredesign.R
import im.vector.riotredesign.core.platform.VectorBaseActivity import im.vector.riotredesign.core.platform.VectorBaseActivity
@ -30,7 +28,7 @@ class SignOutUiWorker(val activity: VectorBaseActivity) {
if (SignOutViewModel.doYouNeedToBeDisplayed(session)) { if (SignOutViewModel.doYouNeedToBeDisplayed(session)) {
val signOutDialog = SignOutBottomSheetDialogFragment.newInstance(session.sessionParams.credentials.userId) val signOutDialog = SignOutBottomSheetDialogFragment.newInstance(session.sessionParams.credentials.userId)
signOutDialog.onSignOut = Runnable { signOutDialog.onSignOut = Runnable {
doSignOut(session) doSignOut()
} }
signOutDialog.show(activity.supportFragmentManager, "SO") signOutDialog.show(activity.supportFragmentManager, "SO")
} else { } else {
@ -39,31 +37,14 @@ class SignOutUiWorker(val activity: VectorBaseActivity) {
.setTitle(R.string.action_sign_out) .setTitle(R.string.action_sign_out)
.setMessage(R.string.action_sign_out_confirmation_simple) .setMessage(R.string.action_sign_out_confirmation_simple)
.setPositiveButton(R.string.action_sign_out) { _, _ -> .setPositiveButton(R.string.action_sign_out) { _, _ ->
doSignOut(session) doSignOut()
} }
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.show() .show()
} }
} }
private fun doSignOut(session: Session) { private fun doSignOut() {
// TODO showWaitingView() MainActivity.restartApp(activity, clearCache = true, clearCredentials = true)
session.signOut(object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
// Start MainActivity in a new task
val intent = Intent(activity, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
activity.startActivity(intent)
}
override fun onFailure(failure: Throwable) {
// TODO Notify user, or ignore?
}
})
} }
} }