diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 5df4eef2..a277f9a5 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -821,106 +821,101 @@ class RoomDetailFragment : textComposerViewModel.process(TextComposerActions.QueryUsers(query)) } - private fun handleActions(actionData: ActionsHandler.ActionData) { - when (actionData.actionId) { - MessageMenuViewModel.ACTION_ADD_REACTION -> { - val eventId = actionData.data?.toString() ?: return - startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), eventId), REACTION_SELECT_REQUEST_CODE) + private fun handleActions(action: SimpleAction) { + when (action) { + is SimpleAction.AddReaction -> { + startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), action.eventId), REACTION_SELECT_REQUEST_CODE) } - MessageMenuViewModel.ACTION_VIEW_REACTIONS -> { - val messageInformationData = actionData.data as? MessageInformationData - ?: return - ViewReactionBottomSheet.newInstance(roomDetailArgs.roomId, messageInformationData) + is SimpleAction.ViewReactions -> { + ViewReactionBottomSheet.newInstance(roomDetailArgs.roomId, action.messageInformationData) .show(requireActivity().supportFragmentManager, "DISPLAY_REACTIONS") } - MessageMenuViewModel.ACTION_COPY -> { + is SimpleAction.Copy -> { //I need info about the current selected message :/ - copyToClipboard(requireContext(), actionData.data?.toString() ?: "", false) + copyToClipboard(requireContext(), action.content, false) val msg = requireContext().getString(R.string.copied_to_clipboard) showSnackWithMessage(msg, Snackbar.LENGTH_SHORT) } - MessageMenuViewModel.ACTION_DELETE -> { - val eventId = actionData.data?.toString() ?: return - roomDetailViewModel.process(RoomDetailActions.RedactAction(eventId, context?.getString(R.string.event_redacted_by_user_reason))) + is SimpleAction.Delete -> { + roomDetailViewModel.process(RoomDetailActions.RedactAction(action.eventId, context?.getString(R.string.event_redacted_by_user_reason))) } - MessageMenuViewModel.ACTION_SHARE -> { + is SimpleAction.Share -> { //TODO current data communication is too limited //Need to now the media type - actionData.data?.toString()?.let { - //TODO bad, just POC - BigImageViewer.imageLoader().loadImage( - actionData.hashCode(), - Uri.parse(it), - object : ImageLoader.Callback { - override fun onFinish() {} - - override fun onSuccess(image: File?) { - if (image != null) - shareMedia(requireContext(), image, "image/*") - } - - override fun onFail(error: Exception?) {} - - override fun onCacheHit(imageType: Int, image: File?) {} - - override fun onCacheMiss(imageType: Int, image: File?) {} - - override fun onProgress(progress: Int) {} - - override fun onStart() {} + //TODO bad, just POC + BigImageViewer.imageLoader().loadImage( + action.hashCode(), + Uri.parse(action.imageUrl), + object : ImageLoader.Callback { + override fun onFinish() {} + override fun onSuccess(image: File?) { + if (image != null) + shareMedia(requireContext(), image, "image/*") } - ) - } + override fun onFail(error: Exception?) {} + + override fun onCacheHit(imageType: Int, image: File?) {} + + override fun onCacheMiss(imageType: Int, image: File?) {} + + override fun onProgress(progress: Int) {} + + override fun onStart() {} + + } + ) } - MessageMenuViewModel.VIEW_SOURCE, - MessageMenuViewModel.VIEW_DECRYPTED_SOURCE -> { + is SimpleAction.ViewSource -> { val view = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_event_content, null) view.findViewById(R.id.event_content_text_view)?.let { - it.text = actionData.data?.toString() ?: "" + it.text = action.content } AlertDialog.Builder(requireActivity()) .setView(view) - .setPositiveButton(R.string.ok) { dialog, id -> dialog.cancel() } + .setPositiveButton(R.string.ok, null) .show() } - MessageMenuViewModel.ACTION_QUICK_REACT -> { - //eventId,ClickedOn,Add - (actionData.data as? Triple)?.let { (eventId, clickedOn, add) -> - roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(eventId, clickedOn, add)) + is SimpleAction.ViewDecryptedSource -> { + val view = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_event_content, null) + view.findViewById(R.id.event_content_text_view)?.let { + it.text = action.content } + + AlertDialog.Builder(requireActivity()) + .setView(view) + .setPositiveButton(R.string.ok, null) + .show() } - MessageMenuViewModel.ACTION_EDIT -> { - val eventId = actionData.data.toString() - roomDetailViewModel.process(RoomDetailActions.EnterEditMode(eventId)) + is SimpleAction.QuickReact -> { + //eventId,ClickedOn,Add + roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) } - MessageMenuViewModel.ACTION_QUOTE -> { - val eventId = actionData.data.toString() - roomDetailViewModel.process(RoomDetailActions.EnterQuoteMode(eventId)) + is SimpleAction.Edit -> { + roomDetailViewModel.process(RoomDetailActions.EnterEditMode(action.eventId)) } - MessageMenuViewModel.ACTION_REPLY -> { - val eventId = actionData.data.toString() - roomDetailViewModel.process(RoomDetailActions.EnterReplyMode(eventId)) + is SimpleAction.Quote -> { + roomDetailViewModel.process(RoomDetailActions.EnterQuoteMode(action.eventId)) } - MessageMenuViewModel.ACTION_COPY_PERMALINK -> { - val eventId = actionData.data.toString() - val permalink = PermalinkFactory.createPermalink(roomDetailArgs.roomId, eventId) + is SimpleAction.Reply -> { + roomDetailViewModel.process(RoomDetailActions.EnterReplyMode(action.eventId)) + } + is SimpleAction.CopyPermalink -> { + val permalink = PermalinkFactory.createPermalink(roomDetailArgs.roomId, action.eventId) copyToClipboard(requireContext(), permalink, false) showSnackWithMessage(requireContext().getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT) } - MessageMenuViewModel.ACTION_RESEND -> { - val eventId = actionData.data.toString() - roomDetailViewModel.process(RoomDetailActions.ResendMessage(eventId)) + is SimpleAction.Resend -> { + roomDetailViewModel.process(RoomDetailActions.ResendMessage(action.eventId)) } - MessageMenuViewModel.ACTION_REMOVE -> { - val eventId = actionData.data.toString() - roomDetailViewModel.process(RoomDetailActions.RemoveFailedEcho(eventId)) + is SimpleAction.Remove -> { + roomDetailViewModel.process(RoomDetailActions.RemoveFailedEcho(action.eventId)) } - else -> { - Toast.makeText(context, "Action ${actionData.actionId} not implemented", Toast.LENGTH_LONG).show() + else -> { + Toast.makeText(context, "Action $action is not implemented yet", Toast.LENGTH_LONG).show() } } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ActionsHandler.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ActionsHandler.kt index 6ad47bfe..ddc8a543 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ActionsHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ActionsHandler.kt @@ -17,6 +17,7 @@ package im.vector.riotx.features.home.room.detail.timeline.action import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import im.vector.riotx.core.extensions.postLiveEvent import im.vector.riotx.core.utils.LiveEvent import javax.inject.Inject @@ -25,15 +26,10 @@ import javax.inject.Inject */ class ActionsHandler @Inject constructor() : ViewModel() { - data class ActionData( - val actionId: String, - val data: Any? - ) + val actionCommandEvent = MutableLiveData>() - val actionCommandEvent = MutableLiveData>() - - fun fireAction(actionId: String, data: Any? = null) { - actionCommandEvent.value = LiveEvent(ActionData(actionId,data)) + fun fireAction(action: SimpleAction) { + actionCommandEvent.postLiveEvent(action) } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt index f3bec83a..a80a3454 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt @@ -89,7 +89,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment() { } menuActionFragment.interactionListener = object : MessageMenuFragment.InteractionListener { override fun didSelectMenuAction(simpleAction: SimpleAction) { - actionHandlerModel.fireAction(simpleAction.uid, simpleAction.data) + actionHandlerModel.fireAction(simpleAction) dismiss() } } @@ -105,7 +105,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment() { quickReactionFragment.interactionListener = object : QuickReactionFragment.InteractionListener { override fun didQuickReactWith(clickedOn: String, add: Boolean, eventId: String) { - actionHandlerModel.fireAction(MessageMenuViewModel.ACTION_QUICK_REACT, Triple(eventId, clickedOn, add)) + actionHandlerModel.fireAction(SimpleAction.QuickReact(eventId, clickedOn, add)) dismiss() } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageMenuViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageMenuViewModel.kt index fcf00173..4a8661d8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageMenuViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageMenuViewModel.kt @@ -15,6 +15,8 @@ */ package im.vector.riotx.features.home.room.detail.timeline.action +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes import com.airbnb.mvrx.* import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject @@ -36,7 +38,24 @@ import im.vector.riotx.core.utils.isSingleEmoji import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData -data class SimpleAction(val uid: String, val titleRes: Int, val iconResId: Int?, val data: Any? = null) +sealed class SimpleAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) { + data class AddReaction(val eventId: String) : SimpleAction(R.string.message_add_reaction, R.drawable.ic_add_reaction) + data class Copy(val content: String) : SimpleAction(R.string.copy, R.drawable.ic_copy) + data class Edit(val eventId: String) : SimpleAction(R.string.edit, R.drawable.ic_edit) + data class Quote(val eventId: String) : SimpleAction(R.string.quote, R.drawable.ic_quote) + data class Reply(val eventId: String) : SimpleAction(R.string.reply, R.drawable.ic_reply) + data class Share(val imageUrl: String?) : SimpleAction(R.string.share, R.drawable.ic_share) + data class Resend(val eventId: String) : SimpleAction(R.string.global_retry, R.drawable.ic_refresh_cw) + data class Remove(val eventId: String) : SimpleAction(R.string.remove, R.drawable.ic_trash) + data class Delete(val eventId: String) : SimpleAction(R.string.delete, R.drawable.ic_delete) + data class Cancel(val eventId: String) : SimpleAction(R.string.cancel, R.drawable.ic_close_round) + data class ViewSource(val content: String) : SimpleAction(R.string.view_source, R.drawable.ic_view_source) + data class ViewDecryptedSource(val content: String) : SimpleAction(R.string.view_decrypted_source, R.drawable.ic_view_source) + data class CopyPermalink(val eventId: String) : SimpleAction(R.string.permalink, R.drawable.ic_permalink) + data class Flag(val eventId: String) : SimpleAction(R.string.report_content, R.drawable.ic_flag) + data class QuickReact(val eventId: String, val clickedOn: String, val add: Boolean) : SimpleAction(0, 0) + data class ViewReactions(val messageInformationData: MessageInformationData) : SimpleAction(R.string.message_view_reaction, R.drawable.ic_view_reactions) +} data class MessageMenuState( val roomId: String, @@ -68,24 +87,6 @@ class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: M private val informationData: MessageInformationData = initialState.informationData companion object : MvRxViewModelFactory { - - const val ACTION_ADD_REACTION = "add_reaction" - const val ACTION_COPY = "copy" - const val ACTION_EDIT = "edit" - const val ACTION_QUOTE = "quote" - const val ACTION_REPLY = "reply" - const val ACTION_SHARE = "share" - const val ACTION_RESEND = "resend" - const val ACTION_REMOVE = "remove" - const val ACTION_DELETE = "delete" - const val ACTION_CANCEL = "cancel" - const val VIEW_SOURCE = "VIEW_SOURCE" - const val VIEW_DECRYPTED_SOURCE = "VIEW_DECRYPTED_SOURCE" - const val ACTION_COPY_PERMALINK = "ACTION_COPY_PERMALINK" - const val ACTION_FLAG = "ACTION_FLAG" - const val ACTION_QUICK_REACT = "ACTION_QUICK_REACT" - const val ACTION_VIEW_REACTIONS = "ACTION_VIEW_REACTIONS" - override fun create(viewModelContext: ViewModelContext, state: MessageMenuState): MessageMenuViewModel? { val fragment: MessageMenuFragment = (viewModelContext as FragmentViewModelContext).fragment() return fragment.messageMenuViewModelFactory.create(state) @@ -115,52 +116,48 @@ class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: M return arrayListOf().apply { if (event.root.sendState.hasFailed()) { if (canRetry(event)) { - add(SimpleAction(ACTION_RESEND, R.string.global_retry, R.drawable.ic_refresh_cw, eventId)) + add(SimpleAction.Resend(eventId)) } - add(SimpleAction(ACTION_REMOVE, R.string.remove, R.drawable.ic_trash, eventId)) + add(SimpleAction.Remove(eventId)) } else if (event.root.sendState.isSending()) { //TODO is uploading attachment? if (canCancel(event)) { - add(SimpleAction(ACTION_CANCEL, R.string.cancel, R.drawable.ic_close_round, eventId)) + add(SimpleAction.Cancel(eventId)) } } else { if (!event.root.isRedacted()) { if (canReply(event, messageContent)) { - add(SimpleAction(ACTION_REPLY, R.string.reply, R.drawable.ic_reply, eventId)) + add(SimpleAction.Reply(eventId)) } if (canEdit(event, session.myUserId)) { - add(SimpleAction(ACTION_EDIT, R.string.edit, R.drawable.ic_edit, eventId)) + add(SimpleAction.Edit(eventId)) } if (canRedact(event, session.myUserId)) { - add(SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_delete, eventId)) + add(SimpleAction.Delete(eventId)) } if (canCopy(type)) { //TODO copy images? html? see ClipBoard - add(SimpleAction(ACTION_COPY, R.string.copy, R.drawable.ic_copy, messageContent!!.body)) + add(SimpleAction.Copy(messageContent!!.body)) } if (event.canReact()) { - add(SimpleAction(ACTION_ADD_REACTION, R.string.message_add_reaction, R.drawable.ic_add_reaction, eventId)) + add(SimpleAction.AddReaction(eventId)) } if (canQuote(event, messageContent)) { - add(SimpleAction(ACTION_QUOTE, R.string.quote, R.drawable.ic_quote, eventId)) + add(SimpleAction.Quote(eventId)) } if (canViewReactions(event)) { - add(SimpleAction(ACTION_VIEW_REACTIONS, R.string.message_view_reaction, R.drawable.ic_view_reactions, informationData)) + add(SimpleAction.ViewReactions(informationData)) } if (canShare(type)) { if (messageContent is MessageImageContent) { - add( - SimpleAction(ACTION_SHARE, - R.string.share, R.drawable.ic_share, - session.contentUrlResolver().resolveFullSize(messageContent.url)) - ) + add(SimpleAction.Share(session.contentUrlResolver().resolveFullSize(messageContent.url))) } //TODO } @@ -174,17 +171,17 @@ class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: M } } - add(SimpleAction(VIEW_SOURCE, R.string.view_source, R.drawable.ic_view_source, event.root.toContentStringWithIndent())) + add(SimpleAction.ViewSource(event.root.toContentStringWithIndent())) if (event.isEncrypted()) { val decryptedContent = event.root.toClearContentStringWithIndent() ?: stringProvider.getString(R.string.encryption_information_decryption_error) - add(SimpleAction(VIEW_DECRYPTED_SOURCE, R.string.view_decrypted_source, R.drawable.ic_view_source, decryptedContent)) + add(SimpleAction.ViewDecryptedSource(decryptedContent)) } - add(SimpleAction(ACTION_COPY_PERMALINK, R.string.permalink, R.drawable.ic_permalink, event.root.eventId)) + add(SimpleAction.CopyPermalink(eventId)) if (session.myUserId != event.root.senderId && event.root.getClearType() == EventType.MESSAGE) { //not sent by me - add(SimpleAction(ACTION_FLAG, R.string.report_content, R.drawable.ic_flag, event.root.eventId)) + add(SimpleAction.Flag(eventId)) } } }