forked from GitHub-Mirror/riotX-android
Room list & event : decouple notice events formatting to be used within room controller
This commit is contained in:
parent
9f9f4c0755
commit
b9d76f5047
@ -20,6 +20,7 @@ import com.squareup.moshi.Json
|
|||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import com.squareup.moshi.Types
|
import com.squareup.moshi.Types
|
||||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||||
|
import timber.log.Timber
|
||||||
import java.lang.reflect.ParameterizedType
|
import java.lang.reflect.ParameterizedType
|
||||||
|
|
||||||
typealias Content = Map<String, @JvmSuppressWildcards Any>
|
typealias Content = Map<String, @JvmSuppressWildcards Any>
|
||||||
@ -27,11 +28,20 @@ typealias Content = Map<String, @JvmSuppressWildcards Any>
|
|||||||
/**
|
/**
|
||||||
* This methods is a facility method to map a json content to a model.
|
* This methods is a facility method to map a json content to a model.
|
||||||
*/
|
*/
|
||||||
inline fun <reified T> Content?.toModel(): T? {
|
inline fun <reified T> Content?.toModel(catchError: Boolean = true): T? {
|
||||||
return this?.let {
|
return this?.let {
|
||||||
val moshi = MoshiProvider.providesMoshi()
|
val moshi = MoshiProvider.providesMoshi()
|
||||||
val moshiAdapter = moshi.adapter(T::class.java)
|
val moshiAdapter = moshi.adapter(T::class.java)
|
||||||
return moshiAdapter.fromJsonValue(it)
|
return try {
|
||||||
|
moshiAdapter.fromJsonValue(it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
if (catchError) {
|
||||||
|
Timber.e(e, "To model failed : $e")
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,11 +25,16 @@ import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserControl
|
|||||||
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter
|
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter
|
||||||
import im.vector.riotredesign.features.home.group.GroupSummaryController
|
import im.vector.riotredesign.features.home.group.GroupSummaryController
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.*
|
import im.vector.riotredesign.features.home.room.detail.timeline.factory.DefaultItemFactory
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.factory.MessageItemFactory
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.factory.NoticeItemFactory
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.factory.TimelineItemFactory
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
||||||
import im.vector.riotredesign.features.home.room.list.RoomSummaryController
|
import im.vector.riotredesign.features.home.room.list.RoomSummaryController
|
||||||
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
||||||
|
import org.koin.core.parameter.parametersOf
|
||||||
import org.koin.dsl.module.module
|
import org.koin.dsl.module.module
|
||||||
|
|
||||||
class HomeModule {
|
class HomeModule {
|
||||||
@ -37,8 +42,6 @@ class HomeModule {
|
|||||||
companion object {
|
companion object {
|
||||||
const val HOME_SCOPE = "HOME_SCOPE"
|
const val HOME_SCOPE = "HOME_SCOPE"
|
||||||
const val ROOM_DETAIL_SCOPE = "ROOM_DETAIL_SCOPE"
|
const val ROOM_DETAIL_SCOPE = "ROOM_DETAIL_SCOPE"
|
||||||
const val ROOM_LIST_SCOPE = "ROOM_LIST_SCOPE"
|
|
||||||
const val GROUP_LIST_SCOPE = "GROUP_LIST_SCOPE"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val definition = module {
|
val definition = module {
|
||||||
@ -59,26 +62,26 @@ class HomeModule {
|
|||||||
TimelineDateFormatter(get())
|
TimelineDateFormatter(get())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
factory {
|
||||||
|
NoticeEventFormatter(get())
|
||||||
|
}
|
||||||
|
|
||||||
factory { (fragment: Fragment) ->
|
factory { (fragment: Fragment) ->
|
||||||
val eventHtmlRenderer = EventHtmlRenderer(GlideApp.with(fragment), fragment.requireContext(), get())
|
val eventHtmlRenderer = EventHtmlRenderer(GlideApp.with(fragment), fragment.requireContext(), get())
|
||||||
|
val noticeEventFormatter = get<NoticeEventFormatter>(parameters = { parametersOf(fragment) })
|
||||||
val timelineMediaSizeProvider = TimelineMediaSizeProvider()
|
val timelineMediaSizeProvider = TimelineMediaSizeProvider()
|
||||||
val colorProvider = ColorProvider(fragment.requireContext())
|
val colorProvider = get<ColorProvider>()
|
||||||
val timelineDateFormatter = get<TimelineDateFormatter>()
|
val timelineDateFormatter = get<TimelineDateFormatter>()
|
||||||
val messageItemFactory = MessageItemFactory(colorProvider, timelineMediaSizeProvider, timelineDateFormatter, eventHtmlRenderer)
|
|
||||||
|
|
||||||
val timelineItemFactory = TimelineItemFactory(messageItemFactory = messageItemFactory,
|
val timelineItemFactory = TimelineItemFactory(messageItemFactory = MessageItemFactory(colorProvider, timelineMediaSizeProvider, timelineDateFormatter, eventHtmlRenderer),
|
||||||
roomNameItemFactory = RoomNameItemFactory(get()),
|
noticeItemFactory = NoticeItemFactory(noticeEventFormatter),
|
||||||
roomTopicItemFactory = RoomTopicItemFactory(get()),
|
defaultItemFactory = DefaultItemFactory()
|
||||||
roomMemberItemFactory = RoomMemberItemFactory(get()),
|
|
||||||
roomHistoryVisibilityItemFactory = RoomHistoryVisibilityItemFactory(get()),
|
|
||||||
callItemFactory = CallItemFactory(get()),
|
|
||||||
defaultItemFactory = DefaultItemFactory()
|
|
||||||
)
|
)
|
||||||
TimelineEventController(timelineDateFormatter, timelineItemFactory, timelineMediaSizeProvider)
|
TimelineEventController(timelineDateFormatter, timelineItemFactory, timelineMediaSizeProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
factory {
|
factory {
|
||||||
RoomSummaryController(get(), get())
|
RoomSummaryController(get(), get(), get())
|
||||||
}
|
}
|
||||||
|
|
||||||
factory {
|
factory {
|
||||||
|
@ -48,7 +48,6 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback
|
|||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
bindScope(getOrCreateScope(HomeModule.GROUP_LIST_SCOPE))
|
|
||||||
groupController.callback = this
|
groupController.callback = this
|
||||||
stateView.contentView = epoxyRecyclerView
|
stateView.contentView = epoxyRecyclerView
|
||||||
epoxyRecyclerView.setController(groupController)
|
epoxyRecyclerView.setController(groupController)
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.riotredesign.features.home.room.detail.timeline.factory
|
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
|
||||||
import im.vector.matrix.android.api.session.room.model.call.CallInviteContent
|
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
|
||||||
import im.vector.riotredesign.R
|
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
|
||||||
|
|
||||||
class CallItemFactory(private val stringProvider: StringProvider) {
|
|
||||||
|
|
||||||
fun create(event: TimelineEvent): NoticeItem? {
|
|
||||||
val text = buildNoticeText(event.root, event.senderName) ?: return null
|
|
||||||
return NoticeItem_()
|
|
||||||
.noticeText(text)
|
|
||||||
.avatarUrl(event.senderAvatar)
|
|
||||||
.memberName(event.senderName)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildNoticeText(event: Event, senderName: String?): CharSequence? {
|
|
||||||
return when {
|
|
||||||
EventType.CALL_INVITE == event.type -> {
|
|
||||||
val content = event.content.toModel<CallInviteContent>() ?: return null
|
|
||||||
val isVideoCall = content.offer.sdp == CallInviteContent.Offer.SDP_VIDEO
|
|
||||||
return if (isVideoCall) {
|
|
||||||
stringProvider.getString(R.string.notice_placed_video_call, senderName)
|
|
||||||
} else {
|
|
||||||
stringProvider.getString(R.string.notice_placed_voice_call, senderName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EventType.CALL_ANSWER == event.type -> stringProvider.getString(R.string.notice_answered_call, senderName)
|
|
||||||
EventType.CALL_HANGUP == event.type -> stringProvider.getString(R.string.notice_ended_call, senderName)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -16,28 +16,24 @@
|
|||||||
|
|
||||||
package im.vector.riotredesign.features.home.room.detail.timeline.factory
|
package im.vector.riotredesign.features.home.room.detail.timeline.factory
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomTopicContent
|
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
||||||
|
|
||||||
class RoomTopicItemFactory(private val stringProvider: StringProvider) {
|
class NoticeItemFactory(private val eventFormatter: NoticeEventFormatter) {
|
||||||
|
|
||||||
fun create(event: TimelineEvent): NoticeItem? {
|
fun create(event: TimelineEvent): NoticeItem? {
|
||||||
|
val formattedText = eventFormatter.format(event) ?: return null
|
||||||
|
val senderName = event.senderName()
|
||||||
|
val senderAvatar = event.senderAvatar()
|
||||||
|
|
||||||
val content: RoomTopicContent = event.root.content.toModel() ?: return null
|
|
||||||
val text = if (content.topic.isNullOrEmpty()) {
|
|
||||||
stringProvider.getString(R.string.notice_room_topic_removed, event.senderName)
|
|
||||||
} else {
|
|
||||||
stringProvider.getString(R.string.notice_room_topic_changed, event.senderName, content.topic)
|
|
||||||
}
|
|
||||||
return NoticeItem_()
|
return NoticeItem_()
|
||||||
.noticeText(text)
|
.noticeText(formattedText)
|
||||||
.avatarUrl(event.senderAvatar)
|
.avatarUrl(senderAvatar)
|
||||||
.memberName(event.senderName)
|
.memberName(senderName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.riotredesign.features.home.room.detail.timeline.factory
|
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibilityContent
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
|
||||||
import im.vector.riotredesign.R
|
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
|
||||||
|
|
||||||
|
|
||||||
class RoomHistoryVisibilityItemFactory(private val stringProvider: StringProvider) {
|
|
||||||
|
|
||||||
fun create(event: TimelineEvent): NoticeItem? {
|
|
||||||
val noticeText = buildNoticeText(event.root, event.senderName) ?: return null
|
|
||||||
return NoticeItem_()
|
|
||||||
.noticeText(noticeText)
|
|
||||||
.avatarUrl(event.senderAvatar)
|
|
||||||
.memberName(event.senderName)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildNoticeText(event: Event, senderName: String?): CharSequence? {
|
|
||||||
val content = event.content.toModel<RoomHistoryVisibilityContent>() ?: return null
|
|
||||||
val formattedVisibility = when (content.historyVisibility) {
|
|
||||||
RoomHistoryVisibility.SHARED -> stringProvider.getString(R.string.notice_room_visibility_shared)
|
|
||||||
RoomHistoryVisibility.INVITED -> stringProvider.getString(R.string.notice_room_visibility_invited)
|
|
||||||
RoomHistoryVisibility.JOINED -> stringProvider.getString(R.string.notice_room_visibility_joined)
|
|
||||||
RoomHistoryVisibility.WORLD_READABLE -> stringProvider.getString(R.string.notice_room_visibility_world_readable)
|
|
||||||
}
|
|
||||||
return stringProvider.getString(R.string.notice_made_future_room_visibility, senderName, formattedVisibility)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.riotredesign.features.home.room.detail.timeline.factory
|
|
||||||
|
|
||||||
import android.text.TextUtils
|
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
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.api.session.room.timeline.TimelineEvent
|
|
||||||
import im.vector.riotredesign.R
|
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.RoomMemberEventHelper
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
|
||||||
|
|
||||||
|
|
||||||
//TODO : complete with call membership events¬
|
|
||||||
class RoomMemberItemFactory(private val stringProvider: StringProvider) {
|
|
||||||
|
|
||||||
fun create(event: TimelineEvent): NoticeItem? {
|
|
||||||
val eventContent: RoomMember? = event.root.content.toModel()
|
|
||||||
val prevEventContent: RoomMember? = event.root.prevContent.toModel()
|
|
||||||
val noticeText = buildRoomMemberNotice(event, eventContent, prevEventContent) ?: return null
|
|
||||||
val senderAvatar = RoomMemberEventHelper.senderAvatar(eventContent, prevEventContent, event)
|
|
||||||
val senderName = RoomMemberEventHelper.senderName(eventContent, prevEventContent, event)
|
|
||||||
|
|
||||||
return NoticeItem_()
|
|
||||||
.userId(event.root.sender ?: "")
|
|
||||||
.noticeText(noticeText)
|
|
||||||
.avatarUrl(senderAvatar)
|
|
||||||
.memberName(senderName)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildRoomMemberNotice(event: TimelineEvent, eventContent: RoomMember?, prevEventContent: RoomMember?): String? {
|
|
||||||
val isMembershipEvent = prevEventContent?.membership != eventContent?.membership
|
|
||||||
return if (isMembershipEvent) {
|
|
||||||
buildMembershipNotice(event, eventContent, prevEventContent)
|
|
||||||
} else {
|
|
||||||
buildProfileNotice(event, eventContent, prevEventContent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildProfileNotice(event: TimelineEvent, eventContent: RoomMember?, prevEventContent: RoomMember?): String? {
|
|
||||||
val displayText = StringBuilder()
|
|
||||||
// Check display name has been changed
|
|
||||||
if (!TextUtils.equals(eventContent?.displayName, prevEventContent?.displayName)) {
|
|
||||||
val displayNameText = when {
|
|
||||||
prevEventContent?.displayName.isNullOrEmpty() ->
|
|
||||||
stringProvider.getString(R.string.notice_display_name_set, event.root.sender, eventContent?.displayName)
|
|
||||||
eventContent?.displayName.isNullOrEmpty() ->
|
|
||||||
stringProvider.getString(R.string.notice_display_name_removed, event.root.sender, prevEventContent?.displayName)
|
|
||||||
else ->
|
|
||||||
stringProvider.getString(R.string.notice_display_name_changed_from,
|
|
||||||
event.root.sender, prevEventContent?.displayName, eventContent?.displayName)
|
|
||||||
}
|
|
||||||
displayText.append(displayNameText)
|
|
||||||
}
|
|
||||||
// Check whether the avatar has been changed
|
|
||||||
if (!TextUtils.equals(eventContent?.avatarUrl, prevEventContent?.avatarUrl)) {
|
|
||||||
val displayAvatarText = if (displayText.isNotEmpty()) {
|
|
||||||
displayText.append(" ")
|
|
||||||
stringProvider.getString(R.string.notice_avatar_changed_too)
|
|
||||||
} else {
|
|
||||||
stringProvider.getString(R.string.notice_avatar_url_changed, event.senderName)
|
|
||||||
}
|
|
||||||
displayText.append(displayAvatarText)
|
|
||||||
}
|
|
||||||
return displayText.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildMembershipNotice(event: TimelineEvent, eventContent: RoomMember?, prevEventContent: RoomMember?): String? {
|
|
||||||
val senderDisplayName = event.senderName ?: event.root.sender
|
|
||||||
val targetDisplayName = eventContent?.displayName ?: event.root.sender
|
|
||||||
return when {
|
|
||||||
Membership.INVITE == eventContent?.membership -> {
|
|
||||||
// TODO get userId
|
|
||||||
val selfUserId = ""
|
|
||||||
when {
|
|
||||||
eventContent.thirdPartyInvite != null ->
|
|
||||||
stringProvider.getString(R.string.notice_room_third_party_registered_invite,
|
|
||||||
targetDisplayName, eventContent.thirdPartyInvite?.displayName)
|
|
||||||
TextUtils.equals(event.root.stateKey, selfUserId) ->
|
|
||||||
stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName)
|
|
||||||
event.root.stateKey.isNullOrEmpty() ->
|
|
||||||
stringProvider.getString(R.string.notice_room_invite_no_invitee, senderDisplayName)
|
|
||||||
else ->
|
|
||||||
stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Membership.JOIN == eventContent?.membership ->
|
|
||||||
stringProvider.getString(R.string.notice_room_join, senderDisplayName)
|
|
||||||
Membership.LEAVE == eventContent?.membership ->
|
|
||||||
// 2 cases here: this member may have left voluntarily or they may have been "left" by someone else ie. kicked
|
|
||||||
return if (TextUtils.equals(event.root.sender, event.root.stateKey)) {
|
|
||||||
if (prevEventContent?.membership == Membership.INVITE) {
|
|
||||||
stringProvider.getString(R.string.notice_room_reject, senderDisplayName)
|
|
||||||
} else {
|
|
||||||
val leftDisplayName = RoomMemberEventHelper.senderName(eventContent, prevEventContent, event)
|
|
||||||
stringProvider.getString(R.string.notice_room_leave, leftDisplayName)
|
|
||||||
}
|
|
||||||
} else if (prevEventContent?.membership == Membership.INVITE) {
|
|
||||||
stringProvider.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName)
|
|
||||||
} else if (prevEventContent?.membership == Membership.JOIN) {
|
|
||||||
stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName)
|
|
||||||
} else if (prevEventContent?.membership == Membership.BAN) {
|
|
||||||
stringProvider.getString(R.string.notice_room_unban, senderDisplayName, targetDisplayName)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
Membership.BAN == eventContent?.membership ->
|
|
||||||
stringProvider.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName)
|
|
||||||
Membership.KNOCK == eventContent?.membership ->
|
|
||||||
stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.riotredesign.features.home.room.detail.timeline.factory
|
|
||||||
|
|
||||||
import android.text.TextUtils
|
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomNameContent
|
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
|
||||||
import im.vector.riotredesign.R
|
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
|
||||||
|
|
||||||
class RoomNameItemFactory(private val stringProvider: StringProvider) {
|
|
||||||
|
|
||||||
fun create(event: TimelineEvent): NoticeItem? {
|
|
||||||
|
|
||||||
val content: RoomNameContent = event.root.content.toModel() ?: return null
|
|
||||||
val text = if (!TextUtils.isEmpty(content.name)) {
|
|
||||||
stringProvider.getString(R.string.notice_room_name_changed, event.senderName, content.name)
|
|
||||||
} else {
|
|
||||||
stringProvider.getString(R.string.notice_room_name_removed, event.senderName)
|
|
||||||
}
|
|
||||||
return NoticeItem_()
|
|
||||||
.noticeText(text)
|
|
||||||
.avatarUrl(event.senderAvatar)
|
|
||||||
.memberName(event.senderName)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -23,11 +23,7 @@ import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
|||||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
||||||
|
|
||||||
class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,
|
class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,
|
||||||
private val roomNameItemFactory: RoomNameItemFactory,
|
private val noticeItemFactory: NoticeItemFactory,
|
||||||
private val roomTopicItemFactory: RoomTopicItemFactory,
|
|
||||||
private val roomMemberItemFactory: RoomMemberItemFactory,
|
|
||||||
private val roomHistoryVisibilityItemFactory: RoomHistoryVisibilityItemFactory,
|
|
||||||
private val callItemFactory: CallItemFactory,
|
|
||||||
private val defaultItemFactory: DefaultItemFactory) {
|
private val defaultItemFactory: DefaultItemFactory) {
|
||||||
|
|
||||||
fun create(event: TimelineEvent,
|
fun create(event: TimelineEvent,
|
||||||
@ -36,23 +32,22 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,
|
|||||||
|
|
||||||
val computedModel = try {
|
val computedModel = try {
|
||||||
when (event.root.type) {
|
when (event.root.type) {
|
||||||
EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, callback)
|
EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, callback)
|
||||||
EventType.STATE_ROOM_NAME -> roomNameItemFactory.create(event)
|
|
||||||
EventType.STATE_ROOM_TOPIC -> roomTopicItemFactory.create(event)
|
|
||||||
EventType.STATE_ROOM_MEMBER -> roomMemberItemFactory.create(event)
|
|
||||||
EventType.STATE_HISTORY_VISIBILITY -> roomHistoryVisibilityItemFactory.create(event)
|
|
||||||
|
|
||||||
|
EventType.STATE_ROOM_NAME,
|
||||||
|
EventType.STATE_ROOM_TOPIC,
|
||||||
|
EventType.STATE_ROOM_MEMBER,
|
||||||
|
EventType.STATE_HISTORY_VISIBILITY,
|
||||||
EventType.CALL_INVITE,
|
EventType.CALL_INVITE,
|
||||||
EventType.CALL_HANGUP,
|
EventType.CALL_HANGUP,
|
||||||
EventType.CALL_ANSWER -> callItemFactory.create(event)
|
EventType.CALL_ANSWER -> noticeItemFactory.create(event)
|
||||||
|
|
||||||
EventType.ENCRYPTED,
|
EventType.ENCRYPTED,
|
||||||
EventType.ENCRYPTION,
|
EventType.ENCRYPTION,
|
||||||
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
||||||
EventType.STICKER,
|
EventType.STICKER,
|
||||||
EventType.STATE_ROOM_CREATE -> defaultItemFactory.create(event)
|
EventType.STATE_ROOM_CREATE -> defaultItemFactory.create(event)
|
||||||
|
else -> null
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
defaultItemFactory.create(event, e)
|
defaultItemFactory.create(event, e)
|
||||||
|
@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* 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.riotredesign.features.home.room.detail.timeline.format
|
||||||
|
|
||||||
|
import android.text.TextUtils
|
||||||
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibilityContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomNameContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomTopicContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.call.CallInviteContent
|
||||||
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
class NoticeEventFormatter(private val stringProvider: StringProvider) {
|
||||||
|
|
||||||
|
fun format(timelineEvent: TimelineEvent): CharSequence? {
|
||||||
|
return when (timelineEvent.root.type) {
|
||||||
|
EventType.STATE_ROOM_NAME -> formatRoomNameEvent(timelineEvent.root, timelineEvent.senderName)
|
||||||
|
EventType.STATE_ROOM_TOPIC -> formatRoomTopicEvent(timelineEvent.root, timelineEvent.senderName)
|
||||||
|
EventType.STATE_ROOM_MEMBER -> formatRoomMemberEvent(timelineEvent.root, timelineEvent.senderName())
|
||||||
|
EventType.STATE_HISTORY_VISIBILITY -> formatRoomHistoryVisibilityEvent(timelineEvent.root, timelineEvent.senderName)
|
||||||
|
EventType.CALL_INVITE,
|
||||||
|
EventType.CALL_HANGUP,
|
||||||
|
EventType.CALL_ANSWER -> formatCallEvent(timelineEvent.root, timelineEvent.senderName)
|
||||||
|
else -> {
|
||||||
|
Timber.v("Type ${timelineEvent.root.type} not handled by this formatter")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatRoomNameEvent(event: Event, senderName: String?): CharSequence? {
|
||||||
|
val content = event.content.toModel<RoomNameContent>() ?: return null
|
||||||
|
return if (!TextUtils.isEmpty(content.name)) {
|
||||||
|
stringProvider.getString(R.string.notice_room_name_changed, senderName, content.name)
|
||||||
|
} else {
|
||||||
|
stringProvider.getString(R.string.notice_room_name_removed, senderName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatRoomTopicEvent(event: Event, senderName: String?): CharSequence? {
|
||||||
|
val content = event.content.toModel<RoomTopicContent>() ?: return null
|
||||||
|
return if (content.topic.isNullOrEmpty()) {
|
||||||
|
stringProvider.getString(R.string.notice_room_topic_removed, senderName)
|
||||||
|
} else {
|
||||||
|
stringProvider.getString(R.string.notice_room_topic_changed, senderName, content.topic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatRoomHistoryVisibilityEvent(event: Event, senderName: String?): CharSequence? {
|
||||||
|
val content = event.content.toModel<RoomHistoryVisibilityContent>() ?: return null
|
||||||
|
val formattedVisibility = when (content.historyVisibility) {
|
||||||
|
RoomHistoryVisibility.SHARED -> stringProvider.getString(R.string.notice_room_visibility_shared)
|
||||||
|
RoomHistoryVisibility.INVITED -> stringProvider.getString(R.string.notice_room_visibility_invited)
|
||||||
|
RoomHistoryVisibility.JOINED -> stringProvider.getString(R.string.notice_room_visibility_joined)
|
||||||
|
RoomHistoryVisibility.WORLD_READABLE -> stringProvider.getString(R.string.notice_room_visibility_world_readable)
|
||||||
|
}
|
||||||
|
return stringProvider.getString(R.string.notice_made_future_room_visibility, senderName, formattedVisibility)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatCallEvent(event: Event, senderName: String?): CharSequence? {
|
||||||
|
return when {
|
||||||
|
EventType.CALL_INVITE == event.type -> {
|
||||||
|
val content = event.content.toModel<CallInviteContent>() ?: return null
|
||||||
|
val isVideoCall = content.offer.sdp == CallInviteContent.Offer.SDP_VIDEO
|
||||||
|
return if (isVideoCall) {
|
||||||
|
stringProvider.getString(R.string.notice_placed_video_call, senderName)
|
||||||
|
} else {
|
||||||
|
stringProvider.getString(R.string.notice_placed_voice_call, senderName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EventType.CALL_ANSWER == event.type -> stringProvider.getString(R.string.notice_answered_call, senderName)
|
||||||
|
EventType.CALL_HANGUP == event.type -> stringProvider.getString(R.string.notice_ended_call, senderName)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatRoomMemberEvent(event: Event, senderName: String?): String? {
|
||||||
|
val eventContent: RoomMember? = event.content.toModel()
|
||||||
|
val prevEventContent: RoomMember? = event.prevContent.toModel()
|
||||||
|
val isMembershipEvent = prevEventContent?.membership != eventContent?.membership
|
||||||
|
return if (isMembershipEvent) {
|
||||||
|
buildMembershipNotice(event, senderName, eventContent, prevEventContent)
|
||||||
|
} else {
|
||||||
|
buildProfileNotice(event, senderName, eventContent, prevEventContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildProfileNotice(event: Event, senderName: String?, eventContent: RoomMember?, prevEventContent: RoomMember?): String? {
|
||||||
|
val displayText = StringBuilder()
|
||||||
|
// Check display name has been changed
|
||||||
|
if (!TextUtils.equals(eventContent?.displayName, prevEventContent?.displayName)) {
|
||||||
|
val displayNameText = when {
|
||||||
|
prevEventContent?.displayName.isNullOrEmpty() ->
|
||||||
|
stringProvider.getString(R.string.notice_display_name_set, event.sender, eventContent?.displayName)
|
||||||
|
eventContent?.displayName.isNullOrEmpty() ->
|
||||||
|
stringProvider.getString(R.string.notice_display_name_removed, event.sender, prevEventContent?.displayName)
|
||||||
|
else ->
|
||||||
|
stringProvider.getString(R.string.notice_display_name_changed_from,
|
||||||
|
event.sender, prevEventContent?.displayName, eventContent?.displayName)
|
||||||
|
}
|
||||||
|
displayText.append(displayNameText)
|
||||||
|
}
|
||||||
|
// Check whether the avatar has been changed
|
||||||
|
if (!TextUtils.equals(eventContent?.avatarUrl, prevEventContent?.avatarUrl)) {
|
||||||
|
val displayAvatarText = if (displayText.isNotEmpty()) {
|
||||||
|
displayText.append(" ")
|
||||||
|
stringProvider.getString(R.string.notice_avatar_changed_too)
|
||||||
|
} else {
|
||||||
|
stringProvider.getString(R.string.notice_avatar_url_changed, senderName)
|
||||||
|
}
|
||||||
|
displayText.append(displayAvatarText)
|
||||||
|
}
|
||||||
|
return displayText.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildMembershipNotice(event: Event, senderName: String?, eventContent: RoomMember?, prevEventContent: RoomMember?): String? {
|
||||||
|
val senderDisplayName = senderName ?: event.sender
|
||||||
|
val targetDisplayName = eventContent?.displayName ?: event.sender
|
||||||
|
return when {
|
||||||
|
Membership.INVITE == eventContent?.membership -> {
|
||||||
|
// TODO get userId
|
||||||
|
val selfUserId = ""
|
||||||
|
when {
|
||||||
|
eventContent.thirdPartyInvite != null ->
|
||||||
|
stringProvider.getString(R.string.notice_room_third_party_registered_invite,
|
||||||
|
targetDisplayName, eventContent.thirdPartyInvite?.displayName)
|
||||||
|
TextUtils.equals(event.stateKey, selfUserId) ->
|
||||||
|
stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName)
|
||||||
|
event.stateKey.isNullOrEmpty() ->
|
||||||
|
stringProvider.getString(R.string.notice_room_invite_no_invitee, senderDisplayName)
|
||||||
|
else ->
|
||||||
|
stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Membership.JOIN == eventContent?.membership ->
|
||||||
|
stringProvider.getString(R.string.notice_room_join, senderDisplayName)
|
||||||
|
Membership.LEAVE == eventContent?.membership ->
|
||||||
|
// 2 cases here: this member may have left voluntarily or they may have been "left" by someone else ie. kicked
|
||||||
|
return if (TextUtils.equals(event.sender, event.stateKey)) {
|
||||||
|
if (prevEventContent?.membership == Membership.INVITE) {
|
||||||
|
stringProvider.getString(R.string.notice_room_reject, senderDisplayName)
|
||||||
|
} else {
|
||||||
|
stringProvider.getString(R.string.notice_room_leave, senderDisplayName)
|
||||||
|
}
|
||||||
|
} else if (prevEventContent?.membership == Membership.INVITE) {
|
||||||
|
stringProvider.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName)
|
||||||
|
} else if (prevEventContent?.membership == Membership.JOIN) {
|
||||||
|
stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName)
|
||||||
|
} else if (prevEventContent?.membership == Membership.BAN) {
|
||||||
|
stringProvider.getString(R.string.notice_room_unban, senderDisplayName, targetDisplayName)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
Membership.BAN == eventContent?.membership ->
|
||||||
|
stringProvider.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName)
|
||||||
|
Membership.KNOCK == eventContent?.membership ->
|
||||||
|
stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,25 +16,11 @@
|
|||||||
|
|
||||||
package im.vector.riotredesign.features.home.room.detail.timeline.helper
|
package im.vector.riotredesign.features.home.room.detail.timeline.helper
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
|
|
||||||
object RoomMemberEventHelper {
|
object RoomMemberEventHelper {
|
||||||
|
|
||||||
fun senderAvatar(eventContent: RoomMember?, prevEventContent: RoomMember?, event: TimelineEvent): String? {
|
|
||||||
return if (eventContent?.membership == Membership.LEAVE && eventContent.avatarUrl == null && prevEventContent?.avatarUrl != null) {
|
|
||||||
prevEventContent.avatarUrl
|
|
||||||
} else {
|
|
||||||
event.senderAvatar
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun senderName(eventContent: RoomMember?, prevEventContent: RoomMember?, event: TimelineEvent): String? {
|
|
||||||
return if (eventContent?.membership == Membership.LEAVE && eventContent.displayName == null && prevEventContent?.displayName != null) {
|
|
||||||
prevEventContent.displayName
|
|
||||||
} else {
|
|
||||||
event.senderName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -17,6 +17,8 @@
|
|||||||
package im.vector.riotredesign.features.home.room.detail.timeline.helper
|
package im.vector.riotredesign.features.home.room.detail.timeline.helper
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.riotredesign.core.extensions.localDateTime
|
import im.vector.riotredesign.core.extensions.localDateTime
|
||||||
|
|
||||||
@ -49,6 +51,26 @@ fun List<TimelineEvent>.filterDisplayableEvents(): List<TimelineEvent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun TimelineEvent.senderAvatar(): String? {
|
||||||
|
// We might have no avatar when user leave, so we try to get it from prevContent
|
||||||
|
return senderAvatar
|
||||||
|
?: if (root.type == EventType.STATE_ROOM_MEMBER) {
|
||||||
|
root.prevContent.toModel<RoomMember>()?.avatarUrl
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TimelineEvent.senderName(): String? {
|
||||||
|
// We might have no senderName when user leave, so we try to get it from prevContent
|
||||||
|
return senderName
|
||||||
|
?: if (root.type == EventType.STATE_ROOM_MEMBER) {
|
||||||
|
root.prevContent.toModel<RoomMember>()?.displayName
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun TimelineEvent.canBeMerged(): Boolean {
|
fun TimelineEvent.canBeMerged(): Boolean {
|
||||||
return root.type == EventType.STATE_ROOM_MEMBER
|
return root.type == EventType.STATE_ROOM_MEMBER
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,6 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
|
|||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
bindScope(getOrCreateScope(HomeModule.ROOM_LIST_SCOPE))
|
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
setupCreateRoomButton()
|
setupCreateRoomButton()
|
||||||
roomListViewModel.subscribe { renderState(it) }
|
roomListViewModel.subscribe { renderState(it) }
|
||||||
|
@ -22,9 +22,11 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary
|
|||||||
import im.vector.riotredesign.core.extensions.localDateTime
|
import im.vector.riotredesign.core.extensions.localDateTime
|
||||||
import im.vector.riotredesign.core.resources.DateProvider
|
import im.vector.riotredesign.core.resources.DateProvider
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
|
|
||||||
class RoomSummaryController(private val stringProvider: StringProvider,
|
class RoomSummaryController(private val stringProvider: StringProvider,
|
||||||
|
private val eventFormatter: NoticeEventFormatter,
|
||||||
private val timelineDateFormatter: TimelineDateFormatter
|
private val timelineDateFormatter: TimelineDateFormatter
|
||||||
) : TypedEpoxyController<RoomListViewState>() {
|
) : TypedEpoxyController<RoomListViewState>() {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user