mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-26 05:26:00 +00:00
feat: support message formatting
This commit is contained in:
parent
36ded19dff
commit
21af287654
35
src/app/chat/views/message_format.nim
Normal file
35
src/app/chat/views/message_format.nim
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
proc sectionIdentifier(message: Message): string =
|
||||||
|
result = message.fromAuthor
|
||||||
|
# Force section change, because group status messages are sent with the
|
||||||
|
# same fromAuthor, and ends up causing the header to not be shown
|
||||||
|
if message.contentType == ContentType.Group:
|
||||||
|
result = "GroupChatMessage"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# See render-inline in status-react/src/status_im/ui/screens/chat/message/message.cljs
|
||||||
|
proc renderInline(elem: TextItem): string =
|
||||||
|
case elem.textType:
|
||||||
|
of "": result = elem.literal
|
||||||
|
of "code": result = fmt("<span style=\"background-color: #1a356b; color: #FFFFFF\">{elem.literal}</span> ")
|
||||||
|
of "emph": result = fmt("<span style=\"font-style: italic;\">{elem.literal}</span> ")
|
||||||
|
of "strong": result = fmt("<span style=\"font-weight: bold;\">{elem.literal}</span> ")
|
||||||
|
of "link": result = "TODO: write safe link here: " & elem.destination
|
||||||
|
of "mention": result = elem.literal
|
||||||
|
|
||||||
|
# See render-block in status-react/src/status_im/ui/screens/chat/message/message.cljs
|
||||||
|
proc renderBlock(message: Message): string =
|
||||||
|
# TODO: find out how to extract the css styles
|
||||||
|
for pMsg in message.parsedText:
|
||||||
|
case pMsg.textType:
|
||||||
|
of "paragraph":
|
||||||
|
result = "<p>"
|
||||||
|
for children in pMsg.children:
|
||||||
|
result = result & renderInline(children)
|
||||||
|
result = result & "</p>"
|
||||||
|
of "blockquote":
|
||||||
|
# TODO: extract this from the theme somehow
|
||||||
|
var color = if message.isCurrentUser: "#FFFFFF" else: "#666666"
|
||||||
|
result = result & fmt("<span style=\"color: {color}\">▍ ") & pMsg.literal[1 .. ^1] & "</span>"
|
||||||
|
of "codeblock":
|
||||||
|
result = "<table style=\"background-color: #1a356b;\"><tr><td style=\"padding: 5px;\"><code style=\"color: #ffffff\">" & pMsg.literal & "</code></td></tr></table>"
|
@ -3,6 +3,8 @@ import ../../../status/chat
|
|||||||
import ../../../status/chat/[message,stickers]
|
import ../../../status/chat/[message,stickers]
|
||||||
import ../../../status/profile/profile
|
import ../../../status/profile/profile
|
||||||
import ../../../status/ens
|
import ../../../status/ens
|
||||||
|
import strformat
|
||||||
|
include message_format
|
||||||
|
|
||||||
type
|
type
|
||||||
ChatMessageRoles {.pure.} = enum
|
ChatMessageRoles {.pure.} = enum
|
||||||
@ -44,13 +46,6 @@ QtObject:
|
|||||||
method rowCount(self: ChatMessageList, index: QModelIndex = nil): int =
|
method rowCount(self: ChatMessageList, index: QModelIndex = nil): int =
|
||||||
return self.messages.len
|
return self.messages.len
|
||||||
|
|
||||||
proc sectionIdentifier(message: Message): string =
|
|
||||||
result = message.fromAuthor
|
|
||||||
# Force section change, because group status messages are sent with the
|
|
||||||
# same fromAuthor, and ends up causing the header to not be shown
|
|
||||||
if message.contentType == ContentType.Group:
|
|
||||||
result = "GroupChatMessage"
|
|
||||||
|
|
||||||
method data(self: ChatMessageList, index: QModelIndex, role: int): QVariant =
|
method data(self: ChatMessageList, index: QModelIndex, role: int): QVariant =
|
||||||
if not index.isValid:
|
if not index.isValid:
|
||||||
return
|
return
|
||||||
@ -60,7 +55,7 @@ QtObject:
|
|||||||
let chatMessageRole = role.ChatMessageRoles
|
let chatMessageRole = role.ChatMessageRoles
|
||||||
case chatMessageRole:
|
case chatMessageRole:
|
||||||
of ChatMessageRoles.UserName: result = newQVariant(message.alias)
|
of ChatMessageRoles.UserName: result = newQVariant(message.alias)
|
||||||
of ChatMessageRoles.Message: result = newQVariant(message.text)
|
of ChatMessageRoles.Message: result = newQVariant(renderBlock(message))
|
||||||
of ChatMessageRoles.Timestamp: result = newQVariant(message.timestamp)
|
of ChatMessageRoles.Timestamp: result = newQVariant(message.timestamp)
|
||||||
of ChatMessageRoles.Clock: result = newQVariant($message.clock)
|
of ChatMessageRoles.Clock: result = newQVariant($message.clock)
|
||||||
of ChatMessageRoles.Identicon: result = newQVariant(message.identicon)
|
of ChatMessageRoles.Identicon: result = newQVariant(message.identicon)
|
||||||
|
@ -107,6 +107,19 @@ proc toChat*(jsonChat: JsonNode): Chat =
|
|||||||
for jsonMember in jsonChat["membershipUpdateEvents"]:
|
for jsonMember in jsonChat["membershipUpdateEvents"]:
|
||||||
result.membershipUpdateEvents.add(jsonMember.toChatMembershipEvent)
|
result.membershipUpdateEvents.add(jsonMember.toChatMembershipEvent)
|
||||||
|
|
||||||
|
proc toTextItem*(jsonText: JsonNode): TextItem =
|
||||||
|
result = TextItem(
|
||||||
|
literal: jsonText{"literal"}.getStr,
|
||||||
|
textType: jsonText{"type"}.getStr,
|
||||||
|
destination: jsonText{"destination"}.getStr,
|
||||||
|
children: @[]
|
||||||
|
)
|
||||||
|
|
||||||
|
if jsonText.hasKey("children") and jsonText["children"].kind != JNull:
|
||||||
|
for child in jsonText["children"]:
|
||||||
|
result.children.add(child.toTextItem)
|
||||||
|
|
||||||
|
|
||||||
proc toMessage*(jsonMsg: JsonNode): Message =
|
proc toMessage*(jsonMsg: JsonNode): Message =
|
||||||
result = Message(
|
result = Message(
|
||||||
alias: jsonMsg{"alias"}.getStr,
|
alias: jsonMsg{"alias"}.getStr,
|
||||||
@ -128,9 +141,14 @@ proc toMessage*(jsonMsg: JsonNode): Message =
|
|||||||
timestamp: $jsonMsg{"timestamp"}.getInt,
|
timestamp: $jsonMsg{"timestamp"}.getInt,
|
||||||
whisperTimestamp: $jsonMsg{"whisperTimestamp"}.getInt,
|
whisperTimestamp: $jsonMsg{"whisperTimestamp"}.getInt,
|
||||||
isCurrentUser: $jsonMsg{"outgoingStatus"}.getStr == "sending",
|
isCurrentUser: $jsonMsg{"outgoingStatus"}.getStr == "sending",
|
||||||
stickerHash: ""
|
stickerHash: "",
|
||||||
|
parsedText: @[]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if jsonMsg["parsedText"].kind != JNull:
|
||||||
|
for text in jsonMsg["parsedText"]:
|
||||||
|
result.parsedText.add(text.toTextItem)
|
||||||
|
|
||||||
if result.contentType == ContentType.Sticker:
|
if result.contentType == ContentType.Sticker:
|
||||||
result.stickerHash = jsonMsg["sticker"]["hash"].getStr
|
result.stickerHash = jsonMsg["sticker"]["hash"].getStr
|
||||||
|
|
||||||
|
@ -10,25 +10,31 @@ type ContentType* {.pure.} = enum
|
|||||||
Transaction = 5,
|
Transaction = 5,
|
||||||
Group = 6
|
Group = 6
|
||||||
|
|
||||||
|
type TextItem* = object
|
||||||
|
textType*: string
|
||||||
|
children*: seq[TextItem]
|
||||||
|
literal*: string
|
||||||
|
destination*: string
|
||||||
|
|
||||||
type Message* = object
|
type Message* = object
|
||||||
alias*: string
|
alias*: string
|
||||||
chatId*: string
|
chatId*: string
|
||||||
clock*: int
|
clock*: int
|
||||||
# commandParameters*: # ???
|
# commandParameters*: # ???
|
||||||
contentType*: ContentType # ???
|
contentType*: ContentType
|
||||||
ensName*: string # ???
|
ensName*: string
|
||||||
fromAuthor*: string
|
fromAuthor*: string
|
||||||
id*: string
|
id*: string
|
||||||
identicon*: string
|
identicon*: string
|
||||||
lineCount*: int
|
lineCount*: int
|
||||||
localChatId*: string
|
localChatId*: string
|
||||||
messageType*: string # ???
|
messageType*: string # ???
|
||||||
# parsedText: # ???
|
parsedText*: seq[TextItem]
|
||||||
# quotedMessage: # ???
|
# quotedMessage: # ???
|
||||||
replace*: string # ???
|
replace*: string # ???
|
||||||
responseTo*: string # ???
|
responseTo*: string # ???
|
||||||
rtl*: bool # ???
|
rtl*: bool # ???
|
||||||
seen*: bool
|
seen*: bool # ???
|
||||||
sticker*: string
|
sticker*: string
|
||||||
text*: string
|
text*: string
|
||||||
timestamp*: string
|
timestamp*: string
|
||||||
|
@ -249,6 +249,7 @@ Item {
|
|||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
color: !isCurrentUser ? Theme.black : Theme.white
|
color: !isCurrentUser ? Theme.black : Theme.white
|
||||||
visible: contentType == Constants.messageType
|
visible: contentType == Constants.messageType
|
||||||
|
textFormat: TextEdit.RichText
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user