From 43ead66991264e1319ba7706f9fbb75d3d345896 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 24 Jun 2019 16:13:58 +0200 Subject: [PATCH 1/3] Update quick reactions to new design --- .../room/model/relation/RelationService.kt | 13 -- .../internal/session/room/RoomFactory.kt | 4 +- .../internal/session/room/RoomModule.kt | 8 +- .../room/relation/DefaultRelationService.kt | 26 --- .../room/relation/UpdateQuickReactionTask.kt | 89 -------- .../home/room/detail/RoomDetailActions.kt | 2 +- .../home/room/detail/RoomDetailFragment.kt | 6 +- .../home/room/detail/RoomDetailViewModel.kt | 6 +- .../action/MessageActionsBottomSheet.kt | 5 +- .../timeline/action/QuickReactionFragment.kt | 93 ++------- .../timeline/action/QuickReactionViewModel.kt | 115 ++--------- .../adapter_item_action_quick_reaction.xml | 190 +++++++++--------- vector/src/main/res/values/strings_riotX.xml | 1 + 13 files changed, 145 insertions(+), 413 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/UpdateQuickReactionTask.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/relation/RelationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/relation/RelationService.kt index ac08b64f..bef89839 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/relation/RelationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/relation/RelationService.kt @@ -63,19 +63,6 @@ interface RelationService { fun undoReaction(reaction: String, targetEventId: String, myUserId: String)//: Cancelable - /** - * Update a quick reaction (toggle). - * If you have reacted with agree and then you click on disagree, this call will delete(redact) - * the disagree and add the agree - * If you click on a reaction that you already reacted with, it will undo it - * @param reaction the reaction (preferably emoji) - * @param oppositeReaction the opposite reaction(preferably emoji) - * @param targetEventId the id of the event being reacted - * @param myUserId used to know if a reaction event was made by the user - */ - fun updateQuickReaction(reaction: String, oppositeReaction: String, targetEventId: String, myUserId: String) - - /** * Edit a text message body. Limited to "m.text" contentType * @param targetEventId The event to edit diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt index 4f4b7e73..ae1c3000 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt @@ -29,7 +29,6 @@ import im.vector.matrix.android.internal.session.room.read.DefaultReadService import im.vector.matrix.android.internal.session.room.read.SetReadMarkersTask import im.vector.matrix.android.internal.session.room.relation.DefaultRelationService import im.vector.matrix.android.internal.session.room.relation.FindReactionEventForUndoTask -import im.vector.matrix.android.internal.session.room.relation.UpdateQuickReactionTask import im.vector.matrix.android.internal.session.room.send.DefaultSendService import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory import im.vector.matrix.android.internal.session.room.state.DefaultStateService @@ -51,7 +50,6 @@ internal class RoomFactory(private val monarchy: Monarchy, private val setReadMarkersTask: SetReadMarkersTask, private val cryptoService: CryptoService, private val findReactionEventForUndoTask: FindReactionEventForUndoTask, - private val updateQuickReactionTask: UpdateQuickReactionTask, private val joinRoomTask: JoinRoomTask, private val leaveRoomTask: LeaveRoomTask) { @@ -64,7 +62,7 @@ internal class RoomFactory(private val monarchy: Monarchy, val stateService = DefaultStateService(roomId, taskExecutor, sendStateTask) val roomMembersService = DefaultMembershipService(roomId, monarchy, taskExecutor, loadRoomMembersTask, inviteTask, joinRoomTask, leaveRoomTask) val readService = DefaultReadService(roomId, monarchy, taskExecutor, setReadMarkersTask) - val reactionService = DefaultRelationService(roomId, eventFactory, findReactionEventForUndoTask, updateQuickReactionTask, monarchy, taskExecutor) + val reactionService = DefaultRelationService(roomId, eventFactory, findReactionEventForUndoTask, monarchy, taskExecutor) return DefaultRoom( roomId, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt index 671a947f..ead2c8e4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt @@ -32,9 +32,7 @@ import im.vector.matrix.android.internal.session.room.prune.PruneEventTask import im.vector.matrix.android.internal.session.room.read.DefaultSetReadMarkersTask import im.vector.matrix.android.internal.session.room.read.SetReadMarkersTask import im.vector.matrix.android.internal.session.room.relation.DefaultFindReactionEventForUndoTask -import im.vector.matrix.android.internal.session.room.relation.DefaultUpdateQuickReactionTask import im.vector.matrix.android.internal.session.room.relation.FindReactionEventForUndoTask -import im.vector.matrix.android.internal.session.room.relation.UpdateQuickReactionTask import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory import im.vector.matrix.android.internal.session.room.send.LocalEchoUpdater import im.vector.matrix.android.internal.session.room.state.DefaultSendStateTask @@ -82,7 +80,7 @@ class RoomModule { } scope(DefaultSession.SCOPE) { - RoomFactory(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) + RoomFactory(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } scope(DefaultSession.SCOPE) { @@ -109,10 +107,6 @@ class RoomModule { DefaultFindReactionEventForUndoTask(get()) as FindReactionEventForUndoTask } - scope(DefaultSession.SCOPE) { - DefaultUpdateQuickReactionTask(get()) as UpdateQuickReactionTask - } - scope(DefaultSession.SCOPE) { DefaultPruneEventTask(get()) as PruneEventTask } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt index 264909e9..f2527d49 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt @@ -46,7 +46,6 @@ import timber.log.Timber internal class DefaultRelationService(private val roomId: String, private val eventFactory: LocalEchoEventFactory, private val findReactionEventForUndoTask: FindReactionEventForUndoTask, - private val updateQuickReactionTask: UpdateQuickReactionTask, private val monarchy: Monarchy, private val taskExecutor: TaskExecutor) : RelationService { @@ -105,31 +104,6 @@ internal class DefaultRelationService(private val roomId: String, } - override fun updateQuickReaction(reaction: String, oppositeReaction: String, targetEventId: String, myUserId: String) { - - val params = UpdateQuickReactionTask.Params( - roomId, - targetEventId, - reaction, - oppositeReaction, - myUserId - ) - - updateQuickReactionTask.configureWith(params) - .dispatchTo(object : MatrixCallback { - override fun onSuccess(data: UpdateQuickReactionTask.Result) { - data.reactionToAdd?.also { sendReaction(it, targetEventId) } - data.reactionToRedact.forEach { - val redactEvent = eventFactory.createRedactEvent(roomId, it, null).also { - saveLocalEcho(it) - } - val redactWork = createRedactEventWork(redactEvent, it, null) - TimelineSendEventWorkCommon.postWork(roomId, redactWork) - } - } - }) - .executeBy(taskExecutor) - } private fun buildWorkIdentifier(identifier: String): String { return "${roomId}_$identifier" diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/UpdateQuickReactionTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/UpdateQuickReactionTask.kt deleted file mode 100644 index bc54464f..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/UpdateQuickReactionTask.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.matrix.android.internal.session.room.relation - -import arrow.core.Try -import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity -import im.vector.matrix.android.internal.database.model.EventEntity -import im.vector.matrix.android.internal.database.model.ReactionAggregatedSummaryEntityFields -import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.task.Task -import io.realm.Realm - - -internal interface UpdateQuickReactionTask : Task { - - data class Params( - val roomId: String, - val eventId: String, - val reaction: String, - val oppositeReaction: String, - val myUserId: String - ) - - data class Result( - val reactionToAdd: String?, - val reactionToRedact: List - ) -} - -internal class DefaultUpdateQuickReactionTask(private val monarchy: Monarchy) : UpdateQuickReactionTask { - override suspend fun execute(params: UpdateQuickReactionTask.Params): Try { - return Try { - var res: Pair?>? = null - monarchy.doWithRealm { realm -> - res = updateQuickReaction(realm, params.reaction, params.oppositeReaction, params.eventId, params.myUserId) - } - UpdateQuickReactionTask.Result(res?.first, res?.second ?: emptyList()) - } - } - - - private fun updateQuickReaction(realm: Realm, reaction: String, oppositeReaction: String, eventId: String, myUserId: String): Pair?> { - //the emoji reaction has been selected, we need to check if we have reacted it or not - val existingSummary = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() - ?: return Pair(reaction, null) - - //Ok there is already reactions on this event, have we reacted to it - val aggregationForReaction = existingSummary.reactionsSummary.where() - .equalTo(ReactionAggregatedSummaryEntityFields.KEY, reaction) - .findFirst() - val aggregationForOppositeReaction = existingSummary.reactionsSummary.where() - .equalTo(ReactionAggregatedSummaryEntityFields.KEY, oppositeReaction) - .findFirst() - - if (aggregationForReaction == null || !aggregationForReaction.addedByMe) { - //i haven't yet reacted to it, so need to add it, but do I need to redact the opposite? - val toRedact = aggregationForOppositeReaction?.sourceEvents?.mapNotNull { - //find source event - val entity = EventEntity.where(realm, it).findFirst() - if (entity?.sender == myUserId) entity.eventId else null - } - return Pair(reaction, toRedact) - } else { - //I already added it, so i need to undo it (like a toggle) - // find all m.redaction coming from me to readact them - val toRedact = aggregationForReaction.sourceEvents.mapNotNull { - //find source event - val entity = EventEntity.where(realm, it).findFirst() - if (entity?.sender == myUserId) entity.eventId else null - } - return Pair(null, toRedact) - } - - } -} \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActions.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActions.kt index ddee224b..51dbc960 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActions.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActions.kt @@ -30,7 +30,7 @@ sealed class RoomDetailActions { data class SendReaction(val reaction: String, val targetEventId: String) : RoomDetailActions() data class RedactAction(val targetEventId: String, val reason: String? = "") : RoomDetailActions() data class UndoReaction(val targetEventId: String, val key: String, val reason: String? = "") : RoomDetailActions() - data class UpdateQuickReactAction(val targetEventId: String, val selectedReaction: String, val opposite: String) : RoomDetailActions() + data class UpdateQuickReactAction(val targetEventId: String, val selectedReaction: String, val add: Boolean) : RoomDetailActions() data class ShowEditHistoryAction(val event: String, val editAggregatedSummary: EditAggregatedSummary) : RoomDetailActions() object AcceptInvite : RoomDetailActions() object RejectInvite : RoomDetailActions() diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt index c8030c25..e1854898 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt @@ -681,9 +681,9 @@ class RoomDetailFragment : .show() } MessageMenuViewModel.ACTION_QUICK_REACT -> { - //eventId,ClickedOn,Opposite - (actionData.data as? Triple)?.let { (eventId, clickedOn, opposite) -> - roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(eventId, clickedOn, opposite)) + //eventId,ClickedOn,Add + (actionData.data as? Triple)?.let { (eventId, clickedOn, add) -> + roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(eventId, clickedOn, add)) } } MessageMenuViewModel.ACTION_EDIT -> { diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewModel.kt index eee29328..cfa210be 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewModel.kt @@ -333,7 +333,11 @@ class RoomDetailViewModel(initialState: RoomDetailViewState, private fun handleUpdateQuickReaction(action: RoomDetailActions.UpdateQuickReactAction) { - room.updateQuickReaction(action.selectedReaction, action.opposite, action.targetEventId, session.sessionParams.credentials.userId) + if (action.add) { + room.sendReaction(action.selectedReaction, action.targetEventId) + } else { + room.undoReaction(action.selectedReaction, action.targetEventId, session.sessionParams.credentials.userId) + } } private fun handleSendMedia(action: RoomDetailActions.SendMedia) { diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt index 9c9bbc2d..95777b8d 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt @@ -94,8 +94,9 @@ class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() { .commit() } quickReactionFragment.interactionListener = object : QuickReactionFragment.InteractionListener { - override fun didQuickReactWith(clikedOn: String, opposite: String, reactions: List, eventId: String) { - actionHandlerModel.fireAction(MessageMenuViewModel.ACTION_QUICK_REACT, Triple(eventId, clikedOn, opposite)) + + override fun didQuickReactWith(clikedOn: String, add: Boolean, eventId: String) { + actionHandlerModel.fireAction(MessageMenuViewModel.ACTION_QUICK_REACT, Triple(eventId, clikedOn, add)) dismiss() } } diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionFragment.kt index b1074480..7e7196a6 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionFragment.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionFragment.kt @@ -20,10 +20,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.constraintlayout.widget.ConstraintLayout -import androidx.transition.TransitionManager -import butterknife.BindView import butterknife.ButterKnife import com.airbnb.mvrx.BaseMvRxFragment import com.airbnb.mvrx.MvRx @@ -31,6 +27,7 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.riotredesign.EmojiCompatFontProvider import im.vector.riotredesign.R +import kotlinx.android.synthetic.main.adapter_item_action_quick_reaction.* import org.koin.android.ext.android.inject /** @@ -40,21 +37,6 @@ class QuickReactionFragment : BaseMvRxFragment() { private val viewModel: QuickReactionViewModel by fragmentViewModel(QuickReactionViewModel::class) - @BindView(R.id.root_layout) - lateinit var rootLayout: ConstraintLayout - - @BindView(R.id.quick_react_1_text) - lateinit var quickReact1Text: TextView - - @BindView(R.id.quick_react_2_text) - lateinit var quickReact2Text: TextView - - @BindView(R.id.quick_react_3_text) - lateinit var quickReact3Text: TextView - - @BindView(R.id.quick_react_4_text) - lateinit var quickReact4Text: TextView - var interactionListener: InteractionListener? = null val fontProvider by inject() @@ -65,77 +47,38 @@ class QuickReactionFragment : BaseMvRxFragment() { return view } + private val textViews by lazy { + listOf(quickReaction0, quickReaction1, quickReaction2, quickReaction3, + quickReaction4, quickReaction5, quickReaction6, quickReaction7) + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - quickReact1Text.text = QuickReactionViewModel.agreePositive - quickReact2Text.text = QuickReactionViewModel.agreeNegative - quickReact3Text.text = QuickReactionViewModel.likePositive - quickReact4Text.text = QuickReactionViewModel.likeNegative - - listOf(quickReact1Text, quickReact2Text, quickReact3Text, quickReact4Text).forEach { - it.typeface = fontProvider.typeface ?: Typeface.DEFAULT - } - - //configure click listeners - quickReact1Text.setOnClickListener { - viewModel.toggleAgree(true) - } - quickReact2Text.setOnClickListener { - viewModel.toggleAgree(false) - } - quickReact3Text.setOnClickListener { - viewModel.toggleLike(true) - } - quickReact4Text.setOnClickListener { - viewModel.toggleLike(false) + textViews.forEachIndexed { index, textView -> + textView.typeface = fontProvider.typeface ?: Typeface.DEFAULT + textView.setOnClickListener { + viewModel.didSelect(index) + } } } override fun invalidate() = withState(viewModel) { - TransitionManager.beginDelayedTransition(rootLayout) - when (it.agreeTrigleState) { - TriggleState.NONE -> { - quickReact1Text.alpha = 1f - quickReact2Text.alpha = 1f - } - TriggleState.FIRST -> { - quickReact1Text.alpha = 1f - quickReact2Text.alpha = 0.2f - - } - TriggleState.SECOND -> { - quickReact1Text.alpha = 0.2f - quickReact2Text.alpha = 1f - } - } - when (it.likeTriggleState) { - TriggleState.NONE -> { - quickReact3Text.alpha = 1f - quickReact4Text.alpha = 1f - } - TriggleState.FIRST -> { - quickReact3Text.alpha = 1f - quickReact4Text.alpha = 0.2f - - } - TriggleState.SECOND -> { - quickReact3Text.alpha = 0.2f - quickReact4Text.alpha = 1f - } + it.quickStates.forEachIndexed { index, qs -> + textViews[index].text = qs.reaction + textViews[index].alpha = if (qs.isSelected) 0.2f else 1f } - if (it.selectionResult != null) { - val clikedOn = it.selectionResult.first - interactionListener?.didQuickReactWith(clikedOn, QuickReactionViewModel.getOpposite(clikedOn) - ?: "", it.selectionResult.second, it.eventId) + if (it.result != null) { + interactionListener?.didQuickReactWith(it.result.reaction, it.result.isSelected, it.eventId) } + } interface InteractionListener { - fun didQuickReactWith(clikedOn: String, opposite: String, reactions: List, eventId: String) + fun didQuickReactWith(clikedOn: String, add: Boolean, eventId: String) } companion object { diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionViewModel.kt index 5252e51b..9ac17333 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionViewModel.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionViewModel.kt @@ -25,18 +25,16 @@ import org.koin.android.ext.android.get /** * Quick reactions state, it's a toggle with 3rd state */ -enum class TriggleState { - NONE, - FIRST, - SECOND -} +data class ToggleState( + val reaction: String, + val isSelected: Boolean +) data class QuickReactionState( - val agreeTrigleState: TriggleState = TriggleState.NONE, - val likeTriggleState: TriggleState = TriggleState.NONE, - /** Pair of 'clickedOn' and current toggles state*/ - val selectionResult: Pair>? = null, - val eventId: String = "") : MvRxState + val quickStates: List, + val eventId: String = "", + val result: ToggleState? = null +) : MvRxState /** * Quick reaction view model @@ -44,107 +42,28 @@ data class QuickReactionState( class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel(initialState) { - fun toggleAgree(isFirst: Boolean) = withState { - if (isFirst) { - setState { - val newTriggle = if (it.agreeTrigleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST - copy( - agreeTrigleState = newTriggle, - selectionResult = Pair(agreePositive, getReactions(this, newTriggle, null)) - ) - } - } else { - setState { - val newTriggle = if (it.agreeTrigleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND - copy( - agreeTrigleState = agreeTrigleState, - selectionResult = Pair(agreeNegative, getReactions(this, newTriggle, null)) - ) - } + fun didSelect(index: Int) = withState { + val isSelected = it.quickStates[index].isSelected + setState { + copy(result = ToggleState(it.quickStates[index].reaction, !isSelected)) } } - fun toggleLike(isFirst: Boolean) = withState { - if (isFirst) { - setState { - val newTriggle = if (it.likeTriggleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST - copy( - likeTriggleState = newTriggle, - selectionResult = Pair(likePositive, getReactions(this, null, newTriggle)) - ) - } - } else { - setState { - val newTriggle = if (it.likeTriggleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND - copy( - likeTriggleState = newTriggle, - selectionResult = Pair(likeNegative, getReactions(this, null, newTriggle)) - ) - } - } - } - - private fun getReactions(state: QuickReactionState, newState1: TriggleState?, newState2: TriggleState?): List { - return ArrayList(4).apply { - when (newState2 ?: state.likeTriggleState) { - TriggleState.FIRST -> add(likePositive) - TriggleState.SECOND -> add(likeNegative) - else -> { - } - } - when (newState1 ?: state.agreeTrigleState) { - TriggleState.FIRST -> add(agreePositive) - TriggleState.SECOND -> add(agreeNegative) - else -> { - } - } - } - } - - companion object : MvRxViewModelFactory { - val agreePositive = "👍" - val agreeNegative = "👎" - val likePositive = "🙂" - val likeNegative = "😔" - - fun getOpposite(reaction: String): String? { - return when (reaction) { - agreePositive -> agreeNegative - agreeNegative -> agreePositive - likePositive -> likeNegative - likeNegative -> likePositive - else -> null - } - } + val quickEmojis = listOf("👍", "👎", "😀", "🎉", "😕", "❤️", "🚀", "👀") override fun initialState(viewModelContext: ViewModelContext): QuickReactionState? { - // Args are accessible from the context. - // val foo = vieWModelContext.args.foo val currentSession = viewModelContext.activity.get() val parcel = viewModelContext.args as TimelineEventFragmentArgs val event = currentSession.getRoom(parcel.roomId)?.getTimeLineEvent(parcel.eventId) ?: return null - var agreeTriggle: TriggleState = TriggleState.NONE - var likeTriggle: TriggleState = TriggleState.NONE - event.annotations?.reactionsSummary?.forEach { - //it.addedByMe - if (it.addedByMe) { - if (agreePositive == it.key) { - agreeTriggle = TriggleState.FIRST - } else if (agreeNegative == it.key) { - agreeTriggle = TriggleState.SECOND - } - if (likePositive == it.key) { - likeTriggle = TriggleState.FIRST - } else if (likeNegative == it.key) { - likeTriggle = TriggleState.SECOND - } - } + val summary = event.annotations?.reactionsSummary + val quickReactions = quickEmojis.map { emoji -> + ToggleState(emoji, summary?.firstOrNull { it.key == emoji }?.addedByMe ?: false) } - return QuickReactionState(agreeTriggle, likeTriggle, null, event.root.eventId ?: "") + return QuickReactionState(quickReactions, event.root.eventId ?: "") } } } \ No newline at end of file diff --git a/vector/src/main/res/layout/adapter_item_action_quick_reaction.xml b/vector/src/main/res/layout/adapter_item_action_quick_reaction.xml index 272f89a6..9f26e95f 100644 --- a/vector/src/main/res/layout/adapter_item_action_quick_reaction.xml +++ b/vector/src/main/res/layout/adapter_item_action_quick_reaction.xml @@ -4,116 +4,116 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root_layout" android:layout_width="match_parent" - android:layout_height="96dp"> + android:layout_height="wrap_content" + android:padding="8dp"> + + + - - - - - + android:padding="4dp" + android:textColor="?riotx_text_secondary" + android:textSize="24sp" + tools:ignore="MissingConstraints" + tools:text="👎" /> - + + + + + + + + + + + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/quickReactionTitle" /> diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 3293c4cf..9dceffe9 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -8,4 +8,5 @@ Matrix SDK Version + Quick Reactions \ No newline at end of file From 56aaa9dce3c7345a13ee8449fbbff4f308235d03 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 24 Jun 2019 16:15:26 +0200 Subject: [PATCH 2/3] Fix / updated unicode for smiling --- .../home/room/detail/timeline/action/QuickReactionViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionViewModel.kt index 9ac17333..541c42cc 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionViewModel.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionViewModel.kt @@ -51,7 +51,7 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel companion object : MvRxViewModelFactory { - val quickEmojis = listOf("👍", "👎", "😀", "🎉", "😕", "❤️", "🚀", "👀") + val quickEmojis = listOf("👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀") override fun initialState(viewModelContext: ViewModelContext): QuickReactionState? { val currentSession = viewModelContext.activity.get() From 98176b9760b1fe7d6fb94996421b945966cdd1bb Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 25 Jun 2019 15:45:44 +0200 Subject: [PATCH 3/3] Cleaning (code review) --- .../room/detail/timeline/action/QuickReactionFragment.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionFragment.kt index 7e7196a6..e7c0813e 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionFragment.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/QuickReactionFragment.kt @@ -20,6 +20,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.TextView import butterknife.ButterKnife import com.airbnb.mvrx.BaseMvRxFragment import com.airbnb.mvrx.MvRx @@ -47,14 +48,14 @@ class QuickReactionFragment : BaseMvRxFragment() { return view } - private val textViews by lazy { - listOf(quickReaction0, quickReaction1, quickReaction2, quickReaction3, - quickReaction4, quickReaction5, quickReaction6, quickReaction7) - } + lateinit var textViews: List override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + textViews = listOf(quickReaction0, quickReaction1, quickReaction2, quickReaction3, + quickReaction4, quickReaction5, quickReaction6, quickReaction7) + textViews.forEachIndexed { index, textView -> textView.typeface = fontProvider.typeface ?: Typeface.DEFAULT textView.setOnClickListener {