mirror of
https://github.com/element-hq/element-android
synced 2024-12-11 20:52:35 +03:00
- Add specific toolbar for threads
- Renamed RoomDetailFragment to TimelineFragment while it should be reused from threads - View root thread message in room functionality
This commit is contained in:
parent
3de0f7bf37
commit
586b3d8caa
38 changed files with 766 additions and 625 deletions
14
vector/src/debug/res/layout/fragment_thread_list.xml
Normal file
14
vector/src/debug/res/layout/fragment_thread_list.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/coordinatorLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -179,8 +179,7 @@
|
|||
<activity android:name=".features.roomdirectory.RoomDirectoryActivity" />
|
||||
<activity android:name=".features.roomdirectory.roompreview.RoomPreviewActivity" />
|
||||
<activity android:name=".features.home.room.filtered.FilteredRoomsActivity" />
|
||||
<activity android:name=".features.home.room.threads.RoomThreadsActivity" />
|
||||
<activity android:name=".features.home.room.threads.detail.RoomThreadDetailActivity" />
|
||||
<activity android:name=".features.home.room.threads.ThreadsActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".features.home.room.detail.RoomDetailActivity"
|
||||
|
|
|
@ -55,10 +55,10 @@ import im.vector.app.features.home.HomeDetailFragment
|
|||
import im.vector.app.features.home.HomeDrawerFragment
|
||||
import im.vector.app.features.home.LoadingFragment
|
||||
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment
|
||||
import im.vector.app.features.home.room.detail.RoomDetailFragment
|
||||
import im.vector.app.features.home.room.detail.TimelineFragment
|
||||
import im.vector.app.features.home.room.detail.search.SearchFragment
|
||||
import im.vector.app.features.home.room.list.RoomListFragment
|
||||
import im.vector.app.features.home.room.threads.detail.RoomThreadDetailFragment
|
||||
import im.vector.app.features.home.room.threads.detail.ThreadListFragment
|
||||
import im.vector.app.features.login.LoginCaptchaFragment
|
||||
import im.vector.app.features.login.LoginFragment
|
||||
import im.vector.app.features.login.LoginGenericTextInputFormFragment
|
||||
|
@ -183,8 +183,8 @@ interface FragmentModule {
|
|||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomDetailFragment::class)
|
||||
fun bindRoomDetailFragment(fragment: RoomDetailFragment): Fragment
|
||||
@FragmentKey(TimelineFragment::class)
|
||||
fun bindRoomDetailFragment(fragment: TimelineFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
|
@ -838,6 +838,6 @@ interface FragmentModule {
|
|||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomThreadDetailFragment::class)
|
||||
fun bindRoomThreadDetailFragment(fragment: RoomThreadDetailFragment): Fragment
|
||||
@FragmentKey(ThreadListFragment::class)
|
||||
fun bindRoomThreadDetailFragment(fragment: ThreadListFragment): Fragment
|
||||
}
|
||||
|
|
|
@ -52,8 +52,7 @@ import im.vector.app.features.home.room.detail.widget.RoomWidgetsBottomSheet
|
|||
import im.vector.app.features.home.room.filtered.FilteredRoomsActivity
|
||||
import im.vector.app.features.home.room.list.RoomListModule
|
||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
|
||||
import im.vector.app.features.home.room.threads.RoomThreadsActivity
|
||||
import im.vector.app.features.home.room.threads.detail.RoomThreadDetailActivity
|
||||
import im.vector.app.features.home.room.threads.ThreadsActivity
|
||||
import im.vector.app.features.invite.AutoAcceptInvites
|
||||
import im.vector.app.features.invite.InviteUsersToRoomActivity
|
||||
import im.vector.app.features.invite.VectorInviteView
|
||||
|
@ -176,8 +175,7 @@ interface ScreenComponent {
|
|||
fun inject(activity: SpaceManageActivity)
|
||||
fun inject(activity: RoomJoinRuleActivity)
|
||||
fun inject(activity: SpaceLeaveAdvancedActivity)
|
||||
fun inject(activity: RoomThreadsActivity)
|
||||
fun inject(activity: RoomThreadDetailActivity)
|
||||
fun inject(activity: ThreadsActivity)
|
||||
|
||||
/* ==========================================================================================
|
||||
* BottomSheets
|
||||
|
|
|
@ -58,7 +58,7 @@ import im.vector.app.features.call.webrtc.WebRtcCallManager
|
|||
import im.vector.app.features.displayname.getBestName
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||
import im.vector.app.features.home.room.detail.RoomDetailArgs
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import io.github.hyuwah.draggableviewlib.DraggableView
|
||||
import io.github.hyuwah.draggableviewlib.setupDraggable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
|
@ -573,7 +573,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
|
|||
|
||||
private fun returnToChat() {
|
||||
val roomId = withState(callViewModel) { it.roomId }
|
||||
val args = RoomDetailArgs(roomId)
|
||||
val args = TimelineArgs(roomId)
|
||||
val intent = RoomDetailActivity.newIntent(this, args).apply {
|
||||
flags = FLAG_ACTIVITY_CLEAR_TOP
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import im.vector.app.core.platform.VectorBaseActivity
|
|||
import im.vector.app.features.displayname.getBestName
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||
import im.vector.app.features.home.room.detail.RoomDetailArgs
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import im.vector.app.features.popup.PopupAlertManager
|
||||
import im.vector.app.features.popup.VerificationVectorAlert
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
|
@ -142,7 +142,7 @@ class IncomingVerificationRequestHandler @Inject constructor(
|
|||
R.drawable.ic_shield_black,
|
||||
shouldBeDisplayedIn = { activity ->
|
||||
if (activity is RoomDetailActivity) {
|
||||
activity.intent?.extras?.getParcelable<RoomDetailArgs>(RoomDetailActivity.EXTRA_ROOM_DETAIL_ARGS)?.let {
|
||||
activity.intent?.extras?.getParcelable<TimelineArgs>(RoomDetailActivity.EXTRA_ROOM_DETAIL_ARGS)?.let {
|
||||
it.roomId != pr.roomId
|
||||
} ?: true
|
||||
} else true
|
||||
|
|
|
@ -34,6 +34,7 @@ import im.vector.app.core.platform.ToolbarConfigurable
|
|||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivityRoomDetailBinding
|
||||
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import im.vector.app.features.matrixto.MatrixToBottomSheet
|
||||
import im.vector.app.features.navigation.Navigator
|
||||
import im.vector.app.features.room.RequireActiveMembershipAction
|
||||
|
@ -102,16 +103,16 @@ class RoomDetailActivity :
|
|||
super.onCreate(savedInstanceState)
|
||||
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
||||
waitingView = views.waitingView.waitingView
|
||||
val roomDetailArgs: RoomDetailArgs? = if (intent?.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) {
|
||||
RoomDetailArgs(roomId = intent?.extras?.getString(EXTRA_ROOM_ID)!!)
|
||||
val timelineArgs: TimelineArgs? = if (intent?.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) {
|
||||
TimelineArgs(roomId = intent?.extras?.getString(EXTRA_ROOM_ID)!!)
|
||||
} else {
|
||||
intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS)
|
||||
}
|
||||
if (roomDetailArgs == null) return
|
||||
currentRoomId = roomDetailArgs.roomId
|
||||
if (timelineArgs == null) return
|
||||
currentRoomId = timelineArgs.roomId
|
||||
|
||||
if (isFirstCreation()) {
|
||||
replaceFragment(R.id.roomDetailContainer, RoomDetailFragment::class.java, roomDetailArgs)
|
||||
replaceFragment(R.id.roomDetailContainer, TimelineFragment::class.java, timelineArgs)
|
||||
replaceFragment(R.id.roomDetailDrawerContainer, BreadcrumbsFragment::class.java)
|
||||
}
|
||||
|
||||
|
@ -147,7 +148,7 @@ class RoomDetailActivity :
|
|||
if (currentRoomId != switchToRoom.roomId) {
|
||||
currentRoomId = switchToRoom.roomId
|
||||
requireActiveMembershipViewModel.handle(RequireActiveMembershipAction.ChangeRoom(switchToRoom.roomId))
|
||||
replaceFragment(R.id.roomDetailContainer, RoomDetailFragment::class.java, RoomDetailArgs(switchToRoom.roomId))
|
||||
replaceFragment(R.id.roomDetailContainer, TimelineFragment::class.java, TimelineArgs(switchToRoom.roomId))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,9 +192,9 @@ class RoomDetailActivity :
|
|||
const val EXTRA_ROOM_ID = "EXTRA_ROOM_ID"
|
||||
const val ACTION_ROOM_DETAILS_FROM_SHORTCUT = "ROOM_DETAILS_FROM_SHORTCUT"
|
||||
|
||||
fun newIntent(context: Context, roomDetailArgs: RoomDetailArgs): Intent {
|
||||
fun newIntent(context: Context, timelineArgs: TimelineArgs): Intent {
|
||||
return Intent(context, RoomDetailActivity::class.java).apply {
|
||||
putExtra(EXTRA_ROOM_DETAIL_ARGS, roomDetailArgs)
|
||||
putExtra(EXTRA_ROOM_DETAIL_ARGS, timelineArgs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? {
|
||||
val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
val fragment: TimelineFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
|
||||
return fragment.roomDetailViewModelFactory.create(state)
|
||||
}
|
||||
|
@ -668,20 +668,30 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
private fun isIntegrationEnabled() = session.integrationManagerService().isIntegrationEnabled()
|
||||
|
||||
fun isMenuItemVisible(@IdRes itemId: Int): Boolean = com.airbnb.mvrx.withState(this) { state ->
|
||||
|
||||
if (state.asyncRoomSummary()?.membership != Membership.JOIN) {
|
||||
return@withState false
|
||||
}
|
||||
when (itemId) {
|
||||
R.id.timeline_setting -> true
|
||||
R.id.invite -> state.canInvite
|
||||
R.id.open_matrix_apps -> true
|
||||
R.id.voice_call -> state.isWebRTCCallOptionAvailable()
|
||||
R.id.video_call -> state.isWebRTCCallOptionAvailable() || state.jitsiState.confId == null || state.jitsiState.hasJoined
|
||||
// Show Join conference button only if there is an active conf id not joined. Otherwise fallback to default video disabled. ^
|
||||
R.id.join_conference -> !state.isWebRTCCallOptionAvailable() && state.jitsiState.confId != null && !state.jitsiState.hasJoined
|
||||
R.id.search -> true
|
||||
R.id.dev_tools -> vectorPreferences.developerMode()
|
||||
else -> false
|
||||
|
||||
if (initialState.isThreadTimeline()) {
|
||||
when (itemId) {
|
||||
R.id.menu_thread_timeline_more -> true
|
||||
else -> false
|
||||
}
|
||||
} else {
|
||||
when (itemId) {
|
||||
R.id.timeline_setting -> true
|
||||
R.id.invite -> state.canInvite
|
||||
R.id.open_matrix_apps -> true
|
||||
R.id.voice_call -> state.isWebRTCCallOptionAvailable()
|
||||
R.id.video_call -> state.isWebRTCCallOptionAvailable() || state.jitsiState.confId == null || state.jitsiState.hasJoined
|
||||
// Show Join conference button only if there is an active conf id not joined. Otherwise fallback to default video disabled. ^
|
||||
R.id.join_conference -> !state.isWebRTCCallOptionAvailable() && state.jitsiState.confId != null && !state.jitsiState.hasJoined
|
||||
R.id.search -> true
|
||||
R.id.threads -> true
|
||||
R.id.dev_tools -> vectorPreferences.developerMode()
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.home.room.detail
|
|||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.MavericksState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.initsync.SyncStatusService
|
||||
|
@ -69,12 +70,12 @@ data class RoomDetailViewState(
|
|||
val rootThreadEventId: String? = null
|
||||
) : MavericksState {
|
||||
|
||||
constructor(args: RoomDetailArgs) : this(
|
||||
constructor(args: TimelineArgs) : this(
|
||||
roomId = args.roomId,
|
||||
eventId = args.eventId,
|
||||
// Also highlight the target event, if any
|
||||
highlightedEventId = args.eventId,
|
||||
rootThreadEventId = args.roomThreadDetailArgs?.eventId
|
||||
rootThreadEventId = args.threadTimelineArgs?.rootThreadEventId
|
||||
)
|
||||
|
||||
fun isWebRTCCallOptionAvailable() = (asyncRoomSummary.invoke()?.joinedMembersCount ?: 0) <= 2
|
||||
|
@ -84,4 +85,7 @@ data class RoomDetailViewState(
|
|||
fun hasActiveJitsiWidget() = activeRoomWidgets()?.any { it.type == WidgetType.Jitsi && it.isActive }.orFalse()
|
||||
|
||||
fun isDm() = asyncRoomSummary()?.isDirect == true
|
||||
|
||||
fun isThreadTimeline() = rootThreadEventId != null
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import android.graphics.Typeface
|
|||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.text.Spannable
|
||||
import android.text.format.DateUtils
|
||||
import android.view.HapticFeedbackConstants
|
||||
|
@ -49,7 +48,6 @@ import androidx.core.text.toSpannable
|
|||
import androidx.core.util.Pair
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.forEach
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.setFragmentResultListener
|
||||
|
@ -134,6 +132,7 @@ import im.vector.app.features.command.Command
|
|||
import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheet
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import im.vector.app.features.home.room.detail.composer.SendMode
|
||||
import im.vector.app.features.home.room.detail.composer.TextComposerAction
|
||||
import im.vector.app.features.home.room.detail.composer.TextComposerView
|
||||
|
@ -162,8 +161,7 @@ import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
|
|||
import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet
|
||||
import im.vector.app.features.home.room.detail.views.RoomDetailLazyLoadedViews
|
||||
import im.vector.app.features.home.room.detail.widget.RoomWidgetsBottomSheet
|
||||
import im.vector.app.features.home.room.threads.detail.arguments.RoomThreadDetailArgs
|
||||
import im.vector.app.features.home.room.threads.detail.RoomThreadDetailActivity
|
||||
import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
|
||||
import im.vector.app.features.html.EventHtmlRenderer
|
||||
import im.vector.app.features.html.PillImageSpan
|
||||
import im.vector.app.features.html.PillsPostProcessor
|
||||
|
@ -188,7 +186,6 @@ import im.vector.app.features.widgets.WidgetArgs
|
|||
import im.vector.app.features.widgets.WidgetKind
|
||||
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import nl.dionsegijn.konfetti.models.Shape
|
||||
import nl.dionsegijn.konfetti.models.Size
|
||||
import org.billcarsonfr.jsonviewer.JSonViewerDialog
|
||||
|
@ -224,16 +221,7 @@ import java.util.UUID
|
|||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
@Parcelize
|
||||
data class RoomDetailArgs(
|
||||
val roomId: String,
|
||||
val eventId: String? = null,
|
||||
val sharedData: SharedData? = null,
|
||||
val openShareSpaceForId: String? = null,
|
||||
val roomThreadDetailArgs: RoomThreadDetailArgs? = null
|
||||
) : Parcelable
|
||||
|
||||
class RoomDetailFragment @Inject constructor(
|
||||
class TimelineFragment @Inject constructor(
|
||||
private val session: Session,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val timelineEventController: TimelineEventController,
|
||||
|
@ -282,16 +270,16 @@ class RoomDetailFragment @Inject constructor(
|
|||
|
||||
private val galleryOrCameraDialogHelper = GalleryOrCameraDialogHelper(this, colorProvider)
|
||||
|
||||
private val roomDetailArgs: RoomDetailArgs by args()
|
||||
private val timelineArgs: TimelineArgs by args()
|
||||
private val glideRequests by lazy {
|
||||
GlideApp.with(this)
|
||||
}
|
||||
private val pillsPostProcessor by lazy {
|
||||
pillsPostProcessorFactory.create(roomDetailArgs.roomId)
|
||||
pillsPostProcessorFactory.create(timelineArgs.roomId)
|
||||
}
|
||||
|
||||
private val autoCompleter: AutoCompleter by lazy {
|
||||
autoCompleterFactory.create(roomDetailArgs.roomId, isThreadTimeLine())
|
||||
autoCompleterFactory.create(timelineArgs.roomId, isThreadTimeLine())
|
||||
}
|
||||
|
||||
private val roomDetailViewModel: RoomDetailViewModel by fragmentViewModel()
|
||||
|
@ -308,6 +296,8 @@ class RoomDetailFragment @Inject constructor(
|
|||
override fun getMenuRes() = R.menu.menu_timeline
|
||||
|
||||
private lateinit var sharedActionViewModel: MessageSharedActionViewModel
|
||||
private lateinit var sharedActivityActionViewModel: RoomDetailSharedActionViewModel
|
||||
|
||||
private lateinit var knownCallsViewModel: SharedKnownCallsViewModel
|
||||
|
||||
private lateinit var layoutManager: LinearLayoutManager
|
||||
|
@ -341,10 +331,11 @@ class RoomDetailFragment @Inject constructor(
|
|||
lifecycle.addObserver(ConferenceEventObserver(vectorBaseActivity, this::onBroadcastJitsiEvent))
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
|
||||
sharedActivityActionViewModel = activityViewModelProvider.get(RoomDetailSharedActionViewModel::class.java)
|
||||
knownCallsViewModel = activityViewModelProvider.get(SharedKnownCallsViewModel::class.java)
|
||||
attachmentsHelper = AttachmentsHelper(requireContext(), this).register()
|
||||
callActionsHandler = StartCallActionsHandler(
|
||||
roomId = roomDetailArgs.roomId,
|
||||
roomId = timelineArgs.roomId,
|
||||
fragment = this,
|
||||
vectorPreferences = vectorPreferences,
|
||||
roomDetailViewModel = roomDetailViewModel,
|
||||
|
@ -355,11 +346,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
)
|
||||
keyboardStateUtils = KeyboardStateUtils(requireActivity())
|
||||
lazyLoadedViews.bind(views)
|
||||
if (isThreadTimeLine()) {
|
||||
views.roomToolbar.isGone = true
|
||||
} else {
|
||||
setupToolbar(views.roomToolbar)
|
||||
}
|
||||
setupToolbar(views.roomToolbar)
|
||||
setupRecyclerView()
|
||||
setupComposer()
|
||||
setupNotificationView()
|
||||
|
@ -370,8 +357,8 @@ class RoomDetailFragment @Inject constructor(
|
|||
setupRemoveJitsiWidgetView()
|
||||
setupVoiceMessageView()
|
||||
|
||||
views.roomToolbarContentView.debouncedClicks {
|
||||
navigator.openRoomProfile(requireActivity(), roomDetailArgs.roomId)
|
||||
views.includeRoomToolbar.roomToolbarContentView.debouncedClicks {
|
||||
navigator.openRoomProfile(requireActivity(), timelineArgs.roomId)
|
||||
}
|
||||
|
||||
sharedActionViewModel
|
||||
|
@ -456,7 +443,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
RoomDetailViewEvents.HideWaitingView -> vectorBaseActivity.hideWaitingView()
|
||||
is RoomDetailViewEvents.RequestNativeWidgetPermission -> requestNativeWidgetPermission(it)
|
||||
is RoomDetailViewEvents.OpenRoom -> handleOpenRoom(it)
|
||||
RoomDetailViewEvents.OpenInvitePeople -> navigator.openInviteUsersToRoom(requireContext(), roomDetailArgs.roomId)
|
||||
RoomDetailViewEvents.OpenInvitePeople -> navigator.openInviteUsersToRoom(requireContext(), timelineArgs.roomId)
|
||||
RoomDetailViewEvents.OpenSetRoomAvatarDialog -> galleryOrCameraDialogHelper.show()
|
||||
RoomDetailViewEvents.OpenRoomSettings -> handleOpenRoomSettings()
|
||||
is RoomDetailViewEvents.ShowRoomAvatarFullScreen -> it.matrixItem?.let { item ->
|
||||
|
@ -532,7 +519,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
|
||||
private fun handleShowRoomUpgradeDialog(roomDetailViewEvents: TextComposerViewEvents.ShowRoomUpgradeDialog) {
|
||||
val tag = MigrateRoomBottomSheet::javaClass.name
|
||||
MigrateRoomBottomSheet.newInstance(roomDetailArgs.roomId, roomDetailViewEvents.newVersion)
|
||||
MigrateRoomBottomSheet.newInstance(timelineArgs.roomId, roomDetailViewEvents.newVersion)
|
||||
.show(parentFragmentManager, tag)
|
||||
}
|
||||
|
||||
|
@ -578,7 +565,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
private fun handleOpenRoomSettings() {
|
||||
navigator.openRoomProfile(
|
||||
requireContext(),
|
||||
roomDetailArgs.roomId,
|
||||
timelineArgs.roomId,
|
||||
RoomProfileActivity.EXTRA_DIRECT_ACCESS_ROOM_SETTINGS
|
||||
)
|
||||
}
|
||||
|
@ -600,7 +587,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
WidgetArgs(
|
||||
baseUrl = it.domain,
|
||||
kind = WidgetKind.ROOM,
|
||||
roomId = roomDetailArgs.roomId,
|
||||
roomId = timelineArgs.roomId,
|
||||
widgetId = it.widget.widgetId
|
||||
)
|
||||
).apply {
|
||||
|
@ -626,7 +613,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
navigator.openIntegrationManager(
|
||||
context = requireContext(),
|
||||
activityResultLauncher = integrationManagerActivityResultLauncher,
|
||||
roomId = roomDetailArgs.roomId,
|
||||
roomId = timelineArgs.roomId,
|
||||
integId = null,
|
||||
screen = screen
|
||||
)
|
||||
|
@ -717,11 +704,11 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun joinJitsiRoom(jitsiWidget: Widget, enableVideo: Boolean) {
|
||||
navigator.openRoomWidget(requireContext(), roomDetailArgs.roomId, jitsiWidget, mapOf(JitsiCallViewModel.ENABLE_VIDEO_OPTION to enableVideo))
|
||||
navigator.openRoomWidget(requireContext(), timelineArgs.roomId, jitsiWidget, mapOf(JitsiCallViewModel.ENABLE_VIDEO_OPTION to enableVideo))
|
||||
}
|
||||
|
||||
private fun openStickerPicker(event: RoomDetailViewEvents.OpenStickerPicker) {
|
||||
navigator.openStickerPicker(requireContext(), stickerActivityResultLauncher, roomDetailArgs.roomId, event.widget)
|
||||
navigator.openStickerPicker(requireContext(), stickerActivityResultLauncher, timelineArgs.roomId, event.widget)
|
||||
}
|
||||
|
||||
private fun startOpenFileIntent(action: RoomDetailViewEvents.OpenFile) {
|
||||
|
@ -795,7 +782,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleShareData() {
|
||||
when (val sharedData = roomDetailArgs.sharedData) {
|
||||
when (val sharedData = timelineArgs.sharedData) {
|
||||
is SharedData.Text -> {
|
||||
textComposerViewModel.handle(TextComposerAction.EnterRegularMode(sharedData.text, fromSharing = true))
|
||||
}
|
||||
|
@ -808,7 +795,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleSpaceShare() {
|
||||
roomDetailArgs.openShareSpaceForId?.let { spaceId ->
|
||||
timelineArgs.openShareSpaceForId?.let { spaceId ->
|
||||
ShareSpaceBottomSheet.show(childFragmentManager, spaceId, true)
|
||||
view?.post {
|
||||
handleChatEffect(ChatEffect.CONFETTI)
|
||||
|
@ -909,7 +896,6 @@ class RoomDetailFragment @Inject constructor(
|
|||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
if (isThreadTimeLine()) return
|
||||
// We use a custom layout for this menu item, so we need to set a ClickListener
|
||||
menu.findItem(R.id.open_matrix_apps)?.let { menuItem ->
|
||||
menuItem.actionView.setOnClickListener {
|
||||
|
@ -923,15 +909,11 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
if (isThreadTimeLine()) {
|
||||
menu.forEach {
|
||||
it.isVisible = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
menu.forEach {
|
||||
it.isVisible = roomDetailViewModel.isMenuItemVisible(it.itemId)
|
||||
}
|
||||
|
||||
withState(roomDetailViewModel) { state ->
|
||||
// Set the visual state of the call buttons (voice/video) to enabled/disabled according to user permissions
|
||||
val hasCallInRoom = callManager.getCallsByRoomId(state.roomId).isNotEmpty() || state.jitsiState.hasJoined
|
||||
|
@ -968,41 +950,72 @@ class RoomDetailFragment @Inject constructor(
|
|||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.invite -> {
|
||||
navigator.openInviteUsersToRoom(requireActivity(), roomDetailArgs.roomId)
|
||||
R.id.invite -> {
|
||||
navigator.openInviteUsersToRoom(requireActivity(), timelineArgs.roomId)
|
||||
true
|
||||
}
|
||||
R.id.timeline_setting -> {
|
||||
navigator.openRoomProfile(requireActivity(), roomDetailArgs.roomId)
|
||||
R.id.timeline_setting -> {
|
||||
navigator.openRoomProfile(requireActivity(), timelineArgs.roomId)
|
||||
true
|
||||
}
|
||||
R.id.open_matrix_apps -> {
|
||||
R.id.open_matrix_apps -> {
|
||||
roomDetailViewModel.handle(RoomDetailAction.ManageIntegrations)
|
||||
true
|
||||
}
|
||||
R.id.voice_call -> {
|
||||
R.id.voice_call -> {
|
||||
callActionsHandler.onVoiceCallClicked()
|
||||
true
|
||||
}
|
||||
R.id.video_call -> {
|
||||
R.id.video_call -> {
|
||||
callActionsHandler.onVideoCallClicked()
|
||||
true
|
||||
}
|
||||
R.id.search -> {
|
||||
R.id.threads -> {
|
||||
requireActivity().toast("View All Threads")
|
||||
true
|
||||
}
|
||||
R.id.search -> {
|
||||
handleSearchAction()
|
||||
true
|
||||
}
|
||||
R.id.dev_tools -> {
|
||||
navigator.openDevTools(requireContext(), roomDetailArgs.roomId)
|
||||
R.id.dev_tools -> {
|
||||
navigator.openDevTools(requireContext(), timelineArgs.roomId)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
R.id.menu_thread_timeline_copy_link -> {
|
||||
requireActivity().toast("menu_thread_timeline_copy_link")
|
||||
true
|
||||
}
|
||||
R.id.menu_thread_timeline_view_in_room -> {
|
||||
handleViewInRoomAction()
|
||||
true
|
||||
}
|
||||
R.id.menu_thread_timeline_share -> {
|
||||
requireActivity().toast("menu_thread_timeline_share")
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View and highlight the original root thread message in the main timeline
|
||||
*/
|
||||
private fun handleViewInRoomAction(){
|
||||
getRootThreadEventId()?.let {
|
||||
val newRoom = timelineArgs.copy(threadTimelineArgs = null,eventId = it)
|
||||
context?.let{ con ->
|
||||
val int = RoomDetailActivity.newIntent(con, newRoom)
|
||||
int.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
con.startActivity(int)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSearchAction() {
|
||||
if (session.getRoom(roomDetailArgs.roomId)?.isEncrypted() == false) {
|
||||
navigator.openSearch(requireContext(), roomDetailArgs.roomId)
|
||||
if (session.getRoom(timelineArgs.roomId)?.isEncrypted() == false) {
|
||||
navigator.openSearch(requireContext(), timelineArgs.roomId)
|
||||
} else {
|
||||
showDialogWithMessage(getString(R.string.search_is_not_supported_in_e2e_room))
|
||||
}
|
||||
|
@ -1080,7 +1093,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
notificationDrawerManager.setCurrentRoom(roomDetailArgs.roomId)
|
||||
notificationDrawerManager.setCurrentRoom(timelineArgs.roomId)
|
||||
roomDetailPendingActionStore.data?.let { handlePendingAction(it) }
|
||||
roomDetailPendingActionStore.data = null
|
||||
|
||||
|
@ -1322,7 +1335,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
views.composerLayout.callback = object : TextComposerView.Callback {
|
||||
override fun onAddAttachment() {
|
||||
if (!::attachmentTypeSelector.isInitialized) {
|
||||
attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@RoomDetailFragment)
|
||||
attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@TimelineFragment)
|
||||
}
|
||||
attachmentTypeSelector.show(views.composerLayout.views.attachmentButton, keyboardStateUtils.isKeyboardShowing)
|
||||
}
|
||||
|
@ -1420,7 +1433,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
} else if (summary?.membership == Membership.INVITE && inviter != null) {
|
||||
views.hideComposerViews()
|
||||
lazyLoadedViews.inviteView(true)?.apply {
|
||||
callback = this@RoomDetailFragment
|
||||
callback = this@TimelineFragment
|
||||
isVisible = true
|
||||
render(inviter, VectorInviteView.Mode.LARGE, mainState.changeMembershipState)
|
||||
setOnClickListener { }
|
||||
|
@ -1437,23 +1450,35 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun renderToolbar(roomSummary: RoomSummary?, typingMessage: String?) {
|
||||
if (roomSummary == null) {
|
||||
views.roomToolbarContentView.isClickable = false
|
||||
if (!isThreadTimeLine()) {
|
||||
views.includeRoomToolbar.roomToolbarContentView.isVisible = true
|
||||
views.includeThreadToolbar.roomToolbarThreadConstraintLayout.isVisible = false
|
||||
if (roomSummary == null) {
|
||||
views.includeRoomToolbar.roomToolbarContentView.isClickable = false
|
||||
} else {
|
||||
views.includeRoomToolbar.roomToolbarContentView.isClickable = roomSummary.membership == Membership.JOIN
|
||||
views.includeRoomToolbar.roomToolbarTitleView.text = roomSummary.displayName
|
||||
avatarRenderer.render(roomSummary.toMatrixItem(), views.includeRoomToolbar.roomToolbarAvatarImageView)
|
||||
renderSubTitle(typingMessage, roomSummary.topic)
|
||||
views.includeRoomToolbar.roomToolbarDecorationImageView.render(roomSummary.roomEncryptionTrustLevel)
|
||||
views.includeRoomToolbar.roomToolbarPresenceImageView.render(roomSummary.isDirect, roomSummary.directUserPresence)
|
||||
views.includeRoomToolbar.roomToolbarPublicImageView.isVisible = roomSummary.isPublic && !roomSummary.isDirect
|
||||
}
|
||||
} else {
|
||||
views.roomToolbarContentView.isClickable = roomSummary.membership == Membership.JOIN
|
||||
views.roomToolbarTitleView.text = roomSummary.displayName
|
||||
avatarRenderer.render(roomSummary.toMatrixItem(), views.roomToolbarAvatarImageView)
|
||||
renderSubTitle(typingMessage, roomSummary.topic)
|
||||
views.roomToolbarDecorationImageView.render(roomSummary.roomEncryptionTrustLevel)
|
||||
views.roomToolbarPresenceImageView.render(roomSummary.isDirect, roomSummary.directUserPresence)
|
||||
views.roomToolbarPublicImageView.isVisible = roomSummary.isPublic && !roomSummary.isDirect
|
||||
views.includeRoomToolbar.roomToolbarContentView.isVisible = false
|
||||
views.includeThreadToolbar.roomToolbarThreadConstraintLayout.isVisible = true
|
||||
timelineArgs.threadTimelineArgs?.let {
|
||||
val matrixItem = MatrixItem.RoomItem(it.roomId, it.displayName, it.avatarUrl)
|
||||
avatarRenderer.render(matrixItem, views.includeThreadToolbar.roomToolbarThreadImageView)
|
||||
views.includeThreadToolbar.roomToolbarThreadSubtitleTextView.text = it.displayName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderSubTitle(typingMessage: String?, topic: String) {
|
||||
// TODO Temporary place to put typing data
|
||||
val subtitle = typingMessage?.takeIf { it.isNotBlank() } ?: topic
|
||||
views.roomToolbarSubtitleView.apply {
|
||||
views.includeRoomToolbar.roomToolbarSubtitleView.apply {
|
||||
setTextOrHide(subtitle)
|
||||
if (typingMessage.isNullOrBlank()) {
|
||||
setTextColor(colorProvider.getColorFromAttribute(R.attr.vctr_content_primary))
|
||||
|
@ -1592,14 +1617,14 @@ class RoomDetailFragment @Inject constructor(
|
|||
is RoomDetailAction.RequestVerification -> {
|
||||
Timber.v("## SAS RequestVerification action")
|
||||
VerificationBottomSheet.withArgs(
|
||||
roomDetailArgs.roomId,
|
||||
timelineArgs.roomId,
|
||||
data.userId
|
||||
).show(parentFragmentManager, "REQ")
|
||||
}
|
||||
is RoomDetailAction.AcceptVerificationRequest -> {
|
||||
Timber.v("## SAS AcceptVerificationRequest action")
|
||||
VerificationBottomSheet.withArgs(
|
||||
roomDetailArgs.roomId,
|
||||
timelineArgs.roomId,
|
||||
data.otherUserId,
|
||||
data.transactionId
|
||||
).show(parentFragmentManager, "REQ")
|
||||
|
@ -1609,7 +1634,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
VerificationBottomSheet().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(Mavericks.KEY_ARG, VerificationBottomSheet.VerificationArgs(
|
||||
otherUserId, data.transactionId, roomId = roomDetailArgs.roomId))
|
||||
otherUserId, data.transactionId, roomId = timelineArgs.roomId))
|
||||
}
|
||||
}.show(parentFragmentManager, "REQ")
|
||||
}
|
||||
|
@ -1624,7 +1649,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
.launch(requireActivity(), url, object : NavigationInterceptor {
|
||||
override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?): Boolean {
|
||||
// Same room?
|
||||
if (roomId == roomDetailArgs.roomId) {
|
||||
if (roomId == timelineArgs.roomId) {
|
||||
// Navigation to same room
|
||||
if (eventId == null) {
|
||||
showSnackWithMessage(getString(R.string.navigate_to_room_when_already_in_the_room))
|
||||
|
@ -1691,7 +1716,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
override fun onImageMessageClicked(messageImageContent: MessageImageInfoContent, mediaData: ImageContentRenderer.Data, view: View) {
|
||||
navigator.openMediaViewer(
|
||||
activity = requireActivity(),
|
||||
roomId = roomDetailArgs.roomId,
|
||||
roomId = timelineArgs.roomId,
|
||||
mediaData = mediaData,
|
||||
view = view
|
||||
) { pairs ->
|
||||
|
@ -1703,7 +1728,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
override fun onVideoMessageClicked(messageVideoContent: MessageVideoContent, mediaData: VideoContentRenderer.Data, view: View) {
|
||||
navigator.openMediaViewer(
|
||||
activity = requireActivity(),
|
||||
roomId = roomDetailArgs.roomId,
|
||||
roomId = timelineArgs.roomId,
|
||||
mediaData = mediaData,
|
||||
view = view
|
||||
) { pairs ->
|
||||
|
@ -1738,7 +1763,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
roomDetailViewModel.handle(RoomDetailAction.LoadMoreTimelineEvents(direction))
|
||||
}
|
||||
|
||||
override fun onEventCellClicked(informationData: MessageInformationData, messageContent: Any?, view: View) {
|
||||
override fun onEventCellClicked(informationData: MessageInformationData, messageContent: Any?, view: View, isRootThreadEvent: Boolean) {
|
||||
when (messageContent) {
|
||||
is MessageVerificationRequestContent -> {
|
||||
roomDetailViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId, null))
|
||||
|
@ -1751,11 +1776,14 @@ class RoomDetailFragment @Inject constructor(
|
|||
roomDetailViewModel.handle(RoomDetailAction.TapOnFailedToDecrypt(informationData.eventId))
|
||||
}
|
||||
}
|
||||
if (isRootThreadEvent) {
|
||||
navigateToThreadTimeline(informationData.eventId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEventLongClicked(informationData: MessageInformationData, messageContent: Any?, view: View): Boolean {
|
||||
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
|
||||
val roomId = roomDetailArgs.roomId
|
||||
val roomId = timelineArgs.roomId
|
||||
this.view?.hideKeyboard()
|
||||
|
||||
MessageActionsBottomSheet
|
||||
|
@ -1786,7 +1814,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun openRoomMemberProfile(userId: String) {
|
||||
navigator.openRoomMemberProfile(userId = userId, roomId = roomDetailArgs.roomId, context = requireActivity())
|
||||
navigator.openRoomMemberProfile(userId = userId, roomId = timelineArgs.roomId, context = requireActivity())
|
||||
}
|
||||
|
||||
override fun onMemberNameClicked(informationData: MessageInformationData) {
|
||||
|
@ -1804,12 +1832,12 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onLongClickOnReactionPill(informationData: MessageInformationData, reaction: String) {
|
||||
ViewReactionsBottomSheet.newInstance(roomDetailArgs.roomId, informationData)
|
||||
ViewReactionsBottomSheet.newInstance(timelineArgs.roomId, informationData)
|
||||
.show(requireActivity().supportFragmentManager, "DISPLAY_REACTIONS")
|
||||
}
|
||||
|
||||
override fun onEditedDecorationClicked(informationData: MessageInformationData) {
|
||||
ViewEditHistoryBottomSheet.newInstance(roomDetailArgs.roomId, informationData)
|
||||
ViewEditHistoryBottomSheet.newInstance(timelineArgs.roomId, informationData)
|
||||
.show(requireActivity().supportFragmentManager, "DISPLAY_EDITS")
|
||||
}
|
||||
|
||||
|
@ -1921,7 +1949,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
emojiActivityResultLauncher.launch(EmojiReactionPickerActivity.intent(requireContext(), action.eventId))
|
||||
}
|
||||
is EventSharedAction.ViewReactions -> {
|
||||
ViewReactionsBottomSheet.newInstance(roomDetailArgs.roomId, action.messageInformationData)
|
||||
ViewReactionsBottomSheet.newInstance(timelineArgs.roomId, action.messageInformationData)
|
||||
.show(requireActivity().supportFragmentManager, "DISPLAY_REACTIONS")
|
||||
}
|
||||
is EventSharedAction.Copy -> {
|
||||
|
@ -1978,20 +2006,13 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
is EventSharedAction.ReplyInThread -> {
|
||||
if (!views.voiceMessageRecorderView.isActive()) {
|
||||
context?.let {
|
||||
val roomThreadDetailArgs = RoomThreadDetailArgs(
|
||||
roomId = roomDetailArgs.roomId,
|
||||
displayName = roomDetailViewModel.getRoomSummary()?.displayName,
|
||||
avatarUrl = roomDetailViewModel.getRoomSummary()?.avatarUrl,
|
||||
eventId = action.eventId)
|
||||
startActivity(RoomThreadDetailActivity.newIntent(it, roomThreadDetailArgs))
|
||||
}
|
||||
navigateToThreadTimeline(action.eventId)
|
||||
} else {
|
||||
requireActivity().toast(R.string.error_voice_message_cannot_reply_or_edit)
|
||||
}
|
||||
}
|
||||
is EventSharedAction.CopyPermalink -> {
|
||||
val permalink = session.permalinkService().createPermalink(roomDetailArgs.roomId, action.eventId)
|
||||
val permalink = session.permalinkService().createPermalink(timelineArgs.roomId, action.eventId)
|
||||
copyToClipboard(requireContext(), permalink, false)
|
||||
showSnackWithMessage(getString(R.string.copied_to_clipboard))
|
||||
}
|
||||
|
@ -2114,15 +2135,31 @@ class RoomDetailFragment @Inject constructor(
|
|||
.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to Threads timeline for the specified threadRootEventId
|
||||
* using the RoomThreadDetailActivity
|
||||
*/
|
||||
|
||||
private fun navigateToThreadTimeline(rootThreadEventId: String) {
|
||||
context?.let {
|
||||
val roomThreadDetailArgs = ThreadTimelineArgs(
|
||||
roomId = timelineArgs.roomId,
|
||||
displayName = roomDetailViewModel.getRoomSummary()?.displayName,
|
||||
avatarUrl = roomDetailViewModel.getRoomSummary()?.avatarUrl,
|
||||
rootThreadEventId = rootThreadEventId)
|
||||
navigator.openThread(it, roomThreadDetailArgs)
|
||||
}
|
||||
}
|
||||
|
||||
// VectorInviteView.Callback
|
||||
|
||||
override fun onAcceptInvite() {
|
||||
notificationDrawerManager.clearMemberShipNotificationForRoom(roomDetailArgs.roomId)
|
||||
notificationDrawerManager.clearMemberShipNotificationForRoom(timelineArgs.roomId)
|
||||
roomDetailViewModel.handle(RoomDetailAction.AcceptInvite)
|
||||
}
|
||||
|
||||
override fun onRejectInvite() {
|
||||
notificationDrawerManager.clearMemberShipNotificationForRoom(roomDetailArgs.roomId)
|
||||
notificationDrawerManager.clearMemberShipNotificationForRoom(timelineArgs.roomId)
|
||||
roomDetailViewModel.handle(RoomDetailAction.RejectInvite)
|
||||
}
|
||||
|
||||
|
@ -2221,6 +2258,13 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun isThreadTimeLine(): Boolean = roomDetailArgs.roomThreadDetailArgs != null
|
||||
fun getRootThreadEventId(): String? = roomDetailArgs.roomThreadDetailArgs?.eventId
|
||||
/**
|
||||
* Returns true if the current room is a Thread room, false otherwise
|
||||
*/
|
||||
private fun isThreadTimeLine(): Boolean = timelineArgs.threadTimelineArgs?.rootThreadEventId != null
|
||||
|
||||
/**
|
||||
* Returns the root thread event if we are in a thread room, otherwise returns null
|
||||
*/
|
||||
fun getRootThreadEventId(): String? = timelineArgs.threadTimelineArgs?.rootThreadEventId
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.detail.arguments
|
||||
|
||||
import android.os.Parcelable
|
||||
import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
|
||||
import im.vector.app.features.share.SharedData
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class TimelineArgs(
|
||||
val roomId: String,
|
||||
val eventId: String? = null,
|
||||
val sharedData: SharedData? = null,
|
||||
val openShareSpaceForId: String? = null,
|
||||
val threadTimelineArgs: ThreadTimelineArgs? = null
|
||||
) : Parcelable
|
|
@ -29,7 +29,7 @@ import im.vector.app.core.resources.StringProvider
|
|||
import im.vector.app.features.command.CommandParser
|
||||
import im.vector.app.features.command.ParsedCommand
|
||||
import im.vector.app.features.home.room.detail.ChatEffect
|
||||
import im.vector.app.features.home.room.detail.RoomDetailFragment
|
||||
import im.vector.app.features.home.room.detail.TimelineFragment
|
||||
import im.vector.app.features.home.room.detail.composer.rainbow.RainbowGenerator
|
||||
import im.vector.app.features.home.room.detail.toMessageType
|
||||
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
|
||||
|
@ -42,7 +42,6 @@ import org.commonmark.renderer.html.HtmlRenderer
|
|||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.events.model.getRootThreadEventId
|
||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||
|
@ -772,7 +771,7 @@ class TextComposerViewModel @AssistedInject constructor(
|
|||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: TextComposerViewState): TextComposerViewModel {
|
||||
val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
val fragment: TimelineFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
return fragment.textComposerViewModelFactory.create(state)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package im.vector.app.features.home.room.detail.composer
|
||||
|
||||
import com.airbnb.mvrx.MavericksState
|
||||
import im.vector.app.features.home.room.detail.RoomDetailArgs
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
|
||||
/**
|
||||
|
@ -53,9 +53,9 @@ data class TextComposerViewState(
|
|||
val isComposerVisible: Boolean
|
||||
get() = canSendMessage && !isVoiceRecording
|
||||
|
||||
constructor(args: RoomDetailArgs) : this(
|
||||
constructor(args: TimelineArgs) : this(
|
||||
roomId = args.roomId,
|
||||
rootThreadEventId = args.roomThreadDetailArgs?.eventId)
|
||||
rootThreadEventId = args.threadTimelineArgs?.rootThreadEventId)
|
||||
|
||||
fun isInThreadTimeline(): Boolean = rootThreadEventId != null
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
|||
}
|
||||
|
||||
interface BaseCallback {
|
||||
fun onEventCellClicked(informationData: MessageInformationData, messageContent: Any?, view: View)
|
||||
fun onEventCellClicked(informationData: MessageInformationData, messageContent: Any?, view: View, isRootThreadEvent: Boolean)
|
||||
fun onEventLongClicked(informationData: MessageInformationData, messageContent: Any?, view: View): Boolean
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class MessageItemAttributesFactory @Inject constructor(
|
|||
callback?.onEventLongClicked(informationData, messageContent, view) ?: false
|
||||
},
|
||||
itemClickListener = { view ->
|
||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||
callback?.onEventCellClicked(informationData, messageContent, view, threadDetails?.isRootThread ?: false)
|
||||
},
|
||||
memberClickListener = {
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright 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
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivityFilteredRoomsBinding
|
||||
import im.vector.app.databinding.ActivityRoomThreadsBinding
|
||||
import im.vector.app.features.home.RoomListDisplayMode
|
||||
import im.vector.app.features.home.room.list.RoomListFragment
|
||||
import im.vector.app.features.home.room.list.RoomListParams
|
||||
|
||||
class RoomThreadsActivity : VectorBaseActivity<ActivityRoomThreadsBinding>() {
|
||||
|
||||
// private val roomListFragment: RoomListFragment?
|
||||
// get() {
|
||||
// return supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? RoomListFragment
|
||||
// }
|
||||
|
||||
override fun getBinding() = ActivityRoomThreadsBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getMenuRes() = R.menu.menu_room_threads
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
configureToolbar(views.roomThreadsToolbar)
|
||||
// if (isFirstCreation()) {
|
||||
// val params = RoomListParams(RoomListDisplayMode.FILTERED)
|
||||
// replaceFragment(R.id.filteredRoomsFragmentContainer, RoomListFragment::class.java, params, FRAGMENT_TAG)
|
||||
// }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val FRAGMENT_TAG = "RoomListFragment"
|
||||
|
||||
fun newIntent(context: Context): Intent {
|
||||
return Intent(context, RoomThreadsActivity::class.java)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.platform.VectorViewModelAction
|
||||
import im.vector.app.databinding.ActivityThreadsBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import im.vector.app.features.home.room.detail.TimelineFragment
|
||||
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.detail.ThreadListFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
class ThreadsActivity : VectorBaseActivity<ActivityThreadsBinding>(), ToolbarConfigurable {
|
||||
|
||||
@Inject
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
// private val roomThreadDetailFragment: RoomThreadDetailFragment?
|
||||
// get() {
|
||||
// return supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? RoomThreadDetailFragment
|
||||
// }
|
||||
|
||||
override fun getBinding() = ActivityThreadsBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
initFragment()
|
||||
}
|
||||
|
||||
private fun initFragment() {
|
||||
if (isFirstCreation()) {
|
||||
when (val fragment = fragmentToNavigate()) {
|
||||
is DisplayFragment.ThreadList -> {
|
||||
initThreadListFragment(fragment.threadListArgs)
|
||||
}
|
||||
is DisplayFragment.ThreadTimeLine -> {
|
||||
initThreadTimelineFragment(fragment.threadTimelineArgs)
|
||||
}
|
||||
is DisplayFragment.ErrorFragment -> {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initThreadListFragment(threadListArgs: ThreadListArgs) {
|
||||
replaceFragment(
|
||||
R.id.threadsActivityFragmentContainer,
|
||||
ThreadListFragment::class.java,
|
||||
threadListArgs)
|
||||
}
|
||||
|
||||
private fun initThreadTimelineFragment(threadTimelineArgs: ThreadTimelineArgs) =
|
||||
replaceFragment(
|
||||
R.id.threadsActivityFragmentContainer,
|
||||
TimelineFragment::class.java,
|
||||
TimelineArgs(
|
||||
roomId = threadTimelineArgs.roomId,
|
||||
threadTimelineArgs = threadTimelineArgs
|
||||
))
|
||||
|
||||
override fun configure(toolbar: MaterialToolbar) {
|
||||
configureToolbar(toolbar)
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine in witch fragment we should navigate
|
||||
*/
|
||||
private fun fragmentToNavigate(): DisplayFragment {
|
||||
getThreadTimelineArgs()?.let {
|
||||
return DisplayFragment.ThreadTimeLine(it)
|
||||
}
|
||||
getThreadListArgs()?.let {
|
||||
return DisplayFragment.ThreadList(it)
|
||||
}
|
||||
return DisplayFragment.ErrorFragment
|
||||
}
|
||||
|
||||
private fun getThreadTimelineArgs(): ThreadTimelineArgs? = intent?.extras?.getParcelable(THREAD_TIMELINE_ARGS)
|
||||
private fun getThreadListArgs(): ThreadListArgs? = intent?.extras?.getParcelable(THREAD_LIST_ARGS)
|
||||
|
||||
companion object {
|
||||
// private val FRAGMENT_TAG = RoomThreadDetailFragment::class.simpleName
|
||||
const val THREAD_TIMELINE_ARGS = "THREAD_TIMELINE_ARGS"
|
||||
const val THREAD_LIST_ARGS = "THREAD_LIST_ARGS"
|
||||
|
||||
fun newIntent(context: Context, threadTimelineArgs: ThreadTimelineArgs?, threadListArgs: ThreadListArgs?): Intent {
|
||||
return Intent(context, ThreadsActivity::class.java).apply {
|
||||
putExtra(THREAD_TIMELINE_ARGS, threadTimelineArgs)
|
||||
putExtra(THREAD_LIST_ARGS, threadListArgs)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class DisplayFragment {
|
||||
data class ThreadList(val threadListArgs: ThreadListArgs) : DisplayFragment()
|
||||
data class ThreadTimeLine(val threadTimelineArgs: ThreadTimelineArgs) : DisplayFragment()
|
||||
object ErrorFragment : DisplayFragment()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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.arguments
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class ThreadListArgs(
|
||||
val roomId: String
|
||||
) : Parcelable
|
|
@ -14,15 +14,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.home.room.threads.detail.arguments
|
||||
package im.vector.app.features.home.room.threads.arguments
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class RoomThreadDetailArgs(
|
||||
data class ThreadTimelineArgs(
|
||||
val roomId: String,
|
||||
val displayName: String?,
|
||||
val avatarUrl: String?,
|
||||
val eventId: String? = null,
|
||||
val rootThreadEventId: String? = null
|
||||
) : Parcelable
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* Copyright 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.detail
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivityRoomThreadDetailBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.RoomDetailArgs
|
||||
import im.vector.app.features.home.room.detail.RoomDetailFragment
|
||||
import im.vector.app.features.home.room.threads.detail.arguments.RoomThreadDetailArgs
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomThreadDetailActivity : VectorBaseActivity<ActivityRoomThreadDetailBinding>() {
|
||||
|
||||
@Inject
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
// private val roomThreadDetailFragment: RoomThreadDetailFragment?
|
||||
// get() {
|
||||
// return supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? RoomThreadDetailFragment
|
||||
// }
|
||||
|
||||
override fun getBinding() = ActivityRoomThreadDetailBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getMenuRes() = R.menu.menu_room_threads
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
initToolbar()
|
||||
initFragment()
|
||||
}
|
||||
|
||||
private fun initToolbar() {
|
||||
configureToolbar(views.roomThreadDetailToolbar)
|
||||
getRoomThreadDetailArgs()?.let {
|
||||
val matrixItem = MatrixItem.RoomItem(it.roomId, it.displayName, it.avatarUrl)
|
||||
avatarRenderer.render(matrixItem, views.roomThreadDetailToolbarImageView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initFragment() {
|
||||
if (isFirstCreation()) {
|
||||
getRoomThreadDetailArgs()?.let {
|
||||
replaceFragment(
|
||||
R.id.roomThreadDetailFragmentContainer,
|
||||
RoomDetailFragment::class.java,
|
||||
RoomDetailArgs(
|
||||
roomId = it.roomId,
|
||||
roomThreadDetailArgs = it
|
||||
))
|
||||
}
|
||||
// replaceFragment(R.id.roomThreadDetailFragmentContainer, RoomThreadDetailFragment::class.java, getRoomThreadDetailArgs(), FRAGMENT_TAG)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRoomThreadDetailArgs(): RoomThreadDetailArgs? = intent?.extras?.getParcelable(ROOM_THREAD_DETAIL_ARGS)
|
||||
|
||||
companion object {
|
||||
private val FRAGMENT_TAG = RoomThreadDetailFragment::class.simpleName
|
||||
const val ROOM_THREAD_DETAIL_ARGS = "ROOM_THREAD_DETAIL_ARGS"
|
||||
|
||||
fun newIntent(context: Context, roomThreadDetailArgs: RoomThreadDetailArgs): Intent {
|
||||
return Intent(context, RoomThreadDetailActivity::class.java).apply {
|
||||
putExtra(ROOM_THREAD_DETAIL_ARGS, roomThreadDetailArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,34 +16,31 @@
|
|||
|
||||
package im.vector.app.features.home.room.threads.detail
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.args
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentRoomThreadDetailBinding
|
||||
import im.vector.app.features.home.room.threads.detail.arguments.RoomThreadDetailArgs
|
||||
import im.vector.app.databinding.FragmentThreadListBinding
|
||||
import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomThreadDetailFragment @Inject constructor(
|
||||
class ThreadListFragment @Inject constructor(
|
||||
private val session: Session
|
||||
) : VectorBaseFragment<FragmentRoomThreadDetailBinding>() {
|
||||
) : VectorBaseFragment<FragmentThreadListBinding>() {
|
||||
|
||||
private val roomThreadDetailArgs: RoomThreadDetailArgs by args()
|
||||
private val threadTimelineArgs: ThreadTimelineArgs by args()
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomThreadDetailBinding {
|
||||
return FragmentRoomThreadDetailBinding.inflate(inflater, container, false)
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentThreadListBinding {
|
||||
return FragmentThreadListBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
initTextComposer()
|
||||
|
@ -59,7 +56,7 @@ class RoomThreadDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun initTextComposer(){
|
||||
views.roomThreadDetailTextComposerView.views.sendButton.isVisible = true
|
||||
// views.roomThreadDetailTextComposerView.views.sendButton.isVisible = true
|
||||
}
|
||||
|
||||
}
|
|
@ -49,10 +49,13 @@ import im.vector.app.features.crypto.verification.VerificationBottomSheet
|
|||
import im.vector.app.features.debug.DebugMenuActivity
|
||||
import im.vector.app.features.devtools.RoomDevToolActivity
|
||||
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||
import im.vector.app.features.home.room.detail.RoomDetailArgs
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import im.vector.app.features.home.room.detail.search.SearchActivity
|
||||
import im.vector.app.features.home.room.detail.search.SearchArgs
|
||||
import im.vector.app.features.home.room.filtered.FilteredRoomsActivity
|
||||
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.ThreadTimelineArgs
|
||||
import im.vector.app.features.invite.InviteUsersToRoomActivity
|
||||
import im.vector.app.features.login.LoginActivity
|
||||
import im.vector.app.features.login.LoginConfig
|
||||
|
@ -118,7 +121,7 @@ class DefaultNavigator @Inject constructor(
|
|||
fatalError("Trying to open an unknown room $roomId", vectorPreferences.failFast())
|
||||
return
|
||||
}
|
||||
val args = RoomDetailArgs(roomId, eventId)
|
||||
val args = TimelineArgs(roomId, eventId)
|
||||
val intent = RoomDetailActivity.newIntent(context, args)
|
||||
startActivity(context, intent, buildTask)
|
||||
}
|
||||
|
@ -141,7 +144,7 @@ class DefaultNavigator @Inject constructor(
|
|||
startActivity(context, SpaceManageActivity.newIntent(context, spaceId, ManageType.AddRooms), false)
|
||||
}
|
||||
is Navigator.PostSwitchSpaceAction.OpenDefaultRoom -> {
|
||||
val args = RoomDetailArgs(
|
||||
val args = TimelineArgs(
|
||||
postSwitchSpaceAction.roomId,
|
||||
eventId = null,
|
||||
openShareSpaceForId = spaceId.takeIf { postSwitchSpaceAction.showShareSheet }
|
||||
|
@ -239,7 +242,7 @@ class DefaultNavigator @Inject constructor(
|
|||
}
|
||||
|
||||
override fun openRoomForSharingAndFinish(activity: Activity, roomId: String, sharedData: SharedData) {
|
||||
val args = RoomDetailArgs(roomId, null, sharedData)
|
||||
val args = TimelineArgs(roomId, null, sharedData)
|
||||
val intent = RoomDetailActivity.newIntent(activity, args)
|
||||
activity.startActivity(intent)
|
||||
activity.finish()
|
||||
|
@ -507,4 +510,11 @@ class DefaultNavigator @Inject constructor(
|
|||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun openThread(context: Context, threadTimelineArgs: ThreadTimelineArgs) {
|
||||
context.startActivity(ThreadsActivity.newIntent(
|
||||
context = context,
|
||||
threadTimelineArgs = threadTimelineArgs,
|
||||
threadListArgs =null))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import androidx.activity.result.ActivityResultLauncher
|
|||
import androidx.core.util.Pair
|
||||
import im.vector.app.features.crypto.recover.SetupMode
|
||||
import im.vector.app.features.displayname.getBestName
|
||||
import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
|
||||
import im.vector.app.features.login.LoginConfig
|
||||
import im.vector.app.features.media.AttachmentData
|
||||
import im.vector.app.features.pin.PinMode
|
||||
|
@ -140,4 +141,7 @@ interface Navigator {
|
|||
fun openDevTools(context: Context, roomId: String)
|
||||
|
||||
fun openCallTransfer(context: Context, callId: String)
|
||||
|
||||
fun openThread(context: Context, threadTimelineArgs: ThreadTimelineArgs)
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ import im.vector.app.features.call.webrtc.WebRtcCall
|
|||
import im.vector.app.features.displayname.getBestName
|
||||
import im.vector.app.features.home.HomeActivity
|
||||
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||
import im.vector.app.features.home.room.detail.RoomDetailArgs
|
||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.settings.troubleshoot.TestNotificationReceiver
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
@ -497,7 +497,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
|
|||
|
||||
val contentPendingIntent = TaskStackBuilder.create(context)
|
||||
.addNextIntentWithParentStack(HomeActivity.newIntent(context))
|
||||
.addNextIntent(RoomDetailActivity.newIntent(context, RoomDetailArgs(callInformation.nativeRoomId)))
|
||||
.addNextIntent(RoomDetailActivity.newIntent(context, TimelineArgs(callInformation.nativeRoomId)))
|
||||
.getPendingIntent(System.currentTimeMillis().toInt(), PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
|
||||
builder.setContentIntent(contentPendingIntent)
|
||||
|
@ -735,7 +735,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
|
|||
}
|
||||
|
||||
private fun buildOpenRoomIntent(roomId: String): PendingIntent? {
|
||||
val roomIntentTap = RoomDetailActivity.newIntent(context, RoomDetailArgs(roomId))
|
||||
val roomIntentTap = RoomDetailActivity.newIntent(context, TimelineArgs(roomId))
|
||||
roomIntentTap.action = TAP_TO_VIEW_ACTION
|
||||
// pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
|
||||
roomIntentTap.data = Uri.parse("foobar://openRoom?$roomId")
|
||||
|
|
12
vector/src/main/res/drawable/ic_thread_link_menu_item.xml
Normal file
12
vector/src/main/res/drawable/ic_thread_link_menu_item.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12.604,5.761L13.1741,5.1909C14.7488,3.6163 17.2867,3.6012 18.8428,5.1572C20.3988,6.7132 20.3837,9.251 18.809,10.8257L16.1004,13.5342C14.5257,15.1089 11.9877,15.124 10.4317,13.568M11.3962,18.2387L10.8259,18.8091C9.2512,20.3837 6.7133,20.3988 5.1572,18.8428C3.6012,17.2868 3.6163,14.749 5.191,13.1743L7.8995,10.4659C9.4741,8.8913 12.0121,8.8762 13.5681,10.4322"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#737D8C"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
10
vector/src/main/res/drawable/ic_thread_menu_item.xml
Normal file
10
vector/src/main/res/drawable/ic_thread_menu_item.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M2,5C2,3.3431 3.3431,2 5,2H19C20.6565,2 22,3.3422 22,4.9994V17C22,18.6569 20.6569,20 19,20H7.6667C7.4503,20 7.2398,20.0702 7.0667,20.2L3.6,22.8C3.297,23.0273 2.8916,23.0638 2.5528,22.8944C2.214,22.725 2,22.3788 2,22V5ZM5,9C5,8.4477 5.4477,8 6,8H18C18.5523,8 19,8.4477 19,9C19,9.5523 18.5523,10 18,10H6C5.4477,10 5,9.5523 5,9ZM6,12C5.4477,12 5,12.4477 5,13C5,13.5523 5.4477,14 6,14H12C12.5523,14 13,13.5523 13,13C13,12.4477 12.5523,12 12,12H6Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
19
vector/src/main/res/drawable/ic_thread_share_menu_item.xml
Normal file
19
vector/src/main/res/drawable/ic_thread_share_menu_item.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M16,7C16,6.4477 16.4477,6 17,6C17.5523,6 18,6.4477 18,7C18,7.5523 17.5523,8 17,8C16.4477,8 16,7.5523 16,7ZM17,4C15.3431,4 14,5.3432 14,7C14,7.0876 14.0038,7.1744 14.0111,7.2601L8.1611,9.9192C7.6154,9.3525 6.8489,9 6,9C4.3432,9 3,10.3431 3,12C3,13.6569 4.3432,15 6,15C6.8488,15 7.6154,14.6474 8.1611,14.0808L14.0111,16.7399C14.0038,16.8256 14,16.9124 14,17C14,18.6569 15.3431,20 17,20C18.6569,20 20,18.6569 20,17C20,15.3431 18.6569,14 17,14C16.1511,14 15.3846,14.3526 14.8389,14.9192L8.9889,12.2601C8.9962,12.1744 9,12.0876 9,12C9,11.9124 8.9962,11.8256 8.9889,11.7399L14.8389,9.0808C15.3846,9.6475 16.1511,10 17,10C18.6569,10 20,8.6568 20,7C20,5.3432 18.6569,4 17,4ZM17,16C16.4477,16 16,16.4477 16,17C16,17.5523 16.4477,18 17,18C17.5523,18 18,17.5523 18,17C18,16.4477 17.5523,16 17,16ZM5,12C5,11.4477 5.4477,11 6,11C6.5523,11 7,11.4477 7,12C7,12.5523 6.5523,13 6,13C5.4477,13 5,12.5523 5,12Z"
|
||||
android:fillColor="#737D8C"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M17,17m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0"
|
||||
android:fillColor="#737D8C"/>
|
||||
<path
|
||||
android:pathData="M17,7m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0"
|
||||
android:fillColor="#737D8C"/>
|
||||
<path
|
||||
android:pathData="M6,12m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0"
|
||||
android:fillColor="#737D8C"/>
|
||||
</vector>
|
|
@ -0,0 +1,30 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M3,4H21"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#737D8C"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M3,10H16"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#737D8C"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M3,14H11"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#737D8C"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M3,20H21"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#737D8C"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
|
@ -1,88 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/coordinatorLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/roomThreadDetailToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:contentInsetStart="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/roomThreadDetailToolbarConstraintLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomThreadDetailToolbarTitleTextView"
|
||||
style="@style/Widget.Vector.TextView.HeadlineMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/a11y_beta"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomThreadDetailToolbarImageView"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_presence_offline"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/roomThreadDetailToolbarTitleTextView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@sample/room_round_avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomThreadDetailToolbarSubtitleTextView"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/roomThreadDetailToolbarImageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="RoomName"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/roomThreadDetailFragmentContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/appBarLayout" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -1,88 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/coordinatorLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/roomThreadsToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:contentInsetStart="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/roomThreadsToolbarConstraintLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomThreadsToolbarTitleTextView"
|
||||
style="@style/Widget.Vector.TextView.HeadlineMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/a11y_beta"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomThreadsToolbarImageView"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_presence_offline"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/roomThreadsToolbarTitleTextView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@sample/room_round_avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomThreadsToolbarSubtitleTextView"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/roomThreadsToolbarImageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="RoomName"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/roomThreadsFragmentContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/appBarLayout" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
24
vector/src/main/res/layout/activity_threads.xml
Normal file
24
vector/src/main/res/layout/activity_threads.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/coordinatorLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/threadsActivityFragmentContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -26,101 +26,13 @@
|
|||
android:layout_height="?actionBarSize"
|
||||
android:transitionName="toolbar">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/roomToolbarContentView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<include
|
||||
android:id="@+id/includeThreadToolbar"
|
||||
layout="@layout/view_room_detail_thread_toolbar" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomToolbarAvatarImageView"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@sample/room_round_avatars" />
|
||||
|
||||
<im.vector.app.core.ui.views.ShieldImageView
|
||||
android:id="@+id/roomToolbarDecorationImageView"
|
||||
android:layout_width="17dp"
|
||||
android:layout_height="17dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="2dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/roomToolbarTitleView"
|
||||
app:layout_constraintStart_toEndOf="@+id/roomToolbarAvatarImageView"
|
||||
app:layout_constraintTop_toTopOf="@+id/roomToolbarTitleView" />
|
||||
|
||||
<im.vector.app.core.ui.views.PresenceStateImageView
|
||||
android:id="@+id/roomToolbarPresenceImageView"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:background="@drawable/background_circle"
|
||||
android:padding="2dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintCircle="@+id/roomToolbarAvatarImageView"
|
||||
app:layout_constraintCircleAngle="135"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:layout_constraintCircleRadius="8dp"
|
||||
tools:src="@drawable/ic_presence_offline"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomToolbarPublicImageView"
|
||||
android:layout_width="13dp"
|
||||
android:layout_height="13dp"
|
||||
android:background="@drawable/background_circle"
|
||||
android:contentDescription="@string/a11y_public_room"
|
||||
android:padding="1dp"
|
||||
android:src="@drawable/ic_public_room"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintCircle="@+id/roomToolbarAvatarImageView"
|
||||
app:layout_constraintCircleAngle="135"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomToolbarTitleView"
|
||||
style="@style/Widget.Vector.TextView.HeadlineMedium"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/roomToolbarSubtitleView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/roomToolbarDecorationImageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:layout_goneMarginStart="7dp"
|
||||
tools:text="@sample/rooms.json/data/name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomToolbarSubtitleView"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="7dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/roomToolbarAvatarImageView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/roomToolbarTitleView"
|
||||
tools:text="@sample/rooms.json/data/topic"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<include
|
||||
android:id="@+id/includeRoomToolbar"
|
||||
layout="@layout/view_room_detail_toolbar" />
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?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:id="@+id/rootConstraintLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/roomThreadDetailRecyclerView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:overScrollMode="always"
|
||||
app:layout_constraintBottom_toTopOf="@id/roomThreadDetailTextComposerView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<im.vector.app.features.home.room.detail.composer.TextComposerView
|
||||
android:id="@+id/roomThreadDetailTextComposerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:colorBackground"
|
||||
android:minHeight="56dp"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,51 @@
|
|||
<?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:id="@+id/roomToolbarThreadConstraintLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:visibility="gone"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomToolbarThreadTitleTextView"
|
||||
style="@style/Widget.Vector.TextView.HeadlineMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/room_threads_title"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomToolbarThreadImageView"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_presence_offline"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/roomToolbarThreadTitleTextView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@sample/room_round_avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomToolbarThreadSubtitleTextView"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/roomToolbarThreadImageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="RoomName"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
99
vector/src/main/res/layout/view_room_detail_toolbar.xml
Normal file
99
vector/src/main/res/layout/view_room_detail_toolbar.xml
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?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:id="@+id/roomToolbarContentView"
|
||||
tools:visibility="visible"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomToolbarAvatarImageView"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@sample/room_round_avatars" />
|
||||
|
||||
<im.vector.app.core.ui.views.ShieldImageView
|
||||
android:id="@+id/roomToolbarDecorationImageView"
|
||||
android:layout_width="17dp"
|
||||
android:layout_height="17dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="2dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/roomToolbarTitleView"
|
||||
app:layout_constraintStart_toEndOf="@+id/roomToolbarAvatarImageView"
|
||||
app:layout_constraintTop_toTopOf="@+id/roomToolbarTitleView" />
|
||||
|
||||
<im.vector.app.core.ui.views.PresenceStateImageView
|
||||
android:id="@+id/roomToolbarPresenceImageView"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:background="@drawable/background_circle"
|
||||
android:padding="2dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintCircle="@+id/roomToolbarAvatarImageView"
|
||||
app:layout_constraintCircleAngle="135"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:layout_constraintCircleRadius="8dp"
|
||||
tools:src="@drawable/ic_presence_offline"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomToolbarPublicImageView"
|
||||
android:layout_width="13dp"
|
||||
android:layout_height="13dp"
|
||||
android:background="@drawable/background_circle"
|
||||
android:contentDescription="@string/a11y_public_room"
|
||||
android:padding="1dp"
|
||||
android:src="@drawable/ic_public_room"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintCircle="@+id/roomToolbarAvatarImageView"
|
||||
app:layout_constraintCircleAngle="135"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomToolbarTitleView"
|
||||
style="@style/Widget.Vector.TextView.HeadlineMedium"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/roomToolbarSubtitleView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/roomToolbarDecorationImageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:layout_goneMarginStart="7dp"
|
||||
tools:text="@sample/rooms.json/data/name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomToolbarSubtitleView"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="7dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/roomToolbarAvatarImageView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/roomToolbarTitleView"
|
||||
tools:text="@sample/rooms.json/data/topic"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
36
vector/src/main/res/menu/menu_thread_timeline.xml
Normal file
36
vector/src/main/res/menu/menu_thread_timeline.xml
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/test"
|
||||
android:icon="@drawable/ic_search"
|
||||
android:title="@string/action_thread_view_in_room"
|
||||
app:showAsAction="always">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/menuWithIconText"
|
||||
android:icon="@drawable/ic_thread_menu_item"
|
||||
android:title="@string/action_thread_share"
|
||||
/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_thread_timeline_view_in_room"
|
||||
android:icon="@drawable/ic_settings_x"
|
||||
android:title="@string/action_thread_view_in_room"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_thread_timeline_copy"
|
||||
android:title="@string/action_thread_copy_link_to_thread"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_thread_timeline_share"
|
||||
android:title="@string/action_thread_share"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
|
@ -37,11 +37,20 @@
|
|||
app:showAsAction="always"
|
||||
tools:visible="true" />
|
||||
|
||||
<item android:id="@+id/join_conference"
|
||||
<item
|
||||
android:id="@+id/threads"
|
||||
android:icon="@drawable/ic_thread_menu_item"
|
||||
android:title="@string/action_view_threads"
|
||||
android:visible="false"
|
||||
app:iconTint="?colorPrimary"
|
||||
app:showAsAction="always"
|
||||
tools:visible="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/join_conference"
|
||||
android:title="@string/join"
|
||||
app:actionLayout="@layout/layout_join_conference_action"
|
||||
app:showAsAction="always"
|
||||
/>
|
||||
app:showAsAction="always" />
|
||||
|
||||
<item
|
||||
android:id="@+id/open_matrix_apps"
|
||||
|
@ -57,4 +66,36 @@
|
|||
app:showAsAction="never"
|
||||
tools:visible="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_thread_timeline_more"
|
||||
android:icon="@drawable/ic_more_vertical"
|
||||
android:title="@string/action_thread_view_in_room"
|
||||
app:iconTint="?vctr_content_secondary"
|
||||
app:showAsAction="always">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/menu_thread_timeline_view_in_room"
|
||||
android:icon="@drawable/ic_thread_view_in_room_menu_item"
|
||||
android:title="@string/action_thread_view_in_room"
|
||||
app:iconTint="?vctr_content_secondary"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_thread_timeline_copy_link"
|
||||
android:icon="@drawable/ic_thread_link_menu_item"
|
||||
android:title="@string/action_thread_copy_link_to_thread"
|
||||
app:iconTint="?vctr_content_secondary"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_thread_timeline_share"
|
||||
android:icon="@drawable/ic_thread_share_menu_item"
|
||||
android:title="@string/action_thread_share"
|
||||
app:iconTint="?vctr_content_secondary"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
|
||||
</menu>
|
|
@ -441,6 +441,7 @@
|
|||
<string name="action_sign_out_confirmation_simple">Are you sure you want to sign out?</string>
|
||||
<string name="action_voice_call">Voice Call</string>
|
||||
<string name="action_video_call">Video Call</string>
|
||||
<string name="action_view_threads">View Threads</string>
|
||||
<string name="action_global_search">Global search</string>
|
||||
<string name="action_mark_all_as_read">Mark all as read</string>
|
||||
<string name="action_historical">Historical</string>
|
||||
|
@ -456,6 +457,11 @@
|
|||
<string name="disable">Disable</string>
|
||||
<string name="action_return">Return</string>
|
||||
|
||||
<!-- actions threads -->
|
||||
<string name="action_thread_view_in_room">View in room</string>
|
||||
<string name="action_thread_copy_link_to_thread">Copy link to thread</string>
|
||||
<string name="action_thread_share">Share</string>
|
||||
|
||||
<!-- dialog titles -->
|
||||
<string name="dialog_title_confirmation">Confirmation</string>
|
||||
<string name="dialog_title_warning">Warning</string>
|
||||
|
@ -1023,6 +1029,7 @@
|
|||
|
||||
<!-- Room Threads -->
|
||||
<string name="room_threads_filter">Filter Threads in room</string>
|
||||
<string name="room_threads_title">Thread</string>
|
||||
|
||||
<!-- Room events -->
|
||||
<string name="room_event_action_report_prompt_reason">Reason for reporting this content</string>
|
||||
|
|
Loading…
Reference in a new issue