mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Makes space bottom sheet header reflect backstack
This commit is contained in:
parent
5012f37e6f
commit
894d4f700e
@ -57,6 +57,8 @@ interface SpaceStateHandler : DefaultLifecycleObserver {
|
|||||||
*/
|
*/
|
||||||
fun popSpaceBackstack(): String?
|
fun popSpaceBackstack(): String?
|
||||||
|
|
||||||
|
fun getPersistedSpaceBackstack(): List<String?>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a flow of the selected space for clients to react immediately to space changes.
|
* Gets a flow of the selected space for clients to react immediately to space changes.
|
||||||
*/
|
*/
|
||||||
|
@ -75,26 +75,28 @@ class SpaceStateHandlerImpl @Inject constructor(
|
|||||||
isForwardNavigation: Boolean,
|
isForwardNavigation: Boolean,
|
||||||
) {
|
) {
|
||||||
val activeSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
val activeSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
||||||
val currentSpace = selectedSpaceDataSource.currentValue?.orNull()
|
val spaceToLeave = selectedSpaceDataSource.currentValue?.orNull()
|
||||||
val spaceSummary = spaceId?.let { activeSession.getRoomSummary(spaceId) }
|
val spaceToSet = spaceId?.let { activeSession.getRoomSummary(spaceId) }
|
||||||
val sameSpaceSelected = spaceId == currentSpace?.roomId
|
val sameSpaceSelected = spaceId == spaceToLeave?.roomId
|
||||||
|
|
||||||
if (sameSpaceSelected) {
|
if (sameSpaceSelected) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isForwardNavigation) {
|
if (isForwardNavigation) {
|
||||||
addToBackstacks(currentSpace)
|
addToBackstacks(spaceToLeave, spaceToSet)
|
||||||
|
} else {
|
||||||
|
popBackstackUntil(spaceToSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (persistNow) {
|
if (persistNow) {
|
||||||
uiStateRepository.storeSelectedSpace(spaceSummary?.roomId, activeSession.sessionId)
|
uiStateRepository.storeSelectedSpace(spaceToSet?.roomId, activeSession.sessionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spaceSummary == null) {
|
if (spaceToSet == null) {
|
||||||
selectedSpaceDataSource.post(Option.empty())
|
selectedSpaceDataSource.post(Option.empty())
|
||||||
} else {
|
} else {
|
||||||
selectedSpaceDataSource.post(Option.just(spaceSummary))
|
selectedSpaceDataSource.post(Option.just(spaceToSet))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spaceId != null) {
|
if (spaceId != null) {
|
||||||
@ -106,12 +108,29 @@ class SpaceStateHandlerImpl @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addToBackstacks(space: RoomSummary?) {
|
private fun addToBackstacks(spaceToLeave: RoomSummary?, spaceToSet: RoomSummary?) {
|
||||||
|
spaceBackstack.addLast(spaceToLeave?.roomId)
|
||||||
|
|
||||||
|
// Only add to the persisted backstack if the space to set is not All Chats, else reset the persisted stack
|
||||||
|
if (spaceToSet != null && spaceToLeave != null) {
|
||||||
|
val currentPersistedBackstack = vectorPreferences.getPersistedSpaceBackstack().toMutableList()
|
||||||
|
currentPersistedBackstack.add(spaceToLeave.roomId)
|
||||||
|
vectorPreferences.setPersistedSpaceBackstack(currentPersistedBackstack)
|
||||||
|
} else if (spaceToSet == null) {
|
||||||
|
vectorPreferences.setPersistedSpaceBackstack(emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun popBackstackUntil(space: RoomSummary?) {
|
||||||
val spaceId = space?.roomId
|
val spaceId = space?.roomId
|
||||||
spaceBackstack.addLast(spaceId)
|
while (spaceBackstack.last() != spaceId) {
|
||||||
|
spaceBackstack.removeLast()
|
||||||
|
}
|
||||||
|
|
||||||
val currentPersistedBackstack = vectorPreferences.getPersistedSpaceBackstack().toMutableList()
|
val currentPersistedBackstack = vectorPreferences.getPersistedSpaceBackstack().toMutableList()
|
||||||
currentPersistedBackstack.add(spaceId)
|
while (currentPersistedBackstack.last() != spaceId) {
|
||||||
|
currentPersistedBackstack.removeLast()
|
||||||
|
}
|
||||||
vectorPreferences.setPersistedSpaceBackstack(currentPersistedBackstack)
|
vectorPreferences.setPersistedSpaceBackstack(currentPersistedBackstack)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +166,8 @@ class SpaceStateHandlerImpl @Inject constructor(
|
|||||||
return poppedSpaceId
|
return poppedSpaceId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getPersistedSpaceBackstack() = vectorPreferences.getPersistedSpaceBackstack()
|
||||||
|
|
||||||
override fun getSelectedSpaceFlow() = selectedSpaceFlow
|
override fun getSelectedSpaceFlow() = selectedSpaceFlow
|
||||||
|
|
||||||
override fun getSafeActiveSpaceId(): String? {
|
override fun getSafeActiveSpaceId(): String? {
|
||||||
|
@ -1121,7 +1121,7 @@ class VectorPreferences @Inject constructor(
|
|||||||
* Only the IDs of the spaces are stored
|
* Only the IDs of the spaces are stored
|
||||||
*/
|
*/
|
||||||
fun setPersistedSpaceBackstack(spaceBackstack: List<String?>) {
|
fun setPersistedSpaceBackstack(spaceBackstack: List<String?>) {
|
||||||
val spaceIdsJoined = spaceBackstack.joinToString(",")
|
val spaceIdsJoined = spaceBackstack.takeIf { it.isNotEmpty() }?.joinToString(",")
|
||||||
defaultPrefs.edit().putString(SETTINGS_PERSISTED_SPACE_BACKSTACK, spaceIdsJoined).apply()
|
defaultPrefs.edit().putString(SETTINGS_PERSISTED_SPACE_BACKSTACK, spaceIdsJoined).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,7 +1130,7 @@ class VectorPreferences @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
fun getPersistedSpaceBackstack(): List<String?> {
|
fun getPersistedSpaceBackstack(): List<String?> {
|
||||||
val spaceIdsJoined = defaultPrefs.getString(SETTINGS_PERSISTED_SPACE_BACKSTACK, null)
|
val spaceIdsJoined = defaultPrefs.getString(SETTINGS_PERSISTED_SPACE_BACKSTACK, null)
|
||||||
return spaceIdsJoined?.split(",").orEmpty()
|
return spaceIdsJoined?.takeIf { it.isNotEmpty() }?.split(",").orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showLiveSenderInfo(): Boolean {
|
fun showLiveSenderInfo(): Boolean {
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package im.vector.app.features.spaces
|
package im.vector.app.features.spaces
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.TextView
|
||||||
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
import com.airbnb.epoxy.EpoxyModelClass
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||||
@ -23,5 +26,28 @@ import im.vector.app.core.epoxy.VectorEpoxyModel
|
|||||||
|
|
||||||
@EpoxyModelClass
|
@EpoxyModelClass
|
||||||
abstract class NewSpaceListHeaderItem : VectorEpoxyModel<NewSpaceListHeaderItem.Holder>(R.layout.item_new_space_list_header) {
|
abstract class NewSpaceListHeaderItem : VectorEpoxyModel<NewSpaceListHeaderItem.Holder>(R.layout.item_new_space_list_header) {
|
||||||
class Holder : VectorEpoxyHolder()
|
|
||||||
|
@EpoxyAttribute var currentSpace: String? = null
|
||||||
|
@EpoxyAttribute var spaceHistory: List<Pair<String?, String>> = emptyList()
|
||||||
|
|
||||||
|
override fun bind(holder: Holder) {
|
||||||
|
super.bind(holder)
|
||||||
|
holder.spaceHeader.text = buildSpaceHeaderText(holder.spaceHeader.context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildSpaceHeaderText(context: Context): String {
|
||||||
|
val allChats = context.getString(R.string.all_chats)
|
||||||
|
var spaceHeaderText = allChats
|
||||||
|
if (spaceHistory.isNotEmpty()) {
|
||||||
|
spaceHeaderText += " > ${spaceHistory.joinToString(" > ") { it.second }}"
|
||||||
|
}
|
||||||
|
if (currentSpace != null) {
|
||||||
|
spaceHeaderText += " > $currentSpace"
|
||||||
|
}
|
||||||
|
return spaceHeaderText
|
||||||
|
}
|
||||||
|
|
||||||
|
class Holder : VectorEpoxyHolder() {
|
||||||
|
val spaceHeader by bind<TextView>(R.id.space_header)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,8 @@ class NewSpaceSummaryController @Inject constructor(
|
|||||||
nonNullViewState.spaces,
|
nonNullViewState.spaces,
|
||||||
nonNullViewState.selectedSpace,
|
nonNullViewState.selectedSpace,
|
||||||
nonNullViewState.rootSpacesOrdered,
|
nonNullViewState.rootSpacesOrdered,
|
||||||
nonNullViewState.homeAggregateCount
|
nonNullViewState.homeAggregateCount,
|
||||||
|
nonNullViewState.spaceHistory,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,11 +59,15 @@ class NewSpaceSummaryController @Inject constructor(
|
|||||||
spaceSummaries: List<RoomSummary>?,
|
spaceSummaries: List<RoomSummary>?,
|
||||||
selectedSpace: RoomSummary?,
|
selectedSpace: RoomSummary?,
|
||||||
rootSpaces: List<RoomSummary>?,
|
rootSpaces: List<RoomSummary>?,
|
||||||
homeCount: RoomAggregateNotificationCount
|
homeCount: RoomAggregateNotificationCount,
|
||||||
|
spaceHistory: List<Pair<String?, String>>,
|
||||||
) {
|
) {
|
||||||
val host = this
|
val host = this
|
||||||
|
|
||||||
newSpaceListHeaderItem {
|
newSpaceListHeaderItem {
|
||||||
id("space_list_header")
|
id("space_list_header")
|
||||||
|
currentSpace(selectedSpace?.displayName)
|
||||||
|
spaceHistory(spaceHistory)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedSpace != null) {
|
if (selectedSpace != null) {
|
||||||
|
@ -65,7 +65,7 @@ class SpaceListViewModel @AssistedInject constructor(
|
|||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val autoAcceptInvites: AutoAcceptInvites,
|
private val autoAcceptInvites: AutoAcceptInvites,
|
||||||
private val analyticsTracker: AnalyticsTracker
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
) : VectorViewModel<SpaceListViewState, SpaceListAction, SpaceListViewEvents>(initialState) {
|
) : VectorViewModel<SpaceListViewState, SpaceListAction, SpaceListViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
@ -85,11 +85,14 @@ class SpaceListViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
observeSpaceSummaries()
|
observeSpaceSummaries()
|
||||||
|
val spaceHistory = spaceStateHandler.getPersistedSpaceBackstack()
|
||||||
|
.map { it to it?.let { session.roomService().getRoomSummary(it)?.displayName }.orEmpty() }
|
||||||
spaceStateHandler.getSelectedSpaceFlow()
|
spaceStateHandler.getSelectedSpaceFlow()
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.setOnEach { selectedSpaceOption ->
|
.setOnEach { selectedSpaceOption ->
|
||||||
copy(
|
copy(
|
||||||
selectedSpace = selectedSpaceOption.orNull()
|
selectedSpace = selectedSpaceOption.orNull(),
|
||||||
|
spaceHistory = spaceHistory,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,5 +32,6 @@ data class SpaceListViewState(
|
|||||||
val spaceOrderInfo: Map<String, String?>? = null,
|
val spaceOrderInfo: Map<String, String?>? = null,
|
||||||
val spaceOrderLocalEchos: Map<String, String?>? = null,
|
val spaceOrderLocalEchos: Map<String, String?>? = null,
|
||||||
val expandedStates: Map<String, Boolean> = emptyMap(),
|
val expandedStates: Map<String, Boolean> = emptyMap(),
|
||||||
|
val spaceHistory: List<Pair<String?, String>> = emptyList(), // List of space id to display name
|
||||||
val homeAggregateCount: RoomAggregateNotificationCount = RoomAggregateNotificationCount(0, 0)
|
val homeAggregateCount: RoomAggregateNotificationCount = RoomAggregateNotificationCount(0, 0)
|
||||||
) : MavericksState
|
) : MavericksState
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/space_header"
|
||||||
style="@style/TextAppearance.Vector.Body.Medium"
|
style="@style/TextAppearance.Vector.Body.Medium"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
Loading…
Reference in New Issue
Block a user