Add local filtering in thread list
This commit is contained in:
parent
e2bf3e7097
commit
afc69c77bd
|
@ -195,7 +195,7 @@ data class Event(
|
||||||
* It can be used especially for message summaries.
|
* It can be used especially for message summaries.
|
||||||
* It will return a decrypted text message or an empty string otherwise.
|
* It will return a decrypted text message or an empty string otherwise.
|
||||||
*/
|
*/
|
||||||
fun getDecryptedUserFriendlyTextSummary(): String {
|
fun getDecryptedTextSummary(): String {
|
||||||
val text = getDecryptedValue().orEmpty()
|
val text = getDecryptedValue().orEmpty()
|
||||||
return when {
|
return when {
|
||||||
isReply() || isQuote() -> ContentUtils.extractUsefulTextFromReply(text)
|
isReply() || isQuote() -> ContentUtils.extractUsefulTextFromReply(text)
|
||||||
|
|
|
@ -68,4 +68,11 @@ interface TimelineService {
|
||||||
*/
|
*/
|
||||||
fun getAllThreads(): List<TimelineEvent>
|
fun getAllThreads(): List<TimelineEvent>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the current user is participating in the thread
|
||||||
|
* @param rootThreadEventId the eventId of the current thread
|
||||||
|
*/
|
||||||
|
fun isUserParticipatingInThread(rootThreadEventId: String, senderId: String): Boolean
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,6 @@ internal fun EventEntity.findAllThreadsForRootEventId(realm: Realm, rootThreadEv
|
||||||
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
||||||
.findAll()
|
.findAll()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all TimelineEventEntity that are root threads for the specified room
|
* Find all TimelineEventEntity that are root threads for the specified room
|
||||||
* @param roomId The room that all stored root threads will be returned
|
* @param roomId The room that all stored root threads will be returned
|
||||||
|
@ -97,3 +96,17 @@ internal fun TimelineEventEntity.Companion.findAllThreadsForRoomId(realm: Realm,
|
||||||
.equalTo(TimelineEventEntityFields.ROOT.IS_ROOT_THREAD, true)
|
.equalTo(TimelineEventEntityFields.ROOT.IS_ROOT_THREAD, true)
|
||||||
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the given user is participating in a current thread
|
||||||
|
* @param roomId the room that the thread exists
|
||||||
|
* @param rootThreadEventId the thread that the search will be done
|
||||||
|
* @param senderId the user that will try to find participation
|
||||||
|
*/
|
||||||
|
internal fun TimelineEventEntity.Companion.isUserParticipatingInThread(realm: Realm, roomId: String, rootThreadEventId: String, senderId: String): Boolean =
|
||||||
|
TimelineEventEntity
|
||||||
|
.whereRoomId(realm, roomId = roomId)
|
||||||
|
.equalTo(TimelineEventEntityFields.ROOT.ROOT_THREAD_EVENT_ID, rootThreadEventId)
|
||||||
|
.equalTo(TimelineEventEntityFields.ROOT.SENDER, senderId)
|
||||||
|
.findFirst()
|
||||||
|
?.let { true }
|
||||||
|
?: false
|
||||||
|
|
|
@ -111,7 +111,7 @@ internal object EventMapper {
|
||||||
avatarUrl = timelineEventEntity.senderAvatar
|
avatarUrl = timelineEventEntity.senderAvatar
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
threadSummaryLatestTextMessage = eventEntity.threadSummaryLatestMessage?.root?.asDomain()?.getDecryptedUserFriendlyTextSummary().orEmpty()
|
threadSummaryLatestTextMessage = eventEntity.threadSummaryLatestMessage?.root?.asDomain()?.getDecryptedTextSummary().orEmpty()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import com.zhuinden.monarchy.Monarchy
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import io.realm.Realm
|
||||||
import io.realm.Sort
|
import io.realm.Sort
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
||||||
|
@ -32,10 +33,10 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.helper.findAllThreadsForRoomId
|
import org.matrix.android.sdk.internal.database.helper.findAllThreadsForRoomId
|
||||||
|
import org.matrix.android.sdk.internal.database.helper.isUserParticipatingInThread
|
||||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
||||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.findAllInRoomWithSendStates
|
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
||||||
|
@ -111,10 +112,21 @@ internal class DefaultTimelineService @AssistedInject constructor(
|
||||||
{ timelineEventMapper.map(it) }
|
{ timelineEventMapper.map(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAllThreads(): List<TimelineEvent> {
|
override fun getAllThreads(): List<TimelineEvent> {
|
||||||
return monarchy.fetchAllMappedSync(
|
return monarchy.fetchAllMappedSync(
|
||||||
{ TimelineEventEntity.findAllThreadsForRoomId(it, roomId = roomId) },
|
{ TimelineEventEntity.findAllThreadsForRoomId(it, roomId = roomId) },
|
||||||
{ timelineEventMapper.map(it) }
|
{ timelineEventMapper.map(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isUserParticipatingInThread(rootThreadEventId: String, senderId: String): Boolean {
|
||||||
|
return Realm.getInstance(monarchy.realmConfiguration).use {
|
||||||
|
TimelineEventEntity.isUserParticipatingInThread(
|
||||||
|
realm = it,
|
||||||
|
roomId = roomId,
|
||||||
|
rootThreadEventId = rootThreadEventId,
|
||||||
|
senderId = senderId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 New Vector Ltd
|
* Copyright 2021 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -34,12 +34,6 @@ class ThreadSummaryController @Inject constructor(
|
||||||
|
|
||||||
private var viewState: ThreadSummaryViewState? = null
|
private var viewState: ThreadSummaryViewState? = null
|
||||||
|
|
||||||
init {
|
|
||||||
// We are requesting a model build directly as the first build of epoxy is on the main thread.
|
|
||||||
// It avoids to build the whole list of breadcrumbs on the main thread.
|
|
||||||
requestModelBuild()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun update(viewState: ThreadSummaryViewState) {
|
fun update(viewState: ThreadSummaryViewState) {
|
||||||
this.viewState = viewState
|
this.viewState = viewState
|
||||||
requestModelBuild()
|
requestModelBuild()
|
||||||
|
@ -48,13 +42,7 @@ class ThreadSummaryController @Inject constructor(
|
||||||
override fun buildModels() {
|
override fun buildModels() {
|
||||||
val safeViewState = viewState ?: return
|
val safeViewState = viewState ?: return
|
||||||
val host = this
|
val host = this
|
||||||
// Add a ZeroItem to avoid automatic scroll when the breadcrumbs are updated from another client
|
|
||||||
// zeroItem {
|
|
||||||
// id("top")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// An empty breadcrumbs list can only be temporary because when entering in a room,
|
|
||||||
// this one is added to the breadcrumbs
|
|
||||||
safeViewState.rootThreadEventList.invoke()
|
safeViewState.rootThreadEventList.invoke()
|
||||||
?.forEach { timelineEvent ->
|
?.forEach { timelineEvent ->
|
||||||
val date = dateFormatter.format(timelineEvent.root.originServerTs, DateFormatKind.ROOM_LIST)
|
val date = dateFormatter.format(timelineEvent.root.originServerTs, DateFormatKind.ROOM_LIST)
|
||||||
|
@ -64,7 +52,7 @@ class ThreadSummaryController @Inject constructor(
|
||||||
matrixItem(timelineEvent.senderInfo.toMatrixItem())
|
matrixItem(timelineEvent.senderInfo.toMatrixItem())
|
||||||
title(timelineEvent.senderInfo.displayName)
|
title(timelineEvent.senderInfo.displayName)
|
||||||
date(date)
|
date(date)
|
||||||
rootMessage(timelineEvent.root.getDecryptedUserFriendlyTextSummary())
|
rootMessage(timelineEvent.root.getDecryptedTextSummary())
|
||||||
lastMessage(timelineEvent.root.threadDetails?.threadSummaryLatestTextMessage.orEmpty())
|
lastMessage(timelineEvent.root.threadDetails?.threadSummaryLatestTextMessage.orEmpty())
|
||||||
lastMessageCounter(timelineEvent.root.threadDetails?.numberOfThreads.toString())
|
lastMessageCounter(timelineEvent.root.threadDetails?.numberOfThreads.toString())
|
||||||
lastMessageMatrixItem(timelineEvent.root.threadDetails?.threadSummarySenderInfo?.toMatrixItem())
|
lastMessageMatrixItem(timelineEvent.root.threadDetails?.threadSummarySenderInfo?.toMatrixItem())
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 New Vector Ltd
|
* Copyright 2021 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -26,11 +26,9 @@ import im.vector.app.core.platform.EmptyAction
|
||||||
import im.vector.app.core.platform.EmptyViewEvents
|
import im.vector.app.core.platform.EmptyViewEvents
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.home.room.threads.list.views.ThreadListFragment
|
import im.vector.app.features.home.room.threads.list.views.ThreadListFragment
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
|
||||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
|
|
||||||
class ThreadSummaryViewModel @AssistedInject constructor(@Assisted val initialState: ThreadSummaryViewState,
|
class ThreadSummaryViewModel @AssistedInject constructor(@Assisted val initialState: ThreadSummaryViewState,
|
||||||
|
@ -54,19 +52,28 @@ class ThreadSummaryViewModel @AssistedInject constructor(@Assisted val initialSt
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
observeThreadsSummary()
|
observeThreadsList(initialState.shouldFilterThreads)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handle(action: EmptyAction) {
|
override fun handle(action: EmptyAction) {}
|
||||||
// No op
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private fun observeThreadsList(shouldFilterThreads: Boolean) =
|
||||||
private fun observeThreadsSummary() {
|
|
||||||
room?.flow()
|
room?.flow()
|
||||||
?.liveThreadList()
|
?.liveThreadList()
|
||||||
|
?.map {
|
||||||
|
if (!shouldFilterThreads) return@map it
|
||||||
|
it.filter { timelineEvent ->
|
||||||
|
room.isUserParticipatingInThread(timelineEvent.eventId, session.myUserId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?.flowOn(room.coroutineDispatchers.io)
|
||||||
?.execute { asyncThreads ->
|
?.execute { asyncThreads ->
|
||||||
copy(rootThreadEventList = asyncThreads)
|
copy(
|
||||||
}
|
rootThreadEventList = asyncThreads,
|
||||||
|
shouldFilterThreads = shouldFilterThreads)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun applyFiltering(shouldFilterThreads: Boolean) {
|
||||||
|
observeThreadsList(shouldFilterThreads)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 New Vector Ltd
|
* Copyright 2021 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
|
|
||||||
data class ThreadSummaryViewState(
|
data class ThreadSummaryViewState(
|
||||||
val rootThreadEventList: Async<List<TimelineEvent>> = Uninitialized,
|
val rootThreadEventList: Async<List<TimelineEvent>> = Uninitialized,
|
||||||
|
val shouldFilterThreads: Boolean = false,
|
||||||
val roomId: String
|
val roomId: String
|
||||||
) : MavericksState{
|
) : MavericksState{
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.app.features.home.room.threads.list.views
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.content.res.AppCompatResources.getDrawable
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.airbnb.mvrx.parentFragmentViewModel
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||||
|
import im.vector.app.databinding.BottomSheetThreadListBinding
|
||||||
|
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryViewModel
|
||||||
|
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryViewState
|
||||||
|
|
||||||
|
class ThreadListBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetThreadListBinding>() {
|
||||||
|
|
||||||
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetThreadListBinding {
|
||||||
|
return BottomSheetThreadListBinding.inflate(inflater, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val threadListViewModel: ThreadSummaryViewModel by parentFragmentViewModel()
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
threadListViewModel.subscribe(this){
|
||||||
|
renderState(it)
|
||||||
|
}
|
||||||
|
views.threadListModalAllThreads.views.bottomSheetActionClickableZone.debouncedClicks {
|
||||||
|
threadListViewModel.applyFiltering(false)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
views.threadListModalMyThreads.views.bottomSheetActionClickableZone.debouncedClicks {
|
||||||
|
threadListViewModel.applyFiltering(true)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderState(state: ThreadSummaryViewState) {
|
||||||
|
|
||||||
|
if(state.shouldFilterThreads){
|
||||||
|
views.threadListModalAllThreads.rightIcon = null
|
||||||
|
views.threadListModalMyThreads.rightIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_tick)
|
||||||
|
}else{
|
||||||
|
views.threadListModalAllThreads.rightIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_tick)
|
||||||
|
views.threadListModalMyThreads.rightIcon = null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,11 +18,10 @@ package im.vector.app.features.home.room.threads.list.views
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.transition.TransitionInflater
|
|
||||||
import com.airbnb.mvrx.args
|
import com.airbnb.mvrx.args
|
||||||
import com.airbnb.mvrx.fragmentViewModel
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
|
@ -32,21 +31,16 @@ import im.vector.app.core.extensions.configureWith
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.databinding.FragmentThreadListBinding
|
import im.vector.app.databinding.FragmentThreadListBinding
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsAnimator
|
import im.vector.app.features.home.room.detail.timeline.animation.TimelineItemAnimator
|
||||||
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsViewModel
|
|
||||||
import im.vector.app.features.home.room.detail.RoomDetailSharedActionViewModel
|
|
||||||
import im.vector.app.features.home.room.threads.ThreadsActivity
|
import im.vector.app.features.home.room.threads.ThreadsActivity
|
||||||
import im.vector.app.features.home.room.threads.arguments.ThreadListArgs
|
import im.vector.app.features.home.room.threads.arguments.ThreadListArgs
|
||||||
import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
|
|
||||||
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryController
|
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryController
|
||||||
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryViewModel
|
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryViewModel
|
||||||
import org.matrix.android.sdk.api.session.Session
|
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.matrix.android.sdk.api.util.MatrixItem
|
import org.matrix.android.sdk.api.util.MatrixItem
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ThreadListFragment @Inject constructor(
|
class ThreadListFragment @Inject constructor(
|
||||||
private val session: Session,
|
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val threadSummaryController: ThreadSummaryController,
|
private val threadSummaryController: ThreadSummaryController,
|
||||||
val threadSummaryViewModelFactory: ThreadSummaryViewModel.Factory
|
val threadSummaryViewModelFactory: ThreadSummaryViewModel.Factory
|
||||||
|
@ -67,10 +61,20 @@ class ThreadListFragment @Inject constructor(
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
return when (item.itemId) {
|
||||||
|
R.id.menu_thread_list_filter -> {
|
||||||
|
ThreadListBottomSheet().show(childFragmentManager, "Filtering")
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
initToolbar()
|
initToolbar()
|
||||||
views.threadListRecyclerView.configureWith(threadSummaryController, BreadcrumbsAnimator(), hasFixedSize = false)
|
views.threadListRecyclerView.configureWith(threadSummaryController, TimelineItemAnimator(), hasFixedSize = false)
|
||||||
threadSummaryController.listener = this
|
threadSummaryController.listener = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?colorSurface"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/threadListModalTitle"
|
||||||
|
style="@style/Widget.Vector.TextView.Subtitle.Medium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="22dp"
|
||||||
|
android:text="@string/thread_list_modal_title"
|
||||||
|
android:textColor="?vctr_content_secondary"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<im.vector.app.core.ui.views.BottomSheetActionButton
|
||||||
|
android:id="@+id/threadListModalAllThreads"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
app:actionDescription="@string/thread_list_modal_all_threads_subtitle"
|
||||||
|
app:actionTitle="@string/thread_list_modal_all_threads_title"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/threadListModalTitle"
|
||||||
|
app:tint="?vctr_content_primary"
|
||||||
|
app:titleTextColor="?vctr_content_primary" />
|
||||||
|
|
||||||
|
<im.vector.app.core.ui.views.BottomSheetActionButton
|
||||||
|
android:id="@+id/threadListModalMyThreads"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
app:actionDescription="@string/thread_list_modal_my_threads_subtitle"
|
||||||
|
app:actionTitle="@string/thread_list_modal_my_threads_title"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/threadListModalAllThreads"
|
||||||
|
app:tint="?vctr_content_primary"
|
||||||
|
app:titleTextColor="?vctr_content_primary" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1027,10 +1027,15 @@
|
||||||
<string name="room_details_people_invited_group_name">INVITED</string>
|
<string name="room_details_people_invited_group_name">INVITED</string>
|
||||||
<string name="room_details_people_present_group_name">JOINED</string>
|
<string name="room_details_people_present_group_name">JOINED</string>
|
||||||
|
|
||||||
<!-- Room Threads -->
|
<!-- Threads -->
|
||||||
<string name="room_threads_filter">Filter Threads in room</string>
|
<string name="room_threads_filter">Filter Threads in room</string>
|
||||||
<string name="thread_timeline_title">Thread</string>
|
<string name="thread_timeline_title">Thread</string>
|
||||||
<string name="thread_list_title">Threads</string>
|
<string name="thread_list_title">Threads</string>
|
||||||
|
<string name="thread_list_modal_title">Filter</string>
|
||||||
|
<string name="thread_list_modal_all_threads_title">All Threads</string>
|
||||||
|
<string name="thread_list_modal_all_threads_subtitle">Shows all threads from current room</string>
|
||||||
|
<string name="thread_list_modal_my_threads_title">My Threads</string>
|
||||||
|
<string name="thread_list_modal_my_threads_subtitle">Shows all threads you’ve participated in</string>
|
||||||
|
|
||||||
<!-- Room events -->
|
<!-- Room events -->
|
||||||
<string name="room_event_action_report_prompt_reason">Reason for reporting this content</string>
|
<string name="room_event_action_report_prompt_reason">Reason for reporting this content</string>
|
||||||
|
|
Loading…
Reference in New Issue