diff --git a/messages.cpp b/messages.cpp index b9ed9bf1..28e5f101 100644 --- a/messages.cpp +++ b/messages.cpp @@ -200,7 +200,7 @@ QHash MessagesModel::roleNames() const return ret; } -void MessagesModel::sendMessage(const QString& message, const QString &replyTo, const QStringList& attachments) +void MessagesModel::sendMessageFull(const QString& message, const QString &replyTo, const QStringList& attachments, const SendAs& as) { ClientContext ctx; client->authenticate(ctx); @@ -220,6 +220,27 @@ void MessagesModel::sendMessage(const QString& message, const QString &replyTo, req.add_attachments(attachment.toStdString()); } + if (std::holds_alternative(as)) { + + } else if (std::holds_alternative(as)) { + auto& fronter = std::get(as); + + auto override = new protocol::core::v1::Override(); + override->set_name(fronter.name.toStdString()); + override->set_allocated_system_plurality(new google::protobuf::Empty{}); + + req.set_allocated_overrides(override); + + } else if (std::holds_alternative(as)) { + auto& character = std::get(as); + + auto override = new protocol::core::v1::Override(); + override->set_name(character.name.toStdString()); + override->set_user_defined("Roleplay"); + + req.set_allocated_overrides(override); + } + protocol::core::v1::SendMessageResponse empty; client->coreKit->SendMessage(&ctx, req, &empty); diff --git a/messages.hpp b/messages.hpp index fb0798b0..1a18b330 100644 --- a/messages.hpp +++ b/messages.hpp @@ -124,6 +124,16 @@ class MessagesModel : public QAbstractListModel MessageCombinedAuthorIDAvatarRole }; + struct Fronter { + QString name; + }; + struct RoleplayCharacter { + QString name; + }; + + using Nobody = std::monostate; + using SendAs = std::variant; + protected: Q_INVOKABLE void customEvent(QEvent *event) override; @@ -138,7 +148,23 @@ class MessagesModel : public QAbstractListModel Q_INVOKABLE bool isOwner() { return isGuildOwner; } Q_INVOKABLE QString userID() { return QString::number(client->userID); } Q_INVOKABLE QVariantMap peekMessage(const QString& id); - Q_INVOKABLE void sendMessage(const QString& content, const QString& replyTo, const QStringList& attachments); + Q_INVOKABLE void sendMessageFull(const QString& content, const QString& replyTo, const QStringList& attachments, const SendAs& as); + Q_INVOKABLE void sendMessage(const QString& content, const QString& replyTo, const QStringList& attachments) + { + sendMessageFull(content, replyTo, attachments, SendAs(Nobody{})); + } + Q_INVOKABLE void sendMessageAsSystem(const QString& content, const QString& replyTo, const QStringList& attachments, const QString& memberName) + { + sendMessageFull(content, replyTo, attachments, SendAs(Fronter { + .name = memberName + })); + } + Q_INVOKABLE void sendMessageAsRoleplay(const QString& content, const QString& replyTo, const QStringList& attachments, const QString& characterName) + { + sendMessageFull(content, replyTo, attachments, SendAs(RoleplayCharacter { + .name = characterName + })); + } Q_INVOKABLE void editMessage(const QString& id, const QString& content); Q_INVOKABLE void deleteMessage(const QString& id); Q_INVOKABLE void triggerAction(const QString& messageID, const QString& name, const QString& data); diff --git a/resources/ComposeBar.qml b/resources/ComposeBar.qml index e7329e0e..12db1657 100644 --- a/resources/ComposeBar.qml +++ b/resources/ComposeBar.qml @@ -107,6 +107,15 @@ QQC2.ToolBar { Layout.fillWidth: true } RowLayout { + QQC2.ComboBox { + id: settingsCombo + model: [{ + "name": qsTr("Default"), + "kind": "default" + }].concat(uiSettings.personas) + visible: uiSettings.personas.length > 0 + textRole: "name" + } QQC2.TextField { id: messageField //: Placeholder text for the message field @@ -115,7 +124,18 @@ QQC2.ToolBar { Layout.fillWidth: true function send() { - Kirigami.PageRouter.data.sendMessage(text, replyingBar.replyingToID, []) + if (uiSettings.personas.length == 0) { + Kirigami.PageRouter.data.sendMessage(text, replyingBar.replyingToID, []) + } else { + switch (settingsCombo.model[settingsCombo.currentIndex].kind) { + case "default": + Kirigami.PageRouter.data.sendMessage(text, replyingBar.replyingToID, []); break + case "roleplay": + Kirigami.PageRouter.data.sendMessageAsRoleplay(text, replyingBar.replyingToID, [], settingsCombo.model[settingsCombo.currentIndex].name); break + case "plurality": + Kirigami.PageRouter.data.sendMessageAsSystem(text, replyingBar.replyingToID, [], settingsCombo.model[settingsCombo.currentIndex].name); break + } + } text = "" replyingBar.replyingToID = "" } diff --git a/resources/MurmurSettings.qml b/resources/MurmurSettings.qml new file mode 100644 index 00000000..6d22ae0d --- /dev/null +++ b/resources/MurmurSettings.qml @@ -0,0 +1,100 @@ +// SPDX-FileCopyrightText: 2020 Carson Black +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +import QtQuick 2.10 +import QtQuick.Window 2.10 +import QtQuick.Layouts 1.10 +import org.kde.kirigami 2.13 as Kirigami +import QtQuick.Controls 2.10 as QQC2 +import com.github.HarmonyDevelopment.Staccato 1.0 + +Kirigami.Page { + id: invitePage + title: qsTr("Settings") + padding: 0 + Kirigami.Theme.colorSet: Kirigami.Theme.View + + Kirigami.SwipeNavigator { + anchors.fill: parent + + Kirigami.ScrollablePage { + //: Personas are alternate identities; e.g. for roleplay reasons + title: qsTr("Personas") + actions.main: Kirigami.Action { + text: qsTr("New Persona") + iconName: "list-add" + onTriggered: personaAddSheet.begin() + } + + Kirigami.OverlaySheet { + id: personaAddSheet + parent: root + + Kirigami.FormLayout { + QQC2.TextField { + id: nameField + + Kirigami.FormData.label: qsTr("Persona Name:") + } + QQC2.ComboBox { + id: reasonField + model: [ + { + "uiString": qsTr("Roleplay"), + "id": "roleplay" + }, + { + "uiString": "System Member", + "id": "plurality" + } + ] + textRole: "uiString" + Kirigami.FormData.label: qsTr("Persona Kind:") + } + QQC2.Button { + text: qsTr("Create") + onClicked: { + let settings = uiSettings.personas + settings.push({ + "name": nameField.text, + "kind": reasonField.model[reasonField.currentIndex].id + }) + uiSettings.personas = settings + personaAddSheet.close() + } + } + } + + function begin() { + nameField.text = "" + reasonField.currentIndex = 0 + this.open() + } + } + + ListView { + model: uiSettings.personas + delegate: Kirigami.SwipeListItem { + id: personaDelegate + + contentItem: QQC2.Label { + text: modelData["name"] + verticalAlignment: Text.AlignVCenter + } + actions: [ + Kirigami.Action { + icon.name: "edit-delete" + onTriggered: { + let a = uiSettings.personas + print(index) + a.splice(index) + uiSettings.personas = a + } + } + ] + } + } + } + } +} diff --git a/resources/StaccatoDrawer.qml b/resources/StaccatoDrawer.qml index ed5f4895..29ea8364 100644 --- a/resources/StaccatoDrawer.qml +++ b/resources/StaccatoDrawer.qml @@ -68,6 +68,10 @@ Item { Menu { id: appMenu + MenuItem { + text: qsTr("Settings") + onTriggered: root.pageStack.layers.push(Qt.resolvedUrl("MurmurSettings.qml"), {}) + } MenuItem { text: qsTr("Log Out") onTriggered: routerInstance.navigateToRoute("login") diff --git a/resources/UISettings.qml b/resources/UISettings.qml new file mode 100644 index 00000000..15955054 --- /dev/null +++ b/resources/UISettings.qml @@ -0,0 +1,5 @@ +import Qt.labs.settings 1.0 as Labs + +Labs.Settings { + property var personas: [] +} diff --git a/resources/data.qrc b/resources/data.qrc index dcef331c..b84f9ea3 100644 --- a/resources/data.qrc +++ b/resources/data.qrc @@ -15,6 +15,9 @@ RecursiveMenuActionComponent.qml RightDrawer.qml StaccatoDrawer.qml + MurmurSettings.qml + UISettings.qml + qmldir com.github.Harmony.Murmur.svg diff --git a/resources/main.qml b/resources/main.qml index 10b7fc10..25b61c18 100644 --- a/resources/main.qml +++ b/resources/main.qml @@ -13,6 +13,8 @@ Kirigami.ApplicationWindow { minimumWidth: 300 width: 1000 + UISettings { id: uiSettings } + pageStack.globalToolBar.showNavigationButtons: 0 pageStack.initialPage: Kirigami.Page { padding: 0 diff --git a/resources/qmldir b/resources/qmldir new file mode 100644 index 00000000..e69de29b