feat: Adding new user profile cards for link previews

This commit is contained in:
Alex Jbanca 2023-09-18 13:30:19 +03:00 committed by Alex Jbanca
parent fb4f77b9bb
commit 7c8436f492
7 changed files with 201 additions and 8 deletions

View File

@ -201,7 +201,7 @@ const asyncGetLinkPreviewDataTask: Task = proc(argEncoded: string) {.gcsafe, nim
let isSupportedImage = any(parsedWhiteListImgExtensions, proc (extenstion: string): bool = path.endsWith(extenstion))
let isListed = parsedWhiteListUrls.hasKey(domain)
let isProfileLink = path.startsWith(profileLinkPrefix)
let processUrl = not isProfileLink and (isListed or isSupportedImage)
let processUrl = isListed or isSupportedImage
if domain == "" or processUrl == false:
continue

View File

@ -266,5 +266,8 @@
],
"UserAgreementPopup": [
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=31450-560694&t=Q4MOViPCoHsTjhs6-0"
],
"UserProfileCard": [
"https://www.figma.com/file/Mr3rqxxgKJ2zMQ06UAKiWL/💬-Chat⎜Desktop?type=design&node-id=21961-655678&mode=design&t=JiMnPfMaLPWlrFK3-0"
]
}

View File

@ -0,0 +1,84 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import shared.controls.chat 1.0
import utils 1.0
SplitView {
id: root
property bool globalUtilsReady: false
// globalUtilsInst mock
QtObject {
function getEmojiHashAsJson(publicKey) {
return JSON.stringify(["👨🏻‍🍼", "🏃🏿‍♂️", "🌇", "🤶🏿", "🏮","🤷🏻‍♂️", "🤦🏻", "📣", "🤎", "👷🏽", "😺", "🥞", "🔃", "🧝🏽‍♂️"])
}
function getColorId(publicKey) { return 4 }
function getCompressedPk(publicKey) { return "zx3sh" + publicKey }
function getColorHashAsJson(publicKey) {
return JSON.stringify([{4: 0, segmentLength: 1},
{5: 19, segmentLength: 2}])
}
function isCompressedPubKey(publicKey) { return true }
Component.onCompleted: {
Utils.globalUtilsInst = this
root.globalUtilsReady = true
}
Component.onDestruction: {
root.globalUtilsReady = false
Utils.globalUtilsInst = {}
}
}
Pane {
SplitView.fillWidth: true
SplitView.fillHeight: true
Loader {
anchors.centerIn: parent
active: root.globalUtilsReady
sourceComponent: UserProfileCard {
id: userProfileCard
userName: nameInput.text
userPublicKey: "0x1234567890"
userBio: bioInput.text
userImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
ensVerified: false
}
}
}
Pane {
SplitView.fillWidth: true
SplitView.fillHeight: true
SplitView.minimumWidth: 300
ColumnLayout {
Label {
text: "userName"
}
TextField {
id: nameInput
text: "John Doe"
}
Label {
text: "userBio"
}
TextField {
id: bioInput
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor."
}
}
}
}

View File

@ -0,0 +1,78 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import shared.status 1.0
import shared.controls 1.0
import shared.controls.chat 1.0
import utils 1.0
CalloutCard {
id: root
required property string userName
required property string userPublicKey
required property string userBio
required property var userImage
required property bool ensVerified
signal clicked()
implicitWidth: 305
implicitHeight: 187
padding: 12
contentItem: ColumnLayout {
spacing: 0
UserImage {
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
name: root.userName
pubkey: root.userPublicKey
image: root.userImage
interactive: false
imageWidth: 58
imageHeight: imageWidth
ensVerified: root.ensVerified
}
StatusBaseText {
id: contactName
Layout.fillWidth: true
Layout.topMargin: 12
font.pixelSize: Style.current.additionalTextSize
font.weight: Font.Medium
elide: Text.ElideRight
text: root.userName
}
EmojiHash {
Layout.fillWidth: true
Layout.topMargin: 4
publicKey: root.userPublicKey
oneRow: true
}
StatusBaseText {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: 15
font.pixelSize: Style.current.tertiaryTextFontSize
color: Theme.palette.baseColor1
text: root.userBio
wrapMode: Text.WordWrap
elide: Text.ElideRight
}
}
MouseArea {
anchors.fill: root
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.clicked()
}
}

View File

@ -3,6 +3,7 @@ FetchMoreMessagesButton 1.0 FetchMoreMessagesButton.qml
GapComponent 1.0 GapComponent.qml
LinkPreviewCard 1.0 LinkPreviewCard.qml
UsernameLabel 1.0 UsernameLabel.qml
UserProfileCard 1.0 UserProfileCard.qml
DateGroup 1.0 DateGroup.qml
UserImage 1.0 UserImage.qml
MessageMouseArea 1.0 MessageMouseArea.qml

View File

@ -7,6 +7,7 @@ import utils 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import shared.status 1.0
import shared.panels 1.0
@ -228,7 +229,7 @@ ColumnLayout {
required property bool success
required property bool isStatusDeepLink
readonly property bool isImage: result.contentType ? result.contentType.startsWith("image/") : false
readonly property bool isUserProfileLink: link.toLowerCase().startsWith(Constants.userLinkPrefix.toLowerCase())
readonly property string thumbnailUrl: result && result.thumbnailUrl ? result.thumbnailUrl : ""
readonly property string title: result && result.title ? result.title : ""
readonly property string hostname: result && result.site ? result.site : ""
@ -247,13 +248,13 @@ ColumnLayout {
name: "loadImage"
when: tempLoader.unfurl && tempLoader.isImage
PropertyChanges { target: tempLoader; sourceComponent: unfurledImageComponent }
},
State {
name: "userProfileLink"
when: unfurl && isUserProfileLink && isStatusDeepLink
PropertyChanges { target: tempLoader; sourceComponent: unfurledProfileLinkComponent }
}
// State {
// name: "loadLinkPreview"
// when: unfurl && !isImage && !isStatusDeepLink
// PropertyChanges { target: tempLoader; sourceComponent: unfurledLinkComponent }
// },
// State {
// name: "statusInvitation"
// when: unfurl && isStatusDeepLink
// PropertyChanges { target: tempLoader; sourceComponent: invitationBubble }
@ -263,6 +264,32 @@ ColumnLayout {
}
}
Component {
id: unfurledProfileLinkComponent
UserProfileCard {
id: unfurledProfileLink
readonly property var contact: Utils.parseContactUrl(parent.link)
readonly property var contactDetails: Utils.getContactDetailsAsJson(contact.publicKey)
readonly property string nickName: contactDetails ? contactDetails.localNickname : ""
readonly property string ensName: contactDetails ? contactDetails.name : ""
readonly property string displayName: contact && contact.displayName ? contact.displayName :
contactDetails && contactDetails.displayName ? contactDetails.displayName : ""
readonly property string aliasName: contactDetails ? contactDetails.alias : ""
leftTail: !root.isCurrentUser
userName: ProfileUtils.displayName(nickName, ensName, displayName, aliasName)
userPublicKey: contactDetails && contactDetails.publicKey ? contactDetails.publicKey : ""
userBio: contactDetails && contactDetails.bio ? contactDetails.bio : ""
userImage: contactDetails && contactDetails.thumbnailImage ? contactDetails.thumbnailImage : ""
ensVerified: contactDetails && contactDetails.ensVerified ? contactDetails.ensVerified : false
onClicked: {
Global.openProfilePopup(userPublicKey)
}
}
}
Component {
id: enableLinkComponent

View File

@ -71,7 +71,7 @@ Loader {
return []
const separator = " "
const arr = links.split(separator)
const filtered = arr.filter(v => v.toLowerCase().endsWith('.gif'))
const filtered = arr.filter(v => v.toLowerCase().endsWith('.gif') || v.toLowerCase().startsWith(Constants.userLinkPrefix.toLowerCase()))
const out = filtered.join(separator)
console.log(`<<<${arr}->${out}`)
return out