feat: list preferred username, available ens names and send preferred username on new messages

This commit is contained in:
Richard Ramos 2020-08-05 15:50:55 -04:00 committed by Pascal Precht
parent 43f4f8775b
commit 40e8802218
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
7 changed files with 272 additions and 44 deletions

View File

@ -53,7 +53,7 @@ QtObject:
let userWallet = status_settings.getSetting[string](Setting.WalletRootAddress, "0x0")
let pubkey = status_ens.pubkey(ens)
if ownerAddr != "":
if pubkey == "":
if pubkey == "" and ownerAddr == userWallet:
output = "owned" # "Continuing will connect this username with your chat key."
elif pubkey == userPubkey:
output = "connected"
@ -65,13 +65,24 @@ QtObject:
output = "taken"
output
proc connect(self: EnsManager, username: string) {.slot.} =
let ensUsername = username & status_ens.domain
proc add*(self: EnsManager, username: string) =
self.beginInsertRows(newQModelIndex(), self.usernames.len, self.usernames.len)
self.usernames.add(username)
self.endInsertRows()
proc connect(self: EnsManager, username: string, isStatus: bool) {.slot.} =
var ensUsername = username
if isStatus:
ensUsername = ensUsername & status_ens.domain
var usernames = status_settings.getSetting[seq[string]](Setting.Usernames, @[])
let preferredUsername = status_settings.getSetting[string](Setting.PreferredUsername, "")
usernames.add ensUsername
discard status_settings.saveSetting(Setting.Usernames, %*usernames)
discard status_settings.saveSetting(Setting.PreferredUsername, ensUsername)
if usernames.len == 1:
discard status_settings.saveSetting(Setting.PreferredUsername, ensUsername)
self.add ensUsername
proc preferredUsername(self: EnsManager): string {.slot.} =
result = status_settings.getSetting[string](Setting.PreferredUsername, "")
method rowCount(self: EnsManager, index: QModelIndex = nil): int =
return self.usernames.len
@ -88,8 +99,3 @@ QtObject:
{
EnsRoles.UserName.int:"username"
}.toTable
proc add*(self: EnsManager, username: string) =
self.beginInsertRows(newQModelIndex(), self.usernames.len, self.usernames.len)
self.usernames.add(username)
self.endInsertRows()

View File

@ -19,7 +19,8 @@ proc isDeviceSetup*():bool =
result = false
proc syncAllDevices*() =
discard syncDevices()
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
discard syncDevices(preferredUsername)
proc advertise*() =
discard sendPairInstallation()

View File

@ -1,8 +1,9 @@
import json, times, strutils, sequtils, chronicles
import json, times, strutils, sequtils, chronicles, json_serialization
import core, utils
import ../chat/[chat, message]
import ../../signals/messages
import ./types
import ./settings
proc buildFilter*(chat: Chat):JsonNode =
if chat.chatType == ChatType.PrivateGroupChat:
@ -72,34 +73,38 @@ proc generateSymKeyFromPassword*(): string =
]))["result"]).strip(chars = {'"'})
proc sendChatMessage*(chatId: string, msg: string, replyTo: string, contentType: int): string =
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
callPrivateRPC("sendChatMessage".prefix, %* [
{
"chatId": chatId,
"text": msg,
"responseTo": replyTo,
"ensName": nil,
"ensName": preferredUsername,
"sticker": nil,
"contentType": contentType
}
])
proc sendImageMessage*(chatId: string, image: string): string =
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
callPrivateRPC("sendChatMessage".prefix, %* [
{
"chatId": chatId,
"contentType": ContentType.Image.int,
"imagePath": image,
"ensName": preferredUsername,
"text": "Update to latest version to see a nice image here!"
}
])
proc sendStickerMessage*(chatId: string, sticker: Sticker): string =
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
callPrivateRPC("sendChatMessage".prefix, %* [
{
"chatId": chatId,
"text": "Update to latest version to see a nice sticker here!",
"responseTo": nil,
"ensName": nil,
"ensName": preferredUsername,
"sticker": {
"hash": sticker.hash,
"pack": sticker.packId

View File

@ -14,9 +14,7 @@ proc getOurInstallations*(useCached: bool = true): JsonNode =
dirty = false
result = installations
proc syncDevices*(): string =
# These are not being used at the moment
let preferredName = ""
proc syncDevices*(preferredName: string): string =
let photoPath = ""
result = callPrivateRPC("syncDevices".prefix, %* [preferredName, photoPath])

View File

@ -3,10 +3,93 @@ import QtQuick.Layouts 1.3
import QtQuick.Controls 2.14
import "../../../../../imports"
import "../../../../../shared"
import "../../../Chat/ChatColumn/MessageComponents"
Item {
property var onClick: function(){}
// Defaults to show message
property bool isMessage: true
property bool isEmoji: false
property bool isCurrentUser: false
property int contentType: 1
property string message: qsTr("Hey")
property string authorCurrentMsg: "0"
property string authorPrevMsg: "1"
property var clickMessage: function(){}
property string identicon: profileModel.profile.identicon
property int timestamp: 1577872140
Component {
id: statusENS
Item {
Text {
id: usernameTxt
text: username.substr(0, username.indexOf("."))
color: Style.current.textColor
}
Text {
anchors.top: usernameTxt.bottom
anchors.topMargin: 2
text: username.substr(username.indexOf("."))
color: Style.current.darkGrey
}
}
}
Component {
id: normalENS
Item {
Text {
id: usernameTxt
text: username
font.pixelSize: 16
color: Style.current.textColor
anchors.top: parent.top
anchors.topMargin: 5
}
}
}
Component {
id: ensDelegate
Item {
height: 45
Rectangle {
id: circle
width: 35
height: 35
radius: 35
color: Style.current.blue
StyledText {
text: "@"
opacity: 0.7
font.weight: Font.Bold
font.pixelSize: 16
color: Style.current.white
anchors.centerIn: parent
verticalAlignment: Text.AlignVCenter
anchors.verticalCenter: parent.verticalCenter
}
Loader {
sourceComponent: model.username.endsWith(".stateofus.eth") ? statusENS : normalENS
property string username: model.username
active: true
anchors.left: circle.right
anchors.leftMargin: Style.current.smallPadding
}
}
}
}
StyledText {
id: sectionTitle
//% "ENS usernames"
@ -51,27 +134,136 @@ Item {
}
}
ScrollView {
id: sview
clip: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
contentHeight: contentItem.childrenRect.height
StyledText {
id: usernamesLabel
text: qsTr("Your usernames")
anchors.left: parent.left
anchors.top: addUsername.bottom
anchors.topMargin: Style.current.padding
anchors.bottom: parent.bottom
anchors.topMargin: 24
font.pixelSize: 16
}
Item {
anchors.top: usernamesLabel.bottom
anchors.topMargin: 10
anchors.left: parent.left
anchors.right: parent.right
height: 200
id: ensList
Item {
id: contentItem
anchors.right: parent.right;
anchors.left: parent.left;
ScrollView {
anchors.fill: parent
Layout.fillWidth: true
Layout.fillHeight: true
StyledText {
id: title
text: "TODO: Show ENS username list"
anchors.top: parent.top
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: lvEns.contentHeight > lvEns.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
ListView {
id: lvEns
anchors.fill: parent
model: profileModel.ens
spacing: 10
clip: true
delegate: ensDelegate
}
}
}
Separator {
id: separator
anchors.topMargin: Style.current.padding
anchors.top: ensList.bottom
}
StyledText {
id: chatSettingsLabel
visible: profileModel.ens.rowCount() > 1
text: qsTr("Chat Settings")
anchors.left: parent.left
anchors.top: ensList.bottom
anchors.topMargin: 24
font.pixelSize: 16
}
StyledText {
id: usernameLabel
visible: chatSettingsLabel.visible
text: qsTr("Primary Username")
anchors.left: parent.left
anchors.top: chatSettingsLabel.bottom
anchors.topMargin: 24
font.pixelSize: 14
font.weight: Font.Bold
}
StyledText {
id: usernameLabel2
visible: chatSettingsLabel.visible
text: profileModel.ens.preferredUsername()
anchors.left: usernameLabel.right
anchors.leftMargin: Style.current.padding
anchors.top: chatSettingsLabel.bottom
anchors.topMargin: 24
font.pixelSize: 14
}
Item {
anchors.top: profileModel.ens.rowCount() == 1 ? separator.bottom : usernameLabel.bottom
anchors.topMargin: Style.current.padding * 2
UserImage {
id: chatImage
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.top: parent.top
anchors.topMargin: 20
}
UsernameLabel {
id: chatName
text: profileModel.ens.preferredUsername()
anchors.leftMargin: 20
anchors.top: parent.top
anchors.topMargin: 0
anchors.left: chatImage.right
}
Rectangle {
property int chatVerticalPadding: 7
property int chatHorizontalPadding: 12
id: chatBox
color: Style.current.secondaryBackground
height: 35
width: 80
radius: 16
anchors.left: chatImage.right
anchors.leftMargin: 8
anchors.top: chatImage.top
ChatText {
id: chatText
anchors.top: parent.top
anchors.topMargin: chatBox.chatVerticalPadding
anchors.left: parent.left
anchors.leftMargin: chatBox.chatHorizontalPadding
horizontalAlignment: Text.AlignLeft
color: Style.current.textColor
}
RectangleCorner {}
}
ChatTime {
id: chatTime
anchors.top: chatBox.bottom
anchors.topMargin: 4
anchors.bottomMargin: Style.current.padding
anchors.right: chatBox.right
anchors.rightMargin: Style.current.padding
}
}
}

View File

@ -12,31 +12,33 @@ Item {
property string validationMessage: ""
property bool valid: false
property bool isStatus: true
property bool loading: false
property string ensStatus: ""
property var validateENS: Backpressure.debounce(searchENS, 500, function (ensName, isStatus){
profileModel.ens.validate(ensName, isStatus)
});
function validate() {
function validate(ensUsername) {
validationMessage = "";
valid = false;
ensStatus = "";
if (ensUsername.text.length < 4) {
if (ensUsername.length < 4) {
validationMessage = qsTr("At least 4 characters. Latin letters, numbers, and lowercase only.");
} else if(isStatus && !ensUsername.text.match(/^[a-z0-9]+$/)){
} else if(isStatus && !ensUsername.match(/^[a-z0-9]+$/)){
validationMessage = qsTr("Letters and numbers only.");
} else if(!isStatus && !ensUsername.text.endsWith(".eth")){
} else if(!isStatus && !ensUsername.endsWith(".eth")){
validationMessage = qsTr("Type the entire username including the custom domain like username.domain.eth")
}
return validationMessage === "";
}
function onKeyReleased(){
if (!validate()) {
function onKeyReleased(ensUsername){
if (!validate(ensUsername)) {
return;
}
Qt.callLater(validateENS, ensUsername.text, isStatus)
loading = true;
Qt.callLater(validateENS, ensUsername, isStatus)
}
StyledText {
@ -60,8 +62,26 @@ Item {
radius: 120
color: Style.current.blue
SVGImage {
id: imgIcon
visible: ensStatus === "taken"
fillMode: Image.PreserveAspectFit
source: "../../../../img/block-icon-white.svg"
width: 20
height: 20
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "@"
visible: ensStatus !== "taken"
text: {
if((ensStatus === "available" || ensStatus === "connected" || ensStatus === "connected-different-key")){
return "✓"
} else {
return "@"
}
}
opacity: 0.7
font.weight: Font.Bold
font.pixelSize: 18
@ -79,13 +99,15 @@ Item {
anchors.right: btnContinue.left
anchors.rightMargin: 24
Keys.onReleased: {
onKeyReleased();
onKeyReleased(ensUsername.text);
}
Connections {
target: profileModel.ens
onEnsWasResolved: {
if(!validate(ensUsername.text)) return;
valid = false;
loading = false;
ensStatus = ensResult;
switch(ensResult){
case "available":
@ -139,7 +161,7 @@ Item {
if(!valid) return;
if(ensStatus === "connected"){
profileModel.ens.connect(ensUsername.text);
profileModel.ens.connect(ensUsername.text, isStatus);
onClick(ensStatus, ensUsername.text);
return;
}
@ -188,8 +210,9 @@ Item {
anchors.fill: parent
onClicked : {
isStatus = !isStatus;
if(validate())
validateENS(ensUsername.text, isStatus)
let ensUser = ensUsername.text;
if(validate(ensUser))
validateENS(ensUser, isStatus)
}
}
}

View File

@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.99967 13.6668C3.31778 13.6668 0.333008 10.6821 0.333008 7.00016C0.333008 3.31826 3.31778 0.333496 6.99967 0.333496C10.6816 0.333496 13.6663 3.31826 13.6663 7.00016C13.6663 10.6821 10.6816 13.6668 6.99967 13.6668ZM2.91208 10.3806C2.77375 10.519 2.54581 10.5094 2.42998 10.3518C1.74037 9.41312 1.33301 8.25421 1.33301 7.00016C1.33301 3.87055 3.87006 1.3335 6.99967 1.3335C8.25373 1.3335 9.41263 1.74086 10.3513 2.43047C10.509 2.5463 10.5185 2.77424 10.3802 2.91257L2.91208 10.3806ZM3.61919 11.0878C3.48086 11.2261 3.4904 11.454 3.64806 11.5699C4.58672 12.2595 5.74562 12.6668 6.99967 12.6668C10.1293 12.6668 12.6663 10.1298 12.6663 7.00016C12.6663 5.74611 12.259 4.5872 11.5694 3.64855C11.4535 3.49089 11.2256 3.48135 11.0873 3.61968L3.61919 11.0878Z" fill="#ffffff"/>
</svg>

After

Width:  |  Height:  |  Size: 922 B