PR Review
This commit is contained in:
parent
7da8b13cde
commit
6957768567
|
@ -35,7 +35,7 @@ enum class ChatEffect {
|
|||
* It also manages effect duration and some cool down, for example if an effect is currently playing,
|
||||
* any other trigger will be ignored
|
||||
* For now it uses visibility callback to check for an effect (that means that a fail to decrypt event - more
|
||||
* precisly an event decrypted with a few delay won't trigger an effect; it's acceptable)
|
||||
* precisely an event decrypted with a few delay won't trigger an effect; it's acceptable)
|
||||
* Events that are more that 10s old won't trigger effects
|
||||
*/
|
||||
class ChatEffectManager @Inject constructor() {
|
||||
|
@ -50,7 +50,7 @@ class ChatEffectManager @Inject constructor() {
|
|||
private var stopTimer: Timer? = null
|
||||
|
||||
// an in memory store to avoid trigger twice for an event (quick close/open timeline)
|
||||
private val alreadyPlayed = emptyList<String>().toMutableList()
|
||||
private val alreadyPlayed = mutableListOf<String>()
|
||||
|
||||
fun checkForEffect(event: TimelineEvent) {
|
||||
val age = event.root.ageLocalTs ?: 0
|
||||
|
@ -80,7 +80,6 @@ class ChatEffectManager @Inject constructor() {
|
|||
fun dispose() {
|
||||
stopTimer?.cancel()
|
||||
stopTimer = null
|
||||
delegate = null
|
||||
alreadyPlayed.clear()
|
||||
}
|
||||
|
||||
|
@ -98,7 +97,7 @@ class ChatEffectManager @Inject constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun hasAlreadyPlayed(event: TimelineEvent) : Boolean {
|
||||
private fun hasAlreadyPlayed(event: TimelineEvent): Boolean {
|
||||
return alreadyPlayed.contains(event.eventId)
|
||||
|| (event.root.unsignedData?.transactionId?.let { alreadyPlayed.contains(it) } ?: false)
|
||||
}
|
||||
|
@ -106,20 +105,30 @@ class ChatEffectManager @Inject constructor() {
|
|||
private fun findEffect(content: MessageContent, event: TimelineEvent): ChatEffect? {
|
||||
return when (content.msgType) {
|
||||
MessageType.MSGTYPE_CONFETTI -> ChatEffect.CONFETTI
|
||||
MessageType.MSGTYPE_SNOW -> ChatEffect.SNOW
|
||||
|
||||
MessageType.MSGTYPE_TEXT -> {
|
||||
val text = event.root.getClearContent().toModel<MessageContent>()?.body ?: ""
|
||||
if (text.contains("🎉")
|
||||
|| text.contains("🎊")) {
|
||||
ChatEffect.CONFETTI
|
||||
} else if (text.contains("⛄️")
|
||||
|| text.contains("☃️")
|
||||
|| text.contains("❄️")) {
|
||||
ChatEffect.SNOW
|
||||
} else null
|
||||
MessageType.MSGTYPE_SNOW -> ChatEffect.SNOW
|
||||
MessageType.MSGTYPE_TEXT -> {
|
||||
event.root.getClearContent().toModel<MessageContent>()?.body
|
||||
?.let { text ->
|
||||
when {
|
||||
EMOJIS_FOR_CONFETTI.any { text.contains(it) } -> ChatEffect.CONFETTI
|
||||
EMOJIS_FOR_SNOW.any { text.contains(it) } -> ChatEffect.SNOW
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val EMOJIS_FOR_CONFETTI = listOf(
|
||||
"🎉",
|
||||
"🎊"
|
||||
)
|
||||
private val EMOJIS_FOR_SNOW = listOf(
|
||||
"⛄️",
|
||||
"☃️",
|
||||
"❄️"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,58 +226,58 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
|
||||
override fun handle(action: RoomDetailAction) {
|
||||
when (action) {
|
||||
is RoomDetailAction.UserIsTyping -> handleUserIsTyping(action)
|
||||
is RoomDetailAction.SaveDraft -> handleSaveDraft(action)
|
||||
is RoomDetailAction.SendMessage -> handleSendMessage(action)
|
||||
is RoomDetailAction.SendMedia -> handleSendMedia(action)
|
||||
is RoomDetailAction.SendSticker -> handleSendSticker(action)
|
||||
is RoomDetailAction.TimelineEventTurnsVisible -> handleEventVisible(action)
|
||||
is RoomDetailAction.TimelineEventTurnsInvisible -> handleEventInvisible(action)
|
||||
is RoomDetailAction.LoadMoreTimelineEvents -> handleLoadMore(action)
|
||||
is RoomDetailAction.SendReaction -> handleSendReaction(action)
|
||||
is RoomDetailAction.AcceptInvite -> handleAcceptInvite()
|
||||
is RoomDetailAction.RejectInvite -> handleRejectInvite()
|
||||
is RoomDetailAction.RedactAction -> handleRedactEvent(action)
|
||||
is RoomDetailAction.UndoReaction -> handleUndoReact(action)
|
||||
is RoomDetailAction.UpdateQuickReactAction -> handleUpdateQuickReaction(action)
|
||||
is RoomDetailAction.EnterRegularMode -> handleEnterRegularMode(action)
|
||||
is RoomDetailAction.EnterEditMode -> handleEditAction(action)
|
||||
is RoomDetailAction.EnterQuoteMode -> handleQuoteAction(action)
|
||||
is RoomDetailAction.EnterReplyMode -> handleReplyAction(action)
|
||||
is RoomDetailAction.DownloadOrOpen -> handleOpenOrDownloadFile(action)
|
||||
is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action)
|
||||
is RoomDetailAction.HandleTombstoneEvent -> handleTombstoneEvent(action)
|
||||
is RoomDetailAction.ResendMessage -> handleResendEvent(action)
|
||||
is RoomDetailAction.RemoveFailedEcho -> handleRemove(action)
|
||||
is RoomDetailAction.ResendAll -> handleResendAll()
|
||||
is RoomDetailAction.MarkAllAsRead -> handleMarkAllAsRead()
|
||||
is RoomDetailAction.ReportContent -> handleReportContent(action)
|
||||
is RoomDetailAction.IgnoreUser -> handleIgnoreUser(action)
|
||||
is RoomDetailAction.UserIsTyping -> handleUserIsTyping(action)
|
||||
is RoomDetailAction.SaveDraft -> handleSaveDraft(action)
|
||||
is RoomDetailAction.SendMessage -> handleSendMessage(action)
|
||||
is RoomDetailAction.SendMedia -> handleSendMedia(action)
|
||||
is RoomDetailAction.SendSticker -> handleSendSticker(action)
|
||||
is RoomDetailAction.TimelineEventTurnsVisible -> handleEventVisible(action)
|
||||
is RoomDetailAction.TimelineEventTurnsInvisible -> handleEventInvisible(action)
|
||||
is RoomDetailAction.LoadMoreTimelineEvents -> handleLoadMore(action)
|
||||
is RoomDetailAction.SendReaction -> handleSendReaction(action)
|
||||
is RoomDetailAction.AcceptInvite -> handleAcceptInvite()
|
||||
is RoomDetailAction.RejectInvite -> handleRejectInvite()
|
||||
is RoomDetailAction.RedactAction -> handleRedactEvent(action)
|
||||
is RoomDetailAction.UndoReaction -> handleUndoReact(action)
|
||||
is RoomDetailAction.UpdateQuickReactAction -> handleUpdateQuickReaction(action)
|
||||
is RoomDetailAction.EnterRegularMode -> handleEnterRegularMode(action)
|
||||
is RoomDetailAction.EnterEditMode -> handleEditAction(action)
|
||||
is RoomDetailAction.EnterQuoteMode -> handleQuoteAction(action)
|
||||
is RoomDetailAction.EnterReplyMode -> handleReplyAction(action)
|
||||
is RoomDetailAction.DownloadOrOpen -> handleOpenOrDownloadFile(action)
|
||||
is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action)
|
||||
is RoomDetailAction.HandleTombstoneEvent -> handleTombstoneEvent(action)
|
||||
is RoomDetailAction.ResendMessage -> handleResendEvent(action)
|
||||
is RoomDetailAction.RemoveFailedEcho -> handleRemove(action)
|
||||
is RoomDetailAction.ResendAll -> handleResendAll()
|
||||
is RoomDetailAction.MarkAllAsRead -> handleMarkAllAsRead()
|
||||
is RoomDetailAction.ReportContent -> handleReportContent(action)
|
||||
is RoomDetailAction.IgnoreUser -> handleIgnoreUser(action)
|
||||
is RoomDetailAction.EnterTrackingUnreadMessagesState -> startTrackingUnreadMessages()
|
||||
is RoomDetailAction.ExitTrackingUnreadMessagesState -> stopTrackingUnreadMessages()
|
||||
is RoomDetailAction.ReplyToOptions -> handleReplyToOptions(action)
|
||||
is RoomDetailAction.AcceptVerificationRequest -> handleAcceptVerification(action)
|
||||
is RoomDetailAction.DeclineVerificationRequest -> handleDeclineVerification(action)
|
||||
is RoomDetailAction.RequestVerification -> handleRequestVerification(action)
|
||||
is RoomDetailAction.ResumeVerification -> handleResumeRequestVerification(action)
|
||||
is RoomDetailAction.ReRequestKeys -> handleReRequestKeys(action)
|
||||
is RoomDetailAction.TapOnFailedToDecrypt -> handleTapOnFailedToDecrypt(action)
|
||||
is RoomDetailAction.SelectStickerAttachment -> handleSelectStickerAttachment()
|
||||
is RoomDetailAction.OpenIntegrationManager -> handleOpenIntegrationManager()
|
||||
is RoomDetailAction.StartCall -> handleStartCall(action)
|
||||
is RoomDetailAction.EndCall -> handleEndCall()
|
||||
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
|
||||
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
|
||||
is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId)
|
||||
is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action)
|
||||
is RoomDetailAction.CancelSend -> handleCancel(action)
|
||||
is RoomDetailAction.OpenOrCreateDm -> handleOpenOrCreateDm(action)
|
||||
is RoomDetailAction.JumpToReadReceipt -> handleJumpToReadReceipt(action)
|
||||
RoomDetailAction.QuickActionInvitePeople -> handleInvitePeople()
|
||||
RoomDetailAction.QuickActionSetAvatar -> handleQuickSetAvatar()
|
||||
is RoomDetailAction.SetAvatarAction -> handleSetNewAvatar(action)
|
||||
RoomDetailAction.QuickActionSetTopic -> _viewEvents.post(RoomDetailViewEvents.OpenRoomSettings)
|
||||
is RoomDetailAction.ShowRoomAvatarFullScreen -> {
|
||||
is RoomDetailAction.ExitTrackingUnreadMessagesState -> stopTrackingUnreadMessages()
|
||||
is RoomDetailAction.ReplyToOptions -> handleReplyToOptions(action)
|
||||
is RoomDetailAction.AcceptVerificationRequest -> handleAcceptVerification(action)
|
||||
is RoomDetailAction.DeclineVerificationRequest -> handleDeclineVerification(action)
|
||||
is RoomDetailAction.RequestVerification -> handleRequestVerification(action)
|
||||
is RoomDetailAction.ResumeVerification -> handleResumeRequestVerification(action)
|
||||
is RoomDetailAction.ReRequestKeys -> handleReRequestKeys(action)
|
||||
is RoomDetailAction.TapOnFailedToDecrypt -> handleTapOnFailedToDecrypt(action)
|
||||
is RoomDetailAction.SelectStickerAttachment -> handleSelectStickerAttachment()
|
||||
is RoomDetailAction.OpenIntegrationManager -> handleOpenIntegrationManager()
|
||||
is RoomDetailAction.StartCall -> handleStartCall(action)
|
||||
is RoomDetailAction.EndCall -> handleEndCall()
|
||||
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
|
||||
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
|
||||
is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId)
|
||||
is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action)
|
||||
is RoomDetailAction.CancelSend -> handleCancel(action)
|
||||
is RoomDetailAction.OpenOrCreateDm -> handleOpenOrCreateDm(action)
|
||||
is RoomDetailAction.JumpToReadReceipt -> handleJumpToReadReceipt(action)
|
||||
RoomDetailAction.QuickActionInvitePeople -> handleInvitePeople()
|
||||
RoomDetailAction.QuickActionSetAvatar -> handleQuickSetAvatar()
|
||||
is RoomDetailAction.SetAvatarAction -> handleSetNewAvatar(action)
|
||||
RoomDetailAction.QuickActionSetTopic -> _viewEvents.post(RoomDetailViewEvents.OpenRoomSettings)
|
||||
is RoomDetailAction.ShowRoomAvatarFullScreen -> {
|
||||
_viewEvents.post(
|
||||
RoomDetailViewEvents.ShowRoomAvatarFullScreen(action.matrixItem, action.transitionView)
|
||||
)
|
||||
|
@ -593,15 +593,15 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
return@withState false
|
||||
}
|
||||
when (itemId) {
|
||||
R.id.resend_all -> state.asyncRoomSummary()?.hasFailedSending == true
|
||||
R.id.resend_all -> state.asyncRoomSummary()?.hasFailedSending == true
|
||||
R.id.timeline_setting -> true
|
||||
R.id.invite -> state.canInvite
|
||||
R.id.clear_all -> state.asyncRoomSummary()?.hasFailedSending == true
|
||||
R.id.invite -> state.canInvite
|
||||
R.id.clear_all -> state.asyncRoomSummary()?.hasFailedSending == true
|
||||
R.id.open_matrix_apps -> true
|
||||
R.id.voice_call,
|
||||
R.id.video_call -> true // always show for discoverability
|
||||
R.id.hangup_call -> webRtcPeerConnectionManager.currentCall != null
|
||||
R.id.search -> true
|
||||
R.id.video_call -> true // always show for discoverability
|
||||
R.id.hangup_call -> webRtcPeerConnectionManager.currentCall != null
|
||||
R.id.search -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
@ -748,7 +748,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
}
|
||||
}.exhaustive
|
||||
}
|
||||
is SendMode.EDIT -> {
|
||||
is SendMode.EDIT -> {
|
||||
// is original event a reply?
|
||||
val inReplyTo = state.sendMode.timelineEvent.root.getClearContent().toModel<MessageContent>()?.relatesTo?.inReplyTo?.eventId
|
||||
?: state.sendMode.timelineEvent.root.content.toModel<EncryptedEventContent>()?.relatesTo?.inReplyTo?.eventId
|
||||
|
@ -774,7 +774,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
_viewEvents.post(RoomDetailViewEvents.MessageSent)
|
||||
popDraft()
|
||||
}
|
||||
is SendMode.QUOTE -> {
|
||||
is SendMode.QUOTE -> {
|
||||
val messageContent: MessageContent? =
|
||||
state.sendMode.timelineEvent.annotations?.editSummary?.aggregatedContent.toModel()
|
||||
?: state.sendMode.timelineEvent.root.getClearContent().toModel()
|
||||
|
@ -797,7 +797,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
_viewEvents.post(RoomDetailViewEvents.MessageSent)
|
||||
popDraft()
|
||||
}
|
||||
is SendMode.REPLY -> {
|
||||
is SendMode.REPLY -> {
|
||||
state.sendMode.timelineEvent.let {
|
||||
room.replyToMessage(it, action.text.toString(), action.autoMarkdown)
|
||||
_viewEvents.post(RoomDetailViewEvents.MessageSent)
|
||||
|
@ -998,14 +998,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
override fun shouldStartEffect(effect: ChatEffect) {
|
||||
when (effect) {
|
||||
ChatEffect.CONFETTI -> {
|
||||
_viewEvents.post(RoomDetailViewEvents.StartChatEffect(ChatEffect.CONFETTI))
|
||||
}
|
||||
ChatEffect.SNOW -> {
|
||||
_viewEvents.post(RoomDetailViewEvents.StartChatEffect(ChatEffect.SNOW))
|
||||
}
|
||||
}
|
||||
_viewEvents.post(RoomDetailViewEvents.StartChatEffect(effect))
|
||||
}
|
||||
|
||||
override fun stopEffects() {
|
||||
|
@ -1413,6 +1406,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
if (vectorPreferences.sendTypingNotifs()) {
|
||||
room.userStopsTyping()
|
||||
}
|
||||
chatEffectManager.delegate = null
|
||||
chatEffectManager.dispose()
|
||||
super.onCleared()
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="106dp"
|
||||
android:height="106dp"
|
||||
android:viewportWidth="106"
|
||||
android:viewportHeight="106">
|
||||
<path
|
||||
android:pathData="M53,53m-52,0a52,52 0,1 1,104 0a52,52 0,1 1,-104 0"
|
||||
android:strokeAlpha="0.5168103"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:strokeColor="#979797"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
|
@ -6,21 +6,6 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<nl.dionsegijn.konfetti.KonfettiView
|
||||
android:id="@+id/viewKonfetti"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:elevation="4dp"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<com.jetradarmobile.snowfall.SnowfallView
|
||||
android:id="@+id/viewSnowFall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?vctr_chat_effect_snow_background"
|
||||
android:elevation="4dp"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/roomToolbar"
|
||||
style="@style/VectorToolbarStyle"
|
||||
|
@ -240,4 +225,17 @@
|
|||
app:maxImageSize="16dp"
|
||||
app:tint="@color/black" />
|
||||
|
||||
<nl.dionsegijn.konfetti.KonfettiView
|
||||
android:id="@+id/viewKonfetti"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<com.jetradarmobile.snowfall.SnowfallView
|
||||
android:id="@+id/viewSnowFall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?vctr_chat_effect_snow_background"
|
||||
android:visibility="invisible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
Loading…
Reference in New Issue