Highlight navigated to message
This commit is contained in:
parent
620b6e8838
commit
82fa8ab292
@ -25,10 +25,6 @@ Popup {
|
||||
height: implicitHeight + completerPopup.height + padding * 2
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
background: Rectangle {
|
||||
color: colors.window
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
completerPopup.open();
|
||||
roomTextInput.forceActiveFocus();
|
||||
@ -110,6 +106,10 @@ Popup {
|
||||
target: completerPopup
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: colors.window
|
||||
}
|
||||
|
||||
Overlay.modal: Rectangle {
|
||||
color: Qt.rgba(colors.window.r, colors.window.g, colors.window.b, 0.7)
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ TextEdit {
|
||||
selectByMouse: !Settings.mobileMode
|
||||
enabled: selectByMouse
|
||||
color: colors.text
|
||||
onLinkActivated: TimelineManager.openLink(link);
|
||||
onLinkActivated: TimelineManager.openLink(link)
|
||||
ToolTip.visible: hoveredLink
|
||||
ToolTip.text: hoveredLink
|
||||
|
||||
|
@ -258,6 +258,7 @@ ScrollView {
|
||||
onRoomAvatarUrlChanged: {
|
||||
messageUserAvatar.url = modelData ? chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") : "";
|
||||
}
|
||||
onScrollToIndex: chat.positionViewAtIndex(index, ListView.Visible)
|
||||
}
|
||||
|
||||
Label {
|
||||
@ -302,10 +303,58 @@ ScrollView {
|
||||
delegate: Item {
|
||||
id: wrapper
|
||||
|
||||
property bool scrolledToThis: model.id === 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 ? section.height + timelinerow.height : timelinerow.height
|
||||
|
||||
Rectangle {
|
||||
id: scrollHighlight
|
||||
|
||||
opacity: 0
|
||||
visible: true
|
||||
anchors.fill: timelinerow
|
||||
color: colors.highlight
|
||||
|
||||
states: State {
|
||||
name: "revealed"
|
||||
when: wrapper.scrolledToThis
|
||||
}
|
||||
|
||||
transitions: Transition {
|
||||
from: ""
|
||||
to: "revealed"
|
||||
|
||||
SequentialAnimation {
|
||||
PropertyAnimation {
|
||||
target: scrollHighlight
|
||||
properties: "opacity"
|
||||
easing.type: Easing.InOutQuad
|
||||
from: 0
|
||||
to: 1
|
||||
duration: 500
|
||||
}
|
||||
|
||||
PropertyAnimation {
|
||||
target: scrollHighlight
|
||||
properties: "opacity"
|
||||
easing.type: Easing.InOutQuad
|
||||
from: 1
|
||||
to: 0
|
||||
duration: 500
|
||||
}
|
||||
|
||||
ScriptAction {
|
||||
script: chat.model.eventShown()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: section
|
||||
|
||||
|
@ -8,7 +8,7 @@ import im.nheko 1.0
|
||||
Item {
|
||||
property double tempWidth: Math.min(parent ? parent.width : undefined, model.data.width < 1 ? parent.width : model.data.width)
|
||||
property double tempHeight: tempWidth * model.data.proportionalHeight
|
||||
property double divisor: model.isReply ? 4 : 2
|
||||
property double divisor: model.isReply ? 5 : 3
|
||||
property bool tooHigh: tempHeight > timelineRoot.height / divisor
|
||||
|
||||
height: Math.round(tooHigh ? timelineRoot.height / divisor : tempHeight)
|
||||
|
@ -18,7 +18,7 @@ Item {
|
||||
height: replyContainer.height
|
||||
|
||||
TapHandler {
|
||||
onSingleTapped: chat.positionViewAtIndex(chat.model.idToIndex(modelData.id), ListView.Contain)
|
||||
onSingleTapped: chat.model.showEvent(modelData.id)
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
}
|
||||
|
||||
|
@ -1376,7 +1376,7 @@ ChatPage::handleMatrixUri(const QByteArray &uri)
|
||||
return;
|
||||
|
||||
QString mxid2;
|
||||
if (segments.size() == 4 && segments[2] == "event") {
|
||||
if (segments.size() == 4 && segments[2] == "e") {
|
||||
if (segments[3].isEmpty())
|
||||
return;
|
||||
else
|
||||
@ -1410,6 +1410,8 @@ ChatPage::handleMatrixUri(const QByteArray &uri)
|
||||
for (auto roomid : joined_rooms) {
|
||||
if (roomid == targetRoomId) {
|
||||
room_list_->highlightSelectedRoom(mxid1);
|
||||
if (!mxid2.isEmpty())
|
||||
view_manager_->showEvent(mxid1, mxid2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1427,6 +1429,9 @@ ChatPage::handleMatrixUri(const QByteArray &uri)
|
||||
if (aliases->alias == targetRoomAlias) {
|
||||
room_list_->highlightSelectedRoom(
|
||||
QString::fromStdString(roomid));
|
||||
if (!mxid2.isEmpty())
|
||||
view_manager_->showEvent(
|
||||
QString::fromStdString(roomid), mxid2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -265,6 +265,8 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
|
||||
connect(&events, &EventStore::updateFlowEventId, this, [this](std::string event_id) {
|
||||
this->updateFlowEventId(event_id);
|
||||
});
|
||||
|
||||
showEventTimer.callOnTimeout(this, &TimelineModel::scrollTimerEvent);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
@ -1298,6 +1300,42 @@ TimelineModel::cacheMedia(QString eventId)
|
||||
cacheMedia(eventId, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineModel::showEvent(QString eventId)
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
if (idToIndex(eventId) != -1) {
|
||||
eventIdToShow = eventId;
|
||||
emit scrollTargetChanged();
|
||||
showEventTimer.start(50ms);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimelineModel::eventShown()
|
||||
{
|
||||
eventIdToShow.clear();
|
||||
emit scrollTargetChanged();
|
||||
}
|
||||
|
||||
QString
|
||||
TimelineModel::scrollTarget() const
|
||||
{
|
||||
return eventIdToShow;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineModel::scrollTimerEvent()
|
||||
{
|
||||
if (eventIdToShow.isEmpty() || showEventTimerCounter > 3) {
|
||||
showEventTimer.stop();
|
||||
showEventTimerCounter = 0;
|
||||
} else {
|
||||
emit scrollToIndex(idToIndex(eventIdToShow));
|
||||
showEventTimerCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
QString
|
||||
TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg)
|
||||
{
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <QDate>
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
|
||||
#include <mtxclient/http/errors.hpp>
|
||||
|
||||
@ -149,6 +150,7 @@ class TimelineModel : public QAbstractListModel
|
||||
int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
|
||||
Q_PROPERTY(std::vector<QString> typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY
|
||||
typingUsersChanged)
|
||||
Q_PROPERTY(QString scrollTarget READ scrollTarget NOTIFY scrollTargetChanged)
|
||||
Q_PROPERTY(QString reply READ reply WRITE setReply NOTIFY replyChanged RESET resetReply)
|
||||
Q_PROPERTY(QString edit READ edit WRITE setEdit NOTIFY editChanged RESET resetEdit)
|
||||
Q_PROPERTY(
|
||||
@ -232,6 +234,7 @@ public:
|
||||
Q_INVOKABLE void openMedia(QString eventId);
|
||||
Q_INVOKABLE void cacheMedia(QString eventId);
|
||||
Q_INVOKABLE bool saveMedia(QString eventId) const;
|
||||
Q_INVOKABLE void showEvent(QString eventId);
|
||||
void cacheMedia(QString eventId, std::function<void(const QString filename)> callback);
|
||||
|
||||
std::vector<::Reaction> reactions(const std::string &event_id)
|
||||
@ -253,6 +256,7 @@ public:
|
||||
public slots:
|
||||
void setCurrentIndex(int index);
|
||||
int currentIndex() const { return idToIndex(currentId); }
|
||||
void eventShown();
|
||||
void markEventsAsRead(const std::vector<QString> &event_ids);
|
||||
QVariantMap getDump(QString eventId, QString relatedTo) const;
|
||||
void updateTypingUsers(const std::vector<QString> &users)
|
||||
@ -298,8 +302,11 @@ public slots:
|
||||
QString roomAvatarUrl() const;
|
||||
QString roomId() const { return room_id_; }
|
||||
|
||||
QString scrollTarget() const;
|
||||
|
||||
private slots:
|
||||
void addPendingMessage(mtx::events::collections::TimelineEvents event);
|
||||
void scrollTimerEvent();
|
||||
|
||||
signals:
|
||||
void currentIndexChanged(int index);
|
||||
@ -312,6 +319,7 @@ signals:
|
||||
void editChanged(QString reply);
|
||||
void paginationInProgressChanged(const bool);
|
||||
void newCallEvent(const mtx::events::collections::TimelineEvents &event);
|
||||
void scrollToIndex(int index);
|
||||
|
||||
void openProfile(UserProfile *profile);
|
||||
void openRoomSettingsDialog(RoomSettings *settings);
|
||||
@ -325,6 +333,8 @@ signals:
|
||||
void roomAvatarUrlChanged();
|
||||
void forwardToRoom(mtx::events::collections::TimelineEvents *e, QString roomId);
|
||||
|
||||
void scrollTargetChanged();
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
void sendEncryptedMessage(mtx::events::RoomEvent<T> msg, mtx::events::EventType eventType);
|
||||
@ -350,6 +360,10 @@ private:
|
||||
|
||||
InputBar input_{this};
|
||||
|
||||
QTimer showEventTimer{this};
|
||||
QString eventIdToShow;
|
||||
int showEventTimerCounter = 0;
|
||||
|
||||
friend struct SendMessageVisitor;
|
||||
};
|
||||
|
||||
|
@ -404,6 +404,22 @@ TimelineViewManager::highlightRoom(const QString &room_id)
|
||||
ChatPage::instance()->highlightRoom(room_id);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineViewManager::showEvent(const QString &room_id, const QString &event_id)
|
||||
{
|
||||
auto room = models.find(room_id);
|
||||
if (room != models.end()) {
|
||||
if (timeline_ != room.value().data()) {
|
||||
timeline_ = room.value().data();
|
||||
emit activeTimelineChanged(timeline_);
|
||||
container->setFocus();
|
||||
nhlog::ui()->info("Activated room {}", room_id.toStdString());
|
||||
}
|
||||
|
||||
timeline_->showEvent(event_id);
|
||||
}
|
||||
}
|
||||
|
||||
QString
|
||||
TimelineViewManager::escapeEmoji(QString str) const
|
||||
{
|
||||
|
@ -106,6 +106,7 @@ public slots:
|
||||
|
||||
void setHistoryView(const QString &room_id);
|
||||
void highlightRoom(const QString &room_id);
|
||||
void showEvent(const QString &room_id, const QString &event_id);
|
||||
void focusTimeline();
|
||||
TimelineModel *getHistoryView(const QString &room_id)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user