Add basic pinned message support.

This commit is contained in:
Michelle Tang
2025-11-24 13:18:36 -05:00
committed by jeffrey-signal
parent 22701da765
commit 80598d42cc
70 changed files with 2162 additions and 89 deletions

View File

@@ -23,32 +23,23 @@ fun MessageRecord.isMediaMessage(): Boolean {
slideDeck.stickerSlide == null
}
fun MessageRecord.hasNonTextSlide(): Boolean =
isMms && (this as MmsMessageRecord).slideDeck.slides.any { slide -> slide !is TextSlide }
fun MessageRecord.hasNonTextSlide(): Boolean = isMms && (this as MmsMessageRecord).slideDeck.slides.any { slide -> slide !is TextSlide }
fun MessageRecord.hasSticker(): Boolean =
isMms && (this as MmsMessageRecord).slideDeck.stickerSlide != null
fun MessageRecord.hasSticker(): Boolean = isMms && (this as MmsMessageRecord).slideDeck.stickerSlide != null
fun MessageRecord.hasSharedContact(): Boolean =
isMms && (this as MmsMessageRecord).sharedContacts.isNotEmpty()
fun MessageRecord.hasSharedContact(): Boolean = isMms && (this as MmsMessageRecord).sharedContacts.isNotEmpty()
fun MessageRecord.hasLocation(): Boolean =
isMms && ((this as MmsMessageRecord).slideDeck.slides).any { slide -> slide.hasLocation() }
fun MessageRecord.hasLocation(): Boolean = isMms && ((this as MmsMessageRecord).slideDeck.slides).any { slide -> slide.hasLocation() }
fun MessageRecord.hasAudio(): Boolean =
isMms && (this as MmsMessageRecord).slideDeck.audioSlide != null
fun MessageRecord.hasAudio(): Boolean = isMms && (this as MmsMessageRecord).slideDeck.audioSlide != null
fun MessageRecord.isCaptionlessMms(context: Context): Boolean =
isMms && isDisplayBodyEmpty(context) && (this as MmsMessageRecord).slideDeck.textSlide == null
fun MessageRecord.isCaptionlessMms(context: Context): Boolean = isMms && isDisplayBodyEmpty(context) && (this as MmsMessageRecord).slideDeck.textSlide == null
fun MessageRecord.hasThumbnail(): Boolean =
isMms && (this as MmsMessageRecord).slideDeck.thumbnailSlide != null
fun MessageRecord.hasThumbnail(): Boolean = isMms && (this as MmsMessageRecord).slideDeck.thumbnailSlide != null
fun MessageRecord.isStoryReaction(): Boolean =
isMms && MessageTypes.isStoryReaction(type)
fun MessageRecord.isStoryReaction(): Boolean = isMms && MessageTypes.isStoryReaction(type)
fun MessageRecord.isStory(): Boolean =
isMms && (this as MmsMessageRecord).storyType.isStory
fun MessageRecord.isStory(): Boolean = isMms && (this as MmsMessageRecord).storyType.isStory
fun MessageRecord.isBorderless(context: Context): Boolean {
return isCaptionlessMms(context) &&
@@ -56,8 +47,7 @@ fun MessageRecord.isBorderless(context: Context): Boolean {
(this as MmsMessageRecord).slideDeck.thumbnailSlide?.isBorderless == true
}
fun MessageRecord.hasNoBubble(context: Context): Boolean =
hasSticker() || isBorderless(context) || (isTextOnly(context) && isJumbomoji(context) && (messageRanges?.ranges?.isEmpty() ?: true))
fun MessageRecord.hasNoBubble(context: Context): Boolean = hasSticker() || isBorderless(context) || (isTextOnly(context) && isJumbomoji(context) && (messageRanges?.ranges?.isEmpty() ?: true))
fun MessageRecord.hasOnlyThumbnail(context: Context): Boolean {
return hasThumbnail() &&
@@ -69,11 +59,9 @@ fun MessageRecord.hasOnlyThumbnail(context: Context): Boolean {
!isViewOnceMessage()
}
fun MessageRecord.hasDocument(): Boolean =
isMms && (this as MmsMessageRecord).slideDeck.documentSlide != null
fun MessageRecord.hasDocument(): Boolean = isMms && (this as MmsMessageRecord).slideDeck.documentSlide != null
fun MessageRecord.isViewOnceMessage(): Boolean =
isMms && (this as MmsMessageRecord).isViewOnce
fun MessageRecord.isViewOnceMessage(): Boolean = isMms && (this as MmsMessageRecord).isViewOnce
fun MessageRecord.hasExtraText(): Boolean {
val hasTextSlide = isMms && (this as MmsMessageRecord).slideDeck.textSlide != null
@@ -82,24 +70,19 @@ fun MessageRecord.hasExtraText(): Boolean {
return hasTextSlide || hasOverflowText
}
fun MessageRecord.hasQuote(): Boolean =
isMms && (this as MmsMessageRecord).quote != null
fun MessageRecord.hasQuote(): Boolean = isMms && (this as MmsMessageRecord).quote != null
fun MessageRecord.getQuote(): Quote? =
if (isMms) {
(this as MmsMessageRecord).quote
} else {
null
}
fun MessageRecord.getQuote(): Quote? = if (isMms) {
(this as MmsMessageRecord).quote
} else {
null
}
fun MessageRecord.hasLinkPreview(): Boolean =
isMms && (this as MmsMessageRecord).linkPreviews.isNotEmpty()
fun MessageRecord.hasLinkPreview(): Boolean = isMms && (this as MmsMessageRecord).linkPreviews.isNotEmpty()
fun MessageRecord.hasTextSlide(): Boolean =
isMms && (this as MmsMessageRecord).slideDeck.textSlide != null && this.slideDeck.textSlide?.uri != null
fun MessageRecord.hasTextSlide(): Boolean = isMms && (this as MmsMessageRecord).slideDeck.textSlide != null && this.slideDeck.textSlide?.uri != null
fun MessageRecord.requireTextSlide(): TextSlide =
requireNotNull((this as MmsMessageRecord).slideDeck.textSlide)
fun MessageRecord.requireTextSlide(): TextSlide = requireNotNull((this as MmsMessageRecord).slideDeck.textSlide)
fun MessageRecord.hasPoll(): Boolean = isMms && (this as MmsMessageRecord).poll != null
@@ -107,6 +90,8 @@ fun MessageRecord.getPoll(): PollRecord? = if (isMms) (this as MmsMessageRecord)
fun MessageRecord.hasPollTerminate(): Boolean = this.isPollTerminate && this.messageExtras != null && this.messageExtras!!.pollTerminate != null
fun MessageRecord.hasPinnedMessageUpdate(): Boolean = this.isPinnedMessageUpdate && this.messageExtras != null && this.messageExtras!!.pinnedMessage != null
fun MessageRecord.hasBigImageLinkPreview(context: Context): Boolean {
if (!hasLinkPreview()) {
return false

View File

@@ -1205,5 +1205,29 @@ object RemoteConfig {
defaultValue = false,
hotSwappable = true
)
@JvmStatic
@get:JvmName("pinLimit")
val pinLimit: Int by remoteInt(
key = "global.pinnedMessageLimit",
defaultValue = 3,
hotSwappable = true
)
@JvmStatic
@get:JvmName("receivePinnedMessages")
val receivePinnedMessages: Boolean by remoteBoolean(
key = "android.receivePinnedMessages",
defaultValue = false,
hotSwappable = true
)
@JvmStatic
@get:JvmName("sendPinnedMessages")
val sendPinnedMessages: Boolean by remoteBoolean(
key = "android.sendPinnedMessages",
defaultValue = false,
hotSwappable = true
)
// endregion
}