mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-23 18:05:59 +03:00
Merge pull request #220 from vector-im/feature/restrict_reaction_emoji
Only show reactions with an emoji key
This commit is contained in:
commit
17a4a86ad1
5 changed files with 71 additions and 25 deletions
|
@ -54,6 +54,7 @@ import im.vector.riotredesign.push.fcm.FcmHelper
|
|||
import timber.log.Timber
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import im.vector.riotredesign.core.utils.initKnownEmojiHashSet
|
||||
import javax.inject.Inject
|
||||
|
||||
class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.Provider, androidx.work.Configuration.Provider {
|
||||
|
@ -124,6 +125,8 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
|
|||
FcmHelper.onEnterBackground(appContext, activeSessionHolder)
|
||||
}
|
||||
})
|
||||
//This should be done as early as possible
|
||||
initKnownEmojiHashSet(appContext)
|
||||
}
|
||||
|
||||
override fun providesMatrixConfiguration() = MatrixConfiguration(BuildConfig.FLAVOR_DESCRIPTION)
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
package im.vector.riotredesign.core.utils
|
||||
|
||||
import android.content.Context
|
||||
import com.squareup.moshi.Moshi
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.features.reactions.EmojiDataSource
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.util.regex.Pattern
|
||||
|
||||
private val emojisPattern = Pattern.compile("((?:[\uD83C\uDF00-\uD83D\uDDFF]" +
|
||||
|
@ -26,6 +33,34 @@ private val emojisPattern = Pattern.compile("((?:[\uD83C\uDF00-\uD83D\uDDFF]" +
|
|||
"|\uD83C\uDCCF\uFE0F?" +
|
||||
"|[\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA]\uFE0F?))")
|
||||
|
||||
//A hashset from all supported emoji
|
||||
private var knownEmojiSet: HashSet<String>? = null
|
||||
|
||||
fun initKnownEmojiHashSet(context: Context, done: (() -> Unit)? = null) {
|
||||
GlobalScope.launch {
|
||||
context.resources.openRawResource(R.raw.emoji_picker_datasource).use { input ->
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(EmojiDataSource.EmojiData::class.java)
|
||||
val inputAsString = input.bufferedReader().use { it.readText() }
|
||||
val source = jsonAdapter.fromJson(inputAsString)
|
||||
knownEmojiSet = HashSet<String>()
|
||||
source?.emojis?.values?.forEach {
|
||||
knownEmojiSet?.add(it.emojiString())
|
||||
}
|
||||
done?.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isSingleEmoji(string: String): Boolean {
|
||||
if (knownEmojiSet == null) {
|
||||
Timber.e("Known Emoji Hashset not initialized")
|
||||
//use fallback regexp
|
||||
return containsOnlyEmojis(string)
|
||||
}
|
||||
return knownEmojiSet?.contains(string) ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a string contains emojis.
|
||||
* It seems that the regex [emoji_regex]+ does not work.
|
||||
|
@ -66,4 +101,3 @@ fun containsOnlyEmojis(str: String?): Boolean {
|
|||
|
||||
return res
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,9 @@ import im.vector.riotredesign.core.resources.StringProvider
|
|||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import org.json.JSONObject
|
||||
|
||||
import im.vector.riotredesign.core.utils.isSingleEmoji
|
||||
|
||||
|
||||
data class SimpleAction(val uid: String, val titleRes: Int, val iconResId: Int?, val data: Any? = null)
|
||||
|
||||
data class MessageMenuState(
|
||||
|
@ -92,7 +95,7 @@ class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: M
|
|||
val event = session.getRoom(state.roomId)?.getTimeLineEvent(state.eventId) ?: return state
|
||||
|
||||
val messageContent: MessageContent? = event.annotations?.editSummary?.aggregatedContent?.toModel()
|
||||
?: event.root.content.toModel()
|
||||
?: event.root.content.toModel()
|
||||
val type = messageContent?.type
|
||||
|
||||
val actions = if (!event.sendState.isSent()) {
|
||||
|
@ -143,8 +146,8 @@ class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: M
|
|||
if (messageContent is MessageImageContent) {
|
||||
this.add(
|
||||
SimpleAction(ACTION_SHARE,
|
||||
R.string.share, R.drawable.ic_share,
|
||||
session.contentUrlResolver().resolveFullSize(messageContent.url))
|
||||
R.string.share, R.drawable.ic_share,
|
||||
session.contentUrlResolver().resolveFullSize(messageContent.url))
|
||||
)
|
||||
}
|
||||
//TODO
|
||||
|
@ -212,31 +215,31 @@ class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: M
|
|||
}
|
||||
}
|
||||
|
||||
private fun canRedact(event: TimelineEvent, myUserId: String): Boolean {
|
||||
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
|
||||
if (event.root.getClearType() != EventType.MESSAGE) return false
|
||||
//TODO if user is admin or moderator
|
||||
return event.root.senderId == myUserId
|
||||
}
|
||||
private fun canRedact(event: TimelineEvent, myUserId: String): Boolean {
|
||||
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
|
||||
if (event.root.getClearType() != EventType.MESSAGE) return false
|
||||
//TODO if user is admin or moderator
|
||||
return event.root.senderId == myUserId
|
||||
}
|
||||
|
||||
private fun canViewReactions(event: TimelineEvent): Boolean {
|
||||
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
|
||||
if (event.root.getClearType() != EventType.MESSAGE) return false
|
||||
//TODO if user is admin or moderator
|
||||
return event.annotations?.reactionsSummary?.isNotEmpty() ?: false
|
||||
return event.annotations?.reactionsSummary?.any { isSingleEmoji(it.key) } ?: false
|
||||
}
|
||||
|
||||
|
||||
private fun canEdit(event: TimelineEvent, myUserId: String): Boolean {
|
||||
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
|
||||
if (event.root.getClearType() != EventType.MESSAGE) return false
|
||||
//TODO if user is admin or moderator
|
||||
val messageContent = event.root.content.toModel<MessageContent>()
|
||||
return event.root.senderId == myUserId && (
|
||||
messageContent?.type == MessageType.MSGTYPE_TEXT
|
||||
|| messageContent?.type == MessageType.MSGTYPE_EMOTE
|
||||
)
|
||||
}
|
||||
private fun canEdit(event: TimelineEvent, myUserId: String): Boolean {
|
||||
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
|
||||
if (event.root.getClearType() != EventType.MESSAGE) return false
|
||||
//TODO if user is admin or moderator
|
||||
val messageContent = event.root.content.toModel<MessageContent>()
|
||||
return event.root.senderId == myUserId && (
|
||||
messageContent?.type == MessageType.MSGTYPE_TEXT
|
||||
|| messageContent?.type == MessageType.MSGTYPE_EMOTE
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun canCopy(type: String?): Boolean {
|
||||
|
|
|
@ -8,6 +8,7 @@ import im.vector.matrix.android.api.session.room.model.ReactionAggregatedSummary
|
|||
import im.vector.matrix.rx.RxRoom
|
||||
import im.vector.riotredesign.core.extensions.localDateTime
|
||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||
import im.vector.riotredesign.core.utils.isSingleEmoji
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
@ -69,7 +70,9 @@ class ViewReactionViewModel @AssistedInject constructor(@Assisted
|
|||
.flatMapSingle { summaries ->
|
||||
Observable
|
||||
.fromIterable(summaries)
|
||||
.flatMapIterable {it.reactionsSummary}
|
||||
.flatMapIterable { it.reactionsSummary
|
||||
.filter { reactionAggregatedSummary -> isSingleEmoji(reactionAggregatedSummary.key) }
|
||||
}
|
||||
.toReactionInfoList()
|
||||
}
|
||||
.execute {
|
||||
|
|
|
@ -20,6 +20,7 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
|||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.riotredesign.core.extensions.localDateTime
|
||||
import im.vector.riotredesign.core.resources.ColorProvider
|
||||
import im.vector.riotredesign.core.utils.isSingleEmoji
|
||||
import im.vector.riotredesign.features.home.getColorFromUserId
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||
|
@ -68,9 +69,11 @@ class MessageInformationDataFactory @Inject constructor(private val timelineDate
|
|||
avatarUrl = avatarUrl,
|
||||
memberName = formattedMemberName,
|
||||
showInformation = showInformation,
|
||||
orderedReactionList = event.annotations?.reactionsSummary?.map {
|
||||
ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty())
|
||||
},
|
||||
orderedReactionList = event.annotations?.reactionsSummary
|
||||
?.filter { isSingleEmoji(it.key) }
|
||||
?.map {
|
||||
ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty())
|
||||
},
|
||||
hasBeenEdited = hasBeenEdited
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue