Skip to content

Commit

Permalink
Merge pull request #213 from RocketChat/release/3.0.1-hotfix
Browse files Browse the repository at this point in the history
Refactor Attachments
  • Loading branch information
rafaelks authored Nov 2, 2018
2 parents 9b38f52 + 0f87a60 commit 647f7d5
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 349 deletions.
228 changes: 73 additions & 155 deletions core/src/main/kotlin/chat/rocket/core/internal/AttachmentAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,14 @@ package chat.rocket.core.internal
import chat.rocket.common.internal.ISO8601Date
import chat.rocket.common.util.Logger
import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.AudioAttachment
import chat.rocket.core.model.attachment.AuthorAttachment
import chat.rocket.core.model.attachment.Color
import chat.rocket.core.model.attachment.ColorAttachment
import chat.rocket.core.model.attachment.DEFAULT_COLOR
import chat.rocket.core.model.attachment.Field
import chat.rocket.core.model.attachment.FileAttachment
import chat.rocket.core.model.attachment.GenericFileAttachment
import chat.rocket.core.model.attachment.ImageAttachment
import chat.rocket.core.model.attachment.MessageAttachment
import chat.rocket.core.model.attachment.VideoAttachment
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonDataException
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import chat.rocket.core.model.attachment.actions.Action
import chat.rocket.core.model.attachment.actions.ActionsAttachment
import chat.rocket.core.model.attachment.actions.ButtonAction
import java.lang.reflect.Type

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

return when {
imageUrl != null -> {
var preview: String? = null
imagePreview?.let {
preview = "data:${imageType!!};base64,$it"
}
ImageAttachment(title, description, text, titleLink, titleLinkDownload, imageUrl, imageType, imageSize, preview)
}
videoUrl != null -> {
VideoAttachment(title, description, text, titleLink, titleLinkDownload, videoUrl, videoType, videoSize)
}
audioUrl != null -> {
AudioAttachment(title, description, text, titleLink, titleLinkDownload, audioUrl, audioType, audioSize)
}
titleLink != null -> {
GenericFileAttachment(title, description, text, titleLink, titleLink, titleLinkDownload)
}
text != null && color != null && fallback != null -> {
ColorAttachment(color, text, fallback, fields)
}
text != null -> {
MessageAttachment(authorName, authorIcon, text, thumbUrl, color, messageLink, attachments, timestamp)
}
authorLink != null -> {
AuthorAttachment(authorLink, authorIcon, authorName, fields)
}
fields != null -> {
ColorAttachment(color ?: DEFAULT_COLOR, text ?: "", fallback, fields)
}
actions != null -> {
ActionsAttachment(title, actions, buttonAlignment = buttonAlignment ?: "vertical")
}
else -> {
logger.debug {
"Invalid Attachment type: supported are file and message at ${reader.path} - type: $type"
}
null
if (isAllNull(title, type, description, authorName, text, thumbUrl, color, titleLink, titleLinkDownload,
imageUrl, imageType, imageSize, videoUrl, videoType, videoSize, audioUrl, audioType, audioSize,
messageLink, attachments, timestamp, authorIcon, authorLink, imagePreview, fields, fallback,
buttonAlignment, actions)) {
logger.debug {
"Empty attachment"
}
return null
}

return Attachment(
title = title,
type = type,
description = description,
authorName = authorName,
text = text,
thumbUrl = thumbUrl,
color = color,
titleLink = titleLink,
titleLinkDownload = titleLinkDownload,
imageUrl = imageUrl,
imageType = imageType,
imageSize = imageSize,
videoUrl = videoUrl,
videoType = videoType,
videoSize = videoSize,
audioUrl = audioUrl,
audioType = audioType,
audioSize = audioSize,
messageLink = messageLink,
attachments = attachments,
timestamp = timestamp,
authorIcon = authorIcon,
authorLink = authorLink,
imagePreview = imagePreview,
fields = fields,
fallback = fallback,
buttonAlignment = buttonAlignment,
actions = actions
)
}

private fun isAllNull(vararg params: Any?): Boolean {
return params.isEmpty()
}

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

override fun toJson(writer: JsonWriter, value: Attachment?) {
if (value == null) {
override fun toJson(writer: JsonWriter, attachment: Attachment?) {
if (attachment == null) {
writer.nullValue()
} else {
when (value) {
is ColorAttachment -> writeColorAttachment(writer, value)
is MessageAttachment -> writeMessageAttachment(writer, value)
is FileAttachment -> writeFileAttachment(writer, value)
is AuthorAttachment -> writeAuthorAttachment(writer, value)
is ActionsAttachment -> writeActionsAttachment(writer, value)
}
}
}

private fun writeColorAttachment(writer: JsonWriter, attachment: ColorAttachment) {
writer.beginObject()
with(writer) {
name("color").value(attachment.color.rawColor)
name("text").value(attachment.text)
name("fallback").value(attachment.fallback)
attachment.fields?.let { writeFields(writer, it) }
}
writer.endObject()
}
with(writer) {
beginObject()
name("title").value(attachment.title)
name("description").value(attachment.description)
name("text").value(attachment.text)
name("title_link").value(attachment.titleLink)
name("title_link_download").value(attachment.titleLinkDownload)
name("image_url").value(attachment.imageUrl)
name("image_size").value(attachment.imageSize)
name("image_type").value(attachment.imageType)
name("image_preview").value(attachment.imagePreview)
name("video_url").value(attachment.videoUrl)
name("video_size").value(attachment.videoType)
name("video_type").value(attachment.videoUrl)
name("audio_url").value(attachment.audioUrl)
name("audio_size").value(attachment.audioSize)
name("audio_type").value(attachment.audioType)
name("author_link").value(attachment.authorLink)
name("author_icon").value(attachment.authorIcon)
name("author_name").value(attachment.authorName)
name("button_alignment").value(attachment.buttonAlignment)
name("color").value(attachment.color?.rawColor)
name("fallback").value(attachment.fallback)
name("thumbUrl").value(attachment.thumbUrl)
name("message_link").value(attachment.messageLink)
name("ts").value(attachment.timestamp)

private fun writeMessageAttachment(writer: JsonWriter, attachment: MessageAttachment) {
writer.beginObject()
with(writer) {
name("author_name").value(attachment.author)
name("author_icon").value(attachment.icon)
name("text").value(attachment.text)
name("thumbUrl").value(attachment.thumbUrl)
name("color").value(attachment.color?.toString())
name("message_link").value(attachment.url)
name("ts").value(attachment.timestamp)
}
writer.endObject()
}

private fun writeFileAttachment(writer: JsonWriter, attachment: FileAttachment) {
writer.beginObject()
writer.name("title").value(attachment.title)
writer.name("description").value(attachment.description)
writer.name("text").value(attachment.text)
writer.name("title_link").value(attachment.titleLink)
writer.name("title_link_download").value(attachment.titleLinkDownload)
when (attachment) {
is AudioAttachment -> writeAudioAttachment(writer, attachment)
is VideoAttachment -> writeVideoAttachment(writer, attachment)
is ImageAttachment -> writeImageAttachment(writer, attachment)
is GenericFileAttachment -> writeGenericFileAttachment(writer, attachment)
}
writer.endObject()
}

private fun writeGenericFileAttachment(writer: JsonWriter, attachment: GenericFileAttachment) {
with(writer) {
name("title").value(attachment.title)
name("titleLink").value(attachment.url)
name("titleLinkDownload").value(attachment.titleLinkDownload)
}
}

private fun writeAudioAttachment(writer: JsonWriter, attachment: AudioAttachment) {
with(writer) {
name("audio_url").value(attachment.url)
name("audio_size").value(attachment.size)
name("audio_type").value(attachment.type)
}
}

private fun writeVideoAttachment(writer: JsonWriter, attachment: VideoAttachment) {
with(writer) {
name("video_url").value(attachment.url)
name("video_size").value(attachment.size)
name("video_type").value(attachment.type)
}
}

private fun writeImageAttachment(writer: JsonWriter, attachment: ImageAttachment) {
with(writer) {
name("image_url").value(attachment.url)
name("image_size").value(attachment.size)
name("image_type").value(attachment.type)
name("image_preview").value(attachment.imagePreview)
}
}

private fun writeAuthorAttachment(writer: JsonWriter, attachment: AuthorAttachment) {
writer.beginObject()
with(writer) {
name("author_link").value(attachment.url)
name("author_icon").value(attachment.authorIcon)
name("author_name").value(attachment.authorName)
attachment.fields?.let { writeFields(writer, it) }
attachment.actions?.let { writeActions(writer, it) }
attachment.fields?.let { writeFields(writer, it) }
}
}
writer.endObject()
}

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

private fun writeActionsAttachment(writer: JsonWriter, attachment: ActionsAttachment) {
writer.beginObject()
with(writer) {
name("title").value(attachment.title)
name("button_alignment").value(attachment.buttonAlignment)
attachment.actions?.let { writeActions(writer, it) }
}
writer.endObject()
}

private fun writeActions(writer: JsonWriter, actions: List<Action>) {
if (actions.isNotEmpty()) {
writer.name("actions")
Expand All @@ -402,10 +324,6 @@ class AttachmentAdapter(moshi: Moshi, private val logger: Logger) : JsonAdapter<
writer.endArray()
}
}

private fun checkNonNull(field: Any?, fieldName: String) {
if (field == null) throw JsonDataException("$fieldName is null")
}
}

class AttachmentAdapterFactory(private val logger: Logger) : JsonAdapter.Factory {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,74 @@
package chat.rocket.core.model.attachment

interface Attachment {
val url: String
import chat.rocket.common.internal.FallbackSealedClass
import chat.rocket.core.model.attachment.actions.Action
import com.squareup.moshi.Json

data class Attachment(
var title: String? = null,
var type: String? = null,
var description: String? = null,
var authorName: String? = null,
var text: String? = null,
var thumbUrl: String? = null,
var color: Color? = null,
var titleLink: String? = null,
var titleLinkDownload: Boolean = false,
var imageUrl: String? = null,
var imageType: String? = null,
var imageSize: Long? = null,
var videoUrl: String? = null,
var videoType: String? = null,
var videoSize: Long? = null,
var audioUrl: String? = null,
var audioType: String? = null,
var audioSize: Long? = null,
var messageLink: String? = null,
var attachments: List<Attachment>? = null,
var timestamp: Long? = null,
var authorIcon: String? = null,
var authorLink: String? = null,
var imagePreview: String? = null,
var fields: List<Field>? = null,
var fallback: String? = null,
var buttonAlignment: String? = null,
var actions: List<Action>? = null
)

@FallbackSealedClass(name = "Custom", fieldName = "colorValue")
sealed class Color(val color: Int, val rawColor: String) {
@Json(name = "good") class Good : Color(parseColor("#35AC19"), "#35AC19")
@Json(name = "warning") class Warning : Color(parseColor("#FCB316"), "#FCB316")
@Json(name = "danger") class Danger : Color(parseColor("#D30230"), "#D30230")
class Custom(private val colorValue: String) : Color(parseColor(colorValue), colorValue)

override fun toString(): String {
return color.toString(16)
}
}

private const val DEFAULT_COLOR_INT = 0xA0A0A0
const val DEFAULT_COLOR_STR = "#A0A0A0"
val DEFAULT_COLOR = Color.Custom(DEFAULT_COLOR_STR)

fun String?.asColorInt() = parseColor(this ?: DEFAULT_COLOR_STR)
fun String?.asColor() = Color.Custom(this ?: DEFAULT_COLOR_STR)

private fun parseColor(toParseColor: String): Int {
var rawColor = toParseColor.toUpperCase()
if (rawColor.startsWith("0X")) {
rawColor = "#${rawColor.drop(2)}"
}
return if (rawColor.startsWith('#')) {
var color = toParseColor.substring(1).toLong(16)
if (toParseColor.length == 7) {
// Set the alpha value
color = color or -0x1000000
} else if (toParseColor.length != 9) {
color = DEFAULT_COLOR_INT.toLong()
}
color.toInt()
} else {
DEFAULT_COLOR_INT
}
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit 647f7d5

Please sign in to comment.