diff --git a/scripts/communityScripts/armored-chat/armored_chat.js b/scripts/communityScripts/armored-chat/armored_chat.js index fe66da7a54..3736922a69 100644 --- a/scripts/communityScripts/armored-chat/armored_chat.js +++ b/scripts/communityScripts/armored-chat/armored_chat.js @@ -164,7 +164,8 @@ case "action": switch (event.action) { case "erase_history": - Settings.setValue("ArmoredChat-Messages", []); + Settings.setValue("ArmoredChat-Messages", null); + messageHistory = []; _emitEvent({ type: "clear_messages", }); diff --git a/scripts/communityScripts/armored-chat/armored_chat.qml b/scripts/communityScripts/armored-chat/armored_chat.qml index 1da7c7ea02..bd6deec3db 100644 --- a/scripts/communityScripts/armored-chat/armored_chat.qml +++ b/scripts/communityScripts/armored-chat/armored_chat.qml @@ -1,5 +1,5 @@ import QtQuick 2.7 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.15 import QtQuick.Layouts 1.3 import controlsUit 1.0 as HifiControlsUit @@ -30,7 +30,7 @@ Rectangle { running: false repeat: false onTriggered: { - scrollToBottom(); + scrollToBottom(true); } } @@ -145,49 +145,60 @@ Rectangle { anchors.top: navigation_bar.bottom visible: ["local", "domain"].includes(pageVal) ? true : false - // Chat Message History - ListView { + Flickable { width: parent.width height: parent.height - 40 + contentWidth: parent.width + contentHeight: listview.height clip: true - interactive: true - spacing: 5 - id: listview - - delegate: Loader { - property int delegateIndex: index - property string delegateText: model.text - property string delegateUsername: model.username - property string delegateDate: model.date - width: listview.width - - sourceComponent: { - if (model.type === "chat") { - return template_chat_message; - } else if (model.type === "notification") { - return template_notification; + id: messageViewFlickable + + ColumnLayout { + id: listview + Layout.fillWidth: true + + Repeater { + model: getChannel(pageVal) + delegate: Loader { + property int delegateIndex: model.index + property string delegateText: model.text + property string delegateUsername: model.username + property string delegateDate: model.date + + sourceComponent: { + if (model.type === "chat") { + return template_chat_message; + } else if (model.type === "notification") { + return template_notification; + } + } + } } } - ScrollBar.vertical: ScrollBar { - id: chat_scrollbar - height: 100 - size: 0.05 + ScrollBar.vertical: ScrollBar { + size: 100 + minimumSize: 0.1 } - model: getChannel(pageVal) - + rebound: Transition { + NumberAnimation { + properties: "x,y" + duration: 1 + } + } } + ListModel { id: local } ListModel { id: domain - } + } // Chat Entry Rectangle { @@ -346,7 +357,7 @@ Rectangle { Component { id: template_chat_message - Rectangle{ + Rectangle { property int index: delegateIndex property string texttest: delegateText property string username: delegateUsername @@ -354,6 +365,8 @@ Rectangle { height: Math.max(65, children[1].height + 30) color: index % 2 === 0 ? "transparent" : Qt.rgba(0.15,0.15,0.15,1) + width: listview.parent.parent.width + Layout.fillWidth: true Item { width: parent.width - 10 @@ -372,7 +385,7 @@ Rectangle { } } - TextEdit{ + TextEdit { anchors.top: parent.children[0].bottom x: 5 text: texttest @@ -453,16 +466,25 @@ Rectangle { } - - property var channels: { "local": local, "domain": domain, } - function scrollToBottom() { - if (listview.count == 0) return; - listview.positionViewAtEnd(); + function scrollToBottom(bypassDistanceCheck = false, extraMoveDistance = 0) { + const totalHeight = listview.height; // Total height of the content + const currentPosition = messageViewFlickable.contentY; // Current position of the view + const windowHeight = listview.parent.parent.height; // Total height of the window + const bottomPosition = currentPosition + windowHeight; + + // Check if the view is within 300 units from the bottom + const closeEnoughToBottom = totalHeight - bottomPosition <= 300; + if (!bypassDistanceCheck && !closeEnoughToBottom) return; + if (totalHeight < windowHeight) return; // No reason to scroll, we don't have an overflow. + if (bottomPosition == totalHeight) return; // At the bottom, do nothing. + + messageViewFlickable.contentY = listview.height - listview.parent.parent.height; + messageViewFlickable.returnToBounds(); } @@ -471,13 +493,13 @@ Rectangle { // Format content message = formatContent(message); - message = embedImages(message); if (type === "notification"){ channel.append({ text: message, date: date, type: "notification" }); last_message_user = ""; - scrollToBottom(); + scrollToBottom(null, 30); + last_message_time = new Date(); return; } @@ -489,22 +511,18 @@ Rectangle { var last_item_index = channel.count - 1; var last_item = channel.get(last_item_index); - // FIXME: When adding a new message this would check to see if we could append the incoming message - // to the bottom of the last message. This current implimentation causes issues with scrollToBottom() - // Specifically, scrolling to the bottom does not like image embeds. - // This needs to be reworked entirely before it can be reimplimented - // if (last_message_user === username && elapsed_minutes < 1 && last_item){ - // message = "
" + message - // last_item.text = last_item.text += "\n" + message; - // scrollToBottom() - // last_message_time = new Date(); - // return; - // } + if (last_message_user === username && elapsed_minutes < 1 && last_item){ + message = "
" + message + last_item.text = last_item.text += "\n" + message; + load_scroll_timer.running = true; + last_message_time = new Date(); + return; + } last_message_user = username; last_message_time = new Date(); channel.append({ text: message, username: username, date: date, type: type }); - scrollToBottom(); + load_scroll_timer.running = true; } function getChannel(id) {