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:
parent
b3e3fd7bc6
commit
026c049d62
5
TODO.md
5
TODO.md
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 : ""
|
||||||
|
|
|
@ -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 {} }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user