diff --git a/retroshare-qml-app/src/ContactDetails.qml b/retroshare-qml-app/src/ContactDetails.qml
index 0336e74ca..2f9a799bf 100644
--- a/retroshare-qml-app/src/ContactDetails.qml
+++ b/retroshare-qml-app/src/ContactDetails.qml
@@ -27,6 +27,45 @@ Item
id: cntDt
property var md
property bool is_contact: cntDt.md.is_contact
+ property bool isOwn: cntDt.md.own
+
+ Button
+ {
+ id: avatarPicker
+
+ text: "Change your Avatar"
+ visible: isOwn
+
+ anchors.top: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ onClicked:
+ {
+ fileChooser.open()
+ }
+ CustomFileChooser
+ {
+ id: fileChooser
+ onResultFileChanged:
+ {
+ console.log("Result file changed! " , resultFile)
+
+ var base64Image = androidImagePicker.imageToBase64(resultFile)
+
+ rsApi.request("/identity/set_avatar", JSON.stringify({"gxs_id": cntDt.md.gxs_id, "avatar": base64Image }),
+ function (par)
+ {
+ var jP = JSON.parse(par.response)
+ if (jP.returncode === "ok")
+ {
+ console.log("Avatar changed! ")
+ topFace.getDetails()
+ }
+ })
+ }
+ }
+ }
+
AvatarOrColorHash
{
@@ -34,7 +73,7 @@ Item
gxs_id: cntDt.md.gxs_id
- anchors.top: parent.top
+ anchors.top: (isOwn)? avatarPicker.bottom : parent.top
anchors.topMargin: 6
anchors.horizontalCenter: parent.horizontalCenter
}
diff --git a/retroshare-qml-app/src/android/AndroidManifest.xml b/retroshare-qml-app/src/android/AndroidManifest.xml
index 321e1bd15..fb102300e 100644
--- a/retroshare-qml-app/src/android/AndroidManifest.xml
+++ b/retroshare-qml-app/src/android/AndroidManifest.xml
@@ -207,4 +207,8 @@
+
+
+
+
diff --git a/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/RetroShareQmlActivity.java b/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/RetroShareQmlActivity.java
index 8d3479f95..365778142 100644
--- a/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/RetroShareQmlActivity.java
+++ b/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/RetroShareQmlActivity.java
@@ -19,17 +19,25 @@
package org.retroshare.android.qml_app;
import android.app.ActivityManager;
+import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.database.Cursor;
import android.os.Bundle;
+import android.provider.MediaStore;
import android.util.Log;
+import android.net.Uri;
+
import org.qtproject.qt5.android.bindings.QtActivity;
import org.retroshare.android.qml_app.jni.NativeCalls;
public class RetroShareQmlActivity extends QtActivity
{
+
+ static final int PICK_PHOTO = 1;
+
@Override
public void onCreate(Bundle savedInstanceState)
{
@@ -84,4 +92,88 @@ public class RetroShareQmlActivity extends QtActivity
return true;
return false;
}
+
+ private Uri capturedImageURI;
+
+ public void openImagePicker()
+ {
+ Log.i("RetroShareQmlActivity", "openImagePicker()");
+
+ Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ pickIntent.setType("image/*");
+
+ ContentValues values = new ContentValues();
+ values.put(MediaStore.Images.Media.TITLE, "Retroshare Avatar");
+ capturedImageURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+ Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ takePicture.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageURI);
+
+ Intent chooserIntent = Intent.createChooser(pickIntent, "Select Image");
+ chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {takePicture});
+
+ startActivityForResult( chooserIntent, PICK_PHOTO);
+ };
+
+ public void onActivityResult(int requestCode, int resultCode, Intent data)
+ {
+ Log.i("RetroShareQmlActivity", "onActivityResult()" + String.valueOf(requestCode));
+
+ if (resultCode == RESULT_OK)
+ {
+ if (requestCode == PICK_PHOTO)
+ {
+ final boolean isCamera;
+
+ if (data == null)
+ {
+ isCamera = true;
+ }
+ else
+ {
+ final String action = data.getAction();
+ if (action == null)
+ {
+ isCamera = false;
+ }
+ else
+ {
+ isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
+ }
+ }
+
+ Uri selectedImageUri;
+ if (isCamera)
+ {
+ selectedImageUri = capturedImageURI;
+ }
+ else
+ {
+ selectedImageUri = data == null ? null : data.getData();
+ }
+
+ String uri = getRealPathFromURI(selectedImageUri);
+ if (uri != null)
+ {
+ Log.i("RetroShareQmlActivity", "Image path from uri found!" + uri);
+ NativeCalls.notifyIntentUri("//file"+uri); // Add the authority for get it on qml code
+ }
+ }
+ }
+ }
+
+ public String getRealPathFromURI(Uri uri) {
+ String[] projection = { MediaStore.Images.Media.DATA };
+ @SuppressWarnings("deprecation")
+ Cursor cursor = managedQuery(uri, projection, null, null, null);
+ int column_index = cursor
+ .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+ cursor.moveToFirst();
+ String result = cursor.getString(column_index);
+ return result;
+ }
+
+
+
+
+
}
diff --git a/retroshare-qml-app/src/androidimagepicker.h b/retroshare-qml-app/src/androidimagepicker.h
new file mode 100644
index 000000000..ad5f0e302
--- /dev/null
+++ b/retroshare-qml-app/src/androidimagepicker.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+
+#ifdef __ANDROID__
+# include
+# include
+#endif // __ANDROID__
+
+struct AndroidImagePicker : QObject
+{
+ Q_OBJECT
+
+public slots:
+
+ static void openPicker()
+ {
+ qDebug() << "Starting image picker intent";
+
+#ifdef __ANDROID__
+ QtAndroid::androidActivity().callMethod(
+ "openImagePicker",
+ "()V" );
+#endif // __ANDROID__
+
+ }
+
+ // Used to convert a given image path into a png base64 string
+ static QString imageToBase64 (QString const& path)
+ {
+ // Get local path from uri
+ QUrl url (path);
+ QString localPath = url.toLocalFile();
+
+ qDebug() << "imageToBase64() local path:" << localPath ;
+
+ // Read the image
+ QImageReader reader;
+ reader.setFileName(localPath);
+ QImage image = reader.read();
+
+ image = image.scaled(96,96,Qt::KeepAspectRatio,Qt::SmoothTransformation);
+
+ // Transform image into PNG format
+ QByteArray ba;
+ QBuffer buffer( &ba );
+ buffer.open( QIODevice::WriteOnly );
+ image.save( &buffer, "png" );
+
+ // Get Based 64 image string
+ QString encoded = QString(ba.toBase64());
+
+ qDebug() << "imageToBase64() encoded" ;
+
+ return encoded;
+
+ }
+};
diff --git a/retroshare-qml-app/src/components/CustomFileChooser.qml b/retroshare-qml-app/src/components/CustomFileChooser.qml
new file mode 100644
index 000000000..e7451dee5
--- /dev/null
+++ b/retroshare-qml-app/src/components/CustomFileChooser.qml
@@ -0,0 +1,60 @@
+import QtQuick 2.7
+import QtQuick.Dialogs 1.2
+
+import "../URI.js" as UriJs
+
+Item
+{
+ id: compRoot
+
+ property var resultFile
+
+ FileDialog
+ {
+ id: fileDialog
+ title: "Please choose a file"
+ folder: shortcuts.pictures
+ nameFilters: [ "Image files (*.png *.jpg)"]
+ visible: false
+ selectMultiple: false
+ onAccepted: {
+ console.log("You chose: " + fileDialog.fileUrl)
+ resultFile = fileDialog.fileUrl
+ }
+ onRejected: {
+ console.log("Canceled")
+ }
+ }
+
+
+ function open()
+ {
+ if (Qt.platform.os === "android")
+ {
+ console.log("ImagePicker Android platform detected")
+ mainWindow.addUriHandler("file", androidResult)
+ androidImagePicker.openPicker()
+ }
+ else
+ {
+ fileDialog.visible = true
+ }
+ }
+
+ function androidResult (uri)
+ {
+ console.log("QML Android image uri found" , uri)
+ resultFile = normalizeUriToFilePath (uri)
+ mainWindow.delUriHandler("media", androidResult)
+ }
+
+ function normalizeUriToFilePath (uriStr)
+ {
+ var uri = new UriJs.URI(uriStr)
+ var hPath = uri.path()
+ return "file:///"+hPath
+
+ }
+
+
+}
diff --git a/retroshare-qml-app/src/main-app.cpp b/retroshare-qml-app/src/main-app.cpp
index 5e5fd532f..b52febcfb 100644
--- a/retroshare-qml-app/src/main-app.cpp
+++ b/retroshare-qml-app/src/main-app.cpp
@@ -38,9 +38,9 @@
#include "libresapilocalclient.h"
#include "rsqmlappengine.h"
+#include "androidimagepicker.h"
#include "platforminteracions.h"
-
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@@ -52,6 +52,7 @@ int main(int argc, char *argv[])
"org.retroshare.qml_components.LibresapiLocalClient", 1, 0,
"LibresapiLocalClient");
+
QString sockPath = QDir::homePath() + "/.retroshare";
sockPath.append("/libresapi.sock");
@@ -61,6 +62,14 @@ int main(int argc, char *argv[])
RsQmlAppEngine engine(true);
QQmlContext& rootContext = *engine.rootContext();
+ qmlRegisterType(
+ "org.retroshare.qml_components.AndroidImagePicker", 1, 0,
+ "AndroidImagePicker");
+
+ AndroidImagePicker androidImagePicker;
+ engine.rootContext()->setContextProperty("androidImagePicker",
+ &androidImagePicker);
+
QStringList mainArgs = app.arguments();
#ifdef Q_OS_ANDROID
diff --git a/retroshare-qml-app/src/main-app.qml b/retroshare-qml-app/src/main-app.qml
index 889bf7ace..17634d741 100644
--- a/retroshare-qml-app/src/main-app.qml
+++ b/retroshare-qml-app/src/main-app.qml
@@ -364,7 +364,7 @@ ApplicationWindow
function handleIntentUri(uriStr)
{
- console.log("handleIntentUri(uriStr)")
+ console.log("handleIntentUri(uriStr)", uriStr)
if(!Array.isArray(uriStr.match(/:\/\/[a-zA-Z.-]*\//g)))
{
@@ -382,7 +382,10 @@ ApplicationWindow
var uri = new UriJs.URI(uriStr)
var hPath = uri.path() // no nesting ATM segmentCoded()
- console.log(hPath)
+ console.log("hPath", hPath)
+
+ var authority = uri.authority()
+ console.log("authority", authority)
if(typeof uriHandlersRegister[hPath] == "function")
{
@@ -390,6 +393,13 @@ ApplicationWindow
hPath, uriHandlersRegister[hPath])
uriHandlersRegister[hPath](uriStr)
}
+
+ else if (typeof uriHandlersRegister[authority] == "function" )
+ {
+ console.log("handleIntentUri(uriStr)", "found handler for path",
+ authority, uriHandlersRegister[authority])
+ uriHandlersRegister[authority](uriStr)
+ }
}
function certificateLinkHandler(uriStr)
diff --git a/retroshare-qml-app/src/qml.qrc b/retroshare-qml-app/src/qml.qrc
index 6332dc6da..fb2a636f0 100644
--- a/retroshare-qml-app/src/qml.qrc
+++ b/retroshare-qml-app/src/qml.qrc
@@ -53,5 +53,6 @@
components/emoji/emoji.js
icons/network-connect.svg
icons/network-disconnect.svg
+ components/CustomFileChooser.qml
diff --git a/retroshare-qml-app/src/retroshare-qml-app.pro b/retroshare-qml-app/src/retroshare-qml-app.pro
index 8dc2db67f..ff10bbc6b 100644
--- a/retroshare-qml-app/src/retroshare-qml-app.pro
+++ b/retroshare-qml-app/src/retroshare-qml-app.pro
@@ -6,6 +6,7 @@ CONFIG += c++11
HEADERS += libresapilocalclient.h \
rsqmlappengine.h \
+ androidimagepicker.h \
platforminteracions.h
SOURCES += main-app.cpp \
libresapilocalclient.cpp \