Warn the user before they ping the whole room
This commit is contained in:
parent
0ce200fee5
commit
3528fe4e5d
|
@ -268,7 +268,7 @@ Rectangle {
|
||||||
function onRoomChanged() {
|
function onRoomChanged() {
|
||||||
messageInput.clear();
|
messageInput.clear();
|
||||||
if (room)
|
if (room)
|
||||||
messageInput.append(room.input.text());
|
messageInput.append(room.input.text);
|
||||||
|
|
||||||
popup.completerName = "";
|
popup.completerName = "";
|
||||||
messageInput.forceActiveFocus();
|
messageInput.forceActiveFocus();
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.3
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import im.nheko 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
implicitHeight: warningRect.visible ? warningDisplay.implicitHeight : 0
|
||||||
|
height: implicitHeight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: warningRect
|
||||||
|
|
||||||
|
visible: (room && room.permissions.canPingRoom && room.input.containsAtRoom)
|
||||||
|
color: Nheko.colors.base
|
||||||
|
anchors.fill: parent
|
||||||
|
z: 3
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: warningDisplay
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
color: Nheko.theme.red
|
||||||
|
text: qsTr("You will be pinging the whole room")
|
||||||
|
textFormat: Text.PlainText
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -123,6 +123,9 @@ Item {
|
||||||
color: Nheko.theme.separator
|
color: Nheko.theme.separator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotificationWarning {
|
||||||
|
}
|
||||||
|
|
||||||
ReplyPopup {
|
ReplyPopup {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,7 @@
|
||||||
<file>qml/QuickSwitcher.qml</file>
|
<file>qml/QuickSwitcher.qml</file>
|
||||||
<file>qml/ForwardCompleter.qml</file>
|
<file>qml/ForwardCompleter.qml</file>
|
||||||
<file>qml/TypingIndicator.qml</file>
|
<file>qml/TypingIndicator.qml</file>
|
||||||
|
<file>qml/NotificationWarning.qml</file>
|
||||||
<file>qml/RoomSettings.qml</file>
|
<file>qml/RoomSettings.qml</file>
|
||||||
<file>qml/emoji/EmojiPicker.qml</file>
|
<file>qml/emoji/EmojiPicker.qml</file>
|
||||||
<file>qml/emoji/StickerPicker.qml</file>
|
<file>qml/emoji/StickerPicker.qml</file>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QMimeDatabase>
|
#include <QMimeDatabase>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QTextBoundaryFinder>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
@ -129,6 +130,34 @@ InputBar::insertMimeData(const QMimeData *md)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InputBar::updateAtRoom(const QString &t)
|
||||||
|
{
|
||||||
|
bool roomMention = false;
|
||||||
|
|
||||||
|
if (t.size() > 4) {
|
||||||
|
QTextBoundaryFinder finder(QTextBoundaryFinder::BoundaryType::Word, t);
|
||||||
|
|
||||||
|
finder.toStart();
|
||||||
|
do {
|
||||||
|
auto start = finder.position();
|
||||||
|
finder.toNextBoundary();
|
||||||
|
auto end = finder.position();
|
||||||
|
if (start > 0 && end - start >= 4 &&
|
||||||
|
t.midRef(start, end - start) == "room" &&
|
||||||
|
t.at(start - 1) == QChar('@')) {
|
||||||
|
roomMention = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (finder.position() < t.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roomMention != this->containsAtRoom_) {
|
||||||
|
this->containsAtRoom_ = roomMention;
|
||||||
|
emit containsAtRoomChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InputBar::setText(QString newText)
|
InputBar::setText(QString newText)
|
||||||
{
|
{
|
||||||
|
@ -157,6 +186,8 @@ InputBar::updateState(int selectionStart_, int selectionEnd_, int cursorPosition
|
||||||
else
|
else
|
||||||
history_.front() = text_;
|
history_.front() = text_;
|
||||||
history_index_ = 0;
|
history_index_ = 0;
|
||||||
|
|
||||||
|
updateAtRoom(text_);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectionStart = selectionStart_;
|
selectionStart = selectionStart_;
|
||||||
|
@ -182,6 +213,7 @@ InputBar::previousText()
|
||||||
else if (text().isEmpty())
|
else if (text().isEmpty())
|
||||||
history_index_--;
|
history_index_--;
|
||||||
|
|
||||||
|
updateAtRoom(text());
|
||||||
return text();
|
return text();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +224,7 @@ InputBar::nextText()
|
||||||
if (history_index_ >= INPUT_HISTORY_SIZE)
|
if (history_index_ >= INPUT_HISTORY_SIZE)
|
||||||
history_index_ = 0;
|
history_index_ = 0;
|
||||||
|
|
||||||
|
updateAtRoom(text());
|
||||||
return text();
|
return text();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ class InputBar : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged)
|
Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged)
|
||||||
|
Q_PROPERTY(bool containsAtRoom READ containsAtRoom NOTIFY containsAtRoomChanged)
|
||||||
|
Q_PROPERTY(QString text READ text NOTIFY textChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InputBar(TimelineModel *parent)
|
InputBar(TimelineModel *parent)
|
||||||
|
@ -48,6 +50,8 @@ public slots:
|
||||||
QString nextText();
|
QString nextText();
|
||||||
void setText(QString newText);
|
void setText(QString newText);
|
||||||
|
|
||||||
|
bool containsAtRoom() const { return containsAtRoom_; }
|
||||||
|
|
||||||
void send();
|
void send();
|
||||||
void paste(bool fromMouse);
|
void paste(bool fromMouse);
|
||||||
void insertMimeData(const QMimeData *data);
|
void insertMimeData(const QMimeData *data);
|
||||||
|
@ -68,6 +72,7 @@ signals:
|
||||||
void insertText(QString text);
|
void insertText(QString text);
|
||||||
void textChanged(QString newText);
|
void textChanged(QString newText);
|
||||||
void uploadingChanged(bool value);
|
void uploadingChanged(bool value);
|
||||||
|
void containsAtRoomChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void emote(QString body, bool rainbowify);
|
void emote(QString body, bool rainbowify);
|
||||||
|
@ -105,11 +110,14 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateAtRoom(const QString &t);
|
||||||
|
|
||||||
QTimer typingRefresh_;
|
QTimer typingRefresh_;
|
||||||
QTimer typingTimeout_;
|
QTimer typingTimeout_;
|
||||||
TimelineModel *room;
|
TimelineModel *room;
|
||||||
std::deque<QString> history_;
|
std::deque<QString> history_;
|
||||||
std::size_t history_index_ = 0;
|
std::size_t history_index_ = 0;
|
||||||
int selectionStart = 0, selectionEnd = 0, cursorPosition = 0;
|
int selectionStart = 0, selectionEnd = 0, cursorPosition = 0;
|
||||||
bool uploading_ = false;
|
bool uploading_ = false;
|
||||||
|
bool containsAtRoom_ = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -61,3 +61,10 @@ Permissions::canSend(int eventType)
|
||||||
pl.event_level(to_string(qml_mtx_events::fromRoomEventType(
|
pl.event_level(to_string(qml_mtx_events::fromRoomEventType(
|
||||||
static_cast<qml_mtx_events::EventType>(eventType))));
|
static_cast<qml_mtx_events::EventType>(eventType))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Permissions::canPingRoom()
|
||||||
|
{
|
||||||
|
return pl.user_level(http::client()->user_id().to_string()) >=
|
||||||
|
pl.notification_level(mtx::events::state::notification_keys::room);
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ public:
|
||||||
Q_INVOKABLE bool canChange(int eventType);
|
Q_INVOKABLE bool canChange(int eventType);
|
||||||
Q_INVOKABLE bool canSend(int eventType);
|
Q_INVOKABLE bool canSend(int eventType);
|
||||||
|
|
||||||
|
Q_INVOKABLE bool canPingRoom();
|
||||||
|
|
||||||
void invalidate();
|
void invalidate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue