This commit is contained in:
Valere 2019-05-09 18:43:10 +02:00
parent dcc430f91b
commit 93cb7b8ce6
10 changed files with 86 additions and 42 deletions

View File

@ -2,7 +2,7 @@ Changes in RiotX 0.XX (2019-XX-XX)
=================================================== ===================================================


Features: Features:
- - Contextual action menu for messages in room


Improvements: Improvements:
- -

View File

@ -426,17 +426,9 @@ class RoomDetailFragment :
} }


override fun onEventCellClicked(eventId: String, informationData: MessageInformationData, messageContent: MessageContent, view: View) { override fun onEventCellClicked(eventId: String, informationData: MessageInformationData, messageContent: MessageContent, view: View) {
val roomId = (arguments?.get(MvRx.KEY_ARG) as? RoomDetailArgs)?.roomId
if (roomId.isNullOrBlank()) {
Timber.e("Missing RoomId, cannot open bottomsheet")
return
}
MessageActionsBottomSheet
.newInstance(eventId, roomId, informationData)
.show(requireActivity().supportFragmentManager, "MESSAGE_CONTEXTUAL_ACTIONS")
} }


// AutocompleteUserPresenter.Callback
override fun onEventLongClicked(eventId: String, informationData: MessageInformationData, messageContent: MessageContent, view: View): Boolean { override fun onEventLongClicked(eventId: String, informationData: MessageInformationData, messageContent: MessageContent, view: View): Boolean {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
val roomId = (arguments?.get(MvRx.KEY_ARG) as? RoomDetailArgs)?.roomId val roomId = (arguments?.get(MvRx.KEY_ARG) as? RoomDetailArgs)?.roomId

View File

@ -1,3 +1,18 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotredesign.features.home.room.detail.timeline.action package im.vector.riotredesign.features.home.room.detail.timeline.action


import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData

View File

@ -20,7 +20,9 @@ import com.airbnb.mvrx.MvRxView
import com.airbnb.mvrx.MvRxViewModelStore import com.airbnb.mvrx.MvRxViewModelStore
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment



/**
* Add MvRx capabilities to bottomsheetdialog (like BaseMvRxFragment)
*/
abstract class BaseMvRxBottomSheetDialog() : BottomSheetDialogFragment(), MvRxView { abstract class BaseMvRxBottomSheetDialog() : BottomSheetDialogFragment(), MvRxView {
override val mvrxViewModelStore by lazy { MvRxViewModelStore(viewModelStore) } override val mvrxViewModelStore by lazy { MvRxViewModelStore(viewModelStore) }



View File

@ -38,7 +38,10 @@ import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize



/**
* Bottom sheet fragment that shows a message preview with list of contextual actions
* (Includes fragments for quick reactions and list of actions)
*/
class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() { class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {


private val viewModel: MessageActionsViewModel by fragmentViewModel(MessageActionsViewModel::class) private val viewModel: MessageActionsViewModel by fragmentViewModel(MessageActionsViewModel::class)
@ -137,9 +140,6 @@ class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {
val eventId: String, val eventId: String,
val roomId: String, val roomId: String,
val informationData: MessageInformationData val informationData: MessageInformationData
// val body: String,
// val type: String,
// var url: String? = null
) : Parcelable ) : Parcelable


companion object { companion object {
@ -149,16 +149,7 @@ class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {
eventId, eventId,
roomId, roomId,
informationData informationData
// messageContent.body,
// messageContent.type
) )
// if (messageContent is MessageImageContent) {
// parcelableArgs.url = messageContent.url
// }
// if (messageContent is MessageVideoContent) {
// parcelableArgs.url = messageContent.url
// }

args.putParcelable(MvRx.KEY_ARG, parcelableArgs) args.putParcelable(MvRx.KEY_ARG, parcelableArgs)
return MessageActionsBottomSheet().apply { arguments = args } return MessageActionsBottomSheet().apply { arguments = args }



View File

@ -1,3 +1,18 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotredesign.features.home.room.detail.timeline.action package im.vector.riotredesign.features.home.room.detail.timeline.action


import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.MvRxState
@ -22,16 +37,13 @@ data class MessageActionState(
val senderAvatarPath: String? = null) val senderAvatarPath: String? = null)
: MvRxState : MvRxState



/**
* Information related to an event and used to display preview in contextual bottomsheet.
*/
class MessageActionsViewModel(initialState: MessageActionState) : VectorViewModel<MessageActionState>(initialState) { class MessageActionsViewModel(initialState: MessageActionState) : VectorViewModel<MessageActionState>(initialState) {


companion object : MvRxViewModelFactory<MessageActionsViewModel, MessageActionState> { companion object : MvRxViewModelFactory<MessageActionsViewModel, MessageActionState> {


// override fun create(viewModelContext: ViewModelContext, state: MessageActionState): MessageActionsViewModel? {
// //val currentSession = viewModelContext.activity.get<Session>()
// return MessageActionsViewModel(state/*,currentSession*/)
// }

val dateFormat = SimpleDateFormat("EEE, d MMM yyyy HH:mm") val dateFormat = SimpleDateFormat("EEE, d MMM yyyy HH:mm")


override fun initialState(viewModelContext: ViewModelContext): MessageActionState? { override fun initialState(viewModelContext: ViewModelContext): MessageActionState? {

View File

@ -1,3 +1,18 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotredesign.features.home.room.detail.timeline.action package im.vector.riotredesign.features.home.room.detail.timeline.action


import android.os.Bundle import android.os.Bundle
@ -17,6 +32,9 @@ import im.vector.riotredesign.R
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
import im.vector.riotredesign.features.themes.ThemeUtils import im.vector.riotredesign.features.themes.ThemeUtils


/**
* Fragment showing the list of available contextual action for a given message.
*/
class MessageMenuFragment : BaseMvRxFragment() { class MessageMenuFragment : BaseMvRxFragment() {


private val viewModel: MessageMenuViewModel by fragmentViewModel(MessageMenuViewModel::class) private val viewModel: MessageMenuViewModel by fragmentViewModel(MessageMenuViewModel::class)

View File

@ -1,3 +1,18 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotredesign.features.home.room.detail.timeline.action package im.vector.riotredesign.features.home.room.detail.timeline.action


import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.MvRxState
@ -17,13 +32,13 @@ import im.vector.riotredesign.core.platform.VectorViewModel
import org.json.JSONObject import org.json.JSONObject
import org.koin.android.ext.android.get import org.koin.android.ext.android.get



data class SimpleAction(val uid: String, val titleRes: Int, val iconResId: Int?, val data: Any? = null) data class SimpleAction(val uid: String, val titleRes: Int, val iconResId: Int?, val data: Any? = null)


data class MessageMenuState( data class MessageMenuState(val actions: List<SimpleAction>) : MvRxState
val actions: List<SimpleAction>
) : MvRxState


/**
* Manages list actions for a given message (copy / paste / forward...)
*/
class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<MessageMenuState>(initialState) { class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<MessageMenuState>(initialState) {


companion object : MvRxViewModelFactory<MessageMenuViewModel, MessageMenuState> { companion object : MvRxViewModelFactory<MessageMenuViewModel, MessageMenuState> {

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.riotredesign.features.home.room.detail.timeline.action package im.vector.riotredesign.features.home.room.detail.timeline.action


import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -30,12 +29,13 @@ import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
import im.vector.riotredesign.R import im.vector.riotredesign.R



/**
* Quick Reaction Fragment (agree / like reactions)
*/
class QuickReactionFragment : BaseMvRxFragment() { class QuickReactionFragment : BaseMvRxFragment() {


private val viewModel: QuickReactionViewModel by fragmentViewModel(QuickReactionViewModel::class) private val viewModel: QuickReactionViewModel by fragmentViewModel(QuickReactionViewModel::class)



@BindView(R.id.root_layout) @BindView(R.id.root_layout)
lateinit var rootLayout: ConstraintLayout lateinit var rootLayout: ConstraintLayout


@ -49,7 +49,6 @@ class QuickReactionFragment : BaseMvRxFragment() {
@BindView(R.id.quick_react_4) @BindView(R.id.quick_react_4)
lateinit var quickReact4: View lateinit var quickReact4: View



@BindView(R.id.quick_react_1_text) @BindView(R.id.quick_react_1_text)
lateinit var quickReact1Text: TextView lateinit var quickReact1Text: TextView


@ -70,10 +69,6 @@ class QuickReactionFragment : BaseMvRxFragment() {
return view return view
} }


override fun onAttach(context: Context) {
super.onAttach(context)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)



View File

@ -31,6 +31,10 @@ enum class TriggleState {


data class QuickReactionState(val agreeTrigleState: TriggleState, val likeTriggleState: TriggleState, val selectionResult: List<String>? = null) : MvRxState data class QuickReactionState(val agreeTrigleState: TriggleState, val likeTriggleState: TriggleState, val selectionResult: List<String>? = null) : MvRxState


/**
* Quick reaction view model
* TODO: configure initial state from event
*/
class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel<QuickReactionState>(initialState) { class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel<QuickReactionState>(initialState) {


val agreePositive = "👍" val agreePositive = "👍"