diff --git a/CHANGELOG.md b/CHANGELOG.md index d33bcbb..88ec35d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,3 +58,9 @@ * Fix for Friendica [issue 4689](https://github.com/friendica/friendica/issues/4689) * Long posts are automatically truncated * Intents for pictures (Send one image from gallery: attach to message, send multiple images: upload to album) + +## v0.2.2 ## +* Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5) +* Link to list of public server on Config Tab +* Small redesign of SendMessage page +* Intents for texts/urls (Send text or url from everywhere to create message) diff --git a/Friendiqa_v0.2.2.apk b/Friendiqa_v0.2.2.apk new file mode 100644 index 0000000..f04ea35 Binary files /dev/null and b/Friendiqa_v0.2.2.apk differ diff --git a/README.md b/README.md index 6e062f8..d269bbd 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Currently supported: * More shows older posts from local DB * Create new Message with images or direct messages, Contact/Group access rights(can be stored), smileys * Send image from Android gallery +* Send text or urls from other apps to Friendiqa * Native Android image dialog ToDo: diff --git a/source-android/android/AndroidManifest.xml b/source-android/android/AndroidManifest.xml index 841fac6..5f087d3 100644 --- a/source-android/android/AndroidManifest.xml +++ b/source-android/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + @@ -12,6 +12,11 @@ + + + + + diff --git a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java index 08ac034..dd2d3f1 100644 --- a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java +++ b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java @@ -21,14 +21,23 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt protected void onResume() { super.onResume(); - - if((getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_NEW_TASK) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)) { + + if((getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_NEW_TASK) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) || (getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))) { SystemDispatcher.onActivityResume(); } else { Intent data = getIntent(); - if ((data != null) && !(data.getBooleanExtra("used",false))){ - SystemDispatcher.loadClass("androidnative.ImagePicker"); - SystemDispatcher.onActivityResult(0x245285a3,Activity.RESULT_OK,data); + if ((data!=null) && (data.getType() != null) && !(data.getBooleanExtra("used",false))){ + String type = data.getType(); + String[] parts = type.split("/"); + String maintype= parts[0]; + if (maintype.equals("text")){ + SystemDispatcher.loadClass("androidnative.TextIntent"); + SystemDispatcher.onActivityResult(0x245285a4,Activity.RESULT_OK,data); + + } else { + SystemDispatcher.loadClass("androidnative.ImagePicker"); + SystemDispatcher.onActivityResult(0x245285a3,Activity.RESULT_OK,data); + } getIntent().replaceExtras(new Bundle()); getIntent().setAction(""); getIntent().setData(null); @@ -42,13 +51,25 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt protected void onNewIntent(Intent data) { super.onNewIntent(data); - SystemDispatcher.loadClass("androidnative.ImagePicker"); - SystemDispatcher.onActivityResult(0x245285a3,Activity.RESULT_OK,data); - getIntent().replaceExtras(new Bundle()); - getIntent().setAction(""); - getIntent().setData(null); - getIntent().setFlags(0); - getIntent().putExtra("used", true); + if ((data!=null) && (data.getType() != null) && !(data.getBooleanExtra("used",false))){ + String type = data.getType(); + String[] parts = type.split("/"); + String maintype= parts[0]; + if (maintype.equals("text")){ + SystemDispatcher.loadClass("androidnative.TextIntent"); + SystemDispatcher.onActivityResult(0x245285a4,Activity.RESULT_OK,data); + } else { + SystemDispatcher.loadClass("androidnative.ImagePicker"); + SystemDispatcher.onActivityResult(0x245285a3,Activity.RESULT_OK,data); + } + getIntent().replaceExtras(new Bundle()); + getIntent().setAction(""); + getIntent().setData(null); + getIntent().setFlags(0); + getIntent().putExtra("used", true); + } else { + SystemDispatcher.onActivityResume(); + } } // onNewIntent } diff --git a/source-android/androidnative.pri/java/src/androidnative/SystemDispatcher.java b/source-android/androidnative.pri/java/src/androidnative/SystemDispatcher.java index 3ba45e5..0f86233 100644 --- a/source-android/androidnative.pri/java/src/androidnative/SystemDispatcher.java +++ b/source-android/androidnative.pri/java/src/androidnative/SystemDispatcher.java @@ -17,8 +17,6 @@ import android.util.Log; import android.os.Handler; import android.os.Looper; import android.content.Intent; -//import android.content.*; -//import android.app.*; import android.os.*; import java.util.concurrent.Semaphore; import java.io.StringWriter; @@ -133,19 +131,21 @@ public class SystemDispatcher { */ public static void onActivityResult (int requestCode, int resultCode, Intent data) { Map message = new HashMap(); - + message.put("requestCode",requestCode); message.put("resultCode",resultCode); message.put("data",data); - if(isInitialized) { dispatch(ACTIVITY_RESULT_MESSAGE,message); waitingIntent=null; isIntentPending=false; } else { //onIntent start + message.put("text",data.getStringExtra(Intent.EXTRA_TEXT)); + message.put("subject",data.getStringExtra(Intent.EXTRA_SUBJECT)); waitingIntent = message; isIntentPending = true; + } //onIntent end @@ -216,7 +216,6 @@ public class SystemDispatcher { try { ClassLoader classLoader = SystemDispatcher.class.getClassLoader(); Class aClass = Class.forName(className,true,classLoader); -// Log.d(TAG,"Class Loaded: " + className); } catch (ClassNotFoundException e) { Log.e(TAG,"Failed to load class: " + className); e.printStackTrace(); diff --git a/source-android/androidnative.pri/java/src/androidnative/TextIntent.java b/source-android/androidnative.pri/java/src/androidnative/TextIntent.java new file mode 100644 index 0000000..96bd097 --- /dev/null +++ b/source-android/androidnative.pri/java/src/androidnative/TextIntent.java @@ -0,0 +1,59 @@ +package androidnative; +import org.qtproject.qt5.android.QtNative; +import android.content.Intent; +import android.app.Activity; +import java.util.Map; +import java.util.HashMap; +import android.os.Environment; +import android.util.Log; + +public class TextIntent { + + // Random + public static final int TEXT_INTENT_ACTION = 0x245285a4; + + public static final String CHOSEN_MESSAGE = "androidnative.TextIntent.chosen"; + + private static final String TAG = "androidnative.TextIntent"; + + private static Boolean broadcast = false; + + static { + SystemDispatcher.addListener(new SystemDispatcher.Listener() { + public void onDispatched(String type , Map message) { + if (type.equals(SystemDispatcher.ACTIVITY_RESULT_MESSAGE)) { + onActivityResult(message); + } + } + }); + } + + static private void onActivityResult(Map message) { + int resultCode = (Integer) message.get("resultCode"); + if (resultCode != Activity.RESULT_OK) + return; + int requestCode = (Integer) message.get("requestCode"); + Intent data = (Intent) message.get("data"); + + if (requestCode == TEXT_INTENT_ACTION) { + String extrasubject = (String) message.get("subject"); + String extratext = (String) message.get("text"); + importText(data,extrasubject,extratext); + } + } + + static private void importText(Intent data, String extrasubject, String extratext) { + + String subject = data.getStringExtra(Intent.EXTRA_SUBJECT); + String plaintext = data.getStringExtra(Intent.EXTRA_TEXT); + String htmltext = data.getStringExtra(Intent.EXTRA_HTML_TEXT); + if (subject==null){subject=extrasubject;}; + if (plaintext==null){plaintext=extratext;}; + Map reply = new HashMap(); + reply.put("subject",subject); + reply.put("plaintext",plaintext); + reply.put("htmltext",htmltext); + SystemDispatcher.dispatch(CHOSEN_MESSAGE,reply); + } +} + diff --git a/source-android/application.qrc b/source-android/application.qrc index 00e0a7c..1ac493d 100644 --- a/source-android/application.qrc +++ b/source-android/application.qrc @@ -218,5 +218,6 @@ qml/contactqml/ProfileComponent.qml translations/friendiqa-it.ts translations/friendiqa-it.qm + qml/genericqml/IntentReceiver.qml diff --git a/source-android/qml/configqml/ConfigTab.qml b/source-android/qml/configqml/ConfigTab.qml index 16b5917..9aef03d 100644 --- a/source-android/qml/configqml/ConfigTab.qml +++ b/source-android/qml/configqml/ConfigTab.qml @@ -59,8 +59,9 @@ StackView{ function setServericon(server){ try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){ - var serverdata = JSON.parse(obj); - servericon.source=serverdata.site.logo})} catch(e){print(e)} + var serverdata = JSON.parse(obj); + servericon.visible=true; + servericon.source=serverdata.site.logo})} catch(e){print(e)} } BlueButton{ @@ -127,6 +128,7 @@ StackView{ id:servericon x:19*mm;y:10*mm width:5*mm; height: 5*mm + visible: false source:"" MouseArea{ anchors.fill:parent @@ -137,6 +139,17 @@ StackView{ } } + BlueButton{ + id:serverSearchButton + text:"\uf002" + x:19*mm + y:10*mm + width: 5*mm; height:5*mm + visible: servericon.visible?false:true + onClicked:{Qt.openUrlExternally(Qt.resolvedUrl("https://dir.friendica.social/servers"))} + } + + Rectangle{color: "light grey"; x: 25*mm; y: 10*mm; width: root.width/2; height: 5*mm;} Flickable { id: servernameFlickable @@ -327,6 +340,7 @@ StackView{ filesystem.rmDir(); configBackground.registeredUser=true; servername.text="https://..."; + servericon.visible=false; servericon.source=""; username.text=""; password.text=""; @@ -349,6 +363,7 @@ StackView{ onClicked:{ configBackground.registeredUser=true; servername.text="https://..." + servericon.visible=false; servericon.source=""; username.text="" password.text="" diff --git a/source-android/qml/friendiqa.qml b/source-android/qml/friendiqa.qml index 6bf0e7d..cafaf92 100644 --- a/source-android/qml/friendiqa.qml +++ b/source-android/qml/friendiqa.qml @@ -36,11 +36,13 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.4 import "qrc:/js/news.js" as Newsjs import "qrc:/js/service.js" as Service +import "qrc:/qml/genericqml" TabView{ id:root property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettingsAndroid.qml");return tmp.createObject(root)} + IntentReceiver{} tabPosition: Qt.BottomEdge width: osSettings.appWidth height:osSettings.appHeight @@ -58,6 +60,7 @@ TabView{ signal contactdetailsSignal(var contact) signal eventSignal(var contact) signal uploadSignal(var urls) + signal sendtextSignal(var intenttext) property var news:[] property var newContacts:[] @@ -189,11 +192,11 @@ TabView{ id: configtab source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":"" } - Component.onCompleted: { - var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ - osSettings.imagePickQml+'{multiple : true; onReady: {'+ - 'if(imageUrls.length==1){root.currentIndex=0;newstab.active=true;root.uploadSignal(imageUrls)} else{'+ - ' root.currentIndex=2;fotostab.active=true;'+ - 'root.uploadSignal(imageUrls)};}}',root,"imagePicker"); - } +// Component.onCompleted: { +// var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ +// osSettings.imagePickQml+'{multiple : true; onReady: {'+ +// 'if(imageUrls.length==1){root.currentIndex=0;newstab.active=true;root.uploadSignal(imageUrls)} else{'+ +// ' root.currentIndex=2;fotostab.active=true;'+ +// 'root.uploadSignal(imageUrls)};}}',root,"imagePicker"); +// } } diff --git a/source-android/qml/genericqml/IntentReceiver.qml b/source-android/qml/genericqml/IntentReceiver.qml new file mode 100644 index 0000000..c39c742 --- /dev/null +++ b/source-android/qml/genericqml/IntentReceiver.qml @@ -0,0 +1,43 @@ +import QtQuick 2.0 +import AndroidNative 1.0 + +Item { + + /// The URL of the image chosen. If multiple images are picked, it will be equal to the first image. + property string imageUrl: "" + + /// A list of images chosen + property var imageUrls: [] + + property string m_TEXT_MESSAGE: "androidnative.TextIntent.chosen"; + property string m_IMAGE_MESSAGE: "androidnative.ImagePicker.chosen"; + + + Connections { + target: SystemDispatcher + onDispatched: { + if (type === m_IMAGE_MESSAGE) { + var h=[]; + for (var n in message.imageUrls){ + h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5)) + } + imageUrls=h; + if(imageUrls.length==1){ + root.currentIndex=0;newstab.active=true; + root.uploadSignal(imageUrls) + } else{ + root.currentIndex=2;fotostab.active=true; + root.uploadSignal(imageUrls) + } + } else if (type==m_TEXT_MESSAGE){ + root.currentIndex=0;newstab.active=true; + root.sendtextSignal(message) + } + } + } + + Component.onCompleted: { + SystemDispatcher.setInitialized(); + } +} + diff --git a/source-android/qml/genericqml/PermissionDialog.qml b/source-android/qml/genericqml/PermissionDialog.qml index 0d866b8..61a05cc 100644 --- a/source-android/qml/genericqml/PermissionDialog.qml +++ b/source-android/qml/genericqml/PermissionDialog.qml @@ -196,7 +196,7 @@ Rectangle{ anchors.bottomMargin:1 text:"\u2713" onClicked:{updatePerms(); - permissionDialog.destroy(); + permissionDialog.visible=false; } } diff --git a/source-android/qml/newsqml/MessageSend.qml b/source-android/qml/newsqml/MessageSend.qml index a238a78..935960f 100644 --- a/source-android/qml/newsqml/MessageSend.qml +++ b/source-android/qml/newsqml/MessageSend.qml @@ -47,6 +47,7 @@ Flickable{ id:messageSend property string parentId: "" property string reply_to_user:"" + property alias bodyMessage: bodyField.text property var attachImageURLs: []; property int directmessage: 0; property var contacts: [] @@ -58,7 +59,8 @@ Flickable{ function attachImage(url){ var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment'+attachImageURLs.length+'; source:"'+ - url.toString()+'"; width: 15*mm; height: 15*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+url+'"),1); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage"); + url.toString()+'"; x:2*mm; width: 45*mm; height: 45*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+ + url+'"),1); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage"); } function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { @@ -90,7 +92,7 @@ Flickable{ Column { id:messageColumn - spacing: 2 + spacing: 0.5*mm width: parent.width TextField { id: titleField @@ -99,14 +101,23 @@ Flickable{ visible: messageSend.parentId === "" } - TextArea { - id: bodyField - width: parent.width - height: 30*mm - wrapMode: TextEdit.Wrap - textFormat: TextEdit.PlainText + Rectangle{ + color: "white" + radius: 0.5*mm + x:mm + width: parent.width-2*mm + height:Math.max(bodyField.contentHeight+2*mm,10*mm) + TextArea { + id: bodyField + anchors.fill: parent + font.pixelSize: 3*mm + wrapMode: Text.Wrap + selectByMouse: true + textFormat: TextEdit.PlainText + } } + Row{ spacing: 2 CheckBox{ @@ -143,10 +154,9 @@ Flickable{ text:"\u2713" onClicked: {if(urlTextEdit.text!=""){ var start = bodyField.selectionStart; - var end = bodyField.selectionEnd; - var text = bodyField.getText(start,end); + var text=bodyField.selectedText text = "[url="+urlTextEdit.text+"]" + text + "[/url]"; - bodyField.remove(start,end); + bodyField.remove(start,bodyField.selectionEnd); bodyField.insert(start,text);} urlRectangle.visible=false} } @@ -158,13 +168,11 @@ Flickable{ BlueButton{id:permButton visible: (directmessage==1)?false:true text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" - onClicked: { - var component = Qt.createComponent("qrc:/qml/genericqml/PermissionDialog.qml"); - var permissions = component.createObject(messageColumn); - }} + onClicked: { permissionDialog.visible=true;} + } BlueButton { id: attachButton - text: "\uf0c6" + text: "\uf03e" visible:(directmessage==0) onClicked: { if (attachImageURLs.length>0){//Server currently accepts only one attachment @@ -189,27 +197,26 @@ Flickable{ if(Helperjs.getCount(db,login,"contacts","screen_name",contacts[i].screen_name)>1){ contacts[i].screen_name=contacts[i].screen_name+"+"+contacts[i].cid } - contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"';iconSource:'"+contacts[i].profile_image+"'; onTriggered: bodyField.insert(0,' @"+contacts[i].screen_name+" ')}" + contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"'; onTriggered: bodyField.insert(0,' @"+contacts[i].screen_name+" ')}" }} var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}"; - var contactlistObject=Qt.createQmlObject(menuString,messageSend,"contactmenuOutput") + var contactlistObject=Qt.createQmlObject(menuString,messageColumn,"contactmenuOutput") contactlistObject.popup() } } BlueButton{ id:smileyButton text: "\uf118" - onClicked: { - var smileyarray=Smileyjs.smileys - var component = Qt.createComponent("qrc:/qml/newsqml/SmileyDialog.qml"); - var smileydialog = component.createObject(messageColumn) - }} + onClicked: {smileyDialog.visible=true} + } BlueButton { id: cancelButton text: "\uf057" - onClicked: {newstab.newstabstatus=login.newsViewType; - newsStack.pop(null)} + onClicked: { + newstab.newstabstatus=login.newsViewType; + newsStack.pop(null) + } } BlueButton { id: sendButton @@ -224,7 +231,8 @@ Flickable{ } } } - + PermissionDialog{id:permissionDialog;x:mm;visible: false} + SmileyDialog{id:smileyDialog;x:mm;visible: false} } Component.onCompleted: if(attachImageURLs.length>0){attachImage(attachImageURLs[0])} } diff --git a/source-android/qml/newsqml/NewsTab.qml b/source-android/qml/newsqml/NewsTab.qml index 5db9a5c..c8bcb15 100644 --- a/source-android/qml/newsqml/NewsTab.qml +++ b/source-android/qml/newsqml/NewsTab.qml @@ -117,7 +117,14 @@ Item { function sendUrls(urls){ if((urls.length==1)&&(newsStack.depth<2)){ - newsStack.push([newslistRectangle,{item:"qrc:/qml/newsqml/MessageSend.qml",properties:{attachImageURLs:urls}}]) + newsStack.push([newslistRectangle,{item:"qrc:/qml/newsqml/MessageSend.qml",properties:{attachImageURLs:urls}}]) + } + } + + function sendtext(text){ + if(text&&(newsStack.depth<2)){ + if (text.subject=="undefined"){text.subject=""} + newsStack.push([newslistRectangle,{item:"qrc:/qml/newsqml/MessageSend.qml",properties:{bodyMessage:text.subject+"\n"+text.plaintext}}]) } } @@ -338,6 +345,7 @@ Item { root.directmessageSignal.connect(onDirectMessage); root.newsSignal.connect(showNews); root.uploadSignal.connect(sendUrls); + root.sendtextSignal.connect(sendtext); try{newsModel.clear()} catch(e){} //print("imageUrls "+JSON.stringify(imageUrls)+" newsstack.depth:"+newsStack.depth); diff --git a/source-android/qml/newsqml/SmileyDialog.qml b/source-android/qml/newsqml/SmileyDialog.qml index a0be90c..82ee0e9 100644 --- a/source-android/qml/newsqml/SmileyDialog.qml +++ b/source-android/qml/newsqml/SmileyDialog.qml @@ -49,7 +49,7 @@ Rectangle{ anchors.right: parent.right anchors.rightMargin: 1*mm text: "\uf057" - onClicked:{smileyDialog.destroy()} + onClicked:{smileyDialog.visible=false} } TabView{ @@ -164,7 +164,8 @@ Rectangle{ MouseArea{ anchors.fill: parent onClicked:{ - bodyField.append(emoji.name+" ") + //bodyField.append(emoji.name+" ") + bodyField.insert(bodyField.cursorPosition,emoji.name+" "); smileyDialog.destroy() } } diff --git a/source-linux/qml/configqml/ConfigTab.qml b/source-linux/qml/configqml/ConfigTab.qml index 16b5917..9aef03d 100644 --- a/source-linux/qml/configqml/ConfigTab.qml +++ b/source-linux/qml/configqml/ConfigTab.qml @@ -59,8 +59,9 @@ StackView{ function setServericon(server){ try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){ - var serverdata = JSON.parse(obj); - servericon.source=serverdata.site.logo})} catch(e){print(e)} + var serverdata = JSON.parse(obj); + servericon.visible=true; + servericon.source=serverdata.site.logo})} catch(e){print(e)} } BlueButton{ @@ -127,6 +128,7 @@ StackView{ id:servericon x:19*mm;y:10*mm width:5*mm; height: 5*mm + visible: false source:"" MouseArea{ anchors.fill:parent @@ -137,6 +139,17 @@ StackView{ } } + BlueButton{ + id:serverSearchButton + text:"\uf002" + x:19*mm + y:10*mm + width: 5*mm; height:5*mm + visible: servericon.visible?false:true + onClicked:{Qt.openUrlExternally(Qt.resolvedUrl("https://dir.friendica.social/servers"))} + } + + Rectangle{color: "light grey"; x: 25*mm; y: 10*mm; width: root.width/2; height: 5*mm;} Flickable { id: servernameFlickable @@ -327,6 +340,7 @@ StackView{ filesystem.rmDir(); configBackground.registeredUser=true; servername.text="https://..."; + servericon.visible=false; servericon.source=""; username.text=""; password.text=""; @@ -349,6 +363,7 @@ StackView{ onClicked:{ configBackground.registeredUser=true; servername.text="https://..." + servericon.visible=false; servericon.source=""; username.text="" password.text="" diff --git a/source-linux/qml/friendiqa.qml b/source-linux/qml/friendiqa.qml index 3432d25..7f00b02 100644 --- a/source-linux/qml/friendiqa.qml +++ b/source-linux/qml/friendiqa.qml @@ -36,11 +36,13 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.4 import "qrc:/js/news.js" as Newsjs import "qrc:/js/service.js" as Service +import "qrc:/qml/genericqml" TabView{ id:root property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettingsLinux.qml");return tmp.createObject(root)} + //IntentReceiver{} tabPosition: Qt.BottomEdge width: osSettings.appWidth height:osSettings.appHeight @@ -58,6 +60,7 @@ TabView{ signal contactdetailsSignal(var contact) signal eventSignal(var contact) signal uploadSignal(var urls) + signal sendtextSignal(var intenttext) property var news:[] property var newContacts:[] @@ -189,5 +192,11 @@ TabView{ id: configtab source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":"" } - +// Component.onCompleted: { +// var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ +// osSettings.imagePickQml+'{multiple : true; onReady: {'+ +// 'if(imageUrls.length==1){root.currentIndex=0;newstab.active=true;root.uploadSignal(imageUrls)} else{'+ +// ' root.currentIndex=2;fotostab.active=true;'+ +// 'root.uploadSignal(imageUrls)};}}',root,"imagePicker"); +// } } diff --git a/source-linux/qml/genericqml/IntentReceiver.qml b/source-linux/qml/genericqml/IntentReceiver.qml new file mode 100644 index 0000000..c39c742 --- /dev/null +++ b/source-linux/qml/genericqml/IntentReceiver.qml @@ -0,0 +1,43 @@ +import QtQuick 2.0 +import AndroidNative 1.0 + +Item { + + /// The URL of the image chosen. If multiple images are picked, it will be equal to the first image. + property string imageUrl: "" + + /// A list of images chosen + property var imageUrls: [] + + property string m_TEXT_MESSAGE: "androidnative.TextIntent.chosen"; + property string m_IMAGE_MESSAGE: "androidnative.ImagePicker.chosen"; + + + Connections { + target: SystemDispatcher + onDispatched: { + if (type === m_IMAGE_MESSAGE) { + var h=[]; + for (var n in message.imageUrls){ + h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5)) + } + imageUrls=h; + if(imageUrls.length==1){ + root.currentIndex=0;newstab.active=true; + root.uploadSignal(imageUrls) + } else{ + root.currentIndex=2;fotostab.active=true; + root.uploadSignal(imageUrls) + } + } else if (type==m_TEXT_MESSAGE){ + root.currentIndex=0;newstab.active=true; + root.sendtextSignal(message) + } + } + } + + Component.onCompleted: { + SystemDispatcher.setInitialized(); + } +} + diff --git a/source-linux/qml/genericqml/PermissionDialog.qml b/source-linux/qml/genericqml/PermissionDialog.qml index 0d866b8..61a05cc 100644 --- a/source-linux/qml/genericqml/PermissionDialog.qml +++ b/source-linux/qml/genericqml/PermissionDialog.qml @@ -196,7 +196,7 @@ Rectangle{ anchors.bottomMargin:1 text:"\u2713" onClicked:{updatePerms(); - permissionDialog.destroy(); + permissionDialog.visible=false; } } diff --git a/source-linux/qml/newsqml/MessageSend.qml b/source-linux/qml/newsqml/MessageSend.qml index a238a78..935960f 100644 --- a/source-linux/qml/newsqml/MessageSend.qml +++ b/source-linux/qml/newsqml/MessageSend.qml @@ -47,6 +47,7 @@ Flickable{ id:messageSend property string parentId: "" property string reply_to_user:"" + property alias bodyMessage: bodyField.text property var attachImageURLs: []; property int directmessage: 0; property var contacts: [] @@ -58,7 +59,8 @@ Flickable{ function attachImage(url){ var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment'+attachImageURLs.length+'; source:"'+ - url.toString()+'"; width: 15*mm; height: 15*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+url+'"),1); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage"); + url.toString()+'"; x:2*mm; width: 45*mm; height: 45*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+ + url+'"),1); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage"); } function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { @@ -90,7 +92,7 @@ Flickable{ Column { id:messageColumn - spacing: 2 + spacing: 0.5*mm width: parent.width TextField { id: titleField @@ -99,14 +101,23 @@ Flickable{ visible: messageSend.parentId === "" } - TextArea { - id: bodyField - width: parent.width - height: 30*mm - wrapMode: TextEdit.Wrap - textFormat: TextEdit.PlainText + Rectangle{ + color: "white" + radius: 0.5*mm + x:mm + width: parent.width-2*mm + height:Math.max(bodyField.contentHeight+2*mm,10*mm) + TextArea { + id: bodyField + anchors.fill: parent + font.pixelSize: 3*mm + wrapMode: Text.Wrap + selectByMouse: true + textFormat: TextEdit.PlainText + } } + Row{ spacing: 2 CheckBox{ @@ -143,10 +154,9 @@ Flickable{ text:"\u2713" onClicked: {if(urlTextEdit.text!=""){ var start = bodyField.selectionStart; - var end = bodyField.selectionEnd; - var text = bodyField.getText(start,end); + var text=bodyField.selectedText text = "[url="+urlTextEdit.text+"]" + text + "[/url]"; - bodyField.remove(start,end); + bodyField.remove(start,bodyField.selectionEnd); bodyField.insert(start,text);} urlRectangle.visible=false} } @@ -158,13 +168,11 @@ Flickable{ BlueButton{id:permButton visible: (directmessage==1)?false:true text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" - onClicked: { - var component = Qt.createComponent("qrc:/qml/genericqml/PermissionDialog.qml"); - var permissions = component.createObject(messageColumn); - }} + onClicked: { permissionDialog.visible=true;} + } BlueButton { id: attachButton - text: "\uf0c6" + text: "\uf03e" visible:(directmessage==0) onClicked: { if (attachImageURLs.length>0){//Server currently accepts only one attachment @@ -189,27 +197,26 @@ Flickable{ if(Helperjs.getCount(db,login,"contacts","screen_name",contacts[i].screen_name)>1){ contacts[i].screen_name=contacts[i].screen_name+"+"+contacts[i].cid } - contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"';iconSource:'"+contacts[i].profile_image+"'; onTriggered: bodyField.insert(0,' @"+contacts[i].screen_name+" ')}" + contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"'; onTriggered: bodyField.insert(0,' @"+contacts[i].screen_name+" ')}" }} var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}"; - var contactlistObject=Qt.createQmlObject(menuString,messageSend,"contactmenuOutput") + var contactlistObject=Qt.createQmlObject(menuString,messageColumn,"contactmenuOutput") contactlistObject.popup() } } BlueButton{ id:smileyButton text: "\uf118" - onClicked: { - var smileyarray=Smileyjs.smileys - var component = Qt.createComponent("qrc:/qml/newsqml/SmileyDialog.qml"); - var smileydialog = component.createObject(messageColumn) - }} + onClicked: {smileyDialog.visible=true} + } BlueButton { id: cancelButton text: "\uf057" - onClicked: {newstab.newstabstatus=login.newsViewType; - newsStack.pop(null)} + onClicked: { + newstab.newstabstatus=login.newsViewType; + newsStack.pop(null) + } } BlueButton { id: sendButton @@ -224,7 +231,8 @@ Flickable{ } } } - + PermissionDialog{id:permissionDialog;x:mm;visible: false} + SmileyDialog{id:smileyDialog;x:mm;visible: false} } Component.onCompleted: if(attachImageURLs.length>0){attachImage(attachImageURLs[0])} } diff --git a/source-linux/qml/newsqml/NewsTab.qml b/source-linux/qml/newsqml/NewsTab.qml index 07be7d7..c8bcb15 100644 --- a/source-linux/qml/newsqml/NewsTab.qml +++ b/source-linux/qml/newsqml/NewsTab.qml @@ -71,7 +71,7 @@ Item { function showNews(newsToShow){ try{if (newsStack.depth>1){newsStack.pop()}}catch(e){} - newsBusy.running = false; + newsBusy.running=false; var currentTime= new Date(); downloadNotice.text=""; var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow}; @@ -117,7 +117,14 @@ Item { function sendUrls(urls){ if((urls.length==1)&&(newsStack.depth<2)){ - newsStack.push([newslistRectangle,{item:"qrc:/qml/newsqml/MessageSend.qml",properties:{attachImageURLs:urls}}]) + newsStack.push([newslistRectangle,{item:"qrc:/qml/newsqml/MessageSend.qml",properties:{attachImageURLs:urls}}]) + } + } + + function sendtext(text){ + if(text&&(newsStack.depth<2)){ + if (text.subject=="undefined"){text.subject=""} + newsStack.push([newslistRectangle,{item:"qrc:/qml/newsqml/MessageSend.qml",properties:{bodyMessage:text.subject+"\n"+text.plaintext}}]) } } @@ -338,6 +345,7 @@ Item { root.directmessageSignal.connect(onDirectMessage); root.newsSignal.connect(showNews); root.uploadSignal.connect(sendUrls); + root.sendtextSignal.connect(sendtext); try{newsModel.clear()} catch(e){} //print("imageUrls "+JSON.stringify(imageUrls)+" newsstack.depth:"+newsStack.depth); diff --git a/source-linux/qml/newsqml/SmileyDialog.qml b/source-linux/qml/newsqml/SmileyDialog.qml index a0be90c..82ee0e9 100644 --- a/source-linux/qml/newsqml/SmileyDialog.qml +++ b/source-linux/qml/newsqml/SmileyDialog.qml @@ -49,7 +49,7 @@ Rectangle{ anchors.right: parent.right anchors.rightMargin: 1*mm text: "\uf057" - onClicked:{smileyDialog.destroy()} + onClicked:{smileyDialog.visible=false} } TabView{ @@ -164,7 +164,8 @@ Rectangle{ MouseArea{ anchors.fill: parent onClicked:{ - bodyField.append(emoji.name+" ") + //bodyField.append(emoji.name+" ") + bodyField.insert(bodyField.cursorPosition,emoji.name+" "); smileyDialog.destroy() } }