feat: list preferred username, available ens names and send preferred username on new messages
This commit is contained in:
parent
43f4f8775b
commit
40e8802218
|
@ -53,7 +53,7 @@ QtObject:
|
||||||
let userWallet = status_settings.getSetting[string](Setting.WalletRootAddress, "0x0")
|
let userWallet = status_settings.getSetting[string](Setting.WalletRootAddress, "0x0")
|
||||||
let pubkey = status_ens.pubkey(ens)
|
let pubkey = status_ens.pubkey(ens)
|
||||||
if ownerAddr != "":
|
if ownerAddr != "":
|
||||||
if pubkey == "":
|
if pubkey == "" and ownerAddr == userWallet:
|
||||||
output = "owned" # "Continuing will connect this username with your chat key."
|
output = "owned" # "Continuing will connect this username with your chat key."
|
||||||
elif pubkey == userPubkey:
|
elif pubkey == userPubkey:
|
||||||
output = "connected"
|
output = "connected"
|
||||||
|
@ -65,13 +65,24 @@ QtObject:
|
||||||
output = "taken"
|
output = "taken"
|
||||||
output
|
output
|
||||||
|
|
||||||
proc connect(self: EnsManager, username: string) {.slot.} =
|
proc add*(self: EnsManager, username: string) =
|
||||||
let ensUsername = username & status_ens.domain
|
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, @[])
|
var usernames = status_settings.getSetting[seq[string]](Setting.Usernames, @[])
|
||||||
let preferredUsername = status_settings.getSetting[string](Setting.PreferredUsername, "")
|
|
||||||
usernames.add ensUsername
|
usernames.add ensUsername
|
||||||
discard status_settings.saveSetting(Setting.Usernames, %*usernames)
|
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 =
|
method rowCount(self: EnsManager, index: QModelIndex = nil): int =
|
||||||
return self.usernames.len
|
return self.usernames.len
|
||||||
|
@ -88,8 +99,3 @@ QtObject:
|
||||||
{
|
{
|
||||||
EnsRoles.UserName.int:"username"
|
EnsRoles.UserName.int:"username"
|
||||||
}.toTable
|
}.toTable
|
||||||
|
|
||||||
proc add*(self: EnsManager, username: string) =
|
|
||||||
self.beginInsertRows(newQModelIndex(), self.usernames.len, self.usernames.len)
|
|
||||||
self.usernames.add(username)
|
|
||||||
self.endInsertRows()
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ proc isDeviceSetup*():bool =
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc syncAllDevices*() =
|
proc syncAllDevices*() =
|
||||||
discard syncDevices()
|
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
|
||||||
|
discard syncDevices(preferredUsername)
|
||||||
|
|
||||||
proc advertise*() =
|
proc advertise*() =
|
||||||
discard sendPairInstallation()
|
discard sendPairInstallation()
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import json, times, strutils, sequtils, chronicles
|
import json, times, strutils, sequtils, chronicles, json_serialization
|
||||||
import core, utils
|
import core, utils
|
||||||
import ../chat/[chat, message]
|
import ../chat/[chat, message]
|
||||||
import ../../signals/messages
|
import ../../signals/messages
|
||||||
import ./types
|
import ./types
|
||||||
|
import ./settings
|
||||||
|
|
||||||
proc buildFilter*(chat: Chat):JsonNode =
|
proc buildFilter*(chat: Chat):JsonNode =
|
||||||
if chat.chatType == ChatType.PrivateGroupChat:
|
if chat.chatType == ChatType.PrivateGroupChat:
|
||||||
|
@ -72,34 +73,38 @@ proc generateSymKeyFromPassword*(): string =
|
||||||
]))["result"]).strip(chars = {'"'})
|
]))["result"]).strip(chars = {'"'})
|
||||||
|
|
||||||
proc sendChatMessage*(chatId: string, msg: string, replyTo: string, contentType: int): string =
|
proc sendChatMessage*(chatId: string, msg: string, replyTo: string, contentType: int): string =
|
||||||
|
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
|
||||||
callPrivateRPC("sendChatMessage".prefix, %* [
|
callPrivateRPC("sendChatMessage".prefix, %* [
|
||||||
{
|
{
|
||||||
"chatId": chatId,
|
"chatId": chatId,
|
||||||
"text": msg,
|
"text": msg,
|
||||||
"responseTo": replyTo,
|
"responseTo": replyTo,
|
||||||
"ensName": nil,
|
"ensName": preferredUsername,
|
||||||
"sticker": nil,
|
"sticker": nil,
|
||||||
"contentType": contentType
|
"contentType": contentType
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
proc sendImageMessage*(chatId: string, image: string): string =
|
proc sendImageMessage*(chatId: string, image: string): string =
|
||||||
|
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
|
||||||
callPrivateRPC("sendChatMessage".prefix, %* [
|
callPrivateRPC("sendChatMessage".prefix, %* [
|
||||||
{
|
{
|
||||||
"chatId": chatId,
|
"chatId": chatId,
|
||||||
"contentType": ContentType.Image.int,
|
"contentType": ContentType.Image.int,
|
||||||
"imagePath": image,
|
"imagePath": image,
|
||||||
|
"ensName": preferredUsername,
|
||||||
"text": "Update to latest version to see a nice image here!"
|
"text": "Update to latest version to see a nice image here!"
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
proc sendStickerMessage*(chatId: string, sticker: Sticker): string =
|
proc sendStickerMessage*(chatId: string, sticker: Sticker): string =
|
||||||
|
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
|
||||||
callPrivateRPC("sendChatMessage".prefix, %* [
|
callPrivateRPC("sendChatMessage".prefix, %* [
|
||||||
{
|
{
|
||||||
"chatId": chatId,
|
"chatId": chatId,
|
||||||
"text": "Update to latest version to see a nice sticker here!",
|
"text": "Update to latest version to see a nice sticker here!",
|
||||||
"responseTo": nil,
|
"responseTo": nil,
|
||||||
"ensName": nil,
|
"ensName": preferredUsername,
|
||||||
"sticker": {
|
"sticker": {
|
||||||
"hash": sticker.hash,
|
"hash": sticker.hash,
|
||||||
"pack": sticker.packId
|
"pack": sticker.packId
|
||||||
|
|
|
@ -14,9 +14,7 @@ proc getOurInstallations*(useCached: bool = true): JsonNode =
|
||||||
dirty = false
|
dirty = false
|
||||||
result = installations
|
result = installations
|
||||||
|
|
||||||
proc syncDevices*(): string =
|
proc syncDevices*(preferredName: string): string =
|
||||||
# These are not being used at the moment
|
|
||||||
let preferredName = ""
|
|
||||||
let photoPath = ""
|
let photoPath = ""
|
||||||
result = callPrivateRPC("syncDevices".prefix, %* [preferredName, photoPath])
|
result = callPrivateRPC("syncDevices".prefix, %* [preferredName, photoPath])
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,93 @@ import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.14
|
||||||
import "../../../../../imports"
|
import "../../../../../imports"
|
||||||
import "../../../../../shared"
|
import "../../../../../shared"
|
||||||
|
import "../../../Chat/ChatColumn/MessageComponents"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property var onClick: function(){}
|
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 {
|
StyledText {
|
||||||
id: sectionTitle
|
id: sectionTitle
|
||||||
//% "ENS usernames"
|
//% "ENS usernames"
|
||||||
|
@ -51,27 +134,136 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: sview
|
StyledText {
|
||||||
clip: true
|
id: usernamesLabel
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
text: qsTr("Your usernames")
|
||||||
contentHeight: contentItem.childrenRect.height
|
anchors.left: parent.left
|
||||||
anchors.top: addUsername.bottom
|
anchors.top: addUsername.bottom
|
||||||
anchors.topMargin: Style.current.padding
|
anchors.topMargin: 24
|
||||||
anchors.bottom: parent.bottom
|
font.pixelSize: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.top: usernamesLabel.bottom
|
||||||
|
anchors.topMargin: 10
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
height: 200
|
||||||
|
id: ensList
|
||||||
|
|
||||||
Item {
|
ScrollView {
|
||||||
id: contentItem
|
anchors.fill: parent
|
||||||
anchors.right: parent.right;
|
Layout.fillWidth: true
|
||||||
anchors.left: parent.left;
|
Layout.fillHeight: true
|
||||||
|
|
||||||
StyledText {
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||||
id: title
|
ScrollBar.vertical.policy: lvEns.contentHeight > lvEns.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||||
text: "TODO: Show ENS username list"
|
|
||||||
anchors.top: parent.top
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -12,31 +12,33 @@ Item {
|
||||||
property string validationMessage: ""
|
property string validationMessage: ""
|
||||||
property bool valid: false
|
property bool valid: false
|
||||||
property bool isStatus: true
|
property bool isStatus: true
|
||||||
|
property bool loading: false
|
||||||
property string ensStatus: ""
|
property string ensStatus: ""
|
||||||
|
|
||||||
property var validateENS: Backpressure.debounce(searchENS, 500, function (ensName, isStatus){
|
property var validateENS: Backpressure.debounce(searchENS, 500, function (ensName, isStatus){
|
||||||
profileModel.ens.validate(ensName, isStatus)
|
profileModel.ens.validate(ensName, isStatus)
|
||||||
});
|
});
|
||||||
|
|
||||||
function validate() {
|
function validate(ensUsername) {
|
||||||
validationMessage = "";
|
validationMessage = "";
|
||||||
valid = false;
|
valid = false;
|
||||||
ensStatus = "";
|
ensStatus = "";
|
||||||
if (ensUsername.text.length < 4) {
|
if (ensUsername.length < 4) {
|
||||||
validationMessage = qsTr("At least 4 characters. Latin letters, numbers, and lowercase only.");
|
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.");
|
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")
|
validationMessage = qsTr("Type the entire username including the custom domain like username.domain.eth")
|
||||||
}
|
}
|
||||||
return validationMessage === "";
|
return validationMessage === "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKeyReleased(){
|
function onKeyReleased(ensUsername){
|
||||||
if (!validate()) {
|
if (!validate(ensUsername)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Qt.callLater(validateENS, ensUsername.text, isStatus)
|
loading = true;
|
||||||
|
Qt.callLater(validateENS, ensUsername, isStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
@ -60,8 +62,26 @@ Item {
|
||||||
radius: 120
|
radius: 120
|
||||||
color: Style.current.blue
|
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 {
|
StyledText {
|
||||||
text: "@"
|
visible: ensStatus !== "taken"
|
||||||
|
text: {
|
||||||
|
if((ensStatus === "available" || ensStatus === "connected" || ensStatus === "connected-different-key")){
|
||||||
|
return "✓"
|
||||||
|
} else {
|
||||||
|
return "@"
|
||||||
|
}
|
||||||
|
}
|
||||||
opacity: 0.7
|
opacity: 0.7
|
||||||
font.weight: Font.Bold
|
font.weight: Font.Bold
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
|
@ -79,13 +99,15 @@ Item {
|
||||||
anchors.right: btnContinue.left
|
anchors.right: btnContinue.left
|
||||||
anchors.rightMargin: 24
|
anchors.rightMargin: 24
|
||||||
Keys.onReleased: {
|
Keys.onReleased: {
|
||||||
onKeyReleased();
|
onKeyReleased(ensUsername.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: profileModel.ens
|
target: profileModel.ens
|
||||||
onEnsWasResolved: {
|
onEnsWasResolved: {
|
||||||
|
if(!validate(ensUsername.text)) return;
|
||||||
valid = false;
|
valid = false;
|
||||||
|
loading = false;
|
||||||
ensStatus = ensResult;
|
ensStatus = ensResult;
|
||||||
switch(ensResult){
|
switch(ensResult){
|
||||||
case "available":
|
case "available":
|
||||||
|
@ -139,7 +161,7 @@ Item {
|
||||||
if(!valid) return;
|
if(!valid) return;
|
||||||
|
|
||||||
if(ensStatus === "connected"){
|
if(ensStatus === "connected"){
|
||||||
profileModel.ens.connect(ensUsername.text);
|
profileModel.ens.connect(ensUsername.text, isStatus);
|
||||||
onClick(ensStatus, ensUsername.text);
|
onClick(ensStatus, ensUsername.text);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -188,8 +210,9 @@ Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked : {
|
onClicked : {
|
||||||
isStatus = !isStatus;
|
isStatus = !isStatus;
|
||||||
if(validate())
|
let ensUser = ensUsername.text;
|
||||||
validateENS(ensUsername.text, isStatus)
|
if(validate(ensUser))
|
||||||
|
validateENS(ensUser, isStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 |
Loading…
Reference in New Issue