diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e5f5bf..283fc91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,30 +1,19 @@ -## v0.004# +## v0.1# + - # News # - -* Conversation opens as child of news item -* Pull-to-refresh news -* Delete Icon -* Animated Gif attachments shown below news item -* Improved image selector for new message -* Gif attachments for new message -* Timeline reloaded after new message - -# Contacts # -* Contact details window mechanism completely reworked -* New calendar icon for Friendica contacts -* "Connect" opens connect request page for Friendica contacs - -# Calendar # -* new calendar tab -* shows own public events and public events of Friendica contacts -* list view of events of selected date -* click on event to show details - -# Config # -* the icon of the server is shown if url is correct -* Click on icon for server details - -# Translations # -* German \ No newline at end of file + +* Native Android image selector for new message +* Click on contacts shows contact details on news page +* Fix problem with news list after deletion of item + +# Contacts # +* Clean contacts with no news + +# Images # +* Upload pictures with description to album (permissions cannot be set due to API problems) +* Delete pictures or albums from client and server (long press on picture in overview) +* Fix problem when enlarging photo + +# Translations # +* German, Spanish diff --git a/Friendiqa.apk b/Friendiqa.apk index e03c28e..673aa2e 100644 Binary files a/Friendiqa.apk and b/Friendiqa.apk differ diff --git a/README.md b/README.md index 334656b..b7eaa1d 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,14 @@ QML based client for the Friendica Social Network. Tabs for news (incl. Direct Messages), friends, photos and events. OS: currently Linux and Android(4.3). - Source code is a QtCreator project. - + Source code is a QtCreator project. + ## Screenshots ## ![Newstab](Screenshots/NewsTab.jpg) ![Friendstab](Screenshots/FriendsTab.jpg) ![Photostab](Screenshots/PhotoTab.jpg) -![Eventstab](Screenshots/EventsTab.jpg) +![Eventstab](Screenshots/EventsTab.jpg) ![Configtab](Screenshots/ConfigTab.jpg) @@ -19,38 +19,40 @@ QML based client for the Friendica Social Network. # News # Currently supported: * Shows Posts from friends, favorited messages, Direct Messages and Notifications -* Open links in external browser -* Click on contact photo for contact details -* Click on like text for additional contact info +* Open links in external browser +* +Click on contact photo for contact details +* Click on like text for additional contact info * Deletion, Reposting, Answering of Posts * Liking, disliking, favoriting -* Attending for event posts +* Attending for event posts * Update fetches new posts (up to last 50) since last in local DB * More shows older posts from local DB -* Create new Message with images or direct messages, Contact/Group access rights(can be stored), smileys -* New image dialog +* Create new Message with images or direct messages, Contact/Group access rights(can be stored), smileys +* Native Android image dialog ToDo: - -* Videos and other binary data as attachment (sending and receiving) -* More than one attachment -* Rich text editing in Send Dialog -* Attachments for Direct messages (currently not supported in API) - + +* Videos and other binary data as attachment (sending and receiving, currently not supported in API) +* More than one attachment (currently not supported in API) +* Rich text editing in Send Dialog +* Attachments for Direct messages (currently not supported in API) + # Friends # Currently supported: - -* Tabs for friends, other contacts and groups -* Grid of all known contacts with locally downloaded pictures -* Large friend item for addional information and functionality -* Show news of contact from local database -* Send direct message, if contact is following -* Show public pictures of contact (screenscraping of contact's website, works only with certain theme) -* Open website of contact or connect page (for other contacts) + +* Tabs for friends, other contacts and groups +* Grid of all known contacts with locally downloaded pictures +* Large friend item for addional information and functionality +* Show news of contact from local database +* Send direct message, if contact is following +* Show public pictures of contact (screenscraping of contact's website, works only with certain theme) +* Open website of contact or connect page (for other contacts) +* Clean other contacts with no news ToDo: -* More information for contact from description page, possibly private information for friends +* More information for contact from description page, possibly private information for friends (currently not supported in API) * Groups: create, change, delete @@ -58,45 +60,45 @@ ToDo: Currently supported: * Download all own images to local directory * Show albums in grid, show images in album in grid and fullscreen +* Upload pictures to albums with description +* Delete pictures on client and server * Show albums and images of contacts -* Pinch to zoom, swipe to scroll - +* Pinch to zoom, swipe to scroll + ToDo: * Private images of friends * Support for all themes of friends -* Delete downloaded own images - -# Events # -* download own public events and public events of Friendica contacts -* list view of events of selected date -* click on event to show details - -ToDo -* private events - + +# Events # +* download own public events and show public events of Friendica contacts +* list view of events of selected date +* click on event to show details + +ToDo +* private events + # Config # Currently supported: * Multiple accounts -* Maximum news (deleted after use of Quit button) -* View mode for news (tree or timeline) +* Maximum news (surplus deleted after use of Quit button) +* View mode for news (tree or timeline) ToDo * OAuth? - + # Other # ToDo * Video tab -* Photo upload to album (needs API change) * Translation * Blingbling - -# Translations # -* German - + +# Translations # +* German, Spanish + ## License ## Pubished under the [GPL v3](http://gplv3.fsf.org). diff --git a/source-android/android/AndroidManifest.xml b/source-android/android/AndroidManifest.xml index e64dbfa..60b9234 100644 --- a/source-android/android/AndroidManifest.xml +++ b/source-android/android/AndroidManifest.xml @@ -1,7 +1,11 @@ - - - + + + diff --git a/source-android/android/androidnative.gradle b/source-android/android/androidnative.gradle new file mode 100644 index 0000000..8fe9786 --- /dev/null +++ b/source-android/android/androidnative.gradle @@ -0,0 +1,34 @@ + +// Obtain androidPackageSourceDir +// androidPackageSourceDir is the absolute path of the folder containing build.gradle and AndroidManifests.xml +// This code also works with androiddeployqt. + +import groovy.json.JsonSlurper + +String getAndroidPackageSourceDir() { + String res = System.getProperty("user.dir"); + + FileTree tree = fileTree(dir: res + "/..").include("android*deployment-settings.json"); + + if (tree.getFiles().size() > 0) { + def inputFile = tree.getFiles().toArray()[0]; + def InputJSON = new JsonSlurper().parseText(inputFile.text); + res = InputJSON["android-package-source-directory"] + } else { + println("android*deployment-settings.json not found. Set androidPackageSourceDir to user.dir"); + } + + return res; +} + +String setAndroidNativePath(String path) { + String androidPackageSourceDir = getAndroidPackageSourceDir(); + String androidNativePath = androidPackageSourceDir + path + "/java/src"; + LinkedHashSet hash = android.sourceSets.main.java.srcDirs; + hash.add(androidNativePath); + android.sourceSets.main.java.srcDirs = hash; +} + +ext { + setAndroidNativePath = this.&setAndroidNativePath; +} diff --git a/source-android/android/build.gradle b/source-android/android/build.gradle index ef416b0..4b3e83a 100644 --- a/source-android/android/build.gradle +++ b/source-android/android/build.gradle @@ -55,3 +55,5 @@ android { abortOnError false } } + apply from: "androidnative.gradle" + setAndroidNativePath("/../androidnative.pri"); \ No newline at end of file diff --git a/source-android/android/gradle.properties b/source-android/android/gradle.properties index 760ded2..0463ab8 100644 --- a/source-android/android/gradle.properties +++ b/source-android/android/gradle.properties @@ -1,4 +1,4 @@ -androidBuildToolsVersion=23.0.2 -androidCompileSdkVersion=23 +androidBuildToolsVersion=25.0.3 +androidCompileSdkVersion=25 buildDir=.build -qt5AndroidDir=/home/pankraz/Qt/5.8/android_armv7/src/android/java +qt5AndroidDir=/home/pankraz/Qt/5.9.1/android_armv7/src/android/java diff --git a/source-android/android/gradle.properties~ b/source-android/android/gradle.properties~ new file mode 100644 index 0000000..0463ab8 --- /dev/null +++ b/source-android/android/gradle.properties~ @@ -0,0 +1,4 @@ +androidBuildToolsVersion=25.0.3 +androidCompileSdkVersion=25 +buildDir=.build +qt5AndroidDir=/home/pankraz/Qt/5.9.1/android_armv7/src/android/java diff --git a/source-android/android/local.properties b/source-android/android/local.properties index daae45e..ada6c98 100644 --- a/source-android/android/local.properties +++ b/source-android/android/local.properties @@ -1 +1 @@ -sdk.dir=/opt/android-sdk +sdk.dir=/home/pankraz/android-sdk_alt diff --git a/source-android/android/local.properties~ b/source-android/android/local.properties~ new file mode 100644 index 0000000..ada6c98 --- /dev/null +++ b/source-android/android/local.properties~ @@ -0,0 +1 @@ +sdk.dir=/home/pankraz/android-sdk_alt diff --git a/source-android/android/res/drawable-hdpi/splash.png b/source-android/android/res/drawable-hdpi/splash.png new file mode 100644 index 0000000..25a3580 Binary files /dev/null and b/source-android/android/res/drawable-hdpi/splash.png differ diff --git a/source-android/android/res/drawable-ldpi/icon.png b/source-android/android/res/drawable-ldpi/icon.png deleted file mode 100644 index d77cd59..0000000 Binary files a/source-android/android/res/drawable-ldpi/icon.png and /dev/null differ diff --git a/source-android/android/res/drawable-ldpi/splash.png b/source-android/android/res/drawable-ldpi/splash.png new file mode 100644 index 0000000..25a3580 Binary files /dev/null and b/source-android/android/res/drawable-ldpi/splash.png differ diff --git a/source-android/android/res/drawable-mdpi/splash.png b/source-android/android/res/drawable-mdpi/splash.png new file mode 100644 index 0000000..25a3580 Binary files /dev/null and b/source-android/android/res/drawable-mdpi/splash.png differ diff --git a/source-android/android/res/drawable-xhdpi/splash.png b/source-android/android/res/drawable-xhdpi/splash.png new file mode 100644 index 0000000..25a3580 Binary files /dev/null and b/source-android/android/res/drawable-xhdpi/splash.png differ diff --git a/source-android/android/res/drawable-xxhdpi/splash.png b/source-android/android/res/drawable-xxhdpi/splash.png new file mode 100644 index 0000000..25a3580 Binary files /dev/null and b/source-android/android/res/drawable-xxhdpi/splash.png differ diff --git a/source-android/android/res/drawable-xxxhdpi/splash.png b/source-android/android/res/drawable-xxxhdpi/splash.png new file mode 100644 index 0000000..25a3580 Binary files /dev/null and b/source-android/android/res/drawable-xxxhdpi/splash.png differ diff --git a/source-android/android/res/drawable/friendiqa.png b/source-android/android/res/drawable/friendiqa.png deleted file mode 100644 index d77cd59..0000000 Binary files a/source-android/android/res/drawable/friendiqa.png and /dev/null differ diff --git a/source-android/android/res/drawable/icon.png b/source-android/android/res/drawable/icon.png deleted file mode 100644 index d77cd59..0000000 Binary files a/source-android/android/res/drawable/icon.png and /dev/null differ diff --git a/source-android/android/src/ExampleService.java b/source-android/android/src/ExampleService.java new file mode 100644 index 0000000..217e99c --- /dev/null +++ b/source-android/android/src/ExampleService.java @@ -0,0 +1,96 @@ +package androidnative.example; +import androidnative.SystemDispatcher; +import android.app.Notification; +import android.app.NotificationManager; +import android.util.Log; +import android.os.Handler; +import android.app.Activity; +import android.view.View; +import android.content.Context; +import java.util.Map; +import org.qtproject.qt5.android.QtNative; + +public class ExampleService { + + static { + + SystemDispatcher.addListener(new SystemDispatcher.Listener() { + + NotificationManager m_notificationManager; + Notification.Builder m_builder; + + private void notificationManagerNotify(Map data) { + + final Activity activity = QtNative.activity(); + final Map messageData = data; + + Runnable runnable = new Runnable () { + public void run() { + try { + String title = (String) messageData.get("title"); + + String message = (String) messageData.get("message"); + + if (m_notificationManager == null) { + m_notificationManager = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE); + m_builder = new Notification.Builder(activity); + + // Small Icon is a must to make notification works. + // And that is why you need to inherit QtActivity + //m_builder.setSmallIcon(drawable.icon); + } + + m_builder.setContentTitle(title); + m_builder.setContentText(message); + m_notificationManager.notify(1, m_builder.build()); + + // Test function. Remove it later. + SystemDispatcher.dispatch("Notifier.notifyFinished"); + } catch (Exception e) { + Log.d("",e.getMessage()); + } + + }; + }; + activity.runOnUiThread(runnable); + } + + private void hapticFeedbackPerform(Map data) { + + final Activity activity = QtNative.activity(); + final Map messageData = data; + Runnable runnable = new Runnable () { + public void run() { + int feedbackConstant = (Integer) messageData.get("feedbackConstant"); + int flags = (Integer) messageData.get("flags"); + + Log.d("",String.format("hapticFeedbackPerform(%d,%d)",feedbackConstant,flags)); + + View rootView = activity.getWindow().getDecorView().getRootView(); + rootView.performHapticFeedback(feedbackConstant, flags); + + // Test function. Remove it later. + SystemDispatcher.dispatch("hapticFeedbackPerformFinished"); + }; + }; + activity.runOnUiThread(runnable); + } + + public void onDispatched(String name , Map data) { + + if (name.equals("Notifier.notify")) { + notificationManagerNotify(data); + return; + } else if (name.equals("hapticFeedbackPerform")) { + hapticFeedbackPerform(data); + return; + } + + return; + } + }); + + } + +} + diff --git a/source-android/android/src/FriendiqaActivity.java b/source-android/android/src/FriendiqaActivity.java new file mode 100644 index 0000000..2b04ff3 --- /dev/null +++ b/source-android/android/src/FriendiqaActivity.java @@ -0,0 +1,16 @@ +package androidnative.friendiqa; + +import androidnative.AndroidNativeActivity; + +/** + * Created by benlau on 8/3/2017. + */ + +public class FriendiqaActivity extends AndroidNativeActivity { + public FriendiqaActivity() { + super(); + + QT_ANDROID_THEMES = new String[] {""}; + QT_ANDROID_DEFAULT_THEME = ""; + } +} diff --git a/source-android/androidnative.pri b/source-android/androidnative.pri new file mode 160000 index 0000000..86774d7 --- /dev/null +++ b/source-android/androidnative.pri @@ -0,0 +1 @@ +Subproject commit 86774d715cead715661892dd8f95c7854894fa9f diff --git a/source-android/application.qrc b/source-android/application.qrc index 7413671..45a0e2d 100644 --- a/source-android/application.qrc +++ b/source-android/application.qrc @@ -4,14 +4,13 @@ qml/newsqml/NewsTab.qml qml/newsqml/Newsitem.qml qml/newsqml/MessageSend.qml - qml/newsqml/PermissionDialog.qml qml/newsqml/Conversation.qml - qml/newsqml/ImageDialog.qml qml/newsqml/FriendicaActivities.qml qml/contactqml/FriendsTab.qml qml/contactqml/GroupComponent.qml qml/contactqml/ContactComponent.qml qml/contactqml/ContactDetailsComponent.qml + qml/contactqml/Contactlist.qml qml/genericqml/BlueButton.qml qml/photoqml/PhotoComponent.qml qml/photoqml/PhotogroupComponent.qml @@ -208,7 +207,14 @@ qml/calendarqml/EventList.qml translations/friendiqa-de.qm translations/friendiqa-de.ts - translations/friendiqa-es.ts - translations/friendiqa-es.qm + qml/photoqml/ImageUploadDialog.qml + qml/genericqml/ImageDialog.qml + qml/genericqml/PermissionDialog.qml + images/addImage.png + common/imageselectandroid.h + common/imageselectandroid.cpp + qml/genericqml/ImagePicker.qml + common/quickandroid.h + common/quickandroid.cpp diff --git a/source-android/common/filesystem.cpp b/source-android/common/filesystem.cpp index 05200fa..fa29a92 100644 --- a/source-android/common/filesystem.cpp +++ b/source-android/common/filesystem.cpp @@ -54,6 +54,7 @@ void FILESYSTEM::makeDir(QString name) void FILESYSTEM::rmDir() { QDir dir(m_Directory); + //qDebug()<(), EXTERNAL_CONTENT_URI.object()); + + if (ACTION_PICK.isValid() && intent.isValid()) + { + intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("image/*").object()); + QtAndroid::startActivity(intent.object(), 101,this); + qDebug() << "OK"; + } + else + { + qDebug() << "ERRO"; + } +} + +void FILESYSTEM::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) +{ + jint RESULT_OK = QAndroidJniObject::getStaticField("android/app/Activity", "RESULT_OK"); + if (receiverRequestCode == 101 && resultCode == RESULT_OK) + { + QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;"); + QAndroidJniObject dadosAndroid = QAndroidJniObject::getStaticObjectField("android/provider/MediaStore$MediaColumns", "DATA", "Ljava/lang/String;"); + QAndroidJniEnvironment env; + jobjectArray projecao = (jobjectArray)env->NewObjectArray(1, env->FindClass("java/lang/String"), NULL); + jobject projacaoDadosAndroid = env->NewStringUTF(dadosAndroid.toString().toStdString().c_str()); + env->SetObjectArrayElement(projecao, 0, projacaoDadosAndroid); + QAndroidJniObject contentResolver = QtAndroid::androidActivity().callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;"); + QAndroidJniObject cursor = contentResolver.callObjectMethod("query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;", uri.object(), projecao, NULL, NULL, NULL); + jint columnIndex = cursor.callMethod("getColumnIndex", "(Ljava/lang/String;)I", dadosAndroid.object()); + cursor.callMethod("moveToFirst", "()Z"); + QAndroidJniObject resultUri = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex); + QString imageSelect = "file://" + resultUri.toString(); + emit imageselected(imageSelect); + } + else + { + qDebug() << "Select error"; + } +} diff --git a/source-android/common/filesystem.h b/source-android/common/filesystem.h index 696d646..d8b2bac 100644 --- a/source-android/common/filesystem.h +++ b/source-android/common/filesystem.h @@ -4,8 +4,9 @@ #include #include #include +#include -class FILESYSTEM : public QObject +class FILESYSTEM : public QObject, public QAndroidActivityResultReceiver { Q_OBJECT Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged) @@ -23,8 +24,10 @@ public: //bool direxist(QString Directory); QString homePath() const; QString cameraPath() const; + virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data); signals: + void imageselected(QString); void directoryChanged(); //void fileListContent(QList data); void success(QString data); @@ -34,6 +37,7 @@ public slots: void makeDir(QString name); void rmDir(); void rmFile(QString name); + void searchImage(); //void fileList(); private: diff --git a/source-android/common/friendiqa.cpp b/source-android/common/friendiqa.cpp index 51659e4..3ad211e 100644 --- a/source-android/common/friendiqa.cpp +++ b/source-android/common/friendiqa.cpp @@ -3,6 +3,26 @@ #include #include "xhr.h" #include "filesystem.h" +//#include "qadrawableprovider.h" +//#include "androidnative.pri/cpp/AndroidNative/systemdispatcher.h" +#include "AndroidNative/systemdispatcher.h" +#include "AndroidNative/environment.h" +#include "AndroidNative/debug.h" +#include "AndroidNative/mediascannerconnection.h" +//#include "debugwrapper.h" + +#ifdef Q_OS_ANDROID +#include +#include +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { + Q_UNUSED(vm); + qDebug("NativeInterface::JNI_OnLoad()"); // It must call this function within JNI_OnLoad to enable System Dispatcher + + AndroidNative::SystemDispatcher::registerNatives(); + return JNI_VERSION_1_6; + } +#endif + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -11,6 +31,8 @@ int main(int argc, char *argv[]) { qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations"); app.installTranslator(&qtTranslator); +// qmlRegisterType("SystemDispatcher", 0, 1, "SystemDispatcher"); + XHR* xhr = XHR::instance(); view.rootContext()->setContextProperty("xhr", xhr); FILESYSTEM* filesystem = FILESYSTEM::instance(); diff --git a/source-android/common/imageselectandroid.cpp b/source-android/common/imageselectandroid.cpp new file mode 100644 index 0000000..63a88c1 --- /dev/null +++ b/source-android/common/imageselectandroid.cpp @@ -0,0 +1,56 @@ +#include "imageselectandroid.h" + +imageSelectAndroid::imageSelectAndroid() +{ + +} +imageSelectAndroid *imageSelectAndroid::instance() +{ + static imageSelectAndroid imageselectandroid; + return &imageselectandroid; +} + +void imageSelectAndroid::searchImage() +{ + QAndroidJniObject ACTION_PICK = QAndroidJniObject::getStaticObjectField("android/content/Intent", "ACTION_PICK", "Ljava/lang/String;"); + QAndroidJniObject EXTERNAL_CONTENT_URI = QAndroidJniObject::getStaticObjectField("android/provider/MediaStore$Images$Media", "EXTERNAL_CONTENT_URI", "Landroid/net/Uri;"); + + QAndroidJniObject intent=QAndroidJniObject("android/content/Intent", "(Ljava/lang/String;Landroid/net/Uri;)V", ACTION_PICK.object(), EXTERNAL_CONTENT_URI.object()); + + if (ACTION_PICK.isValid() && intent.isValid()) + { + intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("image/*").object()); + QtAndroid::startActivity(intent.object(), 101, this); + qDebug() << "OK"; + } + else + { + qDebug() << "ERRO"; + } +} + +void imageSelectAndroid::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) +{ qDebug() << "done"; + jint RESULT_OK = QAndroidJniObject::getStaticField("android/app/Activity", "RESULT_OK"); + if (receiverRequestCode == 101 && resultCode == RESULT_OK) + { + qDebug() << "done"; + QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;"); + QAndroidJniObject dadosAndroid = QAndroidJniObject::getStaticObjectField("android/provider/MediaStore$MediaColumns", "DATA", "Ljava/lang/String;"); + QAndroidJniEnvironment env; + jobjectArray projecao = (jobjectArray)env->NewObjectArray(1, env->FindClass("java/lang/String"), NULL); + jobject projacaoDadosAndroid = env->NewStringUTF(dadosAndroid.toString().toStdString().c_str()); + env->SetObjectArrayElement(projecao, 0, projacaoDadosAndroid); + QAndroidJniObject contentResolver = QtAndroid::androidActivity().callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;"); + QAndroidJniObject cursor = contentResolver.callObjectMethod("query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;", uri.object(), projecao, NULL, NULL, NULL); + jint columnIndex = cursor.callMethod("getColumnIndex", "(Ljava/lang/String;)I", dadosAndroid.object()); + cursor.callMethod("moveToFirst", "()Z"); + QAndroidJniObject resultUri = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex); + QString imageSelect = "file://" + resultUri.toString(); + emit imageselected(imageSelect); + } + else + { + qDebug() << "Select error"; + } +} diff --git a/source-android/common/imageselectandroid.h b/source-android/common/imageselectandroid.h new file mode 100644 index 0000000..5a3690e --- /dev/null +++ b/source-android/common/imageselectandroid.h @@ -0,0 +1,23 @@ +#ifndef IMAGEPICKANDROID_H +#define IMAGEPICKANDROID_H +#include +#include + +#include + +class imageSelectAndroid : public QObject, public QAndroidActivityResultReceiver +{ + Q_OBJECT + +public: + imageSelectAndroid(); + static imageSelectAndroid *instance(); + void searchImage(); + + virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject & data); + +signals: + void imageselected(QString); +}; + +#endif // IMAGEPICKANDROID_H diff --git a/source-android/common/qasystemdispatcher.cpp b/source-android/common/qasystemdispatcher.cpp new file mode 100644 index 0000000..d9bd18a --- /dev/null +++ b/source-android/common/qasystemdispatcher.cpp @@ -0,0 +1,348 @@ +// Author: Ben Lau (https://github.com/benlau) +#include +#include +#include +#include +#include +#include "qasystemdispatcher.h" + +static QPointer m_instance; + +QString QASystemDispatcher::ACTIVITY_RESUME_MESSAGE = "Activity.onResume"; +QString QASystemDispatcher::ACTIVITY_RESULT_MESSAGE = "Activity.onActivityResult"; + + +#ifdef Q_OS_ANDROID +#include +#include + +#define JCLASS_Name "quickandroid/SystemDispatcher" +#define DISPATCH_SIGNATURE "(Ljava/lang/String;Ljava/util/Map;)V" +#define EMIT_SIGNATURE "(Ljava/lang/String;Ljava/util/Map;)V" + +static QVariantMap createVariantMap(jobject data); +static jobject createHashMap(const QVariantMap &data); + +static QVariant convertToQVariant(QAndroidJniObject value) { + QVariant v; + if (!value.isValid()) { + return v; + } + + QAndroidJniEnvironment env; + + jclass jclass_of_string = env->FindClass("java/lang/String"); + jclass jclass_of_integer = env->FindClass("java/lang/Integer"); + jclass jclass_of_boolean = env->FindClass("java/lang/Boolean"); + jclass jclass_of_list = env->FindClass("java/util/List"); + jclass jclass_of_map = env->FindClass("java/util/Map"); + + if (env->IsInstanceOf(value.object(),jclass_of_boolean)) { + v = QVariant::fromValue(value.callMethod("booleanValue","()Z")); + } else if (env->IsInstanceOf(value.object(),jclass_of_integer)) { + v = value.callMethod("intValue","()I"); + } else if (env->IsInstanceOf(value.object(),jclass_of_string)) { + v = value.toString(); + } else if (env->IsInstanceOf(value.object(), jclass_of_map)) { + v = createVariantMap(value.object()); + } else if (env->IsInstanceOf(value.object(),jclass_of_list)) { + QVariantList list; + int count = value.callMethod("size","()I"); + for (int i = 0 ; i < count ; i++) { + QAndroidJniObject item = value.callObjectMethod("get","(I)Ljava/lang/Object;",i); + list.append(convertToQVariant(item)); + } + v = list; + } + + env->DeleteLocalRef(jclass_of_string); + env->DeleteLocalRef(jclass_of_integer); + env->DeleteLocalRef(jclass_of_boolean); + env->DeleteLocalRef(jclass_of_list); + env->DeleteLocalRef(jclass_of_map); + + return v; +} + +static QVariantMap createVariantMap(jobject data) { + QVariantMap res; + + QAndroidJniEnvironment env; + /* Reference : https://community.oracle.com/thread/1549999 */ + + // Get the HashMap Class + jclass jclass_of_hashmap = (env)->GetObjectClass(data); + + // Get link to Method "entrySet" + jmethodID entrySetMethod = (env)->GetMethodID(jclass_of_hashmap, "entrySet", "()Ljava/util/Set;"); + + // Invoke the "entrySet" method on the HashMap object + jobject jobject_of_entryset = env->CallObjectMethod(data, entrySetMethod); + + // Get the Set Class + jclass jclass_of_set = (env)->FindClass("java/util/Set"); // Problem during compilation !!!!! + + if (jclass_of_set == 0) { + qWarning() << "java/util/Set lookup failed\n"; + return res; + } + + // Get link to Method "iterator" + jmethodID iteratorMethod = env->GetMethodID(jclass_of_set, "iterator", "()Ljava/util/Iterator;"); + + // Invoke the "iterator" method on the jobject_of_entryset variable of type Set + jobject jobject_of_iterator = env->CallObjectMethod(jobject_of_entryset, iteratorMethod); + + // Get the "Iterator" class + jclass jclass_of_iterator = (env)->FindClass("java/util/Iterator"); + + // Get link to Method "hasNext" + jmethodID hasNextMethod = env->GetMethodID(jclass_of_iterator, "hasNext", "()Z"); + + jmethodID nextMethod = env->GetMethodID(jclass_of_iterator, "next", "()Ljava/lang/Object;"); + + while (env->CallBooleanMethod(jobject_of_iterator, hasNextMethod) ) { + jobject jEntry = env->CallObjectMethod(jobject_of_iterator,nextMethod); + QAndroidJniObject entry = QAndroidJniObject(jEntry); + QAndroidJniObject key = entry.callObjectMethod("getKey","()Ljava/lang/Object;"); + QAndroidJniObject value = entry.callObjectMethod("getValue","()Ljava/lang/Object;"); + QString k = key.toString(); + + QVariant v = convertToQVariant(value); + + env->DeleteLocalRef(jEntry); + + if (v.isNull()) { + continue; + } + + res[k] = v; + } + + if (env->ExceptionOccurred()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + + env->DeleteLocalRef(jclass_of_hashmap); + env->DeleteLocalRef(jobject_of_entryset); + env->DeleteLocalRef(jclass_of_set); + env->DeleteLocalRef(jobject_of_iterator); + env->DeleteLocalRef(jclass_of_iterator); + + return res; +} + +static jobject convertToJObject(QVariant v) { + jobject res = 0; + QAndroidJniEnvironment env; + + if (v.type() == QVariant::String) { + QString str = v.toString(); + res = env->NewStringUTF(str.toLocal8Bit().data()); + } else if (v.type() == QVariant::Int) { + jclass integerClass = env->FindClass("java/lang/Integer"); + jmethodID integerConstructor = env->GetMethodID(integerClass, "", "(I)V"); + + res = env->NewObject(integerClass,integerConstructor,v.toInt()); + + env->DeleteLocalRef(integerClass); + } else if (v.type() == QVariant::Bool) { + jclass booleanClass = env->FindClass("java/lang/Boolean"); + jmethodID booleanConstructor = env->GetMethodID(booleanClass,"","(Z)V"); + + res = env->NewObject(booleanClass,booleanConstructor,v.toBool()); + + env->DeleteLocalRef(booleanClass); + + } else if (v.type() == QVariant::Map) { + res = createHashMap(v.toMap()); + } else if (v.type() == QVariant::List){ + QVariantList list = v.value(); + jclass arrayListClass = env->FindClass("java/util/ArrayList"); + jmethodID init = env->GetMethodID(arrayListClass, "", "(I)V"); + res = env->NewObject( arrayListClass, init, list.size()); + + jmethodID add = env->GetMethodID( arrayListClass, "add", + "(Ljava/lang/Object;)Z"); + + for (int i = 0 ; i < list.size() ; i++) { + jobject item = convertToJObject(list.at(i)); + env->CallBooleanMethod(res,add, item); + env->DeleteLocalRef(item); + } + + env->DeleteLocalRef(arrayListClass); + } else { + qWarning() << "QASystemDispatcher: Non-supported data type - " << v.type(); + } + return res; +} + +static jobject createHashMap(const QVariantMap &data) { + QAndroidJniEnvironment env; + + jclass mapClass = env->FindClass("java/util/HashMap"); + + if (mapClass == NULL) { + qWarning() << "Failed to find class" << "java/util/HashMap"; + return NULL; + } + + jsize map_len = data.size(); + + jmethodID init = env->GetMethodID(mapClass, "", "(I)V"); + jobject hashMap = env->NewObject( mapClass, init, map_len); + + jmethodID put = env->GetMethodID( mapClass, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + QMapIterator iter(data); + while (iter.hasNext()) { + iter.next(); + + QString key = iter.key(); + jstring jkey = env->NewStringUTF(key.toLocal8Bit().data()); + QVariant v = iter.value(); + jobject item = convertToJObject(v); + + if (item == 0) { + continue; + } + + env->CallObjectMethod(hashMap,put,jkey,item); + env->DeleteLocalRef(item); + env->DeleteLocalRef(jkey); + } + + if (env->ExceptionOccurred()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + + env->DeleteLocalRef(mapClass); + + return hashMap; +} + +static void jniEmit(JNIEnv* env,jobject object,jstring name,jobject data) { + Q_UNUSED(object); + Q_UNUSED(env); + + QAndroidJniObject tmp(name); + QString str = tmp.toString(); + + QVariantMap map; + + if (data != 0) { + map = createVariantMap(data); + } + + if (m_instance.isNull()) { + return; + } + + QMetaObject::invokeMethod(m_instance.data(),"dispatched",Qt::AutoConnection, + Q_ARG(QString, str), + Q_ARG(QVariantMap,map)); +} + + +#endif + +QASystemDispatcher::QASystemDispatcher(QObject* parent) : QObject(parent) +{ + +} + +QASystemDispatcher::~QASystemDispatcher() +{ + +} + +QASystemDispatcher *QASystemDispatcher::instance() +{ + if (!m_instance) { + QCoreApplication* app = QCoreApplication::instance(); + m_instance = new QASystemDispatcher(app); + } + return m_instance; +} + +void QASystemDispatcher::dispatch(QString type, QVariantMap message) +{ + Q_UNUSED(type); + Q_UNUSED(message); +#ifdef Q_OS_ANDROID + QAndroidJniEnvironment env; + + jstring jType = env->NewStringUTF(type.toLocal8Bit().data()); + jobject jData = createHashMap(message); + QAndroidJniObject::callStaticMethod(JCLASS_Name, "dispatch", + DISPATCH_SIGNATURE, + jType,jData); + env->DeleteLocalRef(jType); + env->DeleteLocalRef(jData); + +#else + static bool dispatching = false; + static QQueue > queue; + + + if (dispatching) { + queue.enqueue(QPair (type,message) ); + return; + } + + dispatching = true; + emit dispatched(type,message); + + +qWarning() << "QASystemDispatcher: emitted" + + while (queue.size() > 0) { + QPair pair = queue.dequeue(); + emit dispatched(pair.first,pair.second); + } + dispatching = false; +#endif +} + +void QASystemDispatcher::loadClass(QString javaClassName) +{ + QVariantMap message; + message["className"] = javaClassName; + + dispatch("quickandroid.SystemDispatcher.loadClass",message); +} + +void QASystemDispatcher::registerNatives() +{ +#ifdef Q_OS_ANDROID + QAndroidJniEnvironment env; + jclass clazz = env->FindClass(JCLASS_Name); + if (!clazz) + { + qCritical() << QString("Can't find %1 class").arg(QString(JCLASS_Name)); + return ; + } + + JNINativeMethod methods[] = + { + {"jniEmit", EMIT_SIGNATURE, (void *)&jniEmit}, + }; + + int numMethods = sizeof(methods) / sizeof(methods[0]); + if (env->RegisterNatives(clazz, methods, numMethods) < 0) { + if (env->ExceptionOccurred()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + qCritical() << "Exception occurred!!!"; + return; + } + } + + QAndroidJniObject::callStaticMethod(JCLASS_Name, "init", + "()V"); +#endif +} diff --git a/source-android/common/qasystemdispatcher.h b/source-android/common/qasystemdispatcher.h new file mode 100644 index 0000000..414d18d --- /dev/null +++ b/source-android/common/qasystemdispatcher.h @@ -0,0 +1,47 @@ +// Author: Ben Lau (https://github.com/benlau) +#pragma once +#include +#include + +/// QASystemDispatcher provides an simple messaging interface between C/C++/QML and Java code. + +class QASystemDispatcher : public QObject +{ + Q_OBJECT +public: + ~QASystemDispatcher(); + static QASystemDispatcher* instance(); + + /// Dispatch a message via Dispatcher + /** The message will be first passed to Java's SystemDispatcher and invoke + * registered listener. Once it is finished, it will emit the + * "dispatched" signal. + * + */ + Q_INVOKABLE void dispatch(QString type , QVariantMap message = QVariantMap()); + + /// Load a Java class + /** It will dispatch a message to Java and let it to load a Java class. That + * will force to run code in static block. + * + */ + Q_INVOKABLE void loadClass(QString javaClassName); + + /// Register JNI native methods. This function must be called in JNI_OnLoad. Otherwise, the messenger will not be working + static void registerNatives(); + + /// The name of message that will be dispatched during Activity.onActivityResult. + static QString ACTIVITY_RESULT_MESSAGE; + + /// The name of message that will be dispatched during Activity.onResume. + static QString ACTIVITY_RESUME_MESSAGE; + +signals: + /// The signal is emitted when a message is dispatched. + void dispatched(QString type , QVariantMap message); + +public: + explicit QASystemDispatcher(QObject* parent = 0); + +}; + diff --git a/source-android/common/quickandroid.cpp b/source-android/common/quickandroid.cpp new file mode 100644 index 0000000..2ceb04e --- /dev/null +++ b/source-android/common/quickandroid.cpp @@ -0,0 +1,22 @@ +#include +#include +#include "quickandroid.h" +//#include "qadevice.h" +//#include "qamousesensor.h" + +#ifdef Q_OS_ANDROID +#include +#include +#endif + +void QuickAndroid::registerTypes() +{ + // "A" has been changed to a QML object. So now this function will do nothing. + // Keep here for compatible purpose only. +} + +//qreal QuickAndroid::dp() +//{ +// return QADevice::readDp(); +//} + diff --git a/source-android/common/quickandroid.h b/source-android/common/quickandroid.h new file mode 100644 index 0000000..1b0d01b --- /dev/null +++ b/source-android/common/quickandroid.h @@ -0,0 +1,21 @@ +#ifndef QUICKANDROID_H +#define QUICKANDROID_H + +#include +/// Quick Android Context + +class QuickAndroid +{ +public: + static void registerTypes(); + + /// Obtain the detected "dp" value. + /** This function has been deprecated. Please use QADevice::dp() + @deprecated. + * @brief dp + * @return The detected "dp" value + */ + static qreal dp(); +}; + +#endif // QUICKANDROID_H diff --git a/source-android/common/xhr.cpp b/source-android/common/xhr.cpp index dd2e3df..2fe9ceb 100644 --- a/source-android/common/xhr.cpp +++ b/source-android/common/xhr.cpp @@ -3,7 +3,10 @@ #include #include #include - +#include +#include +#include +#include #include "uploadableimage.h" XHR *XHR::instance() @@ -114,7 +117,8 @@ void XHR::get() QByteArray loginData = m_login.toLocal8Bit().toBase64(); QString headerData = "Basic " + loginData; request.setRawHeader("Authorization", headerData.toLocal8Bit()); - +// QNetworkCookieJar* cJar = new QNetworkCookieJar; +// manager.setCookieJar(cJar); request.setUrl(requrl); reply = manager.get(request); @@ -184,7 +188,7 @@ void XHR::onReplySuccess() qDebug() << "!"; emit this->success( bufferToString() ); buffer.clear(); - reply->deleteLater(); +// reply->deleteLater(); } void XHR::onRequestFinished() @@ -206,6 +210,15 @@ void XHR::onReadyRead() { qDebug() << "."; buffer += reply->readAll(); +// QList list = manager.cookieJar()->cookiesForUrl(m_url); +// QFile f("/home/pankraz/cookie.txt"); +// f.open(QIODevice::ReadWrite); +// for(int i = 0; i < list.size(); ++i){ +// QDataStream s(&f); +// s << list.at(i).toRawForm(); +// } +// f.close(); + } //void XHR::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes) @@ -227,5 +240,3 @@ QString XHR::bufferToString() { return QTextCodec::codecForName("utf-8")->toUnicode(buffer); } - - diff --git a/source-android/friendiqa.pro b/source-android/friendiqa.pro index a160a6a..1f23310 100644 --- a/source-android/friendiqa.pro +++ b/source-android/friendiqa.pro @@ -10,14 +10,20 @@ # - translation filenames have to be changed # The name of your application +TEMPLATE = app TARGET = friendiqa CONFIG += debug QT += qml quick gui widgets androidextras +include(androidnative.pri/androidnative.pri) + SOURCES += common/friendiqa.cpp \ common/uploadableimage.cpp \ common/xhr.cpp \ - common/filesystem.cpp + common/filesystem.cpp \ + +ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android + RESOURCES = application.qrc @@ -30,18 +36,16 @@ OTHER_FILES += qml/friendiqa.qml \ qml/configqml/*.qml js/*.js -# German translation is enabled as an example. If you aren't -# planning to localize your app, remember to comment out the -# following TRANSLATIONS line. And also do not forget to -# modify the localized app name in the the .desktop file. TRANSLATIONS += translations/friendiqa-de.ts \ translations/friendiqa-es.ts + HEADERS += \ common/uploadableimage.h \ common/xhr.h \ - common/filesystem.h - + common/filesystem.h + DISTFILES += \ + qml/calendarqml/*.qml \ android/AndroidManifest.xml \ android/gradle/wrapper/gradle-wrapper.jar \ android/gradlew \ @@ -49,8 +53,15 @@ DISTFILES += \ android/build.gradle \ android/gradle/wrapper/gradle-wrapper.properties \ android/gradlew.bat \ - translations/friendiqa-es.qm - -ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android + translations/*.ts \ + qml/*.qml \ + qml/newsqml/*.qml \ + qml/contactqml/*.qml \ + qml/photoqml/*.qml \ + qml/configqml/*.qml \ + js/*.js \ + android/androidnative.gradle \ + android/src/FriendiqaActivity.java \ + android/src/ExampleService.java diff --git a/source-android/friendiqa.pro.user b/source-android/friendiqa.pro.user new file mode 100644 index 0000000..8b54897 --- /dev/null +++ b/source-android/friendiqa.pro.user @@ -0,0 +1,713 @@ + + + + + + EnvironmentId + {8825bc46-5cad-4a59-be78-bf9eeaa7217a} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + + + ProjectExplorer.Project.Target.0 + + Android + Android + {8e3757e7-5698-4d0f-9f13-55359b1a832e} + 1 + 0 + 0 + + /home/pankraz/build/debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + true + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/pankraz/build/release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + /home/pankraz/ownCloud/clientsync/android_release.keystore + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + true + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/pankraz/build/profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + true + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + + true + Deployment auf Android-Gerät + + Qt4ProjectManager.AndroidDeployQtStep + false + + 1 + Deployment + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deployment auf Android-Gerät + Deployment auf Android-Gerät + Qt4ProjectManager.AndroidDeployConfiguration2 + + 1 + + CB5A22HSB9 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + + + friendiqa + + Qt4ProjectManager.AndroidRunConfiguration:/home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/source-android/friendiqa.pro + friendiqa.pro + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.Target.1 + + Android for armeabi-v7a (GCC 4.9, Qt 5.9.1 for Android armv7) + Android for armeabi-v7a (GCC 4.9, Qt 5.9.1 for Android armv7) + {24723259-836b-41bd-b02d-59d6a39363d2} + 0 + 0 + 0 + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/build-friendiqa-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_1_for_Android_armv7-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + true + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/build-friendiqa-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_1_for_Android_armv7-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + true + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/build-friendiqa-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_1_for_Android_armv7-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + true + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + + true + Deployment auf Android-Gerät + + Qt4ProjectManager.AndroidDeployQtStep + false + + 1 + Deployment + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deployment auf Android-Gerät + Deployment auf Android-Gerät + Qt4ProjectManager.AndroidDeployConfiguration2 + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + + + friendiqa + + Qt4ProjectManager.AndroidRunConfiguration:/home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/source-android/friendiqa.pro + friendiqa.pro + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/source-android/friendiqa.pro.user.feb2a9e b/source-android/friendiqa.pro.user.feb2a9e new file mode 100644 index 0000000..75267e8 --- /dev/null +++ b/source-android/friendiqa.pro.user.feb2a9e @@ -0,0 +1,390 @@ + + + + + + EnvironmentId + {feb2a9e8-6b42-4908-9ecd-b9e4d47e7412} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Android for armeabi-v7a (GCC 4.9, Qt 5.9.1 for Android armv7) + Android for armeabi-v7a (GCC 4.9, Qt 5.9.1 for Android armv7) + {d23c4988-3f50-4390-a021-93c3e1352521} + 0 + 0 + 0 + + /home/pankraz/bin/Friendiqa + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + /home/pankraz/ownCloud/clientsync/android_release.keystore + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + false + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/build-friendiqa-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_1_for_Android_armv7-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + false + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/build-friendiqa-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_1_for_Android_armv7-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + + true + Anwendungsdaten kopieren + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-25 + + true + Android-APK erstellen + + QmakeProjectManager.AndroidBuildApkStep + 2 + false + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + + true + Deployment auf Android-Gerät + + Qt4ProjectManager.AndroidDeployQtStep + false + + 1 + Deployment + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deployment auf Android-Gerät + Deployment auf Android-Gerät + Qt4ProjectManager.AndroidDeployConfiguration2 + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + + + friendiqa + + Qt4ProjectManager.AndroidRunConfiguration:/home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/source-android/friendiqa.pro + friendiqa.pro + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/source-android/images/addImage.png b/source-android/images/addImage.png new file mode 100644 index 0000000..988f9f1 Binary files /dev/null and b/source-android/images/addImage.png differ diff --git a/source-android/js/helper.js b/source-android/js/helper.js index 4deece4..37f00bf 100644 --- a/source-android/js/helper.js +++ b/source-android/js/helper.js @@ -22,7 +22,7 @@ function friendicaRequest(login,api,rootwindow,callback) { xhrequest.send(); } -function friendicaPostRequest(login,api,rootwindow,callback) { +function friendicaPostRequest(login,api,data,method,rootwindow,callback) { var xhrequest= new XMLHttpRequest(); xhrequest.onreadystatechange = function() { //print(api+JSON.stringify(login)+Qt.atob(login.password)); @@ -40,9 +40,10 @@ function friendicaPostRequest(login,api,rootwindow,callback) { } } } - xhrequest.open("POST", login.server+api,true,login.username,Qt.atob(login.password)); - xhrequest.send(); + xhrequest.open(method, login.server+api,true,login.username,Qt.atob(login.password)); + xhrequest.send(data); } + function getCount(database,login,table,field,countvalue){ var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var count=0; @@ -111,7 +112,7 @@ var where = " AND "+ filter +" = '" + filtervalue+"'"; }); } -function showMessage(header,message,rootwindow){print("message: "+message); +function showMessage(header,message,rootwindow){//print("message: "+message); var cleanmessage=message.replace(/"/g,"-"); var messageString='import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:"'+header+'";standardButtons: StandardButton.Ok; text:" '+cleanmessage+'"}'; var messageObject=Qt.createQmlObject(messageString,rootwindow,"messageOutput"); diff --git a/source-android/js/news.js b/source-android/js/news.js index 98798ae..8c1c26c 100644 --- a/source-android/js/news.js +++ b/source-android/js/news.js @@ -29,6 +29,30 @@ function requestGroups(login,database,rootwindow,callback){ }); })} +function listFriends(login,database,callback){ + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=1'); // check for friends + var contactlist=[]; + for (var i=0;i1){ - var helpernews=newsrs.rows.item(0); - helpernews.newscount=newsrs.rows.length; - helpernews=fetchUsersForNews(database,user,helpernews) - newsArray.push(helpernews); - //} -} - callback(newsArray); - })} + var helpernews=newsrs.rows.item(0); + helpernews.newscount=newsrs.rows.length; + helpernews=fetchUsersForNews(database,user,helpernews); + //var chatArray=[]; + // for (var k=0;k 0 ) { diff --git a/source-android/js/newsworker.js b/source-android/js/newsworker.js index c350a70..8e912fb 100644 --- a/source-android/js/newsworker.js +++ b/source-android/js/newsworker.js @@ -1,6 +1,11 @@ WorkerScript.onMessage = function(msg) { - if(msg.appendnews!==true){ msg.model.clear()}; - +if(msg.deleteId) + {msg.model.remove(msg.deleteId); + msg.model.sync() +} +else{ + if(msg.appendnews!==true){msg.model.clear()}; + msg.model.sync() for (var j=0;j0){ if (newsitemobject.like.length==1){likeText= Qt.atob(newsitemobject.like[0].name)+" "+ qsTr("likes this.")} else {likeText= newsitemobject.like.length+" "+ qsTr("like this.")} @@ -40,33 +48,38 @@ WorkerScript.onMessage = function(msg) { if (newsitemobject.friendica_activities_self.indexOf(5)!=-1){self.attending=qsTr("maybe")} if (newsitemobject.friendica_activities_self.indexOf(1)!=-1){self.liked=1} if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1} - } - var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText,self:self} + }} catch(e){print("Activities "+e)} + var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText,self:self} - var attachmentList=[];if(newsitemobject.attachments){ + var attachmentList=[];try{if(newsitemobject.attachments){ var attachArray=JSON.parse(Qt.atob(newsitemobject.attachments)); for (var image in attachArray){if(attachArray[image].mimetype=="image/gif"){ attachmentList.push(attachArray[image]) } } - } + }}catch(e){print("attachment "+e)} newsitemobject.attachmentList=attachmentList; var seconds=(msg.currentTime-newsitemobject.created_at)/1000; - var timestring=""; - if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");} - else if (seconds<90){timestring=Math.round(seconds/60)+" "+qsTr("minute") +" "+qsTr("ago");} - else if (seconds<3600){timestring=Math.round(seconds/60)+" "+qsTr("minutes") +" "+qsTr("ago");} - else if (seconds<5400){timestring=Math.round(seconds/3600)+" "+qsTr("hour") +" "+qsTr("ago");} - else if (seconds<86400){timestring=Math.round(seconds/3600)+" "+qsTr("hours") +" "+qsTr("ago");} - else if (seconds<129600){timestring=Math.round(seconds/86400)+" "+qsTr("day") +" "+qsTr("ago");} - else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");} - else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");} - else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");} - else {timestring=Math.round(seconds/46656000)+" "+qsTr("years") +" "+qsTr("ago");} - var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities})} - //print("News:"+j+msg.news.length+JSON.stringify(data)); - msg.model.append(data);} - if (j==msg.news.length){ - msg.model.sync() - }; + var timestring=""; + if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");} + else if (seconds<90){timestring=Math.round(seconds/60)+" "+qsTr("minute") +" "+qsTr("ago");} + else if (seconds<3600){timestring=Math.round(seconds/60)+" "+qsTr("minutes") +" "+qsTr("ago");} + else if (seconds<5400){timestring=Math.round(seconds/3600)+" "+qsTr("hour") +" "+qsTr("ago");} + else if (seconds<86400){timestring=Math.round(seconds/3600)+" "+qsTr("hours") +" "+qsTr("ago");} + else if (seconds<129600){timestring=Math.round(seconds/86400)+" "+qsTr("day") +" "+qsTr("ago");} + else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");} + else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");} + else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");} + else {timestring=Math.round(seconds/46656000)+" "+qsTr("years") +" "+qsTr("ago");} + + var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities,"forumname":forumname})} + //print("News:"+j+msg.news.length+JSON.stringify(data)); + msg.model.append(data) + } + + if (j==msg.news.length){ + //print("j: "+j+" msg.model.count: "+msg.model.count); + msg.model.sync() +} +} } diff --git a/source-android/js/service.js b/source-android/js/service.js index 8ea1252..2b82e49 100644 --- a/source-android/js/service.js +++ b/source-android/js/service.js @@ -24,43 +24,79 @@ function requestList(login,database,rootwindow,callback) { function dataRequest(login,photoID,database,rootwindow) { // check if image exist and call download function Helperjs.friendicaRequest(login,"/api/friendica/photo?photo_id="+photoID, rootwindow, function (image){ - try{ if(image==""){currentimageno=currentimageno+1}else{ - var obj = JSON.parse(image); - var helpfilename=obj.filename.substring(0,obj.filename.lastIndexOf(".")); - var filesuffix=""; - if (obj.type=="image/jpeg"){filesuffix=".jpg"} - else if (obj.type=="image/png"){filesuffix=".png"} - else {filesuffix=""} - - if (helpfilename==""){// check if file has any filename - obj.filename=obj["id"]+filesuffix; - } - else{obj.filename=helpfilename+filesuffix} - - var link=""; - if(obj["link"][0]){link=obj["link"][0]} else{link=obj["link"]["4"]} - xhr.setUrl(Qt.resolvedUrl(link)); - xhr.setFilename(login.imagestore+'albums/'+obj.album+"/"+obj["filename"]); - xhr.setDownloadtype("picture"); - xhr.download(); - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - db.transaction( function(tx) { - var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"'); - if(result.rows.length === 1) {// use update - result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+obj.id+'", created="'+obj.created+'", edited="'+obj.edited+'", profile="'+obj.profile+'", link="'+obj["link"]["4"]+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", location="file://'+login.imagestore+'albums/'+obj.album+'/" where id="'+obj["id"]+'"'); - } else {// use insert print('... does not exists, create it') - result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,obj.id,obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width,obj. profile,obj["link"]["4"],'file://'+login.imagestore+'albums/'+obj.album+"/"]); - } - })}} + try{ if(image==""){currentimageno=currentimageno+1}else{ + var obj = JSON.parse(image); + var helpfilename=obj.filename.substring(0,obj.filename.lastIndexOf(".")); + var filesuffix=""; + if (obj.type=="image/jpeg"){filesuffix=".jpg"} + else if (obj.type=="image/png"){filesuffix=".png"} + else {filesuffix=""} + if (helpfilename==""){// check if file has any filename + obj.filename=obj["id"]+filesuffix; + } + else{obj.filename=helpfilename+filesuffix} + var link=""; + if(obj["link"][0]){link=obj["link"][0]} else{link=obj["link"]["4"]} + xhr.setUrl(Qt.resolvedUrl(link)); + xhr.setFilename(login.imagestore+'albums/'+obj.album+"/"+obj["filename"]); + xhr.setDownloadtype("picture"); + xhr.download(); + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"'); + if(result.rows.length === 1) {// use update + result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+obj.id+'", created="'+obj.created+'", edited="'+obj.edited+'", profile="'+obj.profile+'", link="'+obj["link"]["4"]+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", location="file://'+login.imagestore+'albums/'+obj.album+'/" where id="'+obj["id"]+'"'); + } else {// use insert print('... does not exists, create it') + result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,obj.id,obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width,obj. profile,obj["link"]["4"],'file://'+login.imagestore+'albums/'+obj.album+"/"]); + } + })}} catch (e){print("Data retrieval failure! "+ e+obj);} })} -function deleteImageData(database,user,field,selection,callback) { // does nothing useful at the moment +function deleteImage(database,login,type,location,rootwindow,callback) { // delete image locally and on server + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + var rsfilename=location.substring(location.lastIndexOf("/")+1,location.length); + var rslocation=location.substring(0,location.lastIndexOf("/")+1); + //print(type+" Name "+ rsfilename+" Location: "+rslocation) + db.transaction( function(tx) { + if (type=='image'){ + var rs= tx.executeSql('SELECT * FROM imageData WHERE filename="'+rsfilename+'" AND location="'+rslocation+'"') + var imageId=rs.rows.item(0).id; + Helperjs.friendicaPostRequest(login,"/api/friendica/photo/delete?photo_id="+imageId,"","DELETE",rootwindow, function (obj){ + //var deletereturn = JSON.parse(obj); print(obj); + //if (deletereturn.result=="deleted"){ + db.transaction( function(tx) { + var deleters=tx.executeSql('DELETE FROM imageData WHERE location="'+rslocation+'" AND filename="'+rsfilename+'"'); }); + filesystem.Directory=rslocation.substring(7,rslocation.length-1); + filesystem.rmFile(rsfilename) + //} + }) + } + else{ + Helperjs.friendicaPostRequest(login,"/api/friendica/photoalbum/delete?album="+rsfilename,"","DELETE",rootwindow, function (obj){ + //var deletereturn = JSON.parse(obj); + //if (deletereturn.result=="deleted"){ + db.transaction( function(tx) { + var rs= tx.executeSql('SELECT DISTINCT location FROM imageData WHERE album="'+rsfilename+'" AND username="'+login.username+'"'); + var locationstring=rs.rows.item(0).location; + filesystem.Directory=locationstring.substring(7,locationstring.length-1); + filesystem.rmDir(); + var deleters=tx.executeSql('DELETE FROM imageData WHERE album="'+location+'"'); + }) + //} + }) + } + callback(location) + }) +} + +function deleteContacts(database,user,callback) { // does nothing useful at the moment var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); //print(' delete Image Data() for ' + field +"="+selection) db.transaction( function(tx) { - result = tx.executeSql('UPDATE imageData SET data="" where '+ field +'="'+selection+'"'); + result1= tx.executeSql('SELECT * FROM contacts a LEFT OUTER JOIN news b ON a.url==b.uid'); + result2= tx.executeSql('SELECT * FROM contacts a LEFT OUTER JOIN news b ON a.url==b.uid'); callback(result)}) } @@ -98,7 +134,6 @@ function requestFriendsPictures(link,rootwindow,callback){ for (var i=0;icurrentts) || (image_timestamp==0)){ + xhr.setUrl(Qt.resolvedUrl(contact.profile_image_url)); + xhr.setFilename(imagename); + xhr.setDownloadtype("contact"); + xhr.download(); + } + var result; result = tx.executeSql('SELECT * from contacts where username="'+login.username+'" AND url = "'+contact.url+'"'); // check for news url if(result.rows.length === 1) {// use update - result = tx.executeSql('UPDATE contacts SET id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",imageAge='+currentTime+', profile_image_url="'+contact.profile_image_url+'", description="'+Qt.btoa(contact.description)+'", profile_image="'+imagename+'", protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ Date.parse(Newsjs.cleanDate(contact.created_at))+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+' where username="'+login.username+'" AND url="'+contact.url+'"'); + result = tx.executeSql('UPDATE contacts SET id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",imageAge='+currentTime+', profile_image_url="'+contact.profile_image_url+'", description="'+Qt.btoa(contact.description)+'", profile_image="'+imagename+'", protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ Date.parse(Newsjs.cleanDate(contact.created_at))+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+', timestamp='+ image_timestamp+' where username="'+login.username+'" AND url="'+contact.url+'"'); } else {// use insert - result = tx.executeSql('INSERT INTO contacts VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,contact.id,Qt.btoa(contact.name),contact.screen_name,contact.location,currentTime,contact.profile_image_url, Qt.btoa(contact.description),imagename,contact.url,contact.protected,contact.followers_count, contact.friends_count,Date.parse(Newsjs.cleanDate(contact.created_at)),contact.favorites_count,contact.utc_offset,contact.time_zone,contact.statuses_count,contact.following,contact.verfied,contact.statusnet_blocking,contact.notifications,contact.statusnet_profile_url,contact.cid,contact.network,isFriend]);} + result = tx.executeSql('INSERT INTO contacts VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,contact.id,Qt.btoa(contact.name),contact.screen_name,contact.location,currentTime,contact.profile_image_url, Qt.btoa(contact.description),imagename,contact.url,contact.protected,contact.followers_count, contact.friends_count,Date.parse(Newsjs.cleanDate(contact.created_at)),contact.favorites_count,contact.utc_offset,contact.time_zone,contact.statuses_count,contact.following,contact.verfied,contact.statusnet_blocking,contact.notifications,contact.statusnet_profile_url,contact.cid,contact.network,isFriend,image_timestamp]);} }); -} +}} diff --git a/source-android/qml/calendarqml/CalendarTab.qml b/source-android/qml/calendarqml/CalendarTab.qml index 7127a31..fe106f5 100644 --- a/source-android/qml/calendarqml/CalendarTab.qml +++ b/source-android/qml/calendarqml/CalendarTab.qml @@ -18,7 +18,7 @@ Rectangle { property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000 property var events:[] property var eventdays:[] - onEventdaysChanged: print(JSON.stringify(eventdays)) + //onEventdaysChanged: print(JSON.stringify(eventdays)) function showEvents(friend){ if(friend=="backButton"){Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ @@ -32,10 +32,10 @@ Rectangle { eventdays=dayArray}) } else {calendartab.calendartabstatus="Events"; - Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ - events=eventArray; - eventdays=dayArray; - calBusy.running=false + Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ + events=eventArray; + eventdays=dayArray; + calBusy.running=false }) } } diff --git a/source-android/qml/configqml/ConfigTab.qml b/source-android/qml/configqml/ConfigTab.qml index 32957b6..3b6ff57 100644 --- a/source-android/qml/configqml/ConfigTab.qml +++ b/source-android/qml/configqml/ConfigTab.qml @@ -1,6 +1,7 @@ import QtQuick 2.7 import QtQuick.Dialogs 1.2 import QtQuick.Controls 1.2 + import "qrc:/js/service.js" as Service import "qrc:/js/layout.js" as Layoutjs import "qrc:/js/helper.js" as Helperjs diff --git a/source-android/qml/configqml/InfoBox.qml b/source-android/qml/configqml/InfoBox.qml index 7c3932a..fc6d935 100644 --- a/source-android/qml/configqml/InfoBox.qml +++ b/source-android/qml/configqml/InfoBox.qml @@ -10,15 +10,17 @@ Rectangle{ anchors.top:closeButton.bottom anchors.topMargin: mm textFormat: Text.RichText - wrapMode: Text.Wrap - text: "Friendiqa v0.003
Licensed under GPL 3
"+ + width: parent.width + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + text: "Friendiqa v0.1
Licensed under GPL 3
"+ "Profile https://freunde.ma-nic.de/profile/friendiqa
"+ "Sourcecode: https://github.com/LubuWest/Friendica
"+ "C++ code by Fabio
"+ "QML and Javascript code by Marco
"+ "Qt Framework www.qt.io
"+ "Icons by FontAwesome
"+ - "Folder Icon by KDE Breeze Icons" + "Folder Icon by KDE Breeze Icons
"+ + "AndroidNative by Ben Lau" onLinkActivated:{ Qt.openUrlExternally(link)} } @@ -28,7 +30,7 @@ Rectangle{ anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm - text: "\uf057" //qsTr("Close") + text: "\uf057" onClicked:{configStack.pop()} } } diff --git a/source-android/qml/contactqml/ContactComponent.qml b/source-android/qml/contactqml/ContactComponent.qml index 2c8a671..75112ee 100644 --- a/source-android/qml/contactqml/ContactComponent.qml +++ b/source-android/qml/contactqml/ContactComponent.qml @@ -20,7 +20,7 @@ Rectangle { width: 10*mm height:10*mm source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url - onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + onStatusChanged: {if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}} } Label { diff --git a/source-android/qml/contactqml/ContactDetailsComponent.qml b/source-android/qml/contactqml/ContactDetailsComponent.qml index 3f797a2..db2da09 100644 --- a/source-android/qml/contactqml/ContactDetailsComponent.qml +++ b/source-android/qml/contactqml/ContactDetailsComponent.qml @@ -13,8 +13,8 @@ property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend==1)?"" Rectangle { id: wrapper - width:friendsTabView.width; - height:friendsTabView.height-15*mm + width:root.width-2*mm //friendsTabView.width; + height:root.height-20*mm// friendsTabView.height-15*mm border.color: "grey" color:"white" Image { @@ -30,7 +30,7 @@ Rectangle { Label { id: namelabel x: mm - width:friendsTabView.width-4*mm + width: root.width-6*mm //friendsTabView.width-4*mm height: 3*mm text:Qt.atob(contact.name)+" (@"+contact.screen_name+")" elide:Text.ElideRight @@ -50,7 +50,7 @@ Rectangle{ frameVisible: true id:namelabelflickable width: root.width-10*mm - height:friendsTabView.height-45*mm + height:root.height-50*mm//friendsTabView.height-45*mm x: mm clip:true Text{ @@ -83,6 +83,7 @@ Rectangle{ root.currentIndex=2; fotostab.active=true; root.fotoSignal(contact) ; + contactLargeComponent.destroy(); } } @@ -93,6 +94,7 @@ Rectangle{ root.currentIndex=0; newstab.active=true; root.messageSignal(contact.id) ; + contactLargeComponent.destroy(); } } @@ -104,6 +106,7 @@ Rectangle{ root.currentIndex=0; newstab.active=true; root.directmessageSignal(contact.screen_name); + contactLargeComponent.destroy(); } } @@ -117,6 +120,7 @@ Rectangle{ calendartab.active=true; calendartab.calendartabstatus="Friend" root.eventSignal(contact.url); + contactLargeComponent.destroy(); } } @@ -124,8 +128,7 @@ Rectangle{ id: closeButton text: "\uf057" //"close" onClicked:{contactLargeComponent.destroy(); - //contactComponent.state=""; - friendsTabView.contactSignal} + } } } } diff --git a/source-android/qml/contactqml/Contactlist.qml b/source-android/qml/contactqml/Contactlist.qml new file mode 100644 index 0000000..6aa6991 --- /dev/null +++ b/source-android/qml/contactqml/Contactlist.qml @@ -0,0 +1,101 @@ +// List of people +import QtQuick 2.0 +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Rectangle { + id:contactlistRectangle + property var contacts:[] + property var possibleUsers: [] + //y:8*mm + color: "white" + border.color: "light grey" + radius:0.5*mm + width:groupListView.width + height:groupListView.height + + ListView { + id: contactView + x:mm + y:6*mm + width: contactlistRectangle.width-2*mm + height: contactlistRectangle.height-10*mm + clip: true + spacing: 0 + model: contactModel + delegate: listContact + } + + ListModel{id: contactModel} + + Component { id:listContact + Rectangle{ + border.color: "#EEEEEE" + border.width: 1 + radius:0.5*mm + width:contactView.width + height:6*mm + Image { + id: contactImage + x:1 + y:1 + width: 5*mm + height:5*mm + source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url + onStatusChanged: if (contactImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + } + Text{ + font.pixelSize: 3*mm + anchors.left: contactImage.right + anchors.margins: 1*mm + text:Qt.atob(contact.name) + } + Text { + id:selected + anchors.right:parent.right + visible: contactlist.indexOf(contact)>-1 + z:4 + text: "\u2713" + width: 5*mm + anchors.top: parent.top + color: "green" + font.pixelSize: 3*mm + } + + MouseArea{ + anchors.fill: parent + onClicked:{ + if(selected.visible==true){ + contacts.splice(Helperjs.inArray(contacts,"id",contact.id),1); + selected.visible=false + } + else{ + contacts.push(contact); + selected.visible=true; + } + } + } + } + } + + BlueButton { + id: closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + color:"white" + text: "\uf057" + onClicked: { + groupModelAppend(contacts,function(){ + contactlistRectangle.destroy() + }); + } + } + + Component.onCompleted: { + for (var user in possibleUsers){ + contactModel.append({"contact":possibleUsers[user]}) + } + } +} diff --git a/source-android/qml/contactqml/FriendsTab.qml b/source-android/qml/contactqml/FriendsTab.qml index a82ce97..2c1e3d7 100644 --- a/source-android/qml/contactqml/FriendsTab.qml +++ b/source-android/qml/contactqml/FriendsTab.qml @@ -3,6 +3,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs +import "qrc:/js/service.js" as Service import "qrc:/qml/contactqml" import "qrc:/qml/genericqml" @@ -20,6 +21,9 @@ Rectangle { var contactDetails = component.createObject(friendstab,{"contact": contact}) } } + + + TabView{ id:friendsTabView tabPosition: Qt.TopEdge @@ -63,7 +67,7 @@ Rectangle { id: friendsGridTab function showFriends(contact){ try {friendsModel.clear()} catch(e){print(e)}; - Helperjs.readData(db,"contacts",root.login.username,function(friendsobject){ + Helperjs.readData(db,"contacts",login.username,function(friendsobject){ for (var i=0;i1){ friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid @@ -140,13 +144,30 @@ Rectangle { } },"isFriend",0,"screen_name ASC"); } + BlueButton { + id: cleanButton + text: "\uf021" + anchors.top: parent.top + anchors.topMargin: mm + anchors.right: parent.right + onClicked: { + Service.cleanContacts(root.login,root.db,function(){ + try {contactsModel.clear()} catch(e){print(e)}; + Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){ + for (var j=0;j-1 + z:4 + text: "\u2713" + width: 10*mm + anchors.top: folderImage.top + color: "green" + font.pixelSize: 10*mm + } + + Image{id:folderImage + width: fileIsDir?10*mm: imageView.width-mm + fillMode:Image.PreserveAspectFit + source:fileIsDir?"qrc:/images/folder-blue.png":fileURL + } + + MouseArea{ + anchors.fill: parent + onClicked:{ + if (fileName==".."){ + imageModel.folder=imageModel.parentFolder; + directory=imageModel.parentFolder + } + else if (fileIsDir){ + imageModel.folder=fileURL; + directory=fileURL + } + else{ + if (multiSelection!=true){ + attachImageURLs.push(fileURL); + attachImage(fileURL); + imageDialog.destroy() + } + else { + if(selected.visible==true){ + attachImageURLs.splice(attachImageURLs.indexOf(fileURL,1)) + selected.visible=false + } + else{ + attachImageURLs.push(fileURL); + selected.visible=true; + + } + attachImage(fileURL) + } + } + } + } + } + } +} diff --git a/source-android/qml/genericqml/ImagePicker.qml b/source-android/qml/genericqml/ImagePicker.qml new file mode 100644 index 0000000..ffbfe43 --- /dev/null +++ b/source-android/qml/genericqml/ImagePicker.qml @@ -0,0 +1,59 @@ +import QtQuick 2.0 +import AndroidNative 1.0 + +Item { + + /// Set it to true if multiple images should be picked. + property bool multiple: false + + /// If it is true, it will broadcast the taked photo to other application (e.g Let it show in Google Photos) + property bool broadcast: true + + /// 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: [] + + /// It is emitted whatever photo(s) are picked/taken. + signal ready(); + + function pickImage() { + SystemDispatcher.dispatch(m_PICK_IMAGE_MESSAGE,{ multiple: multiple}); + } + + function takePhoto() { + SystemDispatcher.dispatch(m_TAKE_PHOTO_MESSAGE,{ + broadcast: broadcast + }) + } + + property string m_PICK_IMAGE_MESSAGE: "androidnative.ImagePicker.pickImage"; + + property string m_TAKE_PHOTO_MESSAGE: "androidnative.ImagePicker.takePhoto"; + + property string m_CHOSEN_MESSAGE: "androidnative.ImagePicker.chosen"; + + + Connections { + target: SystemDispatcher + onDispatched: { + if (type === m_CHOSEN_MESSAGE) { + //imageUrls = message.imageUrls; + //imageUrl = imageUrls[0]; + var h=[]; + for (var n in message.imageUrls){ + h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5)) + } + imageUrls=h; + imageUrl=h[0]; + ready(); + } + } + } + + Component.onCompleted: { + SystemDispatcher.loadClass("androidnative.ImagePicker"); + } +} + diff --git a/source-android/qml/genericqml/OSSettingsAndroid.qml b/source-android/qml/genericqml/OSSettingsAndroid.qml deleted file mode 100644 index 76bc3ff..0000000 --- a/source-android/qml/genericqml/OSSettingsAndroid.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Window 2.0 -QtObject{ - property int appWidth: Screen.desktopAvailableWidth - property int appHeight: Screen.desktopAvailableHeight - property int backKey: Qt.Key_Back - property string attachImageDir:filesystem.cameraPath+"/" -} diff --git a/source-android/qml/genericqml/OSSettingsLinux.qml b/source-android/qml/genericqml/OSSettingsLinux.qml deleted file mode 100644 index 567e582..0000000 --- a/source-android/qml/genericqml/OSSettingsLinux.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 -QtObject{ - property real appWidth: 500 - property real appHeight: 500 - property int backKey: Qt.Key_Escape - property string attachImageDir:filesystem.homePath+"/Pictures/" -} diff --git a/source-android/qml/genericqml/PermissionDialog.qml b/source-android/qml/genericqml/PermissionDialog.qml new file mode 100644 index 0000000..172f971 --- /dev/null +++ b/source-android/qml/genericqml/PermissionDialog.qml @@ -0,0 +1,189 @@ +import QtQuick 2.0 +import "qrc:/js/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Rectangle{ + id:permissionDialog +// x: mm + width: parent.width-5*mm + height:root.height/3 + function updatePerms(){ + for (var i=0;i-1){contactstatus="positive"} + else if (contact_deny.indexOf(contacts[name].cid)>-1){contactstatus="negative"} + contactModel.append({"contact":contacts[name],"contactstatus":contactstatus}) + }},"isFriend",1); + + Helperjs.readData(db,"groups",login.username,function(owngroups){ + for (var number in owngroups){ + var groupstatus= "neutral"; + if (group_allow.indexOf(owngroups[number].gid)>-1){groupstatus="positive"} + else if (group_deny.indexOf(owngroups[number].gid)>-1){groupstatus="negative"} + groupModel.append({"group":owngroups[number],"groupstatus":groupstatus}) + }}); + } +} diff --git a/source-android/qml/newsqml/Conversation.qml b/source-android/qml/newsqml/Conversation.qml index 4864f91..3ca9eb1 100644 --- a/source-android/qml/newsqml/Conversation.qml +++ b/source-android/qml/newsqml/Conversation.qml @@ -1,26 +1,18 @@ // ConversationView with button import QtQuick 2.0 +import QtQuick.Controls 1.2 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" Rectangle { id:conversationList - property var news + //property var news y:1 z:2 color: "white" border.color: "grey" width:root.width-5*mm height: conversationView.height+10*mm - Connections{ - target:newstab - onConversationChanged:{ - if(newstab.conversation.length==0){ - newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning); - conversationList.destroy(); conversationsymbol.color="grey" - } - } - } ListView { id: conversationView @@ -34,6 +26,32 @@ Rectangle { model: conversationModel delegate: Newsitem{} } + BusyIndicator{ + id: conversationBusy + anchors.horizontalCenter: conversationView.horizontalCenter + anchors.top:conversationList.top + anchors.topMargin: 2*mm + width:10*mm + height: 10*mm + running: true + } + + Connections{ + target:newstab + onConversationChanged:{ + if(newsitem.itemindex==newsStack.conversationIndex){ + if(newstab.conversation.length==0){ + newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning); + conversationList.destroy(); conversationsymbol.color="grey" + } else { conversationBusy.running=false; + conversationModel.clear(); + var currentTime= new Date(); + var msg = {'currentTime': currentTime, 'model': conversationModel,'news':newstab.conversation}; + conversationWorker.sendMessage(msg) + conversationsymbol.color="grey"} + } + } + } Component { id:footerReply Rectangle{ @@ -117,9 +135,9 @@ Rectangle { } } - Component.onCompleted: { - var currentTime= new Date(); - var msg = {'currentTime': currentTime, 'model': conversationModel,'news':news}; - conversationWorker.sendMessage(msg) - } +// Component.onCompleted: { +// if (news){var currentTime= new Date(); +// var msg = {'currentTime': currentTime, 'model': conversationModel,'news':news}; +// conversationWorker.sendMessage(msg)} +// } } diff --git a/source-android/qml/newsqml/FriendicaActivities.qml b/source-android/qml/newsqml/FriendicaActivities.qml index ac97306..d325a2a 100644 --- a/source-android/qml/newsqml/FriendicaActivities.qml +++ b/source-android/qml/newsqml/FriendicaActivities.qml @@ -1,4 +1,4 @@ -// List if people from Friendica Activities +// List of people from Friendica Activities import QtQuick 2.0 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -51,11 +51,7 @@ Rectangle { MouseArea{ anchors.fill: parent - onClicked:{ - try {root.currentIndex=1; - friendstab.active=true; - root.contactdetailsSignal(contact) - } catch(e) {Helperjs.showMessage("Error",e,root)}} + onClicked:{showContact(contact)} } }} diff --git a/source-android/qml/newsqml/ImageDialog.qml b/source-android/qml/newsqml/ImageDialog.qml deleted file mode 100644 index 34add5a..0000000 --- a/source-android/qml/newsqml/ImageDialog.qml +++ /dev/null @@ -1,121 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.2 -import Qt.labs.folderlistmodel 2.1 -import "qrc:/js/service.js" as Service -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/genericqml" - -Rectangle{ - id:imageDialog - z:2 - border.color: "grey" - width: parent.width-4*mm - height:parent.height-12*mm - x:2*mm - y:10*mm - property string directory: "" - - Text{ - id:directoryText - x:0.5*mm - y:0.5*mm - width: imageDialog.width-15*mm - height:contentHeight - wrapMode: Text.Wrap - text: directory - } - BlueButton{ - id:closeButton - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - onClicked:{imageDialog.destroy()} - } - ListView { - id: imageView - x:0.5*mm - y:directoryText.height+mm - width: imageDialog.width-2*mm - height: imageDialog.height-directoryText.height-4*mm - clip: true - model: imageModel - delegate: imageItem - } - - FolderListModel{ - id: imageModel - nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG","*.gif"] - sortField: FolderListModel.Time - sortReversed:false - showDotAndDotDot: true - showDirs: true - showDirsFirst: true - folder:directory - } - - BusyIndicator{ - id: imageBusy - anchors.horizontalCenter: imageView.horizontalCenter - anchors.top:imageView.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - running:false - } - - - Component{ - id:imageItem - Item{ - width:imageView.width - height:folderImage.height+2*mm - Rectangle{ - id:imagetextRectangle - color:"black" - x:mm - z:3 - opacity: fileIsDir?0:0.5 - width:imagetext.contentWidth - height: imagetext.contentHeight - anchors.bottom: folderImage.bottom - } - Text { - id:imagetext - x:fileIsDir?11*mm:mm - z:4 - text: fileName - width: fileIsDir?parent.width - 12*mm :imageView.width-mm - anchors.bottom: folderImage.bottom - color: fileIsDir?"black":"white" - font.pixelSize: 3*mm - wrapMode:Text.Wrap - } - Image{id:folderImage - width: fileIsDir?10*mm: imageView.width-mm - fillMode:Image.PreserveAspectFit - source:fileIsDir?"qrc:/images/folder-blue.png":fileURL - } - - MouseArea{ - anchors.fill: parent - onClicked:{ - if (fileName==".."){ - imageModel.folder=imageModel.parentFolder; - directory=imageModel.parentFolder - } - else if (fileIsDir){ - imageModel.folder=fileURL; - directory=fileURL - } - else{ - attachImageURLs.push(fileURL); - attachImage(fileURL); - imageDialog.destroy() - } - } - } - } - } -} diff --git a/source-android/qml/newsqml/MessageSend.qml b/source-android/qml/newsqml/MessageSend.qml index a093cc8..e7c6552 100644 --- a/source-android/qml/newsqml/MessageSend.qml +++ b/source-android/qml/newsqml/MessageSend.qml @@ -26,10 +26,8 @@ Flickable{ property var group_deny:login.permissions[3] function attachImage(url){ - //onAttachImageURLsChanged: {if(attachImageURL!=""){ - 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"); - console.log("You chose: " + 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"); } function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { @@ -125,12 +123,21 @@ Flickable{ } Row{ + + ImagePicker { + id: imagePicker; + multiple : false + onReady: { + attachImageURLs.push(imagePicker.imageUrl); + attachImage(imagePicker.imageUrl) + } + } spacing:2 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/newsqml/PermissionDialog.qml"); + var component = Qt.createComponent("qrc:/qml/genericqml/PermissionDialog.qml"); var permissions = component.createObject(messageColumn); }} BlueButton { @@ -142,9 +149,10 @@ Flickable{ Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn) } else{ - var defaultDirectory="file://"+osSettings.attachImageDir; - var component = Qt.createComponent("qrc:/qml/newsqml/ImageDialog.qml"); - var imagedialog = component.createObject(messageSend,{"directory": defaultDirectory}); + //var defaultDirectory="file://"+osSettings.attachImageDir; + //var component = Qt.createComponent("qrc:/qml/genericqml/ImageDialog.qml"); + //var imagedialog = component.createObject(messageSend,{"directory": defaultDirectory}); + imagePicker.pickImage() } } } @@ -159,7 +167,7 @@ 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+"+"+contacts[i].cid+" ')}" + contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"';iconSource:'"+contacts[i].profile_image+"'; onTriggered: bodyField.insert(0,' @"+contacts[i].screen_name+" ')}" }} var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}"; var contactlistObject=Qt.createQmlObject(menuString,messageSend,"contactmenuOutput") @@ -171,7 +179,6 @@ Flickable{ text: "\uf118" onClicked: { var smileyarray=Smileyjs.smileys - //print(JSON.stringify(smileyarray[0])) var component = Qt.createComponent("qrc:/qml/newsqml/SmileyDialog.qml"); var smileydialog = component.createObject(messageColumn) }} diff --git a/source-android/qml/newsqml/NewsTab.qml b/source-android/qml/newsqml/NewsTab.qml index 14dd731..3d594d2 100644 --- a/source-android/qml/newsqml/NewsTab.qml +++ b/source-android/qml/newsqml/NewsTab.qml @@ -33,13 +33,16 @@ Item { } Timer {id:replytimer; interval: 1000; running: false; repeat: false - onTriggered: {if(newstab.newstabstatus=="Conversation"){ - showConversation(newsStack.timelineIndex-1,newsModel.get(0).newsitemobject)} else{ + onTriggered: { + if(newstab.newstabstatus=="Conversation"){ + showConversation(newsStack.timelineIndex-1,newsModel.get(0).newsitemobject)} + else{ var onlynew=true; Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){ root.contactLoadType="news"; root.news=rns;root.newContacts=rnc;root.currentContact=0}) - }} + } + } } @@ -53,7 +56,7 @@ Item { } function showConversation(conversationIndex,newsitemobject){ - newsBusy.running=true; + //newsBusy.running=true; root.contactLoadType="conversation"; newsStack.conversationIndex= conversationIndex; if(newsitemobject.messagetype==0){ @@ -65,6 +68,13 @@ Item { })} } + function showContact(contact){ + var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml"); + if (component.status== Component.Ready){ + var contactDetails = component.createObject(newstab,{"contact": contact}) + } + } + function onFriendsMessages(friend){ newstab.newstabstatus="Contact" Newsjs.newsfromdb(db,root.login.username, function(dbnews){showNews(dbnews)},friend) @@ -75,6 +85,8 @@ Item { newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1,"login":root.login}}); } + + StackView{ id: newsStack anchors.fill:parent @@ -100,7 +112,6 @@ Item { BlueButton { id: newMessageButton - width:10*mm text: "\uf040" onClicked: { var groups=[]; @@ -115,7 +126,6 @@ Item { } BlueButton { id: quitButton - width:10*mm text: "\uf08b" onClicked: {Service.cleanNews(root.db,function(){Qt.quit() })} } @@ -127,6 +137,7 @@ Item { newstab.newstabstatus=login.newsViewType; root.contactLoadType="news"; var onlynew=true; + //print("newstab "+ JSON.stringify(contactlist)); Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(ns,nc){ root.news=ns;root.newContacts=nc;root.currentContact=0; if (ns.length==0){// update last 20 existing news for changes and likes @@ -153,29 +164,29 @@ Item { } MouseArea{anchors.fill:parent onClicked:{ - var currentTime= new Date(); - if(newstab.newstabstatus=="Timeline"){ - var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; + var currentTime= new Date(); + var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; + print("Lastnews ID "+lastnews_id+Qt.atob(newsModel.get(newsModel.count-1).newsitemobject.statusnet_html)) + if(newstab.newstabstatus=="Timeline"){ Newsjs.newsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; - newsWorker.sendMessage(msg); - },false,lastnews_id)} - if(newstab.newstabstatus=="Conversations"){ - var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; + newsWorker.sendMessage(msg); + },false,lastnews_id)} + if(newstab.newstabstatus=="Conversations"){ Newsjs.chatsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; - newsWorker.sendMessage(msg); - },lastnews_id)} - else if(newstab.newstabstatus=="Contact"){ - Newsjs.newsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; - newsWorker.sendMessage(msg); - },newsModel.get(newsModel.count-1).newsitemobject.uid,newsModel.get(newsModel.count-1).newsitemobject.created_at)} - }} - } + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; + newsWorker.sendMessage(msg); + },lastnews_id)} + else if(newstab.newstabstatus=="Contact"){ + Newsjs.newsfromdb(root.db,root.login.username, function(news){ + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; + newsWorker.sendMessage(msg); + },newsModel.get(newsModel.count-1).newsitemobject.uid,lastnews_id)} + } + } + } } - ListView { id: newsView anchors.fill: parent @@ -187,8 +198,8 @@ Item { footer: footerComponent model: newsModel delegate: Newsitem{} - //onContentYChanged:{if(contentY<-15*mm&&contentY>(-15*mm-1)){print("refreshing"); - onDragEnded:{if(contentY<-8*mm){//print("refreshing"); + //onContentYChanged:{if(contentY<-8*mm&&contentY>(-8*mm-1)){print("refreshing"); + onDragEnded:{if(contentY<-5*mm){//print("refreshing"); newsBusy.running=true; newstab.newstabstatus=login.newsViewType; root.contactLoadType="news"; diff --git a/source-android/qml/newsqml/Newsitem.qml b/source-android/qml/newsqml/Newsitem.qml index d9c9fa7..48e703f 100644 --- a/source-android/qml/newsqml/Newsitem.qml +++ b/source-android/qml/newsqml/Newsitem.qml @@ -10,21 +10,8 @@ Item { width: parent.width height:toprow.height+friendicaActivities.height+controlrow.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm) - Connections{ - target:newstab - onConversationChanged:{ - newsBusy.running=false; - if(index==newsStack.conversationIndex){ - if(newstab.conversation.length>0){ - var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); - var conversation = component.createObject(friendicaActivities,{"news":newstab.conversation}); - } - else{conversationsymbol.color="grey"} - } - } - } - property string attending: "" + property int itemindex: index onAttendingChanged: {attendLabel.visible=true; attendLabel.text= qsTr("attending: ")+ qsTr(attending)} @@ -54,11 +41,7 @@ Item { height: 7*mm MouseArea{ anchors.fill: parent - onClicked:{ - try{root.currentIndex=1; - friendstab.active=true; - root.contactdetailsSignal(newsitemobject.user)} catch (e){Helperjs.showMessage("Error",e,root)} - } + onClicked:{showContact(newsitemobject.user)} } onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} } @@ -68,13 +51,12 @@ Item { width:parent.width font.pixelSize: 1.5*mm wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: Qt.atob(newsitemobject.user.name)//+forumname + text: Qt.atob(newsitemobject.user.name)+forumname } } Column { id:newscolumn width: newsitem.width-8*mm - //anchors.left: authorcolumn.right Flow{ id:topFlow @@ -114,7 +96,13 @@ Item { text: try {(newsitemobject.newscount-1)+qsTr(" comments") }catch(e){" "} MouseArea{ anchors.fill:parent - onClicked: {conversationsymbol.color="black";showConversation(index,newsitemobject)} + onClicked: { + conversationsymbol.color="black"; + newsView.contentY+=newsitem.height; + var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); + var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray}); + showConversation(index,newsitemobject); + } } } } @@ -150,6 +138,7 @@ Item { spacing:mm Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.likeText MouseArea{ @@ -158,6 +147,7 @@ Item { } } Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.dislikeText MouseArea{ @@ -166,6 +156,7 @@ Item { } } Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.attendyesText MouseArea{ @@ -173,6 +164,7 @@ Item { onClicked: { showActivityContacts(newsitemobject.attendyes)} }} Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.attendnoText MouseArea{ @@ -181,6 +173,7 @@ Item { } } Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.attendmaybeText MouseArea{ @@ -190,7 +183,6 @@ Item { } Label{ id:attendLabel - //visible: false color: "grey" height:3.5*mm font.pixelSize: 1.5*mm @@ -203,28 +195,21 @@ Item { CheckBox{ id:likeCheckbox - //height:3*mm - width:8*mm + width:10*mm visible: (newsitemobject.messagetype==0)? true:false checked:(friendica_activities.self.liked==1)?true:false style: CheckBoxStyle { - background: Rectangle { - implicitWidth: 6*mm - implicitHeight: 3*mm - color:"white" - } - indicator: Rectangle{ - implicitWidth: 3*mm - implicitHeight:3*mm - color:control.checked?"yellow":"white" - x: 4*mm - Text{ - anchors.centerIn: parent - font.pixelSize: 2.5*mm - font.family:fontAwesome.name - color:control.checked?"black": "grey" - text:"\uf118" - }} + indicator: Rectangle{ + implicitWidth: 10*mm + implicitHeight:3*mm + Text{ + anchors.centerIn: parent + font.pixelSize: 2.5*mm + font.family:fontAwesome.name + color:control.checked?"black": "grey" + text:"\uf118" + } + } } onClicked: { if(likeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"like",newsitemobject.status_id,root);dislikeCheckbox.checked=false; model.friendica_activities.self.liked=0 } @@ -232,73 +217,43 @@ Item { } CheckBox{ id: dislikeCheckbox - //height:3*mm - width:8*mm + width:10*mm visible: (newsitemobject.messagetype==0)? true:false checked: (friendica_activities.self.disliked==1)?true:false style: CheckBoxStyle { - background: Rectangle { - implicitWidth: 6*mm - implicitHeight:3*mm - color:"white" - } indicator: Rectangle{ - implicitWidth: 3*mm + implicitWidth: 10*mm implicitHeight:3*mm - color:control.checked?"yellow":"white" - x:4*mm Text{ anchors.centerIn: parent font.pixelSize: 2.5*mm font.family:fontAwesome.name color:control.checked?"black": "grey" text: "\uf119" - }} + } } + } onClicked: { if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.status_id,root);likeCheckbox.checked=false; model.friendica_activities.self.disliked=0} else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.status_id,root); model.friendica_activities.self.disliked=1}} } -// Rectangle{ -// width: 8*mm -// height: 3*mm -// color:"transparent" -// Text{ -// id:trashsymbol -// color: "grey" -// anchors.centerIn: parent -// font.pixelSize: 2*mm -// font.bold: true -// text: "\uf1f8" -// } -// MouseArea{ -// anchors.fill:parent -// onClicked: { -// Newsjs.deleteNews(root.login,root.db,newsitemobject.status_id,newsitemobject.messagetype,root,function(reply){ -// newsModel.remove(index)}) -// }} -// } CheckBox { id:favoritedCheckbox visible:(newsitemobject.messagetype==0) - width: 8*mm + width: 10*mm style: CheckBoxStyle { - background: Rectangle { - implicitWidth: 6*mm - implicitHeight:3*mm - color:"transparent" + indicator:Rectangle{ + x:4*mm + width: 3*mm + implicitHeight:4*mm + Text{ + color: control.checked?"black":"grey" + font.pixelSize: 2.5*mm + text:"\uf005" + } } - indicator:Rectangle{ - x:3*mm - width: 3*mm - implicitHeight:3*mm - Text{ - color: control.checked?"black":"grey" - font.pixelSize: 2.5*mm - text:"\uf005" - }} - } + } checked:(newsitemobject.favorited>0) onClicked:{ if(favoritedCheckbox.checkedState==Qt.Checked){ @@ -308,8 +263,8 @@ Item { } } Rectangle{ - width: 8*mm - height: 3*mm + width: 10*mm + height: 4*mm color:"transparent" Text{ id:newsmenusymbol @@ -324,8 +279,8 @@ Item { onClicked: {newsmenu.popup()}} } Rectangle{ - width: 8*mm - height: 3*mm + width: 10*mm + height: 4*mm visible:newstab.newstabstatus!="Conversation" color:"transparent" Text{ @@ -340,7 +295,11 @@ Item { anchors.fill:parent onClicked:{ conversationsymbol.color="black"; - showConversation(index,newsitemobject) + + //Newsjs.conversationfromdb(db,login.username,newsitemobject.conversation_id,function(conversation){ + var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); + // var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray}); + var conversationItem = component.createObject(friendicaActivities); showConversation(index,newsitemobject) } } } @@ -367,12 +326,19 @@ Item { text: qsTr("Repost") onTriggered: { Newsjs.retweetNews(root.login,db,newsitemobject.status_id,root,function(reply){ - print(reply)}) + Helperjs.showMessage("Repost",qsTr("Success!"),root) + }) } } MenuItem { text: qsTr("Conversation") - onTriggered: showConversation(index,newsitemobject) + onTriggered: { + conversationsymbol.color="black"; + //Newsjs.conversationfromdb(db,login.username,newsitemobject.conversation_id,function(conversation){ + var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); + var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray}); + showConversation(index,newsitemobject) + } } Menu{ @@ -398,8 +364,15 @@ Item { text: qsTr("Delete") onTriggered: { Newsjs.deleteNews(root.login,root.db,newsitemobject.status_id,newsitemobject.messagetype,root,function(reply){ - newsModel.remove(index)}) + // newsModel.remove(index) + var msg = {'deleteId': index, 'model': newsModel}; + newsWorker.sendMessage(msg); + }) } } + //MenuItem{ + // text:qsTr("Show on website") + // onTriggered:Qt.openUrlExternally(login.server+"/display/"+newsitemobject + //} } }} diff --git a/source-android/qml/newsqml/PermissionDialog.qml b/source-android/qml/newsqml/PermissionDialog.qml index 4040c76..5f4df7c 100644 --- a/source-android/qml/newsqml/PermissionDialog.qml +++ b/source-android/qml/newsqml/PermissionDialog.qml @@ -173,7 +173,7 @@ Rectangle{ Helperjs.readData(db,"contacts",login.username,function(contacts){ for (var name in contacts){ var contactstatus="neutral"; - if (contact_allow.indexOf(contacts[name].cid)>-1){contactstatus="positive";print(contacts[name].cid+" pos")} + if (contact_allow.indexOf(contacts[name].cid)>-1){contactstatus="positive"} else if (contact_deny.indexOf(contacts[name].cid)>-1){contactstatus="negative"} contactModel.append({"contact":contacts[name],"contactstatus":contactstatus}) }},"isFriend",1); diff --git a/source-android/qml/photoqml/ImageUploadDialog.qml b/source-android/qml/photoqml/ImageUploadDialog.qml new file mode 100644 index 0000000..8c29c5f --- /dev/null +++ b/source-android/qml/photoqml/ImageUploadDialog.qml @@ -0,0 +1,244 @@ +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import "qrc:/js/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Rectangle{ + id:imageDialog + //property var attachImageURLs: [] + property var contacts: [] + property var groups: [] + property var contact_allow:login.permissions[0] + property var contact_deny:login.permissions[1] + property var group_allow:login.permissions[2] + property var group_deny:login.permissions[3] + property int imageNo: 0 + + function uploadSelectedImage(inumber){ + xhr.url= login.server + "/api/friendica/photo/create.json"; + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.clearParams(); + xhr.setParam("desc",imageUploadModel.get(inumber).description); + xhr.setParam("album", album.currentText); + xhr.setParam("contact_allow","27"); + if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))}; + if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; + //if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; + if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; + xhr.setImageFileParam("media", imageUploadModel.get(inumber).imageUrl ); + xhr.post(); + } + + z:2 + border.color: "grey" + width: parent.width-4*mm + height:parent.height-12*mm + x:2*mm + y:10*mm + property string directory: "" + + + ImagePicker { + id: imagePicker; + multiple : true + onReady: {//var urlstring=decodeURIComponent(imagePicker.imageUrl); + //var fileurl="file://"+urlstring.substring(5); + for (var n in imagePicker.imageUrls){ + imageUploadModel.append({"imageUrl":imagePicker.imageUrls[n].toString(),"description":""}) + } + } + } + + + Connections{ + target:xhr + onError:{print(data)}//if (data=="image"){Helperjs.showMessage()}} + onSuccess:{ + imageNo=imageNo+1; + if(imageNo0){ + uploadSelectedImage(0) + }} + } + } + ProgressBar{ + id: newimageProgress + width: 15*mm + height: buttonRow.height + anchors.top: parent.top + anchors.right:buttonRow.left + anchors.rightMargin:mm + visible: false + value: imageNo/imageUploadModel.count + } + + Component.onCompleted:{ + albumModel.append({"text":""}); + try{Helperjs.readField("album",db,"imageData",login.username,function(storedAlbums){ + //print(JSON.stringify(storedAlbums)) + for (var n in storedAlbums){ + albumModel.append({"text":storedAlbums[n]})} + })} + catch (e){print(e)} + } +// BusyIndicator{ +// id: imageBusy +// anchors.horizontalCenter: imageUploadView.horizontalCenter +// anchors.top:imageUploadView.top +// anchors.topMargin: 2*mm +// width:10*mm +// height: 10*mm +// running:false +// } +} diff --git a/source-android/qml/photoqml/PhotoComponent.qml b/source-android/qml/photoqml/PhotoComponent.qml index 4dc33e1..8ea3559 100644 --- a/source-android/qml/photoqml/PhotoComponent.qml +++ b/source-android/qml/photoqml/PhotoComponent.qml @@ -48,10 +48,16 @@ Package { } MouseArea { width: realImage.paintedWidth; height: realImage.paintedHeight; anchors.centerIn: realImage - onClicked: { + onPressAndHold:{ + var menuString="import QtQuick.Controls 1.4; Menu {MenuItem{text:qsTr('Delete on client and server'); onTriggered: {deletepics('image','"+imageLocation+"');photoModel.remove(index)}}}"; + var imagemenuObject=Qt.createQmlObject(menuString,photoWrapper,"imagemenuOutput") + imagemenuObject.popup() + } + onClicked: { if (albumWrapper.state == 'inGrid') { gridItem.GridView.view.currentIndex = index; - albumWrapper.state = 'fullscreen' + albumWrapper.state = 'fullscreen'; + listItem.ListView.view.currentIndex=index } else { gridItem.GridView.view.currentIndex = index; albumWrapper.state = 'inGrid' diff --git a/source-android/qml/photoqml/PhotoPlaceholder.qml b/source-android/qml/photoqml/PhotoPlaceholder.qml deleted file mode 100644 index 162529c..0000000 --- a/source-android/qml/photoqml/PhotoPlaceholder.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 -import "qrc:/js/helper.js" as Helperjs - -Image { -id:photoPlaceholder -property string imageName:"x.jpg" -property string downloadtype:"" -fillMode: Image.PreserveAspectFit -onStatusChanged: { - if (photoPlaceholder.status == Image.Ready) { - //print("Source: "+source+"Photo width"+width+" height"+height+" Ratio "+ fillMode); - var saveprocess=photoPlaceholder.grabToImage(function(result){ - var saveresult=result.saveToFile(imageName.toString()); - if (saveresult){ - if ((downloadtype=="picture")&&(newImages.length>0)){ - photoPlaceholder.destroy(); - currentImageNo=currentImageNo+1 - } -S }}); -}}} - diff --git a/source-android/qml/photoqml/PhotoTab.qml b/source-android/qml/photoqml/PhotoTab.qml index 09ed13b..6745e60 100644 --- a/source-android/qml/photoqml/PhotoTab.qml +++ b/source-android/qml/photoqml/PhotoTab.qml @@ -47,6 +47,12 @@ Rectangle { onError:{if(data=="picture"){print("Error"+data); currentimageno=currentimageno+1}} } +// Connections{ +// target:filesystem +// onError:{print("Error deleting"); +// } +// onSuccess:print("Success deleting"); +// } function showFotos(friend){ if(friend=="backButton"){ @@ -76,28 +82,46 @@ Rectangle { }} } + function deletepics(type,url ,imageId){ + Service.deleteImage(db,login,type, url,root,function(){//showFotos("") + }) + } + ProgressBar{ id: newImagesProgress width: 15*mm height: updatePhotolist.height anchors.top: parent.top - anchors.right:updatePhotolist.left + anchors.right:uploadPhoto.left anchors.rightMargin:mm visible: false value: currentimageno/newimages.length } + //ImageUploadDialog{} + BlueButton{ + id: uploadPhoto + anchors.top: parent.top + anchors.topMargin: 0.5*mm + anchors.right:updatePhotolist.left + anchors.rightMargin:mm + text:"\uf0ee" + onClicked: { + var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml"); + var imageUpload = component.createObject(fotorectangle); + }} + BlueButton{ id: updatePhotolist anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right:phototabstatusButton.left anchors.rightMargin:mm - text:"\uf021" + text:"\uf0ed" onClicked: { - Service.requestList(root.login,root.db, fotostab,function(obj){ - newimages=obj;print("newimages"+JSON.stringify(obj)) - })}} + Service.requestList(root.login,root.db, fotostab,function(obj){newimages=obj}) + } + } BlueButton{ id: phototabstatusButton diff --git a/source-android/qml/photoqml/PhotogroupComponent.qml b/source-android/qml/photoqml/PhotogroupComponent.qml index 76dbf66..ef9b4da 100644 --- a/source-android/qml/photoqml/PhotogroupComponent.qml +++ b/source-android/qml/photoqml/PhotogroupComponent.qml @@ -83,7 +83,8 @@ Package { Helperjs.readData(db,"imageData",root.login.username,function(obj){ if (obj) { for (var k=0;k ConfigTab - - - - + + + + User Name - + Server Server - + Password Passwort - + Image dir. Bildverz. - + Max. News Max. Nachr. - + News as Anzeige - + Interval (0=None) Intervall (0=keins) - + Confirm Bestätigen - + No server given! Kein Server angegeben! - + No username given! Kein Nutzername angegeben! - + No password given! Kein Passwort angegeben! - + No image directory given! Kein Verzeichnis für Bilder angegeben! - + No maximum news number given! Maximale News-Anzahl nicht angegeben! - + Timeline Chronologisch - + Conversations Unterhaltungen @@ -139,35 +139,79 @@ FriendsTab - + Friends Freunde - + Contacts Kontakte - + Groups Gruppen - MessageSend + GroupComponent - - Title (optional) - Überschrift (optional) + Error + Fehler - + No name given + Kein Name angegeben + + + + ImageUploadDialog + + + Album + Album + + + + Image + Bild + + + + Description + Beschreibung + + + + Upload + Hochladen + + + Error Fehler - + + No album name given + Kein Albumname angegeben + + + + MessageSend + + + Title (optional) + Überschrift (optional) + + + + Error + Fehler + + + Only one attachment supported at the moment. Remove other attachment first! Nur ein Anhang derzeit unterstützt. @@ -182,27 +226,27 @@ Lade Profilbild für - + More Mehr - + Timeline Chronologisch - + Favorites Markierte News - + Conversations Unterhaltungen - + Notifications Meldungen @@ -210,77 +254,82 @@ Newsitem - + attending: Teilnahme - + Source: Quelle: - + Direct Message Direktnachricht - + In reply to Antwort an - + comments Kommentare - + Attending: Teilnahme: - + Reply Antworten - + DM Direktnachricht - + Repost Teilen - + + Success! + Erledigt! + + + Conversation Unterhaltung - + Attending Teilnahme - + yes ja - + maybe vielleicht - + no nein - + Delete Löschen @@ -288,12 +337,12 @@ PermissionDialog - + Friends Freunde - + Groups Gruppen @@ -301,18 +350,18 @@ PhotoTab - + 's images s Bilder - - + + Own Images Eigene Bilder - + More Mehr @@ -338,131 +387,131 @@ newsworker - + likes this. mag das. - + like this. mögen das. - + doesn't like this. mag das nicht. - + don't like this. mögen das nicht. - + will attend. nehmen teil. - + persons will attend. Personen nehmen teil. - + will not attend. nimmt nicht teil. - + persons will not attend. Personen nehmen nicht teil. - + may attend. nimmt vielleicht teil. - + persons may attend. Personen nehmen vielleicht teil. - + yes ja - + no nein - + maybe vielleicht - + seconds Sekunden - - - - - - - - + + + + + + + + ago her - + minute Minute - + minutes Minuten - + hour Stunde - + hours Stunden - + day Tag - + days Tage - + month Monat - + months Monate - + years diff --git a/source-android/translations/friendiqa-es.qm b/source-android/translations/friendiqa-es.qm index 168374a..853f462 100644 Binary files a/source-android/translations/friendiqa-es.qm and b/source-android/translations/friendiqa-es.qm differ diff --git a/source-android/translations/friendiqa-es.ts b/source-android/translations/friendiqa-es.ts index 33c9667..8022119 100644 --- a/source-android/translations/friendiqa-es.ts +++ b/source-android/translations/friendiqa-es.ts @@ -17,80 +17,80 @@ ConfigTab - - - - + + + + User Usuario - + Server Servidor - + Password Contraseña - + Image dir. Dir. de imágenes - + Max. News Nº Max. de noticias. - + News as Noticias como - + Interval (0=None) Intervalo (0=ningún) - + Confirm Confirmar - + No server given! ¡Servidor no encontrado! - + No username given! ¡Usuario incorrecto! - + No password given! ¡Contraseña incorrecta! - + No image directory given! ¡No se ha encontrado el directorio de imágenes! - + No maximum news number given! ¡Nº máximo de noticias incorrecto! - + Timeline Cronología - + Conversations Conversaciones @@ -139,35 +139,68 @@ FriendsTab - + Friends Amigos - + Contacts Contactos - + Groups Grupos - MessageSend + ImageUploadDialog - - Title (optional) - Título (opcional) + + Album + álbum - + + Image + imagen + + + + Description + Descripción + + + + Upload + Subir + + + Error Error - + + No album name given + ¡Nombre del álbum no encontrado! + + + + MessageSend + + + Title (optional) + Título (opcional) + + + + Error + Error + + + Only one attachment supported at the moment. Remove other attachment first! Solo se admite adjuntar un solo archivo en este momento. @@ -182,27 +215,27 @@ Descargar la imagen del perfil para - + More Mas - + Timeline Cronología - + Favorites Favoritos - + Conversations Conversaciones - + Notifications Notificaciones @@ -210,77 +243,82 @@ Newsitem - + attending: Asistiendo: - + Source: Fuente: - + Direct Message Mensaje directo - + In reply to En respuesta a - + comments comentarios - + Attending: Asistiendo: - + Reply Respuesta - + DM Mensaje directo - + Repost Volver a publicar - + + Success! + éxito! + + + Conversation Conversación - + Attending Asistiendo - + yes si - + maybe quizás - + no no - + Delete Borrar @@ -288,12 +326,12 @@ PermissionDialog - + Friends Amigos - + Groups Grupos @@ -301,18 +339,18 @@ PhotoTab - + 's images s Imágenes - - + + Own Images Mis imágenes - + More Mas @@ -338,131 +376,131 @@ newsworker - + likes this. le gusta esto. - + like this. me gusta esto. - + doesn't like this. no de ése. - + don't like this. no me gusta. - + will attend. asistirá. - + persons will attend. Personas que asistirán. - + will not attend. no asistirá. - + persons will not attend. Personas que no asistirán.. - + may attend. Puede asistir. - + persons may attend. Personas que pueden asistir. - + yes si - + no no - + maybe quizás - + seconds Segundos - - - - - - - - + + + + + + + + ago hace - + minute Minuto - + minutes Minutos - + hour Hora - + hours Horas - + day Dia - + days Dias - + month Mes - + months Meses - + years Años diff --git a/source-linux/application.qrc b/source-linux/application.qrc index e7aba98..baf9e0a 100644 --- a/source-linux/application.qrc +++ b/source-linux/application.qrc @@ -4,14 +4,13 @@ qml/newsqml/NewsTab.qml qml/newsqml/Newsitem.qml qml/newsqml/MessageSend.qml - qml/newsqml/PermissionDialog.qml qml/newsqml/Conversation.qml - qml/newsqml/ImageDialog.qml qml/newsqml/FriendicaActivities.qml qml/contactqml/FriendsTab.qml qml/contactqml/GroupComponent.qml qml/contactqml/ContactComponent.qml qml/contactqml/ContactDetailsComponent.qml + qml/contactqml/Contactlist.qml qml/genericqml/BlueButton.qml qml/photoqml/PhotoComponent.qml qml/photoqml/PhotogroupComponent.qml @@ -208,5 +207,10 @@ qml/calendarqml/EventList.qml translations/friendiqa-de.qm translations/friendiqa-de.ts + qml/photoqml/ImageUploadDialog.qml + qml/genericqml/AttachmentDialog.qml + qml/genericqml/ImageDialog.qml + qml/genericqml/PermissionDialog.qml + images/addImage.png diff --git a/source-linux/common/filesystem.cpp b/source-linux/common/filesystem.cpp index e54f063..f37ba97 100644 --- a/source-linux/common/filesystem.cpp +++ b/source-linux/common/filesystem.cpp @@ -54,6 +54,7 @@ void FILESYSTEM::makeDir(QString name) void FILESYSTEM::rmDir() { QDir dir(m_Directory); + //qDebug()<(), EXTERNAL_CONTENT_URI.object()); + + if (ACTION_PICK.isValid() && intent.isValid()) + { + intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("image/*").object()); + QtAndroid::startActivity(intent.object(), 101, this); + qDebug() << "OK"; + } + else + { + qDebug() << "ERRO"; + } +} + +void imagePickerAndroid::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) +{ + jint RESULT_OK = QAndroidJniObject::getStaticField("android/app/Activity", "RESULT_OK"); + if (receiverRequestCode == 101 && resultCode == RESULT_OK) + { + QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;"); + QAndroidJniObject dadosAndroid = QAndroidJniObject::getStaticObjectField("android/provider/MediaStore$MediaColumns", "DATA", "Ljava/lang/String;"); + QAndroidJniEnvironment env; + jobjectArray projecao = (jobjectArray)env->NewObjectArray(1, env->FindClass("java/lang/String"), NULL); + jobject projacaoDadosAndroid = env->NewStringUTF(dadosAndroid.toString().toStdString().c_str()); + env->SetObjectArrayElement(projecao, 0, projacaoDadosAndroid); + QAndroidJniObject contentResolver = QtAndroid::androidActivity().callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;"); + QAndroidJniObject cursor = contentResolver.callObjectMethod("query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;", uri.object(), projecao, NULL, NULL, NULL); + jint columnIndex = cursor.callMethod("getColumnIndex", "(Ljava/lang/String;)I", dadosAndroid.object()); + cursor.callMethod("moveToFirst", "()Z"); + QAndroidJniObject resultado = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex); + QString imagemCaminho = "file://" + resultado.toString(); + emit imagemCaminhoSignal(imagemCaminho); + } + else + { + qDebug() << "Caminho errado"; + } +} diff --git a/source-linux/common/imagepickerandroid.h b/source-linux/common/imagepickerandroid.h new file mode 100644 index 0000000..19b8340 --- /dev/null +++ b/source-linux/common/imagepickerandroid.h @@ -0,0 +1,23 @@ +#ifndef IMAGEPICKANDROID_H +#define IMAGEPICKANDROID_H +#include +#include + +#include + +class imagePickerAndroid : public QObject, public QAndroidActivityResultReceiver +{ + Q_OBJECT + +public: + imagePickerAndroid(); + + void buscaImagem(); + + virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject & data); + +signals: + void imagemCaminhoSignal(QString); +}; + +#endif // IMAGEPICKANDROID_H diff --git a/source-linux/common/xhr.cpp b/source-linux/common/xhr.cpp index d6fc091..2fe9ceb 100644 --- a/source-linux/common/xhr.cpp +++ b/source-linux/common/xhr.cpp @@ -117,8 +117,8 @@ void XHR::get() QByteArray loginData = m_login.toLocal8Bit().toBase64(); QString headerData = "Basic " + loginData; request.setRawHeader("Authorization", headerData.toLocal8Bit()); - QNetworkCookieJar* cJar = new QNetworkCookieJar; - manager.setCookieJar(cJar); +// QNetworkCookieJar* cJar = new QNetworkCookieJar; +// manager.setCookieJar(cJar); request.setUrl(requrl); reply = manager.get(request); @@ -188,7 +188,7 @@ void XHR::onReplySuccess() qDebug() << "!"; emit this->success( bufferToString() ); buffer.clear(); - reply->deleteLater(); +// reply->deleteLater(); } void XHR::onRequestFinished() @@ -210,14 +210,14 @@ void XHR::onReadyRead() { qDebug() << "."; buffer += reply->readAll(); - QList list = manager.cookieJar()->cookiesForUrl(m_url); - QFile f("/home/pankraz/cookie.txt"); - f.open(QIODevice::ReadWrite); - for(int i = 0; i < list.size(); ++i){ - QDataStream s(&f); - s << list.at(i).toRawForm(); - } - f.close(); +// QList list = manager.cookieJar()->cookiesForUrl(m_url); +// QFile f("/home/pankraz/cookie.txt"); +// f.open(QIODevice::ReadWrite); +// for(int i = 0; i < list.size(); ++i){ +// QDataStream s(&f); +// s << list.at(i).toRawForm(); +// } +// f.close(); } diff --git a/source-linux/friendiqa.pro b/source-linux/friendiqa.pro index 2d4eebe..165efae 100644 --- a/source-linux/friendiqa.pro +++ b/source-linux/friendiqa.pro @@ -17,7 +17,8 @@ QT += qml quick gui widgets SOURCES += common/friendiqa.cpp \ common/uploadableimage.cpp \ common/xhr.cpp \ - common/filesystem.cpp + common/filesystem.cpp \ + common/imagepickerandroid.cpp RESOURCES = application.qrc @@ -40,9 +41,17 @@ TRANSLATIONS += translations/friendiqa-de.ts HEADERS += \ common/uploadableimage.h \ common/xhr.h \ - common/filesystem.h + common/filesystem.h \ + common/imagepickerandroid.h DISTFILES += \ - qml/calendarqml/CalendarTab.qml + qml/calendarqml/*.qml + translations/*.ts + qml/*.qml + qml/newsqml/*.qml + qml/contactqml/*.qml + qml/photoqml/*.qml + qml/configqml/*.qml + js/*.js diff --git a/source-linux/friendiqa.pro.user b/source-linux/friendiqa.pro.user new file mode 100644 index 0000000..605c886 --- /dev/null +++ b/source-linux/friendiqa.pro.user @@ -0,0 +1,336 @@ + + + + + + EnvironmentId + {4e26e1df-26fd-4b76-8028-2f213523c328} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Linux + Linux + {52f4b2cf-b3aa-447e-af87-fc8e27ab3925} + 0 + 0 + 0 + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/build-friendiqa-Linux-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/build-friendiqa-Linux-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/build-friendiqa-Linux-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Deployment + + ProjectExplorer.BuildSteps.Deploy + + 1 + Lokales Deployment + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + friendiqa + friendiqa2 + Qt4ProjectManager.Qt4RunConfiguration:/home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/source-linux/friendiqa.pro + true + + friendiqa.pro + false + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/build-friendiqa-Linux-Debug + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/source-linux/friendiqa.pro.user.4e26e1d b/source-linux/friendiqa.pro.user.4e26e1d new file mode 100644 index 0000000..4bc4493 --- /dev/null +++ b/source-linux/friendiqa.pro.user.4e26e1d @@ -0,0 +1,336 @@ + + + + + + EnvironmentId + {4e26e1df-26fd-4b76-8028-2f213523c328} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Linux + Linux + {52f4b2cf-b3aa-447e-af87-fc8e27ab3925} + 0 + 0 + 0 + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/build-friendiqa-Linux-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/build-friendiqa-Linux-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/build-friendiqa-Linux-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Bereinigen + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Deployment + + ProjectExplorer.BuildSteps.Deploy + + 1 + Lokales Deployment + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + friendiqa + + Qt4ProjectManager.Qt4RunConfiguration:/home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/source-linux/friendiqa.pro + true + + friendiqa.pro + false + + /home/pankraz/ownCloud/clientsync/Friendiqa/v0.002/Develop/build-friendiqa-Linux-Debug + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/source-linux/friendiqa.pro.user.edcf3fd b/source-linux/friendiqa.pro.user.edcf3fd new file mode 100644 index 0000000..a823164 --- /dev/null +++ b/source-linux/friendiqa.pro.user.edcf3fd @@ -0,0 +1,336 @@ + + + + + + EnvironmentId + {edcf3fd2-f5d6-4f74-8175-958e4f7b717e} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {697d53b5-2856-4c15-8e25-1da8c6633594} + 0 + 0 + 0 + + /home/pankraz/build-friendiqa-Desktop-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/pankraz/build-friendiqa-Desktop-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/pankraz/build-friendiqa-Desktop-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + friendiqa + + Qt4ProjectManager.Qt4RunConfiguration:/home/pankraz/sdcard/Files/owncloud/clientsync/Friendiqa/v0.002/Develop/source-linux/friendiqa.pro + true + + friendiqa.pro + false + + /home/pankraz/build-friendiqa-Desktop-Debug + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/source-linux/images/addImage.png b/source-linux/images/addImage.png new file mode 100644 index 0000000..988f9f1 Binary files /dev/null and b/source-linux/images/addImage.png differ diff --git a/source-linux/js/helper.js b/source-linux/js/helper.js index 4deece4..297a0d1 100644 --- a/source-linux/js/helper.js +++ b/source-linux/js/helper.js @@ -22,7 +22,7 @@ function friendicaRequest(login,api,rootwindow,callback) { xhrequest.send(); } -function friendicaPostRequest(login,api,rootwindow,callback) { +function friendicaPostRequest(login,api,data,method,rootwindow,callback) { var xhrequest= new XMLHttpRequest(); xhrequest.onreadystatechange = function() { //print(api+JSON.stringify(login)+Qt.atob(login.password)); @@ -40,9 +40,10 @@ function friendicaPostRequest(login,api,rootwindow,callback) { } } } - xhrequest.open("POST", login.server+api,true,login.username,Qt.atob(login.password)); - xhrequest.send(); + xhrequest.open(method, login.server+api,true,login.username,Qt.atob(login.password)); + xhrequest.send(data); } + function getCount(database,login,table,field,countvalue){ var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var count=0; diff --git a/source-linux/js/news.js b/source-linux/js/news.js index 98798ae..9015453 100644 --- a/source-linux/js/news.js +++ b/source-linux/js/news.js @@ -17,7 +17,7 @@ function requestFriends(login,database,rootwindow,callback){ function requestGroups(login,database,rootwindow,callback){ // retrieve, save and return groups. Other features currently not implemented var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - Helperjs.friendicaRequest(login,"/api/friendica/group_show",rootwindow, function (obj){ + Helperjs.friendicaRequest(login,"/api/friendica/group_show",rootwindow, function (obj){print(obj); var groups=JSON.parse(obj); db.transaction( function(tx) { var result = tx.executeSql('DELETE from groups where username="'+login.username+'"'); // clean old groups @@ -29,6 +29,30 @@ function requestGroups(login,database,rootwindow,callback){ }); })} +function listFriends(login,database,callback){ + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=1'); // check for friends + var contactlist=[]; + for (var i=0;i1){ - var helpernews=newsrs.rows.item(0); - helpernews.newscount=newsrs.rows.length; - helpernews=fetchUsersForNews(database,user,helpernews) - newsArray.push(helpernews); - //} -} - callback(newsArray); - })} + var helpernews=newsrs.rows.item(0); + helpernews.newscount=newsrs.rows.length; + helpernews=fetchUsersForNews(database,user,helpernews); + //var chatArray=[]; + // for (var k=0;k 0 ) { diff --git a/source-linux/js/newsworker.js b/source-linux/js/newsworker.js index c350a70..b545aa2 100644 --- a/source-linux/js/newsworker.js +++ b/source-linux/js/newsworker.js @@ -1,6 +1,11 @@ WorkerScript.onMessage = function(msg) { - if(msg.appendnews!==true){ msg.model.clear()}; - +if(msg.deleteId) + {msg.model.remove(msg.deleteId); + msg.model.sync() +} +else{ + if(msg.appendnews!==true){msg.model.clear()}; + msg.model.sync() for (var j=0;j0){ @@ -41,7 +46,7 @@ WorkerScript.onMessage = function(msg) { if (newsitemobject.friendica_activities_self.indexOf(1)!=-1){self.liked=1} if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1} } - var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText,self:self} + var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText,self:self} var attachmentList=[];if(newsitemobject.attachments){ var attachArray=JSON.parse(Qt.atob(newsitemobject.attachments)); @@ -52,21 +57,26 @@ WorkerScript.onMessage = function(msg) { } newsitemobject.attachmentList=attachmentList; var seconds=(msg.currentTime-newsitemobject.created_at)/1000; - var timestring=""; - if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");} - else if (seconds<90){timestring=Math.round(seconds/60)+" "+qsTr("minute") +" "+qsTr("ago");} - else if (seconds<3600){timestring=Math.round(seconds/60)+" "+qsTr("minutes") +" "+qsTr("ago");} - else if (seconds<5400){timestring=Math.round(seconds/3600)+" "+qsTr("hour") +" "+qsTr("ago");} - else if (seconds<86400){timestring=Math.round(seconds/3600)+" "+qsTr("hours") +" "+qsTr("ago");} - else if (seconds<129600){timestring=Math.round(seconds/86400)+" "+qsTr("day") +" "+qsTr("ago");} - else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");} - else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");} - else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");} - else {timestring=Math.round(seconds/46656000)+" "+qsTr("years") +" "+qsTr("ago");} - var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities})} - //print("News:"+j+msg.news.length+JSON.stringify(data)); - msg.model.append(data);} - if (j==msg.news.length){ - msg.model.sync() - }; + var timestring=""; + if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");} + else if (seconds<90){timestring=Math.round(seconds/60)+" "+qsTr("minute") +" "+qsTr("ago");} + else if (seconds<3600){timestring=Math.round(seconds/60)+" "+qsTr("minutes") +" "+qsTr("ago");} + else if (seconds<5400){timestring=Math.round(seconds/3600)+" "+qsTr("hour") +" "+qsTr("ago");} + else if (seconds<86400){timestring=Math.round(seconds/3600)+" "+qsTr("hours") +" "+qsTr("ago");} + else if (seconds<129600){timestring=Math.round(seconds/86400)+" "+qsTr("day") +" "+qsTr("ago");} + else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");} + else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");} + else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");} + else {timestring=Math.round(seconds/46656000)+" "+qsTr("years") +" "+qsTr("ago");} + + var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities,"forumname":forumname})} + //print("News:"+j+msg.news.length+JSON.stringify(data)); + msg.model.append(data) + } + + if (j==msg.news.length){ + //print("j: "+j+" msg.model.count: "+msg.model.count); + msg.model.sync() +} +} } diff --git a/source-linux/js/service.js b/source-linux/js/service.js index 8ea1252..02499ec 100644 --- a/source-linux/js/service.js +++ b/source-linux/js/service.js @@ -24,46 +24,86 @@ function requestList(login,database,rootwindow,callback) { function dataRequest(login,photoID,database,rootwindow) { // check if image exist and call download function Helperjs.friendicaRequest(login,"/api/friendica/photo?photo_id="+photoID, rootwindow, function (image){ - try{ if(image==""){currentimageno=currentimageno+1}else{ - var obj = JSON.parse(image); - var helpfilename=obj.filename.substring(0,obj.filename.lastIndexOf(".")); - var filesuffix=""; - if (obj.type=="image/jpeg"){filesuffix=".jpg"} - else if (obj.type=="image/png"){filesuffix=".png"} - else {filesuffix=""} - - if (helpfilename==""){// check if file has any filename - obj.filename=obj["id"]+filesuffix; - } - else{obj.filename=helpfilename+filesuffix} - - var link=""; - if(obj["link"][0]){link=obj["link"][0]} else{link=obj["link"]["4"]} - xhr.setUrl(Qt.resolvedUrl(link)); - xhr.setFilename(login.imagestore+'albums/'+obj.album+"/"+obj["filename"]); - xhr.setDownloadtype("picture"); - xhr.download(); - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - db.transaction( function(tx) { - var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"'); - if(result.rows.length === 1) {// use update - result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+obj.id+'", created="'+obj.created+'", edited="'+obj.edited+'", profile="'+obj.profile+'", link="'+obj["link"]["4"]+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", location="file://'+login.imagestore+'albums/'+obj.album+'/" where id="'+obj["id"]+'"'); - } else {// use insert print('... does not exists, create it') - result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,obj.id,obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width,obj. profile,obj["link"]["4"],'file://'+login.imagestore+'albums/'+obj.album+"/"]); - } - })}} + try{ if(image==""){currentimageno=currentimageno+1}else{ + var obj = JSON.parse(image); + var helpfilename=obj.filename.substring(0,obj.filename.lastIndexOf(".")); + var filesuffix=""; + if (obj.type=="image/jpeg"){filesuffix=".jpg"} + else if (obj.type=="image/png"){filesuffix=".png"} + else {filesuffix=""} + if (helpfilename==""){// check if file has any filename + obj.filename=obj["id"]+filesuffix; + } + else{obj.filename=helpfilename+filesuffix} + var link=""; + if(obj["link"][0]){link=obj["link"][0]} else{link=obj["link"]["4"]} + xhr.setUrl(Qt.resolvedUrl(link)); + xhr.setFilename(login.imagestore+'albums/'+obj.album+"/"+obj["filename"]); + xhr.setDownloadtype("picture"); + xhr.download(); + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"'); + if(result.rows.length === 1) {// use update + result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+obj.id+'", created="'+obj.created+'", edited="'+obj.edited+'", profile="'+obj.profile+'", link="'+obj["link"]["4"]+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", location="file://'+login.imagestore+'albums/'+obj.album+'/" where id="'+obj["id"]+'"'); + } else {// use insert print('... does not exists, create it') + result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,obj.id,obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width,obj. profile,obj["link"]["4"],'file://'+login.imagestore+'albums/'+obj.album+"/"]); + } + })}} catch (e){print("Data retrieval failure! "+ e+obj);} })} -function deleteImageData(database,user,field,selection,callback) { // does nothing useful at the moment +function deleteImage(database,login,type,location,rootwindow,callback) { // delete image locally and on server + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + //print(' delete Image Data() for ' + location) + var rsfilename=location.substring(location.lastIndexOf("/")+1,location.length); + var rslocation=location.substring(0,location.lastIndexOf("/")+1); + print(type+" Name "+ rsfilename+" Location: "+rslocation) + db.transaction( function(tx) { + if (type=='image'){ + var rs= tx.executeSql('SELECT * FROM imageData WHERE filename="'+rsfilename+'" AND location="'+rslocation+'"') + print(rs.rows.item(0).id) //); + var imageId=rs.rows.item(0).id; + Helperjs.friendicaPostRequest(login,"/api/friendica/photo/delete?photo_id="+imageId,"","DELETE",rootwindow, function (obj){ + var deletereturn = JSON.parse(obj); print(obj); + if (deletereturn.result=="deleted"){ + db.transaction( function(tx) { + var deleters=tx.executeSql('DELETE FROM imageData WHERE location="'+rslocation+'" AND filename="'+rsfilename+'"'); }); + filesystem.Directory=rslocation.substring(7,rslocation.length-1); + filesystem.rmFile(rsfilename) + }}) + } + else{ + Helperjs.friendicaPostRequest(login,"/api/friendica/photoalbum/delete?album="+rsfilename,"","DELETE",rootwindow, function (obj){ + print(" Return "+ obj); + var deletereturn = JSON.parse(obj); + if (deletereturn.result=="deleted"){ + db.transaction( function(tx) { + var rs= tx.executeSql('SELECT DISTINCT location FROM imageData WHERE album="'+rsfilename+'" AND username="'+login.username+'"'); + var locationstring=rs.rows.item(0).location; + filesystem.Directory=locationstring.substring(7,locationstring.length-1); + filesystem.rmDir(); + var deleters=tx.executeSql('DELETE FROM imageData WHERE album="'+location+'"'); + }) + } + }) + } + callback(location) + }) +} + +function deleteContacts(database,user,callback) { // does nothing useful at the moment var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); //print(' delete Image Data() for ' + field +"="+selection) db.transaction( function(tx) { - result = tx.executeSql('UPDATE imageData SET data="" where '+ field +'="'+selection+'"'); + result1= tx.executeSql('SELECT * FROM contacts a LEFT OUTER JOIN news b ON a.url==b.uid'); +result2= tx.executeSql('SELECT * FROM contacts a LEFT OUTER JOIN news b ON a.url==b.uid'); + + + callback(result)}) } - function requestFriendsAlbumPictures(login,friend,rootwindow,callback){ // screenscraping of albums page of contact without user and password Helperjs.friendicaWebRequest(friend.url.replace("profile","photos"),rootwindow,function(photohtml){ @@ -98,7 +138,6 @@ function requestFriendsPictures(link,rootwindow,callback){ for (var i=0;icurrentts) || (image_timestamp==0)){ + xhr.setUrl(Qt.resolvedUrl(contact.profile_image_url)); + xhr.setFilename(imagename); + xhr.setDownloadtype("contact"); + xhr.download(); + } + var result; result = tx.executeSql('SELECT * from contacts where username="'+login.username+'" AND url = "'+contact.url+'"'); // check for news url if(result.rows.length === 1) {// use update - result = tx.executeSql('UPDATE contacts SET id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",imageAge='+currentTime+', profile_image_url="'+contact.profile_image_url+'", description="'+Qt.btoa(contact.description)+'", profile_image="'+imagename+'", protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ Date.parse(Newsjs.cleanDate(contact.created_at))+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+' where username="'+login.username+'" AND url="'+contact.url+'"'); + result = tx.executeSql('UPDATE contacts SET id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",imageAge='+currentTime+', profile_image_url="'+contact.profile_image_url+'", description="'+Qt.btoa(contact.description)+'", profile_image="'+imagename+'", protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ Date.parse(Newsjs.cleanDate(contact.created_at))+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+', timestamp='+ image_timestamp+' where username="'+login.username+'" AND url="'+contact.url+'"'); } else {// use insert - result = tx.executeSql('INSERT INTO contacts VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,contact.id,Qt.btoa(contact.name),contact.screen_name,contact.location,currentTime,contact.profile_image_url, Qt.btoa(contact.description),imagename,contact.url,contact.protected,contact.followers_count, contact.friends_count,Date.parse(Newsjs.cleanDate(contact.created_at)),contact.favorites_count,contact.utc_offset,contact.time_zone,contact.statuses_count,contact.following,contact.verfied,contact.statusnet_blocking,contact.notifications,contact.statusnet_profile_url,contact.cid,contact.network,isFriend]);} + result = tx.executeSql('INSERT INTO contacts VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,contact.id,Qt.btoa(contact.name),contact.screen_name,contact.location,currentTime,contact.profile_image_url, Qt.btoa(contact.description),imagename,contact.url,contact.protected,contact.followers_count, contact.friends_count,Date.parse(Newsjs.cleanDate(contact.created_at)),contact.favorites_count,contact.utc_offset,contact.time_zone,contact.statuses_count,contact.following,contact.verfied,contact.statusnet_blocking,contact.notifications,contact.statusnet_profile_url,contact.cid,contact.network,isFriend,image_timestamp]);} }); -} +}} diff --git a/source-linux/qml/configqml/InfoBox.qml b/source-linux/qml/configqml/InfoBox.qml index 7c3932a..cfdfcba 100644 --- a/source-linux/qml/configqml/InfoBox.qml +++ b/source-linux/qml/configqml/InfoBox.qml @@ -11,7 +11,7 @@ Rectangle{ anchors.topMargin: mm textFormat: Text.RichText wrapMode: Text.Wrap - text: "Friendiqa v0.003
Licensed under GPL 3
"+ + text: "Friendiqa v0.1
Licensed under GPL 3
"+ "Profile https://freunde.ma-nic.de/profile/friendiqa
"+ "Sourcecode: https://github.com/LubuWest/Friendica
"+ "C++ code by Fabio
"+ @@ -28,7 +28,7 @@ Rectangle{ anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm - text: "\uf057" //qsTr("Close") + text: "\uf057" onClicked:{configStack.pop()} } } diff --git a/source-linux/qml/contactqml/ContactDetailsComponent.qml b/source-linux/qml/contactqml/ContactDetailsComponent.qml index 3f797a2..db2da09 100644 --- a/source-linux/qml/contactqml/ContactDetailsComponent.qml +++ b/source-linux/qml/contactqml/ContactDetailsComponent.qml @@ -13,8 +13,8 @@ property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend==1)?"" Rectangle { id: wrapper - width:friendsTabView.width; - height:friendsTabView.height-15*mm + width:root.width-2*mm //friendsTabView.width; + height:root.height-20*mm// friendsTabView.height-15*mm border.color: "grey" color:"white" Image { @@ -30,7 +30,7 @@ Rectangle { Label { id: namelabel x: mm - width:friendsTabView.width-4*mm + width: root.width-6*mm //friendsTabView.width-4*mm height: 3*mm text:Qt.atob(contact.name)+" (@"+contact.screen_name+")" elide:Text.ElideRight @@ -50,7 +50,7 @@ Rectangle{ frameVisible: true id:namelabelflickable width: root.width-10*mm - height:friendsTabView.height-45*mm + height:root.height-50*mm//friendsTabView.height-45*mm x: mm clip:true Text{ @@ -83,6 +83,7 @@ Rectangle{ root.currentIndex=2; fotostab.active=true; root.fotoSignal(contact) ; + contactLargeComponent.destroy(); } } @@ -93,6 +94,7 @@ Rectangle{ root.currentIndex=0; newstab.active=true; root.messageSignal(contact.id) ; + contactLargeComponent.destroy(); } } @@ -104,6 +106,7 @@ Rectangle{ root.currentIndex=0; newstab.active=true; root.directmessageSignal(contact.screen_name); + contactLargeComponent.destroy(); } } @@ -117,6 +120,7 @@ Rectangle{ calendartab.active=true; calendartab.calendartabstatus="Friend" root.eventSignal(contact.url); + contactLargeComponent.destroy(); } } @@ -124,8 +128,7 @@ Rectangle{ id: closeButton text: "\uf057" //"close" onClicked:{contactLargeComponent.destroy(); - //contactComponent.state=""; - friendsTabView.contactSignal} + } } } } diff --git a/source-linux/qml/contactqml/Contactlist.qml b/source-linux/qml/contactqml/Contactlist.qml new file mode 100644 index 0000000..6aa6991 --- /dev/null +++ b/source-linux/qml/contactqml/Contactlist.qml @@ -0,0 +1,101 @@ +// List of people +import QtQuick 2.0 +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Rectangle { + id:contactlistRectangle + property var contacts:[] + property var possibleUsers: [] + //y:8*mm + color: "white" + border.color: "light grey" + radius:0.5*mm + width:groupListView.width + height:groupListView.height + + ListView { + id: contactView + x:mm + y:6*mm + width: contactlistRectangle.width-2*mm + height: contactlistRectangle.height-10*mm + clip: true + spacing: 0 + model: contactModel + delegate: listContact + } + + ListModel{id: contactModel} + + Component { id:listContact + Rectangle{ + border.color: "#EEEEEE" + border.width: 1 + radius:0.5*mm + width:contactView.width + height:6*mm + Image { + id: contactImage + x:1 + y:1 + width: 5*mm + height:5*mm + source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url + onStatusChanged: if (contactImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + } + Text{ + font.pixelSize: 3*mm + anchors.left: contactImage.right + anchors.margins: 1*mm + text:Qt.atob(contact.name) + } + Text { + id:selected + anchors.right:parent.right + visible: contactlist.indexOf(contact)>-1 + z:4 + text: "\u2713" + width: 5*mm + anchors.top: parent.top + color: "green" + font.pixelSize: 3*mm + } + + MouseArea{ + anchors.fill: parent + onClicked:{ + if(selected.visible==true){ + contacts.splice(Helperjs.inArray(contacts,"id",contact.id),1); + selected.visible=false + } + else{ + contacts.push(contact); + selected.visible=true; + } + } + } + } + } + + BlueButton { + id: closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + color:"white" + text: "\uf057" + onClicked: { + groupModelAppend(contacts,function(){ + contactlistRectangle.destroy() + }); + } + } + + Component.onCompleted: { + for (var user in possibleUsers){ + contactModel.append({"contact":possibleUsers[user]}) + } + } +} diff --git a/source-linux/qml/contactqml/FriendsTab.qml b/source-linux/qml/contactqml/FriendsTab.qml index a82ce97..e9cdbf3 100644 --- a/source-linux/qml/contactqml/FriendsTab.qml +++ b/source-linux/qml/contactqml/FriendsTab.qml @@ -3,6 +3,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs +import "qrc:/js/service.js" as Service import "qrc:/qml/contactqml" import "qrc:/qml/genericqml" @@ -20,6 +21,9 @@ Rectangle { var contactDetails = component.createObject(friendstab,{"contact": contact}) } } + + + TabView{ id:friendsTabView tabPosition: Qt.TopEdge @@ -63,7 +67,7 @@ Rectangle { id: friendsGridTab function showFriends(contact){ try {friendsModel.clear()} catch(e){print(e)}; - Helperjs.readData(db,"contacts",root.login.username,function(friendsobject){ + Helperjs.readData(db,"contacts",login.username,function(friendsobject){ for (var i=0;i1){ friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid @@ -140,13 +144,30 @@ Rectangle { } },"isFriend",0,"screen_name ASC"); } + BlueButton { + id: cleanButton + text: "\uf021" + anchors.top: parent.top + anchors.topMargin: mm + anchors.right: parent.right + onClicked: { + Service.cleanContacts(root.login,root.db,function(){ + try {contactsModel.clear()} catch(e){print(e)}; + Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){ + for (var j=0;j-1 + z:4 + text: "\u2713" + width: 10*mm + anchors.top: folderImage.top + color: "green" + font.pixelSize: 10*mm + } + + Image{id:folderImage + width: fileIsDir?10*mm: imageView.width-mm + fillMode:Image.PreserveAspectFit + source:fileIsDir?"qrc:/images/folder-blue.png":fileURL + } + + MouseArea{ + anchors.fill: parent + onClicked:{ + if (fileName==".."){ + imageModel.folder=imageModel.parentFolder; + directory=imageModel.parentFolder + } + else if (fileIsDir){ + imageModel.folder=fileURL; + directory=fileURL + } + else{ + if (multiSelection!=true){ + attachImageURLs.push(fileURL); + attachImage(fileURL); + imageDialog.destroy() + } + else { + if(selected.visible==true){ + attachImageURLs.splice(attachImageURLs.indexOf(fileURL,1)) + selected.visible=false + } + else{ + attachImageURLs.push(fileURL); + selected.visible=true; + + } + attachImage(fileURL) + } + } + } + } + } + } +} diff --git a/source-linux/qml/newsqml/PermissionDialog.qml b/source-linux/qml/genericqml/PermissionDialog.qml similarity index 99% rename from source-linux/qml/newsqml/PermissionDialog.qml rename to source-linux/qml/genericqml/PermissionDialog.qml index 4040c76..9ab93e9 100644 --- a/source-linux/qml/newsqml/PermissionDialog.qml +++ b/source-linux/qml/genericqml/PermissionDialog.qml @@ -5,8 +5,8 @@ import "qrc:/qml/genericqml" Rectangle{ id:permissionDialog - x: mm - width: messageColumn.width-5*mm +// x: mm + width: parent.width-5*mm height:root.height/3 function updatePerms(){ for (var i=0;i1){ 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+"+"+contacts[i].cid+" ')}" + contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"';iconSource:'"+contacts[i].profile_image+"'; onTriggered: bodyField.insert(0,' @"+contacts[i].screen_name+" ')}" }} var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}"; var contactlistObject=Qt.createQmlObject(menuString,messageSend,"contactmenuOutput") diff --git a/source-linux/qml/newsqml/NewsTab.qml b/source-linux/qml/newsqml/NewsTab.qml index 14dd731..7203717 100644 --- a/source-linux/qml/newsqml/NewsTab.qml +++ b/source-linux/qml/newsqml/NewsTab.qml @@ -53,7 +53,7 @@ Item { } function showConversation(conversationIndex,newsitemobject){ - newsBusy.running=true; + //newsBusy.running=true; root.contactLoadType="conversation"; newsStack.conversationIndex= conversationIndex; if(newsitemobject.messagetype==0){ @@ -65,6 +65,13 @@ Item { })} } + function showContact(contact){ + var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml"); + if (component.status== Component.Ready){ + var contactDetails = component.createObject(newstab,{"contact": contact}) + } + } + function onFriendsMessages(friend){ newstab.newstabstatus="Contact" Newsjs.newsfromdb(db,root.login.username, function(dbnews){showNews(dbnews)},friend) @@ -75,6 +82,8 @@ Item { newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1,"login":root.login}}); } + + StackView{ id: newsStack anchors.fill:parent @@ -100,7 +109,6 @@ Item { BlueButton { id: newMessageButton - width:10*mm text: "\uf040" onClicked: { var groups=[]; @@ -115,7 +123,6 @@ Item { } BlueButton { id: quitButton - width:10*mm text: "\uf08b" onClicked: {Service.cleanNews(root.db,function(){Qt.quit() })} } @@ -153,29 +160,29 @@ Item { } MouseArea{anchors.fill:parent onClicked:{ - var currentTime= new Date(); - if(newstab.newstabstatus=="Timeline"){ - var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; + var currentTime= new Date(); + var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; + print("Lastnews ID "+lastnews_id+Qt.atob(newsModel.get(newsModel.count-1).newsitemobject.statusnet_html)) + if(newstab.newstabstatus=="Timeline"){ Newsjs.newsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; - newsWorker.sendMessage(msg); - },false,lastnews_id)} - if(newstab.newstabstatus=="Conversations"){ - var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; + newsWorker.sendMessage(msg); + },false,lastnews_id)} + if(newstab.newstabstatus=="Conversations"){ Newsjs.chatsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; - newsWorker.sendMessage(msg); - },lastnews_id)} - else if(newstab.newstabstatus=="Contact"){ - Newsjs.newsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; - newsWorker.sendMessage(msg); - },newsModel.get(newsModel.count-1).newsitemobject.uid,newsModel.get(newsModel.count-1).newsitemobject.created_at)} - }} - } + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; + newsWorker.sendMessage(msg); + },lastnews_id)} + else if(newstab.newstabstatus=="Contact"){ + Newsjs.newsfromdb(root.db,root.login.username, function(news){ + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; + newsWorker.sendMessage(msg); + },newsModel.get(newsModel.count-1).newsitemobject.uid,lastnews_id)} + } + } + } } - ListView { id: newsView anchors.fill: parent @@ -187,8 +194,8 @@ Item { footer: footerComponent model: newsModel delegate: Newsitem{} - //onContentYChanged:{if(contentY<-15*mm&&contentY>(-15*mm-1)){print("refreshing"); - onDragEnded:{if(contentY<-8*mm){//print("refreshing"); + //onContentYChanged:{if(contentY<-8*mm&&contentY>(-8*mm-1)){print("refreshing"); + onDragEnded:{if(contentY<-5*mm){//print("refreshing"); newsBusy.running=true; newstab.newstabstatus=login.newsViewType; root.contactLoadType="news"; diff --git a/source-linux/qml/newsqml/Newsitem.qml b/source-linux/qml/newsqml/Newsitem.qml index d9c9fa7..2f8ffec 100644 --- a/source-linux/qml/newsqml/Newsitem.qml +++ b/source-linux/qml/newsqml/Newsitem.qml @@ -10,21 +10,8 @@ Item { width: parent.width height:toprow.height+friendicaActivities.height+controlrow.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm) - Connections{ - target:newstab - onConversationChanged:{ - newsBusy.running=false; - if(index==newsStack.conversationIndex){ - if(newstab.conversation.length>0){ - var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); - var conversation = component.createObject(friendicaActivities,{"news":newstab.conversation}); - } - else{conversationsymbol.color="grey"} - } - } - } - property string attending: "" + property int itemindex: index onAttendingChanged: {attendLabel.visible=true; attendLabel.text= qsTr("attending: ")+ qsTr(attending)} @@ -54,13 +41,9 @@ Item { height: 7*mm MouseArea{ anchors.fill: parent - onClicked:{ - try{root.currentIndex=1; - friendstab.active=true; - root.contactdetailsSignal(newsitemobject.user)} catch (e){Helperjs.showMessage("Error",e,root)} - } + onClicked:{showContact(newsitemobject.user)} } - onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + onStatusChanged: if (profileImage.status == Image.Error) {print("Image Failed "+"file://"+newsitemobject.user.profile_image);source="qrc:/images/defaultcontact.jpg"} } Label { id:user_name @@ -68,13 +51,12 @@ Item { width:parent.width font.pixelSize: 1.5*mm wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: Qt.atob(newsitemobject.user.name)//+forumname + text: Qt.atob(newsitemobject.user.name)+forumname } } Column { id:newscolumn width: newsitem.width-8*mm - //anchors.left: authorcolumn.right Flow{ id:topFlow @@ -114,7 +96,13 @@ Item { text: try {(newsitemobject.newscount-1)+qsTr(" comments") }catch(e){" "} MouseArea{ anchors.fill:parent - onClicked: {conversationsymbol.color="black";showConversation(index,newsitemobject)} + onClicked: { + conversationsymbol.color="black"; + newsView.contentY+=newsitem.height; + var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); + var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray}); + showConversation(index,newsitemobject); + } } } } @@ -150,6 +138,7 @@ Item { spacing:mm Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.likeText MouseArea{ @@ -158,6 +147,7 @@ Item { } } Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.dislikeText MouseArea{ @@ -166,6 +156,7 @@ Item { } } Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.attendyesText MouseArea{ @@ -173,6 +164,7 @@ Item { onClicked: { showActivityContacts(newsitemobject.attendyes)} }} Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.attendnoText MouseArea{ @@ -181,6 +173,7 @@ Item { } } Label{color: "grey" + height:3.5*mm font.pixelSize: 1.5*mm text: friendica_activities.attendmaybeText MouseArea{ @@ -190,7 +183,6 @@ Item { } Label{ id:attendLabel - //visible: false color: "grey" height:3.5*mm font.pixelSize: 1.5*mm @@ -203,28 +195,21 @@ Item { CheckBox{ id:likeCheckbox - //height:3*mm - width:8*mm + width:10*mm visible: (newsitemobject.messagetype==0)? true:false checked:(friendica_activities.self.liked==1)?true:false style: CheckBoxStyle { - background: Rectangle { - implicitWidth: 6*mm - implicitHeight: 3*mm - color:"white" - } - indicator: Rectangle{ - implicitWidth: 3*mm - implicitHeight:3*mm - color:control.checked?"yellow":"white" - x: 4*mm - Text{ - anchors.centerIn: parent - font.pixelSize: 2.5*mm - font.family:fontAwesome.name - color:control.checked?"black": "grey" - text:"\uf118" - }} + indicator: Rectangle{ + implicitWidth: 10*mm + implicitHeight:3*mm + Text{ + anchors.centerIn: parent + font.pixelSize: 2.5*mm + font.family:fontAwesome.name + color:control.checked?"black": "grey" + text:"\uf118" + } + } } onClicked: { if(likeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"like",newsitemobject.status_id,root);dislikeCheckbox.checked=false; model.friendica_activities.self.liked=0 } @@ -232,73 +217,43 @@ Item { } CheckBox{ id: dislikeCheckbox - //height:3*mm - width:8*mm + width:10*mm visible: (newsitemobject.messagetype==0)? true:false checked: (friendica_activities.self.disliked==1)?true:false style: CheckBoxStyle { - background: Rectangle { - implicitWidth: 6*mm - implicitHeight:3*mm - color:"white" - } indicator: Rectangle{ - implicitWidth: 3*mm + implicitWidth: 10*mm implicitHeight:3*mm - color:control.checked?"yellow":"white" - x:4*mm Text{ anchors.centerIn: parent font.pixelSize: 2.5*mm font.family:fontAwesome.name color:control.checked?"black": "grey" text: "\uf119" - }} + } } + } onClicked: { if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.status_id,root);likeCheckbox.checked=false; model.friendica_activities.self.disliked=0} else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.status_id,root); model.friendica_activities.self.disliked=1}} } -// Rectangle{ -// width: 8*mm -// height: 3*mm -// color:"transparent" -// Text{ -// id:trashsymbol -// color: "grey" -// anchors.centerIn: parent -// font.pixelSize: 2*mm -// font.bold: true -// text: "\uf1f8" -// } -// MouseArea{ -// anchors.fill:parent -// onClicked: { -// Newsjs.deleteNews(root.login,root.db,newsitemobject.status_id,newsitemobject.messagetype,root,function(reply){ -// newsModel.remove(index)}) -// }} -// } CheckBox { id:favoritedCheckbox visible:(newsitemobject.messagetype==0) - width: 8*mm + width: 10*mm style: CheckBoxStyle { - background: Rectangle { - implicitWidth: 6*mm - implicitHeight:3*mm - color:"transparent" + indicator:Rectangle{ + x:4*mm + width: 3*mm + implicitHeight:4*mm + Text{ + color: control.checked?"black":"grey" + font.pixelSize: 2.5*mm + text:"\uf005" + } } - indicator:Rectangle{ - x:3*mm - width: 3*mm - implicitHeight:3*mm - Text{ - color: control.checked?"black":"grey" - font.pixelSize: 2.5*mm - text:"\uf005" - }} - } + } checked:(newsitemobject.favorited>0) onClicked:{ if(favoritedCheckbox.checkedState==Qt.Checked){ @@ -308,8 +263,8 @@ Item { } } Rectangle{ - width: 8*mm - height: 3*mm + width: 10*mm + height: 4*mm color:"transparent" Text{ id:newsmenusymbol @@ -324,8 +279,8 @@ Item { onClicked: {newsmenu.popup()}} } Rectangle{ - width: 8*mm - height: 3*mm + width: 10*mm + height: 4*mm visible:newstab.newstabstatus!="Conversation" color:"transparent" Text{ @@ -340,7 +295,11 @@ Item { anchors.fill:parent onClicked:{ conversationsymbol.color="black"; - showConversation(index,newsitemobject) + + //Newsjs.conversationfromdb(db,login.username,newsitemobject.conversation_id,function(conversation){ + var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); + // var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray}); + var conversationItem = component.createObject(friendicaActivities); showConversation(index,newsitemobject) } } } @@ -372,7 +331,13 @@ Item { } MenuItem { text: qsTr("Conversation") - onTriggered: showConversation(index,newsitemobject) + onTriggered: { + conversationsymbol.color="black"; + //Newsjs.conversationfromdb(db,login.username,newsitemobject.conversation_id,function(conversation){ + var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); + var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray}); + showConversation(index,newsitemobject) + } } Menu{ @@ -398,8 +363,15 @@ Item { text: qsTr("Delete") onTriggered: { Newsjs.deleteNews(root.login,root.db,newsitemobject.status_id,newsitemobject.messagetype,root,function(reply){ - newsModel.remove(index)}) + // newsModel.remove(index) + var msg = {'deleteId': index, 'model': newsModel}; + newsWorker.sendMessage(msg); + }) } } + //MenuItem{ + // text:qsTr("Show on website") + // onTriggered:Qt.openUrlExternally(login.server+"/display/"+newsitemobject + //} } }} diff --git a/source-linux/qml/photoqml/ImageUploadDialog.qml b/source-linux/qml/photoqml/ImageUploadDialog.qml new file mode 100644 index 0000000..dd38705 --- /dev/null +++ b/source-linux/qml/photoqml/ImageUploadDialog.qml @@ -0,0 +1,233 @@ +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import "qrc:/js/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Rectangle{ + id:imageDialog + property var attachImageURLs: [] + property var contacts: [] + property var groups: [] + property var contact_allow:login.permissions[0] + property var contact_deny:login.permissions[1] + property var group_allow:login.permissions[2] + property var group_deny:login.permissions[3] + property int imageNo: 0 + + function attachImage(url){ + var attachIndex=attachImageURLs.indexOf(url); + if(attachIndex>-1){ + imageUploadModel.append({"imageUrl":url.toString(),"description":""}) + } + else{imageUploadModel.remove(attachImage)} + } + + function uploadSelectedImage(inumber){ + xhr.url= login.server + "/api/friendica/photo/create.json"; + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.clearParams(); + xhr.setParam("desc",imageUploadModel.get(inumber).description); + xhr.setParam("album", album.currentText); + if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))}; + if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; + if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; + if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; + xhr.setImageFileParam("media", imageUploadModel.get(inumber).imageUrl ); + xhr.post(); + } + + z:2 + border.color: "grey" + width: parent.width-4*mm + height:parent.height-12*mm + x:2*mm + y:10*mm + property string directory: "" + + Connections{ + target:xhr + onError:{print(data)}//if (data=="image"){Helperjs.showMessage()}} + onSuccess:{//print("Bild hochgeladen "+data+" aktuelleBild "+imageNo); + print(imageNo+" "+imageUploadModel.count); + imageNo=imageNo+1; + if(imageNo0){ + uploadSelectedImage(0) + }} + } + } + ProgressBar{ + id: newimageProgress + width: 15*mm + height: buttonRow.height + anchors.top: parent.top + anchors.right:buttonRow.left + anchors.rightMargin:mm + visible: false + value: imageNo/attachImageURLs.length + } + + Component.onCompleted:{ + albumModel.append({"text":""}); + try{Helperjs.readField("album",db,"imageData",login.username,function(storedAlbums){ + //print(JSON.stringify(storedAlbums)) + for (var n in storedAlbums){ + albumModel.append({"text":storedAlbums[n]})} + })} + catch (e){print(e)} + } +// BusyIndicator{ +// id: imageBusy +// anchors.horizontalCenter: imageUploadView.horizontalCenter +// anchors.top:imageUploadView.top +// anchors.topMargin: 2*mm +// width:10*mm +// height: 10*mm +// running:false +// } +} diff --git a/source-linux/qml/photoqml/PhotoComponent.qml b/source-linux/qml/photoqml/PhotoComponent.qml index 4dc33e1..918df55 100644 --- a/source-linux/qml/photoqml/PhotoComponent.qml +++ b/source-linux/qml/photoqml/PhotoComponent.qml @@ -48,10 +48,17 @@ Package { } MouseArea { width: realImage.paintedWidth; height: realImage.paintedHeight; anchors.centerIn: realImage - onClicked: { + onPressAndHold:{print("Pressed"); + var menuString="import QtQuick.Controls 1.4; Menu {MenuItem{text:qsTr('Delete on client and server'); onTriggered: {deletepics('image','"+imageLocation+"');photoModel.remove(index)}}}"; + print (menuString); + var imagemenuObject=Qt.createQmlObject(menuString,photoWrapper,"imagemenuOutput") + imagemenuObject.popup() + } + onClicked: { if (albumWrapper.state == 'inGrid') { gridItem.GridView.view.currentIndex = index; - albumWrapper.state = 'fullscreen' + albumWrapper.state = 'fullscreen'; + listItem.ListView.view.currentIndex=index } else { gridItem.GridView.view.currentIndex = index; albumWrapper.state = 'inGrid' diff --git a/source-linux/qml/photoqml/PhotoTab.qml b/source-linux/qml/photoqml/PhotoTab.qml index 09ed13b..42392a5 100644 --- a/source-linux/qml/photoqml/PhotoTab.qml +++ b/source-linux/qml/photoqml/PhotoTab.qml @@ -47,6 +47,12 @@ Rectangle { onError:{if(data=="picture"){print("Error"+data); currentimageno=currentimageno+1}} } +// Connections{ +// target:filesystem +// onError:{print("Error deleting"); +// } +// onSuccess:print("Success deleting"); +// } function showFotos(friend){ if(friend=="backButton"){ @@ -76,24 +82,42 @@ Rectangle { }} } + function deletepics(type,url ,imageId){ + Service.deleteImage(db,login,type, url,root,function(){//showFotos("") + }) + } + ProgressBar{ id: newImagesProgress width: 15*mm height: updatePhotolist.height anchors.top: parent.top - anchors.right:updatePhotolist.left + anchors.right:uploadPhoto.left anchors.rightMargin:mm visible: false value: currentimageno/newimages.length } + //ImageUploadDialog{} + BlueButton{ + id: uploadPhoto + anchors.top: parent.top + anchors.topMargin: 0.5*mm + anchors.right:updatePhotolist.left + anchors.rightMargin:mm + text:"\uf0ee" + onClicked: { + var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml"); + var imageUpload = component.createObject(fotorectangle); + }} + BlueButton{ id: updatePhotolist anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right:phototabstatusButton.left anchors.rightMargin:mm - text:"\uf021" + text:"\uf0ed" onClicked: { Service.requestList(root.login,root.db, fotostab,function(obj){ newimages=obj;print("newimages"+JSON.stringify(obj)) diff --git a/source-linux/qml/photoqml/PhotogroupComponent.qml b/source-linux/qml/photoqml/PhotogroupComponent.qml index 76dbf66..ef9b4da 100644 --- a/source-linux/qml/photoqml/PhotogroupComponent.qml +++ b/source-linux/qml/photoqml/PhotogroupComponent.qml @@ -83,7 +83,8 @@ Package { Helperjs.readData(db,"imageData",root.login.username,function(obj){ if (obj) { for (var k=0;k - - + + User Name @@ -55,42 +55,42 @@ Intervall (0=keins) - + Confirm Bestätigen - + No server given! Kein Server angegeben! - + No username given! Kein Nutzername angegeben! - + No password given! Kein Passwort angegeben! - + No image directory given! Kein Verzeichnis für Bilder angegeben! - + No maximum news number given! Maximale News-Anzahl nicht angegeben! - + Timeline Chronologisch - + Conversations Unterhaltungen @@ -139,21 +139,67 @@ FriendsTab - + Friends Freunde - + Contacts Kontakte - + Groups Gruppen + + GroupComponent + + + Error + Fehler + + + + No name given + Kein Name angegeben + + + + ImageUploadDialog + + + Album + Album + + + + Image + Bild + + + + Description + Beschreibung + + + + Upload + Hochladen + + + + Error + Fehler + + + + No album name given + Kein Albumname angegeben + + MessageSend @@ -182,27 +228,27 @@ Lade Profilbild für - + More Mehr - + Timeline Chronologisch - + Favorites Markierte News - + Conversations Unterhaltungen - + Notifications Meldungen @@ -210,77 +256,77 @@ Newsitem - + attending: Teilnahme - + Source: Quelle: - + Direct Message Direktnachricht - + In reply to Antwort an - + comments Kommentare - + Attending: Teilnahme: - + Reply Antworten - + DM Direktnachricht - + Repost Teilen - + Conversation Unterhaltung - + Attending Teilnahme - + yes ja - + maybe vielleicht - + no nein - + Delete Löschen @@ -288,12 +334,12 @@ PermissionDialog - + Friends Freunde - + Groups Gruppen @@ -301,18 +347,18 @@ PhotoTab - + 's images s Bilder - - + + Own Images Eigene Bilder - + More Mehr @@ -338,131 +384,131 @@ newsworker - + likes this. mag das. - + like this. mögen das. - + doesn't like this. mag das nicht. - + don't like this. mögen das nicht. - + will attend. nehmen teil. - + persons will attend. Personen nehmen teil. - + will not attend. nimmt nicht teil. - + persons will not attend. Personen nehmen nicht teil. - + may attend. nimmt vielleicht teil. - + persons may attend. Personen nehmen vielleicht teil. - + yes ja - + no nein - + maybe vielleicht - + seconds Sekunden - - - - - + + + + + ago her - + minute Minute - + minutes Minuten - + hour Stunde - + hours Stunden - + day Tag - + days Tage - + month Monat - + months Monate - + years diff --git a/source-linux/translations/friendiqa-es.qm b/source-linux/translations/friendiqa-es.qm new file mode 100644 index 0000000..168374a Binary files /dev/null and b/source-linux/translations/friendiqa-es.qm differ