mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Start introducing theme on app + branch toolbar to drawer, still requires refinements
This commit is contained in:
parent
e5fc1e3412
commit
cc29a387c7
Binary file not shown.
@ -12,7 +12,7 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/Theme.Riot">
|
||||||
<activity android:name=".features.login.LoginActivity">
|
<activity android:name=".features.login.LoginActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
@ -4,6 +4,11 @@ import com.airbnb.mvrx.BaseMvRxFragment
|
|||||||
|
|
||||||
abstract class RiotFragment : BaseMvRxFragment() {
|
abstract class RiotFragment : BaseMvRxFragment() {
|
||||||
|
|
||||||
|
val riotActivity: RiotActivity by lazy {
|
||||||
|
activity as RiotActivity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun invalidate() {
|
override fun invalidate() {
|
||||||
//no-ops by default
|
//no-ops by default
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package im.vector.riotredesign.core.platform
|
||||||
|
|
||||||
|
import android.support.v7.widget.Toolbar
|
||||||
|
|
||||||
|
interface ToolbarConfigurable {
|
||||||
|
|
||||||
|
fun configure(toolbar: Toolbar)
|
||||||
|
|
||||||
|
}
|
@ -3,10 +3,15 @@ package im.vector.riotredesign.features.home
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.support.v4.view.GravityCompat
|
||||||
|
import android.support.v7.app.ActionBarDrawerToggle
|
||||||
|
import android.support.v7.widget.Toolbar
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
|
import android.view.MenuItem
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.replaceFragment
|
import im.vector.riotredesign.core.extensions.replaceFragment
|
||||||
import im.vector.riotredesign.core.platform.RiotActivity
|
import im.vector.riotredesign.core.platform.RiotActivity
|
||||||
|
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
||||||
import im.vector.riotredesign.features.home.detail.LoadingRoomDetailFragment
|
import im.vector.riotredesign.features.home.detail.LoadingRoomDetailFragment
|
||||||
import im.vector.riotredesign.features.home.detail.RoomDetailFragment
|
import im.vector.riotredesign.features.home.detail.RoomDetailFragment
|
||||||
import im.vector.riotredesign.features.home.list.RoomListFragment
|
import im.vector.riotredesign.features.home.list.RoomListFragment
|
||||||
@ -14,12 +19,13 @@ import kotlinx.android.synthetic.main.activity_home.*
|
|||||||
import org.koin.standalone.StandAloneContext.loadKoinModules
|
import org.koin.standalone.StandAloneContext.loadKoinModules
|
||||||
|
|
||||||
|
|
||||||
class HomeActivity : RiotActivity(), HomeNavigator {
|
class HomeActivity : RiotActivity(), HomeNavigator, ToolbarConfigurable {
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
loadKoinModules(listOf(HomeModule(this)))
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_home)
|
setContentView(R.layout.activity_home)
|
||||||
loadKoinModules(listOf(HomeModule(this)))
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
val roomListFragment = RoomListFragment.newInstance()
|
val roomListFragment = RoomListFragment.newInstance()
|
||||||
val loadingDetail = LoadingRoomDetailFragment.newInstance()
|
val loadingDetail = LoadingRoomDetailFragment.newInstance()
|
||||||
@ -28,6 +34,35 @@ class HomeActivity : RiotActivity(), HomeNavigator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun configure(toolbar: Toolbar) {
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
supportActionBar?.setHomeButtonEnabled(true)
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
val drawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, 0, 0)
|
||||||
|
drawerLayout.addDrawerListener(drawerToggle)
|
||||||
|
drawerToggle.syncState()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
when (item.itemId) {
|
||||||
|
// Android home
|
||||||
|
android.R.id.home -> {
|
||||||
|
drawerLayout.openDrawer(GravityCompat.START)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBackPressed() {
|
||||||
|
if (drawerLayout.isDrawerOpen(Gravity.LEFT)) {
|
||||||
|
drawerLayout.closeDrawer(Gravity.LEFT)
|
||||||
|
} else {
|
||||||
|
super.onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun openRoomDetail(roomId: String) {
|
override fun openRoomDetail(roomId: String) {
|
||||||
val roomDetailFragment = RoomDetailFragment.newInstance(roomId)
|
val roomDetailFragment = RoomDetailFragment.newInstance(roomId)
|
||||||
replaceFragment(roomDetailFragment, R.id.homeDetailFragmentContainer)
|
replaceFragment(roomDetailFragment, R.id.homeDetailFragmentContainer)
|
||||||
|
@ -11,8 +11,10 @@ import android.view.ViewGroup
|
|||||||
import im.vector.matrix.android.api.Matrix
|
import im.vector.matrix.android.api.Matrix
|
||||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||||
import im.vector.matrix.android.api.session.room.Room
|
import im.vector.matrix.android.api.session.room.Room
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.RiotFragment
|
import im.vector.riotredesign.core.platform.RiotFragment
|
||||||
|
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
||||||
import im.vector.riotredesign.core.utils.FragmentArgumentDelegate
|
import im.vector.riotredesign.core.utils.FragmentArgumentDelegate
|
||||||
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
@ -41,14 +43,19 @@ class RoomDetailFragment : RiotFragment(), TimelineEventAdapter.Callback {
|
|||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
setupRecyclerView()
|
|
||||||
room = currentSession.getRoom(roomId)!!
|
room = currentSession.getRoom(roomId)!!
|
||||||
|
setupRecyclerView()
|
||||||
|
setupToolbar()
|
||||||
room.loadRoomMembersIfNeeded()
|
room.loadRoomMembersIfNeeded()
|
||||||
room.liveTimeline().observe(this, Observer { renderEvents(it) })
|
room.liveTimeline().observe(this, Observer { renderEvents(it) })
|
||||||
|
room.roomSummary.observe(this, Observer { renderRoomSummary(it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderEvents(events: PagedList<EnrichedEvent>?) {
|
private fun setupToolbar() {
|
||||||
timelineAdapter.submitList(events)
|
val parentActivity = riotActivity
|
||||||
|
if (parentActivity is ToolbarConfigurable) {
|
||||||
|
parentActivity.configure(toolbar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
@ -67,7 +74,19 @@ class RoomDetailFragment : RiotFragment(), TimelineEventAdapter.Callback {
|
|||||||
//recyclerView.setController(timelineEventController)
|
//recyclerView.setController(timelineEventController)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEventsListChanged(oldList: List<EnrichedEvent>?, newList: List<EnrichedEvent>?) {
|
private fun renderRoomSummary(roomSummary: RoomSummary?) {
|
||||||
|
roomSummary?.let {
|
||||||
|
toolbar.title = it.displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderEvents(events: PagedList<EnrichedEvent>?) {
|
||||||
|
timelineAdapter.submitList(events)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override
|
||||||
|
fun onEventsListChanged(oldList: List<EnrichedEvent>?, newList: List<EnrichedEvent>?) {
|
||||||
if (oldList == null && newList != null) {
|
if (oldList == null && newList != null) {
|
||||||
recyclerView.scrollToPosition(0)
|
recyclerView.scrollToPosition(0)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,11 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.airbnb.mvrx.*
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.Incomplete
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.matrix.android.api.failure.Failure
|
import im.vector.matrix.android.api.failure.Failure
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
@ -35,16 +39,19 @@ class RoomListFragment : RiotFragment(), RoomSummaryController.Callback {
|
|||||||
roomController = RoomSummaryController(this)
|
roomController = RoomSummaryController(this)
|
||||||
stateView.contentView = epoxyRecyclerView
|
stateView.contentView = epoxyRecyclerView
|
||||||
epoxyRecyclerView.setController(roomController)
|
epoxyRecyclerView.setController(roomController)
|
||||||
|
|
||||||
viewModel.subscribe { renderState(it) }
|
viewModel.subscribe { renderState(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderState(state: RoomListViewState) {
|
private fun renderState(state: RoomListViewState) {
|
||||||
when (state.roomSummaries) {
|
when (state.roomSummaries) {
|
||||||
is Incomplete -> renderLoading()
|
is Incomplete -> renderLoading()
|
||||||
is Success -> renderSuccess(state.roomSummaries(), state.selectedRoom)
|
is Success -> renderSuccess(state.roomSummaries(), state.selectedRoom)
|
||||||
is Fail -> renderFailure(state.roomSummaries.error)
|
is Fail -> renderFailure(state.roomSummaries.error)
|
||||||
}
|
}
|
||||||
if (state.showLastSelectedRoom && state.selectedRoom != null) {
|
if (state.selectedRoom != null && state.showLastSelectedRoom) {
|
||||||
|
val position = state.roomSummaries()?.indexOf(state.selectedRoom) ?: 0
|
||||||
|
epoxyRecyclerView.scrollToPosition(position)
|
||||||
homeNavigator.openRoomDetail(state.selectedRoom.roomId)
|
homeNavigator.openRoomDetail(state.selectedRoom.roomId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +72,7 @@ class RoomListFragment : RiotFragment(), RoomSummaryController.Callback {
|
|||||||
private fun renderFailure(error: Throwable) {
|
private fun renderFailure(error: Throwable) {
|
||||||
val message = when (error) {
|
val message = when (error) {
|
||||||
is Failure.NetworkConnection -> "Pas de connexion internet"
|
is Failure.NetworkConnection -> "Pas de connexion internet"
|
||||||
else -> "Une erreur est survenue"
|
else -> "Une erreur est survenue"
|
||||||
}
|
}
|
||||||
stateView.state = StateView.State.Error(message)
|
stateView.state = StateView.State.Error(message)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/homeDrawerFragmentContainer"
|
android:id="@+id/homeDrawerFragmentContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -1,11 +1,27 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="?actionBarSize"
|
||||||
|
android:background="@color/dark"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||||
|
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||||
|
|
||||||
<com.airbnb.epoxy.EpoxyRecyclerView
|
<com.airbnb.epoxy.EpoxyRecyclerView
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/recyclerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
9
app/src/main/res/values-v21/themes_base.xml
Normal file
9
app/src/main/res/values-v21/themes_base.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="Base.V21.Theme.Riot" parent="Base.V1.Theme.Riot"></style>
|
||||||
|
|
||||||
|
<style name="Base.Theme.Riot" parent="Base.V21.Theme.Riot" />
|
||||||
|
|
||||||
|
|
||||||
|
</resources>
|
@ -1,10 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="colorPrimary">#3F51B5</color>
|
|
||||||
<color name="colorPrimaryDark">#303F9F</color>
|
|
||||||
<color name="colorAccent">#FF4081</color>
|
|
||||||
|
|
||||||
|
|
||||||
<color name="pale_grey">#f2f5f8</color>
|
<color name="pale_grey">#f2f5f8</color>
|
||||||
<color name="dark">#2e3649</color>
|
<color name="dark">#2e3649</color>
|
||||||
<color name="pale_teal">#7ac9a1</color>
|
<color name="pale_teal">#7ac9a1</color>
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
5
app/src/main/res/values/styles_widget.xml
Normal file
5
app/src/main/res/values/styles_widget.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
|
||||||
|
</resources>
|
5
app/src/main/res/values/text_appearances.xml
Normal file
5
app/src/main/res/values/text_appearances.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
|
||||||
|
</resources>
|
9
app/src/main/res/values/themes.xml
Normal file
9
app/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="Theme.Riot" parent="Base.Theme.Riot">
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</resources>
|
13
app/src/main/res/values/themes_base.xml
Normal file
13
app/src/main/res/values/themes_base.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="Base.V1.Theme.Riot" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
|
<item name="colorPrimary">@color/dark</item>
|
||||||
|
<item name="colorPrimaryDark">@color/dark</item>
|
||||||
|
<item name="colorAccent">@color/pale_teal</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Base.Theme.Riot" parent="Base.V1.Theme.Riot" />
|
||||||
|
|
||||||
|
|
||||||
|
</resources>
|
2
app/src/main/res/values/themes_overlay.xml
Normal file
2
app/src/main/res/values/themes_overlay.xml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources></resources>
|
2
app/src/main/res/values/themes_overlay_base.xml
Normal file
2
app/src/main/res/values/themes_overlay_base.xml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources></resources>
|
@ -1,15 +1,18 @@
|
|||||||
package im.vector.matrix.android.api.session.room
|
package im.vector.matrix.android.api.session.room
|
||||||
|
|
||||||
|
import android.arch.lifecycle.LiveData
|
||||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
|
|
||||||
interface Room: TimelineHolder {
|
interface Room : TimelineHolder {
|
||||||
|
|
||||||
val roomId: String
|
val roomId: String
|
||||||
|
|
||||||
val myMembership: MyMembership
|
val myMembership: MyMembership
|
||||||
|
|
||||||
fun getNumberOfJoinedMembers(): Int
|
val roomSummary: LiveData<RoomSummary>
|
||||||
|
|
||||||
fun loadRoomMembersIfNeeded(): Cancelable
|
fun loadRoomMembersIfNeeded(): Cancelable
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package im.vector.matrix.android.api.session.room.model
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class RoomAvatarContent(
|
||||||
|
@Json(name = "url") val avatarUrl: String? = null
|
||||||
|
)
|
@ -2,6 +2,7 @@ package im.vector.matrix.android.api.session.room.model
|
|||||||
|
|
||||||
data class RoomSummary(
|
data class RoomSummary(
|
||||||
val roomId: String,
|
val roomId: String,
|
||||||
var displayName: String = "",
|
val displayName: String = "",
|
||||||
var topic: String = ""
|
val topic: String = "",
|
||||||
|
val avatarUrl: String = ""
|
||||||
)
|
)
|
@ -10,7 +10,8 @@ object RoomSummaryMapper {
|
|||||||
return RoomSummary(
|
return RoomSummary(
|
||||||
roomSummaryEntity.roomId,
|
roomSummaryEntity.roomId,
|
||||||
roomSummaryEntity.displayName ?: "",
|
roomSummaryEntity.displayName ?: "",
|
||||||
roomSummaryEntity.topic ?: ""
|
roomSummaryEntity.topic ?: "",
|
||||||
|
roomSummaryEntity.avatarUrl ?: ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +19,8 @@ object RoomSummaryMapper {
|
|||||||
return RoomSummaryEntity(
|
return RoomSummaryEntity(
|
||||||
roomSummary.roomId,
|
roomSummary.roomId,
|
||||||
roomSummary.displayName,
|
roomSummary.displayName,
|
||||||
roomSummary.topic
|
roomSummary.topic,
|
||||||
|
roomSummary.avatarUrl
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import io.realm.annotations.PrimaryKey
|
|||||||
// TODO to be completed
|
// TODO to be completed
|
||||||
open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||||
var displayName: String? = "",
|
var displayName: String? = "",
|
||||||
|
var avatarUrl: String? = "",
|
||||||
var topic: String? = "",
|
var topic: String? = "",
|
||||||
var lastMessage: EventEntity? = null,
|
var lastMessage: EventEntity? = null,
|
||||||
var heroes: RealmList<String> = RealmList(),
|
var heroes: RealmList<String> = RealmList(),
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package im.vector.matrix.android.internal.database.query
|
package im.vector.matrix.android.internal.database.query
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
|
||||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntityFields
|
import im.vector.matrix.android.internal.database.model.ChunkEntityFields
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||||
@ -45,13 +42,3 @@ fun RealmQuery<EventEntity>.last(from: Long? = null): EventEntity? {
|
|||||||
fun RealmList<EventEntity>.fastContains(eventEntity: EventEntity): Boolean {
|
fun RealmList<EventEntity>.fastContains(eventEntity: EventEntity): Boolean {
|
||||||
return this.where().equalTo(EventEntityFields.EVENT_ID, eventEntity.eventId).findFirst() != null
|
return this.where().equalTo(EventEntityFields.EVENT_ID, eventEntity.eventId).findFirst() != null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun EventEntity.Companion.findAllRoomMembers(realm: Realm, roomId: String): Map<String, RoomMember> {
|
|
||||||
return EventEntity
|
|
||||||
.where(realm, roomId, EventType.STATE_ROOM_MEMBER)
|
|
||||||
.sort(EventEntityFields.ORIGIN_SERVER_TS)
|
|
||||||
.findAll()
|
|
||||||
.map { it.asDomain() }
|
|
||||||
.associateBy { it.stateKey!! }
|
|
||||||
.mapValues { it.value.content<RoomMember>()!! }
|
|
||||||
}
|
|
@ -4,9 +4,10 @@ import com.zhuinden.monarchy.Monarchy
|
|||||||
import im.vector.matrix.android.api.session.room.RoomService
|
import im.vector.matrix.android.api.session.room.RoomService
|
||||||
import im.vector.matrix.android.internal.auth.data.SessionParams
|
import im.vector.matrix.android.internal.auth.data.SessionParams
|
||||||
import im.vector.matrix.android.internal.session.room.DefaultRoomService
|
import im.vector.matrix.android.internal.session.room.DefaultRoomService
|
||||||
|
import im.vector.matrix.android.internal.session.room.RoomAvatarResolver
|
||||||
|
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
|
||||||
import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
|
import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
|
||||||
import im.vector.matrix.android.internal.session.room.members.RoomMemberDisplayNameResolver
|
import im.vector.matrix.android.internal.session.room.members.RoomMemberDisplayNameResolver
|
||||||
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
|
|
||||||
import io.realm.RealmConfiguration
|
import io.realm.RealmConfiguration
|
||||||
import org.koin.dsl.context.ModuleDefinition
|
import org.koin.dsl.context.ModuleDefinition
|
||||||
import org.koin.dsl.module.Module
|
import org.koin.dsl.module.Module
|
||||||
@ -37,11 +38,15 @@ class SessionModule(private val sessionParams: SessionParams) : Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scope(DefaultSession.SCOPE) {
|
scope(DefaultSession.SCOPE) {
|
||||||
RoomDisplayNameResolver(get(), get(), sessionParams)
|
RoomDisplayNameResolver(get(), get(), sessionParams.credentials)
|
||||||
}
|
}
|
||||||
|
|
||||||
scope(DefaultSession.SCOPE) {
|
scope(DefaultSession.SCOPE) {
|
||||||
RoomSummaryUpdater(get(), get(), get())
|
RoomAvatarResolver(get(), sessionParams.credentials)
|
||||||
|
}
|
||||||
|
|
||||||
|
scope(DefaultSession.SCOPE) {
|
||||||
|
RoomSummaryUpdater(get(), get(), get(), get())
|
||||||
}
|
}
|
||||||
|
|
||||||
scope(DefaultSession.SCOPE) {
|
scope(DefaultSession.SCOPE) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package im.vector.matrix.android.internal.session.room
|
package im.vector.matrix.android.internal.session.room
|
||||||
|
|
||||||
import android.arch.lifecycle.LiveData
|
import android.arch.lifecycle.LiveData
|
||||||
|
import android.arch.lifecycle.Transformations
|
||||||
import android.arch.paging.PagedList
|
import android.arch.paging.PagedList
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
@ -9,7 +10,9 @@ import im.vector.matrix.android.api.session.room.Room
|
|||||||
import im.vector.matrix.android.api.session.room.TimelineHolder
|
import im.vector.matrix.android.api.session.room.TimelineHolder
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
@ -24,18 +27,25 @@ data class DefaultRoom(
|
|||||||
override val myMembership: MyMembership
|
override val myMembership: MyMembership
|
||||||
) : Room, KoinComponent {
|
) : Room, KoinComponent {
|
||||||
|
|
||||||
|
|
||||||
private val loadRoomMembersRequest by inject<LoadRoomMembersRequest>()
|
private val loadRoomMembersRequest by inject<LoadRoomMembersRequest>()
|
||||||
private val syncTokenStore by inject<SyncTokenStore>()
|
private val syncTokenStore by inject<SyncTokenStore>()
|
||||||
private val monarchy by inject<Monarchy>()
|
private val monarchy by inject<Monarchy>()
|
||||||
private val timelineHolder by inject<TimelineHolder>(parameters = { parametersOf(roomId) })
|
private val timelineHolder by inject<TimelineHolder>(parameters = { parametersOf(roomId) })
|
||||||
|
|
||||||
override fun liveTimeline(): LiveData<PagedList<EnrichedEvent>> {
|
override val roomSummary: LiveData<RoomSummary> by lazy {
|
||||||
return timelineHolder.liveTimeline()
|
val liveData = monarchy
|
||||||
|
.findAllMappedWithChanges(
|
||||||
|
{ realm -> RoomSummaryEntity.where(realm, roomId) },
|
||||||
|
{ from -> from.asDomain() })
|
||||||
|
|
||||||
|
Transformations.map(liveData) {
|
||||||
|
it.first()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNumberOfJoinedMembers(): Int {
|
override fun liveTimeline(): LiveData<PagedList<EnrichedEvent>> {
|
||||||
val roomSummary = monarchy.fetchAllCopiedSync { realm -> RoomSummaryEntity.where(realm, roomId) }.firstOrNull()
|
return timelineHolder.liveTimeline()
|
||||||
return roomSummary?.joinedMembersCount ?: 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadRoomMembersIfNeeded(): Cancelable {
|
override fun loadRoomMembersIfNeeded(): Cancelable {
|
||||||
@ -47,7 +57,6 @@ data class DefaultRoom(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun areAllMembersLoaded(): Boolean {
|
private fun areAllMembersLoaded(): Boolean {
|
||||||
return monarchy
|
return monarchy
|
||||||
.fetchAllCopiedSync { RoomEntity.where(it, roomId) }
|
.fetchAllCopiedSync { RoomEntity.where(it, roomId) }
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package im.vector.matrix.android.internal.session.room
|
||||||
|
|
||||||
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
|
import im.vector.matrix.android.api.session.room.Room
|
||||||
|
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomAvatarContent
|
||||||
|
import im.vector.matrix.android.internal.auth.data.Credentials
|
||||||
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||||
|
import im.vector.matrix.android.internal.database.query.last
|
||||||
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
|
import im.vector.matrix.android.internal.session.room.members.RoomMembers
|
||||||
|
|
||||||
|
internal class RoomAvatarResolver(private val monarchy: Monarchy,
|
||||||
|
private val credentials: Credentials) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the room avatar url
|
||||||
|
*
|
||||||
|
* @return the room avatar url, can be a fallback to a room member avatar or null
|
||||||
|
*/
|
||||||
|
fun resolve(room: Room): String? {
|
||||||
|
var res: String? = null
|
||||||
|
monarchy.doWithRealm { realm ->
|
||||||
|
val roomName = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_AVATAR).last()?.asDomain()
|
||||||
|
res = roomName?.content<RoomAvatarContent>()?.avatarUrl
|
||||||
|
if (!res.isNullOrEmpty()) {
|
||||||
|
return@doWithRealm
|
||||||
|
}
|
||||||
|
val roomMembers = RoomMembers(realm, room.roomId)
|
||||||
|
val members = roomMembers.getLoaded()
|
||||||
|
if (room.myMembership == MyMembership.INVITED) {
|
||||||
|
if (members.size == 1) {
|
||||||
|
res = members.entries.first().value.avatarUrl
|
||||||
|
} else if (members.size > 1) {
|
||||||
|
val firstOtherMember = members.filterKeys { it != credentials.userId }.values.firstOrNull()
|
||||||
|
res = firstOtherMember?.avatarUrl
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// detect if it is a room with no more than 2 members (i.e. an alone or a 1:1 chat)
|
||||||
|
if (roomMembers.getNumberOfJoinedMembers() == 1 && members.isNotEmpty()) {
|
||||||
|
res = members.entries.first().value.avatarUrl
|
||||||
|
} else if (roomMembers.getNumberOfMembers() == 2 && members.size > 1) {
|
||||||
|
val firstOtherMember = members.filterKeys { it != credentials.userId }.values.firstOrNull()
|
||||||
|
res = firstOtherMember?.avatarUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||||||
|
|
||||||
internal class RoomSummaryUpdater(private val monarchy: Monarchy,
|
internal class RoomSummaryUpdater(private val monarchy: Monarchy,
|
||||||
private val roomDisplayNameResolver: RoomDisplayNameResolver,
|
private val roomDisplayNameResolver: RoomDisplayNameResolver,
|
||||||
|
private val roomAvatarResolver: RoomAvatarResolver,
|
||||||
private val context: Context
|
private val context: Context
|
||||||
) : Observer<Monarchy.ManagedChangeSet<RoomEntity>> {
|
) : Observer<Monarchy.ManagedChangeSet<RoomEntity>> {
|
||||||
|
|
||||||
@ -47,23 +48,23 @@ internal class RoomSummaryUpdater(private val monarchy: Monarchy,
|
|||||||
val rooms = changeSet.realmResults.map { it.asDomain() }
|
val rooms = changeSet.realmResults.map { it.asDomain() }
|
||||||
val indexesToUpdate = changeSet.orderedCollectionChangeSet.changes + changeSet.orderedCollectionChangeSet.insertions
|
val indexesToUpdate = changeSet.orderedCollectionChangeSet.changes + changeSet.orderedCollectionChangeSet.insertions
|
||||||
monarchy.writeAsync { realm ->
|
monarchy.writeAsync { realm ->
|
||||||
insertRoomList(realm, rooms, indexesToUpdate)
|
updateRoomList(realm, rooms, indexesToUpdate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun insertRoomList(realm: Realm, rooms: List<Room>, indexes: IntArray) {
|
private fun updateRoomList(realm: Realm, rooms: List<Room>, indexes: IntArray) {
|
||||||
indexes.forEach {
|
indexes.forEach {
|
||||||
val room = rooms[it]
|
val room = rooms[it]
|
||||||
try {
|
try {
|
||||||
insertRoom(realm, room)
|
updateRoom(realm, room)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "An error occured when updating room summaries")
|
Timber.e(e, "An error occured when updating room summaries")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun insertRoom(realm: Realm, room: Room?) {
|
private fun updateRoom(realm: Realm, room: Room?) {
|
||||||
if (room == null) {
|
if (room == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -74,6 +75,7 @@ internal class RoomSummaryUpdater(private val monarchy: Monarchy,
|
|||||||
val lastTopicEvent = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_TOPIC).last()?.asDomain()
|
val lastTopicEvent = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_TOPIC).last()?.asDomain()
|
||||||
|
|
||||||
roomSummary.displayName = roomDisplayNameResolver.resolve(context, room).toString()
|
roomSummary.displayName = roomDisplayNameResolver.resolve(context, room).toString()
|
||||||
|
roomSummary.avatarUrl = roomAvatarResolver.resolve(room)
|
||||||
roomSummary.topic = lastTopicEvent?.content<RoomTopicContent>()?.topic
|
roomSummary.topic = lastTopicEvent?.content<RoomTopicContent>()?.topic
|
||||||
roomSummary.lastMessage = lastMessageEvent
|
roomSummary.lastMessage = lastMessageEvent
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,7 @@ 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.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
import im.vector.matrix.android.internal.database.query.findAllRoomMembers
|
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.network.executeRequest
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||||
@ -63,7 +61,7 @@ internal class LoadRoomMembersRequest(private val roomAPI: RoomAPI,
|
|||||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||||
?: throw IllegalStateException("You shouldn't use this method without a room")
|
?: throw IllegalStateException("You shouldn't use this method without a room")
|
||||||
|
|
||||||
val roomMembers = EventEntity.findAllRoomMembers(realm, roomId)
|
val roomMembers = RoomMembers(realm, roomId).getLoaded()
|
||||||
val eventsToInsert = response.roomMemberEvents.filter { !roomMembers.containsKey(it.stateKey) }
|
val eventsToInsert = response.roomMemberEvents.filter { !roomMembers.containsKey(it.stateKey) }
|
||||||
|
|
||||||
val chunk = stateEventsChunkHandler.handle(realm, roomId, eventsToInsert)
|
val chunk = stateEventsChunkHandler.handle(realm, roomId, eventsToInsert)
|
||||||
|
@ -25,20 +25,19 @@ import im.vector.matrix.android.api.session.room.model.MyMembership
|
|||||||
import im.vector.matrix.android.api.session.room.model.RoomAliasesContent
|
import im.vector.matrix.android.api.session.room.model.RoomAliasesContent
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomCanonicalAliasContent
|
import im.vector.matrix.android.api.session.room.model.RoomCanonicalAliasContent
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomNameContent
|
import im.vector.matrix.android.api.session.room.model.RoomNameContent
|
||||||
import im.vector.matrix.android.internal.auth.data.SessionParams
|
import im.vector.matrix.android.internal.auth.data.Credentials
|
||||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||||
import im.vector.matrix.android.internal.database.query.findAllRoomMembers
|
|
||||||
import im.vector.matrix.android.internal.database.query.last
|
import im.vector.matrix.android.internal.database.query.last
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class computes room display name
|
* This class computes room display name
|
||||||
*/
|
*/
|
||||||
class RoomDisplayNameResolver(private val monarchy: Monarchy,
|
internal class RoomDisplayNameResolver(private val monarchy: Monarchy,
|
||||||
private val roomMemberDisplayNameResolver: RoomMemberDisplayNameResolver,
|
private val roomMemberDisplayNameResolver: RoomMemberDisplayNameResolver,
|
||||||
private val sessionParams: SessionParams
|
private val credentials: Credentials
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,9 +74,9 @@ class RoomDisplayNameResolver(private val monarchy: Monarchy,
|
|||||||
return@doWithRealm
|
return@doWithRealm
|
||||||
}
|
}
|
||||||
|
|
||||||
val otherRoomMembers = EventEntity
|
val roomMembers = RoomMembers(realm, room.roomId)
|
||||||
.findAllRoomMembers(realm, room.roomId)
|
val otherRoomMembers = roomMembers.getLoaded()
|
||||||
.filterKeys { it != sessionParams.credentials.userId }
|
.filterKeys { it != credentials.userId }
|
||||||
|
|
||||||
if (room.myMembership == MyMembership.INVITED) {
|
if (room.myMembership == MyMembership.INVITED) {
|
||||||
//TODO handle invited
|
//TODO handle invited
|
||||||
@ -117,9 +116,9 @@ class RoomDisplayNameResolver(private val monarchy: Monarchy,
|
|||||||
else -> {
|
else -> {
|
||||||
val member = memberIds[0]
|
val member = memberIds[0]
|
||||||
name = context.resources.getQuantityString(R.plurals.room_displayname_three_and_more_members,
|
name = context.resources.getQuantityString(R.plurals.room_displayname_three_and_more_members,
|
||||||
room.getNumberOfJoinedMembers() - 1,
|
roomMembers.getNumberOfJoinedMembers() - 1,
|
||||||
roomMemberDisplayNameResolver.resolve(member, otherRoomMembers),
|
roomMemberDisplayNameResolver.resolve(member, otherRoomMembers),
|
||||||
room.getNumberOfJoinedMembers() - 1)
|
roomMembers.getNumberOfJoinedMembers() - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package im.vector.matrix.android.internal.session.room.members
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||||
|
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||||
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
|
import io.realm.Realm
|
||||||
|
|
||||||
|
internal class RoomMembers(private val realm: Realm,
|
||||||
|
private val roomId: String
|
||||||
|
) {
|
||||||
|
|
||||||
|
private val roomSummary: RoomSummaryEntity? by lazy {
|
||||||
|
RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLoaded(): Map<String, RoomMember> {
|
||||||
|
return EventEntity
|
||||||
|
.where(realm, roomId, EventType.STATE_ROOM_MEMBER)
|
||||||
|
.sort(EventEntityFields.ORIGIN_SERVER_TS)
|
||||||
|
.findAll()
|
||||||
|
.map { it.asDomain() }
|
||||||
|
.associateBy { it.stateKey!! }
|
||||||
|
.mapValues { it.value.content<RoomMember>()!! }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getNumberOfJoinedMembers(): Int {
|
||||||
|
return roomSummary?.joinedMembersCount
|
||||||
|
?: getLoaded().filterValues { it.membership == Membership.JOIN }.size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNumberOfInvitedMembers(): Int {
|
||||||
|
return roomSummary?.invitedMembersCount
|
||||||
|
?: getLoaded().filterValues { it.membership == Membership.INVITE }.size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNumberOfMembers(): Int {
|
||||||
|
return getNumberOfJoinedMembers() + getNumberOfInvitedMembers()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -63,9 +63,6 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
|||||||
|
|
||||||
roomEntity.membership = MyMembership.JOINED
|
roomEntity.membership = MyMembership.JOINED
|
||||||
|
|
||||||
if (roomSync.summary != null) {
|
|
||||||
handleRoomSummary(realm, roomId, roomSync.summary)
|
|
||||||
}
|
|
||||||
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
|
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
|
||||||
val chunkEntity = stateEventsChunkHandler.handle(realm, roomId, roomSync.state.events)
|
val chunkEntity = stateEventsChunkHandler.handle(realm, roomId, roomSync.state.events)
|
||||||
if (!roomEntity.chunks.contains(chunkEntity)) {
|
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||||
@ -78,6 +75,9 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
|||||||
roomEntity.chunks.add(chunkEntity)
|
roomEntity.chunks.add(chunkEntity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (roomSync.summary != null) {
|
||||||
|
handleRoomSummary(realm, roomId, roomSync.summary)
|
||||||
|
}
|
||||||
return roomEntity
|
return roomEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user