Merge pull request #6677 from vector-im/feature/bma/fix_room_shortcut
Shortcuts must first start MainActivity to ensure the session is restored.
This commit is contained in:
commit
24e78fef74
@ -86,6 +86,8 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
|
|||||||
private const val EXTRA_ARGS = "EXTRA_ARGS"
|
private const val EXTRA_ARGS = "EXTRA_ARGS"
|
||||||
private const val EXTRA_NEXT_INTENT = "EXTRA_NEXT_INTENT"
|
private const val EXTRA_NEXT_INTENT = "EXTRA_NEXT_INTENT"
|
||||||
private const val EXTRA_INIT_SESSION = "EXTRA_INIT_SESSION"
|
private const val EXTRA_INIT_SESSION = "EXTRA_INIT_SESSION"
|
||||||
|
private const val EXTRA_ROOM_ID = "EXTRA_ROOM_ID"
|
||||||
|
private const val ACTION_ROOM_DETAILS_FROM_SHORTCUT = "ROOM_DETAILS_FROM_SHORTCUT"
|
||||||
|
|
||||||
// Special action to clear cache and/or clear credentials
|
// Special action to clear cache and/or clear credentials
|
||||||
fun restartApp(activity: Activity, args: MainActivityArgs) {
|
fun restartApp(activity: Activity, args: MainActivityArgs) {
|
||||||
@ -107,6 +109,14 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
|
|||||||
intent.putExtra(EXTRA_NEXT_INTENT, nextIntent)
|
intent.putExtra(EXTRA_NEXT_INTENT, nextIntent)
|
||||||
return intent
|
return intent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shortcuts can't have intents with parcelables
|
||||||
|
fun shortcutIntent(context: Context, roomId: String): Intent {
|
||||||
|
return Intent(context, MainActivity::class.java).apply {
|
||||||
|
action = ACTION_ROOM_DETAILS_FROM_SHORTCUT
|
||||||
|
putExtra(EXTRA_ROOM_ID, roomId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val startAppViewModel: StartAppViewModel by viewModel()
|
private val startAppViewModel: StartAppViewModel by viewModel()
|
||||||
@ -131,6 +141,8 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
shortcutsHandler.updateShortcutsWithPreviousIntent()
|
||||||
|
|
||||||
startAppViewModel.onEach {
|
startAppViewModel.onEach {
|
||||||
renderState(it)
|
renderState(it)
|
||||||
}
|
}
|
||||||
@ -171,6 +183,13 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
|
|||||||
} else if (intent.hasExtra(EXTRA_INIT_SESSION)) {
|
} else if (intent.hasExtra(EXTRA_INIT_SESSION)) {
|
||||||
setResult(RESULT_OK)
|
setResult(RESULT_OK)
|
||||||
finish()
|
finish()
|
||||||
|
} else if (intent.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) {
|
||||||
|
val roomId = intent.getStringExtra(EXTRA_ROOM_ID)
|
||||||
|
if (roomId?.isNotEmpty() == true) {
|
||||||
|
// TODO Add a trigger Shortcut to the analytics.
|
||||||
|
navigator.openRoom(this, roomId)
|
||||||
|
}
|
||||||
|
finish()
|
||||||
} else {
|
} else {
|
||||||
args = parseArgs()
|
args = parseArgs()
|
||||||
if (args.clearCredentials || args.isUserLoggedOut || args.clearCache) {
|
if (args.clearCredentials || args.isUserLoggedOut || args.clearCache) {
|
||||||
|
@ -27,7 +27,7 @@ import androidx.core.graphics.drawable.IconCompat
|
|||||||
import im.vector.app.BuildConfig
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.core.glide.GlideApp
|
import im.vector.app.core.glide.GlideApp
|
||||||
import im.vector.app.core.utils.DimensionConverter
|
import im.vector.app.core.utils.DimensionConverter
|
||||||
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
import im.vector.app.features.MainActivity
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -58,7 +58,7 @@ class ShortcutCreator @Inject constructor(
|
|||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
fun create(roomSummary: RoomSummary, rank: Int = 1): ShortcutInfoCompat {
|
fun create(roomSummary: RoomSummary, rank: Int = 1): ShortcutInfoCompat {
|
||||||
val intent = RoomDetailActivity.shortcutIntent(context, roomSummary.roomId)
|
val intent = MainActivity.shortcutIntent(context, roomSummary.roomId)
|
||||||
val bitmap = try {
|
val bitmap = try {
|
||||||
val glideRequests = GlideApp.with(context)
|
val glideRequests = GlideApp.with(context)
|
||||||
val matrixItem = roomSummary.toMatrixItem()
|
val matrixItem = roomSummary.toMatrixItem()
|
||||||
|
@ -16,15 +16,22 @@
|
|||||||
|
|
||||||
package im.vector.app.features.home
|
package im.vector.app.features.home
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.ShortcutManager
|
import android.content.pm.ShortcutManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import androidx.core.content.edit
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.core.di.DefaultPreferences
|
||||||
import im.vector.app.core.dispatchers.CoroutineDispatchers
|
import im.vector.app.core.dispatchers.CoroutineDispatchers
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.features.MainActivity
|
||||||
|
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||||
import im.vector.app.features.pin.PinCodeStore
|
import im.vector.app.features.pin.PinCodeStore
|
||||||
import im.vector.app.features.pin.PinCodeStoreListener
|
import im.vector.app.features.pin.PinCodeStoreListener
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -35,6 +42,7 @@ import kotlinx.coroutines.flow.onCompletion
|
|||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
@ -50,7 +58,9 @@ class ShortcutsHandler @Inject constructor(
|
|||||||
private val appDispatchers: CoroutineDispatchers,
|
private val appDispatchers: CoroutineDispatchers,
|
||||||
private val shortcutCreator: ShortcutCreator,
|
private val shortcutCreator: ShortcutCreator,
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val pinCodeStore: PinCodeStore
|
private val pinCodeStore: PinCodeStore,
|
||||||
|
@DefaultPreferences
|
||||||
|
private val sharedPreferences: SharedPreferences,
|
||||||
) : PinCodeStoreListener {
|
) : PinCodeStoreListener {
|
||||||
|
|
||||||
private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context)
|
private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context)
|
||||||
@ -87,6 +97,27 @@ class ShortcutsHandler @Inject constructor(
|
|||||||
.launchIn(coroutineScope)
|
.launchIn(coroutineScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
fun updateShortcutsWithPreviousIntent() {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) return
|
||||||
|
// Check if it's been already done
|
||||||
|
if (sharedPreferences.getBoolean(SHARED_PREF_KEY, false)) return
|
||||||
|
ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_PINNED)
|
||||||
|
.filter { it.intent.component?.className == RoomDetailActivity::class.qualifiedName }
|
||||||
|
.mapNotNull {
|
||||||
|
it.intent.getStringExtra("EXTRA_ROOM_ID")?.let { roomId ->
|
||||||
|
ShortcutInfoCompat.Builder(context, it.toShortcutInfo())
|
||||||
|
.setIntent(MainActivity.shortcutIntent(context, roomId))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.takeIf { it.isNotEmpty() }
|
||||||
|
?.also { Timber.d("Update ${it.size} shortcut(s)") }
|
||||||
|
?.let { tryOrNull("Error") { ShortcutManagerCompat.updateShortcuts(context, it) } }
|
||||||
|
?.also { Timber.d("Update shortcuts with success: $it") }
|
||||||
|
sharedPreferences.edit { putBoolean(SHARED_PREF_KEY, true) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun removeDeadShortcuts(roomIds: List<String>) {
|
private fun removeDeadShortcuts(roomIds: List<String>) {
|
||||||
val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC)
|
val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC)
|
||||||
.map { it.id }
|
.map { it.id }
|
||||||
@ -163,4 +194,8 @@ class ShortcutsHandler @Inject constructor(
|
|||||||
// Else shortcut will be created next time any room summary is updated, or
|
// Else shortcut will be created next time any room summary is updated, or
|
||||||
// next time the app is started which is acceptable
|
// next time the app is started which is acceptable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SHARED_PREF_KEY = "ROOM_DETAIL_ACTIVITY_SHORTCUT_UPDATED"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,12 +99,7 @@ class RoomDetailActivity :
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
||||||
waitingView = views.waitingView.waitingView
|
waitingView = views.waitingView.waitingView
|
||||||
val timelineArgs: TimelineArgs? = if (intent?.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) {
|
val timelineArgs: TimelineArgs = intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS) ?: return
|
||||||
TimelineArgs(roomId = intent?.extras?.getString(EXTRA_ROOM_ID)!!)
|
|
||||||
} else {
|
|
||||||
intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS)
|
|
||||||
}
|
|
||||||
if (timelineArgs == null) return
|
|
||||||
intent.putExtra(Mavericks.KEY_ARG, timelineArgs)
|
intent.putExtra(Mavericks.KEY_ARG, timelineArgs)
|
||||||
currentRoomId = timelineArgs.roomId
|
currentRoomId = timelineArgs.roomId
|
||||||
|
|
||||||
@ -187,10 +182,7 @@ class RoomDetailActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val EXTRA_ROOM_DETAIL_ARGS = "EXTRA_ROOM_DETAIL_ARGS"
|
const val EXTRA_ROOM_DETAIL_ARGS = "EXTRA_ROOM_DETAIL_ARGS"
|
||||||
const val EXTRA_ROOM_ID = "EXTRA_ROOM_ID"
|
|
||||||
const val ACTION_ROOM_DETAILS_FROM_SHORTCUT = "ROOM_DETAILS_FROM_SHORTCUT"
|
|
||||||
|
|
||||||
fun newIntent(context: Context, timelineArgs: TimelineArgs, firstStartMainActivity: Boolean): Intent {
|
fun newIntent(context: Context, timelineArgs: TimelineArgs, firstStartMainActivity: Boolean): Intent {
|
||||||
val intent = Intent(context, RoomDetailActivity::class.java).apply {
|
val intent = Intent(context, RoomDetailActivity::class.java).apply {
|
||||||
@ -202,14 +194,6 @@ class RoomDetailActivity :
|
|||||||
intent
|
intent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shortcuts can't have intents with parcelables
|
|
||||||
fun shortcutIntent(context: Context, roomId: String): Intent {
|
|
||||||
return Intent(context, RoomDetailActivity::class.java).apply {
|
|
||||||
action = ACTION_ROOM_DETAILS_FROM_SHORTCUT
|
|
||||||
putExtra(EXTRA_ROOM_ID, roomId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) {
|
override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) {
|
||||||
|
@ -28,6 +28,7 @@ import im.vector.app.R
|
|||||||
import im.vector.app.core.di.DefaultSharedPreferences
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import im.vector.app.core.time.Clock
|
import im.vector.app.core.time.Clock
|
||||||
import im.vector.app.features.disclaimer.SHARED_PREF_KEY
|
import im.vector.app.features.disclaimer.SHARED_PREF_KEY
|
||||||
|
import im.vector.app.features.home.ShortcutsHandler
|
||||||
import im.vector.app.features.homeserver.ServerUrlsRepository
|
import im.vector.app.features.homeserver.ServerUrlsRepository
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
@ -268,7 +269,9 @@ class VectorPreferences @Inject constructor(
|
|||||||
SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY,
|
SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY,
|
||||||
|
|
||||||
SETTINGS_USE_RAGE_SHAKE_KEY,
|
SETTINGS_USE_RAGE_SHAKE_KEY,
|
||||||
SETTINGS_SECURITY_USE_FLAG_SECURE
|
SETTINGS_SECURITY_USE_FLAG_SECURE,
|
||||||
|
|
||||||
|
ShortcutsHandler.SHARED_PREF_KEY,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user