Event Handler

Similar to text handler, pull out the disparate array of functions which format information from an event ready for display in the UI and put in a handler class with a test suite.

requires https://github.com/quotient-im/libQuotient/pull/686
This commit is contained in:
James Graham
2023-09-07 19:02:50 +00:00
parent 597633f824
commit 2c6ab498ac
26 changed files with 2397 additions and 997 deletions

View File

@@ -87,7 +87,6 @@ Components.AlbumMaximizeComponent {
eventId: root.currentEventId,
source: root.currentJsonSource,
file: parent,
mimeType: root.currentMimeType,
progressInfo: root.currentProgressInfo,
plainText: root.currentPlainText
});

View File

@@ -14,78 +14,78 @@ DelegateChooser {
property var room
DelegateChoice {
roleValue: MessageEventModel.State
roleValue: DelegateType.State
delegate: StateDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Emote
roleValue: DelegateType.Emote
delegate: MessageDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Message
roleValue: DelegateType.Message
delegate: MessageDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Notice
roleValue: DelegateType.Notice
delegate: MessageDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Image
roleValue: DelegateType.Image
delegate: ImageDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Sticker
roleValue: DelegateType.Sticker
delegate: ImageDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Audio
roleValue: DelegateType.Audio
delegate: AudioDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Video
roleValue: DelegateType.Video
delegate: VideoDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.File
roleValue: DelegateType.File
delegate: FileDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Encrypted
roleValue: DelegateType.Encrypted
delegate: EncryptedDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.ReadMarker
roleValue: DelegateType.ReadMarker
delegate: ReadMarkerDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Poll
roleValue: DelegateType.Poll
delegate: PollDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.Location
roleValue: DelegateType.Location
delegate: LocationDelegate {}
}
DelegateChoice {
roleValue: MessageEventModel.LiveLocation
roleValue: DelegateType.LiveLocation
delegate: LiveLocationDelegate {
room: root.room
}
}
DelegateChoice {
roleValue: MessageEventModel.Other
roleValue: DelegateType.Other
delegate: Item {}
}
}

View File

@@ -117,22 +117,22 @@ Item {
id: loader
Layout.fillWidth: true
Layout.maximumHeight: loader.item && (root.type == MessageEventModel.Image || root.type == MessageEventModel.Sticker) ? loader.item.height : -1
Layout.maximumHeight: loader.item && (root.type == DelegateType.Image || root.type == DelegateType.Sticker) ? loader.item.height : -1
Layout.columnSpan: 2
sourceComponent: {
switch (root.type) {
case MessageEventModel.Image:
case MessageEventModel.Sticker:
case DelegateType.Image:
case DelegateType.Sticker:
return imageComponent;
case MessageEventModel.Message:
case MessageEventModel.Notice:
case DelegateType.Message:
case DelegateType.Notice:
return textComponent;
case MessageEventModel.File:
case MessageEventModel.Video:
case MessageEventModel.Audio:
case DelegateType.File:
case DelegateType.Video:
case DelegateType.Audio:
return mimeComponent;
case MessageEventModel.Encrypted:
case DelegateType.Encrypted:
return encryptedComponent;
default:
return textComponent;
@@ -187,7 +187,7 @@ Item {
MimeComponent {
mimeIconSource: root.mediaInfo.mimeIcon
label: root.display
subLabel: root.type === MessageEventModel.File ? Controller.formatByteSize(root.mediaInfo.size) : Controller.formatDuration(root.mediaInfo.duration)
subLabel: root.type === DelegateType.File ? Controller.formatByteSize(root.mediaInfo.size) : Controller.formatDuration(root.mediaInfo.duration)
}
}
Component {

View File

@@ -42,6 +42,11 @@ ColumnLayout {
*/
required property var time
/**
* @brief The timestamp of the message as a string.
*/
required property string timeString
/**
* @brief The message author.
*
@@ -154,13 +159,14 @@ ColumnLayout {
required property var replyAuthor
/**
* @brief The reply content.
*
* This should consist of the following:
* - display - The display text of the reply.
* - type - The delegate type of the reply.
* @brief The delegate type of the message replied to.
*/
required property var reply
required property int replyDelegateType
/**
* @brief The display text of the message replied to.
*/
required property string replyDisplay
/**
* @brief The media info for the reply event.
@@ -206,11 +212,6 @@ ColumnLayout {
*/
required property bool verified
/**
* @brief The mime type of the message's file or media.
*/
required property var mimeType
/**
* @brief The full message source JSON.
*/
@@ -357,7 +358,7 @@ ColumnLayout {
implicitHeight: Math.max(root.showAuthor || root.alwaysShowAuthor ? avatar.implicitHeight : 0, bubble.height)
Component.onCompleted: {
if (root.isReply && root.reply === undefined) {
if (root.isReply && root.replyDelegateType === DelegateType.Other) {
currentRoom.loadReply(root.eventId, root.replyId)
}
}
@@ -478,7 +479,7 @@ ColumnLayout {
QQC2.Label {
id: timeLabel
text: visible ? root.time.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) : ""
text: root.timeString
color: Kirigami.Theme.disabledTextColor
QQC2.ToolTip.visible: hoverHandler.hovered
QQC2.ToolTip.text: root.time.toLocaleString(Qt.locale(), Locale.LongFormat)
@@ -494,13 +495,13 @@ ColumnLayout {
Layout.maximumWidth: contentMaxWidth
active: root.isReply && root.reply
active: root.isReply && root.replyDelegateType !== DelegateType.Other
visible: active
sourceComponent: ReplyComponent {
author: root.replyAuthor
type: root.reply.type
display: root.reply.display
type: root.replyDelegateType
display: root.replyDisplay
mediaInfo: root.replyMediaInfo
contentMaxWidth: bubbleSizeHelper.currentWidth
}
@@ -609,7 +610,6 @@ ColumnLayout {
eventId: root.eventId,
source: root.jsonSource,
file: file,
mimeType: root.mimeType,
progressInfo: root.progressInfo,
plainText: root.plainText,
});

View File

@@ -240,7 +240,7 @@ QQC2.ScrollView {
currentRoom: root.currentRoom
showActions: delegate && delegate.hovered
verified: delegate && delegate.verified
editable: delegate && delegate.author.isLocalUser && (delegate.delegateType === MessageEventModel.Emote || delegate.delegateType === MessageEventModel.Message)
editable: delegate && delegate.author.isLocalUser && (delegate.delegateType === DelegateType.Emote || delegate.delegateType === DelegateType.Message)
onReactClicked: (emoji) => {
root.currentRoom.toggleReaction(delegate.eventId, emoji);

View File

@@ -16,7 +16,6 @@ MessageDelegateContextMenu {
required property var file
required property var progressInfo
required property string mimeType
property list<Kirigami.Action> actions: [
Kirigami.Action {
@@ -108,7 +107,7 @@ MessageDelegateContextMenu {
id: shareAction
inputData: {
'urls': [],
'mimeType': [mimeType]
'mimeType': [root.file.mediaInfo.mimeType]
}
property string filename: StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/" + eventId.replace(":", "_").replace("/", "_").replace("+", "_") + currentRoom.fileNameToDownload(eventId);
@@ -118,7 +117,7 @@ MessageDelegateContextMenu {
Component.onCompleted: {
shareAction.inputData = {
urls: [filename],
mimeType: [mimeType]
mimeType: [root.file.mediaInfo.mimeType]
};
}
}

View File

@@ -31,7 +31,7 @@ Loader {
currentRoom.chatBoxEditId = eventId;
currentRoom.chatBoxReplyId = "";
}
visible: author.id === Controller.activeConnection.localUserId && (loadRoot.eventType === MessageEventModel.Emote || loadRoot.eventType === MessageEventModel.Message)
visible: author.id === Controller.activeConnection.localUserId && (loadRoot.eventType === DelegateType.Emote || loadRoot.eventType === DelegateType.Message)
},
Kirigami.Action {
text: i18n("Reply")