Skip to content

Commit 647f7d5

Browse files
authored
Merge pull request #213 from RocketChat/release/3.0.1-hotfix
Refactor Attachments
2 parents 9b38f52 + 0f87a60 commit 647f7d5

11 files changed

+144
-349
lines changed

core/src/main/kotlin/chat/rocket/core/internal/AttachmentAdapter.kt

+73-155
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,14 @@ package chat.rocket.core.internal
33
import chat.rocket.common.internal.ISO8601Date
44
import chat.rocket.common.util.Logger
55
import chat.rocket.core.model.attachment.Attachment
6-
import chat.rocket.core.model.attachment.AudioAttachment
7-
import chat.rocket.core.model.attachment.AuthorAttachment
86
import chat.rocket.core.model.attachment.Color
9-
import chat.rocket.core.model.attachment.ColorAttachment
10-
import chat.rocket.core.model.attachment.DEFAULT_COLOR
117
import chat.rocket.core.model.attachment.Field
12-
import chat.rocket.core.model.attachment.FileAttachment
13-
import chat.rocket.core.model.attachment.GenericFileAttachment
14-
import chat.rocket.core.model.attachment.ImageAttachment
15-
import chat.rocket.core.model.attachment.MessageAttachment
16-
import chat.rocket.core.model.attachment.VideoAttachment
178
import com.squareup.moshi.JsonAdapter
18-
import com.squareup.moshi.JsonDataException
199
import com.squareup.moshi.JsonReader
2010
import com.squareup.moshi.JsonWriter
2111
import com.squareup.moshi.Moshi
2212
import com.squareup.moshi.Types
2313
import chat.rocket.core.model.attachment.actions.Action
24-
import chat.rocket.core.model.attachment.actions.ActionsAttachment
2514
import chat.rocket.core.model.attachment.actions.ButtonAction
2615
import java.lang.reflect.Type
2716

@@ -143,45 +132,50 @@ class AttachmentAdapter(moshi: Moshi, private val logger: Logger) : JsonAdapter<
143132
}
144133
reader.endObject()
145134

146-
return when {
147-
imageUrl != null -> {
148-
var preview: String? = null
149-
imagePreview?.let {
150-
preview = "data:${imageType!!};base64,$it"
151-
}
152-
ImageAttachment(title, description, text, titleLink, titleLinkDownload, imageUrl, imageType, imageSize, preview)
153-
}
154-
videoUrl != null -> {
155-
VideoAttachment(title, description, text, titleLink, titleLinkDownload, videoUrl, videoType, videoSize)
156-
}
157-
audioUrl != null -> {
158-
AudioAttachment(title, description, text, titleLink, titleLinkDownload, audioUrl, audioType, audioSize)
159-
}
160-
titleLink != null -> {
161-
GenericFileAttachment(title, description, text, titleLink, titleLink, titleLinkDownload)
162-
}
163-
text != null && color != null && fallback != null -> {
164-
ColorAttachment(color, text, fallback, fields)
165-
}
166-
text != null -> {
167-
MessageAttachment(authorName, authorIcon, text, thumbUrl, color, messageLink, attachments, timestamp)
168-
}
169-
authorLink != null -> {
170-
AuthorAttachment(authorLink, authorIcon, authorName, fields)
171-
}
172-
fields != null -> {
173-
ColorAttachment(color ?: DEFAULT_COLOR, text ?: "", fallback, fields)
174-
}
175-
actions != null -> {
176-
ActionsAttachment(title, actions, buttonAlignment = buttonAlignment ?: "vertical")
177-
}
178-
else -> {
179-
logger.debug {
180-
"Invalid Attachment type: supported are file and message at ${reader.path} - type: $type"
181-
}
182-
null
135+
if (isAllNull(title, type, description, authorName, text, thumbUrl, color, titleLink, titleLinkDownload,
136+
imageUrl, imageType, imageSize, videoUrl, videoType, videoSize, audioUrl, audioType, audioSize,
137+
messageLink, attachments, timestamp, authorIcon, authorLink, imagePreview, fields, fallback,
138+
buttonAlignment, actions)) {
139+
logger.debug {
140+
"Empty attachment"
183141
}
142+
return null
184143
}
144+
145+
return Attachment(
146+
title = title,
147+
type = type,
148+
description = description,
149+
authorName = authorName,
150+
text = text,
151+
thumbUrl = thumbUrl,
152+
color = color,
153+
titleLink = titleLink,
154+
titleLinkDownload = titleLinkDownload,
155+
imageUrl = imageUrl,
156+
imageType = imageType,
157+
imageSize = imageSize,
158+
videoUrl = videoUrl,
159+
videoType = videoType,
160+
videoSize = videoSize,
161+
audioUrl = audioUrl,
162+
audioType = audioType,
163+
audioSize = audioSize,
164+
messageLink = messageLink,
165+
attachments = attachments,
166+
timestamp = timestamp,
167+
authorIcon = authorIcon,
168+
authorLink = authorLink,
169+
imagePreview = imagePreview,
170+
fields = fields,
171+
fallback = fallback,
172+
buttonAlignment = buttonAlignment,
173+
actions = actions
174+
)
175+
}
176+
177+
private fun isAllNull(vararg params: Any?): Boolean {
178+
return params.isEmpty()
185179
}
186180

187181
private fun parseFields(reader: JsonReader): List<Field>? {
@@ -258,103 +252,41 @@ class AttachmentAdapter(moshi: Moshi, private val logger: Logger) : JsonAdapter<
258252
}
259253
}
260254

261-
override fun toJson(writer: JsonWriter, value: Attachment?) {
262-
if (value == null) {
255+
override fun toJson(writer: JsonWriter, attachment: Attachment?) {
256+
if (attachment == null) {
263257
writer.nullValue()
264258
} else {
265-
when (value) {
266-
is ColorAttachment -> writeColorAttachment(writer, value)
267-
is MessageAttachment -> writeMessageAttachment(writer, value)
268-
is FileAttachment -> writeFileAttachment(writer, value)
269-
is AuthorAttachment -> writeAuthorAttachment(writer, value)
270-
is ActionsAttachment -> writeActionsAttachment(writer, value)
271-
}
272-
}
273-
}
274-
275-
private fun writeColorAttachment(writer: JsonWriter, attachment: ColorAttachment) {
276-
writer.beginObject()
277-
with(writer) {
278-
name("color").value(attachment.color.rawColor)
279-
name("text").value(attachment.text)
280-
name("fallback").value(attachment.fallback)
281-
attachment.fields?.let { writeFields(writer, it) }
282-
}
283-
writer.endObject()
284-
}
259+
with(writer) {
260+
beginObject()
261+
name("title").value(attachment.title)
262+
name("description").value(attachment.description)
263+
name("text").value(attachment.text)
264+
name("title_link").value(attachment.titleLink)
265+
name("title_link_download").value(attachment.titleLinkDownload)
266+
name("image_url").value(attachment.imageUrl)
267+
name("image_size").value(attachment.imageSize)
268+
name("image_type").value(attachment.imageType)
269+
name("image_preview").value(attachment.imagePreview)
270+
name("video_url").value(attachment.videoUrl)
271+
name("video_size").value(attachment.videoType)
272+
name("video_type").value(attachment.videoUrl)
273+
name("audio_url").value(attachment.audioUrl)
274+
name("audio_size").value(attachment.audioSize)
275+
name("audio_type").value(attachment.audioType)
276+
name("author_link").value(attachment.authorLink)
277+
name("author_icon").value(attachment.authorIcon)
278+
name("author_name").value(attachment.authorName)
279+
name("button_alignment").value(attachment.buttonAlignment)
280+
name("color").value(attachment.color?.rawColor)
281+
name("fallback").value(attachment.fallback)
282+
name("thumbUrl").value(attachment.thumbUrl)
283+
name("message_link").value(attachment.messageLink)
284+
name("ts").value(attachment.timestamp)
285285

286-
private fun writeMessageAttachment(writer: JsonWriter, attachment: MessageAttachment) {
287-
writer.beginObject()
288-
with(writer) {
289-
name("author_name").value(attachment.author)
290-
name("author_icon").value(attachment.icon)
291-
name("text").value(attachment.text)
292-
name("thumbUrl").value(attachment.thumbUrl)
293-
name("color").value(attachment.color?.toString())
294-
name("message_link").value(attachment.url)
295-
name("ts").value(attachment.timestamp)
296-
}
297-
writer.endObject()
298-
}
299-
300-
private fun writeFileAttachment(writer: JsonWriter, attachment: FileAttachment) {
301-
writer.beginObject()
302-
writer.name("title").value(attachment.title)
303-
writer.name("description").value(attachment.description)
304-
writer.name("text").value(attachment.text)
305-
writer.name("title_link").value(attachment.titleLink)
306-
writer.name("title_link_download").value(attachment.titleLinkDownload)
307-
when (attachment) {
308-
is AudioAttachment -> writeAudioAttachment(writer, attachment)
309-
is VideoAttachment -> writeVideoAttachment(writer, attachment)
310-
is ImageAttachment -> writeImageAttachment(writer, attachment)
311-
is GenericFileAttachment -> writeGenericFileAttachment(writer, attachment)
312-
}
313-
writer.endObject()
314-
}
315-
316-
private fun writeGenericFileAttachment(writer: JsonWriter, attachment: GenericFileAttachment) {
317-
with(writer) {
318-
name("title").value(attachment.title)
319-
name("titleLink").value(attachment.url)
320-
name("titleLinkDownload").value(attachment.titleLinkDownload)
321-
}
322-
}
323-
324-
private fun writeAudioAttachment(writer: JsonWriter, attachment: AudioAttachment) {
325-
with(writer) {
326-
name("audio_url").value(attachment.url)
327-
name("audio_size").value(attachment.size)
328-
name("audio_type").value(attachment.type)
329-
}
330-
}
331-
332-
private fun writeVideoAttachment(writer: JsonWriter, attachment: VideoAttachment) {
333-
with(writer) {
334-
name("video_url").value(attachment.url)
335-
name("video_size").value(attachment.size)
336-
name("video_type").value(attachment.type)
337-
}
338-
}
339-
340-
private fun writeImageAttachment(writer: JsonWriter, attachment: ImageAttachment) {
341-
with(writer) {
342-
name("image_url").value(attachment.url)
343-
name("image_size").value(attachment.size)
344-
name("image_type").value(attachment.type)
345-
name("image_preview").value(attachment.imagePreview)
346-
}
347-
}
348-
349-
private fun writeAuthorAttachment(writer: JsonWriter, attachment: AuthorAttachment) {
350-
writer.beginObject()
351-
with(writer) {
352-
name("author_link").value(attachment.url)
353-
name("author_icon").value(attachment.authorIcon)
354-
name("author_name").value(attachment.authorName)
355-
attachment.fields?.let { writeFields(writer, it) }
286+
attachment.actions?.let { writeActions(writer, it) }
287+
attachment.fields?.let { writeFields(writer, it) }
288+
}
356289
}
357-
writer.endObject()
358290
}
359291

360292
private fun writeFields(writer: JsonWriter, fields: List<Field>) {
@@ -371,16 +303,6 @@ class AttachmentAdapter(moshi: Moshi, private val logger: Logger) : JsonAdapter<
371303
}
372304
}
373305

374-
private fun writeActionsAttachment(writer: JsonWriter, attachment: ActionsAttachment) {
375-
writer.beginObject()
376-
with(writer) {
377-
name("title").value(attachment.title)
378-
name("button_alignment").value(attachment.buttonAlignment)
379-
attachment.actions?.let { writeActions(writer, it) }
380-
}
381-
writer.endObject()
382-
}
383-
384306
private fun writeActions(writer: JsonWriter, actions: List<Action>) {
385307
if (actions.isNotEmpty()) {
386308
writer.name("actions")
@@ -402,10 +324,6 @@ class AttachmentAdapter(moshi: Moshi, private val logger: Logger) : JsonAdapter<
402324
writer.endArray()
403325
}
404326
}
405-
406-
private fun checkNonNull(field: Any?, fieldName: String) {
407-
if (field == null) throw JsonDataException("$fieldName is null")
408-
}
409327
}
410328

411329
class AttachmentAdapterFactory(private val logger: Logger) : JsonAdapter.Factory {
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,74 @@
11
package chat.rocket.core.model.attachment
22

3-
interface Attachment {
4-
val url: String
3+
import chat.rocket.common.internal.FallbackSealedClass
4+
import chat.rocket.core.model.attachment.actions.Action
5+
import com.squareup.moshi.Json
6+
7+
data class Attachment(
8+
var title: String? = null,
9+
var type: String? = null,
10+
var description: String? = null,
11+
var authorName: String? = null,
12+
var text: String? = null,
13+
var thumbUrl: String? = null,
14+
var color: Color? = null,
15+
var titleLink: String? = null,
16+
var titleLinkDownload: Boolean = false,
17+
var imageUrl: String? = null,
18+
var imageType: String? = null,
19+
var imageSize: Long? = null,
20+
var videoUrl: String? = null,
21+
var videoType: String? = null,
22+
var videoSize: Long? = null,
23+
var audioUrl: String? = null,
24+
var audioType: String? = null,
25+
var audioSize: Long? = null,
26+
var messageLink: String? = null,
27+
var attachments: List<Attachment>? = null,
28+
var timestamp: Long? = null,
29+
var authorIcon: String? = null,
30+
var authorLink: String? = null,
31+
var imagePreview: String? = null,
32+
var fields: List<Field>? = null,
33+
var fallback: String? = null,
34+
var buttonAlignment: String? = null,
35+
var actions: List<Action>? = null
36+
)
37+
38+
@FallbackSealedClass(name = "Custom", fieldName = "colorValue")
39+
sealed class Color(val color: Int, val rawColor: String) {
40+
@Json(name = "good") class Good : Color(parseColor("#35AC19"), "#35AC19")
41+
@Json(name = "warning") class Warning : Color(parseColor("#FCB316"), "#FCB316")
42+
@Json(name = "danger") class Danger : Color(parseColor("#D30230"), "#D30230")
43+
class Custom(private val colorValue: String) : Color(parseColor(colorValue), colorValue)
44+
45+
override fun toString(): String {
46+
return color.toString(16)
47+
}
48+
}
49+
50+
private const val DEFAULT_COLOR_INT = 0xA0A0A0
51+
const val DEFAULT_COLOR_STR = "#A0A0A0"
52+
val DEFAULT_COLOR = Color.Custom(DEFAULT_COLOR_STR)
53+
54+
fun String?.asColorInt() = parseColor(this ?: DEFAULT_COLOR_STR)
55+
fun String?.asColor() = Color.Custom(this ?: DEFAULT_COLOR_STR)
56+
57+
private fun parseColor(toParseColor: String): Int {
58+
var rawColor = toParseColor.toUpperCase()
59+
if (rawColor.startsWith("0X")) {
60+
rawColor = "#${rawColor.drop(2)}"
61+
}
62+
return if (rawColor.startsWith('#')) {
63+
var color = toParseColor.substring(1).toLong(16)
64+
if (toParseColor.length == 7) {
65+
// Set the alpha value
66+
color = color or -0x1000000
67+
} else if (toParseColor.length != 9) {
68+
color = DEFAULT_COLOR_INT.toLong()
69+
}
70+
color.toInt()
71+
} else {
72+
DEFAULT_COLOR_INT
73+
}
574
}

core/src/main/kotlin/chat/rocket/core/model/attachment/AudioAttachment.kt

-21
This file was deleted.

core/src/main/kotlin/chat/rocket/core/model/attachment/AuthorAttachment.kt

-16
This file was deleted.

0 commit comments

Comments
 (0)