PR Remarks

This commit is contained in:
ariskotsomitopoulos 2022-01-17 17:28:40 +02:00
parent f6067977fe
commit 81a1dfd66d
32 changed files with 152 additions and 151 deletions

View File

@ -222,8 +222,8 @@ data class Event(
private fun getDecryptedValue(key: String = "body"): String? {
return if (isEncrypted()) {
@Suppress("UNCHECKED_CAST")
val content = mxDecryptionResult?.payload?.get("content") as? JsonDict
content?.get(key) as? String
val decryptedContent = mxDecryptionResult?.payload?.get("content") as? JsonDict
decryptedContent?.get(key) as? String
} else {
content?.get(key) as? String
}

View File

@ -28,7 +28,7 @@ object RelationType {
/** Lets you define an event which references an existing event.*/
const val REFERENCE = "m.reference"
/** Lets you define an event which is a reply to an existing event.*/
/** Lets you define an event which is a thread reply to an existing event.*/
const val THREAD = "m.thread"
const val IO_THREAD = "io.element.thread"

View File

@ -57,13 +57,13 @@ interface TimelineService {
fun getAttachmentMessages(): List<TimelineEvent>
/**
* Get a live list of all the thread for the specified roomId
* Get a live list of all the TimelineEvents which have thread replies for the specified roomId
* @return the [LiveData] of [TimelineEvent]
*/
fun getAllThreadsLive(): LiveData<List<TimelineEvent>>
/**
* Get a list of all the thread for the specified roomId
* Get a list of all the TimelineEvents which have thread replies for the specified roomId
* @return the [LiveData] of [TimelineEvent]
*/
fun getAllThreads(): List<TimelineEvent>

View File

@ -27,7 +27,7 @@ enum class ThreadNotificationState {
// There is at least one new message
NEW_MESSAGE,
// The is at least one new message that should bi highlighted
// The is at least one new message that should be highlighted
// ex. "Hello @aris.kotsomitopoulos"
NEW_HIGHLIGHTED_MESSAGE;
}

View File

@ -20,5 +20,4 @@ internal enum class LoadMoreResult {
REACHED_END,
SUCCESS,
FAILURE
// evenIDS
}

View File

@ -223,7 +223,7 @@ internal class ThreadsAwarenessHandler @Inject constructor(
body)
val messageTextContent = MessageTextContent(
msgType = "m.text",
msgType = MessageType.MSGTYPE_TEXT,
format = MessageFormat.FORMAT_MATRIX_HTML,
body = body,
formattedBody = replyFormatted

View File

@ -203,7 +203,7 @@ interface FragmentModule {
@Binds
@IntoMap
@FragmentKey(TimelineFragment::class)
fun bindRoomDetailFragment(fragment: TimelineFragment): Fragment
fun bindTimelineFragment(fragment: TimelineFragment): Fragment
@Binds
@IntoMap
@ -933,7 +933,7 @@ interface FragmentModule {
@Binds
@IntoMap
@FragmentKey(ThreadListFragment::class)
fun bindRoomThreadDetailFragment(fragment: ThreadListFragment): Fragment
fun bindThreadListFragment(fragment: ThreadListFragment): Fragment
@Binds
@IntoMap

View File

@ -44,7 +44,7 @@ import im.vector.app.features.home.UnknownDeviceDetectorSharedViewModel
import im.vector.app.features.home.UnreadMessagesSharedViewModel
import im.vector.app.features.home.UserColorAccountDataViewModel
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsViewModel
import im.vector.app.features.home.room.detail.RoomDetailViewModel
import im.vector.app.features.home.room.detail.TimelineViewModel
import im.vector.app.features.home.room.detail.composer.MessageComposerViewModel
import im.vector.app.features.home.room.detail.search.SearchViewModel
import im.vector.app.features.home.room.detail.timeline.action.MessageActionsViewModel
@ -536,8 +536,8 @@ interface MavericksViewModelModule {
@Binds
@IntoMap
@MavericksViewModelKey(RoomDetailViewModel::class)
fun roomDetailViewModelFactory(factory: RoomDetailViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@MavericksViewModelKey(TimelineViewModel::class)
fun roomDetailViewModelFactory(factory: TimelineViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap

View File

@ -126,7 +126,7 @@ fun TextView.setLeftDrawable(@DrawableRes iconRes: Int, @AttrRes tintColor: Int?
}
fun TextView.clearDrawables() {
this.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
}
/**

View File

@ -44,7 +44,7 @@ class JoinReplacementRoomBottomSheet :
@Inject
lateinit var errorFormatter: ErrorFormatter
private val viewModel: RoomDetailViewModel by parentFragmentViewModel()
private val viewModel: TimelineViewModel by parentFragmentViewModel()
override val showExpanded: Boolean
get() = true

View File

@ -32,7 +32,7 @@ class StartCallActionsHandler(
private val fragment: Fragment,
private val callManager: WebRtcCallManager,
private val vectorPreferences: VectorPreferences,
private val roomDetailViewModel: RoomDetailViewModel,
private val timelineViewModel: TimelineViewModel,
private val startCallActivityResultLauncher: ActivityResultLauncher<Array<String>>,
private val showDialogWithMessage: (String) -> Unit,
private val onTapToReturnToCall: () -> Unit) {
@ -45,7 +45,7 @@ class StartCallActionsHandler(
handleCallRequest(false)
}
private fun handleCallRequest(isVideoCall: Boolean) = withState(roomDetailViewModel) { state ->
private fun handleCallRequest(isVideoCall: Boolean) = withState(timelineViewModel) { state ->
val roomSummary = state.asyncRoomSummary.invoke() ?: return@withState
when (roomSummary.joinedMembersCount) {
1 -> {
@ -95,7 +95,7 @@ class StartCallActionsHandler(
.setMessage(R.string.audio_video_meeting_description)
.setPositiveButton(fragment.getString(R.string.create)) { _, _ ->
// create the widget, then navigate to it..
roomDetailViewModel.handle(RoomDetailAction.AddJitsiWidget(isVideoCall))
timelineViewModel.handle(RoomDetailAction.AddJitsiWidget(isVideoCall))
}
.setNegativeButton(fragment.getString(R.string.action_cancel), null)
.show()
@ -121,22 +121,22 @@ class StartCallActionsHandler(
private fun safeStartCall2(isVideoCall: Boolean) {
val startCallAction = RoomDetailAction.StartCall(isVideoCall)
roomDetailViewModel.pendingAction = startCallAction
timelineViewModel.pendingAction = startCallAction
if (isVideoCall) {
if (checkPermissions(PERMISSIONS_FOR_VIDEO_IP_CALL,
fragment.requireActivity(),
startCallActivityResultLauncher,
R.string.permissions_rationale_msg_camera_and_audio)) {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(startCallAction)
timelineViewModel.pendingAction = null
timelineViewModel.handle(startCallAction)
}
} else {
if (checkPermissions(PERMISSIONS_FOR_AUDIO_IP_CALL,
fragment.requireActivity(),
startCallActivityResultLauncher,
R.string.permissions_rationale_msg_record_audio)) {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(startCallAction)
timelineViewModel.pendingAction = null
timelineViewModel.handle(startCallAction)
}
}
}

View File

@ -117,7 +117,7 @@ import im.vector.app.core.utils.shareText
import im.vector.app.core.utils.startInstallFromSourceIntent
import im.vector.app.core.utils.toast
import im.vector.app.databinding.DialogReportContentBinding
import im.vector.app.databinding.FragmentRoomDetailBinding
import im.vector.app.databinding.FragmentTimelineBinding
import im.vector.app.features.attachments.AttachmentTypeSelectorView
import im.vector.app.features.attachments.AttachmentsHelper
import im.vector.app.features.attachments.ContactAttachment
@ -255,7 +255,7 @@ class TimelineFragment @Inject constructor(
private val voiceMessagePlaybackTracker: VoiceMessagePlaybackTracker,
private val clock: Clock
) :
VectorBaseFragment<FragmentRoomDetailBinding>(),
VectorBaseFragment<FragmentTimelineBinding>(),
TimelineEventController.Callback,
VectorInviteView.Callback,
AttachmentTypeSelectorView.Callback,
@ -295,15 +295,15 @@ class TimelineFragment @Inject constructor(
autoCompleterFactory.create(timelineArgs.roomId, isThreadTimeLine())
}
private val roomDetailViewModel: RoomDetailViewModel by fragmentViewModel()
private val timelineViewModel: TimelineViewModel by fragmentViewModel()
private val messageComposerViewModel: MessageComposerViewModel by fragmentViewModel()
private val debouncer = Debouncer(createUIHandler())
private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback
private lateinit var scrollOnHighlightedEventCallback: ScrollOnHighlightedEventCallback
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomDetailBinding {
return FragmentRoomDetailBinding.inflate(inflater, container, false)
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentTimelineBinding {
return FragmentTimelineBinding.inflate(inflater, container, false)
}
override fun getMenuRes() = R.menu.menu_timeline
@ -335,7 +335,7 @@ class TimelineFragment @Inject constructor(
super.onCreate(savedInstanceState)
setFragmentResultListener(MigrateRoomBottomSheet.REQUEST_KEY) { _, bundle ->
bundle.getString(MigrateRoomBottomSheet.BUNDLE_KEY_REPLACEMENT_ROOM)?.let { replacementRoomId ->
roomDetailViewModel.handle(RoomDetailAction.RoomUpgradeSuccess(replacementRoomId))
timelineViewModel.handle(RoomDetailAction.RoomUpgradeSuccess(replacementRoomId))
}
}
}
@ -351,7 +351,7 @@ class TimelineFragment @Inject constructor(
roomId = timelineArgs.roomId,
fragment = this,
vectorPreferences = vectorPreferences,
roomDetailViewModel = roomDetailViewModel,
timelineViewModel = timelineViewModel,
callManager = callManager,
startCallActivityResultLauncher = startCallActivityResultLauncher,
showDialogWithMessage = ::showDialogWithMessage,
@ -388,7 +388,7 @@ class TimelineFragment @Inject constructor(
invalidateOptionsMenu()
}
roomDetailViewModel.onEach(RoomDetailViewState::canShowJumpToReadMarker, RoomDetailViewState::unreadState) { _, _ ->
timelineViewModel.onEach(RoomDetailViewState::canShowJumpToReadMarker, RoomDetailViewState::unreadState) { _, _ ->
updateJumpToReadMarkerViewVisibility()
}
@ -405,7 +405,7 @@ class TimelineFragment @Inject constructor(
}
}
roomDetailViewModel.onEach(
timelineViewModel.onEach(
RoomDetailViewState::syncState,
RoomDetailViewState::incrementalSyncStatus,
RoomDetailViewState::pushCounter
@ -435,7 +435,7 @@ class TimelineFragment @Inject constructor(
}.exhaustive
}
roomDetailViewModel.observeViewEvents {
timelineViewModel.observeViewEvents {
when (it) {
is RoomDetailViewEvents.Failure -> showErrorInSnackbar(it.throwable)
is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds)
@ -501,12 +501,12 @@ class TimelineFragment @Inject constructor(
private fun setupRemoveJitsiWidgetView() {
views.removeJitsiWidgetView.onCompleteSliding = {
withState(roomDetailViewModel) {
withState(timelineViewModel) {
val jitsiWidgetId = it.jitsiState.widgetId ?: return@withState
if (it.jitsiState.hasJoined) {
leaveJitsiConference()
}
roomDetailViewModel.handle(RoomDetailAction.RemoveWidget(jitsiWidgetId))
timelineViewModel.handle(RoomDetailAction.RemoveWidget(jitsiWidgetId))
}
}
}
@ -516,7 +516,7 @@ class TimelineFragment @Inject constructor(
}
private fun onBroadcastJitsiEvent(conferenceEvent: ConferenceEvent) {
roomDetailViewModel.handle(RoomDetailAction.UpdateJoinJitsiCallStatus(conferenceEvent))
timelineViewModel.handle(RoomDetailAction.UpdateJoinJitsiCallStatus(conferenceEvent))
}
private fun onCannotRecord() {
@ -577,7 +577,7 @@ class TimelineFragment @Inject constructor(
override fun onImageReady(uri: Uri?) {
uri ?: return
roomDetailViewModel.handle(
timelineViewModel.handle(
RoomDetailAction.SetAvatarAction(
newAvatarUri = uri,
newAvatarFileName = getFilenameFromUri(requireContext(), uri) ?: UUID.randomUUID().toString()
@ -616,7 +616,7 @@ class TimelineFragment @Inject constructor(
).apply {
directListener = { granted ->
if (granted) {
roomDetailViewModel.handle(RoomDetailAction.EnsureNativeWidgetAllowed(
timelineViewModel.handle(RoomDetailAction.EnsureNativeWidgetAllowed(
widget = it.widget,
userJustAccepted = true,
grantedEvents = it.grantedEvents
@ -696,13 +696,13 @@ class TimelineFragment @Inject constructor(
.setMessage(getString(R.string.event_status_delete_all_failed_dialog_message))
.setNegativeButton(R.string.no, null)
.setPositiveButton(R.string.yes) { _, _ ->
roomDetailViewModel.handle(RoomDetailAction.RemoveAllFailedMessages)
timelineViewModel.handle(RoomDetailAction.RemoveAllFailedMessages)
}
.show()
}
override fun onRetryClicked() {
roomDetailViewModel.handle(RoomDetailAction.ResendAll)
timelineViewModel.handle(RoomDetailAction.ResendAll)
}
}
}
@ -799,7 +799,7 @@ class TimelineFragment @Inject constructor(
val safeContext = context ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!safeContext.packageManager.canRequestPackageInstalls()) {
roomDetailViewModel.pendingEvent = action
timelineViewModel.pendingEvent = action
startInstallFromSourceIntent(safeContext, installApkActivityResultLauncher)
} else {
openFile(action)
@ -811,7 +811,7 @@ class TimelineFragment @Inject constructor(
private val installApkActivityResultLauncher = registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
roomDetailViewModel.pendingEvent?.let {
timelineViewModel.pendingEvent?.let {
if (it is RoomDetailViewEvents.OpenFile) {
openFile(it)
}
@ -819,7 +819,7 @@ class TimelineFragment @Inject constructor(
} else {
// User cancelled
}
roomDetailViewModel.pendingEvent = null
timelineViewModel.pendingEvent = null
}
private fun displayPromptForIntegrationManager() {
@ -879,18 +879,18 @@ class TimelineFragment @Inject constructor(
}
override fun onDestroy() {
roomDetailViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState)
timelineViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState)
super.onDestroy()
}
private fun setupJumpToBottomView() {
views.jumpToBottomView.visibility = View.INVISIBLE
views.jumpToBottomView.debouncedClicks {
roomDetailViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState)
timelineViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState)
views.jumpToBottomView.visibility = View.INVISIBLE
if (!roomDetailViewModel.timeline.isLive) {
if (!timelineViewModel.timeline.isLive) {
scrollOnNewMessageCallback.forceScrollOnNextUpdate()
roomDetailViewModel.timeline.restartWithEventId(null)
timelineViewModel.timeline.restartWithEventId(null)
} else {
layoutManager.scrollToPosition(0)
}
@ -909,7 +909,7 @@ class TimelineFragment @Inject constructor(
onJumpToReadMarkerClicked()
}
views.jumpToReadMarkerView.setOnCloseIconClickListener {
roomDetailViewModel.handle(RoomDetailAction.MarkAllAsRead)
timelineViewModel.handle(RoomDetailAction.MarkAllAsRead)
}
}
@ -952,11 +952,11 @@ class TimelineFragment @Inject constructor(
private fun setupNotificationView() {
views.notificationAreaView.delegate = object : NotificationAreaView.Delegate {
override fun onTombstoneEventClicked() {
roomDetailViewModel.handle(RoomDetailAction.JoinAndOpenReplacementRoom)
timelineViewModel.handle(RoomDetailAction.JoinAndOpenReplacementRoom)
}
override fun onMisconfiguredEncryptionClicked() {
roomDetailViewModel.handle(RoomDetailAction.OnClickMisconfiguredEncryption)
timelineViewModel.handle(RoomDetailAction.OnClickMisconfiguredEncryption)
}
}
}
@ -971,7 +971,7 @@ class TimelineFragment @Inject constructor(
}
val joinConfItem = menu.findItem(R.id.join_conference)
(joinConfItem.actionView as? JoinConferenceView)?.onJoinClicked = {
roomDetailViewModel.handle(RoomDetailAction.JoinJitsiCall)
timelineViewModel.handle(RoomDetailAction.JoinJitsiCall)
}
// Custom thread notification menu item
@ -984,10 +984,10 @@ class TimelineFragment @Inject constructor(
override fun onPrepareOptionsMenu(menu: Menu) {
menu.forEach {
it.isVisible = roomDetailViewModel.isMenuItemVisible(it.itemId)
it.isVisible = timelineViewModel.isMenuItemVisible(it.itemId)
}
withState(roomDetailViewModel) { state ->
withState(timelineViewModel) { 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
val callButtonsEnabled = !hasCallInRoom && when (state.asyncRoomSummary.invoke()?.joinedMembersCount) {
@ -1035,7 +1035,7 @@ class TimelineFragment @Inject constructor(
true
}
R.id.open_matrix_apps -> {
roomDetailViewModel.handle(RoomDetailAction.ManageIntegrations)
timelineViewModel.handle(RoomDetailAction.ManageIntegrations)
true
}
R.id.voice_call -> {
@ -1123,8 +1123,8 @@ class TimelineFragment @Inject constructor(
navigator.openSearch(
context = requireContext(),
roomId = timelineArgs.roomId,
roomDisplayName = roomDetailViewModel.getRoomSummary()?.displayName,
roomAvatarUrl = roomDetailViewModel.getRoomSummary()?.avatarUrl
roomDisplayName = timelineViewModel.getRoomSummary()?.displayName,
roomAvatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl
)
} else {
showDialogWithMessage(getString(R.string.search_is_not_supported_in_e2e_room))
@ -1219,11 +1219,11 @@ class TimelineFragment @Inject constructor(
private fun handlePendingAction(roomDetailPendingAction: RoomDetailPendingAction) {
when (roomDetailPendingAction) {
is RoomDetailPendingAction.JumpToReadReceipt ->
roomDetailViewModel.handle(RoomDetailAction.JumpToReadReceipt(roomDetailPendingAction.userId))
timelineViewModel.handle(RoomDetailAction.JumpToReadReceipt(roomDetailPendingAction.userId))
is RoomDetailPendingAction.MentionUser ->
insertUserDisplayNameInTextEditor(roomDetailPendingAction.userId)
is RoomDetailPendingAction.OpenOrCreateDm ->
roomDetailViewModel.handle(RoomDetailAction.OpenOrCreateDm(roomDetailPendingAction.userId))
timelineViewModel.handle(RoomDetailAction.OpenOrCreateDm(roomDetailPendingAction.userId))
is RoomDetailPendingAction.OpenRoom ->
handleOpenRoom(RoomDetailViewEvents.OpenRoom(roomDetailPendingAction.roomId, roomDetailPendingAction.closeCurrentRoom))
}.exhaustive
@ -1276,7 +1276,7 @@ class TimelineFragment @Inject constructor(
if (activityResult.resultCode == Activity.RESULT_OK) {
val sendData = AttachmentsPreviewActivity.getOutput(data)
val keepOriginalSize = AttachmentsPreviewActivity.getKeepOriginalSize(data)
roomDetailViewModel.handle(RoomDetailAction.SendMedia(sendData, !keepOriginalSize))
timelineViewModel.handle(RoomDetailAction.SendMedia(sendData, !keepOriginalSize))
}
}
@ -1285,7 +1285,7 @@ class TimelineFragment @Inject constructor(
val eventId = EmojiReactionPickerActivity.getOutputEventId(activityResult.data)
val reaction = EmojiReactionPickerActivity.getOutputReaction(activityResult.data)
if (eventId != null && reaction != null) {
roomDetailViewModel.handle(RoomDetailAction.SendReaction(eventId, reaction))
timelineViewModel.handle(RoomDetailAction.SendReaction(eventId, reaction))
}
}
}
@ -1295,16 +1295,16 @@ class TimelineFragment @Inject constructor(
if (activityResult.resultCode == Activity.RESULT_OK) {
WidgetActivity.getOutput(data).toModel<MessageStickerContent>()
?.let { content ->
roomDetailViewModel.handle(RoomDetailAction.SendSticker(content))
timelineViewModel.handle(RoomDetailAction.SendSticker(content))
}
}
}
private val startCallActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
if (allGranted) {
(roomDetailViewModel.pendingAction as? RoomDetailAction.StartCall)?.let {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(it)
(timelineViewModel.pendingAction as? RoomDetailAction.StartCall)?.let {
timelineViewModel.pendingAction = null
timelineViewModel.handle(it)
}
} else {
if (deniedPermanently) {
@ -1318,7 +1318,7 @@ class TimelineFragment @Inject constructor(
private fun setupRecyclerView() {
timelineEventController.callback = this
timelineEventController.timeline = roomDetailViewModel.timeline
timelineEventController.timeline = timelineViewModel.timeline
views.timelineRecyclerView.trackItemsVisibilityChange()
layoutManager = object : LinearLayoutManager(context, RecyclerView.VERTICAL, true) {
@ -1388,7 +1388,7 @@ class TimelineFragment @Inject constructor(
private fun updateJumpToReadMarkerViewVisibility() {
if (isThreadTimeLine()) return
viewLifecycleOwner.lifecycleScope.launchWhenResumed {
val state = roomDetailViewModel.awaitState()
val state = timelineViewModel.awaitState()
val showJumpToUnreadBanner = when (state.unreadState) {
UnreadState.Unknown,
UnreadState.HasNoUnread -> false
@ -1500,7 +1500,7 @@ class TimelineFragment @Inject constructor(
views.composerLayout.views.composerEditText.focusChanges()
.onEach {
roomDetailViewModel.handle(RoomDetailAction.ComposerFocusChange(it))
timelineViewModel.handle(RoomDetailAction.ComposerFocusChange(it))
}
.launchIn(viewLifecycleOwner.lifecycleScope)
}
@ -1514,7 +1514,7 @@ class TimelineFragment @Inject constructor(
return isHandled
}
override fun invalidate() = withState(roomDetailViewModel, messageComposerViewModel) { mainState, messageComposerState ->
override fun invalidate() = withState(timelineViewModel, messageComposerViewModel) { mainState, messageComposerState ->
invalidateOptionsMenu()
val summary = mainState.asyncRoomSummary()
renderToolbar(summary, mainState.formattedTypingUsers)
@ -1568,7 +1568,7 @@ class TimelineFragment @Inject constructor(
}
}
private fun FragmentRoomDetailBinding.hideComposerViews() {
private fun FragmentTimelineBinding.hideComposerViews() {
composerLayout.isVisible = false
voiceMessageRecorderView.isVisible = false
}
@ -1679,7 +1679,7 @@ class TimelineFragment @Inject constructor(
.setView(layout)
.setPositiveButton(R.string.report_content_custom_submit) { _, _ ->
val reason = views.dialogReportContentInput.text.toString()
roomDetailViewModel.handle(RoomDetailAction.ReportContent(action.eventId, action.senderId, reason))
timelineViewModel.handle(RoomDetailAction.ReportContent(action.eventId, action.senderId, reason))
}
.setNegativeButton(R.string.action_cancel, null)
.show()
@ -1695,7 +1695,7 @@ class TimelineFragment @Inject constructor(
reasonHintRes = R.string.delete_event_dialog_reason_hint,
titleRes = action.dialogTitleRes
) { reason ->
roomDetailViewModel.handle(RoomDetailAction.RedactAction(action.eventId, reason))
timelineViewModel.handle(RoomDetailAction.RedactAction(action.eventId, reason))
}
}
@ -1717,7 +1717,7 @@ class TimelineFragment @Inject constructor(
.setMessage(R.string.content_reported_as_spam_content)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.block_user) { _, _ ->
roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId))
timelineViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId))
}
.show()
}
@ -1727,7 +1727,7 @@ class TimelineFragment @Inject constructor(
.setMessage(R.string.content_reported_as_inappropriate_content)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.block_user) { _, _ ->
roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId))
timelineViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId))
}
.show()
}
@ -1737,7 +1737,7 @@ class TimelineFragment @Inject constructor(
.setMessage(R.string.content_reported_content)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.block_user) { _, _ ->
roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId))
timelineViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId))
}
.show()
}
@ -1791,7 +1791,7 @@ class TimelineFragment @Inject constructor(
true
} else {
// Highlight and scroll to this event
roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true))
timelineViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true))
true
}
} else {
@ -1800,7 +1800,7 @@ class TimelineFragment @Inject constructor(
true
} else if (rootThreadEventId == getRootThreadEventId() && eventId != null) {
// we are in the same thread
roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true))
timelineViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true))
true
} else {
false
@ -1847,11 +1847,11 @@ class TimelineFragment @Inject constructor(
}
override fun onEventVisible(event: TimelineEvent) {
roomDetailViewModel.handle(RoomDetailAction.TimelineEventTurnsVisible(event))
timelineViewModel.handle(RoomDetailAction.TimelineEventTurnsVisible(event))
}
override fun onEventInvisible(event: TimelineEvent) {
roomDetailViewModel.handle(RoomDetailAction.TimelineEventTurnsInvisible(event))
timelineViewModel.handle(RoomDetailAction.TimelineEventTurnsInvisible(event))
}
override fun onEncryptedMessageClicked(informationData: MessageInformationData, view: View) {
@ -1896,7 +1896,7 @@ class TimelineFragment @Inject constructor(
private fun cleanUpAfterPermissionNotGranted() {
// Reset all pending data
roomDetailViewModel.pendingAction = null
timelineViewModel.pendingAction = null
attachmentsHelper.pendingType = null
}
@ -1905,23 +1905,23 @@ class TimelineFragment @Inject constructor(
// }
override fun onLoadMore(direction: Timeline.Direction) {
roomDetailViewModel.handle(RoomDetailAction.LoadMoreTimelineEvents(direction))
timelineViewModel.handle(RoomDetailAction.LoadMoreTimelineEvents(direction))
}
override fun onEventCellClicked(informationData: MessageInformationData, messageContent: Any?, view: View, isRootThreadEvent: Boolean) {
when (messageContent) {
is MessageVerificationRequestContent -> {
roomDetailViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId, null))
timelineViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId, null))
}
is MessageWithAttachmentContent -> {
val action = RoomDetailAction.DownloadOrOpen(informationData.eventId, informationData.senderId, messageContent)
roomDetailViewModel.handle(action)
timelineViewModel.handle(action)
}
is EncryptedEventContent -> {
if (isRootThreadEvent) {
onThreadSummaryClicked(informationData.eventId, isRootThreadEvent)
} else {
roomDetailViewModel.handle(RoomDetailAction.TapOnFailedToDecrypt(informationData.eventId))
timelineViewModel.handle(RoomDetailAction.TapOnFailedToDecrypt(informationData.eventId))
}
}
else -> {
@ -1944,14 +1944,14 @@ class TimelineFragment @Inject constructor(
private fun handleCancelSend(action: EventSharedAction.Cancel) {
if (action.force) {
roomDetailViewModel.handle(RoomDetailAction.CancelSend(action.eventId, true))
timelineViewModel.handle(RoomDetailAction.CancelSend(action.eventId, true))
} else {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.dialog_title_confirmation)
.setMessage(getString(R.string.event_status_cancel_sending_dialog_message))
.setNegativeButton(R.string.no, null)
.setPositiveButton(R.string.yes) { _, _ ->
roomDetailViewModel.handle(RoomDetailAction.CancelSend(action.eventId, false))
timelineViewModel.handle(RoomDetailAction.CancelSend(action.eventId, false))
}
.show()
}
@ -1979,10 +1979,10 @@ class TimelineFragment @Inject constructor(
override fun onClickOnReactionPill(informationData: MessageInformationData, reaction: String, on: Boolean) {
if (on) {
// we should test the current real state of reaction on this event
roomDetailViewModel.handle(RoomDetailAction.SendReaction(informationData.eventId, reaction))
timelineViewModel.handle(RoomDetailAction.SendReaction(informationData.eventId, reaction))
} else {
// I need to redact a reaction
roomDetailViewModel.handle(RoomDetailAction.UndoReaction(informationData.eventId, reaction))
timelineViewModel.handle(RoomDetailAction.UndoReaction(informationData.eventId, reaction))
}
}
@ -1997,11 +1997,11 @@ class TimelineFragment @Inject constructor(
}
override fun onTimelineItemAction(itemAction: RoomDetailAction) {
roomDetailViewModel.handle(itemAction)
timelineViewModel.handle(itemAction)
}
override fun getPreviewUrlRetriever(): PreviewUrlRetriever {
return roomDetailViewModel.previewUrlRetriever
return timelineViewModel.previewUrlRetriever
}
override fun onRoomCreateLinkClicked(url: String) {
@ -2022,7 +2022,7 @@ class TimelineFragment @Inject constructor(
}
override fun onReadMarkerVisible() {
roomDetailViewModel.handle(RoomDetailAction.EnterTrackingUnreadMessagesState)
timelineViewModel.handle(RoomDetailAction.EnterTrackingUnreadMessagesState)
}
override fun onPreviewUrlClicked(url: String) {
@ -2030,7 +2030,7 @@ class TimelineFragment @Inject constructor(
}
override fun onPreviewUrlCloseClicked(eventId: String, url: String) {
roomDetailViewModel.handle(RoomDetailAction.DoNotShowPreviewUrlFor(eventId, url))
timelineViewModel.handle(RoomDetailAction.DoNotShowPreviewUrlFor(eventId, url))
}
override fun onPreviewUrlImageClicked(sharedView: View?, mxcUrl: String?, title: String?) {
@ -2140,7 +2140,7 @@ class TimelineFragment @Inject constructor(
}
is EventSharedAction.QuickReact -> {
// eventId,ClickedOn,Add
roomDetailViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add))
timelineViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add))
}
is EventSharedAction.Edit -> {
if (withState(messageComposerViewModel) { it.isVoiceMessageIdle }) {
@ -2179,20 +2179,20 @@ class TimelineFragment @Inject constructor(
showSnackWithMessage(getString(R.string.copied_to_clipboard))
}
is EventSharedAction.Resend -> {
roomDetailViewModel.handle(RoomDetailAction.ResendMessage(action.eventId))
timelineViewModel.handle(RoomDetailAction.ResendMessage(action.eventId))
}
is EventSharedAction.Remove -> {
roomDetailViewModel.handle(RoomDetailAction.RemoveFailedEcho(action.eventId))
timelineViewModel.handle(RoomDetailAction.RemoveFailedEcho(action.eventId))
}
is EventSharedAction.Cancel -> {
handleCancelSend(action)
}
is EventSharedAction.ReportContentSpam -> {
roomDetailViewModel.handle(RoomDetailAction.ReportContent(
timelineViewModel.handle(RoomDetailAction.ReportContent(
action.eventId, action.senderId, "This message is spam", spam = true))
}
is EventSharedAction.ReportContentInappropriate -> {
roomDetailViewModel.handle(RoomDetailAction.ReportContent(
timelineViewModel.handle(RoomDetailAction.ReportContent(
action.eventId, action.senderId, "This message is inappropriate", inappropriate = true))
}
is EventSharedAction.ReportContentCustom -> {
@ -2208,7 +2208,7 @@ class TimelineFragment @Inject constructor(
onUrlLongClicked(action.url)
}
is EventSharedAction.ReRequestKey -> {
roomDetailViewModel.handle(RoomDetailAction.ReRequestKeys(action.eventId))
timelineViewModel.handle(RoomDetailAction.ReRequestKeys(action.eventId))
}
is EventSharedAction.UseKeyBackup -> {
context?.let {
@ -2227,7 +2227,7 @@ class TimelineFragment @Inject constructor(
.setMessage(R.string.end_poll_confirmation_description)
.setNegativeButton(R.string.action_cancel, null)
.setPositiveButton(R.string.end_poll_confirmation_approve_button) { _, _ ->
roomDetailViewModel.handle(RoomDetailAction.EndPoll(eventId))
timelineViewModel.handle(RoomDetailAction.EndPoll(eventId))
}
.show()
}
@ -2238,7 +2238,7 @@ class TimelineFragment @Inject constructor(
.setMessage(R.string.room_participants_action_ignore_prompt_msg)
.setNegativeButton(R.string.action_cancel, null)
.setPositiveButton(R.string.room_participants_action_ignore) { _, _ ->
roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(senderId))
timelineViewModel.handle(RoomDetailAction.IgnoreUser(senderId))
}
.show()
}
@ -2258,7 +2258,7 @@ class TimelineFragment @Inject constructor(
views.composerLayout.views.composerEditText.setText(Command.EMOTE.command + " ")
views.composerLayout.views.composerEditText.setSelection(Command.EMOTE.length)
} else {
val roomMember = roomDetailViewModel.getMember(userId)
val roomMember = timelineViewModel.getMember(userId)
// TODO move logic outside of fragment
(roomMember?.displayName ?: userId)
.let { sanitizeDisplayName(it) }
@ -2320,9 +2320,9 @@ class TimelineFragment @Inject constructor(
context?.let {
val roomThreadDetailArgs = ThreadTimelineArgs(
roomId = timelineArgs.roomId,
displayName = roomDetailViewModel.getRoomSummary()?.displayName,
avatarUrl = roomDetailViewModel.getRoomSummary()?.avatarUrl,
roomEncryptionTrustLevel = roomDetailViewModel.getRoomSummary()?.roomEncryptionTrustLevel,
displayName = timelineViewModel.getRoomSummary()?.displayName,
avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl,
roomEncryptionTrustLevel = timelineViewModel.getRoomSummary()?.roomEncryptionTrustLevel,
rootThreadEventId = rootThreadEventId)
navigator.openThread(it, roomThreadDetailArgs)
}
@ -2337,9 +2337,9 @@ class TimelineFragment @Inject constructor(
context?.let {
val roomThreadDetailArgs = ThreadTimelineArgs(
roomId = timelineArgs.roomId,
displayName = roomDetailViewModel.getRoomSummary()?.displayName,
roomEncryptionTrustLevel = roomDetailViewModel.getRoomSummary()?.roomEncryptionTrustLevel,
avatarUrl = roomDetailViewModel.getRoomSummary()?.avatarUrl)
displayName = timelineViewModel.getRoomSummary()?.displayName,
roomEncryptionTrustLevel = timelineViewModel.getRoomSummary()?.roomEncryptionTrustLevel,
avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl)
navigator.openThreadList(it, roomThreadDetailArgs)
}
}
@ -2348,20 +2348,20 @@ class TimelineFragment @Inject constructor(
override fun onAcceptInvite() {
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) }
roomDetailViewModel.handle(RoomDetailAction.AcceptInvite)
timelineViewModel.handle(RoomDetailAction.AcceptInvite)
}
override fun onRejectInvite() {
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) }
roomDetailViewModel.handle(RoomDetailAction.RejectInvite)
timelineViewModel.handle(RoomDetailAction.RejectInvite)
}
private fun onJumpToReadMarkerClicked() = withState(roomDetailViewModel) {
private fun onJumpToReadMarkerClicked() = withState(timelineViewModel) {
if (it.unreadState is UnreadState.HasUnread) {
roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(it.unreadState.firstUnreadEventId, false))
timelineViewModel.handle(RoomDetailAction.NavigateToEvent(it.unreadState.firstUnreadEventId, false))
}
if (it.unreadState is UnreadState.ReadMarkerNotLoaded) {
roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(it.unreadState.readMarkerId, false))
timelineViewModel.handle(RoomDetailAction.NavigateToEvent(it.unreadState.readMarkerId, false))
}
}
@ -2401,7 +2401,7 @@ class TimelineFragment @Inject constructor(
AttachmentTypeSelectorView.Type.FILE -> attachmentsHelper.selectFile(attachmentFileActivityResultLauncher)
AttachmentTypeSelectorView.Type.GALLERY -> attachmentsHelper.selectGallery(attachmentMediaActivityResultLauncher)
AttachmentTypeSelectorView.Type.CONTACT -> attachmentsHelper.selectContact(attachmentContactActivityResultLauncher)
AttachmentTypeSelectorView.Type.STICKER -> roomDetailViewModel.handle(RoomDetailAction.SelectStickerAttachment)
AttachmentTypeSelectorView.Type.STICKER -> timelineViewModel.handle(RoomDetailAction.SelectStickerAttachment)
AttachmentTypeSelectorView.Type.POLL -> navigator.openCreatePoll(requireContext(), timelineArgs.roomId)
}.exhaustive
}
@ -2412,7 +2412,7 @@ class TimelineFragment @Inject constructor(
val grouped = attachments.toGroupedContentAttachmentData()
if (grouped.notPreviewables.isNotEmpty()) {
// Send the not previewable attachments right now (?)
roomDetailViewModel.handle(RoomDetailAction.SendMedia(grouped.notPreviewables, false))
timelineViewModel.handle(RoomDetailAction.SendMedia(grouped.notPreviewables, false))
}
if (grouped.previewables.isNotEmpty()) {
val intent = AttachmentsPreviewActivity.newIntent(requireContext(), AttachmentsPreviewArgs(grouped.previewables))

View File

@ -103,7 +103,7 @@ import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode
import timber.log.Timber
import java.util.concurrent.atomic.AtomicBoolean
class RoomDetailViewModel @AssistedInject constructor(
class TimelineViewModel @AssistedInject constructor(
@Assisted private val initialState: RoomDetailViewState,
private val vectorPreferences: VectorPreferences,
private val vectorDataStore: VectorDataStore,
@ -144,11 +144,11 @@ class RoomDetailViewModel @AssistedInject constructor(
private var prepareToEncrypt: Async<Unit> = Uninitialized
@AssistedFactory
interface Factory : MavericksAssistedViewModelFactory<RoomDetailViewModel, RoomDetailViewState> {
override fun create(initialState: RoomDetailViewState): RoomDetailViewModel
interface Factory : MavericksAssistedViewModelFactory<TimelineViewModel, RoomDetailViewState> {
override fun create(initialState: RoomDetailViewState): TimelineViewModel
}
companion object : MavericksViewModelFactory<RoomDetailViewModel, RoomDetailViewState> by hiltMavericksViewModelFactory() {
companion object : MavericksViewModelFactory<TimelineViewModel, RoomDetailViewState> by hiltMavericksViewModelFactory() {
const val PAGINATION_COUNT = 50
}

View File

@ -215,7 +215,7 @@ class MessageComposerViewModel @AssistedInject constructor(
if (state.rootThreadEventId != null) {
room.replyInThread(
rootThreadEventId = state.rootThreadEventId,
replyInThreadText = action.text.toString(),
replyInThreadText = slashCommandResult.message,
autoMarkdown = false)
} else {
room.sendTextMessage(slashCommandResult.message, autoMarkdown = false)
@ -270,7 +270,7 @@ class MessageComposerViewModel @AssistedInject constructor(
is ParsedCommand.SendEmote -> {
state.rootThreadEventId?.let {
room.replyInThread(
rootThreadEventId = state.rootThreadEventId,
rootThreadEventId = it,
replyInThreadText = slashCommandResult.message,
msgType = MessageType.MSGTYPE_EMOTE,
autoMarkdown = action.autoMarkdown)
@ -282,7 +282,7 @@ class MessageComposerViewModel @AssistedInject constructor(
val message = slashCommandResult.message.toString()
state.rootThreadEventId?.let {
room.replyInThread(
rootThreadEventId = state.rootThreadEventId,
rootThreadEventId = it,
replyInThreadText = slashCommandResult.message,
formattedText = rainbowGenerator.generate(message))
} ?: room.sendFormattedTextMessage(message, rainbowGenerator.generate(message))
@ -293,7 +293,7 @@ class MessageComposerViewModel @AssistedInject constructor(
val message = slashCommandResult.message.toString()
state.rootThreadEventId?.let {
room.replyInThread(
rootThreadEventId = state.rootThreadEventId,
rootThreadEventId = it,
replyInThreadText = slashCommandResult.message,
msgType = MessageType.MSGTYPE_EMOTE,
formattedText = rainbowGenerator.generate(message))
@ -307,7 +307,7 @@ class MessageComposerViewModel @AssistedInject constructor(
val formattedText = "<span data-mx-spoiler>${slashCommandResult.message}</span>"
state.rootThreadEventId?.let {
room.replyInThread(
rootThreadEventId = state.rootThreadEventId,
rootThreadEventId = it,
replyInThreadText = text,
formattedText = formattedText)
} ?: room.sendFormattedTextMessage(
@ -479,9 +479,9 @@ class MessageComposerViewModel @AssistedInject constructor(
}
is SendMode.Reply -> {
val timelineEvent = state.sendMode.timelineEvent
state.rootThreadEventId?.let { rootThreadEventId ->
state.rootThreadEventId?.let {
room.replyInThread(
rootThreadEventId = rootThreadEventId,
rootThreadEventId = it,
replyInThreadText = action.text.toString(),
autoMarkdown = action.autoMarkdown,
eventReplied = timelineEvent)

View File

@ -48,11 +48,9 @@ sealed class EventSharedAction(@StringRes val titleRes: Int,
data class Reply(val eventId: String) :
EventSharedAction(R.string.reply, R.drawable.ic_reply)
// TODO add translations
data class ReplyInThread(val eventId: String) :
EventSharedAction(R.string.reply_in_thread, R.drawable.ic_reply_in_thread)
// TODO add translations
object ViewInRoom :
EventSharedAction(R.string.view_in_room, R.drawable.ic_thread_view_in_room_menu_item)

View File

@ -441,13 +441,12 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
}
/**
* Determine whether or not the Reply In Thread bottom sheet setting will be visible
* Determine whether or not the Reply In Thread bottom sheet action will be visible
* to the user
*/
private fun canReplyInThread(event: TimelineEvent,
messageContent: MessageContent?,
actionPermissions: ActionPermissions): Boolean {
// Only event of type EventType.MESSAGE are supported for the moment
if (!BuildConfig.THREADING_ENABLED) return false
if (initialState.isFromThreadTimeline) return false
if (event.root.getClearType() != EventType.MESSAGE &&
@ -468,13 +467,11 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
}
/**
* Determine whether or no the selected event is a root thread event from within
* a thread timeline
* Determine whether or not the view in room action will be available for the current event
*/
private fun canViewInRoom(event: TimelineEvent,
messageContent: MessageContent?,
actionPermissions: ActionPermissions): Boolean {
// Only event of type EventType.MESSAGE are supported for the moment
if (!BuildConfig.THREADING_ENABLED) return false
if (!initialState.isFromThreadTimeline) return false
if (event.root.getClearType() != EventType.MESSAGE &&

View File

@ -19,7 +19,7 @@ package im.vector.app.features.home.room.detail.views
import android.view.View
import android.view.ViewStub
import im.vector.app.core.ui.views.FailedMessagesWarningView
import im.vector.app.databinding.FragmentRoomDetailBinding
import im.vector.app.databinding.FragmentTimelineBinding
import im.vector.app.features.invite.VectorInviteView
import kotlin.reflect.KMutableProperty0
@ -29,12 +29,12 @@ import kotlin.reflect.KMutableProperty0
*/
class RoomDetailLazyLoadedViews {
private var roomDetailBinding: FragmentRoomDetailBinding? = null
private var roomDetailBinding: FragmentTimelineBinding? = null
private var failedMessagesWarningView: FailedMessagesWarningView? = null
private var inviteView: VectorInviteView? = null
fun bind(roomDetailBinding: FragmentRoomDetailBinding) {
fun bind(roomDetailBinding: FragmentTimelineBinding) {
this.roomDetailBinding = roomDetailBinding
}

View File

@ -30,8 +30,8 @@ import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.core.resources.ColorProvider
import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding
import im.vector.app.features.home.room.detail.RoomDetailAction
import im.vector.app.features.home.room.detail.RoomDetailViewModel
import im.vector.app.features.home.room.detail.RoomDetailViewState
import im.vector.app.features.home.room.detail.TimelineViewModel
import im.vector.app.features.navigation.Navigator
import org.matrix.android.sdk.api.session.widgets.model.Widget
import javax.inject.Inject
@ -48,7 +48,7 @@ class RoomWidgetsBottomSheet :
@Inject lateinit var colorProvider: ColorProvider
@Inject lateinit var navigator: Navigator
private val roomDetailViewModel: RoomDetailViewModel by parentFragmentViewModel()
private val timelineViewModel: TimelineViewModel by parentFragmentViewModel()
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding {
return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false)
@ -61,7 +61,7 @@ class RoomWidgetsBottomSheet :
views.bottomSheetTitle.textSize = 20f
views.bottomSheetTitle.setTextColor(colorProvider.getColorFromAttribute(R.attr.vctr_content_primary))
epoxyController.listener = this
roomDetailViewModel.onAsync(RoomDetailViewState::activeRoomWidgets) {
timelineViewModel.onAsync(RoomDetailViewState::activeRoomWidgets) {
epoxyController.setData(it)
}
}
@ -72,13 +72,13 @@ class RoomWidgetsBottomSheet :
super.onDestroyView()
}
override fun didSelectWidget(widget: Widget) = withState(roomDetailViewModel) {
override fun didSelectWidget(widget: Widget) = withState(timelineViewModel) {
navigator.openRoomWidget(requireContext(), it.roomId, widget)
dismiss()
}
override fun didSelectManageWidgets() {
roomDetailViewModel.handle(RoomDetailAction.OpenIntegrationManager)
timelineViewModel.handle(RoomDetailAction.OpenIntegrationManager)
dismiss()
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019 New Vector Ltd
* 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.
@ -36,8 +36,8 @@ import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.session.threads.ThreadNotificationState
import org.matrix.android.sdk.api.util.MatrixItem
@EpoxyModelClass(layout = R.layout.item_thread_list)
abstract class ThreadListModel : VectorEpoxyModel<ThreadListModel.Holder>() {
@EpoxyModelClass(layout = R.layout.item_thread)
abstract class ThreadListItem : VectorEpoxyModel<ThreadListItem.Holder>() {
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute lateinit var matrixItem: MatrixItem

View File

@ -22,7 +22,7 @@ import im.vector.app.core.date.DateFormatKind
import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.threads.list.model.threadList
import im.vector.app.features.home.room.threads.list.model.threadListItem
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.session.threads.ThreadNotificationState
import org.matrix.android.sdk.api.util.toMatrixItem
@ -60,7 +60,7 @@ class ThreadListController @Inject constructor(
?.forEach { timelineEvent ->
val date = dateFormatter.format(timelineEvent.root.threadDetails?.lastMessageTimestamp, DateFormatKind.ROOM_LIST)
val decryptionErrorMessage = stringProvider.getString(R.string.encrypted_message)
threadList {
threadListItem {
id(timelineEvent.eventId)
avatarRenderer(host.avatarRenderer)
matrixItem(timelineEvent.senderInfo.toMatrixItem())

View File

@ -75,6 +75,7 @@ class ThreadListFragment @Inject constructor(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initToolbar()
initTextConstants()
views.threadListRecyclerView.configureWith(threadListController, TimelineItemAnimator(), hasFixedSize = false)
threadListController.listener = this
}
@ -90,6 +91,12 @@ class ThreadListFragment @Inject constructor(
renderToolbar()
}
private fun initTextConstants() {
views.threadListEmptyNoticeTextView.text = String.format(
resources.getString(R.string.thread_list_empty_notice),
resources.getString(R.string.reply_in_thread))
}
override fun invalidate() = withState(threadListViewModel) { state ->
renderEmptyStateIfNeeded(state)
threadListController.update(state)

View File

@ -34,7 +34,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/threadListAppBarLayout"
tools:listitem="@layout/item_thread_list"
tools:listitem="@layout/item_thread"
tools:visibility="gone" />
<androidx.constraintlayout.widget.ConstraintLayout
@ -108,7 +108,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/threadListEmptySubtitleTextView"
android:text="@string/thread_list_empty_notice" />
tools:text="@string/thread_list_empty_notice" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -56,7 +56,7 @@
app:layout_constraintBottom_toBottomOf="@id/roomToolbarThreadImageView"
app:layout_constraintStart_toEndOf="@id/roomToolbarThreadImageView"
app:layout_constraintTop_toTopOf="@id/roomToolbarThreadImageView"
tools:text="RoomName"
tools:text="@sample/rooms.json/data/name"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -55,5 +55,5 @@
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/messageThreadSummaryAvatarImageView"
app:layout_constraintTop_toTopOf="parent"
tools:text="Hello There, whats up! Its a large sentence whats up! Its a large centence" />
tools:text="@sample/messages.json/data/message" />
</merge>

View File

@ -90,7 +90,7 @@
<item
android:id="@+id/menu_thread_timeline_share"
android:icon="@drawable/ic_thread_share_menu_item"
android:title="@string/action_thread_share"
android:title="@string/action_share"
app:iconTint="?vctr_content_secondary"
app:showAsAction="ifRoom" />
</menu>

View File

@ -472,7 +472,6 @@
<!-- 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>
@ -1048,7 +1047,8 @@
<string name="thread_list_modal_my_threads_subtitle">Shows all threads youve participated in</string>
<string name="thread_list_empty_title">Keep discussions organised with threads</string>
<string name="thread_list_empty_subtitle">Threads help keep your conversations on-topic and easy to track.</string>
<string name="thread_list_empty_notice">Tip: Long tap a message and use “Reply in thread”.</string>
<!-- Parameter %s will be replaced by the value of string reply_in_thread -->
<string name="thread_list_empty_notice">Tip: Long tap a message and use “%s”.</string>
<!-- Room events -->
<string name="room_event_action_report_prompt_reason">Reason for reporting this content</string>