Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ data class SpaceChildInfo(
val order: String?,
val activeMemberCount: Int?,
val autoJoin: Boolean,
val viaServers: List<String>
val viaServers: List<String>,
val parentRoomId: String?
)
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ interface SpaceService {
/**
* Get's information of a space by querying the server
*/
suspend fun querySpaceChildren(spaceId: String): Pair<RoomSummary, List<SpaceChildInfo>>
suspend fun querySpaceChildren(spaceId: String, suggestedOnly: Boolean? = null, autoJoinedOnly: Boolean? = null)
: Pair<RoomSummary, List<SpaceChildInfo>>

/**
* Get a live list of space summaries. This list is refreshed as soon as the data changes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
activeMemberCount = it.childSummaryEntity?.joinedMembersCount,
order = it.order,
autoJoin = it.autoJoin ?: false,
viaServers = it.viaServers.toList()
viaServers = it.viaServers.toList(),
parentRoomId = roomSummaryEntity.roomId
)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
import org.matrix.android.sdk.internal.session.space.peeking.PeekSpaceTask
import org.matrix.android.sdk.internal.session.space.peeking.SpacePeekResult
import java.lang.IllegalArgumentException
import javax.inject.Inject

internal class DefaultSpaceService @Inject constructor(
Expand Down Expand Up @@ -90,8 +89,8 @@ internal class DefaultSpaceService @Inject constructor(
return peekSpaceTask.execute(PeekSpaceTask.Params(spaceId))
}

override suspend fun querySpaceChildren(spaceId: String): Pair<RoomSummary, List<SpaceChildInfo>> {
return resolveSpaceInfoTask.execute(ResolveSpaceInfoTask.Params.withId(spaceId)).let { response ->
override suspend fun querySpaceChildren(spaceId: String, suggestedOnly: Boolean?, autoJoinedOnly: Boolean?): Pair<RoomSummary, List<SpaceChildInfo>> {
return resolveSpaceInfoTask.execute(ResolveSpaceInfoTask.Params.withId(spaceId, suggestedOnly, autoJoinedOnly)).let { response ->
val spaceDesc = response.rooms?.firstOrNull { it.roomId == spaceId }
Pair(
first = RoomSummary(
Expand All @@ -111,18 +110,19 @@ internal class DefaultSpaceService @Inject constructor(
?.map { childSummary ->
val childStateEv = response.events
?.firstOrNull { it.stateKey == childSummary.roomId && it.type == EventType.STATE_SPACE_CHILD }
?.content.toModel<SpaceChildContent>()
val childStateEvContent = childStateEv?.content.toModel<SpaceChildContent>()
SpaceChildInfo(
childRoomId = childSummary.roomId,
isKnown = true,
roomType = childSummary.roomType,
name = childSummary.name,
topic = childSummary.topic,
avatarUrl = childSummary.avatarUrl,
order = childStateEv?.order,
autoJoin = childStateEv?.autoJoin ?: false,
viaServers = childStateEv?.via ?: emptyList(),
activeMemberCount = childSummary.numJoinedMembers
order = childStateEvContent?.order,
autoJoin = childStateEvContent?.autoJoin ?: false,
viaServers = childStateEvContent?.via ?: emptyList(),
activeMemberCount = childSummary.numJoinedMembers,
parentRoomId = childStateEv?.roomId
)
} ?: emptyList()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ import javax.inject.Inject
internal interface ResolveSpaceInfoTask : Task<ResolveSpaceInfoTask.Params, SpacesResponse> {
data class Params(
val spaceId: String,
val maxRoomPerSpace: Int,
val maxRoomPerSpace: Int?,
val limit: Int,
val batchToken: String?
val batchToken: String?,
val suggestedOnly: Boolean?,
val autoJoinOnly: Boolean?
) {
companion object {
fun withId(spaceId: String) = Params(spaceId, 10, 20, null)
fun withId(spaceId: String, suggestedOnly: Boolean?, autoJoinOnly: Boolean?) =
Params(spaceId, 10, 20, null, suggestedOnly, autoJoinOnly)
}
}
}
Expand All @@ -37,7 +40,13 @@ internal class DefaultResolveSpaceInfoTask @Inject constructor(
private val spaceApi: SpaceApi
) : ResolveSpaceInfoTask {
override suspend fun execute(params: ResolveSpaceInfoTask.Params): SpacesResponse {
val body = SpaceSummaryParams(maxRoomPerSpace = params.maxRoomPerSpace, limit = params.limit, batch = params.batchToken ?: "")
val body = SpaceSummaryParams(
maxRoomPerSpace = params.maxRoomPerSpace,
limit = params.limit,
batch = params.batchToken ?: "",
autoJoinedOnly = params.autoJoinOnly,
suggestedOnly = params.suggestedOnly
)
return executeRequest<SpacesResponse>(null) {
apiCall = spaceApi.getSpaces(params.spaceId, body)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ internal interface SpaceApi {
* POST /_matrix/client/r0/rooms/{roomID}/spaces
* {
* "max_rooms_per_space": 5, // The maximum number of rooms/subspaces to return for a given space, if negative unbounded. default: -1.
* "auto_join_only": true, // If true, only return m.space.child events with auto_join:true, default: false, which returns all events.
* "limit": 100, // The maximum number of rooms/subspaces to return, server can override this, default: 100.
* "batch": "opaque_string" // A token to use if this is a subsequent HTTP hit, default: "".
* }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class SpaceSummaryParams(
/** The maximum number of rooms/subspaces to return for a given space, if negative unbounded. default: -1*/
@Json(name = "max_rooms_per_space") val maxRoomPerSpace: Int = 100,
@Json(name = "max_rooms_per_space") val maxRoomPerSpace: Int?,
/** The maximum number of rooms/subspaces to return, server can override this, default: 100 */
@Json(name = "limit") val limit: Int = 100,
@Json(name = "limit") val limit: Int?,
/** A token to use if this is a subsequent HTTP hit, default: "".*/
@Json(name = "batch") val batch: String = "",
/** whether we should only return children with the "suggested" flag set.*/
@Json(name = "suggested_only") val suggestedOnly: Boolean = false
@Json(name = "suggested_only") val suggestedOnly: Boolean?,
/** whether we should only return children with the "suggested" flag set.*/
@Json(name = "auto_join_only") val autoJoinedOnly: Boolean?

)
2 changes: 1 addition & 1 deletion vector/src/main/java/im/vector/app/AppStateHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class AppStateHandler @Inject constructor(
if (currentSpace != null) {
val childInfo = withContext(Dispatchers.IO) {
tryOrNull {
session.spaceService().querySpaceChildren(currentSpace.roomId)
session.spaceService().querySpaceChildren(currentSpace.roomId, suggestedOnly = true)
}
}
childInfo?.second?.let { currentSpaceSuggestedDataSource.post(it) } ?: kotlin.run {
Expand Down
6 changes: 6 additions & 0 deletions vector/src/main/java/im/vector/app/core/di/FragmentModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ import im.vector.app.features.spaces.SpaceListFragment
import im.vector.app.features.spaces.create.ChooseSpaceTypeFragment
import im.vector.app.features.spaces.create.CreateSpaceDefaultRoomsFragment
import im.vector.app.features.spaces.create.CreateSpaceDetailsFragment
import im.vector.app.features.spaces.explore.SpaceDirectoryFragment
import im.vector.app.features.spaces.preview.SpacePreviewFragment
import im.vector.app.features.terms.ReviewTermsFragment
import im.vector.app.features.usercode.ShowUserCodeFragment
Expand Down Expand Up @@ -666,4 +667,9 @@ interface FragmentModule {
@IntoMap
@FragmentKey(MatrixToRoomSpaceFragment::class)
fun bindMatrixToRoomSpaceFragment(fragment: MatrixToRoomSpaceFragment): Fragment

@Binds
@IntoMap
@FragmentKey(SpaceDirectoryFragment::class)
fun bindSpaceDirectoryFragment(fragment: SpaceDirectoryFragment): Fragment
}
2 changes: 2 additions & 0 deletions vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import im.vector.app.features.share.IncomingShareActivity
import im.vector.app.features.signout.soft.SoftLogoutActivity
import im.vector.app.features.spaces.ShareSpaceBottomSheet
import im.vector.app.features.spaces.SpaceCreationActivity
import im.vector.app.features.spaces.SpaceExploreActivity
import im.vector.app.features.terms.ReviewTermsActivity
import im.vector.app.features.ui.UiStateRepository
import im.vector.app.features.usercode.UserCodeActivity
Expand Down Expand Up @@ -154,6 +155,7 @@ interface ScreenComponent {
fun inject(activity: ReAuthActivity)
fun inject(activity: RoomDevToolActivity)
fun inject(activity: SpaceCreationActivity)
fun inject(activity: SpaceExploreActivity)

/* ==========================================================================================
* BottomSheets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor

fun createSuggestion(spaceChildInfo: SpaceChildInfo,
suggestedRoomJoiningStates: Map<String, Async<Unit>>,
onJoinClick: View.OnClickListener) : VectorEpoxyModel<*> {
return SuggestedRoomItem_()
onJoinClick: View.OnClickListener): VectorEpoxyModel<*> {
return SpaceChildInfoItem_()
.id("sug_${spaceChildInfo.childRoomId}")
.matrixItem(MatrixItem.RoomItem(spaceChildInfo.childRoomId, spaceChildInfo.name, spaceChildInfo.avatarUrl))
.avatarRenderer(avatarRenderer)
.topic(spaceChildInfo.topic)
.buttonLabel(stringProvider.getString(R.string.join))
.loading(suggestedRoomJoiningStates[spaceChildInfo.childRoomId] is Loading)
.memberCount(spaceChildInfo.activeMemberCount ?: 0)
.buttonClickListener(onJoinClick)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import me.gujun.android.span.span
import org.matrix.android.sdk.api.util.MatrixItem

@EpoxyModelClass(layout = R.layout.item_suggested_room)
abstract class SuggestedRoomItem : VectorEpoxyModel<SuggestedRoomItem.Holder>() {
abstract class SpaceChildInfoItem : VectorEpoxyModel<SpaceChildInfoItem.Holder>() {

@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute lateinit var matrixItem: MatrixItem
Expand All @@ -48,6 +48,9 @@ abstract class SuggestedRoomItem : VectorEpoxyModel<SuggestedRoomItem.Holder>()

@EpoxyAttribute var memberCount: Int = 0
@EpoxyAttribute var loading: Boolean = false
@EpoxyAttribute var space: Boolean = false

@EpoxyAttribute var buttonLabel: String? = null

@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: View.OnClickListener? = null
Expand All @@ -61,13 +64,17 @@ abstract class SuggestedRoomItem : VectorEpoxyModel<SuggestedRoomItem.Holder>()
itemLongClickListener?.onLongClick(it) ?: false
}
holder.titleView.text = matrixItem.getBestName()
avatarRenderer.render(matrixItem, holder.avatarImageView)
if (space) {
avatarRenderer.renderSpace(matrixItem, holder.avatarImageView)
} else {
avatarRenderer.render(matrixItem, holder.avatarImageView)
}

holder.descriptionText.text = span {
span {
apply {
val tintColor = ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_secondary)
ContextCompat.getDrawable(holder.view.context, R.drawable.ic_room_profile_member_list)
ContextCompat.getDrawable(holder.view.context, R.drawable.ic_member_small)
?.apply {
ThemeUtils.tintDrawableWithColor(this, tintColor)
}?.let {
Expand All @@ -83,6 +90,8 @@ abstract class SuggestedRoomItem : VectorEpoxyModel<SuggestedRoomItem.Holder>()
}
}

holder.joinButton.text = buttonLabel

if (loading) {
holder.joinButtonLoading.isVisible = true
holder.joinButton.isInvisible = true
Expand All @@ -93,8 +102,8 @@ abstract class SuggestedRoomItem : VectorEpoxyModel<SuggestedRoomItem.Holder>()

holder.joinButton.setOnClickListener {
// local echo
holder.joinButtonLoading.isVisible = true
holder.joinButton.isInvisible = true
holder.joinButton.isEnabled = false
holder.view.postDelayed({ holder.joinButton.isEnabled = true }, 400)
buttonClickListener?.onClick(it)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import im.vector.app.features.roomprofile.RoomProfileActivity
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.settings.VectorSettingsActivity
import im.vector.app.features.share.SharedData
import im.vector.app.features.spaces.SpaceExploreActivity
import im.vector.app.features.spaces.SpacePreviewActivity
import im.vector.app.features.terms.ReviewTermsActivity
import im.vector.app.features.widgets.WidgetActivity
Expand Down Expand Up @@ -250,8 +251,17 @@ class DefaultNavigator @Inject constructor(
}

override fun openRoomDirectory(context: Context, initialFilter: String) {
val intent = RoomDirectoryActivity.getIntent(context, initialFilter)
context.startActivity(intent)
val selectedSpace = selectedSpaceDataSource.currentValue?.orNull()?.let {
sessionHolder.getSafeActiveSession()?.getRoomSummary(it.roomId)
}
if (selectedSpace == null) {
val intent = RoomDirectoryActivity.getIntent(context, initialFilter)
context.startActivity(intent)
} else {
SpaceExploreActivity.newIntent(context, selectedSpace.roomId).let {
context.startActivity(it)
}
}
}

override fun openCreateRoom(context: Context, initialName: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,47 +20,60 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.viewModel
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.commitTransaction
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleBinding
import im.vector.app.features.spaces.explore.SpaceDirectoryArgs
import im.vector.app.features.spaces.explore.SpaceDirectoryFragment
import im.vector.app.features.spaces.preview.SpacePreviewArgs
import im.vector.app.features.spaces.preview.SpacePreviewFragment
import im.vector.app.features.spaces.explore.SpaceDirectoryState
import im.vector.app.features.spaces.explore.SpaceDirectoryViewEvents
import im.vector.app.features.spaces.explore.SpaceDirectoryViewModel
import javax.inject.Inject

class SpaceExploreActivity : VectorBaseActivity<ActivitySimpleBinding>() {
class SpaceExploreActivity : VectorBaseActivity<ActivitySimpleBinding>(), SpaceDirectoryViewModel.Factory {

@Inject lateinit var spaceDirectoryViewModelFactory: SpaceDirectoryViewModel.Factory

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun getBinding(): ActivitySimpleBinding = ActivitySimpleBinding.inflate(layoutInflater)
// lateinit var sharedActionViewModel: SpacePreviewSharedActionViewModel

override fun getTitleRes(): Int = R.string.space_explore_activity_title

val sharedViewModel: SpaceDirectoryViewModel by viewModel()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// sharedActionViewModel = viewModelProvider.get(SpacePreviewSharedActionViewModel::class.java)
// sharedActionViewModel
// .observe()
// .subscribe { action ->
// when (action) {
// SpacePreviewSharedAction.DismissAction -> finish()
// SpacePreviewSharedAction.ShowModalLoading -> showWaitingView()
// SpacePreviewSharedAction.HideModalLoading -> hideWaitingView()
// is SpacePreviewSharedAction.ShowErrorMessage -> action.error?.let { showSnackbar(it) }
// }
// }.disposeOnDestroy()

if (isFirstCreation()) {
val simpleName = SpaceDirectoryFragment::class.java.simpleName
val args = intent?.getParcelableExtra<SpacePreviewArgs>(MvRx.KEY_ARG)
val args = intent?.getParcelableExtra<SpaceDirectoryArgs>(MvRx.KEY_ARG)
if (supportFragmentManager.findFragmentByTag(simpleName) == null) {
supportFragmentManager.commitTransaction {
replace(R.id.simpleFragmentContainer,
SpacePreviewFragment::class.java,
SpaceDirectoryFragment::class.java,
Bundle().apply { this.putParcelable(MvRx.KEY_ARG, args) },
simpleName
)
}
}
}

sharedViewModel.observeViewEvents {
when (it) {
SpaceDirectoryViewEvents.Dismiss -> {
finish()
}
is SpaceDirectoryViewEvents.NavigateToRoom -> {
navigator.openRoom(this, it.roomId)
}
}
}
}

companion object {
Expand All @@ -70,4 +83,7 @@ class SpaceExploreActivity : VectorBaseActivity<ActivitySimpleBinding>() {
}
}
}

override fun create(initialState: SpaceDirectoryState): SpaceDirectoryViewModel =
spaceDirectoryViewModelFactory.create(initialState)
}
Loading