Skip to content

Commit

Permalink
Add /alert chat command
Browse files Browse the repository at this point in the history
This command can be used by operators to send high-priority alert
messages. The chat window will be automatically opened when this
message is received.
  • Loading branch information
callaa committed Aug 3, 2022
1 parent 411891b commit e58fd55
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 13 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Added animation timeline editor
* Added screen blend mode
* Disabled built-in server pending rewrite
* Added `/alert` chat command

2021-09-12 Version 2.1.20
* Updated Portugese translations
Expand Down
5 changes: 5 additions & 0 deletions src/desktop/chat/chatbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ ChatBox::ChatBox(Document *doc, QWidget *parent)

connect(m_chatWidget, &ChatWidget::message, this, &ChatBox::message);
connect(m_chatWidget, &ChatWidget::detachRequested, this, &ChatBox::detachFromParent);
connect(m_chatWidget, &ChatWidget::expandRequested, this, [this]() {
if(m_state == State::Collapsed) {
emit expandPlease();
}
});

connect(doc, &Document::canvasChanged, this, &ChatBox::onCanvasChanged);
connect(doc, &Document::serverLoggedIn, this, &ChatBox::onServerLogin);
Expand Down
3 changes: 3 additions & 0 deletions src/desktop/chat/chatbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ private slots:
//! The chatbox was either expanded or collapsed
void expandedChanged(bool isExpanded);

//! Request that the chatbox be expanded
void expandPlease();

//! Detached chat box should be re-attached and reparented (or it will be destroyed)
void reattachNowPlease();

Expand Down
62 changes: 51 additions & 11 deletions src/desktop/chat/chatwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct Chat {
"color: #eff0f1;"
"margin: 1px 0 1px 0"
"}"
".alert { background: #da4453 }"
".shout { background: #34292c }"
".shout .tab { background: #da4453 }"
".action { font-style: italic }"
Expand All @@ -71,6 +72,7 @@ struct Chat {
".op { color: #f47750 }"
".mod { color: #ed1515 }"
".timestamp { color: #8d8d8d }"
".alert .timestamp { color: #eff0f1 }"
"a:link { color: #1d99f3 }"
);
}
Expand All @@ -79,6 +81,7 @@ struct Chat {
void appendMessage(int userId, const QString &usernameSpan, const QString &message, bool shout);
void appendMessageCompact(int userId, const QString &usernameSpan, const QString &message, bool shout);
void appendAction(const QString &usernameSpan, const QString &message);
void appendAlert(const QString &usernameSpan, const QString &message);
void appendNotification(const QString &message);
};

Expand Down Expand Up @@ -418,6 +421,32 @@ void Chat::appendMessage(int userId, const QString &usernameSpan, const QString
lastMessageTs = ts;
}

void Chat::appendAlert(const QString &usernameSpan, const QString &message)
{
QTextCursor cursor(doc);
cursor.movePosition(QTextCursor::End);

lastAppendedId = -2;

cursor.insertHtml(QStringLiteral(
"<table width=\"100%\" class=\"message alert\">"
"<tr>"
"<td width=3 rowspan=2 class=tab></td>"
"<td>%1</td>"
"<td class=timestamp align=right>%2</td>"
"</tr>"
"<tr>"
"<td colspan=2>%3</td>"
"</tr>"
"</table>"
).arg(
usernameSpan,
timestamp(),
htmlutils::newlineToBr(message)
)
);
}

void Chat::appendAction(const QString &usernameSpan, const QString &message)
{
QTextCursor cursor(doc);
Expand Down Expand Up @@ -557,15 +586,15 @@ void ChatWidget::receiveMessage(int sender, int recipient, uint8_t tflags, uint8
Q_ASSERT(d->chats.contains(chatId));
Chat &chat = d->chats[chatId];

if(oflags & rustpile::ChatMessage_OFLAGS_ACTION) {
if(tflags & rustpile::ChatMessage_TFLAGS_ALERT) {
chat.appendAlert(d->usernameSpan(sender), safetext);
emit expandRequested();
} else if(oflags & rustpile::ChatMessage_OFLAGS_ACTION)
chat.appendAction(d->usernameSpan(sender), safetext);

} else {
if(d->compactMode)
chat.appendMessageCompact(sender, d->usernameSpan(sender), safetext, oflags & rustpile::ChatMessage_OFLAGS_SHOUT);
else
chat.appendMessage(sender, d->usernameSpan(sender), safetext, oflags & rustpile::ChatMessage_OFLAGS_SHOUT);
}
else if(d->compactMode)
chat.appendMessageCompact(sender, d->usernameSpan(sender), safetext, oflags & rustpile::ChatMessage_OFLAGS_SHOUT);
else
chat.appendMessage(sender, d->usernameSpan(sender), safetext, oflags & rustpile::ChatMessage_OFLAGS_SHOUT);

if(chatId != d->currentChat) {
for(int i=0;i<d->tabs->count();++i) {
Expand All @@ -590,16 +619,20 @@ void ChatWidget::setPinnedMessage(const QString &message)

void ChatWidget::systemMessage(const QString& message, bool alert)
{
Q_UNUSED(alert);
const bool wasAtEnd = d->isAtEnd();
d->publicChat().appendNotification(message.toHtmlEscaped());
if(alert) {
d->publicChat().appendAlert(QString(), message);
emit expandRequested();
} else
d->publicChat().appendNotification(message.toHtmlEscaped());

if(wasAtEnd)
d->scrollToEnd(0);
}

void ChatWidget::sendMessage(const QString &msg)
{
const uint8_t tflags = d->preserveChat ? rustpile::ChatMessage_TFLAGS_BYPASS : 0;
uint8_t tflags = d->preserveChat ? rustpile::ChatMessage_TFLAGS_BYPASS : 0;
uint8_t oflags = 0;
auto chatmsg = msg;

Expand All @@ -623,6 +656,12 @@ void ChatWidget::sendMessage(const QString &msg)
oflags = rustpile::ChatMessage_OFLAGS_SHOUT;
}

} else if(cmd == QStringLiteral("alert")) {
if(msg.length() > 2) {
chatmsg = params;
tflags |= rustpile::ChatMessage_TFLAGS_ALERT;
}

} else if(cmd == QStringLiteral("me")) {
if(!params.isEmpty()) {
oflags = rustpile::ChatMessage_OFLAGS_ACTION;
Expand Down Expand Up @@ -656,6 +695,7 @@ void ChatWidget::sendMessage(const QString &msg)
"/help - show this message\n"
"/clear - clear chat window\n"
"/! <text> - make an announcement (recorded in session history)\n"
"/alert <text> - send a high priority alert\n"
"/me <text> - send action type message\n"
"/pin <text> - pin a message to the top of the chat box (Ops only)\n"
"/unpin - remove pinned message\n"
Expand Down
1 change: 1 addition & 0 deletions src/desktop/chat/chatwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ private slots:
signals:
void message(const net::Envelope &msg);
void detachRequested();
void expandRequested();

private:
struct Private;
Expand Down
1 change: 1 addition & 0 deletions src/desktop/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2539,6 +2539,7 @@ void MainWindow::setupActions()

connect(m_chatbox, &widgets::ChatBox::expandedChanged, toggleChat, &QAction::setChecked);
connect(m_chatbox, &widgets::ChatBox::expandedChanged, m_statusChatButton, &QToolButton::hide);
connect(m_chatbox, &widgets::ChatBox::expandPlease, toggleChat, &QAction::trigger);
connect(toggleChat, &QAction::triggered, this, [this](bool show) {
QList<int> sizes;
if(show) {
Expand Down
6 changes: 5 additions & 1 deletion src/dpcore/src/protocol/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ pub struct ChatMessage {

impl ChatMessage {
pub const TFLAGS_BYPASS: u8 = 0x1;
pub const TFLAGS: &'static [&'static str] = &["bypass"];
pub const TFLAGS_ALERT: u8 = 0x2;
pub const TFLAGS: &'static [&'static str] = &["bypass", "alert"];
pub const OFLAGS_SHOUT: u8 = 0x1;
pub const OFLAGS_ACTION: u8 = 0x2;
pub const OFLAGS_PIN: u8 = 0x4;
Expand Down Expand Up @@ -1690,6 +1691,9 @@ pub enum CommandMessage {
/// Specifying a sublayer requires session operator privileges. Currently, it is used
/// only when sublayers are needed at canvas initialization.
///
/// Note: the `fixed` flag is unused since version 2.2. It's functionality is replaced
/// by the custom timeline feature.
///
LayerAttributes(u8, LayerAttributesMessage),

/// Change a layer's title
Expand Down
2 changes: 1 addition & 1 deletion src/dpcore/src/protocol/protocol.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Chat:
(Typically a Command message is used for server announcements, but the Chat message
is used for those messages that must be stored in the session history.)
fields:
- tflags flags: [bypass]
- tflags flags: [bypass, alert]
- oflags flags: [shout, action, pin]
- message utf8

Expand Down
2 changes: 2 additions & 0 deletions src/libserver/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,8 @@ void Session::handleClientMessage(Client &client, protocol::MessagePtr msg)
case protocol::MSG_CHAT: {
if(client.isMuted())
return;
if(!client.isOperator() && msg.cast<protocol::Chat>().isAlert())
return;
if(msg.cast<protocol::Chat>().isBypass()) {
directToAll(msg);
return;
Expand Down
6 changes: 6 additions & 0 deletions src/libshared/net/meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class Chat : public Message {
public:
// Transparent flags: these affect serverside behavior
static const uint8_t FLAG_BYPASS = 0x01; // bypass session history and send directly to logged in users
static const uint8_t FLAG_ALERT = 0x02; // high priority alert (can be send by operators only)

// Opaque flags: the server doesn't know anything about these
static const uint8_t FLAG_SHOUT = 0x01; // public announcement
Expand Down Expand Up @@ -197,6 +198,11 @@ class Chat : public Message {
*/
bool isBypass() const { return m_tflags & FLAG_BYPASS; }

/**
* @brief Is this an alert message?
*/
bool isAlert() const { return m_tflags & FLAG_ALERT; }

/**
* @brief Is this a shout?
*
Expand Down
2 changes: 2 additions & 0 deletions src/rustpile/rustpile.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ static const uint8_t ChatMessage_OFLAGS_PIN = 4;

static const uint8_t ChatMessage_OFLAGS_SHOUT = 1;

static const uint8_t ChatMessage_TFLAGS_ALERT = 2;

static const uint8_t ChatMessage_TFLAGS_BYPASS = 1;

enum class AnimationExportMode {
Expand Down

0 comments on commit e58fd55

Please sign in to comment.