From 73eb4fe8b161362ba6ffccb475bbac0a16499993 Mon Sep 17 00:00:00 2001 From: Pascal Precht Date: Thu, 11 Jun 2020 10:22:20 +0200 Subject: [PATCH] feat: introduce button to block users Closes #158 --- src/app/chat/view.nim | 3 ++ src/status/chat.nim | 8 ++++ src/status/libstatus/chat.nim | 14 +++++++ src/status/profile.nim | 17 ++++++--- .../Chat/components/ProfilePopup.qml | 37 +++++++++++++++---- ui/shared/ModalPopup.qml | 23 ++++++------ ui/shared/StyledButton.qml | 4 ++ 7 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/app/chat/view.nim b/src/app/chat/view.nim index 1a8c95503d..e1c4b3a605 100644 --- a/src/app/chat/view.nim +++ b/src/app/chat/view.nim @@ -132,3 +132,6 @@ QtObject: if(self.activeChannel.id == chat.id): self.activeChannel.setChatItem(chat) self.activeChannelChanged() + + proc blockContact*(self: ChatsView, id: string): string {.slot.} = + return self.status.chat.blockContact(id) diff --git a/src/status/chat.nim b/src/status/chat.nim index 08571add36..7ba717dff3 100644 --- a/src/status/chat.nim +++ b/src/status/chat.nim @@ -1,6 +1,8 @@ import eventemitter, json import sequtils import libstatus/chat as status_chat +import libstatus/core as libstatus_core +import ./profile as status_profile import chronicles import chat/[chat, message] import ../signals/messages @@ -158,3 +160,9 @@ proc confirmJoiningGroup*(self: ChatModel, chatId: string) = var response = parseJson(status_chat.confirmJoiningGroup(chatId)) var (chats, messages) = formatChatUpdate(response) self.events.emit("pushMessage", PushMessageArgs(messages: messages, chats: chats)) + +proc blockContact*(self: ChatModel, id: string): string = + var contact = status_profile.getContactByID(id) + contact.systemTags.add(":contact/blocked") + result = status_chat.blockContact(contact) + diff --git a/src/status/libstatus/chat.nim b/src/status/libstatus/chat.nim index 2f2cdb0ee1..48aa23b707 100644 --- a/src/status/libstatus/chat.nim +++ b/src/status/libstatus/chat.nim @@ -6,6 +6,7 @@ import strutils import chronicles import ../chat/[chat, message] import ../../signals/messages +import ../profile proc buildFilter*(chatId: string, filterId: string = "", symKeyId: string = "", oneToOne: bool = false, identity: string = "", topic: string = "", discovery: bool = false, negotiated: bool = false, listen: bool = true):JsonNode = result = %* { @@ -106,6 +107,19 @@ proc sendChatMessage*(chatId: string, msg: string): string = } ]) +proc blockContact*(contact: Profile): string = + callPrivateRPC("blockContact".prefix, %* [ + { + "id": contact.id, + "ensVerified": contact.ensVerified, + "ensVerifiedAt": contact.ensVerifiedAt, + "ensVerificationRetries": contact.ensVerificationRetries, + "alias": contact.alias, + "identicon": contact.identicon, + "systemTags": contact.systemTags + } + ]) + proc markAllRead*(chatId: string): string = callPrivateRPC("markAllRead".prefix, %* [chatId]) diff --git a/src/status/profile.nim b/src/status/profile.nim index e7ec747c0e..1cc0d3d245 100644 --- a/src/status/profile.nim +++ b/src/status/profile.nim @@ -16,7 +16,8 @@ type Profile* = ref object id*, alias*, username*, identicon*: string ensVerified*: bool ensVerifiedAt*: int - ensVerificationEntries*: int + ensVerificationRetries*: int + systemTags*: seq[string] proc toProfileModel*(account: Account): Profile = result = Profile( @@ -26,10 +27,15 @@ proc toProfileModel*(account: Account): Profile = alias: account.name, ensVerified: false, ensVerifiedAt: 0, - ensVerificationEntries: 0, + ensVerificationRetries: 0, + systemTags: @[] ) proc toProfileModel*(profile: JsonNode): Profile = + var systemTags: seq[string] = @[] + if profile["systemTags"].kind != JNull: + systemTags = profile["systemTags"].to(seq[string]) + result = Profile( id: profile["id"].str, username: profile["alias"].str, @@ -37,14 +43,13 @@ proc toProfileModel*(profile: JsonNode): Profile = alias: profile["alias"].str, ensVerified: profile["ensVerified"].getBool, ensVerifiedAt: profile["ensVerifiedAt"].getInt, - ensVerificationEntries: profile["ensVerificationEntries"].getInt + ensVerificationRetries: profile["ensVerificationRetries"].getInt, + systemTags: systemTags ) - proc getContactByID*(id: string): Profile = let response = libstatus_core.getContactByID(id) - let val = parseJSON($response) - result = toProfileModel(val) + result = toProfileModel(parseJSON($response)["result"]) type ProfileModel* = ref object diff --git a/ui/app/AppLayouts/Chat/components/ProfilePopup.qml b/ui/app/AppLayouts/Chat/components/ProfilePopup.qml index 5b383a1ec9..1b44c99bbd 100644 --- a/ui/app/AppLayouts/Chat/components/ProfilePopup.qml +++ b/ui/app/AppLayouts/Chat/components/ProfilePopup.qml @@ -194,13 +194,36 @@ ModalPopup { // } // } - footer: StyledButton { - anchors.right: parent.right - anchors.rightMargin: Theme.smallPadding - label: "Add to contacts" - anchors.bottom: parent.bottom - onClicked: { - profilePopup.close() + footer: Item { + width: parent.width + height: children[0].height + + StyledButton { + anchors.right: parent.right + anchors.rightMargin: addToContactsButton.width + 32 + btnColor: "white" + btnBorderWidth: 1 + btnBorderColor: "#EEF2F5" + textColor: "#FF2D55" + label: "Block User" + anchors.bottom: parent.bottom + onClicked: { + chatsModel.blockContact(fromAuthor) + // TODO(pascal): Change block user button state based + // on :contact/blocked state + profilePopup.close() + } } + + StyledButton { + id: addToContactsButton + anchors.right: parent.right + anchors.rightMargin: Theme.smallPadding + label: "Add to contacts" + anchors.bottom: parent.bottom + onClicked: { + profilePopup.close() + } + } } } diff --git a/ui/shared/ModalPopup.qml b/ui/shared/ModalPopup.qml index 0b11f6ba20..024dd4cade 100644 --- a/ui/shared/ModalPopup.qml +++ b/ui/shared/ModalPopup.qml @@ -114,16 +114,17 @@ Popup { } Item { - id: footerContent - height: children[0] && children[0].height - width: parent.width - anchors.top: separator2.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.bottomMargin: Theme.padding - anchors.rightMargin: Theme.padding - anchors.leftMargin: Theme.padding + id: footerContent + height: children[0] && children[0].height + width: parent.width + anchors.top: separator2.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.topMargin: Theme.padding + anchors.bottomMargin: Theme.padding + anchors.rightMargin: Theme.padding + anchors.leftMargin: Theme.padding } - } + } } diff --git a/ui/shared/StyledButton.qml b/ui/shared/StyledButton.qml index ef3b9e8d1a..ef032db250 100644 --- a/ui/shared/StyledButton.qml +++ b/ui/shared/StyledButton.qml @@ -8,6 +8,8 @@ import "../imports" Button { property string label: "My button" property color btnColor: Theme.lightBlue + property color btnBorderColor: "transparent" + property int btnBorderWidth: 0 property color textColor: Theme.blue property bool disabled: false @@ -20,6 +22,8 @@ Button { color: disabled ? Theme.grey : btnStyled.btnColor radius: Theme.radius anchors.fill: parent + border.color: btnBorderColor + border.width: btnBorderWidth } Text {