From b206015e7005a8368cde25724b50da520697c818 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 20 Jun 2017 15:33:28 +0200 Subject: [PATCH 1/3] libresapi: expose identity avatar in JSON API The avatar is sent as a base64 string The solution is not optimal but is the best we can do inside a JSON and it's acceptable for the moment --- libresapi/src/api/IdentityHandler.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 13332487a..6b7e1d05d 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include "Operators.h" @@ -500,6 +501,11 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) RsIdentityDetails details; mRsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId), details); + + std::string base64Avatar; + Radix64::encode(details.mAvatar.mData, details.mAvatar.mSize, base64Avatar); + resp.mDataStream << makeKeyValue("avatar", base64Avatar); + StreamBase& usagesStream = resp.mDataStream.getStreamToMember("usages"); usagesStream.getStreamToMember(); From 8c62c2a32632e693993d976be770180b45b28037 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 20 Jun 2017 15:35:05 +0200 Subject: [PATCH 2/3] Qml app: show contact avatar in details if available --- retroshare-qml-app/src/ContactDetails.qml | 70 ++++++++++++++++++++--- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/retroshare-qml-app/src/ContactDetails.qml b/retroshare-qml-app/src/ContactDetails.qml index 7b7cfedf8..ff14ff338 100644 --- a/retroshare-qml-app/src/ContactDetails.qml +++ b/retroshare-qml-app/src/ContactDetails.qml @@ -26,22 +26,64 @@ Item id: cntDt property var md property bool is_contact: cntDt.md.is_contact + property bool has_avatar: false - ColorHash + property int avatarAttemptCnt: 0 + function getDetails() { - id: colorHash + ++cntDt.avatarAttemptCnt + rsApi.request( + "/identity/get_identity_details", + JSON.stringify({ gxs_id: cntDt.md.gxs_id }), + function(par) + { + var jData = JSON.parse(par.response).data + setDetails(jData) + if(!cntDt.has_avatar && avatarAttemptCnt < 3) + getDetails() + }) + } + function setDetails(data) + { + cntDt.has_avatar = data.avatar.length > 0 + if(cntDt.has_avatar) + { + contactAvatar.source = + "data:image/png;base64," + data.avatar + } + } + + Component.onCompleted: getDetails() + + Item + { + id: topFace + + height: 130 + width: 130 anchors.top: parent.top anchors.topMargin: 6 anchors.horizontalCenter: parent.horizontalCenter - height: 150 - hash: cntDt.md.gxs_id + Image + { + id: contactAvatar + anchors.fill: parent + visible: cntDt.has_avatar + } + + ColorHash + { + anchors.fill: parent + visible: !cntDt.has_avatar + hash: cntDt.md.gxs_id + } } Column { - anchors.top: colorHash.bottom + anchors.top: topFace.bottom anchors.topMargin: 6 anchors.horizontalCenter: parent.horizontalCenter @@ -61,7 +103,6 @@ Item Image { - source: cntDt.is_contact ? "qrc:/icons/rating.png" : "qrc:/icons/rating-unrated.png" @@ -86,10 +127,23 @@ Item } } - Text + Row { - text: "
"+cntDt.md.gxs_id+"
" + ColorHash + { + hash: cntDt.md.gxs_id + height: 30 + visible: cntDt.has_avatar + } + + Text + { + text: "
"+cntDt.md.gxs_id+"
" + y: 5 + } + anchors.horizontalCenter: parent.horizontalCenter + spacing: 5 } Text From 1d031910cb46ce73abd076748dd283d2bdf91907 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 20 Jun 2017 17:16:27 +0200 Subject: [PATCH 3/3] Created a dedicated component for avatar image --- retroshare-qml-app/src/AvatarOrColorHash.qml | 76 ++++++++++++++++++++ retroshare-qml-app/src/ContactDetails.qml | 71 +++--------------- retroshare-qml-app/src/qml.qrc | 1 + 3 files changed, 88 insertions(+), 60 deletions(-) create mode 100644 retroshare-qml-app/src/AvatarOrColorHash.qml diff --git a/retroshare-qml-app/src/AvatarOrColorHash.qml b/retroshare-qml-app/src/AvatarOrColorHash.qml new file mode 100644 index 000000000..0cf09a9c4 --- /dev/null +++ b/retroshare-qml-app/src/AvatarOrColorHash.qml @@ -0,0 +1,76 @@ +/* + * RetroShare Android QML App + * Copyright (C) 2017 Gioacchino Mazzurco + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.7 + + +Item +{ + id: compRoot + + property string gxs_id + + height: 130 + width: height + + +////////////// The following should be considered privates ///////////////////// + + property bool has_avatar: false + property int avatarAttemptCnt: 0 + function getDetails() + { + ++compRoot.avatarAttemptCnt + rsApi.request( + "/identity/get_identity_details", + JSON.stringify({ gxs_id: compRoot.gxs_id }), + function(par) + { + var jData = JSON.parse(par.response).data + setDetails(jData) + if(!compRoot.has_avatar && + compRoot.avatarAttemptCnt < 3) getDetails() + }) + } + function setDetails(data) + { + compRoot.has_avatar = data.avatar.length > 0 + if(compRoot.has_avatar) + { + contactAvatar.source = + "data:image/png;base64," + data.avatar + } + } + + Component.onCompleted: if(visible && !has_avatar) getDetails() + onVisibleChanged: if(visible && !has_avatar) getDetails() + + Image + { + id: contactAvatar + anchors.fill: parent + visible: compRoot.has_avatar + } + + ColorHash + { + anchors.fill: parent + visible: !compRoot.has_avatar + hash: compRoot.gxs_id + } +} diff --git a/retroshare-qml-app/src/ContactDetails.qml b/retroshare-qml-app/src/ContactDetails.qml index ff14ff338..e66b267a9 100644 --- a/retroshare-qml-app/src/ContactDetails.qml +++ b/retroshare-qml-app/src/ContactDetails.qml @@ -26,59 +26,16 @@ Item id: cntDt property var md property bool is_contact: cntDt.md.is_contact - property bool has_avatar: false - property int avatarAttemptCnt: 0 - function getDetails() - { - ++cntDt.avatarAttemptCnt - rsApi.request( - "/identity/get_identity_details", - JSON.stringify({ gxs_id: cntDt.md.gxs_id }), - function(par) - { - var jData = JSON.parse(par.response).data - setDetails(jData) - if(!cntDt.has_avatar && avatarAttemptCnt < 3) - getDetails() - }) - } - function setDetails(data) - { - cntDt.has_avatar = data.avatar.length > 0 - if(cntDt.has_avatar) - { - contactAvatar.source = - "data:image/png;base64," + data.avatar - } - } - - Component.onCompleted: getDetails() - - Item + AvatarOrColorHash { id: topFace - height: 130 - width: 130 + gxs_id: cntDt.md.gxs_id anchors.top: parent.top anchors.topMargin: 6 anchors.horizontalCenter: parent.horizontalCenter - - Image - { - id: contactAvatar - anchors.fill: parent - visible: cntDt.has_avatar - } - - ColorHash - { - anchors.fill: parent - visible: !cntDt.has_avatar - hash: cntDt.md.gxs_id - } } Column @@ -95,6 +52,13 @@ Item anchors.horizontalCenter: parent.horizontalCenter spacing: 6 + ColorHash + { + hash: cntDt.md.gxs_id + height: parent.height - 10 + anchors.verticalCenter: parent.verticalCenter + } + Text { text: cntDt.md.name @@ -127,23 +91,10 @@ Item } } - Row + Text { - ColorHash - { - hash: cntDt.md.gxs_id - height: 30 - visible: cntDt.has_avatar - } - - Text - { - text: "
"+cntDt.md.gxs_id+"
" - y: 5 - } - + text: "
"+cntDt.md.gxs_id+"
" anchors.horizontalCenter: parent.horizontalCenter - spacing: 5 } Text diff --git a/retroshare-qml-app/src/qml.qrc b/retroshare-qml-app/src/qml.qrc index 3859fde54..61bcfd8d1 100644 --- a/retroshare-qml-app/src/qml.qrc +++ b/retroshare-qml-app/src/qml.qrc @@ -29,5 +29,6 @@ icons/rating-unrated.png icons/rating.png TimedPopup.qml + AvatarOrColorHash.qml