Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
nheko
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Nheko Reborn
nheko
Commits
b3da8738
Unverified
Commit
b3da8738
authored
3 years ago
by
Nicolas Werner
Committed by
GitHub
3 years ago
Browse files
Options
Downloads
Plain Diff
Merge pull request #951 from maltee1/fix_timeline_scrollbar
Fix timeline scrollbar
parents
fd25f6ee
8b6d4a57
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Pipeline
#2685
passed
3 years ago
Stage: build
Stage: deploy
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
resources/qml/MessageView.qml
+426
-434
426 additions, 434 deletions
resources/qml/MessageView.qml
with
426 additions
and
434 deletions
resources/qml/MessageView.qml
+
426
−
434
View file @
b3da8738
...
@@ -23,552 +23,544 @@ Item {
...
@@ -23,552 +23,544 @@ Item {
ScrollBar
{
ScrollBar
{
id
:
scrollbar
id
:
scrollbar
interactive
:
!
touchObserver
.
wasTouched
parent
:
chat
.
parent
parent
:
chat
.
parent
anchors.top
:
parent
.
top
anchors.top
:
parent
.
top
anchors.right
:
parent
.
right
anchors.right
:
parent
.
right
anchors.bottom
:
parent
.
bottom
anchors.bottom
:
parent
.
bottom
}
}
ListView
{
id
:
chat
EventObserver
{
id
:
touchObserver
anchors.fill
:
parent
anchors.fill
:
parent
ListView
{
property
int
delegateMaxWidth
:
((
Settings
.
timelineMaxWidth
>
100
&&
Settings
.
timelineMaxWidth
<
chatRoot
.
availableWidth
)
?
Settings
.
timelineMaxWidth
:
chatRoot
.
availableWidth
)
-
chatRoot
.
padding
*
2
-
(
scrollbar
.
interactive
?
scrollbar
.
width
:
0
)
id
:
chat
displayMarginBeginning
:
height
/
2
displayMarginEnd
:
height
/
2
model
:
room
// reuseItems still has a few bugs, see https://bugreports.qt.io/browse/QTBUG-95105 https://bugreports.qt.io/browse/QTBUG-95107
//onModelChanged: if (room) room.sendReset()
//reuseItems: true
boundsBehavior
:
Flickable
.
StopAtBounds
//pixelAligned: true
spacing
:
2
verticalLayoutDirection
:
ListView
.
BottomToTop
onCountChanged
:
{
// Mark timeline as read
if
(
atYEnd
&&
room
)
model
.
currentIndex
=
0
;
anchors.fill
:
parent
}
property
int
delegateMaxWidth
:
((
Settings
.
timelineMaxWidth
>
100
&&
Settings
.
timelineMaxWidth
<
chatRoot
.
availableWidth
)
?
Settings
.
timelineMaxWidth
:
chatRoot
.
availableWidth
)
-
chatRoot
.
padding
*
2
-
scrollbar
.
width
displayMarginBeginning
:
height
/
2
displayMarginEnd
:
height
/
2
model
:
room
// reuseItems still has a few bugs, see https://bugreports.qt.io/browse/QTBUG-95105 https://bugreports.qt.io/browse/QTBUG-95107
//onModelChanged: if (room) room.sendReset()
//reuseItems: true
boundsBehavior
:
Flickable
.
StopAtBounds
//pixelAligned: true
spacing
:
2
verticalLayoutDirection
:
ListView
.
BottomToTop
onCountChanged
:
{
// Mark timeline as read
if
(
atYEnd
&&
room
)
model
.
currentIndex
=
0
;
}
ScrollBar.vertical
:
scrollbar
anchors.rightMargin
:
scrollbar
.
interactive
?
scrollbar
.
width
:
0
Rectangle
{
ScrollBar.vertical
:
scrollbar
//closePolicy: Popup.NoAutoClose
id
:
messageActions
anchors.rightMargin
:
scrollbar
.
interactive
?
scrollbar
.
width
:
0
property
Item
attached
:
null
Rectangle
{
property
alias
model
:
row
.
model
//closePolicy: Popup.NoAutoClose
// use comma to update on scroll
property
var
attachedPos
:
chat
.
contentY
,
attached
?
chat
.
mapFromItem
(
attached
,
attached
?
attached
.
width
-
width
:
0
,
-
height
)
:
null
readonly
property
int
padding
:
Nheko
.
paddingSmall
visible
:
Settings
.
buttonsInTimeline
&&
!!
attached
&&
(
attached
.
hovered
||
messageActionHover
.
hovered
)
id
:
messageActions
x
:
attached
?
attachedPos
.
x
:
0
y
:
attached
?
attachedPos
.
y
:
0
z
:
10
height
:
row
.
implicitHeight
+
padding
*
2
width
:
row
.
implicitWidth
+
padding
*
2
color
:
Nheko
.
colors
.
window
border.color
:
Nheko
.
colors
.
buttonText
border.width
:
1
radius
:
padding
HoverHandler
{
property
Item
attached
:
null
id
:
messageActionHover
property
alias
model
:
row
.
model
// use comma to update on scroll
property
var
attachedPos
:
chat
.
contentY
,
attached
?
chat
.
mapFromItem
(
attached
,
attached
?
attached
.
width
-
width
:
0
,
-
height
)
:
null
readonly
property
int
padding
:
Nheko
.
paddingSmall
grabPermissions
:
PointerHandler
.
CanTakeOverFromAnything
visible
:
Settings
.
buttonsInTimeline
&&
!!
attached
&&
(
attached
.
hovered
||
messageActionHover
.
hovered
)
}
x
:
attached
?
attachedPos
.
x
:
0
y
:
attached
?
attachedPos
.
y
:
0
z
:
10
height
:
row
.
implicitHeight
+
padding
*
2
width
:
row
.
implicitWidth
+
padding
*
2
color
:
Nheko
.
colors
.
window
border.color
:
Nheko
.
colors
.
buttonText
border.width
:
1
radius
:
padding
Row
{
HoverHandler
{
id
:
row
id
:
messageActionHover
property
var
model
grabPermissions
:
PointerHandler
.
CanTakeOverFromAnything
}
anchors.centerIn
:
parent
Row
{
spacing
:
messageActions
.
padding
id
:
row
Repeater
{
property
var
model
model
:
Settings
.
recentReactions
delegate
:
TextButton
{
anchors.centerIn
:
parent
required
property
str
ing
m
odelData
spac
ing
:
m
essageActions
.
padding
visible
:
chat
.
model
?
chat
.
model
.
permissions
.
canSend
(
MtxEvent
.
Reaction
)
:
false
Repeater
{
model
:
Settings
.
recentReactions
height
:
fontMetrics
.
height
delegate
:
TextButton
{
font.family
:
Settings
.
emojiFont
required
property
string
modelData
text
:
modelData
visible
:
chat
.
model
?
chat
.
model
.
permissions
.
canSend
(
MtxEvent
.
Reaction
)
:
false
onClicked
:
{
room
.
input
.
reaction
(
row
.
model
.
eventId
,
modelData
);
TimelineManager
.
focusMessageInput
();
}
}
}
ImageButton
{
height
:
fontMetrics
.
height
id
:
editButt
on
font.family
:
Settings
.
emojiF
on
t
visible
:
!!
row
.
model
&&
row
.
model
.
isEditable
text
:
modelData
buttonTextColor
:
Nheko
.
colors
.
buttonText
width
:
16
hoverEnabled
:
true
image
:
"
:/icons/icons/ui/edit.svg
"
ToolTip.visible
:
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
qsTr
(
"
Edit
"
)
onClicked
:
{
onClicked
:
{
if
(
row
.
model
.
isEditable
)
room
.
input
.
reaction
(
row
.
model
.
eventId
,
modelData
);
chat
.
model
.
editAction
(
row
.
model
.
eventId
);
TimelineManager
.
focusMessageInput
();
}
}
}
}
}
ImageButton
{
ImageButton
{
id
:
reactButton
id
:
editButton
visible
:
!!
row
.
model
&&
row
.
model
.
isEditable
buttonTextColor
:
Nheko
.
colors
.
buttonText
width
:
16
hoverEnabled
:
true
image
:
"
:/icons/icons/ui/edit.svg
"
ToolTip.visible
:
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
qsTr
(
"
Edit
"
)
onClicked
:
{
if
(
row
.
model
.
isEditable
)
chat
.
model
.
editAction
(
row
.
model
.
eventId
);
visible
:
chat
.
model
?
chat
.
model
.
permissions
.
canSend
(
MtxEvent
.
Reaction
)
:
false
width
:
16
hoverEnabled
:
true
image
:
"
:/icons/icons/ui/smile.svg
"
ToolTip.visible
:
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
qsTr
(
"
React
"
)
onClicked
:
emojiPopup
.
visible
?
emojiPopup
.
close
()
:
emojiPopup
.
show
(
reactButton
,
function
(
emoji
)
{
var
event_id
=
row
.
model
?
row
.
model
.
eventId
:
""
;
room
.
input
.
reaction
(
event_id
,
emoji
);
TimelineManager
.
focusMessageInput
();
})
}
}
}
ImageButton
{
ImageButton
{
id
:
replyButton
id
:
reactButton
visible
:
chat
.
model
?
chat
.
model
.
permissions
.
canSend
(
MtxEvent
.
TextMessage
)
:
false
visible
:
chat
.
model
?
chat
.
model
.
permissions
.
canSend
(
MtxEvent
.
Reaction
)
:
false
width
:
16
width
:
16
hoverEnabled
:
true
hoverEnabled
:
true
image
:
"
:/icons/icons/ui/reply.svg
"
image
:
"
:/icons/icons/ui/smile.svg
"
ToolTip.visible
:
hovered
ToolTip.visible
:
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
qsTr
(
"
Reply
"
)
ToolTip.text
:
qsTr
(
"
React
"
)
onClicked
:
chat
.
model
.
replyAction
(
row
.
model
.
eventId
)
onClicked
:
emojiPopup
.
visible
?
emojiPopup
.
close
()
:
emojiPopup
.
show
(
reactButton
,
function
(
emoji
)
{
}
var
event_id
=
row
.
model
?
row
.
model
.
eventId
:
""
;
room
.
input
.
reaction
(
event_id
,
emoji
);
TimelineManager
.
focusMessageInput
();
})
}
ImageButton
{
ImageButton
{
id
:
optionsButton
id
:
replyButton
visible
:
chat
.
model
?
chat
.
model
.
permissions
.
canSend
(
MtxEvent
.
TextMessage
)
:
false
width
:
16
hoverEnabled
:
true
image
:
"
:/icons/icons/ui/reply.svg
"
ToolTip.visible
:
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
qsTr
(
"
Reply
"
)
onClicked
:
chat
.
model
.
replyAction
(
row
.
model
.
eventId
)
}
width
:
16
ImageButton
{
hoverEnabled
:
true
id
:
optionsButton
image
:
"
:/icons/icons/ui/options.svg
"
ToolTip.visible
:
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
qsTr
(
"
Options
"
)
onClicked
:
messageContextMenu
.
show
(
row
.
model
.
eventId
,
row
.
model
.
type
,
row
.
model
.
isSender
,
row
.
model
.
isEncrypted
,
row
.
model
.
isEditable
,
""
,
row
.
model
.
body
,
optionsButton
)
}
width
:
16
hoverEnabled
:
true
image
:
"
:/icons/icons/ui/options.svg
"
ToolTip.visible
:
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
qsTr
(
"
Options
"
)
onClicked
:
messageContextMenu
.
show
(
row
.
model
.
eventId
,
row
.
model
.
type
,
row
.
model
.
isSender
,
row
.
model
.
isEncrypted
,
row
.
model
.
isEditable
,
""
,
row
.
model
.
body
,
optionsButton
)
}
}
}
}
ScrollHelper
{
}
flickable
:
parent
anchors.fill
:
parent
}
Shortcut
{
ScrollHelper
{
sequence
:
StandardKey
.
MoveToPreviousPage
flickable
:
parent
onActivated
:
{
anchors.fill
:
parent
chat
.
contentY
=
chat
.
contentY
-
chat
.
height
/
2
;
}
chat
.
returnToBounds
();
}
Shortcut
{
sequence
:
StandardKey
.
MoveToPreviousPage
onActivated
:
{
chat
.
contentY
=
chat
.
contentY
-
chat
.
height
/
2
;
chat
.
returnToBounds
();
}
}
}
Shortcut
{
Shortcut
{
sequence
:
StandardKey
.
MoveToNextPage
sequence
:
StandardKey
.
MoveToNextPage
onActivated
:
{
onActivated
:
{
chat
.
contentY
=
chat
.
contentY
+
chat
.
height
/
2
;
chat
.
contentY
=
chat
.
contentY
+
chat
.
height
/
2
;
chat
.
returnToBounds
();
chat
.
returnToBounds
();
}
}
}
}
Shortcut
{
Shortcut
{
sequence
:
StandardKey
.
Cancel
sequence
:
StandardKey
.
Cancel
onActivated
:
{
onActivated
:
{
if
(
chat
.
model
.
reply
)
if
(
chat
.
model
.
reply
)
chat
.
model
.
reply
=
undefined
;
chat
.
model
.
reply
=
undefined
;
else
else
chat
.
model
.
edit
=
undefined
;
chat
.
model
.
edit
=
undefined
;
}
}
}
}
Shortcut
{
Shortcut
{
sequence
:
"
Alt+Up
"
sequence
:
"
Alt+Up
"
onActivated
:
chat
.
model
.
reply
=
chat
.
model
.
indexToId
(
chat
.
model
.
reply
?
chat
.
model
.
idToIndex
(
chat
.
model
.
reply
)
+
1
:
0
)
onActivated
:
chat
.
model
.
reply
=
chat
.
model
.
indexToId
(
chat
.
model
.
reply
?
chat
.
model
.
idToIndex
(
chat
.
model
.
reply
)
+
1
:
0
)
}
}
Shortcut
{
Shortcut
{
sequence
:
"
Alt+Down
"
sequence
:
"
Alt+Down
"
onActivated
:
{
onActivated
:
{
var
idx
=
chat
.
model
.
reply
?
chat
.
model
.
idToIndex
(
chat
.
model
.
reply
)
-
1
:
-
1
;
var
idx
=
chat
.
model
.
reply
?
chat
.
model
.
idToIndex
(
chat
.
model
.
reply
)
-
1
:
-
1
;
chat
.
model
.
reply
=
idx
>=
0
?
chat
.
model
.
indexToId
(
idx
)
:
null
;
chat
.
model
.
reply
=
idx
>=
0
?
chat
.
model
.
indexToId
(
idx
)
:
null
;
}
}
}
}
Shortcut
{
Shortcut
{
sequence
:
"
Alt+F
"
sequence
:
"
Alt+F
"
onActivated
:
{
onActivated
:
{
if
(
chat
.
model
.
reply
)
{
if
(
chat
.
model
.
reply
)
{
var
forwardMess
=
forwardCompleterComponent
.
createObject
(
timelineRoot
);
var
forwardMess
=
forwardCompleterComponent
.
createObject
(
timelineRoot
);
forwardMess
.
setMessageEventId
(
chat
.
model
.
reply
);
forwardMess
.
setMessageEventId
(
chat
.
model
.
reply
);
forwardMess
.
open
();
forwardMess
.
open
();
chat
.
model
.
reply
=
null
;
chat
.
model
.
reply
=
null
;
}
}
}
}
}
}
Shortcut
{
Shortcut
{
sequence
:
"
Ctrl+E
"
sequence
:
"
Ctrl+E
"
onActivated
:
{
onActivated
:
{
chat
.
model
.
edit
=
chat
.
model
.
reply
;
chat
.
model
.
edit
=
chat
.
model
.
reply
;
}
}
}
}
Connections
{
Connections
{
function
onFocusChanged
()
{
function
onFocusChanged
()
{
readTimer
.
running
=
TimelineManager
.
isWindowFocused
;
readTimer
.
running
=
TimelineManager
.
isWindowFocused
;
}
target
:
TimelineManager
}
}
Timer
{
target
:
TimelineManager
id
:
readTimer
}
Timer
{
id
:
readTimer
// force current read index to update
// force current read index to update
onTriggered
:
{
onTriggered
:
{
if
(
chat
.
model
)
if
(
chat
.
model
)
chat
.
model
.
setCurrentIndex
(
chat
.
model
.
currentIndex
);
chat
.
model
.
setCurrentIndex
(
chat
.
model
.
currentIndex
);
}
interval
:
1000
}
}
interval
:
1000
}
Component
{
Component
{
id
:
sectionHeader
id
:
sectionHeader
Column
{
topPadding
:
userName_
.
visible
?
4
:
0
bottomPadding
:
Settings
.
bubbles
?
(
isSender
?
0
:
2
)
:
3
spacing
:
8
visible
:
(
previousMessageUserId
!==
userId
||
previousMessageDay
!==
day
||
isStateEvent
!==
previousMessageIsStateEvent
)
width
:
parentWidth
height
:
((
previousMessageDay
!==
day
)
?
dateBubble
.
height
:
0
)
+
(
isStateEvent
?
0
:
userName
.
height
+
8
)
Label
{
id
:
dateBubble
anchors.horizontalCenter
:
parent
?
parent
.
horizontalCenter
:
undefined
visible
:
room
&&
previousMessageDay
!==
day
text
:
room
?
room
.
formatDateSeparator
(
timestamp
)
:
""
color
:
Nheko
.
colors
.
text
height
:
Math
.
round
(
fontMetrics
.
height
*
1.4
)
width
:
contentWidth
*
1.2
horizontalAlignment
:
Text
.
AlignHCenter
verticalAlignment
:
Text
.
AlignVCenter
background
:
Rectangle
{
radius
:
parent
.
height
/
2
color
:
Nheko
.
colors
.
window
}
Column
{
}
topPadding
:
userName_
.
visible
?
4
:
0
bottomPadding
:
Settings
.
bubbles
?
(
isSender
?
0
:
2
)
:
3
Row
{
height
:
userName_
.
height
spacing
:
8
spacing
:
8
visible
:
(
previousMessageUserId
!==
userId
||
previousMessageDay
!==
day
||
isStateEvent
!==
previousMessageIsStateEvent
)
visible
:
!
isStateEvent
&&
(
!
isSender
||
!
Settings
.
bubbles
)
width
:
parentWidth
height
:
((
previousMessageDay
!==
day
)
?
dateBubble
.
height
:
0
)
+
(
isStateEvent
?
0
:
userName
.
height
+
8
)
Avatar
{
id
:
messageUserAvatar
width
:
Nheko
.
avatarSize
*
(
Settings
.
smallAvatars
?
0.5
:
1
)
height
:
Nheko
.
avatarSize
*
(
Settings
.
smallAvatars
?
0.5
:
1
)
url
:
!
room
?
""
:
room
.
avatarUrl
(
userId
).
replace
(
"
mxc://
"
,
"
image://MxcImage/
"
)
displayName
:
userName
userid
:
userId
onClicked
:
room
.
openUserProfile
(
userId
)
ToolTip.visible
:
avatarHover
.
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
userid
Label
{
HoverHandler
{
id
:
dateBubble
id
:
avatarHover
anchors.horizontalCenter
:
parent
?
parent
.
horizontalCenter
:
undefined
visible
:
room
&&
previousMessageDay
!==
day
text
:
room
?
room
.
formatDateSeparator
(
timestamp
)
:
""
color
:
Nheko
.
colors
.
text
height
:
Math
.
round
(
fontMetrics
.
height
*
1.4
)
width
:
contentWidth
*
1.2
horizontalAlignment
:
Text
.
AlignHCenter
verticalAlignment
:
Text
.
AlignVCenter
background
:
Rectangle
{
radius
:
parent
.
height
/
2
color
:
Nheko
.
colors
.
window
}
}
}
}
Row
{
Connections
{
height
:
userName_
.
height
function
onRoomAvatarUrlChanged
()
{
spacing
:
8
messageUserAvatar
.
url
=
chat
.
model
.
avatarUrl
(
userId
).
replace
(
"
mxc://
"
,
"
image://MxcImage/
"
);
visible
:
!
isStateEvent
&&
(
!
isSender
||
!
Settings
.
bubbles
)
}
Avatar
{
id
:
messageUserAvatar
width
:
Nheko
.
avatarSize
*
(
Settings
.
smallAvatars
?
0.5
:
1
)
height
:
Nheko
.
avatarSize
*
(
Settings
.
smallAvatars
?
0.5
:
1
)
url
:
!
room
?
""
:
room
.
avatarUrl
(
userId
).
replace
(
"
mxc://
"
,
"
image://MxcImage/
"
)
displayName
:
userName
userid
:
userId
onClicked
:
room
.
openUserProfile
(
userId
)
ToolTip.visible
:
avatarHover
.
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
userid
HoverHandler
{
id
:
avatarHover
}
function
onScrollToIndex
(
index
)
{
chat
.
positionViewAtIndex
(
index
,
ListView
.
Center
);
}
}
Connections
{
target
:
chat
.
model
function
onRoomAvatarUrlChanged
()
{
}
messageUserAvatar
.
url
=
chat
.
model
.
avatarUrl
(
userId
).
replace
(
"
mxc://
"
,
"
image://MxcImage/
"
);
}
function
onScrollToIndex
(
index
)
{
Label
{
chat
.
positionViewAtIndex
(
index
,
ListView
.
Center
);
id
:
userName_
}
target
:
chat
.
model
text
:
TimelineManager
.
escapeEmoji
(
userName
)
}
color
:
TimelineManager
.
userColor
(
userId
,
Nheko
.
colors
.
base
)
textFormat
:
Text
.
RichText
ToolTip.visible
:
displayNameHover
.
hovered
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
userId
Label
{
TapHandler
{
id
:
userName_
onSingleTapped
:
chat
.
model
.
openUserProfile
(
userId
)
dragThreshold
:
0
}
text
:
TimelineManager
.
escapeEmoji
(
userName
)
CursorShape
{
color
:
TimelineManager
.
userColor
(
userId
,
Nheko
.
colors
.
base
)
anchors.fill
:
parent
textFormat
:
Text
.
RichText
cursorShape
:
Qt
.
PointingHandCursor
ToolTip.visible
:
displayNameHover
.
hovered
}
ToolTip.delay
:
Nheko
.
tooltipDelay
ToolTip.text
:
userId
TapHandler
{
HoverHandler
{
onSingleTapped
:
chat
.
model
.
openUserProfile
(
userId
)
id
:
displayNameHover
dragThreshold
:
0
}
}
CursorShape
{
}
anchors.fill
:
parent
cursorShape
:
Qt
.
PointingHandCursor
}
HoverHandler
{
Label
{
id
:
displayNameHover
id
:
statusMsg
}
color
:
Nheko
.
colors
.
buttonText
text
:
Presence
.
userStatus
(
userId
)
textFormat
:
Text
.
PlainText
elide
:
Text
.
ElideRight
width
:
chat
.
delegateMaxWidth
-
parent
.
spacing
*
2
-
userName
.
implicitWidth
-
Nheko
.
avatarSize
font.italic
:
true
}
Connections
{
target
:
Presence
Label
{
function
onPresenceChanged
(
id
)
{
id
:
statusMsg
if
(
id
==
userId
)
statusMsg
.
text
=
Presence
.
userStatus
(
userId
);
color
:
Nheko
.
colors
.
buttonText
text
:
Presence
.
userStatus
(
userId
)
textFormat
:
Text
.
PlainText
elide
:
Text
.
ElideRight
width
:
chat
.
delegateMaxWidth
-
parent
.
spacing
*
2
-
userName
.
implicitWidth
-
Nheko
.
avatarSize
font.italic
:
true
Connections
{
target
:
Presence
function
onPresenceChanged
(
id
)
{
if
(
id
==
userId
)
statusMsg
.
text
=
Presence
.
userStatus
(
userId
);
}
}
}
}
}
}
}
}
}
}
}
delegate
:
ItemDelegate
{
}
id
:
wrapper
required
property
double
proportionalHeight
required
property
int
type
required
property
string
typeString
required
property
int
originalWidth
required
property
string
blurhash
required
property
string
body
required
property
string
formattedBody
required
property
string
eventId
required
property
string
filename
required
property
string
filesize
required
property
string
url
required
property
string
thumbnailUrl
required
property
bool
isOnlyEmoji
required
property
bool
isSender
required
property
bool
isEncrypted
required
property
bool
isEditable
required
property
bool
isEdited
required
property
bool
isStateEvent
required
property
bool
previousMessageIsStateEvent
required
property
string
replyTo
required
property
string
userId
required
property
string
roomTopic
required
property
string
roomName
required
property
string
callType
required
property
var
reactions
required
property
int
trustlevel
required
property
int
encryptionError
required
property
var
timestamp
required
property
int
status
required
property
int
index
required
property
int
relatedEventCacheBuster
required
property
string
previousMessageUserId
required
property
string
day
required
property
string
previousMessageDay
required
property
string
userName
property
bool
scrolledToThis
:
eventId
===
chat
.
model
.
scrollTarget
&&
(
y
+
height
>
chat
.
y
+
chat
.
contentY
&&
y
<
chat
.
y
+
chat
.
height
+
chat
.
contentY
)
anchors.horizontalCenter
:
parent
?
parent
.
horizontalCenter
:
undefined
width
:
chat
.
delegateMaxWidth
height
:
section
.
active
?
section
.
height
+
timelinerow
.
height
:
timelinerow
.
height
hoverEnabled
:
true
background
:
Rectangle
{
id
:
scrollHighlight
opacity
:
0
visible
:
true
z
:
1
enabled
:
false
color
:
Nheko
.
colors
.
highlight
states
:
State
{
name
:
"
revealed
"
when
:
wrapper
.
scrolledToThis
}
transitions
:
Transition
{
delegate
:
ItemDelegate
{
from
:
""
id
:
wrapper
to
:
"
revealed
"
required
property
double
proportionalHeight
SequentialAnimation
{
required
property
int
type
PropertyAnimation
{
required
property
string
typeString
target
:
scrollHighlight
required
property
int
originalWidth
properties
:
"
opacity
"
required
property
string
blurhash
easing.type
:
Easing
.
InOutQuad
required
property
string
body
from
:
0
required
property
string
formattedBody
to
:
1
required
property
string
eventId
duration
:
500
required
property
string
filename
}
required
property
string
filesize
required
property
string
url
required
property
string
thumbnailUrl
required
property
bool
isOnlyEmoji
required
property
bool
isSender
required
property
bool
isEncrypted
required
property
bool
isEditable
required
property
bool
isEdited
required
property
bool
isStateEvent
required
property
bool
previousMessageIsStateEvent
required
property
string
replyTo
required
property
string
userId
required
property
string
roomTopic
required
property
string
roomName
required
property
string
callType
required
property
var
reactions
required
property
int
trustlevel
required
property
int
encryptionError
required
property
var
timestamp
required
property
int
status
required
property
int
index
required
property
int
relatedEventCacheBuster
required
property
string
previousMessageUserId
required
property
string
day
required
property
string
previousMessageDay
required
property
string
userName
property
bool
scrolledToThis
:
eventId
===
chat
.
model
.
scrollTarget
&&
(
y
+
height
>
chat
.
y
+
chat
.
contentY
&&
y
<
chat
.
y
+
chat
.
height
+
chat
.
contentY
)
anchors.horizontalCenter
:
parent
?
parent
.
horizontalCenter
:
undefined
width
:
chat
.
delegateMaxWidth
height
:
section
.
active
?
section
.
height
+
timelinerow
.
height
:
timelinerow
.
height
hoverEnabled
:
true
background
:
Rectangle
{
id
:
scrollHighlight
opacity
:
0
visible
:
true
z
:
1
enabled
:
false
color
:
Nheko
.
colors
.
highlight
states
:
State
{
name
:
"
revealed
"
when
:
wrapper
.
scrolledToThis
}
PropertyAnimation
{
transitions
:
Transition
{
target
:
scrollHighlight
from
:
""
properties
:
"
opacity
"
to
:
"
revealed
"
easing.type
:
Easing
.
InOutQuad
from
:
1
SequentialAnimation
{
to
:
0
PropertyAnimation
{
duration
:
500
target
:
scrollHighlight
}
properties
:
"
opacity
"
easing.type
:
Easing
.
InOutQuad
from
:
0
to
:
1
duration
:
500
}
ScriptAction
{
PropertyAnimation
{
script
:
chat
.
model
.
eventShown
()
target
:
scrollHighlight
}
properties
:
"
opacity
"
easing.type
:
Easing
.
InOutQuad
from
:
1
to
:
0
duration
:
500
}
ScriptAction
{
script
:
chat
.
model
.
eventShown
()
}
}
}
}
}
}
Loader
{
}
id
:
section
property
int
parentWidth
:
parent
.
width
property
string
userId
:
wrapper
.
userId
property
string
previousMessageUserId
:
wrapper
.
previousMessageUserId
property
string
day
:
wrapper
.
day
property
string
previousMessageDay
:
wrapper
.
previousMessageDay
property
bool
previousMessageIsStateEvent
:
wrapper
.
previousMessageIsStateEvent
property
bool
isStateEvent
:
wrapper
.
isStateEvent
property
bool
isSender
:
wrapper
.
isSender
property
string
userName
:
wrapper
.
userName
property
date
timestamp
:
wrapper
.
timestamp
z
:
4
active
:
previousMessageUserId
!==
undefined
&&
previousMessageUserId
!==
userId
||
previousMessageDay
!==
day
||
previousMessageIsStateEvent
!==
isStateEvent
//asynchronous: true
sourceComponent
:
sectionHeader
visible
:
status
==
Loader
.
Ready
}
TimelineRow
{
Loader
{
id
:
timelinerow
id
:
section
hovered
:
(
wrapper
.
hovered
&&
!
messageActionHover
.
hovered
)
||
(
messageActions
.
model
!=
undefined
&&
messageActions
.
model
.
eventId
==
timelinerow
.
eventId
)
property
int
parentWidth
:
parent
.
width
property
string
userId
:
wrapper
.
userId
proportionalHeight
:
wrapper
.
proportionalHeight
property
string
previousMessageUserId
:
wrapper
.
previousMessageUserId
type
:
chat
.
model
,
wrapper
.
type
property
string
day
:
wrapper
.
day
typeString
:
wrapper
.
typeString
property
string
previousMessageDay
:
wrapper
.
previousMessageDay
originalWidth
:
wrapper
.
originalWidth
property
bool
previousMessageIsStateEvent
:
wrapper
.
previousMessageIsStateEvent
blurhash
:
wrapper
.
blurhash
property
bool
isStateEvent
:
wrapper
.
isStateEvent
body
:
wrapper
.
body
property
bool
isSender
:
wrapper
.
isSender
formattedBody
:
wrapper
.
formattedBody
property
string
userName
:
wrapper
.
userName
eventId
:
chat
.
model
,
wrapper
.
eventId
property
date
timestamp
:
wrapper
.
timestamp
filename
:
wrapper
.
filename
filesize
:
wrapper
.
filesize
z
:
4
url
:
wrapper
.
url
active
:
previousMessageUserId
!==
undefined
&&
previousMessageUserId
!==
userId
||
previousMessageDay
!==
day
||
previousMessageIsStateEvent
!==
isStateEvent
thumbnailUrl
:
wrapper
.
thumbnailUrl
//asynchronous: true
isOnlyEmoji
:
wrapper
.
isOnlyEmoji
sourceComponent
:
sectionHeader
isSender
:
wrapper
.
isSender
visible
:
status
==
Loader
.
Ready
isEncrypted
:
wrapper
.
isEncrypted
}
isEditable
:
wrapper
.
isEditable
isEdited
:
wrapper
.
isEdited
isStateEvent
:
wrapper
.
isStateEvent
replyTo
:
wrapper
.
replyTo
userId
:
wrapper
.
userId
userName
:
wrapper
.
userName
roomTopic
:
wrapper
.
roomTopic
roomName
:
wrapper
.
roomName
callType
:
wrapper
.
callType
reactions
:
wrapper
.
reactions
trustlevel
:
wrapper
.
trustlevel
encryptionError
:
wrapper
.
encryptionError
timestamp
:
wrapper
.
timestamp
status
:
wrapper
.
status
relatedEventCacheBuster
:
wrapper
.
relatedEventCacheBuster
y
:
section
.
visible
&&
section
.
active
?
section
.
y
+
section
.
height
:
0
}
onHoveredChanged
:
{
TimelineRow
{
if
(
!
Settings
.
mobileMode
&&
hovered
)
{
id
:
timelinerow
if
(
!
messageActionHover
.
hovered
)
{
messageActions
.
attached
=
timelinerow
;
hovered
:
(
wrapper
.
hovered
&&
!
messageActionHover
.
hovered
)
||
(
messageActions
.
model
!=
undefined
&&
messageActions
.
model
.
eventId
==
timelinerow
.
eventId
)
messageActions
.
model
=
timelinerow
;
}
proportionalHeight
:
wrapper
.
proportionalHeight
type
:
chat
.
model
,
wrapper
.
type
typeString
:
wrapper
.
typeString
originalWidth
:
wrapper
.
originalWidth
blurhash
:
wrapper
.
blurhash
body
:
wrapper
.
body
formattedBody
:
wrapper
.
formattedBody
eventId
:
chat
.
model
,
wrapper
.
eventId
filename
:
wrapper
.
filename
filesize
:
wrapper
.
filesize
url
:
wrapper
.
url
thumbnailUrl
:
wrapper
.
thumbnailUrl
isOnlyEmoji
:
wrapper
.
isOnlyEmoji
isSender
:
wrapper
.
isSender
isEncrypted
:
wrapper
.
isEncrypted
isEditable
:
wrapper
.
isEditable
isEdited
:
wrapper
.
isEdited
isStateEvent
:
wrapper
.
isStateEvent
replyTo
:
wrapper
.
replyTo
userId
:
wrapper
.
userId
userName
:
wrapper
.
userName
roomTopic
:
wrapper
.
roomTopic
roomName
:
wrapper
.
roomName
callType
:
wrapper
.
callType
reactions
:
wrapper
.
reactions
trustlevel
:
wrapper
.
trustlevel
encryptionError
:
wrapper
.
encryptionError
timestamp
:
wrapper
.
timestamp
status
:
wrapper
.
status
relatedEventCacheBuster
:
wrapper
.
relatedEventCacheBuster
y
:
section
.
visible
&&
section
.
active
?
section
.
y
+
section
.
height
:
0
}
onHoveredChanged
:
{
if
(
!
Settings
.
mobileMode
&&
hovered
)
{
if
(
!
messageActionHover
.
hovered
)
{
messageActions
.
attached
=
timelinerow
;
messageActions
.
model
=
timelinerow
;
}
}
}
}
}
Connections
{
Connections
{
function
onMovementEnded
()
{
function
onMovementEnded
()
{
if
(
y
+
height
+
2
*
chat
.
spacing
>
chat
.
contentY
+
chat
.
height
&&
y
<
chat
.
contentY
+
chat
.
height
)
if
(
y
+
height
+
2
*
chat
.
spacing
>
chat
.
contentY
+
chat
.
height
&&
y
<
chat
.
contentY
+
chat
.
height
)
chat
.
model
.
currentIndex
=
index
;
chat
.
model
.
currentIndex
=
index
;
}
target
:
chat
}
}
target
:
chat
}
}
footer
:
Item
{
}
anchors.horizontalCenter
:
parent
.
horizontalCenter
anchors.margins
:
Nheko
.
paddingLarge
visible
:
chat
.
model
&&
chat
.
model
.
paginationInProgress
// hacky, but works
height
:
loadingSpinner
.
height
+
2
*
Nheko
.
paddingLarge
Spinner
{
id
:
loadingSpinner
anchors.centerIn
:
parent
anchors.margins
:
Nheko
.
paddingLarge
running
:
chat
.
model
&&
chat
.
model
.
paginationInProgress
foreground
:
Nheko
.
colors
.
mid
z
:
3
}
footer
:
Item
{
anchors.horizontalCenter
:
parent
.
horizontalCenter
anchors.margins
:
Nheko
.
paddingLarge
visible
:
chat
.
model
&&
chat
.
model
.
paginationInProgress
// hacky, but works
height
:
loadingSpinner
.
height
+
2
*
Nheko
.
paddingLarge
Spinner
{
id
:
loadingSpinner
anchors.centerIn
:
parent
anchors.margins
:
Nheko
.
paddingLarge
running
:
chat
.
model
&&
chat
.
model
.
paginationInProgress
foreground
:
Nheko
.
colors
.
mid
z
:
3
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment