core, ui: tolerate unknown MsgContentTag in chatContentTypes (#6805)

This commit is contained in:
Narasimha-sc
2026-04-16 09:10:48 +00:00
committed by GitHub
parent ac6f8b76ac
commit e2a55291fc
4 changed files with 86 additions and 14 deletions
+1 -1
View File
@@ -458,7 +458,7 @@ func apiGetChat(chatId: ChatId, scope: GroupChatScope?, contentTag: MsgContentTa
func apiGetChatContentTypes(chatId: ChatId, scope: GroupChatScope? = nil) async throws -> [MsgContentTag] {
let r: ChatResponse0 = try await chatSendCmd(.apiGetChatContentTypes(chatId: chatId, scope: scope))
if case let .chatContentTypes(types) = r { return types }
if case let .chatContentTypes(types) = r { return types.filter { if case .unknown = $0 { return false }; return true } }
throw r.unexpected
}
+38 -1
View File
@@ -4773,7 +4773,7 @@ extension MsgContent: Encodable {
}
}
public enum MsgContentTag: String, Decodable {
public enum MsgContentTag: Codable, Hashable {
case text
case link
case image
@@ -4781,6 +4781,43 @@ public enum MsgContentTag: String, Decodable {
case voice
case file
case report
case chat
case unknown(type: String)
public var rawValue: String {
switch self {
case .text: return "text"
case .link: return "link"
case .image: return "image"
case .video: return "video"
case .voice: return "voice"
case .file: return "file"
case .report: return "report"
case .chat: return "chat"
case let .unknown(type): return type
}
}
public init(from decoder: Decoder) throws {
let s = try decoder.singleValueContainer().decode(String.self)
switch s {
case "text": self = .text
case "link": self = .link
case "image": self = .image
case "video": self = .video
case "voice": self = .voice
case "file": self = .file
case "report": self = .report
case "chat": self = .chat
case "liveText": self = .text
default: self = .unknown(type: s)
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
}
}
public enum MsgChatLink: Codable, Equatable, Hashable {
@@ -4492,16 +4492,51 @@ object MsgContentSerializer : KSerializer<MsgContent> {
}
}
@Serializable
enum class MsgContentTag {
@SerialName("text") Text,
@SerialName("link") Link,
@SerialName("image") Image,
@SerialName("video") Video,
@SerialName("voice") Voice,
@SerialName("file") File,
@SerialName("report") Report,
@SerialName("chat") Chat,
@Serializable(with = MsgContentTagSerializer::class)
sealed class MsgContentTag {
@Serializable @SerialName("text") object Text: MsgContentTag()
@Serializable @SerialName("link") object Link: MsgContentTag()
@Serializable @SerialName("image") object Image: MsgContentTag()
@Serializable @SerialName("video") object Video: MsgContentTag()
@Serializable @SerialName("voice") object Voice: MsgContentTag()
@Serializable @SerialName("file") object File: MsgContentTag()
@Serializable @SerialName("report") object Report: MsgContentTag()
@Serializable @SerialName("chat") object Chat: MsgContentTag()
@Serializable @SerialName("unknown") data class Unknown(val type: String): MsgContentTag()
val cmdString: String get() = when (this) {
is Text -> "text"
is Link -> "link"
is Image -> "image"
is Video -> "video"
is Voice -> "voice"
is File -> "file"
is Report -> "report"
is Chat -> "chat"
is Unknown -> type
}
}
object MsgContentTagSerializer : KSerializer<MsgContentTag> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("MsgContentTag", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): MsgContentTag =
when (val s = decoder.decodeString()) {
"text" -> MsgContentTag.Text
"link" -> MsgContentTag.Link
"image" -> MsgContentTag.Image
"video" -> MsgContentTag.Video
"voice" -> MsgContentTag.Voice
"file" -> MsgContentTag.File
"report" -> MsgContentTag.Report
"chat" -> MsgContentTag.Chat
"liveText" -> MsgContentTag.Text
else -> MsgContentTag.Unknown(s)
}
override fun serialize(encoder: Encoder, value: MsgContentTag) {
encoder.encodeString(value.cmdString)
}
}
@Serializable
@@ -1043,7 +1043,7 @@ object ChatController {
suspend fun apiGetChatContentTypes(rh: Long?, type: ChatType, id: Long, scope: GroupChatScope?): List<MsgContentTag>? {
val r = sendCmd(rh, CC.ApiGetChatContentTypes(type, id, scope))
if (r is API.Result && r.res is CR.ChatContentTypes) return r.res.contentTypes
if (r is API.Result && r.res is CR.ChatContentTypes) return r.res.contentTypes.filter { it !is MsgContentTag.Unknown }
Log.e(TAG, "apiGetChatContentTypes bad response: ${r.responseType} ${r.details}")
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_loading_details), "${r.responseType}: ${r.details}")
return null
@@ -3790,7 +3790,7 @@ sealed class CC {
val tag = if (contentTag == null) {
""
} else {
" content=${contentTag.name.lowercase()}"
" content=${contentTag.cmdString}"
}
"/_get chat ${chatRef(type, id, scope)}$tag ${pagination.cmdString}" + (if (search == "") "" else " search=$search")
}