Improve message delegate code, fix multiple issues

- Fix the ListView not auto-scrolling like it should when message
  delegates changed height, such as when images were loaded

- Fix messed up delegate positions overlapping each others when
  movements happen

- Fix previous/nextItem binding broken due to imperative modification

- Fix "messageBodyWidth" binding loop
This commit is contained in:
miruka 2019-12-17 03:45:00 -04:00
parent b3e3fd7bc6
commit 026c049d62
6 changed files with 47 additions and 49 deletions

View File

@ -49,18 +49,15 @@
## Issues ## Issues
- Room pane slightly overlaps chat at small width
- invisible uploaded mxc images? - invisible uploaded mxc images?
- first undecryptable message - first undecryptable message
- Join button 502 - Join button 502
- Leave box button focus - Leave box button focus
- two upload delegates height bug
- Pausing uploads doesn't work well, servers end up dropping the connection - Pausing uploads doesn't work well, servers end up dropping the connection
- Pause upload, switch to other room, then come back, wrong state displayed - Pause upload, switch to other room, then come back, wrong state displayed
- Messed up message delegates position
- Event delegates changing height don't scroll the list
- In the "Leave me" room, "join > Hi > left" aren't combined - In the "Leave me" room, "join > Hi > left" aren't combined
- When selecting text and scrolling up, selection stops working after a while - When selecting text and scrolling up, selection stops working after a while
- Ensure all the text that should be copied is copied - Ensure all the text that should be copied is copied

View File

@ -18,17 +18,16 @@ HRowLayout {
leftPadding: theme.spacing leftPadding: theme.spacing
rightPadding: leftPadding rightPadding: leftPadding
Layout.margins: theme.spacing opacity: width > 16 * theme.uiScale ? 1 : 0
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth:
parent.width - Layout.leftMargin - Layout.rightMargin
opacity: width > Layout.leftMargin + Layout.rightMargin ? 1 : 0
background: Rectangle { background: Rectangle {
id: noticeLabelBackground id: noticeLabelBackground
color: theme.controls.box.background color: theme.controls.box.background
radius: theme.controls.box.radius radius: theme.controls.box.radius
} }
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: implicitWidth
Layout.maximumWidth: parent.width
} }
} }

View File

@ -27,16 +27,15 @@ HRowLayout {
readonly property string hoveredLink: contentLabel.hoveredLink readonly property string hoveredLink: contentLabel.hoveredLink
readonly property bool hoveredSelectable: contentHover.hovered readonly property bool hoveredSelectable: contentHover.hovered
readonly property int messageBodyWidth:
width - (avatarWrapper.visible ? avatarWrapper.width : 0) -
spacing * Math.max(0, (visibleChildren.length - 1))
readonly property int xOffset: readonly property int xOffset:
onRight ? onRight ?
contentLabel.width - contentLabel.paintedWidth - contentLabel.width - contentLabel.paintedWidth -
contentLabel.leftPadding - contentLabel.rightPadding : contentLabel.leftPadding - contentLabel.rightPadding :
0 0
// 600px max with a 16px font
readonly property int maxMessageWidth: theme.fontSize.normal * 0.5 * 75
TapHandler { TapHandler {
enabled: debugMode enabled: debugMode
@ -116,11 +115,8 @@ HRowLayout {
transform: Translate { x: xOffset } transform: Translate { x: xOffset }
Layout.maximumWidth: Math.min( Layout.maximumWidth: eventContent.maxMessageWidth
// 600px with 16px font Layout.fillWidth: true
theme.fontSize.normal * 0.5 * 75,
messageBodyWidth - leftPadding - rightPadding,
)
function selectAllText() { function selectAllText() {
// Select the message body without the date or name // Select the message body without the date or name
@ -162,10 +158,10 @@ HRowLayout {
HRepeater { HRepeater {
id: linksRepeater id: linksRepeater
model: eventDelegate.currentItem.links model: eventDelegate.currentModel.links
EventMediaLoader { EventMediaLoader {
singleMediaInfo: eventDelegate.currentItem singleMediaInfo: eventDelegate.currentModel
mediaUrl: modelData mediaUrl: modelData
showSender: pureMedia ? senderText : "" showSender: pureMedia ? senderText : ""
showDate: pureMedia ? timeText : "" showDate: pureMedia ? timeText : ""

View File

@ -3,15 +3,9 @@ import QtQuick.Layouts 1.12
import "../../Base" import "../../Base"
import "../../utils.js" as Utils import "../../utils.js" as Utils
Column { HColumnLayout {
id: eventDelegate id: eventDelegate
width: eventList.width width: eventList.width
topPadding:
model.event_type === "RoomCreateEvent" ? 0 :
dayBreak ? theme.spacing * 4 :
talkBreak ? theme.spacing * 6 :
combine ? theme.spacing / 2 :
theme.spacing * 2
enum Media { Page, File, Image, Video, Audio } enum Media { Page, File, Image, Video, Audio }
@ -19,23 +13,18 @@ Column {
property var hoveredMediaTypeUrl: [] property var hoveredMediaTypeUrl: []
// Remember timeline goes from newest message at index 0 to oldest // Remember timeline goes from newest message at index 0 to oldest
property var previousItem: eventList.model.get(model.index + 1) readonly property var previousModel: eventList.model.get(model.index + 1)
property var nextItem: eventList.model.get(model.index - 1) readonly property var nextModel: eventList.model.get(model.index - 1)
readonly property QtObject currentItem: model readonly property QtObject currentModel: model
property int modelIndex: model.index
onModelIndexChanged: {
previousItem = eventList.model.get(model.index + 1)
nextItem = eventList.model.get(model.index - 1)
}
property bool isOwn: chat.userId === model.sender_id property bool isOwn: chat.userId === model.sender_id
property bool onRight: eventList.ownEventsOnRight && isOwn property bool onRight: eventList.ownEventsOnRight && isOwn
property bool combine: eventList.canCombine(previousItem, model) property bool combine: eventList.canCombine(previousModel, model)
property bool talkBreak: eventList.canTalkBreak(previousItem, model) property bool talkBreak: eventList.canTalkBreak(previousModel, model)
property bool dayBreak: eventList.canDayBreak(previousItem, model) property bool dayBreak: eventList.canDayBreak(previousModel, model)
readonly property bool smallAvatar: readonly property bool smallAvatar:
eventList.canCombine(model, nextItem) && eventList.canCombine(model, nextModel) &&
(model.event_type === "RoomMessageEmote" || (model.event_type === "RoomMessageEmote" ||
! (model.event_type.startsWith("RoomMessage") || ! (model.event_type.startsWith("RoomMessage") ||
model.event_type.startsWith("RoomEncrypted"))) model.event_type.startsWith("RoomEncrypted")))
@ -60,6 +49,12 @@ Column {
Qt.ArrowCursor Qt.ArrowCursor
readonly property int separationSpacing:
dayBreak ? theme.spacing * 4 :
talkBreak ? theme.spacing * 6 :
combine ? theme.spacing / 2 :
theme.spacing * 2
// Needed because of eventList's MouseArea which steals the // Needed because of eventList's MouseArea which steals the
// HSelectableLabel's MouseArea hover events // HSelectableLabel's MouseArea hover events
onCursorShapeChanged: eventList.cursorShape = cursorShape onCursorShapeChanged: eventList.cursorShape = cursorShape
@ -87,20 +82,31 @@ Column {
} }
Item {
Layout.fillWidth: true
Layout.preferredHeight:
model.event_type === "RoomCreateEvent" ? 0 : separationSpacing
}
Daybreak { Daybreak {
visible: dayBreak visible: dayBreak
width: eventDelegate.width
Layout.fillWidth: true
Layout.minimumWidth: parent.width
} }
Item { Item {
visible: dayBreak visible: dayBreak
width: parent.width
height: topPadding Layout.fillWidth: true
Layout.preferredHeight: separationSpacing
} }
EventContent { EventContent {
id: eventContent id: eventContent
width: parent.width
Layout.fillWidth: true
Behavior on x { HNumberAnimation {} } Behavior on x { HNumberAnimation {} }
} }

View File

@ -5,10 +5,10 @@ import "../../utils.js" as Utils
HTile { HTile {
id: file id: file
width: Math.max( width: Math.min(
Math.min(eventContent.messageBodyWidth, eventDelegate.width,
theme.chat.message.fileMinWidth), eventContent.maxMessageWidth,
Math.min(eventContent.messageBodyWidth, implicitWidth), Math.max(theme.chat.message.fileMinWidth, implicitWidth),
) )
height: Math.max(theme.chat.message.avatarSize, implicitHeight) height: Math.max(theme.chat.message.avatarSize, implicitHeight)

View File

@ -49,7 +49,7 @@ HMxcImage {
// Maximum display size // Maximum display size
Math.min( Math.min(
eventList.height * maxHeight, eventList.height * maxHeight,
eventContent.messageBodyWidth * Math.min(1, theme.uiScale), eventContent.maxMessageWidth * Math.min(1, theme.uiScale), // XXX
), ),
eventList.height * maxHeight, eventList.height * maxHeight,
) )