| 
									
										
										
										
											2019-12-19 07:46:16 -04:00
										 |  |  | // SPDX-License-Identifier: LGPL-3.0-or-later
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-13 05:39:01 -04:00
										 |  |  | import QtQuick 2.12 | 
					
						
							| 
									
										
										
										
											2020-03-07 11:11:32 -04:00
										 |  |  | import QtQuick.Layouts 1.12 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:29:29 -04:00
										 |  |  | import "../../.." | 
					
						
							| 
									
										
										
										
											2019-12-18 04:53:08 -04:00
										 |  |  | import "../../../Base" | 
					
						
							| 
									
										
										
										
											2019-03-21 23:28:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-27 22:46:31 -04:00
										 |  |  | Rectangle { | 
					
						
							| 
									
										
										
										
											2019-09-01 06:56:03 -04:00
										 |  |  |     property alias selectableLabelContainer: selectableLabelContainer | 
					
						
							|  |  |  |     property alias eventList: eventList | 
					
						
							| 
									
										
										
										
											2019-07-06 17:29:32 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-13 20:15:20 -04:00
										 |  |  |     color: theme.chat.eventList.background | 
					
						
							| 
									
										
										
										
											2019-04-28 11:01:38 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |     HSelectableLabelContainer { | 
					
						
							|  |  |  |         id: selectableLabelContainer | 
					
						
							|  |  |  |         anchors.fill: parent | 
					
						
							| 
									
										
										
										
											2019-12-09 11:35:50 -04:00
										 |  |  |         reversed: eventList.verticalLayoutDirection === ListView.BottomToTop | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-11 15:25:57 -04:00
										 |  |  |         DragHandler { | 
					
						
							|  |  |  |             target: null | 
					
						
							|  |  |  |             onActiveChanged: if (! active) dragFlicker.speed = 0 | 
					
						
							|  |  |  |             onCentroidChanged: { | 
					
						
							| 
									
										
										
										
											2020-03-08 04:46:20 -04:00
										 |  |  |                 const left  = centroid.pressedButtons & Qt.LeftButton | 
					
						
							|  |  |  |                 const vel   = centroid.velocity.y | 
					
						
							|  |  |  |                 const pos   = centroid.position.y | 
					
						
							|  |  |  |                 const dist  = Math.min(selectableLabelContainer.height / 4, 50) | 
					
						
							|  |  |  |                 const boost = 20 * (pos < dist ?  -pos : -(height - pos)) | 
					
						
							| 
									
										
										
										
											2019-09-11 15:25:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 dragFlicker.speed = | 
					
						
							|  |  |  |                     left && vel && pos < dist          ? 1000 + boost : | 
					
						
							|  |  |  |                     left && vel && pos > height - dist ? -1000 + -boost : | 
					
						
							|  |  |  |                     0 | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-07-19 23:07:26 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |         Timer { | 
					
						
							|  |  |  |             id: dragFlicker | 
					
						
							|  |  |  |             interval: 100 | 
					
						
							| 
									
										
										
										
											2019-12-09 11:35:50 -04:00
										 |  |  |             running: speed !== 0 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             repeat: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             onTriggered: { | 
					
						
							| 
									
										
										
										
											2019-12-09 11:35:50 -04:00
										 |  |  |                 if (eventList.verticalOvershoot !== 0) return | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |                 if (speed < 0 && eventList.atYEnd) return | 
					
						
							|  |  |  |                 if (eventList.atYBeggining) { | 
					
						
							|  |  |  |                     if (bouncedStart) { return } else { bouncedStart = true } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 eventList.flick(0, speed * acceleration) | 
					
						
							|  |  |  |                 acceleration = Math.min(8, acceleration * 1.05) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             onRunningChanged: if (! running) { | 
					
						
							|  |  |  |                 acceleration = 1.0 | 
					
						
							|  |  |  |                 bouncedStart = false | 
					
						
							|  |  |  |                 eventList.cancelFlick() | 
					
						
							|  |  |  |                 eventList.returnToBounds() | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-07-19 23:07:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             property real speed: 0.0 | 
					
						
							|  |  |  |             property real acceleration: 1.0 | 
					
						
							|  |  |  |             property bool bouncedStart: false | 
					
						
							| 
									
										
										
										
											2019-07-19 23:07:26 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |         HListView { | 
					
						
							|  |  |  |             id: eventList | 
					
						
							|  |  |  |             clip: true | 
					
						
							| 
									
										
										
										
											2019-12-10 11:49:46 -04:00
										 |  |  |             allowDragging: false | 
					
						
							| 
									
										
										
										
											2019-08-30 10:33:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             anchors.fill: parent | 
					
						
							|  |  |  |             anchors.leftMargin: theme.spacing | 
					
						
							|  |  |  |             anchors.rightMargin: theme.spacing | 
					
						
							| 
									
										
										
										
											2019-07-19 23:07:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             topMargin: theme.spacing | 
					
						
							|  |  |  |             bottomMargin: theme.spacing | 
					
						
							|  |  |  |             verticalLayoutDirection: ListView.BottomToTop | 
					
						
							| 
									
										
										
										
											2019-07-19 23:07:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 10:36:59 -04:00
										 |  |  |             // Keep x scroll pages cached, to limit images having to be
 | 
					
						
							|  |  |  |             // reloaded from network.
 | 
					
						
							|  |  |  |             cacheBuffer: height * 2 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             onYPosChanged: | 
					
						
							|  |  |  |                 if (canLoad && yPos < 0.1) Qt.callLater(loadPastEvents) | 
					
						
							| 
									
										
										
										
											2019-07-18 06:23:31 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             // When an invited room becomes joined, we should now be able to
 | 
					
						
							|  |  |  |             // fetch past events.
 | 
					
						
							|  |  |  |             onInviterChanged: canLoad = true | 
					
						
							| 
									
										
										
										
											2019-07-02 13:59:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 11:11:32 -04:00
										 |  |  |             // Since the list is BottomToTop, this is actually a header
 | 
					
						
							|  |  |  |             footer: Item { | 
					
						
							|  |  |  |                 width: eventList.width | 
					
						
							|  |  |  |                 height: (button.height + theme.spacing * 2) * opacity | 
					
						
							|  |  |  |                 opacity: eventList.loading ? 1 : 0 | 
					
						
							|  |  |  |                 visible: opacity > 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 Behavior on opacity { HNumberAnimation {} } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 HButton { | 
					
						
							|  |  |  |                     id: button | 
					
						
							|  |  |  |                     width: Math.min(parent.width, implicitWidth) | 
					
						
							|  |  |  |                     anchors.centerIn: parent | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     loading: true | 
					
						
							|  |  |  |                     text: qsTr("Loading previous messages...") | 
					
						
							|  |  |  |                     enableRadius: true | 
					
						
							|  |  |  |                     iconItem.small: true | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             Component.onCompleted: shortcuts.flickTarget = eventList | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 05:25:31 -04:00
										 |  |  |             property string inviter: chat.roomInfo.inviter || "" | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             property real yPos: visibleArea.yPosition | 
					
						
							|  |  |  |             property bool canLoad: true | 
					
						
							| 
									
										
										
										
											2020-03-07 11:11:32 -04:00
										 |  |  |             property bool loading: false | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |             property bool ownEventsOnRight: | 
					
						
							|  |  |  |                 width < theme.chat.eventList.ownEventsOnRightUnderWidth | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             function canCombine(item, itemAfter) { | 
					
						
							|  |  |  |                 if (! item || ! itemAfter) return false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return Boolean( | 
					
						
							|  |  |  |                     ! canTalkBreak(item, itemAfter) && | 
					
						
							|  |  |  |                     ! canDayBreak(item, itemAfter) && | 
					
						
							|  |  |  |                     item.sender_id === itemAfter.sender_id && | 
					
						
							| 
									
										
										
										
											2019-12-17 17:59:53 -04:00
										 |  |  |                     utils.minutesBetween(item.date, itemAfter.date) <= 5 | 
					
						
							| 
									
										
										
										
											2019-08-19 13:14:25 -04:00
										 |  |  |                 ) | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-08-15 11:46:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             function canTalkBreak(item, itemAfter) { | 
					
						
							|  |  |  |                 if (! item || ! itemAfter) return false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return Boolean( | 
					
						
							|  |  |  |                     ! canDayBreak(item, itemAfter) && | 
					
						
							| 
									
										
										
										
											2019-12-17 17:59:53 -04:00
										 |  |  |                     utils.minutesBetween(item.date, itemAfter.date) >= 20 | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |                 ) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             function canDayBreak(item, itemAfter) { | 
					
						
							| 
									
										
										
										
											2019-12-09 11:35:50 -04:00
										 |  |  |                 if (itemAfter && itemAfter.event_type === "RoomCreateEvent") | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |                     return true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (! item || ! itemAfter || ! item.date || ! itemAfter.date) | 
					
						
							|  |  |  |                     return false | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 11:35:50 -04:00
										 |  |  |                 return item.date.getDate() !== itemAfter.date.getDate() | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             function loadPastEvents() { | 
					
						
							|  |  |  |                 // try/catch blocks to hide pyotherside error when the
 | 
					
						
							|  |  |  |                 // component is destroyed but func is still running
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 try { | 
					
						
							| 
									
										
										
										
											2020-03-07 11:11:32 -04:00
										 |  |  |                     eventList.canLoad = false | 
					
						
							|  |  |  |                     eventList.loading = true | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     py.callClientCoro( | 
					
						
							| 
									
										
										
										
											2019-12-20 09:30:57 -04:00
										 |  |  |                         chat.userId, | 
					
						
							|  |  |  |                         "load_past_events", | 
					
						
							|  |  |  |                         [chat.roomId], | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |                         moreToLoad => { | 
					
						
							|  |  |  |                             try { | 
					
						
							|  |  |  |                                 eventList.canLoad = moreToLoad | 
					
						
							| 
									
										
										
										
											2019-09-02 22:55:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 08:20:44 -04:00
										 |  |  |                                 // Call yPosChanged() to run this func again
 | 
					
						
							|  |  |  |                                 // if the loaded messages aren't enough to fill
 | 
					
						
							|  |  |  |                                 // the screen.
 | 
					
						
							| 
									
										
										
										
											2019-09-02 22:55:28 -04:00
										 |  |  |                                 if (moreToLoad) yPosChanged() | 
					
						
							| 
									
										
										
										
											2019-12-17 08:20:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 11:11:32 -04:00
										 |  |  |                                 eventList.loading = false | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |                             } catch (err) { | 
					
						
							|  |  |  |                                 return | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                 } catch (err) { | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:29:29 -04:00
										 |  |  |             model: ModelStore.get(chat.userId, chat.roomId, "events") | 
					
						
							| 
									
										
										
										
											2019-08-30 11:17:13 -04:00
										 |  |  |             delegate: EventDelegate {} | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-21 23:28:14 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-22 11:31:06 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 14:20:21 -04:00
										 |  |  |     HNoticePage { | 
					
						
							| 
									
										
										
										
											2019-12-04 09:32:07 -04:00
										 |  |  |         text: qsTr("No messages to show yet") | 
					
						
							| 
									
										
										
										
											2019-04-28 14:20:30 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-13 20:15:20 -04:00
										 |  |  |         visible: eventList.model.count < 1 | 
					
						
							| 
									
										
										
										
											2019-05-02 14:20:21 -04:00
										 |  |  |         anchors.fill: parent | 
					
						
							| 
									
										
										
										
											2019-04-22 11:31:06 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-21 23:28:14 -04:00
										 |  |  | } |