Friendiqa v0.2

This commit is contained in:
LubuWest 2018-02-19 22:36:00 +01:00
parent 74fb551755
commit a3be940192
123 changed files with 9156 additions and 2455 deletions

View File

@ -1,29 +1,55 @@
## v0.1# ## v0.1##
# News # # News #
* Native Android image selector for new message * Native Android image selector for new message
* Click on contacts shows contact details on news page * Click on contacts shows contact details on news page
* Fix problem with news list after deletion of item * Fix problem with news list after deletion of item
# Contacts # # Contacts #
* Clean contacts with no news * Clean contacts with no news
# Images # # Images #
* Upload pictures with description to album (permissions cannot be set due to API problems) * 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) * Delete pictures or albums from client and server (long press on picture in overview)
* Fix problem when enlarging photo * Fix problem when enlarging photo
# Translations # # Translations #
* German, Spanish * German, Spanish
## v0.1.1# ## v0.1.1##
* FIX: Spanish translation * FIX: Spanish translation
* FIX: Empty Newsview after deletion of first newsitem * FIX: Empty Newsview after deletion of first newsitem
## v0.1.2#
* FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above ## v0.1.2#
* FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above
## v0.2 ##
# News #
* Profile image download completely reworked, resulting in speed improvement
# Contacts #
* New profile tab, data of public and private profiles shown
* Change profile picture
* For friends image button shows private images thanks to new remoteAuth API (Friendica 3.6 server required) --> private holiday pictures have finally arrived!
* For friends calendar button shows private events thanks to new remoteAuth API (Friendica 3.6 server required)
* News button for forum accounts shows news published via that forum
# Images #
* Complete rework of image download, fixes bug with private images
* Download all or only new images
# Config #
* Check if nickname exist on server
* Check if password is correct
* Account deletion now also removes news, image data and events from local db
# Translations #
* Italian thanks to Davide de Prisco

BIN
Friendiqa_v0.2.apk Normal file

Binary file not shown.

View File

@ -20,7 +20,8 @@ QML based client for the Friendica Social Network.
Currently supported: Currently supported:
* Shows Posts from friends, favorited messages, Direct Messages and Notifications * Shows Posts from friends, favorited messages, Direct Messages and Notifications
* Open links in external browser * Open links in external browser
* Click on contact photo for contact details *
Click on contact photo for contact details
* Click on like text for additional contact info * Click on like text for additional contact info
* Deletion, Reposting, Answering of Posts * Deletion, Reposting, Answering of Posts
* Liking, disliking, favoriting * Liking, disliking, favoriting
@ -32,8 +33,7 @@ Currently supported:
ToDo: ToDo:
* Move picture download into a background process * Videos and other binary data as attachment (sending and receiving)
* Videos and other binary data as attachment (sending and receiving, currently not supported in API)
* More than one attachment (currently not supported in API) * More than one attachment (currently not supported in API)
* Rich text editing in Send Dialog * Rich text editing in Send Dialog
* Attachments for Direct messages (currently not supported in API) * Attachments for Direct messages (currently not supported in API)
@ -42,47 +42,54 @@ ToDo:
# Friends # # Friends #
Currently supported: Currently supported:
* Tabs for friends, other contacts and groups * Tabs for own profiles, friends, other contacts and groups
* Show profile(s) of user and change profile picture
* Grid of all known contacts with locally downloaded pictures * Grid of all known contacts with locally downloaded pictures
* Large friend item for addional information and functionality * Large friend item for additional information and functionality
* Show news of contact from local database * Show news of contact from local database
* Send direct message, if contact is following * Send direct message, if contact is following
* Show public pictures of contact (screenscraping of contact's website, works only with certain theme) * Show public and private (Friendica 3.6 required) pictures of contact (screenscraping of contact's website, works only with certain theme)
* Show public and private (Friendica 3.6 required) events of contact
* Show members of groups
* Open website of contact or connect page (for other contacts) * Open website of contact or connect page (for other contacts)
* Clean other contacts with no news * Clean other contacts with no news
ToDo: ToDo:
* More information for contact from description page, possibly private information for friends (currently not supported in API) * More information for contact from description page, possibly private information for friends
(needs API change)
* Groups: create, change, delete * Groups: create, change, delete
(needs API change)
# Images # # Images #
Currently supported: Currently supported:
* Download all own images to local directory * Download public and private own images to local directory
* Upload picture to album with descriptions(public)
* Delete own pictures and albums on client and server
* Show albums in grid, show images in album in grid and fullscreen * Show albums in grid, show images in album in grid and fullscreen
* Upload pictures to albums with description * Show public and private (Friendica 3.6 server required) albums and images of contacts
* 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: ToDo:
* Private images of friends * Change name or album of existing picture
* Support for all themes of friends * Upload private images
# Events # # Events #
* download own public events and show public events of Friendica contacts * Download own public events
* list view of events of selected date * Show public and private events of Friendica contacts (Friendica 3.6 server required)
* click on event to show details * List view of events of selected date
* Click on event to show details
ToDo ToDo
* private events * Show own private events (needs API)
* Create events (needs API)
# Config # # Config #
Currently supported: Currently supported:
* Multiple accounts * Multiple accounts
* Maximum news (surplus deleted after use of Quit button) * Maximum news (deleted after use of Quit button)
* View mode for news (tree or timeline) * View mode for news (tree or timeline)
ToDo ToDo
@ -97,12 +104,14 @@ ToDo
# Translations # # Translations #
* German, Spanish * German, Spanish, Italian
# Install # # Install #
* F-Droid binary repository: [https://www.ma-nic.de/fdroid/repo](https://www.ma-nic.de/fdroid/repo) * F-Droid binary repository: [https://www.ma-nic.de/fdroid/repo](https://www.ma-nic.de/fdroid/repo)
* [Google Playstore](https://play.google.com/store/apps/details?id=org.qtproject.friendiqa) * [Google Playstore](https://play.google.com/store/apps/details?id=org.qtproject.friendiqa)
## License ## ## License ##
Pubished under the [GPL v3](http://gplv3.fsf.org). Pubished under the [GPL v3](http://gplv3.fsf.org) with the exception of the Openssl library, which is published under OpenSSL License.

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.1.2" android:versionCode="3" android:installLocation="auto"> <manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.2" android:versionCode="4" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:vmSafeMode="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Friendiqa" android:icon="@drawable/friendiqa" android:logo="@drawable/friendiqa" android:theme="@android:style/Theme.Holo.Light"> <application android:hardwareAccelerated="true" android:vmSafeMode="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Friendiqa" android:icon="@drawable/friendiqa" android:logo="@drawable/friendiqa" android:theme="@android:style/Theme.Holo.Light">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="androidnative.friendiqa.FriendiqaActivity" android:label="Friendiqa" android:screenOrientation="unspecified" android:launchMode="singleTop"> <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="androidnative.friendiqa.FriendiqaActivity" android:label="Friendiqa" android:screenOrientation="unspecified" android:launchMode="singleTop">
<intent-filter> <intent-filter>

View File

@ -210,13 +210,13 @@
<file>translations/friendiqa-es.qm</file> <file>translations/friendiqa-es.qm</file>
<file>translations/friendiqa-es.ts</file> <file>translations/friendiqa-es.ts</file>
<file>qml/photoqml/ImageUploadDialog.qml</file> <file>qml/photoqml/ImageUploadDialog.qml</file>
<file>qml/genericqml/ImageDialog.qml</file>
<file>qml/genericqml/PermissionDialog.qml</file> <file>qml/genericqml/PermissionDialog.qml</file>
<file>images/addImage.png</file> <file>images/addImage.png</file>
<file>common/imageselectandroid.h</file>
<file>common/imageselectandroid.cpp</file>
<file>qml/genericqml/ImagePicker.qml</file> <file>qml/genericqml/ImagePicker.qml</file>
<file>common/quickandroid.h</file> <file>qml/genericqml/ImagePickerLinux.qml</file>
<file>common/quickandroid.cpp</file> <file>js/image.js</file>
<file>qml/contactqml/ProfileComponent.qml</file>
<file>translations/friendiqa-it.ts</file>
<file>translations/friendiqa-it.qm</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "filesystem.h" #include "filesystem.h"
FILESYSTEM *FILESYSTEM::instance() FILESYSTEM *FILESYSTEM::instance()
@ -29,12 +60,12 @@ QString FILESYSTEM::homePath() const
return homeDir; return homeDir;
} }
QString FILESYSTEM::cameraPath() const //QString FILESYSTEM::cameraPath() const
{ //{
QAndroidJniObject object = QAndroidJniObject::getStaticObjectField<jstring>("android.os.Environment", "DIRECTORY_DCIM"); //QAndroidJniObject object = QAndroidJniObject::getStaticObjectField<jstring>("android.os.Environment", "DIRECTORY_DCIM");
QAndroidJniObject dcim =QAndroidJniObject::callStaticObjectMethod("android.os.Environment","getExternalStoragePublicDirectory", "(Ljava/lang/String;)Ljava/io/File;", object.object<jobject>()); //QAndroidJniObject dcim =QAndroidJniObject::callStaticObjectMethod("android.os.Environment","getExternalStoragePublicDirectory", "(Ljava/lang/String;)Ljava/io/File;", object.object<jobject>());
return dcim.toString(); // return dcim.toString();
} //}
//bool FILESYSTEM::direxist(QString Directory) const //bool FILESYSTEM::direxist(QString Directory) const
@ -83,46 +114,46 @@ QFileInfoList FILESYSTEM::fileList()
return dir.entryInfoList(); return dir.entryInfoList();
} }
void FILESYSTEM::searchImage() //void FILESYSTEM::searchImage()
{ //{
QAndroidJniObject ACTION_PICK = QAndroidJniObject::getStaticObjectField("android/content/Intent", "ACTION_PICK", "Ljava/lang/String;"); // 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 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<jstring>(), EXTERNAL_CONTENT_URI.object<jobject>()); // QAndroidJniObject intent=QAndroidJniObject("android/content/Intent", "(Ljava/lang/String;Landroid/net/Uri;)V", ACTION_PICK.object<jstring>(), EXTERNAL_CONTENT_URI.object<jobject>());
if (ACTION_PICK.isValid() && intent.isValid()) // if (ACTION_PICK.isValid() && intent.isValid())
{ // {
intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("image/*").object<jstring>()); // intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("image/*").object<jstring>());
QtAndroid::startActivity(intent.object<jobject>(), 101,this); // QtAndroid::startActivity(intent.object<jobject>(), 101,this);
qDebug() << "OK"; // qDebug() << "OK";
} // }
else // else
{ // {
qDebug() << "ERRO"; // qDebug() << "ERRO";
} // }
} //}
void FILESYSTEM::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) //void FILESYSTEM::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data)
{ //{
jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK"); // jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK");
if (receiverRequestCode == 101 && resultCode == RESULT_OK) // if (receiverRequestCode == 101 && resultCode == RESULT_OK)
{ // {
QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;"); // QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;");
QAndroidJniObject dadosAndroid = QAndroidJniObject::getStaticObjectField("android/provider/MediaStore$MediaColumns", "DATA", "Ljava/lang/String;"); // QAndroidJniObject dadosAndroid = QAndroidJniObject::getStaticObjectField("android/provider/MediaStore$MediaColumns", "DATA", "Ljava/lang/String;");
QAndroidJniEnvironment env; // QAndroidJniEnvironment env;
jobjectArray projecao = (jobjectArray)env->NewObjectArray(1, env->FindClass("java/lang/String"), NULL); // jobjectArray projecao = (jobjectArray)env->NewObjectArray(1, env->FindClass("java/lang/String"), NULL);
jobject projacaoDadosAndroid = env->NewStringUTF(dadosAndroid.toString().toStdString().c_str()); // jobject projacaoDadosAndroid = env->NewStringUTF(dadosAndroid.toString().toStdString().c_str());
env->SetObjectArrayElement(projecao, 0, projacaoDadosAndroid); // env->SetObjectArrayElement(projecao, 0, projacaoDadosAndroid);
QAndroidJniObject contentResolver = QtAndroid::androidActivity().callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;"); // 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<jobject>(), projecao, NULL, NULL, NULL); // 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<jobject>(), projecao, NULL, NULL, NULL);
jint columnIndex = cursor.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", dadosAndroid.object<jstring>()); // jint columnIndex = cursor.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", dadosAndroid.object<jstring>());
cursor.callMethod<jboolean>("moveToFirst", "()Z"); // cursor.callMethod<jboolean>("moveToFirst", "()Z");
QAndroidJniObject resultUri = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex); // QAndroidJniObject resultUri = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex);
QString imageSelect = "file://" + resultUri.toString(); // QString imageSelect = "file://" + resultUri.toString();
emit imageselected(imageSelect); // emit imageselected(imageSelect);
} // }
else // else
{ // {
qDebug() << "Select error"; // qDebug() << "Select error";
} // }
} //}

View File

@ -1,18 +1,49 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef FILESYSTEM_H #ifndef FILESYSTEM_H
#define FILESYSTEM_H #define FILESYSTEM_H
#include <QDir> #include <QDir>
#include <QObject> #include <QObject>
#include <QtAndroidExtras> //#include <QtAndroidExtras>
#include <QAndroidActivityResultReceiver> //#include <QAndroidActivityResultReceiver>
class FILESYSTEM : public QObject, public QAndroidActivityResultReceiver class FILESYSTEM : public QObject//, public QAndroidActivityResultReceiver
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged) Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged)
//Q_PROPERTY(bool direxist READ direxist) //Q_PROPERTY(bool direxist READ direxist)
Q_PROPERTY(QString homePath READ homePath) Q_PROPERTY(QString homePath READ homePath)
Q_PROPERTY(QString cameraPath READ cameraPath) //Q_PROPERTY(QString cameraPath READ cameraPath)
public: public:
@ -23,11 +54,11 @@ public:
QFileInfoList fileList(); QFileInfoList fileList();
//bool direxist(QString Directory); //bool direxist(QString Directory);
QString homePath() const; QString homePath() const;
QString cameraPath() const; //QString cameraPath() const;
virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data); // virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data);
signals: signals:
void imageselected(QString); //void imageselected(QString);
void directoryChanged(); void directoryChanged();
//void fileListContent(QList data); //void fileListContent(QList data);
void success(QString data); void success(QString data);
@ -37,7 +68,7 @@ public slots:
void makeDir(QString name); void makeDir(QString name);
void rmDir(); void rmDir();
void rmFile(QString name); void rmFile(QString name);
void searchImage(); //void searchImage();
//void fileList(); //void fileList();
private: private:

View File

@ -1,15 +1,45 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QApplication> #include <QApplication>
#include <QtQml/QQmlEngine> #include <QtQml/QQmlEngine>
#include <QtQuick> #include <QtQuick>
#include "xhr.h" #include "xhr.h"
#include "filesystem.h" #include "filesystem.h"
//#include "qadrawableprovider.h" #include "remoteauthasyncimageprovider.h"
//#include "androidnative.pri/cpp/AndroidNative/systemdispatcher.h"
#include "AndroidNative/systemdispatcher.h" #include "AndroidNative/systemdispatcher.h"
#include "AndroidNative/environment.h" #include "AndroidNative/environment.h"
#include "AndroidNative/debug.h" //#include "AndroidNative/debug.h"
#include "AndroidNative/mediascannerconnection.h" #include "AndroidNative/mediascannerconnection.h"
//#include "debugwrapper.h"
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
#include <QtAndroidExtras/QAndroidJniObject> #include <QtAndroidExtras/QAndroidJniObject>
@ -30,9 +60,9 @@ int main(int argc, char *argv[]) {
QTranslator qtTranslator; QTranslator qtTranslator;
qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations"); qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations");
app.installTranslator(&qtTranslator); app.installTranslator(&qtTranslator);
RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider;
// qmlRegisterType<QASystemDispatcher>("SystemDispatcher", 0, 1, "SystemDispatcher"); view.engine()->addImageProvider("remoteauthimage",imageProvider);
view.rootContext()->setContextProperty("remoteauth", imageProvider);
XHR* xhr = XHR::instance(); XHR* xhr = XHR::instance();
view.rootContext()->setContextProperty("xhr", xhr); view.rootContext()->setContextProperty("xhr", xhr);
FILESYSTEM* filesystem = FILESYSTEM::instance(); FILESYSTEM* filesystem = FILESYSTEM::instance();

View File

@ -1,56 +0,0 @@
#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<jstring>(), EXTERNAL_CONTENT_URI.object<jobject>());
if (ACTION_PICK.isValid() && intent.isValid())
{
intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("image/*").object<jstring>());
QtAndroid::startActivity(intent.object<jobject>(), 101, this);
qDebug() << "OK";
}
else
{
qDebug() << "ERRO";
}
}
void imageSelectAndroid::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data)
{ qDebug() << "done";
jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("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<jobject>(), projecao, NULL, NULL, NULL);
jint columnIndex = cursor.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", dadosAndroid.object<jstring>());
cursor.callMethod<jboolean>("moveToFirst", "()Z");
QAndroidJniObject resultUri = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex);
QString imageSelect = "file://" + resultUri.toString();
emit imageselected(imageSelect);
}
else
{
qDebug() << "Select error";
}
}

View File

@ -1,23 +0,0 @@
#ifndef IMAGEPICKANDROID_H
#define IMAGEPICKANDROID_H
#include <QObject>
#include <QtAndroidExtras>
#include <QDebug>
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

View File

@ -1,348 +0,0 @@
// Author: Ben Lau (https://github.com/benlau)
#include <QCoreApplication>
#include <QPointer>
#include <QtCore>
#include <QPair>
#include <QQueue>
#include "qasystemdispatcher.h"
static QPointer<QASystemDispatcher> m_instance;
QString QASystemDispatcher::ACTIVITY_RESUME_MESSAGE = "Activity.onResume";
QString QASystemDispatcher::ACTIVITY_RESULT_MESSAGE = "Activity.onActivityResult";
#ifdef Q_OS_ANDROID
#include <QAndroidJniObject>
#include <QAndroidJniEnvironment>
#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<jobject>(),jclass_of_boolean)) {
v = QVariant::fromValue<bool>(value.callMethod<jboolean>("booleanValue","()Z"));
} else if (env->IsInstanceOf(value.object<jobject>(),jclass_of_integer)) {
v = value.callMethod<jint>("intValue","()I");
} else if (env->IsInstanceOf(value.object<jobject>(),jclass_of_string)) {
v = value.toString();
} else if (env->IsInstanceOf(value.object<jobject>(), jclass_of_map)) {
v = createVariantMap(value.object<jobject>());
} else if (env->IsInstanceOf(value.object<jobject>(),jclass_of_list)) {
QVariantList list;
int count = value.callMethod<jint>("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, "<init>", "(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,"<init>","(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<QVariantList>();
jclass arrayListClass = env->FindClass("java/util/ArrayList");
jmethodID init = env->GetMethodID(arrayListClass, "<init>", "(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, "<init>", "(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<QString, QVariant> 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<void>(JCLASS_Name, "dispatch",
DISPATCH_SIGNATURE,
jType,jData);
env->DeleteLocalRef(jType);
env->DeleteLocalRef(jData);
#else
static bool dispatching = false;
static QQueue<QPair<QString,QVariantMap> > queue;
if (dispatching) {
queue.enqueue(QPair<QString,QVariantMap> (type,message) );
return;
}
dispatching = true;
emit dispatched(type,message);
qWarning() << "QASystemDispatcher: emitted"
while (queue.size() > 0) {
QPair<QString,QVariantMap> 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<void>(JCLASS_Name, "init",
"()V");
#endif
}

View File

@ -1,47 +0,0 @@
// Author: Ben Lau (https://github.com/benlau)
#pragma once
#include <QObject>
#include <QVariantMap>
/// 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);
};

View File

@ -1,22 +0,0 @@
#include <QtQml>
#include <QVariantMap>
#include "quickandroid.h"
//#include "qadevice.h"
//#include "qamousesensor.h"
#ifdef Q_OS_ANDROID
#include <QAndroidJniEnvironment>
#include <QAndroidJniObject>
#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();
//}

View File

@ -1,21 +0,0 @@
#ifndef QUICKANDROID_H
#define QUICKANDROID_H
#include <QtGlobal>
/// 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

View File

@ -0,0 +1,123 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "remoteauthasyncimageprovider.h"
#include <QQuickAsyncImageProvider>
#include <QImage>
AsyncImageResponse::AsyncImageResponse(QNetworkRequest req, QSize reqSize)
{
m_reply = m_imageLoader.get(req);
m_requestedSize = reqSize;
connect(m_reply, &QNetworkReply::finished, this, &AsyncImageResponse::onResponseFinished);
}
void AsyncImageResponse::onResponseFinished()
{
QByteArray myImageData = m_reply->readAll();
m_resultImage = QImage::fromData(myImageData);
if (m_requestedSize.isValid())
{
m_resultImage = m_resultImage.scaled(m_requestedSize);
}
emit finished();
}
QQuickTextureFactory *AsyncImageResponse::textureFactory() const
{
return QQuickTextureFactory::textureFactoryForImage(m_resultImage);
}
RemoteAuthAsyncImageProvider::RemoteAuthAsyncImageProvider()
{
}
QQuickImageResponse* RemoteAuthAsyncImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize)
{
QUrl iUrl=url()+"/api/friendica/remoteauth?c_url="+contacturl()+"&url="+id;
QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData;
QNetworkRequest request(iUrl);
request.setRawHeader("Authorization", headerData.toLocal8Bit());
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute,true);
request.setUrl(iUrl);
return new AsyncImageResponse(request, requestedSize);
}
void RemoteAuthAsyncImageProvider::setContacturl(QString contacturl)
{
if (contacturl!=m_contacturl) {
m_contacturl = contacturl;
emit contacturlChanged();
}
}
void RemoteAuthAsyncImageProvider::setUrl(QString url)
{
if (url!=m_url) {
m_url = url;
emit urlChanged();
}
}
void RemoteAuthAsyncImageProvider::setLogin(QString login)
{
if (login!=m_login) {
m_login = login;
emit loginChanged();
}
}
QString RemoteAuthAsyncImageProvider::contacturl() const
{
return m_contacturl;
}
QString RemoteAuthAsyncImageProvider::url() const
{
return m_url;
}
QString RemoteAuthAsyncImageProvider::login() const
{
return m_login;
}

View File

@ -0,0 +1,95 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef REMOTEAUTHIMAGEPROVIDER_H
#define REMOTEAUTHIMAGEPROVIDER_H
#include <QObject>
#include <QQuickAsyncImageProvider>
#include <QImage>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
class AsyncImageResponse : public QQuickImageResponse
{
Q_OBJECT
public:
explicit AsyncImageResponse(QNetworkRequest req, QSize requestedSize);
QQuickTextureFactory *textureFactory() const;
public slots:
void onResponseFinished();
protected:
QNetworkAccessManager m_imageLoader;
QNetworkReply* m_reply;
QSize m_requestedSize;
QImage m_resultImage;
int m_index;
QString m_id;
QImage m_image;
};
class RemoteAuthAsyncImageProvider : public QObject, public QQuickAsyncImageProvider
{
Q_OBJECT
Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(QString contacturl READ contacturl WRITE setContacturl NOTIFY contacturlChanged)
Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged)
public:
explicit RemoteAuthAsyncImageProvider();
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
QString url() const;
QString contacturl() const;
QString login() const;
signals:
void contacturlChanged();
void urlChanged();
void loginChanged();
public slots:
void setContacturl(QString contacturl);
void setUrl(QString url);
void setLogin(QString login);
private:
QByteArray buffer;
QString m_url;
QString m_contacturl;
QString m_login;
QString bufferToString();
};
#endif // REMOTEAUTHIMAGEPROVIDER_H

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "uploadableimage.h" #include "uploadableimage.h"

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef UPLOADABLEIMAGE_H #ifndef UPLOADABLEIMAGE_H
#define UPLOADABLEIMAGE_H #define UPLOADABLEIMAGE_H

View File

@ -1,12 +1,43 @@
#include "xhr.h" // This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "xhr.h"
#include <QHttpPart> #include <QHttpPart>
#include <QTextCodec> #include <QTextCodec>
#include <QUrlQuery> #include <QUrlQuery>
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QList> #include <QList>
#include <QDataStream> #include <QDataStream>
#include <QJsonDocument>
#include <QJsonObject>
#include "uploadableimage.h" #include "uploadableimage.h"
XHR *XHR::instance() XHR *XHR::instance()
@ -44,6 +75,29 @@ void XHR::setFilename(QString filename)
} }
} }
void XHR::setContactlist(QList<QString> contactlist)
{
if (contactlist!=m_contactlist) {
m_contactlist = contactlist;
emit contactlistChanged();
}
}
void XHR::setFilelist(QList<QString> filelist)
{
if (filelist!=m_filelist) {
m_filelist = filelist;
emit filelistChanged();
}
}
void XHR::setImagedir(QString imagedir)
{
if (imagedir!=m_imagedir) {
m_imagedir = imagedir;
emit imagedirChanged();
}
}
void XHR::setDownloadtype(QString downloadtype) void XHR::setDownloadtype(QString downloadtype)
{ {
if (downloadtype!=m_downloadtype) { if (downloadtype!=m_downloadtype) {
@ -67,6 +121,21 @@ QString XHR::filename() const
return m_filename; return m_filename;
} }
QList<QString> XHR::contactlist() const
{
return m_contactlist;
}
QList<QString> XHR::filelist() const
{
return m_filelist;
}
QString XHR::imagedir() const
{
return m_imagedir;
}
QString XHR::downloadtype() const QString XHR::downloadtype() const
{ {
return m_downloadtype; return m_downloadtype;
@ -91,9 +160,14 @@ void XHR::clearParams()
void XHR::download() void XHR::download()
{ {
QUrl requrl(m_url); QUrl requrl(m_url);
if(m_downloadtype=="picturelist"){
QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData;
request.setRawHeader("Authorization", headerData.toLocal8Bit());
}
request.setUrl(requrl); request.setUrl(requrl);
reply = manager.get(request); reply = manager.get(request);
// reply->ignoreSslErrors(); reply->ignoreSslErrors();
connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead); connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead);
//connect(reply,SIGNAL(downloadProgress(qint64,qint64)), this,SLOT(updateDownloadProgress(qint64,qint64))); //connect(reply,SIGNAL(downloadProgress(qint64,qint64)), this,SLOT(updateDownloadProgress(qint64,qint64)));
connect(reply, &QNetworkReply::finished,this, &XHR::onRequestFinished); connect(reply, &QNetworkReply::finished,this, &XHR::onRequestFinished);
@ -117,9 +191,6 @@ void XHR::get()
QByteArray loginData = m_login.toLocal8Bit().toBase64(); QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData; QString headerData = "Basic " + loginData;
request.setRawHeader("Authorization", headerData.toLocal8Bit()); request.setRawHeader("Authorization", headerData.toLocal8Bit());
// QNetworkCookieJar* cJar = new QNetworkCookieJar;
// manager.setCookieJar(cJar);
request.setUrl(requrl); request.setUrl(requrl);
reply = manager.get(request); reply = manager.get(request);
@ -129,6 +200,20 @@ void XHR::get()
connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError); connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError);
} }
void XHR::getlist()
{
if(dlindex < m_filelist.size()) {
QString cleanfilename;
if (m_downloadtype=="contactlist"){cleanfilename = m_contactlist.at(dlindex)+"-"+ m_filelist.at(dlindex).section('/',-1).section('?',0,0);
XHR::setFilename(imagedir()+"contacts/"+cleanfilename);
XHR::setUrl(m_filelist.at(dlindex));}
else {
XHR::setUrl(m_filelist.at(dlindex));}
XHR::download();
} else {dlindex=0;}
}
void XHR::post() void XHR::post()
{ {
qDebug() << "start post to " << m_url; qDebug() << "start post to " << m_url;
@ -178,7 +263,7 @@ void XHR::post()
void XHR::onReplyError(QNetworkReply::NetworkError code) void XHR::onReplyError(QNetworkReply::NetworkError code)
{ {
qDebug() << code; qDebug() << code;
emit this->error( bufferToString(), (int) code); emit this->error( bufferToString(), m_url, (int) code);
buffer.clear(); buffer.clear();
reply->deleteLater(); reply->deleteLater();
} }
@ -194,14 +279,45 @@ void XHR::onReplySuccess()
void XHR::onRequestFinished() void XHR::onRequestFinished()
{ {
// Save the file here // Save the file here
//qDebug() << "buffer downloaded "<<buffer; if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,m_url,1);}
if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,1);} else if (m_downloadtype=="picturelist") {
else {QFile file(m_filename); QJsonDocument jsonResponse = QJsonDocument::fromJson(buffer);
file.open(QIODevice::WriteOnly); QJsonObject jsonObject = jsonResponse.object();
file.write(buffer); int arraystart=buffer.indexOf('{"data":"')+8;
buffer.clear(); int arraylength=buffer.indexOf('"',9)-arraystart;
file.close(); QByteArray b64=buffer.mid(arraystart,arraylength);
emit this->downloaded(m_downloadtype); QString helpfilename=jsonObject["filename"].toString();
QString helpfile=helpfilename.left(helpfilename.lastIndexOf("."));
QString filesuffix="";
if (jsonObject["type"].toString()=="image/jpeg"){filesuffix=".jpg";}
else if (jsonObject["type"].toString()=="image/png"){filesuffix=".png";}
else {filesuffix="";}
if (helpfilename==""){// check if file has any filename
helpfile=jsonObject["id"].toString();
setFilename(imagedir()+"albums/"+jsonObject["album"].toString()+"/"+jsonObject["id"].toString()+filesuffix);
}
else{setFilename(imagedir()+"albums/"+jsonObject["album"].toString()+"/"+helpfile+filesuffix);}
//qDebug()<<"Filename "<<m_filename;
QFile file(m_filename);
file.open(QIODevice::WriteOnly);
file.write(QByteArray::fromBase64(b64));
buffer.clear();
b64.clear();
file.close();
jsonObject["data"]="";
jsonObject["filename"]=helpfile+filesuffix;
emit this->downloadedjson(m_downloadtype,m_url,m_filename,dlindex,jsonObject);
if(downloadtype()=="picturelist"){dlindex=dlindex+1;XHR::getlist();}
}
else {
QFile file(m_filename);
file.open(QIODevice::WriteOnly);
file.write(buffer);
buffer.clear();
file.close();
emit this->downloaded(m_downloadtype,m_url,m_filename,dlindex);
if(downloadtype()=="contactlist"){dlindex=dlindex+1;XHR::getlist();}
//reply->deleteLater(); //reply->deleteLater();
} }
} }
@ -210,15 +326,6 @@ void XHR::onReadyRead()
{ {
qDebug() << "."; qDebug() << ".";
buffer += reply->readAll(); buffer += reply->readAll();
// QList<QNetworkCookie> 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) //void XHR::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes)

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef XHR_H #ifndef XHR_H
#define XHR_H #define XHR_H
@ -5,6 +36,7 @@
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QObject> #include <QObject>
#include <QJsonObject>
class XHR : public QObject class XHR : public QObject
{ {
@ -12,6 +44,9 @@ class XHR : public QObject
Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged) Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged)
Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged) Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
Q_PROPERTY(QString imagedir READ imagedir WRITE setImagedir NOTIFY imagedirChanged)
Q_PROPERTY(QList<QString> contactlist READ contactlist WRITE setContactlist NOTIFY contactlistChanged)
Q_PROPERTY(QList<QString> filelist READ filelist WRITE setFilelist NOTIFY filelistChanged)
Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged) Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged)
@ -23,27 +58,38 @@ public:
QString url() const; QString url() const;
QString login() const; QString login() const;
QString filename() const; QString filename() const;
QList<QString> contactlist() const;
QList<QString> filelist() const;
QString imagedir() const;
QString downloadtype() const; QString downloadtype() const;
signals: signals:
void urlChanged(); void urlChanged();
void loginChanged(); void loginChanged();
void filenameChanged(); void filenameChanged();
void contactlistChanged();
void filelistChanged();
void imagedirChanged();
void downloadtypeChanged(); void downloadtypeChanged();
void downloaded(QString data); void downloaded(QString type, QString url, QString filename, int i);
void downloadedjson(QString type, QString url, QString filename, int i,QJsonObject jsonObject);
void success(QString data); void success(QString data);
void error(QString data, int code); void error(QString data, QString url, int code);
public slots: public slots:
void setUrl(QString url); void setUrl(QString url);
void setLogin(QString login); void setLogin(QString login);
void setDownloadtype(QString downloadtype); void setDownloadtype(QString downloadtype);
void setFilename(QString filename); void setFilename(QString filename);
void setContactlist(QList<QString> filename);
void setFilelist(QList<QString> filename);
void setImagedir(QString filename);
void setParam(QString name, QString value); void setParam(QString name, QString value);
void setImageFileParam(QString name, QString url); void setImageFileParam(QString name, QString url);
void clearParams(); void clearParams();
void post(); void post();
void get(); void get();
void getlist();
void download(); void download();
private slots: private slots:
@ -62,6 +108,10 @@ private:
QString m_downloadtype; QString m_downloadtype;
QHash<QString, QString> params; QHash<QString, QString> params;
QHash<QString, QString> files; QHash<QString, QString> files;
QList<QString> m_filelist;
QList<QString> m_contactlist;
QString m_imagedir;
int dlindex;
QNetworkAccessManager manager; QNetworkAccessManager manager;
QNetworkRequest request; QNetworkRequest request;

View File

@ -21,6 +21,7 @@ SOURCES += common/friendiqa.cpp \
common/uploadableimage.cpp \ common/uploadableimage.cpp \
common/xhr.cpp \ common/xhr.cpp \
common/filesystem.cpp \ common/filesystem.cpp \
common/remoteauthasyncimageprovider.cpp
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
@ -42,7 +43,8 @@ TRANSLATIONS += translations/friendiqa-de.ts \
HEADERS += \ HEADERS += \
common/uploadableimage.h \ common/uploadableimage.h \
common/xhr.h \ common/xhr.h \
common/filesystem.h common/filesystem.h \
common/remoteauthasyncimageprovider.h
DISTFILES += \ DISTFILES += \
qml/calendarqml/*.qml \ qml/calendarqml/*.qml \

View File

@ -1,3 +1,33 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
WorkerScript.onMessage = function(msg) { WorkerScript.onMessage = function(msg) {
msg.model.clear(); msg.model.clear();
for (var j=0;j<msg.albums.length;j++){ for (var j=0;j<msg.albums.length;j++){

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
.pragma library .pragma library
.import QtQuick.LocalStorage 2.0 as Sql .import QtQuick.LocalStorage 2.0 as Sql
@ -64,6 +95,20 @@ function friendicaWebRequest(url,rootwindow,callback) {
xhrequest.send(); xhrequest.send();
} }
function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) {
var xhrequest = new XMLHttpRequest();
xhrequest.onreadystatechange = function() {
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {}
else if(xhrequest.readyState === XMLHttpRequest.DONE) {
try{callback(xhrequest.responseText)}
catch (e){showMessage("Error",url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)}
}
}
xhrequest.open("GET", login.server+"/api/friendica/remoteauth?c_url="+c_url+"&url="+url,true,login.username,Qt.atob(login.password));
xhrequest.send();
}
function readData(database,table,username,callback,filter,filtervalue, sort) { // reads and applies data from DB function readData(database,table,username,callback,filter,filtervalue, sort) { // reads and applies data from DB
if (filter){ if (filter){
var where = " AND "+ filter +" = '" + filtervalue+"'"; var where = " AND "+ filter +" = '" + filtervalue+"'";
@ -107,7 +152,8 @@ 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 cleanmessage=message.replace(/"/g,"-"); //print(cleanmessage);
if(cleanmessage.length>200){cleanmessage=cleanmessage.slice(0,200)+'...'}
var messageString='import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:"'+header+'";standardButtons: StandardButton.Ok; text:" '+cleanmessage+'"}'; 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"); var messageObject=Qt.createQmlObject(messageString,rootwindow,"messageOutput");
} }

272
source-android/js/image.js Normal file
View File

@ -0,0 +1,272 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
.pragma library
.import QtQuick.LocalStorage 2.0 as Sql
.import "qrc:/js/helper.js" as Helperjs
function requestList(login,database,onlynew,rootwindow,callback) {
//get list of own images and call download function
Helperjs.friendicaRequest(login,"/api/friendica/photos/list", rootwindow,function (helperobject){
//print("return"+helperobject);
var obj=JSON.parse(helperobject);
if (onlynew){Helperjs.readField("id",database,"imageData",login.username,function(AllStoredImages){
if (AllStoredImages.length>0){
for(var i=0;i< AllStoredImages.length;i++){
var position=Helperjs.inArray(obj,"id",AllStoredImages[i]);
if (position>-1){obj.splice(position,1)}
}
}
callback(obj)
})}
else{callback(obj)}
})}
function dataRequest(login,photoID,database,xhr,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.setLogin(login.username+":"+Qt.atob(login.password));
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 storeImagedata(login,database,imagedata,rootwindow) {
// check if image exist and call download function
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 = "'+imagedata["id"]+'"');
if(result.rows.length === 1) {// use update
result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+imagedata.id+'", created="'+imagedata.created+'", edited="'+imagedata.edited+'", profile="'+imagedata.profile+'", link="'+imagedata.link[0]+'", filename="'+imagedata.filename+'",title="'+imagedata.title+'", desc="'+imagedata.desc+'", type="'+imagedata.type+'", width="'+imagedata.width+'", height="'+imagedata.height+'", album="'+imagedata.album+'", location="file://'+login.imagestore+'albums/'+imagedata.album+'/" where id="'+imagedata["id"]+'"');
} else {// use insert print('... does not exists, create it')
result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,imagedata.id,imagedata.created,imagedata.edited, imagedata.title, imagedata.desc, imagedata.album, imagedata.filename, imagedata.type, imagedata.height, imagedata.width,imagedata. profile,imagedata.link[0],'file://'+login.imagestore+'albums/'+imagedata.album+"/"]);
}
})}
function deleteImage(database,login,type,location,filesystem,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) {
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){
// //print(photohtml);
// var photoarray=[];
// var arr = photohtml.split("sidebar-photos-albums-li");
// for (var i=2;i<arr.length;i++){
// var albumlink = arr[i].substring(arr[i].indexOf('http'),arr[i].indexOf('class')-2);
// var albumname=arr[i].substring(arr[i].indexOf('/span')+6,arr[i].indexOf('</a>')-1);
// var album={'link':albumlink,'name':albumname}
// photoarray.push(album);
// }
// callback(photoarray)
// })
//}
function newRequestFriendsAlbumPictures(login,friend,rootwindow,callback){
// screenscraping of albums page of contact with remoteAuth
Helperjs.friendicaRemoteAuthRequest(login,friend.url.replace("profile","photos"),friend.url,rootwindow,function(photohtml){
//print("Photohtml: "+photohtml);
try {var obj=JSON.parse(photohtml);
if (obj.hasOwnProperty('status')){
Helperjs.friendicaWebRequest(friend.url.replace("profile","photos"),rootwindow,function(photohtml){
getAlbumFromHtml(photohtml,false,rootwindow,callback)})
}}
catch (e){
getAlbumFromHtml(photohtml,true,rootwindow,callback)
}
})
}
function getAlbumFromHtml(photohtml,remoteAuthBool,rootwindow,callback){
var photoarray=[];
var arr = photohtml.split("sidebar-photos-albums-li");
for (var i=2;i<arr.length;i++){
var albumlink = arr[i].substring(arr[i].indexOf('http'),arr[i].indexOf('class')-2);
var albumname=arr[i].substring(arr[i].indexOf('/span')+6,arr[i].indexOf('</a>')-1);
var album={'link':albumlink,'name':albumname}//print(albumlink+" "+albumname);
photoarray.push(album);
}
callback(photoarray,remoteAuthBool)
}
function newRequestFriendsPictures(login,link,friend,remoteAuthBool,remoteauth,rootwindow,callback){
// screenscraping of pictures page for given album
if (remoteAuthBool){
remoteauth.setUrl(login.server);
remoteauth.setLogin(login.username+":"+Qt.atob(login.password));
remoteauth.setContacturl(friend.url);
Helperjs.friendicaRemoteAuthRequest(login,link,friend.url,rootwindow,function(photohtml){
getPictureFromHtml(photohtml,remoteAuthBool,function(photoarray){
callback(photoarray)
})
})}
else{
Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){
getPictureFromHtml(photohtml,remoteAuthBool,function(photoarray){
callback(photoarray)
})
})
}
}
function getPictureFromHtml(photohtml,remoteAuthBool,callback){
var photoarray=[];
var basehtml=photohtml.substring(photohtml.indexOf('<base')+12,photohtml.indexOf('/>',photohtml.indexOf('<base'))-2);
// old theme
if (photohtml.indexOf("photo-album-image-wrapper-end")>-1){ //theme 1
var arr = photohtml.split("photo-album-image-wrapper-end");}
// other themes
if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2
var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end"))
var arr = photoarea.split("</a>");}
//print("Url: "+login.server+ "Contacturl: "+friend.url)
// remoteauth.setUrl(login.server);
// remoteauth.setLogin(login.username+":"+Qt.atob(login.password));
// remoteauth.setContacturl(friend.url);
for (var i=0;i<arr.length-1;i++){
var photoname=arr[i].substring(arr[i].lastIndexOf('alt')+5,arr[i].lastIndexOf('title')-2);
var thumblink=arr[i].substring(arr[i].lastIndexOf('<img')+10,arr[i].lastIndexOf('alt')-2);
var imagetype=thumblink.substring(thumblink.lastIndexOf("."));
var photolink=thumblink.substring(0,thumblink.length-imagetype.length-2)+"-0"+imagetype
if(thumblink.substring(0,4)!=="http"){thumblink=basehtml+thumblink}
if(photolink.substring(0,4)!=="http"){photolink=basehtml+photolink}
if(remoteAuthBool){
thumblink="image://remoteauthimage/"+thumblink;
photolink="image://remoteauthimage/"+photolink;
}
//Helperjs.friendicaRemoteAuthRequest(login,thumblink,friend.url,rootwindow,function(thumbimage){thumbbase64=QT.btoa(thumbimage)});
//thumblink="image://remoteauthimage/"+login.username+":"+Qt.atob(login.password)+"@"+login.server+"/api/friendica/remoteauth?c_url="+friend.url+"&url="+thumblink;
var photo={'link':photolink,'name':photoname,'thumb':thumblink}
photoarray.push(photo);
}
callback(photoarray)
}
function requestFriendsPictures(link,rootwindow,callback){
// screenscraping of pictures page for given album
Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){
var photoarray=[];
var basehtml=photohtml.substring(photohtml.indexOf('<base')+12,photohtml.indexOf('/>',photohtml.indexOf('<base'))-2);
// old theme
if (photohtml.indexOf("photo-album-image-wrapper-end")>-1){ //theme 1
var arr = photohtml.split("photo-album-image-wrapper-end");}
// other themes
if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2
var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end"))
var arr = photoarea.split("</a>");}
for (var i=0;i<arr.length-1;i++){
var photoname=arr[i].substring(arr[i].lastIndexOf('alt')+5,arr[i].lastIndexOf('title')-2);
var thumblink=arr[i].substring(arr[i].lastIndexOf('<img')+10,arr[i].lastIndexOf('alt')-2);
var imagetype=thumblink.substring(thumblink.lastIndexOf("."));
var photolink=thumblink.substring(0,thumblink.length-imagetype.length-2)+"-0"+imagetype
if(thumblink.substring(0,4)!=="http"){thumblink=basehtml+thumblink}
if(photolink.substring(0,4)!=="http"){photolink=basehtml+photolink}
var photo={'link':photolink,'name':photoname,'thumb':thumblink}
photoarray.push(photo);
}
callback(photoarray)
})
}

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
function showFriends(db) { function showFriends(db) {
Service.readActiveConfig(db,function(login){ Service.readActiveConfig(db,function(login){
Service.requestFriends(login.url,login.user,login.password,displayFriends); Service.requestFriends(login.url,login.user,login.password,displayFriends);

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
.pragma library .pragma library
.import QtQuick.LocalStorage 2.0 as Sql .import QtQuick.LocalStorage 2.0 as Sql
.import "qrc:/js/helper.js" as Helperjs .import "qrc:/js/helper.js" as Helperjs
@ -10,10 +41,14 @@ function requestFriends(login,database,rootwindow,callback){
Helperjs.friendicaRequest(login,"/api/statuses/friends", rootwindow,function (obj){ Helperjs.friendicaRequest(login,"/api/statuses/friends", rootwindow,function (obj){
var friends=JSON.parse(obj); var friends=JSON.parse(obj);
for (var i=0;i<friends.length;i++){ friends[i].isFriend=1} for (var i=0;i<friends.length;i++){ friends[i].isFriend=1}
callback(friends) //try{requestProfile(login,friends,rootwindow,function(friends_profile){callback(friends_profile)})}
//catch(e){
callback(friends)//}
}); });
} }
function requestGroups(login,database,rootwindow,callback){ function requestGroups(login,database,rootwindow,callback){
// retrieve, save and return groups. Other features currently not implemented // retrieve, save and return groups. Other features currently not implemented
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
@ -32,7 +67,7 @@ function requestGroups(login,database,rootwindow,callback){
function listFriends(login,database,callback){ function listFriends(login,database,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=1'); // check for friends var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'); // check for friends
var contactlist=[]; var contactlist=[];
for (var i=0;i<result.rows.length;i++){ for (var i=0;i<result.rows.length;i++){
contactlist.push(result.rows.item(i)) contactlist.push(result.rows.item(i))
@ -61,7 +96,7 @@ function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback)
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); // check for last news id var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); // check for last news id
try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})} try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})}
var newContacts=[]; var newContacts=[];
Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){//print("newsjs "+JSON.stringify(contacts)); Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){
var news=JSON.parse(obj); var news=JSON.parse(obj);
var newContacts=findNewContacts(news,contacts); var newContacts=findNewContacts(news,contacts);
callback(news,newContacts) callback(news,newContacts)
@ -166,8 +201,9 @@ function getDirectMessage(login,database,rootwindow,callback){
}); });
} }
}) })
if(login.newsViewType=="Timeline"){newsfromdb(database,login.username,callback)} callback()
else{chatsfromdb(database,login.username,callback)} // if(login.newsViewType=="Timeline"){newsfromdb(database,login.username,callback)}
// else{chatsfromdb(database,login.username,callback)}
} }
function getNotifications(login,database,rootwindow,callback){ function getNotifications(login,database,rootwindow,callback){
@ -195,12 +231,14 @@ function getNotifications(login,database,rootwindow,callback){
}) })
})} })}
function getActivitiesUserData(database,username,userUrlArray){//print(JSON.stringify(userUrlArray)); function getActivitiesUserData(database,username,allcontacts,userUrlArray){//print(JSON.stringify(userUrlArray));
var helpArray=[]; var helpArray=[];
for (var i=0;i<userUrlArray.length;i++){ for (var i=0;i<userUrlArray.length;i++){
Helperjs.readData(database,"contacts",username,function(userdata){ helpArray.push(objFromArray(allcontacts,"url",userUrlArray[i]));
helpArray.push(userdata[0]); // Helperjs.readData(database,"contacts",username,function(userdata){
},"url",userUrlArray[i]); // helpArray.push(userdata[0]);
// },"url",userUrlArray[i]);
} }
return helpArray return helpArray
} }
@ -213,42 +251,47 @@ function newsfromdb(database,username,callback,contact,stop_time){
try{var rs = tx.executeSql('select created_at from news WHERE username="'+username+'" ORDER BY created_at DESC LIMIT 1'); try{var rs = tx.executeSql('select created_at from news WHERE username="'+username+'" ORDER BY created_at DESC LIMIT 1');
stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}} stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
else{var stop="<"+stop_time} else{var stop="<"+stop_time}
var contactfilter="";if(contact){contactfilter=" AND uid='"+contact+"'"} var contactfilter="";if(contact){contactfilter=" AND (uid='"+contact+"' OR friendica_owner='"+contact+"')"}
//print('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20'); //print('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
var newsrs=tx.executeSql('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20'); var newsrs=tx.executeSql('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
var newsArray=[]; var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",username,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; i++) { for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i)); newsArray.push(newsrs.rows.item(i));
newsArray[i]=fetchUsersForNews(database,username,newsArray[i]) newsArray[i]=fetchUsersForNews(database,username,newsArray[i],allcontacts)
} }
callback(newsArray)}); callback(newsArray)});
} }
function fetchUsersForNews(database,username,news){//print(JSON.stringify(news)) function fetchUsersForNews(database,username,news,allcontacts){//print(JSON.stringify(news))
Helperjs.readData(database,"contacts",username,function(userdata){ news.user=objFromArray(allcontacts,"id",news.uid);
news.user=userdata[0]; if(news.in_reply_to_user_id){news.reply_user=objFromArray(allcontacts,"id",news.in_reply_to_user_id)}
//print("Fetch user"+JSON.stringify(news.user)); news.friendica_owner_object=objFromArray(allcontacts,"url",news.friendica_owner);
},"id",news.uid); // Helperjs.readData(database,"contacts",username,function(userdata){
if(news.in_reply_to_user_id){ // news.user=userdata[0];
Helperjs.readData(database,"contacts",username,function(replytodata){ // //print("Fetch user"+JSON.stringify(news.user));
news.reply_user=replytodata[0]; // },"id",news.uid);
//print("Fetch reply to"+JSON.stringify(news.reply_user)); // if(news.in_reply_to_user_id){
},"id",news.in_reply_to_user_id); // Helperjs.readData(database,"contacts",username,function(replytodata){
} // news.reply_user=replytodata[0];
// //print("Fetch reply to"+JSON.stringify(news.reply_user));
// },"id",news.in_reply_to_user_id);
// }
if (news.messagetype==0){ if (news.messagetype==0){
for(var j=0;j<news.friendica_activities.length;j++) for(var j=0;j<news.friendica_activities.length;j++)
{var friendicaArray=JSON.parse(Qt.atob(news.friendica_activities)); {var friendicaArray=JSON.parse(Qt.atob(news.friendica_activities));
// print("Array: "+friendicaArray[1]); // print("Array: "+friendicaArray[1]);
news.like=getActivitiesUserData(database,username,friendicaArray[0]); news.like=getActivitiesUserData(database,username,allcontacts,friendicaArray[0]);
news.dislike=getActivitiesUserData(database,username,friendicaArray[1]); news.dislike=getActivitiesUserData(database,username,allcontacts,friendicaArray[1]);
news.attendyes=getActivitiesUserData(database,username,friendicaArray[2]); news.attendyes=getActivitiesUserData(database,username,allcontacts,friendicaArray[2]);
news.attendno=getActivitiesUserData(database,username,friendicaArray[3]); news.attendno=getActivitiesUserData(database,username,allcontacts,friendicaArray[3]);
news.attendmaybe=getActivitiesUserData(database,username,friendicaArray[4]); news.attendmaybe=getActivitiesUserData(database,username,allcontacts,friendicaArray[4]);
} }
Helperjs.readData(database,"contacts",username,function(friendica_owner_data){ // Helperjs.readData(database,"contacts",username,function(friendica_owner_data){
news.friendica_owner_object=friendica_owner_data[0]; // news.friendica_owner_object=friendica_owner_data[0];
//print("Fetch friendica_owner"+JSON.stringify(news.friendica_owner)); // //print("Fetch friendica_owner"+JSON.stringify(news.friendica_owner));
},"url",news.friendica_owner); // },"url",news.friendica_owner);
} }
return news return news
} }
@ -266,11 +309,13 @@ function deleteNews(login,database,newsid,messagetype,rootwindow,callback){
})} })}
function retweetNews(login,database,newsid,rootwindow,callback){ function retweetNews(login,database,newsid,rootwindow,callback){
Helperjs.friendicaPostRequest(login,"/api/statuses/retweet?id="+newsid,"","POST", rootwindow,function (obj){ Helperjs.friendicaPostRequest(login,"/api/statuses/retweet?id="+newsid,"","POST", rootwindow,function (obj){
var answer=JSON.parse(obj); var answer=JSON.parse(obj);
if(answer.status.error){Helperjs.showMessage("Repost",answer.status.code,rootwindow);} if(answer.hasOwnProperty('status'))//('error' in answer.status)
else{Helperjs.showMessage("Repost",obj,rootwindow)} {Helperjs.showMessage("Repost",answer.status.code,rootwindow);}
})} else{Helperjs.showMessage("Repost",answer.text,rootwindow)}
})
}
function favorite(login,favorite,newsid,rootwindow){ function favorite(login,favorite,newsid,rootwindow){
// toggle favorites // toggle favorites
@ -299,7 +344,7 @@ function likerequest(login,database,verb,newsid,rootwindow){
//print(JSON.stringify(currentActivities)); //print(JSON.stringify(currentActivities));
var result = tx.executeSql('UPDATE news SET friendica_activities_self ="'+JSON.stringify(currentActivities)+'" where username="'+login.username+'" AND status_id ='+newsid); var result = tx.executeSql('UPDATE news SET friendica_activities_self ="'+JSON.stringify(currentActivities)+'" where username="'+login.username+'" AND status_id ='+newsid);
})} })}
else{print("likerequest"+obj)}}) else{}})
} }
function like(login,database,toggle,verb,newsid,rootwindow){ function like(login,database,toggle,verb,newsid,rootwindow){
@ -351,13 +396,16 @@ function requestConversation(login,database,newsid,contacts,rootwindow,callback)
function conversationfromdb(database,user,conversationId,callback){ function conversationfromdb(database,user,conversationId,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversationId+'" ORDER BY created_at ASC'); var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversationId+'" ORDER BY created_at ASC');
var newsArray=[]; var newsArray=[];
for(var i = 0; i < newsrs.rows.length; i++) { var allcontacts=[];
newsArray.push(newsrs.rows.item(i)); Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
newsArray[i]=fetchUsersForNews(database,user,newsArray[i]) for(var i = 0; i < newsrs.rows.length; i++) {
} newsArray.push(newsrs.rows.item(i));
callback(newsArray);} )} newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts)
}
callback(newsArray)})
}
function requestFavorites(login,database,contacts,rootwindow,callback){ function requestFavorites(login,database,contacts,rootwindow,callback){
Helperjs.friendicaRequest(login,"/api/favorites",rootwindow, function (obj){ Helperjs.friendicaRequest(login,"/api/favorites",rootwindow, function (obj){
@ -374,9 +422,11 @@ function favoritesfromdb(database,user,callback){
//print('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC'); //print('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC'); var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsArray=[]; var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; i++) { for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i)); newsArray.push(newsrs.rows.item(i));
newsArray[i]=fetchUsersForNews(database,user,newsArray[i]); newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts);
callback(newsArray); callback(newsArray);
}})} }})}
@ -393,11 +443,13 @@ function chatsfromdb(database,user,callback,stop_time){
conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id); conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id);
} }
var newsArray=[]; var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
for(var j = 0; j< conversations.length; j++) { for(var j = 0; j< conversations.length; j++) {
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversations[j] +'" ORDER BY created_at ASC'); var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversations[j] +'" ORDER BY created_at ASC');
var helpernews=newsrs.rows.item(0); var helpernews=newsrs.rows.item(0);
helpernews.newscount=newsrs.rows.length; helpernews.newscount=newsrs.rows.length;
helpernews=fetchUsersForNews(database,user,helpernews); helpernews=fetchUsersForNews(database,user,helpernews,allcontacts);
//var chatArray=[]; //var chatArray=[];
// for (var k=0;k<newsrs.rows.length;k++){ // for (var k=0;k<newsrs.rows.length;k++){
// var helperchat=newsrs.rows.item(k); // var helperchat=newsrs.rows.item(k);
@ -419,7 +471,16 @@ function inArray(list, prop, val) {
} return false; } return false;
} }
function cleanDate(date){ function objFromArray(list, prop, val) {
var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25); if (list.length > 0 ) {
return cleanedDate for (var i in list) {if (list[i][prop] == val) {
return list[i];
}
}
} return false;
}
function cleanDate(date){
var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25);
return cleanedDate
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
WorkerScript.onMessage = function(msg) { WorkerScript.onMessage = function(msg) {
if(msg.deleteId!==undefined) if(msg.deleteId!==undefined)
{msg.model.remove(msg.deleteId); {msg.model.remove(msg.deleteId);

View File

@ -1,5 +1,37 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
WorkerScript.onMessage = function(msg) { WorkerScript.onMessage = function(msg) {
if (msg.firstalbum==0){msg.model.clear();} if (msg.firstalbum==0){msg.model.clear();}
var contact={}; try{contact=msg.friend}catch(e){print(e)}
var limit=0; if (msg.albums.length-msg.firstalbum<20){limit=msg.albums.length} else{limit=msg.firstalbum+20} var limit=0; if (msg.albums.length-msg.firstalbum<20){limit=msg.albums.length} else{limit=msg.firstalbum+20}
for (var j=msg.firstalbum;j<limit;j++){ for (var j=msg.firstalbum;j<limit;j++){
if (msg.albums[msg.firstalbum]) { if (msg.albums[msg.firstalbum]) {
@ -8,7 +40,7 @@ WorkerScript.onMessage = function(msg) {
var albumname=msg.albums[j].name.trim();var albumlink=msg.albums[j].link var albumname=msg.albums[j].name.trim();var albumlink=msg.albums[j].link
}else{ }else{
var albumname=msg.albums[j].toString();var albumlink=""} var albumname=msg.albums[j].toString();var albumlink=""}
msg.model.append({"albumlink":albumlink,"foreignPicture":msg.foreignPicture,"albumname":albumname}); msg.model.append({"albumlink":albumlink,"foreignPicture":msg.foreignPicture,"albumname":albumname,"friend":contact});
msg.model.sync() msg.model.sync()
}; };
} }

View File

@ -1,150 +1,39 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//.pragma library //.pragma library
.import QtQuick.LocalStorage 2.0 as Sql .import QtQuick.LocalStorage 2.0 as Sql
.import "qrc:/js/helper.js" as Helperjs .import "qrc:/js/helper.js" as Helperjs
.import "qrc:/js/news.js" as Newsjs .import "qrc:/js/news.js" as Newsjs
// IMAGE FUNCTIONS
function requestList(login,database,rootwindow,callback) {
//get list of own images and call download function
Helperjs.friendicaRequest(login,"/api/friendica/photos/list", rootwindow,function (helperobject){
//print("return"+helperobject);
var obj=JSON.parse(helperobject);
Helperjs.readField("id",database,"imageData",login.username,function(AllStoredImages){
if (AllStoredImages.length>0){
for(var i=0;i< AllStoredImages.length;i++){
var position=Helperjs.inArray(obj,"resourceID",AllStoredImages[i]);
if (position>-1){obj.splice(position,1)}
//obj.splice(obj.indexOf(AllStoredImages[i]),1);// list of objects instead of list!!!
}}
callback(obj)
})
})}
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+"/"]);
}
})}}
catch (e){print("Data retrieval failure! "+ e+obj);}
})}
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) {
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){
//print(photohtml);
var photoarray=[];
var arr = photohtml.split("sidebar-photos-albums-li");
for (var i=2;i<arr.length;i++){
var albumlink = arr[i].substring(arr[i].indexOf('http'),arr[i].indexOf('class')-2);
var albumname=arr[i].substring(arr[i].indexOf('/span')+6,arr[i].indexOf('</a>')-1);
var album={'link':albumlink,'name':albumname}
photoarray.push(album);
}
callback(photoarray)
})
}
function requestFriendsPictures(link,rootwindow,callback){
// screenscraping of pictures page for given album
Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){
var photoarray=[];
var basehtml=photohtml.substring(photohtml.indexOf('<base')+12,photohtml.indexOf('/>',photohtml.indexOf('<base'))-2);
// old theme
if (photohtml.indexOf("photo-album-image-wrapper-end")>-1){ //theme 1
var arr = photohtml.split("photo-album-image-wrapper-end");}
// other themes
if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2
var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end"))
var arr = photoarea.split("</a>");}
for (var i=0;i<arr.length-1;i++){
var photoname=arr[i].substring(arr[i].lastIndexOf('alt')+5,arr[i].lastIndexOf('title')-2);
var thumblink=arr[i].substring(arr[i].lastIndexOf('<img')+10,arr[i].lastIndexOf('alt')-2);
var imagetype=thumblink.substring(thumblink.lastIndexOf("."));
var photolink=thumblink.substring(0,thumblink.length-imagetype.length-2)+"-0"+imagetype
if(thumblink.substring(0,4)!=="http"){thumblink=basehtml+thumblink}
if(photolink.substring(0,4)!=="http"){photolink=basehtml+photolink}
var photo={'link':photolink,'name':photoname,'thumb':thumblink}
photoarray.push(photo);
}
callback(photoarray)
})
}
// CONFIG FUNCTIONS // CONFIG FUNCTIONS
function initDatabase(database) { // initialize the database object function initDatabase(database) { // initialize the database object
@ -153,9 +42,10 @@ function initDatabase(database) { // initialize the database object
db.transaction( function(tx) { db.transaction( function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(username TEXT,id INT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, profile INT, link TEXT,location TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(username TEXT,id INT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, profile INT, link TEXT,location TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT, imagestore TEXT, maxnews INT, timerInterval INT, newsViewType TEXT,isActive INT, permissions TEXT,maxContactAge INT,APIVersion TEXT,layout TEXT, addons TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT, imagestore TEXT, maxnews INT, timerInterval INT, newsViewType TEXT,isActive INT, permissions TEXT,maxContactAge INT,APIVersion TEXT,layout TEXT, addons TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner INT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT, timestamp INT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT, timestamp INT)');
tx.executeSql('CREATE INDEX IF NOT EXISTS contact_id ON contacts(id)'); // tx.executeSql('CREATE INDEX IF NOT EXISTS contact_id ON contacts(id)');
tx.executeSql('CREATE TABLE IF NOT EXISTS profiles(username TEXT, id INT, profiledata TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS events(username TEXT, id INT, start INT, end INT, allday INT, title TEXT, j INT, d TEXT, isFirst INT, uid INT, cid INT, uri TEXT, created INT, edited INT, desc TEXT, location TEXT, type TEXT, nofinish TEXT, adjust INT, ignore INT, permissions TEXT, guid INT, itemid INT, plink TEXT, authorName TEXT, authorAvatar TEXT, authorLink TEXT, html TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS events(username TEXT, id INT, start INT, end INT, allday INT, title TEXT, j INT, d TEXT, isFirst INT, uid INT, cid INT, uri TEXT, created INT, edited INT, desc TEXT, location TEXT, type TEXT, nofinish TEXT, adjust INT, ignore INT, permissions TEXT, guid INT, itemid INT, plink TEXT, authorName TEXT, authorAvatar TEXT, authorLink TEXT, html TEXT)');
})} })}
@ -169,6 +59,7 @@ return (newpermArray)
function getEvents(database,login,rootwindow,callback){ function getEvents(database,login,rootwindow,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
Helperjs.friendicaWebRequest(login.server+"/cal/"+login.username+"/json",rootwindow,function(obj){ Helperjs.friendicaWebRequest(login.server+"/cal/"+login.username+"/json",rootwindow,function(obj){
//Helperjs.friendicaRemoteAuthRequest(login,login.server+"/cal/"+login.username+"/json",login.server+"/profile/"+login.username,rootwindow,function(obj){
var events = JSON.parse(obj); var events = JSON.parse(obj);
db.transaction( function(tx) { db.transaction( function(tx) {
for (var i=0;i<events.length;i++){ for (var i=0;i<events.length;i++){
@ -244,6 +135,48 @@ function requestFriendsEvents(login,friend,rootwindow,callback){
}) })
} }
function newRequestFriendsEvents(login,friend,rootwindow,callback){
// get calendar JSON object of contact with remoteAuth or without user and password
if(friend.isFriend==1){
Helperjs.friendicaRemoteAuthRequest(login,friend.url.replace("profile","cal")+"/json",friend.url,rootwindow,function(calhtml){
getEventsFromHtml(calhtml,rootwindow,callback)})
}
else{
Helperjs.friendicaWebRequest(friend.url.replace("profile","cal")+"/json",rootwindow,function(calhtml){
getEventsFromHtml(calhtml,rootwindow,callback)})
}
}
function getEventsFromHtml(calhtml,rootwindow,callback){
var eventarray=[];var eventdays=[];
var events=JSON.parse(calhtml);
for (var i=0;i<events.length;i++){
var permissions=[];
permissions.push(cleanPermissions(events[i].item.allow_cid));
permissions.push(cleanPermissions(events[i].item.allow_gid));
permissions.push(cleanPermissions(events[i].item.deny_cid));
permissions.push(cleanPermissions(events[i].item.deny_gid));
var event ={}
event.start=Date.parse(events[i].start);event.end=Date.parse(events[i].end);
event.allday=events[i].allday; event.title=events[i].title; event.j=events[i].j;
event.d=events[i].d; event.isFirst=events[i].isFirst; event.uid=events[i].item.uid;
event.cid=events[i].item.cid; event.uri=events[i].item.uri;
event.created=Date.parse(events[i].item.created); event.edited=Date.parse(events[i].item.edited);
event.desc=events[i].item.desc; event.location=events[i].item.location; event.type=events[i].item.type;
event.nofinish=events[i].item.nofinish; event.adjust =events[i].item.adjust; event.ignore=events[i].item.ignore;
event.permissions=JSON.stringify(permissions); event.guid=events[i].item.guid;
event.itemid=events[i].item.itemid; event.plink=events[i].plink; event.authorName=events[i].item["author-name"];
event.authorAvatar=events[i].item["author-avatar"]; event. authorLink=events[i].item["author-link"];
event.html=Qt.btoa(events[i].html);
eventarray.push(event);
// var offsetTime = new Date().getTimezoneOffset() * 60 * 1000;print(new Date(event.start).toLocaleString()+"Zeitverschiebung:"+offsetTime)
// var time = event.start - offsetTime;
eventdays.push(Math.floor(event.start/(24*60*60*1000)))
}
//print(JSON.stringify(eventarray));
callback(eventarray,eventdays)
}
function savePermissions(database,obj) { // stores config to DB function savePermissions(database,obj) { // stores config to DB
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
@ -280,6 +213,36 @@ Helperjs.friendicaWebRequest(url+"/api/statusnet/config",rootwindow, function (o
callback(serverConfigString) callback(serverConfigString)
})} })}
function checkLogin(login,rootwindow,callback){
// check server with given credentials
try {Helperjs.friendicaRequest(login,"/api/account/verify_credentials",rootwindow, function (obj){
var account = JSON.parse(obj);
callback(account)
})}
catch(e){}
}
function requestProfile(login,database,rootwindow,callback){
// return profile data
Helperjs.friendicaRequest(login,"/api/friendica/profile/show", rootwindow,function (obj){
var profiledata=JSON.parse(obj);
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
for (var i=0;i<profiledata.profiles.length;i++){
//print('store profile data for '+JSON.stringify(profiledata.profiles[i]));
db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from profiles where username="'+login.username+'" AND id = '+profiledata.profiles[i].profile_id); // check for profile id
if(result.rows.length === 1) {// use update
result = tx.executeSql('UPDATE profiles SET profiledata="'+ Qt.btoa(JSON.stringify(profiledata.profiles[i]))+'" WHERE username="'+login.username+'" AND id='+parseInt(profiledata.profiles[i].profile_id));
} else {// use insert
result = tx.executeSql('INSERT INTO profiles (username,id,profiledata) VALUES (?,?,?)', [login.username,profiledata.profiles[i].profile_id,Qt.btoa(JSON.stringify(profiledata.profiles[i]))])}
});
}
var profile=profiledata.friendica_owner;
profile.isFriend=2;
var profilearray=[];profilearray.push(profile);
callback(profilearray)
});
}
function getServerConfig(database,login,rootwindow,callback){ function getServerConfig(database,login,rootwindow,callback){
// check server with given credentials // check server with given credentials
@ -295,14 +258,15 @@ try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, functio
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('UPDATE config SET APIVersion="'+ serverconfig.site.friendica.FRIENDICA_VERSION+'" WHERE username="'+login.username +'"')}) var result = tx.executeSql('UPDATE config SET APIVersion="'+ serverconfig.site.friendica.FRIENDICA_VERSION+'" WHERE username="'+login.username +'"')})
Helperjs.friendicaRequest(login,"/friendica/json",rootwindow, function (obj){ // Helperjs.friendicaRequest(login,"/friendica/json",rootwindow, function (obj){
var serverData = JSON.parse(obj);var serverAddons=JSON.stringify(serverData.plugins).replace(/"/g,""); // var serverData = JSON.parse(obj);var serverAddons=JSON.stringify(serverData.plugins).replace(/"/g,"");
db.transaction( function(tx) { // db.transaction( function(tx) {
var result = tx.executeSql('UPDATE config SET addons="'+ serverAddons+'" WHERE username="'+login.username +'"')}) // var result = tx.executeSql('UPDATE config SET addons="'+ serverAddons+'" WHERE username="'+login.username +'"')})
callback(serverconfigString); // })
})})} callback(serverconfigString);
catch (e){callback (e); })}
catch (e){callback (e);
}} }}
function readConfig(database,callback,filter,filtervalue) { // reads config function readConfig(database,callback,filter,filtervalue) { // reads config
@ -334,8 +298,13 @@ function deleteConfig(database,userobj,callback) { // delete user data from DB
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
if(!db) { return; } if(!db) { return; }
db.transaction( function(tx) { db.transaction( function(tx) {
var rs = tx.executeSql('delete from config'+where); var rs1 = tx.executeSql('delete from config'+where);
callback(rs); var rs2 = tx.executeSql("delete from news WHERE username='"+ userobj.username+"'");
var rs3 = tx.executeSql("delete from contacts WHERE username='"+ userobj.username+"'");
var rs4 = tx.executeSql("delete from imageData WHERE username='"+ userobj.username+"'");
var rs5 = tx.executeSql("delete from groups WHERE username='"+ userobj.username+"'");
var rs5 = tx.executeSql("delete from events WHERE username='"+ userobj.username+"'");
callback();
}) })
} }
@ -370,16 +339,22 @@ function cleanContacts(login,database,callback){
} }
function processNews(callback){ function processNews(callback){
// Newsjs.getCurrentContacts(login,db,function(contacts){
// contactlist=contacts});
if (contactLoadType=="news"){ if (contactLoadType=="news"){
if(root.news.length==0){} if(root.news.length==0){}
else{// show news else{// show news
Newsjs.storeNews(login,db,news,root,function(dbnews){ Newsjs.storeNews(login,db,news,root,function(dbnews){
root.newsSignal(dbnews); if(login.newsViewType=="Timeline"){
newstab.newstabstatus=login.newsViewType Newsjs.newsfromdb(db,login.username,function(dbnews){
})} root.newsSignal(dbnews);
newstab.newstabstatus=login.newsViewType})
}
else{
Newsjs.chatsfromdb(db,login.username,function(dbnews){
root.newsSignal(dbnews);
newstab.newstabstatus=login.newsViewType})
}
})
}
} }
else if (contactLoadType=="friends"){// show friends else if (contactLoadType=="friends"){// show friends
root.friendsSignal(login.username); root.friendsSignal(login.username);
@ -408,37 +383,18 @@ function processNews(callback){
} }
function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab
// var suffix=contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("."), contact.profile_image_url.length);
// var imagename=login.imagestore+"contacts/"+contact.screen_name.trim()+suffix;
var imagename="";
contacttimer.restart();
var currentTime=Date.now(); var currentTime=Date.now();
var image_timestamp=0; var image_timestamp=0;
if(contact.profile_image_url==""){root.currentContact=root.currentContact+1 }
else{//print(JSON.stringify(contact))
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var currentts=0;
var currenttsrs= tx.executeSql('SELECT timestamp FROM contacts WHERE username="'+login.username+'" AND url="'+contact.url+'"');
try{currentts=currenttsrs.rows.item(0).timestamp}catch(e){}
var imagename_helper=[]; var imagename_helper=[];
imagename_helper=contact.profile_image_url.split('?');//print("substring: "+JSON.stringify(imagename_helper)+imagename_helper[0].substring(imagename_helper[0].lastIndexOf("/")+1, imagename_helper[0].length)) imagename_helper=contact.profile_image_url.split('?');//print("substring: "+JSON.stringify(imagename_helper)+imagename_helper[0].substring(imagename_helper[0].lastIndexOf("/")+1, imagename_helper[0].length))
imagename=login.imagestore+"contacts/"+contact.screen_name+"-"+imagename_helper[0].substring(imagename_helper[0].lastIndexOf("/")+1, imagename_helper[0].length);
try {parseInt(image_timestamp=imagename_helper[1].substring(imagename_helper[1].indexOf("ts=")+3,imagename_helper[1].length))} catch(e){}; try {parseInt(image_timestamp=imagename_helper[1].substring(imagename_helper[1].indexOf("ts=")+3,imagename_helper[1].length))} catch(e){};
//print(contact.screen_name+" Timestamp"+image_timestamp+" "+ new Date(parseInt(image_timestamp)*1000));
if ((image_timestamp>currentts) || (image_timestamp==0)){
xhr.setUrl(Qt.resolvedUrl(contact.profile_image_url));
xhr.setFilename(imagename);
xhr.setDownloadtype("contact");
xhr.download();
}
var result; var result;
result = tx.executeSql('SELECT * from contacts where username="'+login.username+'" AND url = "'+contact.url+'"'); // check for news url 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 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+', timestamp='+ image_timestamp+' 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)+'", 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='+ currentTime+' where username="'+login.username+'" AND url="'+contact.url+'"');
} else {// use insert } 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,image_timestamp]);} 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),"",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]);}
}); });
}} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
var core=[ var core=[
{name:'&lt;3',url: {name:'&lt;3',url:

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4

View File

@ -1,7 +1,39 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 2.1 import QtQuick.Controls 2.3
import QtQml 2.2 import QtQml 2.2
import Qt.labs.calendar 1.0 import Qt.labs.calendar 1.0
import QtQuick.Controls 1.2 as Oldcontrol
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
@ -26,8 +58,8 @@ Rectangle {
eventdays=dayArray}) eventdays=dayArray})
} }
else if (friend!=""){ else if (friend!=""){
calendartab.calendartabstatus=friend.substring(friend.lastIndexOf("/")+1,friend.length) calendartab.calendartabstatus=friend.url.substring(friend.url.lastIndexOf("/")+1,friend.url.length)
Service.requestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){ Service.newRequestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){
events=eventArray; events=eventArray;
eventdays=dayArray}) eventdays=dayArray})
} }
@ -71,18 +103,19 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin:2*mm anchors.rightMargin:2*mm
text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus
Oldcontrol.Menu {
id:calendartabmenu
Oldcontrol.MenuItem {
text: qsTr("Own Calendar")
onTriggered: {
calendartab.calendartabstatus="Events";
// calendartabstatusButton.text=qsTr("own Calendar");
showEvents("")}
}
}
onClicked: {calendartabmenu.popup()} onClicked: {calendartabmenu.popup()}
} }
Menu {
id:calendartabmenu
MenuItem {
text: qsTr("Own Calendar")
onTriggered: {
calendartab.calendartabstatus="Events";
// calendartabstatusButton.text=qsTr("own Calendar");
showEvents("")}
}
}
ListView{ ListView{
id: calendarView id: calendarView

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
@ -39,8 +70,7 @@ Rectangle{
} }
Component.onCompleted:{ Component.onCompleted:{
//print(JSON.stringify(daylist)) for (var i=0; i<daylist.length;i++){
for (var i=0; i<daylist.length;i++){//print(JSON.stringify(events[daylist[i]]));
var liststate="";if(daylist.length<2){liststate="large"} var liststate="";if(daylist.length<2){liststate="large"}
eventModel.append({"event":events[daylist[i]],"eventstatus":liststate}); eventModel.append({"event":events[daylist[i]],"eventstatus":liststate});
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
@ -23,11 +54,15 @@ StackView{
width:parent.width width:parent.width
height:Math.max(90*mm,root.height-12*mm) height:Math.max(90*mm,root.height-12*mm)
property var users:[] property var users:[]
property bool registeredUser: true
property var userdata: ({})
function setServericon(server){ function setServericon(server){
try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){ try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){
var serverdata = JSON.parse(obj); var serverdata = JSON.parse(obj);
servericon.source=serverdata.site.logo})} catch(e){print(e)} servericon.source=serverdata.site.logo})} catch(e){print(e)}
} }
BlueButton{ BlueButton{
id:userButton id:userButton
text:qsTr("User") text:qsTr("User")
@ -39,6 +74,7 @@ StackView{
useritems=useritems+"MenuItem{text:'"+configBackground.users[i].username+ useritems=useritems+"MenuItem{text:'"+configBackground.users[i].username+
"'; onTriggered: {Service.readConfig(db,function(obj){ "'; onTriggered: {Service.readConfig(db,function(obj){
configBackground.registeredUser=true;
userButton.text=obj.username; userButton.text=obj.username;
servername.text=obj.server; servername.text=obj.server;
configBackground.setServericon(obj.server); configBackground.setServericon(obj.server);
@ -60,7 +96,7 @@ StackView{
x: 4*mm; y: 10*mm x: 4*mm; y: 10*mm
} }
Text { Text {
text: qsTr("User") text: qsTr("Nickname")
x: 4*mm; y: 20*mm x: 4*mm; y: 20*mm
} }
@ -125,25 +161,35 @@ StackView{
} }
} }
Rectangle{ Rectangle{
color: "light grey" color: "light grey"
x: 25*mm; y: 20*mm; width: root.width/2; height: 5*mm; x: 25*mm; y: 20*mm; width: root.width/2; height: 5*mm;
TextInput { TextInput {
id: username id: username
anchors.fill: parent anchors.fill: parent
selectByMouse: true selectByMouse: true
onEditingFinished:{
Helperjs.friendicaWebRequest(servername.text+'/api/users/show?screen_name='+username.text,configBackground,function(obj){
var screennametest=JSON.parse(obj);
if (screennametest.status.error){
Helperjs.showMessage(qsTr("Error"),qsTr("Nickname not registered at given server!"),configBackground);
configBackground.registeredUser=false;
}else{configBackground.registeredUser=true}
});
}
}
} }
}
Rectangle{ Rectangle{
color: "light grey" color: "light grey"
x: 25*mm; y: 30*mm; width: root.width/2; height: 5*mm; x: 25*mm; y: 30*mm; width: root.width/2; height: 5*mm;
TextInput { TextInput {
id: password id: password
anchors.fill: parent anchors.fill: parent
selectByMouse: true selectByMouse: true
echoMode: TextInput.PasswordEchoOnEdit echoMode: TextInput.PasswordEchoOnEdit
}
} }
}
Rectangle{color: "light grey"; x: 25*mm; y: 40*mm; width: root.width/2-9*mm; height: 5*mm;} Rectangle{color: "light grey"; x: 25*mm; y: 40*mm; width: root.width/2-9*mm; height: 5*mm;}
Flickable { Flickable {
@ -232,34 +278,41 @@ StackView{
var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text,interval: messageIntervalField.text, newsViewType:newsTypeField.text}; var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text,interval: messageIntervalField.text, newsViewType:newsTypeField.text};
var errormessage=""; var errormessage="";
if (servername.text==""){errormessage=qsTr("No server given! ")} if (servername.text==""){errormessage=qsTr("No server given! ")}
else if (username.text==""){errormessage+=qsTr("No username given! ")} else if (username.text==""){errormessage+=qsTr("No nickname given! ")}
else if ((configBackground.registeredUser==false)){errormessage+=qsTr("Nickname not registered at given server! ")}
else if (password.text=="") {errormessage+=qsTr("No password given! ")} else if (password.text=="") {errormessage+=qsTr("No password given! ")}
else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")} else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")} else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")}
else {errormessage=""} else {errormessage=""}
if (errormessage=="") { if (errormessage=="") {
filesystem.Directory=userconfig.imagestore; Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){
filesystem.makeDir("contacts"); var credentials=JSON.parse(obj);
filesystem.makeDir("albums"); if (credentials.hasOwnProperty('status')){
Service.storeConfig(db,userconfig); Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
Service.readConfig(db,function(userconfig){ }
Service.getServerConfig(db,userconfig,root, function(obj){ else{
var serverString=obj; filesystem.Directory=userconfig.imagestore;
var serverconfigObject=Qt.createQmlObject(serverString,configBackground,"serverconfigOutput"); filesystem.makeDir("contacts");
Helperjs.readData(db,"config","",function(storedUsers){ filesystem.makeDir("albums");
storedUsers.sort(function(obj1, obj2) { Service.storeConfig(db,userconfig);
return obj1.isActive - obj2.isActive; Service.readConfig(db,function(userconfig){
}); Helperjs.readData(db,"config","",function(storedUsers){
configBackground.users=storedUsers}); storedUsers.sort(function(obj1, obj2) {
userButton.color="black" return obj1.isActive - obj2.isActive;
//reset values });
root.login=userconfig; configBackground.users=storedUsers});
newstab.newstabstatus=userconfig.newsViewType; userButton.color="black"
root.currentIndex=0; //reset values
newstab.active=true; root.login=userconfig;
})},"isActive",0); root.news=[];
},"isActive",0);
Service.requestProfile(userconfig,db,root,function(nc){root.newContacts=nc})
Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.name+"\nScreen Name: "+credentials.screen_name,root)
}
});
} }
else {Helperjs.show("Error", errormessage,root)} else {Helperjs.showMessage(qsTr("Error"), errormessage,root)}
}} }}
BlueButton { BlueButton {
@ -272,6 +325,7 @@ StackView{
filesystem.rmDir(); filesystem.rmDir();
filesystem.Directory=imagestore.text+"albums"; filesystem.Directory=imagestore.text+"albums";
filesystem.rmDir(); filesystem.rmDir();
configBackground.registeredUser=true;
servername.text="https://..."; servername.text="https://...";
servericon.source=""; servericon.source="";
username.text=""; username.text="";
@ -293,6 +347,7 @@ StackView{
x: root.width/2+8*mm; y: mm; width: 5*mm; height: 5*mm; x: root.width/2+8*mm; y: mm; width: 5*mm; height: 5*mm;
text: "+" text: "+"
onClicked:{ onClicked:{
configBackground.registeredUser=true;
servername.text="https://..." servername.text="https://..."
servericon.source=""; servericon.source="";
username.text="" username.text=""

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
@ -12,9 +43,9 @@ Rectangle{
textFormat: Text.RichText textFormat: Text.RichText
width: parent.width width: parent.width
wrapMode: Text.WrapAtWordBoundaryOrAnywhere wrapMode: Text.WrapAtWordBoundaryOrAnywhere
text: "<b>Friendiqa v0.1.2 </b><br>Licensed under GPL 3 with the exception of OpenSSL <br> "+ text: "<b>Friendiqa v0.2 </b><br>Licensed under GPL 3 with the exception of OpenSSL <br> "+
"Profile <a href='https://freunde.ma-nic.de/profile/friendiqa'>https://freunde.ma-nic.de/profile/friendiqa</a><br>"+ "Profile <a href='https://freunde.ma-nic.de/profile/friendiqa'>https://freunde.ma-nic.de/profile/friendiqa</a><br>"+
"Sourcecode: <a href='https://github.com/LubuWest/Friendiqa'>https://github.com/LubuWest/Friendica</a><br>"+ "Sourcecode: <a href='https://github.com/LubuWest/Friendiqa'>https://github.com/LubuWest/Friendiqa</a><br>"+
"C++ code by <a href='https://kirgroup.com/profile/fabrixxm'>Fabio</a><br>"+ "C++ code by <a href='https://kirgroup.com/profile/fabrixxm'>Fabio</a><br>"+
"QML and Javascript code by <a href='https://freunde.ma-nic.de/profile/marco'>Marco</a><br>"+ "QML and Javascript code by <a href='https://freunde.ma-nic.de/profile/marco'>Marco</a><br>"+
"Qt Framework <a href='https://www.qt.io'>www.qt.io</a><br>"+ "Qt Framework <a href='https://www.qt.io'>www.qt.io</a><br>"+

View File

@ -1,8 +1,40 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick.Window 2.0 import QtQuick.Window 2.0
import QtQuick 2.0 import QtQuick 2.0
QtObject{ QtObject{
property int appWidth: Screen.desktopAvailableWidth property int appWidth: Screen.desktopAvailableWidth
property int appHeight: Screen.desktopAvailableHeight property int appHeight: Screen.desktopAvailableHeight
property int backKey: Qt.Key_Back property int backKey: Qt.Key_Back
property string attachImageDir:filesystem.cameraPath+"/" //property string attachImageDir:filesystem.cameraPath+"/"
property string imagePickQml: "ImagePicker"
} }

View File

@ -1,7 +1,39 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
QtObject{ QtObject{
property real appWidth: 500 property real appWidth: 500
property real appHeight: 500 property real appHeight: 500
property int backKey: Qt.Key_Escape property int backKey: Qt.Key_Escape
property string attachImageDir:filesystem.homePath+"/Pictures/" //property string attachImageDir:filesystem.homePath+"/Pictures/"
property string imagePickQml: "ImagePickerLinux"
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
@ -19,7 +50,7 @@ Rectangle {
y:1 y:1
width: 10*mm width: 10*mm
height:10*mm height:10*mm
source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url source:((contact.profile_image!="") && (typeof(contact.profile_image)=="string"))? "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"}}
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
@ -8,7 +39,7 @@ x:mm
y:mm y:mm
property var contact:{} property var contact:{}
property var createdAtDate: new Date(contact.created_at) property var createdAtDate: new Date(contact.created_at)
property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend==1)?"":( "<a href='"+contact.url.replace("profile","dfrn_request") +"'>"+qsTr("Connect")+"</a><br>") property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend!=0)?"":( "<a href='"+contact.url.replace("profile","dfrn_request") +"'>"+qsTr("Connect")+"</a><br>")
Rectangle { Rectangle {
id: wrapper id: wrapper
@ -50,7 +81,7 @@ Rectangle{
frameVisible: true frameVisible: true
id:namelabelflickable id:namelabelflickable
width: root.width-10*mm width: root.width-10*mm
height:root.height-50*mm//friendsTabView.height-45*mm height:root.height-50*mm
x: mm x: mm
clip:true clip:true
Text{ Text{
@ -82,7 +113,7 @@ Rectangle{
fotostab.phototabstatus="Contact"; fotostab.phototabstatus="Contact";
root.currentIndex=2; root.currentIndex=2;
fotostab.active=true; fotostab.active=true;
root.fotoSignal(contact) ; root.fotoSignal(root.login,contact) ;
contactLargeComponent.destroy(); contactLargeComponent.destroy();
} }
} }
@ -93,7 +124,7 @@ Rectangle{
onClicked:{ onClicked:{
root.currentIndex=0; root.currentIndex=0;
newstab.active=true; newstab.active=true;
root.messageSignal(contact.id) ; root.messageSignal(contact) ;
contactLargeComponent.destroy(); contactLargeComponent.destroy();
} }
} }
@ -119,7 +150,7 @@ Rectangle{
root.currentIndex=3; root.currentIndex=3;
calendartab.active=true; calendartab.active=true;
calendartab.calendartabstatus="Friend" calendartab.calendartabstatus="Friend"
root.eventSignal(contact.url); root.eventSignal(contact);
contactLargeComponent.destroy(); contactLargeComponent.destroy();
} }
} }

View File

@ -1,91 +0,0 @@
import QtQuick 2.0
import QtQuick.Controls 1.3
import "qrc:/qml/genericqml"
Rectangle{
id: detailsrectangle
anchors.top: namelabel.bottom
anchors.topMargin: 2*mm
ScrollView{
horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff
frameVisible: true
id:namelabelflickable
width: root.width-10*mm
height:friendsTabView.height-45*mm
x: mm
clip:true
Text{
id:namelabeltext
width: namelabelflickable.width
height: implicitHeight
font.pixelSize: 3*mm
textFormat:Text.RichText
wrapMode: Text.Wrap
text:"<b>"+qsTr("Description")+": </b> "+Qt.atob(contact.description)+"<br> <b>"+qsTr("Location")+":</b> "+contact.location+"<br> <b>"+qsTr("Posts")+":</b> "+contact.statuses_count+
"<br> <b>"+qsTr("URL")+":</b> <a href='"+ contact.url+"'>"+contact.url+"</a><br>"+
connectUrl+ "<b>"+qsTr("Created at")+":</b> "+createdAtDate.toLocaleString(Qt.locale())
onLinkActivated: {
Qt.openUrlExternally(link)}
}
}
Row{
anchors.top: namelabelflickable.bottom
anchors.topMargin: 2*mm
x: mm
spacing:4
BlueButton{
id:photobutton
text: "\uf03e" // "Photos"
visible:(contact.network=="dfrn")
onClicked:{
fotostab.phototabstatus="Contact";
root.currentIndex=2;
fotostab.active=true;
root.fotoSignal(contact) ;
}
}
BlueButton{
id:messagebutton
text: "\uf0e6" //"Messages"
onClicked:{
root.currentIndex=0;
newstab.active=true;
root.messageSignal(contact.id) ;
}
}
BlueButton{
id:dmbutton
visible: (contact.following=="true")
text: "\uf040" //"DM"
onClicked:{
root.currentIndex=0;
newstab.active=true;
root.directmessageSignal(contact.screen_name);
}
}
BlueButton{
id:eventbutton
visible:(contact.network=="dfrn")
text:"\uf073"
onClicked:{
root.currentIndex=3;
calendartab.active=true;
calendartab.calendartabstatus="Friend"
root.eventSignal(contact.url);
}
}
BlueButton{
id: closeButton
text: "\uf057" //"close"
onClicked:{detailsrectangle.destroy();contactComponent.state="";friendsTabView.contactSignal}
}
}
}

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// List of people // List of people
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs

View File

@ -1,6 +1,38 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import QtQuick.LocalStorage 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/news.js" as Newsjs import "qrc:/js/news.js" as Newsjs
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
@ -14,15 +46,28 @@ Rectangle {
function showContactdetails(contact){ function showContactdetails(contact){
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml"); var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if(contact.isFriend){ if(contact.isFriend){
friendsTabView.currentIndex=0; friendsTabView.currentIndex=1;
var contactDetails = component.createObject(friendstab,{"contact": contact}) var contactDetails = component.createObject(friendstab,{"contact": contact})
} }
else{friendsTabView.currentIndex=1; else{friendsTabView.currentIndex=2;
var contactDetails = component.createObject(friendstab,{"contact": contact}) var contactDetails = component.createObject(friendstab,{"contact": contact})
} }
} }
function showProfile(callback){
var profile=({});
Helperjs.readData(db,"profiles",login.username,function(profileobject){
var profilearray=[];
for (var i in profileobject){
profilearray.push(JSON.parse(Qt.atob(profileobject[i].profiledata)));
}
profile.profiles=profilearray;
});
Helperjs.readData(db,"contacts",login.username,function(owner){
profile.friendica_owner=owner[0];
},"isFriend",2);
callback(profile)
}
TabView{ TabView{
id:friendsTabView id:friendsTabView
@ -31,23 +76,23 @@ Rectangle {
y:mm y:mm
width: root.width-2*mm width: root.width-2*mm
height: root.height-10*mm height: root.height-10*mm
currentIndex: 0 currentIndex: 1
signal contactsSignal(var contact) signal contactsSignal(var contact)
signal groupsSignal(var username) signal groupsSignal(var username)
onCurrentIndexChanged:{ onCurrentIndexChanged:{
if (currentIndex==0){ if (currentIndex==1){
contactsSignal("") contactsSignal("")
} }
else if (currentIndex==1){ else if (currentIndex==2){
contactsSignal("") contactsSignal("")
} }
else if (currentIndex==2){groupsSignal(root.login.username)} else if (currentIndex==3){groupsSignal(root.login.username)}
} }
style: TabViewStyle { style: TabViewStyle {
frameOverlap: 1 frameOverlap: 1
tab: Rectangle { tab: Rectangle {
color: "white" color: "white"
implicitWidth: root.width/3-2*mm implicitWidth: root.width/4-2*mm
implicitHeight: 4*mm implicitHeight: 4*mm
Text { id: text Text { id: text
anchors.centerIn: parent anchors.centerIn: parent
@ -61,24 +106,43 @@ Rectangle {
tabsAlignment:Qt.AlignHCenter tabsAlignment:Qt.AlignHCenter
} }
Tab{
id:profileGridTab
title: qsTr("Me")
Component.onCompleted:{
showProfile(function(profile){
var component = Qt.createComponent("qrc:/qml/contactqml/ProfileComponent.qml");
var profilecomp = component.createObject(profileGridTab,{"profile": profile});
});
}
}
Tab{ Tab{
title: qsTr("Friends") title: qsTr("Friends")
Rectangle{ Rectangle{
id: friendsGridTab id: friendsGridTab
property int currentContact:0
function showFriends(contact){ function showFriends(contact){
try {friendsModel.clear()} catch(e){print(e)}; try {friendsModel.clear()} catch(e){print(e)};
Helperjs.readData(db,"contacts",login.username,function(friendsobject){ Helperjs.readData(root.db,"contacts",login.username,function(friendsobject){
for (var i=0;i<friendsobject.length;i++){ for (var i=0;i<friendsobject.length;i++){
if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){ if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid
} }
friendsModel.append({"contact":friendsobject[i]}); friendsModel.append({"contact":friendsobject[i]});
} }
},"isFriend",1,"screen_name ASC"); },"isFriend",1,"screen_name ASC");
} }
Connections{
target:xhr
onDownloaded:{
if(type=="contactlist"){
//print(url+" "+filename+" "+i)
currentContact=i+1;
if(currentContact==root.newContacts.length){showFriends(root.login.username)}
}
}
}
BlueButton { BlueButton {
id: updateFriendsButton id: updateFriendsButton
text: "\uf021" text: "\uf021"
@ -101,8 +165,8 @@ Rectangle {
anchors.top: parent.top anchors.top: parent.top
anchors.right:updateFriendsButton.left anchors.right:updateFriendsButton.left
anchors.rightMargin:mm anchors.rightMargin:mm
visible: (root.currentContact!=root.newContacts.length)?true:false visible: (currentContact!=(root.newContacts.length))?true:false
value: root.currentContact/root.newContacts.length value: currentContact/root.newContacts.length
} }
GridView { GridView {
@ -126,7 +190,8 @@ Rectangle {
Component.onCompleted: { Component.onCompleted: {
root.friendsSignal.connect(showFriends); root.friendsSignal.connect(showFriends);
friendsTabView.contactsSignal.connect(showFriends); friendsTabView.contactsSignal.connect(showFriends);
showFriends(root.login.username) showFriends(root.login.username);
root.newContacts=[]
} }
} }
} }
@ -210,17 +275,6 @@ Rectangle {
xhr.setParam("user", group.user); xhr.setParam("user", group.user);
xhr.setParam("json",group); xhr.setParam("json",group);
xhr.post(); xhr.post();
// Helperjs.friendicaPostRequest(login,api,groupdata,"POST",rootwindow, function (obj){print("groupcreate "+obj);
// var groups=JSON.parse(obj);
// db.transaction( function(tx) {
// var result = tx.executeSql('DELETE from groups where username="'+login.username+'"'); // clean old groups
// for (var i=0;i<groups.length;i++){
// var memberarray=[]; for (var user in groups[i].user){memberarray.push(parseInt(groups[i].user[user].cid))}
// //print("Members: "+groups[i].user)
// var result2 = tx.executeSql('INSERT INTO groups VALUES (?,?,?,?)', [login.username,groups[i].name,groups[i].gid,JSON.stringify(memberarray)])}
// callback()
// });
// })
} }
Connections{ Connections{

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/news.js" as Newsjs import "qrc:/js/news.js" as Newsjs

View File

@ -0,0 +1,277 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0
import QtQuick.Controls 1.3
import "qrc:/qml/genericqml"
import "qrc:/js/service.js" as Service
Rectangle {
width:root.width-2*mm
height:root.height-14*mm
color:"white"
property var profile:({})
property var attachImageURLs:[]
property var createdAtDate: new Date(profile.friendica_owner.created_at)
function updateProfileImage(){
xhr.url= login.server + "/api/account/update_profile_image.json";
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.clearParams();
xhr.setImageFileParam("image", photoImage.source );
xhr.post();
}
function buildProfiletext(pobject,callback){
var profileobject={};
var profiletext="";
for (var key in pobject){//print(key+obj[key])
if(pobject[key]!=""&&key!="users"&&key!="profile_id"){
var keytext="";
switch(key){
case "profile_name":keytext=qsTr("profile name");break;
case "is_default":keytext=qsTr("is default");break;
case "hide_friends":keytext=qsTr("hide friends");break;
case "profile_photo":keytext=qsTr("profile photo");break;
case "profile_thumb":keytext=qsTr("profile thumb");break;
case "publish":keytext=qsTr("publish");break;
case "net_publish":keytext=qsTr("publish in network");break;
case "description":keytext=qsTr("description");break;
case "date_of_birth":keytext=qsTr("date of birth");break;
case "address":keytext=qsTr("address");break;
case "city":keytext=qsTr("city");break;
case "region":keytext=qsTr("region");break;
case "postal_code":keytext=qsTr("postal code");break;
case "country":keytext=qsTr("country");break;
case "hometown":keytext=qsTr("hometown");break;
case "gender":keytext=qsTr("gender");break;
case "marital":keytext=qsTr("marital status");break;
case "marital_with":keytext=qsTr("married with");break;
case "marital_since":keytext=qsTr("married since");break;
case "sexual":keytext=qsTr("sexual");break;
case "politic":keytext=qsTr("politics");break;
case "religion":keytext=qsTr("religion");break;
case "public_keywords":keytext=qsTr("public keywords");break;
case "private_keywords":keytext=qsTr("private keywords");break;
case "likes":keytext=qsTr("likes");break;
case "dislikes":keytext=qsTr("dislikes");break;
case "about":keytext=qsTr("about");break;
case "music":keytext=qsTr("music");break;
case "book":keytext=qsTr("book");break;
case "tv":keytext=qsTr("tv");break;
case "film":keytext=qsTr("film");break;
case "interest":keytext=qsTr("interest");break;
case "romance":keytext=qsTr("romance");break;
case "work":keytext=qsTr("work");break;
case "education":keytext=qsTr("education");break;
case "social_networks":keytext=qsTr("social networks");break;
case "homepage":keytext=qsTr("homepage");break;
default:keytext=key;
}
profiletext=profiletext+("<b>"+keytext+": </b> "+(pobject[key])+"<br>");
}
}
callback(profiletext)
}
BlueButton {
id: update
anchors.top: parent.top
anchors.topMargin: mm
anchors.right: parent.right
text: "\uf021"
onClicked: {
Service.requestProfile(root.login,root.db,root,function(nc){
root.newContacts=nc;
photoImage.source="";
showProfile(function(newprofile){
profile=newprofile;
try {profileModel.clear()} catch(e){print(e)};
newprofile.profiles.sort(function(obj1, obj2) {
return obj1.profile_id - obj2.profile_id;
})
for(var i in newprofile.profiles){var obj=newprofile.profiles[i];
buildProfiletext(obj,function(profiletext){
profileModel.append({"profileid":obj.profile_id,"profiletext":profiletext})
})
}
photoImage.source="file://"+newprofile.friendica_owner.profile_image;
});
});
}
}
Image {
id: photoImage
x:mm
y:mm
width: 15*mm
height:15*mm
source: "file://"+profile.friendica_owner.profile_image
onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}
MouseArea{
anchors.fill: parent
onClicked:{
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple: false;onReady: {photoImage.source=imageUrl;'+
'}}',profileGridTab,"imagePicker");
imagePicker.pickImage()
}
}
}
Rectangle{
id:phototextRectangle
color:"black"
z:3
opacity: 0.5
width:6*mm
height: phototext.contentHeight
anchors.top: photoImage.top
anchors.right: photoImage.right
}
Text {
id:phototext
z:4
text: "\uf040"
width:5*mm
anchors.top: photoImage.top
anchors.right:photoImage.right
color: "white"
font.pixelSize: 4*mm
}
BlueButton{
id:updatebutton
height: 5*mm
visible: "file://"+profile.friendica_owner.profile_image!= photoImage.source
text:qsTr("Update")
anchors.left: photoImage.right
anchors.leftMargin: 0.5*mm
anchors.topMargin: mm
anchors.top: parent.top
onClicked:{updateProfileImage()}
}
Label {
id: namelabel
x: mm
width: root.width-6*mm
height: 3*mm
text:(Qt.atob(profile.friendica_owner.name))+" (@"+profile.friendica_owner.screen_name+")"
elide:Text.ElideRight
anchors.topMargin: 0
anchors.left: photoImage.left
wrapMode: Text.Wrap
color: "#303030"
font.pixelSize: 4*mm
anchors.top: photoImage.bottom
}
ListModel{id:profileModel}
Component{
id:profileItem
Rectangle{
id:profileRect
width:profileView.width
height: 5*mm+profiletextfield.height
Text{
y:mm
font.pixelSize: 3*mm
text:"<b>"+qsTr("profile id")+": </b> "+profileid+"<br>"
color:"black"
}
Text{
id:profiletextfield
x:2*mm
y:3.5*mm
width:parent.width-2.5*mm
wrapMode: Text.Wrap
font.pixelSize: 3*mm
text:profiletext
color:"black"
}
}
}
Component{
id:textcomponent
Text{
id:namelabeltext
width: namelabelflickable.width
height: implicitHeight
font.pixelSize: 3*mm
textFormat:Text.RichText
wrapMode: Text.Wrap
text:"<b>"+qsTr("Description")+": </b> "+(profile.friendica_owner.description)+"<br> <b>"+qsTr("Location")+":</b> "+profile.friendica_owner.location+"<br> <b>"+qsTr("Posts")+":</b> "+profile.friendica_owner.statuses_count+
"<br> <b>"+qsTr("URL")+":</b> <a href='"+ profile.friendica_owner.url+"'>"+profile.friendica_owner.url+"</a><br>"+
"<b>"+qsTr("Created at")+":</b> "+createdAtDate.toLocaleString(Qt.locale())
onLinkActivated: {
Qt.openUrlExternally(link)}
}
}
Rectangle{
id: detailsrectangle
anchors.top: namelabel.bottom
anchors.topMargin: 2*mm
ScrollView{
horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff
frameVisible: true
id:namelabelflickable
width: root.width-10*mm
height:root.height-36*mm//friendsTabView.height-45*mm
x: mm
clip:true
ListView {
id: profileView
header:textcomponent
width:root.width-10*mm
height: root.height
clip: true
spacing: 0
model: profileModel
delegate: profileItem
}
}
}
Component.onCompleted: {
profile.profiles.sort(function(obj1, obj2) {
return obj1.profile_id - obj2.profile_id;
})
for(var i in profile.profiles){var obj=profile.profiles[i];
buildProfiletext(obj,function(profiletext){
profileModel.append({"profileid":obj.profile_id,"profiletext":profiletext})
})
}
}
}

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.LocalStorage 2.0 import QtQuick.LocalStorage 2.0
import QtQuick.Window 2.0 import QtQuick.Window 2.0
@ -14,12 +45,13 @@ TabView{
width: osSettings.appWidth width: osSettings.appWidth
height:osSettings.appHeight height:osSettings.appHeight
focus:true focus:true
property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000] property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000]
property var login: Service.readActiveConfig(db) property var login: Service.readActiveConfig(db)
property var contactlist: [] property var contactlist: []
property real mm: Screen.pixelDensity property real mm: Screen.pixelDensity
signal messageSignal(var friend) signal messageSignal(var friend)
signal fotoSignal(var friend) signal fotoSignal(var login, var friend)
signal directmessageSignal(var friend) signal directmessageSignal(var friend)
signal newsSignal(var news) signal newsSignal(var news)
signal friendsSignal(var username) signal friendsSignal(var username)
@ -28,7 +60,6 @@ TabView{
property var news:[] property var news:[]
property var newContacts:[] property var newContacts:[]
property int currentContact: 0
property string contactLoadType: "" property string contactLoadType: ""
onLoginChanged:{ onLoginChanged:{
@ -38,9 +69,26 @@ TabView{
Newsjs.getCurrentContacts(login,db,function(contacts){ Newsjs.getCurrentContacts(login,db,function(contacts){
contactlist=contacts})} contactlist=contacts})}
} }
onNewContactsChanged:{//print(JSON.stringify(newContacts)); onNewContactsChanged:{
if(newContacts.length>0){// download first contact image and update db if(newContacts.length>0){// download contact images and update db
Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])} var contacturls=[];
var contactnames=[];
for (var link in newContacts){
contacturls.push(newContacts[link].profile_image_url);
contactnames.push(newContacts[link].screen_name);
Service.updateContactInDB(login,db,newContacts[link].isFriend,newContacts[link])
contactlist.push(newContacts[link].url);
}
xhr.setDownloadtype("contactlist");
xhr.setFilelist(contacturls);
xhr.setContactlist(contactnames);
xhr.setImagedir(login.imagestore);
xhr.getlist();
Service.processNews(function(){
root.contactLoadType="";
root.news=[];
})
}
else if (contactLoadType!=""){ else if (contactLoadType!=""){
Service.processNews(function(){ Service.processNews(function(){
root.contactLoadType=""; root.contactLoadType="";
@ -48,46 +96,22 @@ TabView{
})} })}
} }
onCurrentContactChanged:{// download next contact image after successful download and update db
if(currentContact<newContacts.length){
Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])}
else if (contactLoadType!=""){
Service.processNews(function(){
root.contactLoadType="";
root.news=[];
root.newContacts=[];
root.currentContact=0;
})}
}
Connections{ Connections{
target:xhr target:xhr
onDownloaded:{if(data=="contact"){contacttimer.stop();root.currentContact=root.currentContact+1}} onDownloaded:{
if(type=="contactlist"){
//print("contact image saved"+Date.now()+" "+filename+" "+url);
var database=LocalStorage.openDatabaseSync(root.db[0],root.db[1],root.db[2],root.db[3]);
var result;
database.transaction( function(tx) {
result = tx.executeSql('UPDATE contacts SET profile_image="'+filename+'" where profile_image_url="'+url+'"');
})
}
}
} }
Connections{
target:xhr
onError:{print("Error"+data);
if (data=="contact"){
var database=LocalStorage.openDatabaseSync(root.db[0],root.db[1],root.db[2],root.db[3]);
var result;
database.transaction( function(tx) {
//print('UPDATE contacts SET profile_image="" where username="'+root.login.username+'" AND id = '+newContacts[currentContact].id);
result = tx.executeSql('UPDATE contacts SET profile_image="" where username="'+root.login.username+'" AND id = '+newContacts[currentContact].id);
root.currentContact=root.currentContact+1;contacttimer.stop()})}
}}
FontLoader{id: fontAwesome; source: "qrc:/images/fontawesome-webfont.ttf"} FontLoader{id: fontAwesome; source: "qrc:/images/fontawesome-webfont.ttf"}
Timer {id:contacttimer; interval: 5000; running: false; repeat: false
onTriggered: {
var database=LocalStorage.openDatabaseSync(root.db[0],root.db[1],root.db[2],root.db[3]);
database.transaction( function(tx) {
var result = tx.executeSql('UPDATE contacts SET profile_image="" where username="'+root.login.username+'" AND id = '+newContacts[currentContact].id);
root.currentContact=root.currentContact+1})}
}
Keys.onReleased: { Keys.onReleased: {
if (event.key === osSettings.backKey) { if (event.key === osSettings.backKey) {
if (currentIndex==0){ if (currentIndex==0){
@ -103,7 +127,10 @@ TabView{
})} })}
} }
else if (newstab.conversation.length>0){newstab.conversation=[]} else if (newstab.conversation.length>0){newstab.conversation=[]}
else{Service.cleanNews(root.db,function(){Qt.quit()})} else{Service.cleanNews(root.db,function(){
Service.cleanContacts(root.login,root.db,function(){
Qt.quit()})
})}
} }
else if (currentIndex==2){fotoSignal("backButton")} else if (currentIndex==2){fotoSignal("backButton")}
else {currentIndex=0} else {currentIndex=0}

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
Rectangle{ Rectangle{
id: blueButton id: blueButton

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import Qt.labs.folderlistmodel 2.1 import Qt.labs.folderlistmodel 2.1
@ -14,7 +45,11 @@ Rectangle{
x:2*mm x:2*mm
y:10*mm y:10*mm
property string directory: "" property string directory: ""
property bool multiSelection: false property bool multiple: false
property string imageUrl: ""
property var imageUrls: []
signal ready();
function pickImage() {}
Text{ Text{
id:directoryText id:directoryText
@ -32,7 +67,7 @@ Rectangle{
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 1*mm anchors.rightMargin: 1*mm
text: "\uf057" text: "\uf057"
onClicked:{imageDialog.destroy()} onClicked:{ready();imageDialog.destroy()}
} }
ListView { ListView {
@ -123,22 +158,25 @@ Rectangle{
directory=fileURL directory=fileURL
} }
else{ else{
if (multiSelection!=true){ if (multiple!=true){
attachImageURLs.push(fileURL); //attachImageURLs.push(fileURL);
attachImage(fileURL); //attachImage(fileURL);
imageUrls.push(fileURL);
imageUrl=fileURL;
ready();
imageDialog.destroy() imageDialog.destroy()
} }
else { else {
if(selected.visible==true){ if(selected.visible==true){
attachImageURLs.splice(attachImageURLs.indexOf(fileURL,1)) imageUrls.splice(imageUrls.indexOf(fileURL,1))
selected.visible=false selected.visible=false
} }
else{ else{
attachImageURLs.push(fileURL); imageUrls.push(fileURL);
selected.visible=true; selected.visible=true;
} }
attachImage(fileURL) imageUrl=fileURL
} }
} }
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// ConversationView with button // ConversationView with button
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
@ -104,7 +135,6 @@ Rectangle {
xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.status_id) xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.status_id)
} }
xhr.post(); xhr.post();
//replyText.text=""
} catch(e){Helperjs.showMessage("Error",e.toString(),root)} } catch(e){Helperjs.showMessage("Error",e.toString(),root)}
} }
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// List of people from Friendica Activities // List of people from Friendica Activities
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// message.qml // message.qml
// message with buttons // message with buttons
import QtQuick 2.0 import QtQuick 2.0
@ -123,15 +154,6 @@ Flickable{
} }
Row{ Row{
ImagePicker {
id: imagePicker;
multiple : false
onReady: {
attachImageURLs.push(imagePicker.imageUrl);
attachImage(imagePicker.imageUrl)
}
}
spacing:2 spacing:2
BlueButton{id:permButton BlueButton{id:permButton
visible: (directmessage==1)?false:true visible: (directmessage==1)?false:true
@ -149,9 +171,9 @@ Flickable{
Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn) Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn)
} }
else{ else{
//var defaultDirectory="file://"+osSettings.attachImageDir; var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
//var component = Qt.createComponent("qrc:/qml/genericqml/ImageDialog.qml"); osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+
//var imagedialog = component.createObject(messageSend,{"directory": defaultDirectory}); 'attachImage(imageUrl)}}',messageSend,"imagePicker");
imagePicker.pickImage() imagePicker.pickImage()
} }
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
@ -13,21 +44,21 @@ Item {
} }
} }
Connections{ // Connections{
target:root // target:root
onCurrentContactChanged:{ // onCurrentContactChanged:{
if (root.newContacts.length>0){ // if (root.newContacts.length>0){
if(root.currentContact<root.newContacts.length){ // if(root.currentContact<root.newContacts.length){
downloadNotice.text= qsTr("Download profile image for ")+ root.newContacts[root.currentContact].name; // downloadNotice.text= qsTr("Download profile image for ")+ root.newContacts[root.currentContact].name;
//print(root.newContacts[root.currentContact].name) // //print(root.newContacts[root.currentContact].name)
} // }
}else{downloadNotice.text=""} // }else{downloadNotice.text=""}
} // }
} // }
Connections{ Connections{
target:xhr target:xhr
onError:{if (data=="contact"){downloadNotice.text=root.newContacts[root.currentContact].name+"... Error!"}} // onError:{if (data=="contact"){downloadNotice.text=root.newContacts[root.currentContact].name+"... Error!"}}
onSuccess:{replytimer.start() //wait 1 second to load new timeline onSuccess:{replytimer.start() //wait 1 second to load new timeline
} }
} }
@ -40,7 +71,7 @@ Item {
var onlynew=true; var onlynew=true;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){ Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){
root.contactLoadType="news"; root.contactLoadType="news";
root.news=rns;root.newContacts=rnc;root.currentContact=0}) root.news=rns;root.newContacts=rnc;})
} }
} }
} }
@ -61,10 +92,10 @@ Item {
newsStack.conversationIndex= conversationIndex; newsStack.conversationIndex= conversationIndex;
if(newsitemobject.messagetype==0){ if(newsitemobject.messagetype==0){
Newsjs.requestConversation(root.login,db,newsitemobject.status_id,root.contactlist,root,function(ns,nc){ Newsjs.requestConversation(root.login,db,newsitemobject.status_id,root.contactlist,root,function(ns,nc){
root.news=ns;root.newContacts=nc;root.currentContact=0; root.news=ns;root.newContacts=nc;
})} })}
else{Newsjs.conversationfromdb(root.db,root.login.username,newsitemobject.statusnet_conversation_id, function(newsarray){ else{Newsjs.conversationfromdb(root.db,root.login.username,newsitemobject.statusnet_conversation_id, function(newsarray){
root.news=newsarray;root.newContacts=[];root.currentContact=1; root.news=newsarray;root.newContacts=[];
})} })}
} }
@ -77,7 +108,14 @@ Item {
function onFriendsMessages(friend){ function onFriendsMessages(friend){
newstab.newstabstatus="Contact" newstab.newstabstatus="Contact"
Newsjs.newsfromdb(db,root.login.username, function(dbnews){showNews(dbnews)},friend) Newsjs.newsfromdb(db,root.login.username, function(dbnews){
if (dbnews.length==0){
Newsjs.newsfromdb(db,login.username,function(forumnews){
showNews(forumnews)
},friend.url)
}
else showNews(dbnews)
},friend.id)
} }
function onDirectMessage(friend){ function onDirectMessage(friend){
@ -127,7 +165,10 @@ Item {
BlueButton { BlueButton {
id: quitButton id: quitButton
text: "\uf08b" text: "\uf08b"
onClicked: {Service.cleanNews(root.db,function(){Qt.quit() })} onClicked: {Service.cleanNews(root.db,function(){
Service.cleanContacts(root.login,root.db,function(){
Qt.quit() })
})}
} }
BlueButton { BlueButton {
id: update id: update
@ -139,12 +180,12 @@ Item {
var onlynew=true; var onlynew=true;
//print("newstab "+ JSON.stringify(contactlist)); //print("newstab "+ JSON.stringify(contactlist));
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(ns,nc){ Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(ns,nc){
root.news=ns;root.newContacts=nc;root.currentContact=0; root.news=ns;root.newContacts=nc;
if (ns.length==0){// update last 20 existing news for changes and likes if (ns.length==0){// update last 20 existing news for changes and likes
onlynew=false; onlynew=false;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){ Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){
root.contactLoadType="news"; root.contactLoadType="news";
root.news=rns;root.newContacts=rnc;root.currentContact=0}) root.news=rns;root.newContacts=rnc;})
} }
}) })
} }
@ -205,12 +246,12 @@ Item {
root.contactLoadType="news"; root.contactLoadType="news";
var onlynew=true; var onlynew=true;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(ns,nc){ Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(ns,nc){
root.news=ns;root.newContacts=nc;root.currentContact=0; root.news=ns;root.newContacts=nc;
if (ns.length==0){// update last 20 existing news for changes and likes if (ns.length==0){// update last 20 existing news for changes and likes
onlynew=false; onlynew=false;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){ Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){
root.contactLoadType="news"; root.contactLoadType="news";
root.news=rns;root.newContacts=rnc;root.currentContact=0}) root.news=rns;root.newContacts=rnc;})
} }
}) })
}} }}
@ -272,7 +313,7 @@ Item {
root.contactLoadType="favorites"; root.contactLoadType="favorites";
newsBusy.running=true; newsBusy.running=true;
Newsjs.requestFavorites(root.login,db,root.contactlist,root,function(ns,nc){ Newsjs.requestFavorites(root.login,db,root.contactlist,root,function(ns,nc){
root.news=ns; root.newContacts=nc;root.currentContact=0; root.news=ns; root.newContacts=nc;
}) })
} }
} }
@ -300,10 +341,11 @@ Item {
root.directmessageSignal.connect(onDirectMessage); root.directmessageSignal.connect(onDirectMessage);
root.newsSignal.connect(showNews); root.newsSignal.connect(showNews);
try{newsModel.clear()} catch(e){} try{newsModel.clear()} catch(e){}
newstab.newstabstatus=login.newsViewType; if(root.news.length>0){showNews(root.news)}
else{ newstab.newstabstatus=login.newsViewType;
if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){showNews(dbnews)})} if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){showNews(dbnews)})}
else{Newsjs.chatsfromdb(db,login.username,function(dbnews){showNews(dbnews)})} else{Newsjs.chatsfromdb(db,login.username,function(dbnews){showNews(dbnews)})}
} }
} }}
} }
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
@ -35,7 +66,7 @@ Item {
Image { Image {
id:profileImage id:profileImage
source: (newsitemobject.user.profile_image!="")? "file://"+newsitemobject.user.profile_image : newsitemobject.user.profile_image_url source: ((newsitemobject.user.profile_image!="") && (typeof(newsitemobject.user.profile_image)=="string"))? "file://"+newsitemobject.user.profile_image : newsitemobject.user.profile_image_url
x:1 x:1
width: 7*mm width: 7*mm
height: 7*mm height: 7*mm
@ -295,11 +326,8 @@ Item {
anchors.fill:parent anchors.fill:parent
onClicked:{ onClicked:{
conversationsymbol.color="black"; conversationsymbol.color="black";
//Newsjs.conversationfromdb(db,login.username,newsitemobject.conversation_id,function(conversation){
var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); 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)
var conversationItem = component.createObject(friendicaActivities); showConversation(index,newsitemobject)
} }
} }
} }
@ -334,7 +362,6 @@ Item {
text: qsTr("Conversation") text: qsTr("Conversation")
onTriggered: { onTriggered: {
conversationsymbol.color="black"; conversationsymbol.color="black";
//Newsjs.conversationfromdb(db,login.username,newsitemobject.conversation_id,function(conversation){
var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml"); var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml");
var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray}); var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray});
showConversation(index,newsitemobject) showConversation(index,newsitemobject)

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
@ -6,7 +37,7 @@ import "qrc:/qml/genericqml"
Rectangle{ Rectangle{
id:imageDialog id:imageDialog
//property var attachImageURLs: [] property var attachImageURLs: []
property var contacts: [] property var contacts: []
property var groups: [] property var groups: []
property var contact_allow:login.permissions[0] property var contact_allow:login.permissions[0]
@ -21,15 +52,18 @@ Rectangle{
xhr.clearParams(); xhr.clearParams();
xhr.setParam("desc",imageUploadModel.get(inumber).description); xhr.setParam("desc",imageUploadModel.get(inumber).description);
xhr.setParam("album", album.currentText); 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_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 (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_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))};
if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; //if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))};
xhr.setImageFileParam("media", imageUploadModel.get(inumber).imageUrl ); xhr.setImageFileParam("media", imageUploadModel.get(inumber).imageUrl );
xhr.post(); xhr.post();
} }
function attachImage(url){
imageUploadModel.append({"imageUrl":url,"description":""})
}
z:2 z:2
border.color: "grey" border.color: "grey"
width: parent.width-4*mm width: parent.width-4*mm
@ -38,19 +72,6 @@ Rectangle{
y:10*mm y:10*mm
property string directory: "" 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{ Connections{
target:xhr target:xhr
onError:{print(data)}//if (data=="image"){Helperjs.showMessage()}} onError:{print(data)}//if (data=="image"){Helperjs.showMessage()}}
@ -172,11 +193,10 @@ Rectangle{
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
onClicked:{ onClicked:{
//var defaultDirectory="file://"+osSettings.attachImageDir; var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
//var component = Qt.createComponent("qrc:/qml/genericqml/ImageDialog.qml"); osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+
//var imagedialog = component.createObject(imageDialog,{"directory": defaultDirectory, "multiSelection": true}) 'attachImage(imageUrl)}}',imageDialog,"imagePicker");
// filesystem.search imagePicker.pickImage()
imagePicker.pickImage()
} }
} }
} }
@ -226,7 +246,6 @@ Rectangle{
Component.onCompleted:{ Component.onCompleted:{
albumModel.append({"text":""}); albumModel.append({"text":""});
try{Helperjs.readField("album",db,"imageData",login.username,function(storedAlbums){ try{Helperjs.readField("album",db,"imageData",login.username,function(storedAlbums){
//print(JSON.stringify(storedAlbums))
for (var n in storedAlbums){ for (var n in storedAlbums){
albumModel.append({"text":storedAlbums[n]})} albumModel.append({"text":storedAlbums[n]})}
})} })}

View File

@ -1,4 +1,35 @@
import QtQuick 2.0 // This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.7
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
Package { Package {
@ -20,12 +51,14 @@ Package {
BusyIndicator { anchors.centerIn: parent; running: realImage.status != Image.Ready } BusyIndicator { anchors.centerIn: parent; running: realImage.status != Image.Ready }
Image { Image {
id: realImage; id: realImage;
visible: (albumWrapper.state != '')||(index==0)
width: photoWrapper.width; height: photoWrapper.height width: photoWrapper.width; height: photoWrapper.height
antialiasing: true; antialiasing: true;
asynchronous: true asynchronous: true
autoTransform:true
cache: false cache: false
fillMode: Image.PreserveAspectFit; fillMode: Image.PreserveAspectFit;
source: imageLocation source: (albumWrapper.state == '')&&(index>0)?"":imageLocation
} }
Rectangle{ Rectangle{
id:phototextRectangle id:phototextRectangle

View File

@ -1,51 +1,95 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
//import QtQuick.Dialogs 1.2 import QtQuick.Controls 1.2
import QtQuick.Controls 1.4
import QtQml.Models 2.1 import QtQml.Models 2.1
import "qrc:/js/service.js" as Service import "qrc:/js/image.js" as Imagejs
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/photoqml" import "qrc:/qml/photoqml"
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
Rectangle { Rectangle {
id:fotorectangle id:fotorectangle
y:1 y:1
width:root.width-mm width:root.width-mm
height:root.height-5*mm height:root.height-5*mm
color: '#fff' color: '#fff'
property var newimages:[] property var newimages:[]
property int currentimageno: 0 property int currentimageno: 0
property bool remoteContact: false
onNewimagesChanged:{ onNewimagesChanged:{
if(newimages.length>0){ if(newimages.length>0){
//print("newimages "+JSON.stringify(newimages));
var ownimagelist=[];
Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){ Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){
for (var i=0;i<newimages.length;i++){ for (var i=0;i<newimages.length;i++){
if(albums.indexOf(newimages[i].album)==-1){ if(albums.indexOf(newimages[i].album)==-1){
filesystem.Directory=root.login.imagestore+"/albums"; filesystem.Directory=root.login.imagestore+"/albums";
filesystem.makeDir(newimages[i].album)}} filesystem.makeDir(newimages[i].album)}
ownimagelist.push(root.login.server+"/api/friendica/photo?scale='0'&photo_id="+newimages[i].id);
}
}) })
Service.dataRequest(root.login,newimages[currentimageno].id,root.db,fotostab); xhr.setLogin(login.username+":"+Qt.atob(login.password));
newImagesProgress.visible=true //download first image xhr.setImagedir(login.imagestore);
xhr.setFilelist(ownimagelist);
xhr.setDownloadtype("picturelist");
xhr.getlist();
newImagesProgress.visible=true
} }
} }
onCurrentimagenoChanged:{ onCurrentimagenoChanged:{
if(currentimageno<newimages.length){Service.dataRequest(root.login,newimages[currentimageno].id,root.db,fotostab)}; if(currentimageno==newimages.length){newImagesProgress.visible=false;showFotos(root.login,"");
if(currentimageno==newimages.length){newImagesProgress.visible=false;showFotos("");
newimages=[];currentimageno=0} newimages=[];currentimageno=0}
// download next image // download next image
} }
Connections{ Connections{
target:xhr target:xhr
onDownloaded:{if(data=="picture"){currentimageno=currentimageno+1}} onDownloadedjson:{
} if(type=="picturelist"){
currentimageno=currentimageno+1
Connections{ Imagejs.storeImagedata(login,db,jsonObject,fotorectangle)
target:xhr }
onError:{if(data=="picture"){print("Error"+data); }
currentimageno=currentimageno+1}} onDownloaded:{
if(type=="picture"){currentimageno=currentimageno+1}
}
onError:{if(data=="picturelist"){
var requestid=url.substring(url.lastIndexOf("=")+1);
Imagejs.dataRequest(login,requestid,db,xhr,fotorectangle)
} else {currentimageno=currentimageno+1}
}
} }
// Connections{ // Connections{
// target:filesystem // target:filesystem
@ -54,7 +98,7 @@ Rectangle {
// onSuccess:print("Success deleting"); // onSuccess:print("Success deleting");
// } // }
function showFotos(friend){ function showFotos(login,friend){
if(friend=="backButton"){ if(friend=="backButton"){
if(!albumgridview.currentItem){root.currentIndex=0} if(!albumgridview.currentItem){root.currentIndex=0}
if(albumgridview.currentItem.state=='fullscreen'){ if(albumgridview.currentItem.state=='fullscreen'){
@ -65,11 +109,12 @@ Rectangle {
else{ else{
try {photogroupModel.clear()}catch (e){print(e)} try {photogroupModel.clear()}catch (e){print(e)}
if (friend){ if (friend){
Service.requestFriendsAlbumPictures(login,friend,fotostab,function(albums){ Imagejs.newRequestFriendsAlbumPictures(login,friend,fotorectangle,function(albums,remoteAuthBool){
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture':true} remoteContact=remoteAuthBool;
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture':true,'friend':friend}
photoWorker.sendMessage(msg); photoWorker.sendMessage(msg);
}) })
phototabstatusButton.text=qsTr(friend.screen_name.toString())+qsTr("'s images") phototabstatusButton.text=friend.screen_name+qsTr("\'s images")
} }
else { else {
@ -79,11 +124,12 @@ Rectangle {
photoWorker.sendMessage(msg); photoWorker.sendMessage(msg);
} }
}) })
}} }
}
} }
function deletepics(type,url ,imageId){ function deletepics(type,url ,imageId){
Service.deleteImage(db,login,type, url,root,function(){//showFotos("") Imagejs.deleteImage(db,login,type, url,filesystem,root,function(){//showFotos("")
}) })
} }
@ -98,7 +144,6 @@ Rectangle {
value: currentimageno/newimages.length value: currentimageno/newimages.length
} }
//ImageUploadDialog{}
BlueButton{ BlueButton{
id: uploadPhoto id: uploadPhoto
anchors.top: parent.top anchors.top: parent.top
@ -118,9 +163,20 @@ Rectangle {
anchors.right:phototabstatusButton.left anchors.right:phototabstatusButton.left
anchors.rightMargin:mm anchors.rightMargin:mm
text:"\uf0ed" text:"\uf0ed"
onClicked: { Menu {
Service.requestList(root.login,root.db, fotostab,function(obj){newimages=obj}) id:photoupdatemenu
MenuItem {
text: qsTr("All Images")
onTriggered: {
Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){newimages=obj})}
}
MenuItem {
text: qsTr("Only new")
onTriggered: {
Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){newimages=obj})}
}
} }
onClicked: {photoupdatemenu.popup()}
} }
BlueButton{ BlueButton{
@ -130,18 +186,19 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin:2*mm anchors.rightMargin:2*mm
text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus
Menu {
id:phototabmenu
MenuItem {
text: qsTr("Own Images")
onTriggered: {
fotostab.phototabstatus="Images";
// phototabstatusButton.text=qsTr("Own images");
showFotos(root.login,"")}
}
}
onClicked: {phototabmenu.popup()} onClicked: {phototabmenu.popup()}
} }
Menu {
id:phototabmenu
MenuItem {
text: qsTr("Own Images")
onTriggered: {
fotostab.phototabstatus="Images";
// phototabstatusButton.text=qsTr("Own images");
showFotos("")}
}
}
DelegateModel{ DelegateModel{
id: visualphotoModel id: visualphotoModel
@ -172,13 +229,15 @@ Rectangle {
text:qsTr("More") text:qsTr("More")
} }
MouseArea{anchors.fill:parent MouseArea{anchors.fill:parent
onClicked:{ onClicked:{print(photogroupModel.get(0).foreignPicture);
var lastalbum_id=photogroupModel.get(photogroupModel.count-1); var lastalbum_id=photogroupModel.count-1;
if(photogroupModel.get(photogroupModel.count-1).foreignPictures==false){ if(photogroupModel.get(photogroupModel.count-1).foreignPicture==true){
Service.requestFriendsAlbumPictures(friend,fotostab,function(albums){ Imagejs.newRequestFriendsAlbumPictures(login,photogroupModel.get(0).friend,fotorectangle,function(albums,remoteAuthBool){
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':lastalbum_id+1,'foreignPicture':true} remoteContact=remoteAuthBool;
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':lastalbum_id+1,'foreignPicture':true,'friend':photogroupModel.get(0).friend}
photoWorker.sendMessage(msg) photoWorker.sendMessage(msg)
})} })
}
else{Helperjs.readField("album",root.db, "imageData",root.login.username,function(albums){ else{Helperjs.readField("album",root.db, "imageData",root.login.username,function(albums){
var msg = { 'model': photogroupModel,'albums':albums,'foreignPicture': false,'firstalbum':lastalbum_id+1}; var msg = { 'model': photogroupModel,'albums':albums,'foreignPicture': false,'firstalbum':lastalbum_id+1};
photoWorker.sendMessage(msg)})} photoWorker.sendMessage(msg)})}
@ -202,6 +261,6 @@ Rectangle {
WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"} WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"}
Component.onCompleted: { root.fotoSignal.connect(showFotos); Component.onCompleted: { root.fotoSignal.connect(showFotos);
if (fotostab.phototabstatus=="Images"){showFotos("")} if (fotostab.phototabstatus=="Images"){showFotos(root.login,"")}
} }
} }

View File

@ -1,7 +1,39 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import QtQml.Models 2.1 import QtQml.Models 2.1
import "qrc:/js/service.js" as Service //import "qrc:/js/service.js" as Service
import "qrc:/js/image.js" as Imagejs
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
Package { Package {
@ -72,7 +104,7 @@ Package {
Component.onCompleted:{ Component.onCompleted:{
try {photoModel.clear()}catch (e){print(e)} try {photoModel.clear()}catch (e){print(e)}
if(foreignPicture){ if(foreignPicture){
Service.requestFriendsPictures(albumlink,fotostab,function(obj){ Imagejs.newRequestFriendsPictures(login,albumlink,friend,remoteContact,remoteauth,root,function(obj){
if (obj) { if (obj) {
for (var k=0;k<obj.length;k++){ for (var k=0;k<obj.length;k++){
photoModel.append({"imageLocation": obj[k].thumb,"photoDescription":obj[k].name,"photoLink":obj[k].link}) photoModel.append({"imageLocation": obj[k].thumb,"photoDescription":obj[k].name,"photoLink":obj[k].link})
@ -83,7 +115,7 @@ Package {
Helperjs.readData(db,"imageData",root.login.username,function(obj){ Helperjs.readData(db,"imageData",root.login.username,function(obj){
if (obj) { if (obj) {
for (var k=0;k<obj.length;k++){ for (var k=0;k<obj.length;k++){
if(obj[k].desc!=""&&obj[k].desc!="null"){var name=obj[k].desc}else{var name=obj[k].filename} if(typeof(obj[k].desc)=="string" && obj[k].desc!=""){var name=obj[k].desc}else{var name=obj[k].filename}
photoModel.append({"imageLocation": obj[k].location+obj[k].filename,"photoDescription":name,"photoLink":obj[k].location+obj[k].filename}) photoModel.append({"imageLocation": obj[k].location+obj[k].filename,"photoDescription":name,"photoLink":obj[k].location+obj[k].filename})
} }
} }

View File

@ -4,12 +4,12 @@
<context> <context>
<name>CalendarTab</name> <name>CalendarTab</name>
<message> <message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="73"/> <location filename="../qml/calendarqml/CalendarTab.qml" line="105"/>
<source>Events</source> <source>Events</source>
<translation>Termine</translation> <translation>Termine</translation>
</message> </message>
<message> <message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="79"/> <location filename="../qml/calendarqml/CalendarTab.qml" line="109"/>
<source>Own Calendar</source> <source>Own Calendar</source>
<translation>Eigener Kalender</translation> <translation>Eigener Kalender</translation>
</message> </message>
@ -17,80 +17,120 @@
<context> <context>
<name>ConfigTab</name> <name>ConfigTab</name>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="33"/> <location filename="../qml/configqml/ConfigTab.qml" line="78"/>
<location filename="../qml/configqml/ConfigTab.qml" line="63"/> <location filename="../qml/configqml/ConfigTab.qml" line="362"/>
<location filename="../qml/configqml/ConfigTab.qml" line="283"/> <location filename="../qml/configqml/ConfigTab.qml" line="384"/>
<location filename="../qml/configqml/ConfigTab.qml" line="304"/>
<source>User</source> <source>User</source>
<translation>Name</translation> <translation>Name</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="59"/> <location filename="../qml/configqml/ConfigTab.qml" line="105"/>
<source>Server</source> <source>Server</source>
<translation>Server</translation> <translation>Server</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="68"/> <location filename="../qml/configqml/ConfigTab.qml" line="109"/>
<source>Nickname</source>
<translation>Kurzname</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="114"/>
<source>Password</source> <source>Password</source>
<translation>Passwort</translation> <translation>Passwort</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="72"/> <location filename="../qml/configqml/ConfigTab.qml" line="118"/>
<source>Image dir.</source> <source>Image dir.</source>
<translation>Bildverz.</translation> <translation>Bildverz.</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="77"/> <location filename="../qml/configqml/ConfigTab.qml" line="123"/>
<source>Max. News</source> <source>Max. News</source>
<translation>Max. Nachr.</translation> <translation>Max. Nachr.</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="81"/> <location filename="../qml/configqml/ConfigTab.qml" line="127"/>
<source>News as</source> <source>News as</source>
<translation>Anzeige</translation> <translation>Anzeige</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="85"/> <location filename="../qml/configqml/ConfigTab.qml" line="131"/>
<source>Interval (0=None)</source> <source>Interval (0=None)</source>
<translation>Intervall (0=keins)</translation> <translation>Intervall (0=keins)</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="230"/> <location filename="../qml/configqml/ConfigTab.qml" line="201"/>
<location filename="../qml/configqml/ConfigTab.qml" line="316"/>
<location filename="../qml/configqml/ConfigTab.qml" line="340"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="201"/>
<source>Nickname not registered at given server!</source>
<translation>Name auf der Seite nicht registriert!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="301"/>
<source>Confirm</source> <source>Confirm</source>
<translation>Bestätigen</translation> <translation>Bestätigen</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="234"/> <location filename="../qml/configqml/ConfigTab.qml" line="305"/>
<source>No server given! </source> <source>No server given! </source>
<translation>Kein Server angegeben!</translation> <translation>Kein Server angegeben!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="235"/> <location filename="../qml/configqml/ConfigTab.qml" line="306"/>
<source>No username given! </source> <source>No nickname given! </source>
<translation>Kein Nutzername angegeben!</translation> <translation>Kein Kurzname angegeben!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="236"/> <location filename="../qml/configqml/ConfigTab.qml" line="307"/>
<source>Nickname not registered at given server! </source>
<translation>Name auf der Seite nicht registriert!</translation>
</message>
<message>
<source>No username given! </source>
<translation type="vanished">Kein Nutzername angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="308"/>
<source>No password given! </source> <source>No password given! </source>
<translation>Kein Passwort angegeben!</translation> <translation>Kein Passwort angegeben!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="237"/> <location filename="../qml/configqml/ConfigTab.qml" line="309"/>
<source>No image directory given!</source> <source>No image directory given!</source>
<translation>Kein Verzeichnis für Bilder angegeben!</translation> <translation>Kein Verzeichnis für Bilder angegeben!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="238"/> <location filename="../qml/configqml/ConfigTab.qml" line="310"/>
<source>No maximum news number given!</source> <source>No maximum news number given!</source>
<translation>Maximale News-Anzahl nicht angegeben!</translation> <translation>Maximale News-Anzahl nicht angegeben!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="319"/> <location filename="../qml/configqml/ConfigTab.qml" line="316"/>
<source>Wrong password!</source>
<translation>Falsches Passwort!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="335"/>
<source>Success</source>
<translation>Bestätigt</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="335"/>
<source>Name</source>
<translation>Name</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="399"/>
<source>Timeline</source> <source>Timeline</source>
<translation>Chronologisch</translation> <translation>Chronologisch</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="323"/> <location filename="../qml/configqml/ConfigTab.qml" line="403"/>
<source>Conversations</source> <source>Conversations</source>
<translation>Unterhaltungen</translation> <translation>Unterhaltungen</translation>
</message> </message>
@ -98,7 +138,7 @@
<context> <context>
<name>ContactComponent</name> <name>ContactComponent</name>
<message> <message>
<location filename="../qml/contactqml/ContactComponent.qml" line="8"/> <location filename="../qml/contactqml/ContactComponent.qml" line="39"/>
<source>Connect</source> <source>Connect</source>
<translation>Kontaktanfrage</translation> <translation>Kontaktanfrage</translation>
</message> </message>
@ -106,32 +146,32 @@
<context> <context>
<name>ContactDetailsComponent</name> <name>ContactDetailsComponent</name>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="11"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="42"/>
<source>Connect</source> <source>Connect</source>
<translation>Kontaktanfrage</translation> <translation>Kontaktanfrage</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Description</source> <source>Description</source>
<translation>Beschreibung</translation> <translation>Beschreibung</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Location</source> <source>Location</source>
<translation>Ort</translation> <translation>Ort</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Posts</source> <source>Posts</source>
<translation>Beiträge</translation> <translation>Beiträge</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="64"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="95"/>
<source>URL</source> <source>URL</source>
<translation>Profilseite</translation> <translation>Profilseite</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="65"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="96"/>
<source>Created at</source> <source>Created at</source>
<translation>Erstellt</translation> <translation>Erstellt</translation>
</message> </message>
@ -139,17 +179,22 @@
<context> <context>
<name>FriendsTab</name> <name>FriendsTab</name>
<message> <message>
<location filename="../qml/contactqml/FriendsTab.qml" line="65"/> <location filename="../qml/contactqml/FriendsTab.qml" line="111"/>
<source>Me</source>
<translation>Ich</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="121"/>
<source>Friends</source> <source>Friends</source>
<translation>Freunde</translation> <translation>Freunde</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/FriendsTab.qml" line="135"/> <location filename="../qml/contactqml/FriendsTab.qml" line="200"/>
<source>Contacts</source> <source>Contacts</source>
<translation>Kontakte</translation> <translation>Kontakte</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/FriendsTab.qml" line="188"/> <location filename="../qml/contactqml/FriendsTab.qml" line="253"/>
<source>Groups</source> <source>Groups</source>
<translation>Gruppen</translation> <translation>Gruppen</translation>
</message> </message>
@ -168,32 +213,32 @@
<context> <context>
<name>ImageUploadDialog</name> <name>ImageUploadDialog</name>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="96"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="127"/>
<source>Album</source> <source>Album</source>
<translation>Album</translation> <translation>Album</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="101"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="132"/>
<source>Image</source> <source>Image</source>
<translation>Bild</translation> <translation>Bild</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="106"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="137"/>
<source>Description</source> <source>Description</source>
<translation>Beschreibung</translation> <translation>Beschreibung</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="205"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="236"/>
<source>Upload</source> <source>Upload</source>
<translation>Hochladen</translation> <translation>Hochladen</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="208"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source>Error</source> <source>Error</source>
<translation>Fehler</translation> <translation>Fehler</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="208"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source> No album name given</source> <source> No album name given</source>
<translation>Kein Albumname angegeben</translation> <translation>Kein Albumname angegeben</translation>
</message> </message>
@ -201,17 +246,17 @@
<context> <context>
<name>MessageSend</name> <name>MessageSend</name>
<message> <message>
<location filename="../qml/newsqml/MessageSend.qml" line="67"/> <location filename="../qml/newsqml/MessageSend.qml" line="98"/>
<source>Title (optional)</source> <source>Title (optional)</source>
<translation>Überschrift (optional)</translation> <translation>Überschrift (optional)</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/MessageSend.qml" line="149"/> <location filename="../qml/newsqml/MessageSend.qml" line="180"/>
<source>Error</source> <source>Error</source>
<translation>Fehler</translation> <translation>Fehler</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/MessageSend.qml" line="149"/> <location filename="../qml/newsqml/MessageSend.qml" line="180"/>
<source>Only one attachment supported at the moment. <source>Only one attachment supported at the moment.
Remove other attachment first!</source> Remove other attachment first!</source>
<translation>Nur ein Anhang derzeit unterstützt. <translation>Nur ein Anhang derzeit unterstützt.
@ -221,32 +266,31 @@
<context> <context>
<name>NewsTab</name> <name>NewsTab</name>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="21"/>
<source>Download profile image for </source> <source>Download profile image for </source>
<translation>Lade Profilbild für </translation> <translation type="vanished">Lade Profilbild für </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="163"/> <location filename="../qml/newsqml/NewsTab.qml" line="204"/>
<source>More</source> <source>More</source>
<translation>Mehr</translation> <translation>Mehr</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="260"/> <location filename="../qml/newsqml/NewsTab.qml" line="301"/>
<source>Timeline</source> <source>Timeline</source>
<translation>Chronologisch</translation> <translation>Chronologisch</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="269"/> <location filename="../qml/newsqml/NewsTab.qml" line="310"/>
<source>Favorites</source> <source>Favorites</source>
<translation>Markierte News</translation> <translation>Markierte News</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="281"/> <location filename="../qml/newsqml/NewsTab.qml" line="322"/>
<source>Conversations</source> <source>Conversations</source>
<translation>Unterhaltungen</translation> <translation>Unterhaltungen</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="289"/> <location filename="../qml/newsqml/NewsTab.qml" line="330"/>
<source>Notifications</source> <source>Notifications</source>
<translation>Meldungen</translation> <translation>Meldungen</translation>
</message> </message>
@ -254,82 +298,82 @@
<context> <context>
<name>Newsitem</name> <name>Newsitem</name>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="16"/> <location filename="../qml/newsqml/Newsitem.qml" line="47"/>
<source>attending: </source> <source>attending: </source>
<translation>Teilnahme</translation> <translation>Teilnahme</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="68"/> <location filename="../qml/newsqml/Newsitem.qml" line="99"/>
<source>Source: </source> <source>Source: </source>
<translation>Quelle: </translation> <translation>Quelle: </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="69"/> <location filename="../qml/newsqml/Newsitem.qml" line="100"/>
<source>Direct Message</source> <source>Direct Message</source>
<translation>Direktnachricht</translation> <translation>Direktnachricht</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="84"/> <location filename="../qml/newsqml/Newsitem.qml" line="115"/>
<source>In reply to </source> <source>In reply to </source>
<translation>Antwort an </translation> <translation>Antwort an </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="96"/> <location filename="../qml/newsqml/Newsitem.qml" line="127"/>
<source> comments</source> <source> comments</source>
<translation> Kommentare</translation> <translation> Kommentare</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="190"/> <location filename="../qml/newsqml/Newsitem.qml" line="221"/>
<source>Attending: </source> <source>Attending: </source>
<translation>Teilnahme: </translation> <translation>Teilnahme: </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="312"/> <location filename="../qml/newsqml/Newsitem.qml" line="343"/>
<source>Reply</source> <source>Reply</source>
<translation>Antworten</translation> <translation>Antworten</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="320"/> <location filename="../qml/newsqml/Newsitem.qml" line="351"/>
<source>DM</source> <source>DM</source>
<translation>Direktnachricht</translation> <translation>Direktnachricht</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="326"/> <location filename="../qml/newsqml/Newsitem.qml" line="357"/>
<source>Repost</source> <source>Repost</source>
<translation>Teilen</translation> <translation>Teilen</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="329"/> <location filename="../qml/newsqml/Newsitem.qml" line="360"/>
<source>Success!</source> <source>Success!</source>
<translation>Erledigt!</translation> <translation>Erledigt!</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="334"/> <location filename="../qml/newsqml/Newsitem.qml" line="365"/>
<source>Conversation</source> <source>Conversation</source>
<translation>Unterhaltung</translation> <translation>Unterhaltung</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="345"/> <location filename="../qml/newsqml/Newsitem.qml" line="376"/>
<source>Attending</source> <source>Attending</source>
<translation>Teilnahme</translation> <translation>Teilnahme</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="347"/> <location filename="../qml/newsqml/Newsitem.qml" line="378"/>
<source>yes</source> <source>yes</source>
<translation>ja</translation> <translation>ja</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="352"/> <location filename="../qml/newsqml/Newsitem.qml" line="383"/>
<source>maybe</source> <source>maybe</source>
<translation>vielleicht</translation> <translation>vielleicht</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="357"/> <location filename="../qml/newsqml/Newsitem.qml" line="388"/>
<source>no</source> <source>no</source>
<translation>nein</translation> <translation>nein</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="364"/> <location filename="../qml/newsqml/Newsitem.qml" line="395"/>
<source>Delete</source> <source>Delete</source>
<translation>Löschen</translation> <translation>Löschen</translation>
</message> </message>
@ -337,12 +381,12 @@
<context> <context>
<name>PermissionDialog</name> <name>PermissionDialog</name>
<message> <message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="35"/> <location filename="../qml/genericqml/PermissionDialog.qml" line="66"/>
<source>Friends</source> <source>Friends</source>
<translation>Freunde</translation> <translation>Freunde</translation>
</message> </message>
<message> <message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="96"/> <location filename="../qml/genericqml/PermissionDialog.qml" line="127"/>
<source>Groups</source> <source>Groups</source>
<translation>Gruppen</translation> <translation>Gruppen</translation>
</message> </message>
@ -350,36 +394,269 @@
<context> <context>
<name>PhotoTab</name> <name>PhotoTab</name>
<message> <message>
<location filename="../qml/photoqml/PhotoTab.qml" line="72"/> <location filename="../qml/photoqml/PhotoTab.qml" line="115"/>
<source>&apos;s images</source> <source>&apos;s images</source>
<translation>s Bilder</translation> <translation>s Bilder</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/PhotoTab.qml" line="132"/> <location filename="../qml/photoqml/PhotoTab.qml" line="167"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="138"/> <source>All Images</source>
<translation>Alle Bilder</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="172"/>
<source>Only new</source>
<translation>Nur neue</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="186"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="190"/>
<source>Own Images</source> <source>Own Images</source>
<translation>Eigene Bilder</translation> <translation>Eigene Bilder</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/PhotoTab.qml" line="172"/> <location filename="../qml/photoqml/PhotoTab.qml" line="227"/>
<source>More</source> <source>More</source>
<translation>Mehr</translation> <translation>Mehr</translation>
</message> </message>
</context> </context>
<context>
<name>ProfileComponent</name>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="60"/>
<source>profile name</source>
<translation>Profilname</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="61"/>
<source>is default</source>
<translation>Hauptprofil</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="62"/>
<source>hide friends</source>
<translation>Verberge Freunde</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="63"/>
<source>profile photo</source>
<translation>Profilbild</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="64"/>
<source>profile thumb</source>
<translation>Mini-Profilbild</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="65"/>
<source>publish</source>
<translation>öffentlich</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="66"/>
<source>publish in network</source>
<translation>Öffentlich im Netzwerk</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="67"/>
<source>description</source>
<translation>Beschreibung</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="68"/>
<source>date of birth</source>
<translation>Geburtstag</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="69"/>
<source>address</source>
<translation>Adresse</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="70"/>
<source>city</source>
<translation>Stadt</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="71"/>
<source>region</source>
<translation>Region</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="72"/>
<source>postal code</source>
<translation>Postleitzahl</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="73"/>
<source>country</source>
<translation>Land</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="74"/>
<source>hometown</source>
<translation>Heimatstadt</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="75"/>
<source>gender</source>
<translation>Geschlecht</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="76"/>
<source>marital status</source>
<translation>Beziehungsstatus</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="77"/>
<source>married with</source>
<translation>verheiratet mit</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="78"/>
<source>married since</source>
<translation>verheiratet seit</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="79"/>
<source>sexual</source>
<translation>Sex</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="80"/>
<source>politics</source>
<translation>Politik</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="81"/>
<source>religion</source>
<translation>Religion</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="82"/>
<source>public keywords</source>
<translation>öffentliche Schlagwörter</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="83"/>
<source>private keywords</source>
<translation>private Schlagwörter</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="84"/>
<source>likes</source>
<translation>Vorlieben</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="85"/>
<source>dislikes</source>
<translation>Abneigungen</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="86"/>
<source>about</source>
<translation>über</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="87"/>
<source>music</source>
<translation>Musik</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="88"/>
<source>book</source>
<translation>Bücher</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="89"/>
<source>tv</source>
<translation>TV</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="90"/>
<source>film</source>
<translation>Filme</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="91"/>
<source>interest</source>
<translation>Interessen</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="92"/>
<source>romance</source>
<translation>Liebschaften</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="93"/>
<source>work</source>
<translation>Arbeit</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="94"/>
<source>education</source>
<translation>Bildung</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="95"/>
<source>social networks</source>
<translation>Soziale Netzwerke</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="96"/>
<source>homepage</source>
<translation>Homepage</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="176"/>
<source>Update</source>
<translation>Aktualisieren</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="206"/>
<source>profile id</source>
<translation>Profil-Nummer</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Description</source>
<translation>Beschreibung</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Location</source>
<translation>Ort</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Posts</source>
<translation>Beiträge</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="230"/>
<source>URL</source>
<translation>Profilseite</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="231"/>
<source>Created at</source>
<translation>Erstellt</translation>
</message>
</context>
<context> <context>
<name>SmileyDialog</name> <name>SmileyDialog</name>
<message> <message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="51"/> <location filename="../qml/newsqml/SmileyDialog.qml" line="82"/>
<source>Standard</source> <source>Standard</source>
<translation>Standard</translation> <translation>Standard</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="77"/> <location filename="../qml/newsqml/SmileyDialog.qml" line="108"/>
<source>Addon</source> <source>Addon</source>
<translation>Addon</translation> <translation>Addon</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="101"/> <location filename="../qml/newsqml/SmileyDialog.qml" line="132"/>
<source>Adult</source> <source>Adult</source>
<translation>XXX</translation> <translation>XXX</translation>
</message> </message>
@ -387,131 +664,131 @@
<context> <context>
<name>newsworker</name> <name>newsworker</name>
<message> <message>
<location filename="../js/newsworker.js" line="26"/> <location filename="../js/newsworker.js" line="57"/>
<source>likes this.</source> <source>likes this.</source>
<translation>mag das.</translation> <translation>mag das.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="27"/> <location filename="../js/newsworker.js" line="58"/>
<source>like this.</source> <source>like this.</source>
<translation>mögen das.</translation> <translation>mögen das.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="30"/> <location filename="../js/newsworker.js" line="61"/>
<source>doesn&apos;t like this.</source> <source>doesn&apos;t like this.</source>
<translation>mag das nicht.</translation> <translation>mag das nicht.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="31"/> <location filename="../js/newsworker.js" line="62"/>
<source>don&apos;t like this.</source> <source>don&apos;t like this.</source>
<translation>mögen das nicht.</translation> <translation>mögen das nicht.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="34"/> <location filename="../js/newsworker.js" line="65"/>
<source>will attend.</source> <source>will attend.</source>
<translation>nehmen teil.</translation> <translation>nehmen teil.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="35"/> <location filename="../js/newsworker.js" line="66"/>
<source>persons will attend.</source> <source>persons will attend.</source>
<translation>Personen nehmen teil.</translation> <translation>Personen nehmen teil.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="38"/> <location filename="../js/newsworker.js" line="69"/>
<source>will not attend.</source> <source>will not attend.</source>
<translation>nimmt nicht teil.</translation> <translation>nimmt nicht teil.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="39"/> <location filename="../js/newsworker.js" line="70"/>
<source>persons will not attend.</source> <source>persons will not attend.</source>
<translation>Personen nehmen nicht teil.</translation> <translation>Personen nehmen nicht teil.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="42"/> <location filename="../js/newsworker.js" line="73"/>
<source>may attend.</source> <source>may attend.</source>
<translation>nimmt vielleicht teil.</translation> <translation>nimmt vielleicht teil.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="43"/> <location filename="../js/newsworker.js" line="74"/>
<source>persons may attend.</source> <source>persons may attend.</source>
<translation>Personen nehmen vielleicht teil.</translation> <translation>Personen nehmen vielleicht teil.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="46"/> <location filename="../js/newsworker.js" line="77"/>
<source>yes</source> <source>yes</source>
<translation>ja</translation> <translation>ja</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="47"/> <location filename="../js/newsworker.js" line="78"/>
<source>no</source> <source>no</source>
<translation>nein</translation> <translation>nein</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="48"/> <location filename="../js/newsworker.js" line="79"/>
<source>maybe</source> <source>maybe</source>
<translation>vielleicht</translation> <translation>vielleicht</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="64"/> <location filename="../js/newsworker.js" line="95"/>
<source>seconds</source> <source>seconds</source>
<translation>Sekunden</translation> <translation>Sekunden</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="64"/> <location filename="../js/newsworker.js" line="95"/>
<location filename="../js/newsworker.js" line="65"/> <location filename="../js/newsworker.js" line="96"/>
<location filename="../js/newsworker.js" line="66"/> <location filename="../js/newsworker.js" line="97"/>
<location filename="../js/newsworker.js" line="67"/> <location filename="../js/newsworker.js" line="98"/>
<location filename="../js/newsworker.js" line="68"/> <location filename="../js/newsworker.js" line="99"/>
<location filename="../js/newsworker.js" line="69"/> <location filename="../js/newsworker.js" line="100"/>
<location filename="../js/newsworker.js" line="70"/> <location filename="../js/newsworker.js" line="101"/>
<location filename="../js/newsworker.js" line="71"/> <location filename="../js/newsworker.js" line="102"/>
<location filename="../js/newsworker.js" line="72"/> <location filename="../js/newsworker.js" line="103"/>
<location filename="../js/newsworker.js" line="73"/> <location filename="../js/newsworker.js" line="104"/>
<source>ago</source> <source>ago</source>
<translation>her</translation> <translation>her</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="65"/> <location filename="../js/newsworker.js" line="96"/>
<source>minute</source> <source>minute</source>
<translation>Minute</translation> <translation>Minute</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="66"/> <location filename="../js/newsworker.js" line="97"/>
<source>minutes</source> <source>minutes</source>
<translation>Minuten</translation> <translation>Minuten</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="67"/> <location filename="../js/newsworker.js" line="98"/>
<source>hour</source> <source>hour</source>
<translation>Stunde</translation> <translation>Stunde</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="68"/> <location filename="../js/newsworker.js" line="99"/>
<source>hours</source> <source>hours</source>
<translation>Stunden</translation> <translation>Stunden</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="69"/> <location filename="../js/newsworker.js" line="100"/>
<source>day</source> <source>day</source>
<translation>Tag</translation> <translation>Tag</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="70"/> <location filename="../js/newsworker.js" line="101"/>
<source>days</source> <source>days</source>
<translation>Tage</translation> <translation>Tage</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="71"/> <location filename="../js/newsworker.js" line="102"/>
<source>month</source> <source>month</source>
<translation>Monat</translation> <translation>Monat</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="72"/> <location filename="../js/newsworker.js" line="103"/>
<source>months</source> <source>months</source>
<translation>Monate</translation> <translation>Monate</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="73"/> <location filename="../js/newsworker.js" line="104"/>
<source>years</source> <source>years</source>
<translation></translation> <translation></translation>
</message> </message>

View File

@ -4,12 +4,12 @@
<context> <context>
<name>CalendarTab</name> <name>CalendarTab</name>
<message> <message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="73"/> <location filename="../qml/calendarqml/CalendarTab.qml" line="105"/>
<source>Events</source> <source>Events</source>
<translation>Eventos</translation> <translation>Eventos</translation>
</message> </message>
<message> <message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="79"/> <location filename="../qml/calendarqml/CalendarTab.qml" line="109"/>
<source>Own Calendar</source> <source>Own Calendar</source>
<translation>Calendario propio</translation> <translation>Calendario propio</translation>
</message> </message>
@ -17,80 +17,120 @@
<context> <context>
<name>ConfigTab</name> <name>ConfigTab</name>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="33"/> <location filename="../qml/configqml/ConfigTab.qml" line="78"/>
<location filename="../qml/configqml/ConfigTab.qml" line="63"/> <location filename="../qml/configqml/ConfigTab.qml" line="362"/>
<location filename="../qml/configqml/ConfigTab.qml" line="283"/> <location filename="../qml/configqml/ConfigTab.qml" line="384"/>
<location filename="../qml/configqml/ConfigTab.qml" line="304"/>
<source>User</source> <source>User</source>
<translation>Usuario</translation> <translation>Usuario</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="59"/> <location filename="../qml/configqml/ConfigTab.qml" line="105"/>
<source>Server</source> <source>Server</source>
<translation>Servidor</translation> <translation>Servidor</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="68"/> <location filename="../qml/configqml/ConfigTab.qml" line="109"/>
<source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="114"/>
<source>Password</source> <source>Password</source>
<translation>Contraseña</translation> <translation>Contraseña</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="72"/> <location filename="../qml/configqml/ConfigTab.qml" line="118"/>
<source>Image dir.</source> <source>Image dir.</source>
<translation>Dir. de imágenes</translation> <translation>Dir. de imágenes</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="77"/> <location filename="../qml/configqml/ConfigTab.qml" line="123"/>
<source>Max. News</source> <source>Max. News</source>
<translation> Max. de noticias.</translation> <translation> Max. de noticias.</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="81"/> <location filename="../qml/configqml/ConfigTab.qml" line="127"/>
<source>News as</source> <source>News as</source>
<translation>Noticias como</translation> <translation>Noticias como</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="85"/> <location filename="../qml/configqml/ConfigTab.qml" line="131"/>
<source>Interval (0=None)</source> <source>Interval (0=None)</source>
<translation>Intervalo (0=ningún)</translation> <translation>Intervalo (0=ningún)</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="230"/> <location filename="../qml/configqml/ConfigTab.qml" line="201"/>
<location filename="../qml/configqml/ConfigTab.qml" line="316"/>
<location filename="../qml/configqml/ConfigTab.qml" line="340"/>
<source>Error</source>
<translation type="unfinished">Error</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="201"/>
<source>Nickname not registered at given server!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="301"/>
<source>Confirm</source> <source>Confirm</source>
<translation>Confirmar</translation> <translation>Confirmar</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="234"/> <location filename="../qml/configqml/ConfigTab.qml" line="305"/>
<source>No server given! </source> <source>No server given! </source>
<translation>¡Servidor no encontrado!</translation> <translation>¡Servidor no encontrado!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="235"/> <location filename="../qml/configqml/ConfigTab.qml" line="306"/>
<source>No username given! </source> <source>No nickname given! </source>
<translation>¡Usuario incorrecto!</translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="236"/> <location filename="../qml/configqml/ConfigTab.qml" line="307"/>
<source>Nickname not registered at given server! </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No username given! </source>
<translation type="vanished">¡Usuario incorrecto!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="308"/>
<source>No password given! </source> <source>No password given! </source>
<translation>¡Contraseña incorrecta!</translation> <translation>¡Contraseña incorrecta!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="237"/> <location filename="../qml/configqml/ConfigTab.qml" line="309"/>
<source>No image directory given!</source> <source>No image directory given!</source>
<translation>¡No se ha encontrado el directorio de imágenes!</translation> <translation>¡No se ha encontrado el directorio de imágenes!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="238"/> <location filename="../qml/configqml/ConfigTab.qml" line="310"/>
<source>No maximum news number given!</source> <source>No maximum news number given!</source>
<translation>¡ máximo de noticias incorrecto!</translation> <translation>¡ máximo de noticias incorrecto!</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="319"/> <location filename="../qml/configqml/ConfigTab.qml" line="316"/>
<source>Wrong password!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="335"/>
<source>Success</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="335"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="399"/>
<source>Timeline</source> <source>Timeline</source>
<translation>Cronología</translation> <translation>Cronología</translation>
</message> </message>
<message> <message>
<location filename="../qml/configqml/ConfigTab.qml" line="323"/> <location filename="../qml/configqml/ConfigTab.qml" line="403"/>
<source>Conversations</source> <source>Conversations</source>
<translation>Conversaciones</translation> <translation>Conversaciones</translation>
</message> </message>
@ -98,7 +138,7 @@
<context> <context>
<name>ContactComponent</name> <name>ContactComponent</name>
<message> <message>
<location filename="../qml/contactqml/ContactComponent.qml" line="8"/> <location filename="../qml/contactqml/ContactComponent.qml" line="39"/>
<source>Connect</source> <source>Connect</source>
<translation>Conectar</translation> <translation>Conectar</translation>
</message> </message>
@ -106,32 +146,32 @@
<context> <context>
<name>ContactDetailsComponent</name> <name>ContactDetailsComponent</name>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="11"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="42"/>
<source>Connect</source> <source>Connect</source>
<translation>Conectar</translation> <translation>Conectar</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Description</source> <source>Description</source>
<translation>Descripción</translation> <translation>Descripción</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Location</source> <source>Location</source>
<translation>Localización</translation> <translation>Localización</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Posts</source> <source>Posts</source>
<translation>Mensajes</translation> <translation>Mensajes</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="64"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="95"/>
<source>URL</source> <source>URL</source>
<translation>URL</translation> <translation>URL</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="65"/> <location filename="../qml/contactqml/ContactDetailsComponent.qml" line="96"/>
<source>Created at</source> <source>Created at</source>
<translation>Creado en</translation> <translation>Creado en</translation>
</message> </message>
@ -139,17 +179,22 @@
<context> <context>
<name>FriendsTab</name> <name>FriendsTab</name>
<message> <message>
<location filename="../qml/contactqml/FriendsTab.qml" line="65"/> <location filename="../qml/contactqml/FriendsTab.qml" line="111"/>
<source>Me</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="121"/>
<source>Friends</source> <source>Friends</source>
<translation>Amigos</translation> <translation>Amigos</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/FriendsTab.qml" line="135"/> <location filename="../qml/contactqml/FriendsTab.qml" line="200"/>
<source>Contacts</source> <source>Contacts</source>
<translation>Contactos</translation> <translation>Contactos</translation>
</message> </message>
<message> <message>
<location filename="../qml/contactqml/FriendsTab.qml" line="188"/> <location filename="../qml/contactqml/FriendsTab.qml" line="253"/>
<source>Groups</source> <source>Groups</source>
<translation>Grupos</translation> <translation>Grupos</translation>
</message> </message>
@ -157,32 +202,32 @@
<context> <context>
<name>ImageUploadDialog</name> <name>ImageUploadDialog</name>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="96"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="127"/>
<source>Album</source> <source>Album</source>
<translation>álbum</translation> <translation>álbum</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="101"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="132"/>
<source>Image</source> <source>Image</source>
<translation>imagen</translation> <translation>imagen</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="106"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="137"/>
<source>Description</source> <source>Description</source>
<translation>Descripción</translation> <translation>Descripción</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="205"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="236"/>
<source>Upload</source> <source>Upload</source>
<translation>Subir</translation> <translation>Subir</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="208"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source>Error</source> <source>Error</source>
<translation>Error</translation> <translation>Error</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="208"/> <location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source> No album name given</source> <source> No album name given</source>
<translation>¡Nombre del álbum no encontrado!</translation> <translation>¡Nombre del álbum no encontrado!</translation>
</message> </message>
@ -190,17 +235,17 @@
<context> <context>
<name>MessageSend</name> <name>MessageSend</name>
<message> <message>
<location filename="../qml/newsqml/MessageSend.qml" line="67"/> <location filename="../qml/newsqml/MessageSend.qml" line="98"/>
<source>Title (optional)</source> <source>Title (optional)</source>
<translation>Título (opcional)</translation> <translation>Título (opcional)</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/MessageSend.qml" line="149"/> <location filename="../qml/newsqml/MessageSend.qml" line="180"/>
<source>Error</source> <source>Error</source>
<translation>Error</translation> <translation>Error</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/MessageSend.qml" line="149"/> <location filename="../qml/newsqml/MessageSend.qml" line="180"/>
<source>Only one attachment supported at the moment. <source>Only one attachment supported at the moment.
Remove other attachment first!</source> Remove other attachment first!</source>
<translation>Solo se admite adjuntar un solo archivo en este momento. <translation>Solo se admite adjuntar un solo archivo en este momento.
@ -210,32 +255,31 @@
<context> <context>
<name>NewsTab</name> <name>NewsTab</name>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="21"/>
<source>Download profile image for </source> <source>Download profile image for </source>
<translation>Descargar la imagen del perfil para </translation> <translation type="vanished">Descargar la imagen del perfil para </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="163"/> <location filename="../qml/newsqml/NewsTab.qml" line="204"/>
<source>More</source> <source>More</source>
<translation>Mas</translation> <translation>Mas</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="260"/> <location filename="../qml/newsqml/NewsTab.qml" line="301"/>
<source>Timeline</source> <source>Timeline</source>
<translation>Cronología</translation> <translation>Cronología</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="269"/> <location filename="../qml/newsqml/NewsTab.qml" line="310"/>
<source>Favorites</source> <source>Favorites</source>
<translation>Favoritos</translation> <translation>Favoritos</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="281"/> <location filename="../qml/newsqml/NewsTab.qml" line="322"/>
<source>Conversations</source> <source>Conversations</source>
<translation>Conversaciones</translation> <translation>Conversaciones</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/NewsTab.qml" line="289"/> <location filename="../qml/newsqml/NewsTab.qml" line="330"/>
<source>Notifications</source> <source>Notifications</source>
<translation>Notificaciones</translation> <translation>Notificaciones</translation>
</message> </message>
@ -243,82 +287,82 @@
<context> <context>
<name>Newsitem</name> <name>Newsitem</name>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="16"/> <location filename="../qml/newsqml/Newsitem.qml" line="47"/>
<source>attending: </source> <source>attending: </source>
<translation>Asistiendo: </translation> <translation>Asistiendo: </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="68"/> <location filename="../qml/newsqml/Newsitem.qml" line="99"/>
<source>Source: </source> <source>Source: </source>
<translation>Fuente: </translation> <translation>Fuente: </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="69"/> <location filename="../qml/newsqml/Newsitem.qml" line="100"/>
<source>Direct Message</source> <source>Direct Message</source>
<translation>Mensaje directo</translation> <translation>Mensaje directo</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="84"/> <location filename="../qml/newsqml/Newsitem.qml" line="115"/>
<source>In reply to </source> <source>In reply to </source>
<translation>En respuesta a </translation> <translation>En respuesta a </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="96"/> <location filename="../qml/newsqml/Newsitem.qml" line="127"/>
<source> comments</source> <source> comments</source>
<translation> comentarios</translation> <translation> comentarios</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="190"/> <location filename="../qml/newsqml/Newsitem.qml" line="221"/>
<source>Attending: </source> <source>Attending: </source>
<translation>Asistiendo: </translation> <translation>Asistiendo: </translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="312"/> <location filename="../qml/newsqml/Newsitem.qml" line="343"/>
<source>Reply</source> <source>Reply</source>
<translation>Respuesta</translation> <translation>Respuesta</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="320"/> <location filename="../qml/newsqml/Newsitem.qml" line="351"/>
<source>DM</source> <source>DM</source>
<translation>Mensaje directo</translation> <translation>Mensaje directo</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="326"/> <location filename="../qml/newsqml/Newsitem.qml" line="357"/>
<source>Repost</source> <source>Repost</source>
<translation>Volver a publicar</translation> <translation>Volver a publicar</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="329"/> <location filename="../qml/newsqml/Newsitem.qml" line="360"/>
<source>Success!</source> <source>Success!</source>
<translation>éxito!</translation> <translation>éxito!</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="334"/> <location filename="../qml/newsqml/Newsitem.qml" line="365"/>
<source>Conversation</source> <source>Conversation</source>
<translation>Conversación</translation> <translation>Conversación</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="345"/> <location filename="../qml/newsqml/Newsitem.qml" line="376"/>
<source>Attending</source> <source>Attending</source>
<translation>Asistiendo</translation> <translation>Asistiendo</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="347"/> <location filename="../qml/newsqml/Newsitem.qml" line="378"/>
<source>yes</source> <source>yes</source>
<translation>si</translation> <translation>si</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="352"/> <location filename="../qml/newsqml/Newsitem.qml" line="383"/>
<source>maybe</source> <source>maybe</source>
<translation>quizás</translation> <translation>quizás</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="357"/> <location filename="../qml/newsqml/Newsitem.qml" line="388"/>
<source>no</source> <source>no</source>
<translation>no</translation> <translation>no</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/Newsitem.qml" line="364"/> <location filename="../qml/newsqml/Newsitem.qml" line="395"/>
<source>Delete</source> <source>Delete</source>
<translation>Borrar</translation> <translation>Borrar</translation>
</message> </message>
@ -326,12 +370,12 @@
<context> <context>
<name>PermissionDialog</name> <name>PermissionDialog</name>
<message> <message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="35"/> <location filename="../qml/genericqml/PermissionDialog.qml" line="66"/>
<source>Friends</source> <source>Friends</source>
<translation>Amigos</translation> <translation>Amigos</translation>
</message> </message>
<message> <message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="96"/> <location filename="../qml/genericqml/PermissionDialog.qml" line="127"/>
<source>Groups</source> <source>Groups</source>
<translation>Grupos</translation> <translation>Grupos</translation>
</message> </message>
@ -339,36 +383,269 @@
<context> <context>
<name>PhotoTab</name> <name>PhotoTab</name>
<message> <message>
<location filename="../qml/photoqml/PhotoTab.qml" line="72"/> <location filename="../qml/photoqml/PhotoTab.qml" line="115"/>
<source>&apos;s images</source> <source>&apos;s images</source>
<translation>s Imágenes</translation> <translation>s Imágenes</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/PhotoTab.qml" line="132"/> <location filename="../qml/photoqml/PhotoTab.qml" line="167"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="138"/> <source>All Images</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="172"/>
<source>Only new</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="186"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="190"/>
<source>Own Images</source> <source>Own Images</source>
<translation>Mis imágenes</translation> <translation>Mis imágenes</translation>
</message> </message>
<message> <message>
<location filename="../qml/photoqml/PhotoTab.qml" line="172"/> <location filename="../qml/photoqml/PhotoTab.qml" line="227"/>
<source>More</source> <source>More</source>
<translation>Mas</translation> <translation>Mas</translation>
</message> </message>
</context> </context>
<context>
<name>ProfileComponent</name>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="60"/>
<source>profile name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="61"/>
<source>is default</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="62"/>
<source>hide friends</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="63"/>
<source>profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="64"/>
<source>profile thumb</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="65"/>
<source>publish</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="66"/>
<source>publish in network</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="67"/>
<source>description</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="68"/>
<source>date of birth</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="69"/>
<source>address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="70"/>
<source>city</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="71"/>
<source>region</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="72"/>
<source>postal code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="73"/>
<source>country</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="74"/>
<source>hometown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="75"/>
<source>gender</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="76"/>
<source>marital status</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="77"/>
<source>married with</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="78"/>
<source>married since</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="79"/>
<source>sexual</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="80"/>
<source>politics</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="81"/>
<source>religion</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="82"/>
<source>public keywords</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="83"/>
<source>private keywords</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="84"/>
<source>likes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="85"/>
<source>dislikes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="86"/>
<source>about</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="87"/>
<source>music</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="88"/>
<source>book</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="89"/>
<source>tv</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="90"/>
<source>film</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="91"/>
<source>interest</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="92"/>
<source>romance</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="93"/>
<source>work</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="94"/>
<source>education</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="95"/>
<source>social networks</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="96"/>
<source>homepage</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="176"/>
<source>Update</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="206"/>
<source>profile id</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Description</source>
<translation type="unfinished">Descripción</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Location</source>
<translation type="unfinished">Localización</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Posts</source>
<translation type="unfinished">Mensajes</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="230"/>
<source>URL</source>
<translation type="unfinished">URL</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="231"/>
<source>Created at</source>
<translation type="unfinished">Creado en</translation>
</message>
</context>
<context> <context>
<name>SmileyDialog</name> <name>SmileyDialog</name>
<message> <message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="51"/> <location filename="../qml/newsqml/SmileyDialog.qml" line="82"/>
<source>Standard</source> <source>Standard</source>
<translation>Standard</translation> <translation>Standard</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="77"/> <location filename="../qml/newsqml/SmileyDialog.qml" line="108"/>
<source>Addon</source> <source>Addon</source>
<translation>Addon</translation> <translation>Addon</translation>
</message> </message>
<message> <message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="101"/> <location filename="../qml/newsqml/SmileyDialog.qml" line="132"/>
<source>Adult</source> <source>Adult</source>
<translation>XXX</translation> <translation>XXX</translation>
</message> </message>
@ -376,131 +653,131 @@
<context> <context>
<name>newsworker</name> <name>newsworker</name>
<message> <message>
<location filename="../js/newsworker.js" line="26"/> <location filename="../js/newsworker.js" line="57"/>
<source>likes this.</source> <source>likes this.</source>
<translation>le gusta esto.</translation> <translation>le gusta esto.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="27"/> <location filename="../js/newsworker.js" line="58"/>
<source>like this.</source> <source>like this.</source>
<translation>me gusta esto.</translation> <translation>me gusta esto.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="30"/> <location filename="../js/newsworker.js" line="61"/>
<source>doesn&apos;t like this.</source> <source>doesn&apos;t like this.</source>
<translation>no de ése.</translation> <translation>no de ése.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="31"/> <location filename="../js/newsworker.js" line="62"/>
<source>don&apos;t like this.</source> <source>don&apos;t like this.</source>
<translation>no me gusta.</translation> <translation>no me gusta.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="34"/> <location filename="../js/newsworker.js" line="65"/>
<source>will attend.</source> <source>will attend.</source>
<translation>asistirá.</translation> <translation>asistirá.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="35"/> <location filename="../js/newsworker.js" line="66"/>
<source>persons will attend.</source> <source>persons will attend.</source>
<translation>Personas que asistirán.</translation> <translation>Personas que asistirán.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="38"/> <location filename="../js/newsworker.js" line="69"/>
<source>will not attend.</source> <source>will not attend.</source>
<translation>no asistirá.</translation> <translation>no asistirá.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="39"/> <location filename="../js/newsworker.js" line="70"/>
<source>persons will not attend.</source> <source>persons will not attend.</source>
<translation>Personas que no asistirán..</translation> <translation>Personas que no asistirán..</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="42"/> <location filename="../js/newsworker.js" line="73"/>
<source>may attend.</source> <source>may attend.</source>
<translation>Puede asistir.</translation> <translation>Puede asistir.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="43"/> <location filename="../js/newsworker.js" line="74"/>
<source>persons may attend.</source> <source>persons may attend.</source>
<translation>Personas que pueden asistir.</translation> <translation>Personas que pueden asistir.</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="46"/> <location filename="../js/newsworker.js" line="77"/>
<source>yes</source> <source>yes</source>
<translation>si</translation> <translation>si</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="47"/> <location filename="../js/newsworker.js" line="78"/>
<source>no</source> <source>no</source>
<translation>no</translation> <translation>no</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="48"/> <location filename="../js/newsworker.js" line="79"/>
<source>maybe</source> <source>maybe</source>
<translation>quizás</translation> <translation>quizás</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="64"/> <location filename="../js/newsworker.js" line="95"/>
<source>seconds</source> <source>seconds</source>
<translation>Segundos</translation> <translation>Segundos</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="64"/> <location filename="../js/newsworker.js" line="95"/>
<location filename="../js/newsworker.js" line="65"/> <location filename="../js/newsworker.js" line="96"/>
<location filename="../js/newsworker.js" line="66"/> <location filename="../js/newsworker.js" line="97"/>
<location filename="../js/newsworker.js" line="67"/> <location filename="../js/newsworker.js" line="98"/>
<location filename="../js/newsworker.js" line="68"/> <location filename="../js/newsworker.js" line="99"/>
<location filename="../js/newsworker.js" line="69"/> <location filename="../js/newsworker.js" line="100"/>
<location filename="../js/newsworker.js" line="70"/> <location filename="../js/newsworker.js" line="101"/>
<location filename="../js/newsworker.js" line="71"/> <location filename="../js/newsworker.js" line="102"/>
<location filename="../js/newsworker.js" line="72"/> <location filename="../js/newsworker.js" line="103"/>
<location filename="../js/newsworker.js" line="73"/> <location filename="../js/newsworker.js" line="104"/>
<source>ago</source> <source>ago</source>
<translation>hace</translation> <translation>hace</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="65"/> <location filename="../js/newsworker.js" line="96"/>
<source>minute</source> <source>minute</source>
<translation>Minuto</translation> <translation>Minuto</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="66"/> <location filename="../js/newsworker.js" line="97"/>
<source>minutes</source> <source>minutes</source>
<translation>Minutos</translation> <translation>Minutos</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="67"/> <location filename="../js/newsworker.js" line="98"/>
<source>hour</source> <source>hour</source>
<translation>Hora</translation> <translation>Hora</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="68"/> <location filename="../js/newsworker.js" line="99"/>
<source>hours</source> <source>hours</source>
<translation>Horas</translation> <translation>Horas</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="69"/> <location filename="../js/newsworker.js" line="100"/>
<source>day</source> <source>day</source>
<translation>Dia</translation> <translation>Dia</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="70"/> <location filename="../js/newsworker.js" line="101"/>
<source>days</source> <source>days</source>
<translation>Dias</translation> <translation>Dias</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="71"/> <location filename="../js/newsworker.js" line="102"/>
<source>month</source> <source>month</source>
<translation>Mes</translation> <translation>Mes</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="72"/> <location filename="../js/newsworker.js" line="103"/>
<source>months</source> <source>months</source>
<translation>Meses</translation> <translation>Meses</translation>
</message> </message>
<message> <message>
<location filename="../js/newsworker.js" line="73"/> <location filename="../js/newsworker.js" line="104"/>
<source>years</source> <source>years</source>
<translation>Años</translation> <translation>Años</translation>
</message> </message>

Binary file not shown.

View File

@ -0,0 +1,785 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="it">
<context>
<name>CalendarTab</name>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="105"/>
<source>Events</source>
<translation>Eventi</translation>
</message>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="109"/>
<source>Own Calendar</source>
<translation>Calendario</translation>
</message>
</context>
<context>
<name>ConfigTab</name>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="78"/>
<location filename="../qml/configqml/ConfigTab.qml" line="362"/>
<location filename="../qml/configqml/ConfigTab.qml" line="384"/>
<source>User</source>
<translation>Utente</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="105"/>
<source>Server</source>
<translation>Server</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="109"/>
<source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="114"/>
<source>Password</source>
<translation>Password</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="118"/>
<source>Image dir.</source>
<translation>Directory immagini</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="123"/>
<source>Max. News</source>
<translation> Max. di notizie</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="127"/>
<source>News as</source>
<translation>News come</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="131"/>
<source>Interval (0=None)</source>
<translation>Intervallo (0=nessuno)</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="201"/>
<location filename="../qml/configqml/ConfigTab.qml" line="316"/>
<location filename="../qml/configqml/ConfigTab.qml" line="340"/>
<source>Error</source>
<translation type="unfinished">Errore</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="201"/>
<source>Nickname not registered at given server!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="301"/>
<source>Confirm</source>
<translation>Conferma</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="305"/>
<source>No server given! </source>
<translation>Nessun server inserito!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="306"/>
<source>No nickname given! </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="307"/>
<source>Nickname not registered at given server! </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No username given! </source>
<translation type="vanished">Nessun utente inserito!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="308"/>
<source>No password given! </source>
<translation>Nessuna password inserita!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="309"/>
<source>No image directory given!</source>
<translation>Nessuna directory immagini inserita!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="310"/>
<source>No maximum news number given!</source>
<translation>Nessun numero massimo di news inserito!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="316"/>
<source>Wrong password!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="335"/>
<source>Success</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="335"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="399"/>
<source>Timeline</source>
<translation>Cronologia</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="403"/>
<source>Conversations</source>
<translation>Conversazioni</translation>
</message>
</context>
<context>
<name>ContactComponent</name>
<message>
<location filename="../qml/contactqml/ContactComponent.qml" line="39"/>
<source>Connect</source>
<translation>Connetti</translation>
</message>
</context>
<context>
<name>ContactDetailsComponent</name>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="42"/>
<source>Connect</source>
<translation>Connetti</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Description</source>
<translation>Descrizione</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Location</source>
<translation>Località</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Posts</source>
<translation>Messaggi</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="95"/>
<source>URL</source>
<translation>URL</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="96"/>
<source>Created at</source>
<translation>Creato il</translation>
</message>
</context>
<context>
<name>FriendsTab</name>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="111"/>
<source>Me</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="121"/>
<source>Friends</source>
<translation>Amici</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="200"/>
<source>Contacts</source>
<translation>Contatti</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="253"/>
<source>Groups</source>
<translation>Gruppi</translation>
</message>
</context>
<context>
<name>ImageUploadDialog</name>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="127"/>
<source>Album</source>
<translation>Album</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="132"/>
<source>Image</source>
<translation>Immagine</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="137"/>
<source>Description</source>
<translation>Descrizione</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="236"/>
<source>Upload</source>
<translation>Carica</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source>Error</source>
<translation>Errore</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source> No album name given</source>
<translation>Nessun nome album inserito!</translation>
</message>
</context>
<context>
<name>MessageSend</name>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="98"/>
<source>Title (optional)</source>
<translation>Titolo (opzionale)</translation>
</message>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="180"/>
<source>Error</source>
<translation>Errore</translation>
</message>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="180"/>
<source>Only one attachment supported at the moment.
Remove other attachment first!</source>
<translation>Solo un allegato è attualmente supportato.
Rimuovere prima gli altri allegati!</translation>
</message>
</context>
<context>
<name>NewsTab</name>
<message>
<source>Download profile image for </source>
<translation type="vanished">Download immagine profilo per </translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="204"/>
<source>More</source>
<translation>Ancora</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="301"/>
<source>Timeline</source>
<translation>Cronologia</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="310"/>
<source>Favorites</source>
<translation>Favoriti</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="322"/>
<source>Conversations</source>
<translation>Conversazioni</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="330"/>
<source>Notifications</source>
<translation>Notifiche</translation>
</message>
</context>
<context>
<name>Newsitem</name>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="47"/>
<source>attending: </source>
<translation>attendere: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="99"/>
<source>Source: </source>
<translation>Codice: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="100"/>
<source>Direct Message</source>
<translation>Messaggio diretto</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="115"/>
<source>In reply to </source>
<translation>In risposta a </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="127"/>
<source> comments</source>
<translation> commenti</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="221"/>
<source>Attending: </source>
<translation>Attendi: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="343"/>
<source>Reply</source>
<translation>Risposta</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="351"/>
<source>DM</source>
<translation>Messaggio diretto</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="357"/>
<source>Repost</source>
<translation>Condividi</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="360"/>
<source>Success!</source>
<translation>Ha funzionato!</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="365"/>
<source>Conversation</source>
<translation>Conversazione</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="376"/>
<source>Attending</source>
<translation>Attendi</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="378"/>
<source>yes</source>
<translation>si</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="383"/>
<source>maybe</source>
<translation>potrebbe</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="388"/>
<source>no</source>
<translation>no</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="395"/>
<source>Delete</source>
<translation>Cancella</translation>
</message>
</context>
<context>
<name>PermissionDialog</name>
<message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="66"/>
<source>Friends</source>
<translation>Amici</translation>
</message>
<message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="127"/>
<source>Groups</source>
<translation>Gruppi</translation>
</message>
</context>
<context>
<name>PhotoTab</name>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="115"/>
<source>&apos;s images</source>
<translation> Immagini</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="167"/>
<source>All Images</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="172"/>
<source>Only new</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="186"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="190"/>
<source>Own Images</source>
<translation>Mie immagini</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="227"/>
<source>More</source>
<translation>Ancora</translation>
</message>
</context>
<context>
<name>ProfileComponent</name>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="60"/>
<source>profile name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="61"/>
<source>is default</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="62"/>
<source>hide friends</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="63"/>
<source>profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="64"/>
<source>profile thumb</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="65"/>
<source>publish</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="66"/>
<source>publish in network</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="67"/>
<source>description</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="68"/>
<source>date of birth</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="69"/>
<source>address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="70"/>
<source>city</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="71"/>
<source>region</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="72"/>
<source>postal code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="73"/>
<source>country</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="74"/>
<source>hometown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="75"/>
<source>gender</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="76"/>
<source>marital status</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="77"/>
<source>married with</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="78"/>
<source>married since</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="79"/>
<source>sexual</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="80"/>
<source>politics</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="81"/>
<source>religion</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="82"/>
<source>public keywords</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="83"/>
<source>private keywords</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="84"/>
<source>likes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="85"/>
<source>dislikes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="86"/>
<source>about</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="87"/>
<source>music</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="88"/>
<source>book</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="89"/>
<source>tv</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="90"/>
<source>film</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="91"/>
<source>interest</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="92"/>
<source>romance</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="93"/>
<source>work</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="94"/>
<source>education</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="95"/>
<source>social networks</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="96"/>
<source>homepage</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="176"/>
<source>Update</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="206"/>
<source>profile id</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Description</source>
<translation type="unfinished">Descrizione</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Location</source>
<translation type="unfinished">Località</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="229"/>
<source>Posts</source>
<translation type="unfinished">Messaggi</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="230"/>
<source>URL</source>
<translation type="unfinished">URL</translation>
</message>
<message>
<location filename="../qml/contactqml/ProfileComponent.qml" line="231"/>
<source>Created at</source>
<translation type="unfinished">Creato il</translation>
</message>
</context>
<context>
<name>SmileyDialog</name>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="82"/>
<source>Standard</source>
<translation>Standard</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="108"/>
<source>Addon</source>
<translation>Addon</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="132"/>
<source>Adult</source>
<translation>XXX</translation>
</message>
</context>
<context>
<name>newsworker</name>
<message>
<location filename="../js/newsworker.js" line="57"/>
<source>likes this.</source>
<translation>mi piace.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="58"/>
<source>like this.</source>
<translation>mi piace.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="61"/>
<source>doesn&apos;t like this.</source>
<translation>non mi piace.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="62"/>
<source>don&apos;t like this.</source>
<translation>non mi piace.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="65"/>
<source>will attend.</source>
<translation>attendere.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="66"/>
<source>persons will attend.</source>
<translation>Persone che attendono.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="69"/>
<source>will not attend.</source>
<translation>non aspettare.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="70"/>
<source>persons will not attend.</source>
<translation>Persone che non aspettano.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="73"/>
<source>may attend.</source>
<translation>puoi attendere.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="74"/>
<source>persons may attend.</source>
<translation>Persone che possono attendere.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="77"/>
<source>yes</source>
<translation>si</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="78"/>
<source>no</source>
<translation>no</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="79"/>
<source>maybe</source>
<translation>potrebbe</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="95"/>
<source>seconds</source>
<translation>secondi</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="95"/>
<location filename="../js/newsworker.js" line="96"/>
<location filename="../js/newsworker.js" line="97"/>
<location filename="../js/newsworker.js" line="98"/>
<location filename="../js/newsworker.js" line="99"/>
<location filename="../js/newsworker.js" line="100"/>
<location filename="../js/newsworker.js" line="101"/>
<location filename="../js/newsworker.js" line="102"/>
<location filename="../js/newsworker.js" line="103"/>
<location filename="../js/newsworker.js" line="104"/>
<source>ago</source>
<translation>fa</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="96"/>
<source>minute</source>
<translation>minuti</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="97"/>
<source>minutes</source>
<translation>minuti</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="98"/>
<source>hour</source>
<translation>ora</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="99"/>
<source>hours</source>
<translation>ore</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="100"/>
<source>day</source>
<translation>giorno</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="101"/>
<source>days</source>
<translation>giorni</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="102"/>
<source>month</source>
<translation>mese</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="103"/>
<source>months</source>
<translation>mesi</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="104"/>
<source>years</source>
<translation>anni</translation>
</message>
</context>
</TS>

View File

@ -207,10 +207,15 @@
<file>qml/calendarqml/EventList.qml</file> <file>qml/calendarqml/EventList.qml</file>
<file>translations/friendiqa-de.qm</file> <file>translations/friendiqa-de.qm</file>
<file>translations/friendiqa-de.ts</file> <file>translations/friendiqa-de.ts</file>
<file>translations/friendiqa-es.qm</file>
<file>translations/friendiqa-es.ts</file>
<file>qml/photoqml/ImageUploadDialog.qml</file> <file>qml/photoqml/ImageUploadDialog.qml</file>
<file>qml/genericqml/AttachmentDialog.qml</file>
<file>qml/genericqml/ImageDialog.qml</file>
<file>qml/genericqml/PermissionDialog.qml</file> <file>qml/genericqml/PermissionDialog.qml</file>
<file>images/addImage.png</file> <file>images/addImage.png</file>
<file>qml/genericqml/ImagePicker.qml</file>
<file>qml/genericqml/ImagePickerLinux.qml</file>
<file>js/image.js</file>
<file>qml/contactqml/ProfileComponent.qml</file>
<file>translations/friendiqa-it.ts</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "filesystem.h" #include "filesystem.h"
FILESYSTEM *FILESYSTEM::instance() FILESYSTEM *FILESYSTEM::instance()
@ -33,7 +64,7 @@ QString FILESYSTEM::homePath() const
//{ //{
//QAndroidJniObject object = QAndroidJniObject::getStaticObjectField<jstring>("android.os.Environment", "DIRECTORY_DCIM"); //QAndroidJniObject object = QAndroidJniObject::getStaticObjectField<jstring>("android.os.Environment", "DIRECTORY_DCIM");
//QAndroidJniObject dcim =QAndroidJniObject::callStaticObjectMethod("android.os.Environment","getExternalStoragePublicDirectory", "(Ljava/lang/String;)Ljava/io/File;", object.object<jobject>()); //QAndroidJniObject dcim =QAndroidJniObject::callStaticObjectMethod("android.os.Environment","getExternalStoragePublicDirectory", "(Ljava/lang/String;)Ljava/io/File;", object.object<jobject>());
// return dcim.toString; // return dcim.toString();
//} //}

View File

@ -1,17 +1,49 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef FILESYSTEM_H #ifndef FILESYSTEM_H
#define FILESYSTEM_H #define FILESYSTEM_H
#include <QDir> #include <QDir>
#include <QObject> #include <QObject>
//#include <QtAndroidExtras> //#include <QtAndroidExtras>
//#include <QAndroidActivityResultReceiver>
class FILESYSTEM : public QObject class FILESYSTEM : public QObject//, public QAndroidActivityResultReceiver
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged) Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged)
//Q_PROPERTY(bool direxist READ direxist) //Q_PROPERTY(bool direxist READ direxist)
Q_PROPERTY(QString homePath READ homePath) Q_PROPERTY(QString homePath READ homePath)
//Q_PROPERTY(QString cameraPath READ cameraPath) //Q_PROPERTY(QString cameraPath READ cameraPath)
public: public:
@ -22,9 +54,11 @@ public:
QFileInfoList fileList(); QFileInfoList fileList();
//bool direxist(QString Directory); //bool direxist(QString Directory);
QString homePath() const; QString homePath() const;
QString cameraPath() const; //QString cameraPath() const;
// virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data);
signals: signals:
//void imageselected(QString);
void directoryChanged(); void directoryChanged();
//void fileListContent(QList data); //void fileListContent(QList data);
void success(QString data); void success(QString data);
@ -34,6 +68,7 @@ public slots:
void makeDir(QString name); void makeDir(QString name);
void rmDir(); void rmDir();
void rmFile(QString name); void rmFile(QString name);
//void searchImage();
//void fileList(); //void fileList();
private: private:

View File

@ -1,16 +1,68 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QApplication> #include <QApplication>
#include <QtQml/QQmlEngine> #include <QtQml/QQmlEngine>
#include <QtQuick> #include <QtQuick>
#include "xhr.h" #include "xhr.h"
#include "filesystem.h" #include "filesystem.h"
#include "remoteauthasyncimageprovider.h"
//#include "AndroidNative/systemdispatcher.h"
//#include "AndroidNative/environment.h"
//#include "AndroidNative/debug.h"
//#include "AndroidNative/mediascannerconnection.h"
#ifdef Q_OS_ANDROID
#include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroidExtras/QAndroidJniEnvironment>
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[]) { int main(int argc, char *argv[]) {
QApplication app(argc, argv); QApplication app(argc, argv);
QQuickView view; QQuickView view;
QTranslator qtTranslator; QTranslator qtTranslator;
qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations"); qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations");
app.installTranslator(&qtTranslator); app.installTranslator(&qtTranslator);
RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider;
view.engine()->addImageProvider("remoteauthimage",imageProvider);
view.rootContext()->setContextProperty("remoteauth", imageProvider);
XHR* xhr = XHR::instance(); XHR* xhr = XHR::instance();
view.rootContext()->setContextProperty("xhr", xhr); view.rootContext()->setContextProperty("xhr", xhr);
FILESYSTEM* filesystem = FILESYSTEM::instance(); FILESYSTEM* filesystem = FILESYSTEM::instance();

View File

@ -1,50 +0,0 @@
#include "imagepickerandroid.h"
imagePickerAndroid::imagePickerAndroid()
{
}
void imagePickerAndroid::buscaImagem()
{
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<jstring>(), EXTERNAL_CONTENT_URI.object<jobject>());
if (ACTION_PICK.isValid() && intent.isValid())
{
intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("image/*").object<jstring>());
QtAndroid::startActivity(intent.object<jobject>(), 101, this);
qDebug() << "OK";
}
else
{
qDebug() << "ERRO";
}
}
void imagePickerAndroid::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data)
{
jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("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<jobject>(), projecao, NULL, NULL, NULL);
jint columnIndex = cursor.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", dadosAndroid.object<jstring>());
cursor.callMethod<jboolean>("moveToFirst", "()Z");
QAndroidJniObject resultado = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex);
QString imagemCaminho = "file://" + resultado.toString();
emit imagemCaminhoSignal(imagemCaminho);
}
else
{
qDebug() << "Caminho errado";
}
}

View File

@ -1,23 +0,0 @@
#ifndef IMAGEPICKANDROID_H
#define IMAGEPICKANDROID_H
#include <QObject>
#include <QtAndroidExtras>
#include <QDebug>
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

View File

@ -0,0 +1,123 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "remoteauthasyncimageprovider.h"
#include <QQuickAsyncImageProvider>
#include <QImage>
AsyncImageResponse::AsyncImageResponse(QNetworkRequest req, QSize reqSize)
{
m_reply = m_imageLoader.get(req);
m_requestedSize = reqSize;
connect(m_reply, &QNetworkReply::finished, this, &AsyncImageResponse::onResponseFinished);
}
void AsyncImageResponse::onResponseFinished()
{
QByteArray myImageData = m_reply->readAll();
m_resultImage = QImage::fromData(myImageData);
if (m_requestedSize.isValid())
{
m_resultImage = m_resultImage.scaled(m_requestedSize);
}
emit finished();
}
QQuickTextureFactory *AsyncImageResponse::textureFactory() const
{
return QQuickTextureFactory::textureFactoryForImage(m_resultImage);
}
RemoteAuthAsyncImageProvider::RemoteAuthAsyncImageProvider()
{
}
QQuickImageResponse* RemoteAuthAsyncImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize)
{
QUrl iUrl=url()+"/api/friendica/remoteauth?c_url="+contacturl()+"&url="+id;
QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData;
QNetworkRequest request(iUrl);
request.setRawHeader("Authorization", headerData.toLocal8Bit());
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute,true);
request.setUrl(iUrl);
return new AsyncImageResponse(request, requestedSize);
}
void RemoteAuthAsyncImageProvider::setContacturl(QString contacturl)
{
if (contacturl!=m_contacturl) {
m_contacturl = contacturl;
emit contacturlChanged();
}
}
void RemoteAuthAsyncImageProvider::setUrl(QString url)
{
if (url!=m_url) {
m_url = url;
emit urlChanged();
}
}
void RemoteAuthAsyncImageProvider::setLogin(QString login)
{
if (login!=m_login) {
m_login = login;
emit loginChanged();
}
}
QString RemoteAuthAsyncImageProvider::contacturl() const
{
return m_contacturl;
}
QString RemoteAuthAsyncImageProvider::url() const
{
return m_url;
}
QString RemoteAuthAsyncImageProvider::login() const
{
return m_login;
}

View File

@ -0,0 +1,95 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef REMOTEAUTHIMAGEPROVIDER_H
#define REMOTEAUTHIMAGEPROVIDER_H
#include <QObject>
#include <QQuickAsyncImageProvider>
#include <QImage>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
class AsyncImageResponse : public QQuickImageResponse
{
Q_OBJECT
public:
explicit AsyncImageResponse(QNetworkRequest req, QSize requestedSize);
QQuickTextureFactory *textureFactory() const;
public slots:
void onResponseFinished();
protected:
QNetworkAccessManager m_imageLoader;
QNetworkReply* m_reply;
QSize m_requestedSize;
QImage m_resultImage;
int m_index;
QString m_id;
QImage m_image;
};
class RemoteAuthAsyncImageProvider : public QObject, public QQuickAsyncImageProvider
{
Q_OBJECT
Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(QString contacturl READ contacturl WRITE setContacturl NOTIFY contacturlChanged)
Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged)
public:
explicit RemoteAuthAsyncImageProvider();
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
QString url() const;
QString contacturl() const;
QString login() const;
signals:
void contacturlChanged();
void urlChanged();
void loginChanged();
public slots:
void setContacturl(QString contacturl);
void setUrl(QString url);
void setLogin(QString login);
private:
QByteArray buffer;
QString m_url;
QString m_contacturl;
QString m_login;
QString bufferToString();
};
#endif // REMOTEAUTHIMAGEPROVIDER_H

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "uploadableimage.h" #include "uploadableimage.h"

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef UPLOADABLEIMAGE_H #ifndef UPLOADABLEIMAGE_H
#define UPLOADABLEIMAGE_H #define UPLOADABLEIMAGE_H

View File

@ -1,12 +1,43 @@
#include "xhr.h" // This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "xhr.h"
#include <QHttpPart> #include <QHttpPart>
#include <QTextCodec> #include <QTextCodec>
#include <QUrlQuery> #include <QUrlQuery>
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QList> #include <QList>
#include <QDataStream> #include <QDataStream>
#include <QJsonDocument>
#include <QJsonObject>
#include "uploadableimage.h" #include "uploadableimage.h"
XHR *XHR::instance() XHR *XHR::instance()
@ -44,6 +75,29 @@ void XHR::setFilename(QString filename)
} }
} }
void XHR::setContactlist(QList<QString> contactlist)
{
if (contactlist!=m_contactlist) {
m_contactlist = contactlist;
emit contactlistChanged();
}
}
void XHR::setFilelist(QList<QString> filelist)
{
if (filelist!=m_filelist) {
m_filelist = filelist;
emit filelistChanged();
}
}
void XHR::setImagedir(QString imagedir)
{
if (imagedir!=m_imagedir) {
m_imagedir = imagedir;
emit imagedirChanged();
}
}
void XHR::setDownloadtype(QString downloadtype) void XHR::setDownloadtype(QString downloadtype)
{ {
if (downloadtype!=m_downloadtype) { if (downloadtype!=m_downloadtype) {
@ -67,6 +121,21 @@ QString XHR::filename() const
return m_filename; return m_filename;
} }
QList<QString> XHR::contactlist() const
{
return m_contactlist;
}
QList<QString> XHR::filelist() const
{
return m_filelist;
}
QString XHR::imagedir() const
{
return m_imagedir;
}
QString XHR::downloadtype() const QString XHR::downloadtype() const
{ {
return m_downloadtype; return m_downloadtype;
@ -91,9 +160,14 @@ void XHR::clearParams()
void XHR::download() void XHR::download()
{ {
QUrl requrl(m_url); QUrl requrl(m_url);
if(m_downloadtype=="picturelist"){
QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData;
request.setRawHeader("Authorization", headerData.toLocal8Bit());
}
request.setUrl(requrl); request.setUrl(requrl);
reply = manager.get(request); reply = manager.get(request);
// reply->ignoreSslErrors(); reply->ignoreSslErrors();
connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead); connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead);
//connect(reply,SIGNAL(downloadProgress(qint64,qint64)), this,SLOT(updateDownloadProgress(qint64,qint64))); //connect(reply,SIGNAL(downloadProgress(qint64,qint64)), this,SLOT(updateDownloadProgress(qint64,qint64)));
connect(reply, &QNetworkReply::finished,this, &XHR::onRequestFinished); connect(reply, &QNetworkReply::finished,this, &XHR::onRequestFinished);
@ -117,9 +191,6 @@ void XHR::get()
QByteArray loginData = m_login.toLocal8Bit().toBase64(); QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData; QString headerData = "Basic " + loginData;
request.setRawHeader("Authorization", headerData.toLocal8Bit()); request.setRawHeader("Authorization", headerData.toLocal8Bit());
// QNetworkCookieJar* cJar = new QNetworkCookieJar;
// manager.setCookieJar(cJar);
request.setUrl(requrl); request.setUrl(requrl);
reply = manager.get(request); reply = manager.get(request);
@ -129,6 +200,20 @@ void XHR::get()
connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError); connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError);
} }
void XHR::getlist()
{
if(dlindex < m_filelist.size()) {
QString cleanfilename;
if (m_downloadtype=="contactlist"){cleanfilename = m_contactlist.at(dlindex)+"-"+ m_filelist.at(dlindex).section('/',-1).section('?',0,0);
XHR::setFilename(imagedir()+"contacts/"+cleanfilename);
XHR::setUrl(m_filelist.at(dlindex));}
else {
XHR::setUrl(m_filelist.at(dlindex));}
XHR::download();
} else {dlindex=0;}
}
void XHR::post() void XHR::post()
{ {
qDebug() << "start post to " << m_url; qDebug() << "start post to " << m_url;
@ -178,7 +263,7 @@ void XHR::post()
void XHR::onReplyError(QNetworkReply::NetworkError code) void XHR::onReplyError(QNetworkReply::NetworkError code)
{ {
qDebug() << code; qDebug() << code;
emit this->error( bufferToString(), (int) code); emit this->error( bufferToString(), m_url, (int) code);
buffer.clear(); buffer.clear();
reply->deleteLater(); reply->deleteLater();
} }
@ -194,14 +279,45 @@ void XHR::onReplySuccess()
void XHR::onRequestFinished() void XHR::onRequestFinished()
{ {
// Save the file here // Save the file here
//qDebug() << "buffer downloaded "<<buffer; if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,m_url,1);}
if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,1);} else if (m_downloadtype=="picturelist") {
else {QFile file(m_filename); QJsonDocument jsonResponse = QJsonDocument::fromJson(buffer);
file.open(QIODevice::WriteOnly); QJsonObject jsonObject = jsonResponse.object();
file.write(buffer); int arraystart=buffer.indexOf('{"data":"')+8;
buffer.clear(); int arraylength=buffer.indexOf('"',9)-arraystart;
file.close(); QByteArray b64=buffer.mid(arraystart,arraylength);
emit this->downloaded(m_downloadtype); QString helpfilename=jsonObject["filename"].toString();
QString helpfile=helpfilename.left(helpfilename.lastIndexOf("."));
QString filesuffix="";
if (jsonObject["type"].toString()=="image/jpeg"){filesuffix=".jpg";}
else if (jsonObject["type"].toString()=="image/png"){filesuffix=".png";}
else {filesuffix="";}
if (helpfilename==""){// check if file has any filename
helpfile=jsonObject["id"].toString();
setFilename(imagedir()+"albums/"+jsonObject["album"].toString()+"/"+jsonObject["id"].toString()+filesuffix);
}
else{setFilename(imagedir()+"albums/"+jsonObject["album"].toString()+"/"+helpfile+filesuffix);}
//qDebug()<<"Filename "<<m_filename;
QFile file(m_filename);
file.open(QIODevice::WriteOnly);
file.write(QByteArray::fromBase64(b64));
buffer.clear();
b64.clear();
file.close();
jsonObject["data"]="";
jsonObject["filename"]=helpfile+filesuffix;
emit this->downloadedjson(m_downloadtype,m_url,m_filename,dlindex,jsonObject);
if(downloadtype()=="picturelist"){dlindex=dlindex+1;XHR::getlist();}
}
else {
QFile file(m_filename);
file.open(QIODevice::WriteOnly);
file.write(buffer);
buffer.clear();
file.close();
emit this->downloaded(m_downloadtype,m_url,m_filename,dlindex);
if(downloadtype()=="contactlist"){dlindex=dlindex+1;XHR::getlist();}
//reply->deleteLater(); //reply->deleteLater();
} }
} }
@ -210,15 +326,6 @@ void XHR::onReadyRead()
{ {
qDebug() << "."; qDebug() << ".";
buffer += reply->readAll(); buffer += reply->readAll();
// QList<QNetworkCookie> 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) //void XHR::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes)

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef XHR_H #ifndef XHR_H
#define XHR_H #define XHR_H
@ -5,6 +36,7 @@
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QObject> #include <QObject>
#include <QJsonObject>
class XHR : public QObject class XHR : public QObject
{ {
@ -12,6 +44,9 @@ class XHR : public QObject
Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged) Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged)
Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged) Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
Q_PROPERTY(QString imagedir READ imagedir WRITE setImagedir NOTIFY imagedirChanged)
Q_PROPERTY(QList<QString> contactlist READ contactlist WRITE setContactlist NOTIFY contactlistChanged)
Q_PROPERTY(QList<QString> filelist READ filelist WRITE setFilelist NOTIFY filelistChanged)
Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged) Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged)
@ -23,27 +58,38 @@ public:
QString url() const; QString url() const;
QString login() const; QString login() const;
QString filename() const; QString filename() const;
QList<QString> contactlist() const;
QList<QString> filelist() const;
QString imagedir() const;
QString downloadtype() const; QString downloadtype() const;
signals: signals:
void urlChanged(); void urlChanged();
void loginChanged(); void loginChanged();
void filenameChanged(); void filenameChanged();
void contactlistChanged();
void filelistChanged();
void imagedirChanged();
void downloadtypeChanged(); void downloadtypeChanged();
void downloaded(QString data); void downloaded(QString type, QString url, QString filename, int i);
void downloadedjson(QString type, QString url, QString filename, int i,QJsonObject jsonObject);
void success(QString data); void success(QString data);
void error(QString data, int code); void error(QString data, QString url, int code);
public slots: public slots:
void setUrl(QString url); void setUrl(QString url);
void setLogin(QString login); void setLogin(QString login);
void setDownloadtype(QString downloadtype); void setDownloadtype(QString downloadtype);
void setFilename(QString filename); void setFilename(QString filename);
void setContactlist(QList<QString> filename);
void setFilelist(QList<QString> filename);
void setImagedir(QString filename);
void setParam(QString name, QString value); void setParam(QString name, QString value);
void setImageFileParam(QString name, QString url); void setImageFileParam(QString name, QString url);
void clearParams(); void clearParams();
void post(); void post();
void get(); void get();
void getlist();
void download(); void download();
private slots: private slots:
@ -62,6 +108,10 @@ private:
QString m_downloadtype; QString m_downloadtype;
QHash<QString, QString> params; QHash<QString, QString> params;
QHash<QString, QString> files; QHash<QString, QString> files;
QList<QString> m_filelist;
QList<QString> m_contactlist;
QString m_imagedir;
int dlindex;
QNetworkAccessManager manager; QNetworkAccessManager manager;
QNetworkRequest request; QNetworkRequest request;

View File

@ -10,15 +10,16 @@
# - translation filenames have to be changed # - translation filenames have to be changed
# The name of your application # The name of your application
TEMPLATE = app
TARGET = friendiqa TARGET = friendiqa
CONFIG += debug CONFIG += release
QT += qml quick gui widgets QT += qml quick gui widgets
SOURCES += common/friendiqa.cpp \ SOURCES += common/friendiqa.cpp \
common/uploadableimage.cpp \ common/uploadableimage.cpp \
common/xhr.cpp \ common/xhr.cpp \
common/filesystem.cpp \ common/filesystem.cpp \
common/imagepickerandroid.cpp common/remoteauthasyncimageprovider.cpp
RESOURCES = application.qrc RESOURCES = application.qrc
@ -31,27 +32,22 @@ OTHER_FILES += qml/friendiqa.qml \
qml/configqml/*.qml qml/configqml/*.qml
js/*.js js/*.js
# German translation is enabled as an example. If you aren't TRANSLATIONS += translations/friendiqa-de.ts \
# planning to localize your app, remember to comment out the translations/friendiqa-es.ts \
# following TRANSLATIONS line. And also do not forget to translations/friendiqa-it.ts
# modify the localized app name in the the .desktop file.
TRANSLATIONS += translations/friendiqa-de.ts
HEADERS += \ HEADERS += \
common/uploadableimage.h \ common/uploadableimage.h \
common/xhr.h \ common/xhr.h \
common/filesystem.h \ common/filesystem.h \
common/imagepickerandroid.h common/remoteauthasyncimageprovider.h
DISTFILES += \ DISTFILES += \
qml/calendarqml/*.qml qml/calendarqml/*.qml \
translations/*.ts translations/*.ts \
qml/*.qml translations/*.qm \
qml/newsqml/*.qml qml/*.qml \
qml/contactqml/*.qml qml/newsqml/*.qml \
qml/photoqml/*.qml qml/contactqml/*.qml \
qml/configqml/*.qml qml/photoqml/*.qml \
js/*.js qml/configqml/*.qml \
js/*.js \

View File

@ -1,3 +1,33 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
WorkerScript.onMessage = function(msg) { WorkerScript.onMessage = function(msg) {
msg.model.clear(); msg.model.clear();
for (var j=0;j<msg.albums.length;j++){ for (var j=0;j<msg.albums.length;j++){

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
.pragma library .pragma library
.import QtQuick.LocalStorage 2.0 as Sql .import QtQuick.LocalStorage 2.0 as Sql
@ -64,6 +95,20 @@ function friendicaWebRequest(url,rootwindow,callback) {
xhrequest.send(); xhrequest.send();
} }
function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) {
var xhrequest = new XMLHttpRequest();
xhrequest.onreadystatechange = function() {
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {}
else if(xhrequest.readyState === XMLHttpRequest.DONE) {
try{callback(xhrequest.responseText)}
catch (e){showMessage("Error",url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)}
}
}
xhrequest.open("GET", login.server+"/api/friendica/remoteauth?c_url="+c_url+"&url="+url,true,login.username,Qt.atob(login.password));
xhrequest.send();
}
function readData(database,table,username,callback,filter,filtervalue, sort) { // reads and applies data from DB function readData(database,table,username,callback,filter,filtervalue, sort) { // reads and applies data from DB
if (filter){ if (filter){
var where = " AND "+ filter +" = '" + filtervalue+"'"; var where = " AND "+ filter +" = '" + filtervalue+"'";
@ -107,7 +152,8 @@ 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 cleanmessage=message.replace(/"/g,"-"); //print(cleanmessage);
if(cleanmessage.length>200){cleanmessage=cleanmessage.slice(0,200)+'...'}
var messageString='import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:"'+header+'";standardButtons: StandardButton.Ok; text:" '+cleanmessage+'"}'; 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"); var messageObject=Qt.createQmlObject(messageString,rootwindow,"messageOutput");
} }

272
source-linux/js/image.js Normal file
View File

@ -0,0 +1,272 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
.pragma library
.import QtQuick.LocalStorage 2.0 as Sql
.import "qrc:/js/helper.js" as Helperjs
function requestList(login,database,onlynew,rootwindow,callback) {
//get list of own images and call download function
Helperjs.friendicaRequest(login,"/api/friendica/photos/list", rootwindow,function (helperobject){
//print("return"+helperobject);
var obj=JSON.parse(helperobject);
if (onlynew){Helperjs.readField("id",database,"imageData",login.username,function(AllStoredImages){
if (AllStoredImages.length>0){
for(var i=0;i< AllStoredImages.length;i++){
var position=Helperjs.inArray(obj,"id",AllStoredImages[i]);
if (position>-1){obj.splice(position,1)}
}
}
callback(obj)
})}
else{callback(obj)}
})}
function dataRequest(login,photoID,database,xhr,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.setLogin(login.username+":"+Qt.atob(login.password));
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 storeImagedata(login,database,imagedata,rootwindow) {
// check if image exist and call download function
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 = "'+imagedata["id"]+'"');
if(result.rows.length === 1) {// use update
result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+imagedata.id+'", created="'+imagedata.created+'", edited="'+imagedata.edited+'", profile="'+imagedata.profile+'", link="'+imagedata.link[0]+'", filename="'+imagedata.filename+'",title="'+imagedata.title+'", desc="'+imagedata.desc+'", type="'+imagedata.type+'", width="'+imagedata.width+'", height="'+imagedata.height+'", album="'+imagedata.album+'", location="file://'+login.imagestore+'albums/'+imagedata.album+'/" where id="'+imagedata["id"]+'"');
} else {// use insert print('... does not exists, create it')
result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,imagedata.id,imagedata.created,imagedata.edited, imagedata.title, imagedata.desc, imagedata.album, imagedata.filename, imagedata.type, imagedata.height, imagedata.width,imagedata. profile,imagedata.link[0],'file://'+login.imagestore+'albums/'+imagedata.album+"/"]);
}
})}
function deleteImage(database,login,type,location,filesystem,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) {
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){
// //print(photohtml);
// var photoarray=[];
// var arr = photohtml.split("sidebar-photos-albums-li");
// for (var i=2;i<arr.length;i++){
// var albumlink = arr[i].substring(arr[i].indexOf('http'),arr[i].indexOf('class')-2);
// var albumname=arr[i].substring(arr[i].indexOf('/span')+6,arr[i].indexOf('</a>')-1);
// var album={'link':albumlink,'name':albumname}
// photoarray.push(album);
// }
// callback(photoarray)
// })
//}
function newRequestFriendsAlbumPictures(login,friend,rootwindow,callback){
// screenscraping of albums page of contact with remoteAuth
Helperjs.friendicaRemoteAuthRequest(login,friend.url.replace("profile","photos"),friend.url,rootwindow,function(photohtml){
//print("Photohtml: "+photohtml);
try {var obj=JSON.parse(photohtml);
if (obj.hasOwnProperty('status')){
Helperjs.friendicaWebRequest(friend.url.replace("profile","photos"),rootwindow,function(photohtml){
getAlbumFromHtml(photohtml,false,rootwindow,callback)})
}}
catch (e){
getAlbumFromHtml(photohtml,true,rootwindow,callback)
}
})
}
function getAlbumFromHtml(photohtml,remoteAuthBool,rootwindow,callback){
var photoarray=[];
var arr = photohtml.split("sidebar-photos-albums-li");
for (var i=2;i<arr.length;i++){
var albumlink = arr[i].substring(arr[i].indexOf('http'),arr[i].indexOf('class')-2);
var albumname=arr[i].substring(arr[i].indexOf('/span')+6,arr[i].indexOf('</a>')-1);
var album={'link':albumlink,'name':albumname}//print(albumlink+" "+albumname);
photoarray.push(album);
}
callback(photoarray,remoteAuthBool)
}
function newRequestFriendsPictures(login,link,friend,remoteAuthBool,remoteauth,rootwindow,callback){
// screenscraping of pictures page for given album
if (remoteAuthBool){
remoteauth.setUrl(login.server);
remoteauth.setLogin(login.username+":"+Qt.atob(login.password));
remoteauth.setContacturl(friend.url);
Helperjs.friendicaRemoteAuthRequest(login,link,friend.url,rootwindow,function(photohtml){
getPictureFromHtml(photohtml,remoteAuthBool,function(photoarray){
callback(photoarray)
})
})}
else{
Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){
getPictureFromHtml(photohtml,remoteAuthBool,function(photoarray){
callback(photoarray)
})
})
}
}
function getPictureFromHtml(photohtml,remoteAuthBool,callback){
var photoarray=[];
var basehtml=photohtml.substring(photohtml.indexOf('<base')+12,photohtml.indexOf('/>',photohtml.indexOf('<base'))-2);
// old theme
if (photohtml.indexOf("photo-album-image-wrapper-end")>-1){ //theme 1
var arr = photohtml.split("photo-album-image-wrapper-end");}
// other themes
if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2
var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end"))
var arr = photoarea.split("</a>");}
//print("Url: "+login.server+ "Contacturl: "+friend.url)
// remoteauth.setUrl(login.server);
// remoteauth.setLogin(login.username+":"+Qt.atob(login.password));
// remoteauth.setContacturl(friend.url);
for (var i=0;i<arr.length-1;i++){
var photoname=arr[i].substring(arr[i].lastIndexOf('alt')+5,arr[i].lastIndexOf('title')-2);
var thumblink=arr[i].substring(arr[i].lastIndexOf('<img')+10,arr[i].lastIndexOf('alt')-2);
var imagetype=thumblink.substring(thumblink.lastIndexOf("."));
var photolink=thumblink.substring(0,thumblink.length-imagetype.length-2)+"-0"+imagetype
if(thumblink.substring(0,4)!=="http"){thumblink=basehtml+thumblink}
if(photolink.substring(0,4)!=="http"){photolink=basehtml+photolink}
if(remoteAuthBool){
thumblink="image://remoteauthimage/"+thumblink;
photolink="image://remoteauthimage/"+photolink;
}
//Helperjs.friendicaRemoteAuthRequest(login,thumblink,friend.url,rootwindow,function(thumbimage){thumbbase64=QT.btoa(thumbimage)});
//thumblink="image://remoteauthimage/"+login.username+":"+Qt.atob(login.password)+"@"+login.server+"/api/friendica/remoteauth?c_url="+friend.url+"&url="+thumblink;
var photo={'link':photolink,'name':photoname,'thumb':thumblink}
photoarray.push(photo);
}
callback(photoarray)
}
function requestFriendsPictures(link,rootwindow,callback){
// screenscraping of pictures page for given album
Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){
var photoarray=[];
var basehtml=photohtml.substring(photohtml.indexOf('<base')+12,photohtml.indexOf('/>',photohtml.indexOf('<base'))-2);
// old theme
if (photohtml.indexOf("photo-album-image-wrapper-end")>-1){ //theme 1
var arr = photohtml.split("photo-album-image-wrapper-end");}
// other themes
if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2
var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end"))
var arr = photoarea.split("</a>");}
for (var i=0;i<arr.length-1;i++){
var photoname=arr[i].substring(arr[i].lastIndexOf('alt')+5,arr[i].lastIndexOf('title')-2);
var thumblink=arr[i].substring(arr[i].lastIndexOf('<img')+10,arr[i].lastIndexOf('alt')-2);
var imagetype=thumblink.substring(thumblink.lastIndexOf("."));
var photolink=thumblink.substring(0,thumblink.length-imagetype.length-2)+"-0"+imagetype
if(thumblink.substring(0,4)!=="http"){thumblink=basehtml+thumblink}
if(photolink.substring(0,4)!=="http"){photolink=basehtml+photolink}
var photo={'link':photolink,'name':photoname,'thumb':thumblink}
photoarray.push(photo);
}
callback(photoarray)
})
}

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
function showFriends(db) { function showFriends(db) {
Service.readActiveConfig(db,function(login){ Service.readActiveConfig(db,function(login){
Service.requestFriends(login.url,login.user,login.password,displayFriends); Service.requestFriends(login.url,login.user,login.password,displayFriends);

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
.pragma library .pragma library
.import QtQuick.LocalStorage 2.0 as Sql .import QtQuick.LocalStorage 2.0 as Sql
.import "qrc:/js/helper.js" as Helperjs .import "qrc:/js/helper.js" as Helperjs
@ -10,14 +41,18 @@ function requestFriends(login,database,rootwindow,callback){
Helperjs.friendicaRequest(login,"/api/statuses/friends", rootwindow,function (obj){ Helperjs.friendicaRequest(login,"/api/statuses/friends", rootwindow,function (obj){
var friends=JSON.parse(obj); var friends=JSON.parse(obj);
for (var i=0;i<friends.length;i++){ friends[i].isFriend=1} for (var i=0;i<friends.length;i++){ friends[i].isFriend=1}
callback(friends) //try{requestProfile(login,friends,rootwindow,function(friends_profile){callback(friends_profile)})}
//catch(e){
callback(friends)//}
}); });
} }
function requestGroups(login,database,rootwindow,callback){ function requestGroups(login,database,rootwindow,callback){
// retrieve, save and return groups. Other features currently not implemented // retrieve, save and return groups. Other features currently not implemented
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
Helperjs.friendicaRequest(login,"/api/friendica/group_show",rootwindow, function (obj){print(obj); Helperjs.friendicaRequest(login,"/api/friendica/group_show",rootwindow, function (obj){
var groups=JSON.parse(obj); var groups=JSON.parse(obj);
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('DELETE from groups where username="'+login.username+'"'); // clean old groups var result = tx.executeSql('DELETE from groups where username="'+login.username+'"'); // clean old groups
@ -32,7 +67,7 @@ function requestGroups(login,database,rootwindow,callback){
function listFriends(login,database,callback){ function listFriends(login,database,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=1'); // check for friends var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'); // check for friends
var contactlist=[]; var contactlist=[];
for (var i=0;i<result.rows.length;i++){ for (var i=0;i<result.rows.length;i++){
contactlist.push(result.rows.item(i)) contactlist.push(result.rows.item(i))
@ -61,7 +96,7 @@ function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback)
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); // check for last news id var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); // check for last news id
try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})} try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})}
var newContacts=[]; var newContacts=[];
Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){print(obj); Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){
var news=JSON.parse(obj); var news=JSON.parse(obj);
var newContacts=findNewContacts(news,contacts); var newContacts=findNewContacts(news,contacts);
callback(news,newContacts) callback(news,newContacts)
@ -86,7 +121,7 @@ function getCurrentContacts(login,database,callback){
callback(contactlist) callback(contactlist)
} }
function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(news)) function findNewContacts(news,contacts){
var newContacts=[]; var newContacts=[];
for (var i=0;i<news.length;i++){ for (var i=0;i<news.length;i++){
var url=news[i].user.url; var url=news[i].user.url;
@ -112,11 +147,12 @@ function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(news
} }
} }
} }
// var owner_id=parseInt(news[i].friendica_owner.id);
// if(contacts.indexOf(owner_id)==-1 && !(inArray(newContacts,"id",owner_id))){ var owner_url=news[i].friendica_owner.url;
// news[i].friendica_owner.isFriend=0; if(contacts.indexOf(owner_url)==-1 && !(inArray(newContacts,"url",owner_url))){
// newContacts.push(news[i].friendica_owner); news[i].friendica_owner.isFriend=0;
// } newContacts.push(news[i].friendica_owner);
}
} }
return newContacts return newContacts
} }
@ -165,8 +201,9 @@ function getDirectMessage(login,database,rootwindow,callback){
}); });
} }
}) })
if(login.newsViewType=="Timeline"){newsfromdb(database,login.username,callback)} callback()
else{chatsfromdb(database,login.username,callback)} // if(login.newsViewType=="Timeline"){newsfromdb(database,login.username,callback)}
// else{chatsfromdb(database,login.username,callback)}
} }
function getNotifications(login,database,rootwindow,callback){ function getNotifications(login,database,rootwindow,callback){
@ -194,12 +231,14 @@ function getNotifications(login,database,rootwindow,callback){
}) })
})} })}
function getActivitiesUserData(database,username,userUrlArray){//print(JSON.stringify(userUrlArray)); function getActivitiesUserData(database,username,allcontacts,userUrlArray){//print(JSON.stringify(userUrlArray));
var helpArray=[]; var helpArray=[];
for (var i=0;i<userUrlArray.length;i++){ for (var i=0;i<userUrlArray.length;i++){
Helperjs.readData(database,"contacts",username,function(userdata){ helpArray.push(objFromArray(allcontacts,"url",userUrlArray[i]));
helpArray.push(userdata[0]); // Helperjs.readData(database,"contacts",username,function(userdata){
},"url",userUrlArray[i]); // helpArray.push(userdata[0]);
// },"url",userUrlArray[i]);
} }
return helpArray return helpArray
} }
@ -212,42 +251,47 @@ function newsfromdb(database,username,callback,contact,stop_time){
try{var rs = tx.executeSql('select created_at from news WHERE username="'+username+'" ORDER BY created_at DESC LIMIT 1'); try{var rs = tx.executeSql('select created_at from news WHERE username="'+username+'" ORDER BY created_at DESC LIMIT 1');
stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}} stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
else{var stop="<"+stop_time} else{var stop="<"+stop_time}
var contactfilter="";if(contact){contactfilter=" AND uid='"+contact+"'"} var contactfilter="";if(contact){contactfilter=" AND (uid='"+contact+"' OR friendica_owner='"+contact+"')"}
//print('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20'); //print('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
var newsrs=tx.executeSql('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20'); var newsrs=tx.executeSql('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
var newsArray=[]; var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",username,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; i++) { for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i)); newsArray.push(newsrs.rows.item(i));
newsArray[i]=fetchUsersForNews(database,username,newsArray[i]) newsArray[i]=fetchUsersForNews(database,username,newsArray[i],allcontacts)
} }
callback(newsArray)}); callback(newsArray)});
} }
function fetchUsersForNews(database,username,news){//print(JSON.stringify(news)) function fetchUsersForNews(database,username,news,allcontacts){//print(JSON.stringify(news))
Helperjs.readData(database,"contacts",username,function(userdata){ news.user=objFromArray(allcontacts,"id",news.uid);
news.user=userdata[0]; if(news.in_reply_to_user_id){news.reply_user=objFromArray(allcontacts,"id",news.in_reply_to_user_id)}
//print("Fetch user"+JSON.stringify(news.user)); news.friendica_owner_object=objFromArray(allcontacts,"url",news.friendica_owner);
},"id",news.uid); // Helperjs.readData(database,"contacts",username,function(userdata){
if(news.in_reply_to_user_id){ // news.user=userdata[0];
Helperjs.readData(database,"contacts",username,function(replytodata){ // //print("Fetch user"+JSON.stringify(news.user));
news.reply_user=replytodata[0]; // },"id",news.uid);
//print("Fetch reply to"+JSON.stringify(news.reply_user)); // if(news.in_reply_to_user_id){
},"id",news.in_reply_to_user_id); // Helperjs.readData(database,"contacts",username,function(replytodata){
} // news.reply_user=replytodata[0];
// //print("Fetch reply to"+JSON.stringify(news.reply_user));
// },"id",news.in_reply_to_user_id);
// }
if (news.messagetype==0){ if (news.messagetype==0){
for(var j=0;j<news.friendica_activities.length;j++) for(var j=0;j<news.friendica_activities.length;j++)
{var friendicaArray=JSON.parse(Qt.atob(news.friendica_activities)); {var friendicaArray=JSON.parse(Qt.atob(news.friendica_activities));
// print("Array: "+friendicaArray[1]); // print("Array: "+friendicaArray[1]);
news.like=getActivitiesUserData(database,username,friendicaArray[0]); news.like=getActivitiesUserData(database,username,allcontacts,friendicaArray[0]);
news.dislike=getActivitiesUserData(database,username,friendicaArray[1]); news.dislike=getActivitiesUserData(database,username,allcontacts,friendicaArray[1]);
news.attendyes=getActivitiesUserData(database,username,friendicaArray[2]); news.attendyes=getActivitiesUserData(database,username,allcontacts,friendicaArray[2]);
news.attendno=getActivitiesUserData(database,username,friendicaArray[3]); news.attendno=getActivitiesUserData(database,username,allcontacts,friendicaArray[3]);
news.attendmaybe=getActivitiesUserData(database,username,friendicaArray[4]); news.attendmaybe=getActivitiesUserData(database,username,allcontacts,friendicaArray[4]);
} }
Helperjs.readData(database,"contacts",username,function(friendica_owner_data){ // Helperjs.readData(database,"contacts",username,function(friendica_owner_data){
news.friendica_owner_object=friendica_owner_data[0]; // news.friendica_owner_object=friendica_owner_data[0];
//print("Fetch friendica_owner"+JSON.stringify(news.friendica_owner)); // //print("Fetch friendica_owner"+JSON.stringify(news.friendica_owner));
},"url",news.friendica_owner); // },"url",news.friendica_owner);
} }
return news return news
} }
@ -265,19 +309,19 @@ function deleteNews(login,database,newsid,messagetype,rootwindow,callback){
})} })}
function retweetNews(login,database,newsid,rootwindow,callback){ function retweetNews(login,database,newsid,rootwindow,callback){
Helperjs.friendicaPostRequest(login,"/api/statuses/retweet?id="+newsid,"","POST", rootwindow,function (obj){ Helperjs.friendicaPostRequest(login,"/api/statuses/retweet?id="+newsid,"","POST", rootwindow,function (obj){
var answer=JSON.parse(obj); var answer=JSON.parse(obj);
if(answer.status.error){Helperjs.showMessage("Repost",answer.status.code,rootwindow);} if(answer.hasOwnProperty('status'))//('error' in answer.status)
else{Helperjs.showMessage("Repost",obj,rootwindow)} {Helperjs.showMessage("Repost",answer.status.code,rootwindow);}
})} else{Helperjs.showMessage("Repost",answer.text,rootwindow)}
})
}
function favorite(login,favorite,newsid,rootwindow){ function favorite(login,favorite,newsid,rootwindow){
// toggle favorites // toggle favorites
if(favorite){ Helperjs.friendicaPostRequest(login,"/api/favorites/create?id="+newsid,"","POST", rootwindow,function (obj){ if(favorite){ Helperjs.friendicaPostRequest(login,"/api/favorites/create?id="+newsid,"","POST", rootwindow,function (obj){
print("Favorite "+obj);
})} })}
else {Helperjs.friendicaPostRequest(login,"/api/favorites/destroy?id="+newsid, "POST",rootwindow,function (obj){ else {Helperjs.friendicaPostRequest(login,"/api/favorites/destroy?id="+newsid, "POST",rootwindow,function (obj){
print("Favorite destroyed "+obj);
})} })}
} }
@ -300,7 +344,7 @@ function likerequest(login,database,verb,newsid,rootwindow){
//print(JSON.stringify(currentActivities)); //print(JSON.stringify(currentActivities));
var result = tx.executeSql('UPDATE news SET friendica_activities_self ="'+JSON.stringify(currentActivities)+'" where username="'+login.username+'" AND status_id ='+newsid); var result = tx.executeSql('UPDATE news SET friendica_activities_self ="'+JSON.stringify(currentActivities)+'" where username="'+login.username+'" AND status_id ='+newsid);
})} })}
else{print("likerequest"+obj)}}) else{}})
} }
function like(login,database,toggle,verb,newsid,rootwindow){ function like(login,database,toggle,verb,newsid,rootwindow){
@ -352,13 +396,16 @@ function requestConversation(login,database,newsid,contacts,rootwindow,callback)
function conversationfromdb(database,user,conversationId,callback){ function conversationfromdb(database,user,conversationId,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversationId+'" ORDER BY created_at ASC'); var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversationId+'" ORDER BY created_at ASC');
var newsArray=[]; var newsArray=[];
for(var i = 0; i < newsrs.rows.length; i++) { var allcontacts=[];
newsArray.push(newsrs.rows.item(i)); Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
newsArray[i]=fetchUsersForNews(database,user,newsArray[i]) for(var i = 0; i < newsrs.rows.length; i++) {
} newsArray.push(newsrs.rows.item(i));
callback(newsArray);} )} newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts)
}
callback(newsArray)})
}
function requestFavorites(login,database,contacts,rootwindow,callback){ function requestFavorites(login,database,contacts,rootwindow,callback){
Helperjs.friendicaRequest(login,"/api/favorites",rootwindow, function (obj){ Helperjs.friendicaRequest(login,"/api/favorites",rootwindow, function (obj){
@ -375,9 +422,11 @@ function favoritesfromdb(database,user,callback){
//print('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC'); //print('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC'); var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsArray=[]; var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; i++) { for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i)); newsArray.push(newsrs.rows.item(i));
newsArray[i]=fetchUsersForNews(database,user,newsArray[i]); newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts);
callback(newsArray); callback(newsArray);
}})} }})}
@ -394,11 +443,13 @@ function chatsfromdb(database,user,callback,stop_time){
conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id); conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id);
} }
var newsArray=[]; var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
for(var j = 0; j< conversations.length; j++) { for(var j = 0; j< conversations.length; j++) {
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversations[j] +'" ORDER BY created_at ASC'); var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversations[j] +'" ORDER BY created_at ASC');
var helpernews=newsrs.rows.item(0); var helpernews=newsrs.rows.item(0);
helpernews.newscount=newsrs.rows.length; helpernews.newscount=newsrs.rows.length;
helpernews=fetchUsersForNews(database,user,helpernews); helpernews=fetchUsersForNews(database,user,helpernews,allcontacts);
//var chatArray=[]; //var chatArray=[];
// for (var k=0;k<newsrs.rows.length;k++){ // for (var k=0;k<newsrs.rows.length;k++){
// var helperchat=newsrs.rows.item(k); // var helperchat=newsrs.rows.item(k);
@ -420,7 +471,16 @@ function inArray(list, prop, val) {
} return false; } return false;
} }
function cleanDate(date){ function objFromArray(list, prop, val) {
var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25); if (list.length > 0 ) {
return cleanedDate for (var i in list) {if (list[i][prop] == val) {
return list[i];
}
}
} return false;
}
function cleanDate(date){
var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25);
return cleanedDate
} }

View File

@ -1,5 +1,36 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
WorkerScript.onMessage = function(msg) { WorkerScript.onMessage = function(msg) {
if(msg.deleteId) if(msg.deleteId!==undefined)
{msg.model.remove(msg.deleteId); {msg.model.remove(msg.deleteId);
msg.model.sync() msg.model.sync()
} }
@ -16,9 +47,12 @@ else{
newsitemobject.user.profile_image_url=""; newsitemobject.user.profile_image_url="";
newsitemobject.user.name=""; newsitemobject.user.name="";
} }
var forumname="";if (newsitemobject.messagetype==0&&((newsitemobject.friendica_owner)!=(newsitemobject.user.url))){forumname=" via "+Qt.atob(newsitemobject.friendica_owner_object.name)} var forumname="";try{if (newsitemobject.messagetype==0&&((newsitemobject.friendica_owner)!=(newsitemobject.user.url))){
//print(newsitemobject.friendica_owner+" Friendica Owner "+JSON.stringify(newsitemobject));
forumname=" via "+Qt.atob(newsitemobject.friendica_owner_object.name)
}}catch(e){print("forum name "+e)}
var likeText="";var dislikeText="";var attendyesText="";var attendnoText="";var attendmaybeText=""; var self={}; var likeText="";var dislikeText="";var attendyesText="";var attendnoText="";var attendmaybeText=""; var self={};
if (newsitemobject.messagetype==0){ try{if (newsitemobject.messagetype==0){
if (newsitemobject.like.length>0){ if (newsitemobject.like.length>0){
if (newsitemobject.like.length==1){likeText= Qt.atob(newsitemobject.like[0].name)+" "+ qsTr("likes this.")} if (newsitemobject.like.length==1){likeText= Qt.atob(newsitemobject.like[0].name)+" "+ qsTr("likes this.")}
else {likeText= newsitemobject.like.length+" "+ qsTr("like this.")} else {likeText= newsitemobject.like.length+" "+ qsTr("like this.")}
@ -45,16 +79,16 @@ else{
if (newsitemobject.friendica_activities_self.indexOf(5)!=-1){self.attending=qsTr("maybe")} 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(1)!=-1){self.liked=1}
if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1} if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1}
} }} catch(e){print("Activities "+e)}
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 attachmentList=[];try{if(newsitemobject.attachments){
var attachArray=JSON.parse(Qt.atob(newsitemobject.attachments)); var attachArray=JSON.parse(Qt.atob(newsitemobject.attachments));
for (var image in attachArray){if(attachArray[image].mimetype=="image/gif"){ for (var image in attachArray){if(attachArray[image].mimetype=="image/gif"){
attachmentList.push(attachArray[image]) attachmentList.push(attachArray[image])
} }
} }
} }}catch(e){print("attachment "+e)}
newsitemobject.attachmentList=attachmentList; newsitemobject.attachmentList=attachmentList;
var seconds=(msg.currentTime-newsitemobject.created_at)/1000; var seconds=(msg.currentTime-newsitemobject.created_at)/1000;
var timestring=""; var timestring="";

View File

@ -1,5 +1,37 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
WorkerScript.onMessage = function(msg) { WorkerScript.onMessage = function(msg) {
if (msg.firstalbum==0){msg.model.clear();} if (msg.firstalbum==0){msg.model.clear();}
var contact={}; try{contact=msg.friend}catch(e){print(e)}
var limit=0; if (msg.albums.length-msg.firstalbum<20){limit=msg.albums.length} else{limit=msg.firstalbum+20} var limit=0; if (msg.albums.length-msg.firstalbum<20){limit=msg.albums.length} else{limit=msg.firstalbum+20}
for (var j=msg.firstalbum;j<limit;j++){ for (var j=msg.firstalbum;j<limit;j++){
if (msg.albums[msg.firstalbum]) { if (msg.albums[msg.firstalbum]) {
@ -8,7 +40,7 @@ WorkerScript.onMessage = function(msg) {
var albumname=msg.albums[j].name.trim();var albumlink=msg.albums[j].link var albumname=msg.albums[j].name.trim();var albumlink=msg.albums[j].link
}else{ }else{
var albumname=msg.albums[j].toString();var albumlink=""} var albumname=msg.albums[j].toString();var albumlink=""}
msg.model.append({"albumlink":albumlink,"foreignPicture":msg.foreignPicture,"albumname":albumname}); msg.model.append({"albumlink":albumlink,"foreignPicture":msg.foreignPicture,"albumname":albumname,"friend":contact});
msg.model.sync() msg.model.sync()
}; };
} }

View File

@ -1,166 +1,53 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//.pragma library //.pragma library
.import QtQuick.LocalStorage 2.0 as Sql .import QtQuick.LocalStorage 2.0 as Sql
.import "qrc:/js/helper.js" as Helperjs .import "qrc:/js/helper.js" as Helperjs
.import "qrc:/js/news.js" as Newsjs .import "qrc:/js/news.js" as Newsjs
// IMAGE FUNCTIONS
function requestList(login,database,rootwindow,callback) {
//get list of own images and call download function
Helperjs.friendicaRequest(login,"/api/friendica/photos/list", rootwindow,function (helperobject){
//print("return"+helperobject);
var obj=JSON.parse(helperobject);
Helperjs.readField("id",database,"imageData",login.username,function(AllStoredImages){
if (AllStoredImages.length>0){
for(var i=0;i< AllStoredImages.length;i++){
var position=Helperjs.inArray(obj,"resourceID",AllStoredImages[i]);
if (position>-1){obj.splice(position,1)}
//obj.splice(obj.indexOf(AllStoredImages[i]),1);// list of objects instead of list!!!
}}
callback(obj)
})
})}
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+"/"]);
}
})}}
catch (e){print("Data retrieval failure! "+ e+obj);}
})}
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) {
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){
//print(photohtml);
var photoarray=[];
var arr = photohtml.split("sidebar-photos-albums-li");
for (var i=2;i<arr.length;i++){
var albumlink = arr[i].substring(arr[i].indexOf('http'),arr[i].indexOf('class')-2);
var albumname=arr[i].substring(arr[i].indexOf('/span')+6,arr[i].indexOf('</a>')-1);
var album={'link':albumlink,'name':albumname}
photoarray.push(album);
}
callback(photoarray)
})
}
function requestFriendsPictures(link,rootwindow,callback){
// screenscraping of pictures page for given album
Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){
var photoarray=[];
var basehtml=photohtml.substring(photohtml.indexOf('<base')+12,photohtml.indexOf('/>',photohtml.indexOf('<base'))-2);
// old theme
if (photohtml.indexOf("photo-album-image-wrapper-end")>-1){ //theme 1
var arr = photohtml.split("photo-album-image-wrapper-end");}
// other themes
if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2
var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end"))
var arr = photoarea.split("</a>");}
for (var i=0;i<arr.length-1;i++){
var photoname=arr[i].substring(arr[i].lastIndexOf('alt')+5,arr[i].lastIndexOf('title')-2);
var thumblink=arr[i].substring(arr[i].lastIndexOf('<img')+10,arr[i].lastIndexOf('alt')-2);
var imagetype=thumblink.substring(thumblink.lastIndexOf("."));
var photolink=thumblink.substring(0,thumblink.length-imagetype.length-2)+"-0"+imagetype
if(thumblink.substring(0,4)!=="http"){thumblink=basehtml+thumblink}
if(photolink.substring(0,4)!=="http"){photolink=basehtml+photolink}
var photo={'link':photolink,'name':photoname,'thumb':thumblink}
photoarray.push(photo);
}
callback(photoarray)
})
}
// CONFIG FUNCTIONS // CONFIG FUNCTIONS
function initDatabase(database) { // initialize the database object function initDatabase(database) { // initialize the database object
var db =Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db =Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
print('initDatabase()'+database[0]+database[1]+database[2]+database[3]) print('initDatabase()'+database[0]+database[1]+database[2]+database[3])
db.transaction( function(tx) { db.transaction( function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(username TEXT,id INT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, profile INT, link TEXT,location TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(username TEXT,id INT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, profile INT, link TEXT,location TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT, imagestore TEXT, maxnews INT, timerInterval INT, newsViewType TEXT,isActive INT, permissions TEXT,maxContactAge INT,APIVersion TEXT,layout TEXT, addons TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT, imagestore TEXT, maxnews INT, timerInterval INT, newsViewType TEXT,isActive INT, permissions TEXT,maxContactAge INT,APIVersion TEXT,layout TEXT, addons TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner INT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT, timestamp INT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT, timestamp INT)');
// tx.executeSql('CREATE INDEX IF NOT EXISTS contact_id ON contacts(id)');
tx.executeSql('CREATE TABLE IF NOT EXISTS profiles(username TEXT, id INT, profiledata TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS events(username TEXT, id INT, start INT, end INT, allday INT, title TEXT, j INT, d TEXT, isFirst INT, uid INT, cid INT, uri TEXT, created INT, edited INT, desc TEXT, location TEXT, type TEXT, nofinish TEXT, adjust INT, ignore INT, permissions TEXT, guid INT, itemid INT, plink TEXT, authorName TEXT, authorAvatar TEXT, authorLink TEXT, html TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS events(username TEXT, id INT, start INT, end INT, allday INT, title TEXT, j INT, d TEXT, isFirst INT, uid INT, cid INT, uri TEXT, created INT, edited INT, desc TEXT, location TEXT, type TEXT, nofinish TEXT, adjust INT, ignore INT, permissions TEXT, guid INT, itemid INT, plink TEXT, authorName TEXT, authorAvatar TEXT, authorLink TEXT, html TEXT)');
})} })}
function cleanPermissions(oldperms){ function cleanPermissions(oldperms){
@ -172,6 +59,7 @@ return (newpermArray)
function getEvents(database,login,rootwindow,callback){ function getEvents(database,login,rootwindow,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
Helperjs.friendicaWebRequest(login.server+"/cal/"+login.username+"/json",rootwindow,function(obj){ Helperjs.friendicaWebRequest(login.server+"/cal/"+login.username+"/json",rootwindow,function(obj){
//Helperjs.friendicaRemoteAuthRequest(login,login.server+"/cal/"+login.username+"/json",login.server+"/profile/"+login.username,rootwindow,function(obj){
var events = JSON.parse(obj); var events = JSON.parse(obj);
db.transaction( function(tx) { db.transaction( function(tx) {
for (var i=0;i<events.length;i++){ for (var i=0;i<events.length;i++){
@ -247,6 +135,48 @@ function requestFriendsEvents(login,friend,rootwindow,callback){
}) })
} }
function newRequestFriendsEvents(login,friend,rootwindow,callback){
// get calendar JSON object of contact with remoteAuth or without user and password
if(friend.isFriend==1){
Helperjs.friendicaRemoteAuthRequest(login,friend.url.replace("profile","cal")+"/json",friend.url,rootwindow,function(calhtml){
getEventsFromHtml(calhtml,rootwindow,callback)})
}
else{
Helperjs.friendicaWebRequest(friend.url.replace("profile","cal")+"/json",rootwindow,function(calhtml){
getEventsFromHtml(calhtml,rootwindow,callback)})
}
}
function getEventsFromHtml(calhtml,rootwindow,callback){
var eventarray=[];var eventdays=[];
var events=JSON.parse(calhtml);
for (var i=0;i<events.length;i++){
var permissions=[];
permissions.push(cleanPermissions(events[i].item.allow_cid));
permissions.push(cleanPermissions(events[i].item.allow_gid));
permissions.push(cleanPermissions(events[i].item.deny_cid));
permissions.push(cleanPermissions(events[i].item.deny_gid));
var event ={}
event.start=Date.parse(events[i].start);event.end=Date.parse(events[i].end);
event.allday=events[i].allday; event.title=events[i].title; event.j=events[i].j;
event.d=events[i].d; event.isFirst=events[i].isFirst; event.uid=events[i].item.uid;
event.cid=events[i].item.cid; event.uri=events[i].item.uri;
event.created=Date.parse(events[i].item.created); event.edited=Date.parse(events[i].item.edited);
event.desc=events[i].item.desc; event.location=events[i].item.location; event.type=events[i].item.type;
event.nofinish=events[i].item.nofinish; event.adjust =events[i].item.adjust; event.ignore=events[i].item.ignore;
event.permissions=JSON.stringify(permissions); event.guid=events[i].item.guid;
event.itemid=events[i].item.itemid; event.plink=events[i].plink; event.authorName=events[i].item["author-name"];
event.authorAvatar=events[i].item["author-avatar"]; event. authorLink=events[i].item["author-link"];
event.html=Qt.btoa(events[i].html);
eventarray.push(event);
// var offsetTime = new Date().getTimezoneOffset() * 60 * 1000;print(new Date(event.start).toLocaleString()+"Zeitverschiebung:"+offsetTime)
// var time = event.start - offsetTime;
eventdays.push(Math.floor(event.start/(24*60*60*1000)))
}
//print(JSON.stringify(eventarray));
callback(eventarray,eventdays)
}
function savePermissions(database,obj) { // stores config to DB function savePermissions(database,obj) { // stores config to DB
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
@ -283,6 +213,36 @@ Helperjs.friendicaWebRequest(url+"/api/statusnet/config",rootwindow, function (o
callback(serverConfigString) callback(serverConfigString)
})} })}
function checkLogin(login,rootwindow,callback){
// check server with given credentials
try {Helperjs.friendicaRequest(login,"/api/account/verify_credentials",rootwindow, function (obj){
var account = JSON.parse(obj);
callback(account)
})}
catch(e){}
}
function requestProfile(login,database,rootwindow,callback){
// return profile data
Helperjs.friendicaRequest(login,"/api/friendica/profile/show", rootwindow,function (obj){
var profiledata=JSON.parse(obj);
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
for (var i=0;i<profiledata.profiles.length;i++){
//print('store profile data for '+JSON.stringify(profiledata.profiles[i]));
db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from profiles where username="'+login.username+'" AND id = '+profiledata.profiles[i].profile_id); // check for profile id
if(result.rows.length === 1) {// use update
result = tx.executeSql('UPDATE profiles SET profiledata="'+ Qt.btoa(JSON.stringify(profiledata.profiles[i]))+'" WHERE username="'+login.username+'" AND id='+parseInt(profiledata.profiles[i].profile_id));
} else {// use insert
result = tx.executeSql('INSERT INTO profiles (username,id,profiledata) VALUES (?,?,?)', [login.username,profiledata.profiles[i].profile_id,Qt.btoa(JSON.stringify(profiledata.profiles[i]))])}
});
}
var profile=profiledata.friendica_owner;
profile.isFriend=2;
var profilearray=[];profilearray.push(profile);
callback(profilearray)
});
}
function getServerConfig(database,login,rootwindow,callback){ function getServerConfig(database,login,rootwindow,callback){
// check server with given credentials // check server with given credentials
@ -298,14 +258,15 @@ try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, functio
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('UPDATE config SET APIVersion="'+ serverconfig.site.friendica.FRIENDICA_VERSION+'" WHERE username="'+login.username +'"')}) var result = tx.executeSql('UPDATE config SET APIVersion="'+ serverconfig.site.friendica.FRIENDICA_VERSION+'" WHERE username="'+login.username +'"')})
Helperjs.friendicaRequest(login,"/friendica/json",rootwindow, function (obj){ // Helperjs.friendicaRequest(login,"/friendica/json",rootwindow, function (obj){
var serverData = JSON.parse(obj);var serverAddons=JSON.stringify(serverData.plugins).replace(/"/g,""); // var serverData = JSON.parse(obj);var serverAddons=JSON.stringify(serverData.plugins).replace(/"/g,"");
db.transaction( function(tx) { // db.transaction( function(tx) {
var result = tx.executeSql('UPDATE config SET addons="'+ serverAddons+'" WHERE username="'+login.username +'"')}) // var result = tx.executeSql('UPDATE config SET addons="'+ serverAddons+'" WHERE username="'+login.username +'"')})
callback(serverconfigString); // })
})})} callback(serverconfigString);
catch (e){callback (e); })}
catch (e){callback (e);
}} }}
function readConfig(database,callback,filter,filtervalue) { // reads config function readConfig(database,callback,filter,filtervalue) { // reads config
@ -337,8 +298,13 @@ function deleteConfig(database,userobj,callback) { // delete user data from DB
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
if(!db) { return; } if(!db) { return; }
db.transaction( function(tx) { db.transaction( function(tx) {
var rs = tx.executeSql('delete from config'+where); var rs1 = tx.executeSql('delete from config'+where);
callback(rs); var rs2 = tx.executeSql("delete from news WHERE username='"+ userobj.username+"'");
var rs3 = tx.executeSql("delete from contacts WHERE username='"+ userobj.username+"'");
var rs4 = tx.executeSql("delete from imageData WHERE username='"+ userobj.username+"'");
var rs5 = tx.executeSql("delete from groups WHERE username='"+ userobj.username+"'");
var rs5 = tx.executeSql("delete from events WHERE username='"+ userobj.username+"'");
callback();
}) })
} }
@ -362,7 +328,7 @@ function cleanContacts(login,database,callback){
db.transaction( function(tx) { db.transaction( function(tx) {
var oldestnewsrs= tx.executeSql('SELECT created_at FROM news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY created_at ASC LIMIT 1'); var oldestnewsrs= tx.executeSql('SELECT created_at FROM news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY created_at ASC LIMIT 1');
var oldestnewsTime=oldestnewsrs.rows.item(0).created_at- 604800000; //contacts can be 7 days old var oldestnewsTime=oldestnewsrs.rows.item(0).created_at- 604800000; //contacts can be 7 days old
print(login.username+" älteste news: "+ oldestnewsTime); //print(login.username+" älteste news: "+ oldestnewsTime);
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge<'+oldestnewsTime); // check for friends var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge<'+oldestnewsTime); // check for friends
for (var i=0;i<result.rows.length;i++){ for (var i=0;i<result.rows.length;i++){
filesystem.rmFile(result.rows.item(i).profile_image); filesystem.rmFile(result.rows.item(i).profile_image);
@ -373,16 +339,22 @@ function cleanContacts(login,database,callback){
} }
function processNews(callback){ function processNews(callback){
// Newsjs.getCurrentContacts(login,db,function(contacts){
// contactlist=contacts});
if (contactLoadType=="news"){ if (contactLoadType=="news"){
if(root.news.length==0){} if(root.news.length==0){}
else{// show news else{// show news
Newsjs.storeNews(login,db,news,root,function(dbnews){ Newsjs.storeNews(login,db,news,root,function(dbnews){
root.newsSignal(dbnews); if(login.newsViewType=="Timeline"){
newstab.newstabstatus=login.newsViewType Newsjs.newsfromdb(db,login.username,function(dbnews){
})} root.newsSignal(dbnews);
newstab.newstabstatus=login.newsViewType})
}
else{
Newsjs.chatsfromdb(db,login.username,function(dbnews){
root.newsSignal(dbnews);
newstab.newstabstatus=login.newsViewType})
}
})
}
} }
else if (contactLoadType=="friends"){// show friends else if (contactLoadType=="friends"){// show friends
root.friendsSignal(login.username); root.friendsSignal(login.username);
@ -411,37 +383,18 @@ function processNews(callback){
} }
function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab
// var suffix=contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("."), contact.profile_image_url.length);
// var imagename=login.imagestore+"contacts/"+contact.screen_name.trim()+suffix;
var imagename="";
contacttimer.restart();
var currentTime=Date.now(); var currentTime=Date.now();
var image_timestamp=0; var image_timestamp=0;
if(contact.profile_image_url==""){root.currentContact=root.currentContact+1 }
else{//print(JSON.stringify(contact))
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var currentts=0;
var currenttsrs= tx.executeSql('SELECT timestamp FROM contacts WHERE username="'+login.username+'" AND url="'+contact.url+'"');
try{currentts=currenttsrs.rows.item(0).timestamp}catch(e){}
var imagename_helper=[]; var imagename_helper=[];
imagename_helper=contact.profile_image_url.split('?');//print("substring: "+JSON.stringify(imagename_helper)+imagename_helper[0].substring(imagename_helper[0].lastIndexOf("/")+1, imagename_helper[0].length)) imagename_helper=contact.profile_image_url.split('?');//print("substring: "+JSON.stringify(imagename_helper)+imagename_helper[0].substring(imagename_helper[0].lastIndexOf("/")+1, imagename_helper[0].length))
imagename=login.imagestore+"contacts/"+contact.screen_name+"-"+imagename_helper[0].substring(imagename_helper[0].lastIndexOf("/")+1, imagename_helper[0].length);
try {parseInt(image_timestamp=imagename_helper[1].substring(imagename_helper[1].indexOf("ts=")+3,imagename_helper[1].length))} catch(e){}; try {parseInt(image_timestamp=imagename_helper[1].substring(imagename_helper[1].indexOf("ts=")+3,imagename_helper[1].length))} catch(e){};
print(contact.screen_name+" Timestamp"+image_timestamp+" "+ new Date(parseInt(image_timestamp)*1000));
if ((image_timestamp>currentts) || (image_timestamp==0)){
xhr.setUrl(Qt.resolvedUrl(contact.profile_image_url));
xhr.setFilename(imagename);
xhr.setDownloadtype("contact");
xhr.download();
}
var result; var result;
result = tx.executeSql('SELECT * from contacts where username="'+login.username+'" AND url = "'+contact.url+'"'); // check for news url 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 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+', timestamp='+ image_timestamp+' 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)+'", 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='+ currentTime+' where username="'+login.username+'" AND url="'+contact.url+'"');
} else {// use insert } 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,image_timestamp]);} 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),"",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]);}
}); });
}} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
var core=[ var core=[
{name:'&lt;3',url: {name:'&lt;3',url:

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4

View File

@ -1,7 +1,39 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 2.1 import QtQuick.Controls 2.3
import QtQml 2.2 import QtQml 2.2
import Qt.labs.calendar 1.0 import Qt.labs.calendar 1.0
import QtQuick.Controls 1.2 as Oldcontrol
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
@ -18,7 +50,7 @@ Rectangle {
property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000 property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000
property var events:[] property var events:[]
property var eventdays:[] property var eventdays:[]
onEventdaysChanged: print(JSON.stringify(eventdays)) //onEventdaysChanged: print(JSON.stringify(eventdays))
function showEvents(friend){ function showEvents(friend){
if(friend=="backButton"){Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ if(friend=="backButton"){Service.eventsfromdb(db,login.username,function(eventArray,dayArray){
@ -26,16 +58,16 @@ Rectangle {
eventdays=dayArray}) eventdays=dayArray})
} }
else if (friend!=""){ else if (friend!=""){
calendartab.calendartabstatus=friend.substring(friend.lastIndexOf("/")+1,friend.length) calendartab.calendartabstatus=friend.url.substring(friend.url.lastIndexOf("/")+1,friend.url.length)
Service.requestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){ Service.newRequestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){
events=eventArray; events=eventArray;
eventdays=dayArray}) eventdays=dayArray})
} }
else {calendartab.calendartabstatus="Events"; else {calendartab.calendartabstatus="Events";
Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ Service.eventsfromdb(db,login.username,function(eventArray,dayArray){
events=eventArray; events=eventArray;
eventdays=dayArray; eventdays=dayArray;
calBusy.running=false calBusy.running=false
}) })
} }
} }
@ -71,18 +103,19 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin:2*mm anchors.rightMargin:2*mm
text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus
Oldcontrol.Menu {
id:calendartabmenu
Oldcontrol.MenuItem {
text: qsTr("Own Calendar")
onTriggered: {
calendartab.calendartabstatus="Events";
// calendartabstatusButton.text=qsTr("own Calendar");
showEvents("")}
}
}
onClicked: {calendartabmenu.popup()} onClicked: {calendartabmenu.popup()}
} }
Menu {
id:calendartabmenu
MenuItem {
text: qsTr("Own Calendar")
onTriggered: {
calendartab.calendartabstatus="Events";
// calendartabstatusButton.text=qsTr("own Calendar");
showEvents("")}
}
}
ListView{ ListView{
id: calendarView id: calendarView

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
@ -39,8 +70,7 @@ Rectangle{
} }
Component.onCompleted:{ Component.onCompleted:{
//print(JSON.stringify(daylist)) for (var i=0; i<daylist.length;i++){
for (var i=0; i<daylist.length;i++){//print(JSON.stringify(events[daylist[i]]));
var liststate="";if(daylist.length<2){liststate="large"} var liststate="";if(daylist.length<2){liststate="large"}
eventModel.append({"event":events[daylist[i]],"eventstatus":liststate}); eventModel.append({"event":events[daylist[i]],"eventstatus":liststate});
} }

View File

@ -1,6 +1,38 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
import "qrc:/js/layout.js" as Layoutjs import "qrc:/js/layout.js" as Layoutjs
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
@ -22,11 +54,15 @@ StackView{
width:parent.width width:parent.width
height:Math.max(90*mm,root.height-12*mm) height:Math.max(90*mm,root.height-12*mm)
property var users:[] property var users:[]
property bool registeredUser: true
property var userdata: ({})
function setServericon(server){ function setServericon(server){
try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){ try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){
var serverdata = JSON.parse(obj); var serverdata = JSON.parse(obj);
servericon.source=serverdata.site.logo})} catch(e){print(e)} servericon.source=serverdata.site.logo})} catch(e){print(e)}
} }
BlueButton{ BlueButton{
id:userButton id:userButton
text:qsTr("User") text:qsTr("User")
@ -38,6 +74,7 @@ StackView{
useritems=useritems+"MenuItem{text:'"+configBackground.users[i].username+ useritems=useritems+"MenuItem{text:'"+configBackground.users[i].username+
"'; onTriggered: {Service.readConfig(db,function(obj){ "'; onTriggered: {Service.readConfig(db,function(obj){
configBackground.registeredUser=true;
userButton.text=obj.username; userButton.text=obj.username;
servername.text=obj.server; servername.text=obj.server;
configBackground.setServericon(obj.server); configBackground.setServericon(obj.server);
@ -59,7 +96,7 @@ StackView{
x: 4*mm; y: 10*mm x: 4*mm; y: 10*mm
} }
Text { Text {
text: qsTr("User") text: qsTr("Nickname")
x: 4*mm; y: 20*mm x: 4*mm; y: 20*mm
} }
@ -124,25 +161,35 @@ StackView{
} }
} }
Rectangle{ Rectangle{
color: "light grey" color: "light grey"
x: 25*mm; y: 20*mm; width: root.width/2; height: 5*mm; x: 25*mm; y: 20*mm; width: root.width/2; height: 5*mm;
TextInput { TextInput {
id: username id: username
anchors.fill: parent anchors.fill: parent
selectByMouse: true selectByMouse: true
onEditingFinished:{
Helperjs.friendicaWebRequest(servername.text+'/api/users/show?screen_name='+username.text,configBackground,function(obj){
var screennametest=JSON.parse(obj);
if (screennametest.status.error){
Helperjs.showMessage(qsTr("Error"),qsTr("Nickname not registered at given server!"),configBackground);
configBackground.registeredUser=false;
}else{configBackground.registeredUser=true}
});
}
}
} }
}
Rectangle{ Rectangle{
color: "light grey" color: "light grey"
x: 25*mm; y: 30*mm; width: root.width/2; height: 5*mm; x: 25*mm; y: 30*mm; width: root.width/2; height: 5*mm;
TextInput { TextInput {
id: password id: password
anchors.fill: parent anchors.fill: parent
selectByMouse: true selectByMouse: true
echoMode: TextInput.PasswordEchoOnEdit echoMode: TextInput.PasswordEchoOnEdit
}
} }
}
Rectangle{color: "light grey"; x: 25*mm; y: 40*mm; width: root.width/2-9*mm; height: 5*mm;} Rectangle{color: "light grey"; x: 25*mm; y: 40*mm; width: root.width/2-9*mm; height: 5*mm;}
Flickable { Flickable {
@ -231,34 +278,41 @@ StackView{
var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text,interval: messageIntervalField.text, newsViewType:newsTypeField.text}; var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text,interval: messageIntervalField.text, newsViewType:newsTypeField.text};
var errormessage=""; var errormessage="";
if (servername.text==""){errormessage=qsTr("No server given! ")} if (servername.text==""){errormessage=qsTr("No server given! ")}
else if (username.text==""){errormessage+=qsTr("No username given! ")} else if (username.text==""){errormessage+=qsTr("No nickname given! ")}
else if ((configBackground.registeredUser==false)){errormessage+=qsTr("Nickname not registered at given server! ")}
else if (password.text=="") {errormessage+=qsTr("No password given! ")} else if (password.text=="") {errormessage+=qsTr("No password given! ")}
else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")} else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")} else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")}
else {errormessage=""} else {errormessage=""}
if (errormessage=="") { if (errormessage=="") {
filesystem.Directory=userconfig.imagestore; Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){
filesystem.makeDir("contacts"); var credentials=JSON.parse(obj);
filesystem.makeDir("albums"); if (credentials.hasOwnProperty('status')){
Service.storeConfig(db,userconfig); Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
Service.readConfig(db,function(userconfig){ }
Service.getServerConfig(db,userconfig,root, function(obj){ else{
var serverString=obj; filesystem.Directory=userconfig.imagestore;
var serverconfigObject=Qt.createQmlObject(serverString,configBackground,"serverconfigOutput"); filesystem.makeDir("contacts");
Helperjs.readData(db,"config","",function(storedUsers){ filesystem.makeDir("albums");
storedUsers.sort(function(obj1, obj2) { Service.storeConfig(db,userconfig);
return obj1.isActive - obj2.isActive; Service.readConfig(db,function(userconfig){
}); Helperjs.readData(db,"config","",function(storedUsers){
configBackground.users=storedUsers}); storedUsers.sort(function(obj1, obj2) {
userButton.color="black" return obj1.isActive - obj2.isActive;
//reset values });
root.login=userconfig; configBackground.users=storedUsers});
newstab.newstabstatus=userconfig.newsViewType; userButton.color="black"
root.currentIndex=0; //reset values
newstab.active=true; root.login=userconfig;
})},"isActive",0); root.news=[];
},"isActive",0);
Service.requestProfile(userconfig,db,root,function(nc){root.newContacts=nc})
Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.name+"\nScreen Name: "+credentials.screen_name,root)
}
});
} }
else {Helperjs.show("Error", errormessage,root)} else {Helperjs.showMessage(qsTr("Error"), errormessage,root)}
}} }}
BlueButton { BlueButton {
@ -271,6 +325,7 @@ StackView{
filesystem.rmDir(); filesystem.rmDir();
filesystem.Directory=imagestore.text+"albums"; filesystem.Directory=imagestore.text+"albums";
filesystem.rmDir(); filesystem.rmDir();
configBackground.registeredUser=true;
servername.text="https://..."; servername.text="https://...";
servericon.source=""; servericon.source="";
username.text=""; username.text="";
@ -292,6 +347,7 @@ StackView{
x: root.width/2+8*mm; y: mm; width: 5*mm; height: 5*mm; x: root.width/2+8*mm; y: mm; width: 5*mm; height: 5*mm;
text: "+" text: "+"
onClicked:{ onClicked:{
configBackground.registeredUser=true;
servername.text="https://..." servername.text="https://..."
servericon.source=""; servericon.source="";
username.text="" username.text=""

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
@ -10,15 +41,18 @@ Rectangle{
anchors.top:closeButton.bottom anchors.top:closeButton.bottom
anchors.topMargin: mm anchors.topMargin: mm
textFormat: Text.RichText textFormat: Text.RichText
wrapMode: Text.Wrap width: parent.width
text: "<b>Friendiqa v0.1 </b><br>Licensed under GPL 3<br> "+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
text: "<b>Friendiqa v0.2 </b><br>Licensed under GPL 3 with the exception of OpenSSL <br> "+
"Profile <a href='https://freunde.ma-nic.de/profile/friendiqa'>https://freunde.ma-nic.de/profile/friendiqa</a><br>"+ "Profile <a href='https://freunde.ma-nic.de/profile/friendiqa'>https://freunde.ma-nic.de/profile/friendiqa</a><br>"+
"Sourcecode: <a href='https://github.com/LubuWest/Friendiqa'>https://github.com/LubuWest/Friendica</a><br>"+ "Sourcecode: <a href='https://github.com/LubuWest/Friendiqa'>https://github.com/LubuWest/Friendiqa</a><br>"+
"C++ code by <a href='https://kirgroup.com/profile/fabrixxm'>Fabio</a><br>"+ "C++ code by <a href='https://kirgroup.com/profile/fabrixxm'>Fabio</a><br>"+
"QML and Javascript code by <a href='https://freunde.ma-nic.de/profile/marco'>Marco</a><br>"+ "QML and Javascript code by <a href='https://freunde.ma-nic.de/profile/marco'>Marco</a><br>"+
"Qt Framework <a href='https://www.qt.io'>www.qt.io</a><br>"+ "Qt Framework <a href='https://www.qt.io'>www.qt.io</a><br>"+
"Icons by <a href='http://fontawesome.io'>FontAwesome</a><br>"+ "Icons by <a href='http://fontawesome.io'>FontAwesome</a><br>"+
"Folder Icon by <a href='https://github.com/KDE/breeze-icons'>KDE Breeze Icons</a>" "Folder Icon by <a href='https://github.com/KDE/breeze-icons'>KDE Breeze Icons</a><br>"+
"AndroidNative by <a href='https://github.com/benlau/androidnative.pri'>Ben Lau</a><br>"+
"This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (<a href='http://www.openssl.org/'>http://www.openssl.org/</a>)"
onLinkActivated:{ onLinkActivated:{
Qt.openUrlExternally(link)} Qt.openUrlExternally(link)}
} }

View File

@ -1,8 +1,40 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick.Window 2.0 import QtQuick.Window 2.0
import QtQuick 2.0 import QtQuick 2.0
QtObject{ QtObject{
property int appWidth: Screen.desktopAvailableWidth property int appWidth: Screen.desktopAvailableWidth
property int appHeight: Screen.desktopAvailableHeight property int appHeight: Screen.desktopAvailableHeight
property int backKey: Qt.Key_Back property int backKey: Qt.Key_Back
property string attachImageDir:filesystem.cameraPath+"/" //property string attachImageDir:filesystem.cameraPath+"/"
property string imagePickQml: "ImagePicker"
} }

View File

@ -1,7 +1,39 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
QtObject{ QtObject{
property real appWidth: 500 property real appWidth: 500
property real appHeight: 500 property real appHeight: 500
property int backKey: Qt.Key_Escape property int backKey: Qt.Key_Escape
property string attachImageDir:filesystem.homePath+"/Pictures/" //property string attachImageDir:filesystem.homePath+"/Pictures/"
property string imagePickQml: "ImagePickerLinux"
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
@ -19,8 +50,8 @@ Rectangle {
y:1 y:1
width: 10*mm width: 10*mm
height:10*mm height:10*mm
source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url source:((contact.profile_image!="") && (typeof(contact.profile_image)=="string"))? "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 { Label {

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
@ -8,7 +39,7 @@ x:mm
y:mm y:mm
property var contact:{} property var contact:{}
property var createdAtDate: new Date(contact.created_at) property var createdAtDate: new Date(contact.created_at)
property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend==1)?"":( "<a href='"+contact.url.replace("profile","dfrn_request") +"'>"+qsTr("Connect")+"</a><br>") property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend!=0)?"":( "<a href='"+contact.url.replace("profile","dfrn_request") +"'>"+qsTr("Connect")+"</a><br>")
Rectangle { Rectangle {
id: wrapper id: wrapper
@ -50,7 +81,7 @@ Rectangle{
frameVisible: true frameVisible: true
id:namelabelflickable id:namelabelflickable
width: root.width-10*mm width: root.width-10*mm
height:root.height-50*mm//friendsTabView.height-45*mm height:root.height-50*mm
x: mm x: mm
clip:true clip:true
Text{ Text{
@ -82,7 +113,7 @@ Rectangle{
fotostab.phototabstatus="Contact"; fotostab.phototabstatus="Contact";
root.currentIndex=2; root.currentIndex=2;
fotostab.active=true; fotostab.active=true;
root.fotoSignal(contact) ; root.fotoSignal(root.login,contact) ;
contactLargeComponent.destroy(); contactLargeComponent.destroy();
} }
} }
@ -93,7 +124,7 @@ Rectangle{
onClicked:{ onClicked:{
root.currentIndex=0; root.currentIndex=0;
newstab.active=true; newstab.active=true;
root.messageSignal(contact.id) ; root.messageSignal(contact) ;
contactLargeComponent.destroy(); contactLargeComponent.destroy();
} }
} }
@ -119,7 +150,7 @@ Rectangle{
root.currentIndex=3; root.currentIndex=3;
calendartab.active=true; calendartab.active=true;
calendartab.calendartabstatus="Friend" calendartab.calendartabstatus="Friend"
root.eventSignal(contact.url); root.eventSignal(contact);
contactLargeComponent.destroy(); contactLargeComponent.destroy();
} }
} }

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// List of people // List of people
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs

View File

@ -1,6 +1,38 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import QtQuick.LocalStorage 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/news.js" as Newsjs import "qrc:/js/news.js" as Newsjs
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
@ -14,15 +46,28 @@ Rectangle {
function showContactdetails(contact){ function showContactdetails(contact){
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml"); var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if(contact.isFriend){ if(contact.isFriend){
friendsTabView.currentIndex=0; friendsTabView.currentIndex=1;
var contactDetails = component.createObject(friendstab,{"contact": contact}) var contactDetails = component.createObject(friendstab,{"contact": contact})
} }
else{friendsTabView.currentIndex=1; else{friendsTabView.currentIndex=2;
var contactDetails = component.createObject(friendstab,{"contact": contact}) var contactDetails = component.createObject(friendstab,{"contact": contact})
} }
} }
function showProfile(callback){
var profile=({});
Helperjs.readData(db,"profiles",login.username,function(profileobject){
var profilearray=[];
for (var i in profileobject){
profilearray.push(JSON.parse(Qt.atob(profileobject[i].profiledata)));
}
profile.profiles=profilearray;
});
Helperjs.readData(db,"contacts",login.username,function(owner){
profile.friendica_owner=owner[0];
},"isFriend",2);
callback(profile)
}
TabView{ TabView{
id:friendsTabView id:friendsTabView
@ -31,23 +76,23 @@ Rectangle {
y:mm y:mm
width: root.width-2*mm width: root.width-2*mm
height: root.height-10*mm height: root.height-10*mm
currentIndex: 0 currentIndex: 1
signal contactsSignal(var contact) signal contactsSignal(var contact)
signal groupsSignal(var username) signal groupsSignal(var username)
onCurrentIndexChanged:{ onCurrentIndexChanged:{
if (currentIndex==0){ if (currentIndex==1){
contactsSignal("") contactsSignal("")
} }
else if (currentIndex==1){ else if (currentIndex==2){
contactsSignal("") contactsSignal("")
} }
else if (currentIndex==2){groupsSignal(root.login.username)} else if (currentIndex==3){groupsSignal(root.login.username)}
} }
style: TabViewStyle { style: TabViewStyle {
frameOverlap: 1 frameOverlap: 1
tab: Rectangle { tab: Rectangle {
color: "white" color: "white"
implicitWidth: root.width/3-2*mm implicitWidth: root.width/4-2*mm
implicitHeight: 4*mm implicitHeight: 4*mm
Text { id: text Text { id: text
anchors.centerIn: parent anchors.centerIn: parent
@ -61,24 +106,43 @@ Rectangle {
tabsAlignment:Qt.AlignHCenter tabsAlignment:Qt.AlignHCenter
} }
Tab{
id:profileGridTab
title: qsTr("Me")
Component.onCompleted:{
showProfile(function(profile){
var component = Qt.createComponent("qrc:/qml/contactqml/ProfileComponent.qml");
var profilecomp = component.createObject(profileGridTab,{"profile": profile});
});
}
}
Tab{ Tab{
title: qsTr("Friends") title: qsTr("Friends")
Rectangle{ Rectangle{
id: friendsGridTab id: friendsGridTab
property int currentContact:0
function showFriends(contact){ function showFriends(contact){
try {friendsModel.clear()} catch(e){print(e)}; try {friendsModel.clear()} catch(e){print(e)};
Helperjs.readData(db,"contacts",login.username,function(friendsobject){ Helperjs.readData(root.db,"contacts",login.username,function(friendsobject){
for (var i=0;i<friendsobject.length;i++){ for (var i=0;i<friendsobject.length;i++){
if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){ if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid
} }
friendsModel.append({"contact":friendsobject[i]}); friendsModel.append({"contact":friendsobject[i]});
} }
},"isFriend",1,"screen_name ASC"); },"isFriend",1,"screen_name ASC");
} }
Connections{
target:xhr
onDownloaded:{
if(type=="contactlist"){
//print(url+" "+filename+" "+i)
currentContact=i+1;
if(currentContact==root.newContacts.length){showFriends(root.login.username)}
}
}
}
BlueButton { BlueButton {
id: updateFriendsButton id: updateFriendsButton
text: "\uf021" text: "\uf021"
@ -101,8 +165,8 @@ Rectangle {
anchors.top: parent.top anchors.top: parent.top
anchors.right:updateFriendsButton.left anchors.right:updateFriendsButton.left
anchors.rightMargin:mm anchors.rightMargin:mm
visible: (root.currentContact!=root.newContacts.length)?true:false visible: (currentContact!=(root.newContacts.length))?true:false
value: root.currentContact/root.newContacts.length value: currentContact/root.newContacts.length
} }
GridView { GridView {
@ -126,7 +190,8 @@ Rectangle {
Component.onCompleted: { Component.onCompleted: {
root.friendsSignal.connect(showFriends); root.friendsSignal.connect(showFriends);
friendsTabView.contactsSignal.connect(showFriends); friendsTabView.contactsSignal.connect(showFriends);
showFriends(root.login.username) showFriends(root.login.username);
root.newContacts=[]
} }
} }
} }
@ -210,17 +275,6 @@ Rectangle {
xhr.setParam("user", group.user); xhr.setParam("user", group.user);
xhr.setParam("json",group); xhr.setParam("json",group);
xhr.post(); xhr.post();
// Helperjs.friendicaPostRequest(login,api,groupdata,"POST",rootwindow, function (obj){print("groupcreate "+obj);
// var groups=JSON.parse(obj);
// db.transaction( function(tx) {
// var result = tx.executeSql('DELETE from groups where username="'+login.username+'"'); // clean old groups
// for (var i=0;i<groups.length;i++){
// var memberarray=[]; for (var user in groups[i].user){memberarray.push(parseInt(groups[i].user[user].cid))}
// //print("Members: "+groups[i].user)
// var result2 = tx.executeSql('INSERT INTO groups VALUES (?,?,?,?)', [login.username,groups[i].name,groups[i].gid,JSON.stringify(memberarray)])}
// callback()
// });
// })
} }
Connections{ Connections{
@ -242,17 +296,17 @@ Rectangle {
Newsjs.requestGroups(root.login,root.db,root,function(){ Newsjs.requestGroups(root.login,root.db,root,function(){
showGroups(root.login.username)})} showGroups(root.login.username)})}
} }
BlueButton { // BlueButton {
id: newGroupButton // id: newGroupButton
text: "\uf234" // text: "\uf234"
anchors.top: parent.top // anchors.top: parent.top
anchors.topMargin: mm // anchors.topMargin: mm
anchors.right: updateGroupsButton.left // anchors.right: updateGroupsButton.left
anchors.rightMargin: mm // anchors.rightMargin: mm
onClicked: { // onClicked: {
groupsModel.append({"group": {"new":true}}); // groupsModel.append({"group": {"new":true}});
} // }
} // }
GridView { GridView {
id: groupsView id: groupsView
x:mm x:mm

View File

@ -1,3 +1,34 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/news.js" as Newsjs import "qrc:/js/news.js" as Newsjs
@ -56,7 +87,8 @@ Item {
anchors.topMargin: 3 anchors.topMargin: 3
anchors.top: parent.top anchors.top: parent.top
onClicked:{ onClicked:{
if(group.new){Helperjs.readField("members",root.db,"groups",root.login.username,function(groups){ //if(group.new){
Helperjs.readField("members",root.db,"groups",root.login.username,function(groups){
try {groupModel.clear()}catch (e){print(e)} try {groupModel.clear()}catch (e){print(e)}
groupmembers=JSON.parse(groups); groupmembers=JSON.parse(groups);
for (var user in groupmembers){ for (var user in groupmembers){
@ -64,7 +96,8 @@ Item {
if (userdata[0]){groupModel.append({"groupmember":userdata[0]})} if (userdata[0]){groupModel.append({"groupmember":userdata[0]})}
},"id",groupmembers[user]) },"id",groupmembers[user])
} //catch(e){} } //catch(e){}
},"groupname",group.groupname);} },"groupname",group.groupname);
//}
groupComponent.state="large" groupComponent.state="large"
} }
} }
@ -109,14 +142,14 @@ Item {
root.contactdetailsSignal(groupmember) root.contactdetailsSignal(groupmember)
} }
} }
BlueButton{ // BlueButton{
anchors.left: memberrectangle.right // anchors.left: memberrectangle.right
anchors.margins: 1*mm // anchors.margins: 1*mm
text: "\uf056" // text: "\uf056"
onClicked:{ // onClicked:{
groupModel.remove(index) // groupModel.remove(index)
} // }
} // }
} }
} }
} }
@ -139,54 +172,6 @@ Item {
anchors.top: groupListView.bottom anchors.top: groupListView.bottom
anchors.topMargin: mm anchors.topMargin: mm
spacing: mm spacing: mm
BlueButton{
id: deleteButton
text: "\uf056"
onClicked:{
Newsjs.deleteGroup(root.login,root.db,root,group,function(){
groupComponent.state="";
groupsModel.remove(index)})
}
}
BlueButton{
id: addMembers
text:"\uf234"
onClicked: {
Newsjs.listFriends(root.login,root.db,function(userdata){
var newlistcontacts=[];
for (var n in userdata){
if (groupmembers.indexOf(userdata[n].id)==-1){
newlistcontacts.push(userdata[n])
}
}
var component = Qt.createComponent("qrc:/qml/contactqml/Contactlist.qml");
var contactlistobject = component.createObject(groupListView,{"possibleUsers":newlistcontacts});
})
}
}
BlueButton{
id: updateButton
text: "\uf0ee"
onClicked:{
var groupobject={};
var groupmembers=[];
for (var i=0;i<groupModel.count;i++){groupmembers.push(groupModel.get(i).groupmember)}
try{ groupobject.id=group.gid} catch(e){};
try{ groupobject.new=group.new} catch(e){};
if (namelabel.text==""){
Helperjs.showMessage(qsTr("Error"),qsTr("No name given"),root)}
else {
groupobject.name=namelabel.text;
groupobject.user=groupmembers;
updateGroup(login,db,groupobject)
groupComponent.state="";
}
}
}
BlueButton{ BlueButton{
id: closeButton id: closeButton
text: "\uf057" text: "\uf057"
@ -194,6 +179,53 @@ Item {
if (group.new){groupsModel.remove(index)} if (group.new){groupsModel.remove(index)}
} }
} }
// BlueButton{
// id: addMembers
// text:"\uf234"
// onClicked: {
// Newsjs.listFriends(root.login,root.db,function(userdata){
// var newlistcontacts=[];
// for (var n in userdata){
// if (groupmembers.indexOf(userdata[n].id)==-1){
// newlistcontacts.push(userdata[n])
// }
// }
// var component = Qt.createComponent("qrc:/qml/contactqml/Contactlist.qml");
// var contactlistobject = component.createObject(groupListView,{"possibleUsers":newlistcontacts});
// })
// }
// }
// BlueButton{
// id: updateButton
// text: "\uf0ee"
// onClicked:{
// var groupobject={};
// var groupmembers=[];
// for (var i=0;i<groupModel.count;i++){groupmembers.push(groupModel.get(i).groupmember)}
// try{ groupobject.id=group.gid} catch(e){};
// try{ groupobject.new=group.new} catch(e){};
// if (namelabel.text==""){
// Helperjs.showMessage(qsTr("Error"),qsTr("No name given"),root)}
// else {
// groupobject.name=namelabel.text;
// groupobject.user=groupmembers;
// updateGroup(login,db,groupobject)
// groupComponent.state="";
// }
// }
// }
// BlueButton{
// id: deleteButton
// text: "\uf056"
// onClicked:{
// Newsjs.deleteGroup(root.login,root.db,root,group,function(){
// groupComponent.state="";
// groupsModel.remove(index)})
// }
// }
} }
} }
Component.onCompleted:{if(group.new){groupComponent.state="large"}} Component.onCompleted:{if(group.new){groupComponent.state="large"}}

View File

@ -0,0 +1,277 @@
// This file is part of Friendiqa
// https://github.com/lubuwest/Friendiqa
// Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0
import QtQuick.Controls 1.3
import "qrc:/qml/genericqml"
import "qrc:/js/service.js" as Service
Rectangle {
width:root.width-2*mm
height:root.height-14*mm
color:"white"
property var profile:({})
property var attachImageURLs:[]
property var createdAtDate: new Date(profile.friendica_owner.created_at)
function updateProfileImage(){
xhr.url= login.server + "/api/account/update_profile_image.json";
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.clearParams();
xhr.setImageFileParam("image", photoImage.source );
xhr.post();
}
function buildProfiletext(pobject,callback){
var profileobject={};
var profiletext="";
for (var key in pobject){//print(key+obj[key])
if(pobject[key]!=""&&key!="users"&&key!="profile_id"){
var keytext="";
switch(key){
case "profile_name":keytext=qsTr("profile name");break;
case "is_default":keytext=qsTr("is default");break;
case "hide_friends":keytext=qsTr("hide friends");break;
case "profile_photo":keytext=qsTr("profile photo");break;
case "profile_thumb":keytext=qsTr("profile thumb");break;
case "publish":keytext=qsTr("publish");break;
case "net_publish":keytext=qsTr("publish in network");break;
case "description":keytext=qsTr("description");break;
case "date_of_birth":keytext=qsTr("date of birth");break;
case "address":keytext=qsTr("address");break;
case "city":keytext=qsTr("city");break;
case "region":keytext=qsTr("region");break;
case "postal_code":keytext=qsTr("postal code");break;
case "country":keytext=qsTr("country");break;
case "hometown":keytext=qsTr("hometown");break;
case "gender":keytext=qsTr("gender");break;
case "marital":keytext=qsTr("marital status");break;
case "marital_with":keytext=qsTr("married with");break;
case "marital_since":keytext=qsTr("married since");break;
case "sexual":keytext=qsTr("sexual");break;
case "politic":keytext=qsTr("politics");break;
case "religion":keytext=qsTr("religion");break;
case "public_keywords":keytext=qsTr("public keywords");break;
case "private_keywords":keytext=qsTr("private keywords");break;
case "likes":keytext=qsTr("likes");break;
case "dislikes":keytext=qsTr("dislikes");break;
case "about":keytext=qsTr("about");break;
case "music":keytext=qsTr("music");break;
case "book":keytext=qsTr("book");break;
case "tv":keytext=qsTr("tv");break;
case "film":keytext=qsTr("film");break;
case "interest":keytext=qsTr("interest");break;
case "romance":keytext=qsTr("romance");break;
case "work":keytext=qsTr("work");break;
case "education":keytext=qsTr("education");break;
case "social_networks":keytext=qsTr("social networks");break;
case "homepage":keytext=qsTr("homepage");break;
default:keytext=key;
}
profiletext=profiletext+("<b>"+keytext+": </b> "+(pobject[key])+"<br>");
}
}
callback(profiletext)
}
BlueButton {
id: update
anchors.top: parent.top
anchors.topMargin: mm
anchors.right: parent.right
text: "\uf021"
onClicked: {
Service.requestProfile(root.login,root.db,root,function(nc){
root.newContacts=nc;
photoImage.source="";
showProfile(function(newprofile){
profile=newprofile;
try {profileModel.clear()} catch(e){print(e)};
newprofile.profiles.sort(function(obj1, obj2) {
return obj1.profile_id - obj2.profile_id;
})
for(var i in newprofile.profiles){var obj=newprofile.profiles[i];
buildProfiletext(obj,function(profiletext){
profileModel.append({"profileid":obj.profile_id,"profiletext":profiletext})
})
}
photoImage.source="file://"+newprofile.friendica_owner.profile_image;
});
});
}
}
Image {
id: photoImage
x:mm
y:mm
width: 15*mm
height:15*mm
source: "file://"+profile.friendica_owner.profile_image
onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}
MouseArea{
anchors.fill: parent
onClicked:{
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple: false;onReady: {photoImage.source=imageUrl;'+
'}}',profileGridTab,"imagePicker");
imagePicker.pickImage()
}
}
}
Rectangle{
id:phototextRectangle
color:"black"
z:3
opacity: 0.5
width:6*mm
height: phototext.contentHeight
anchors.top: photoImage.top
anchors.right: photoImage.right
}
Text {
id:phototext
z:4
text: "\uf040"
width:5*mm
anchors.top: photoImage.top
anchors.right:photoImage.right
color: "white"
font.pixelSize: 4*mm
}
BlueButton{
id:updatebutton
height: 5*mm
visible: "file://"+profile.friendica_owner.profile_image!= photoImage.source
text:qsTr("Update")
anchors.left: photoImage.right
anchors.leftMargin: 0.5*mm
anchors.topMargin: mm
anchors.top: parent.top
onClicked:{updateProfileImage()}
}
Label {
id: namelabel
x: mm
width: root.width-6*mm
height: 3*mm
text:(Qt.atob(profile.friendica_owner.name))+" (@"+profile.friendica_owner.screen_name+")"
elide:Text.ElideRight
anchors.topMargin: 0
anchors.left: photoImage.left
wrapMode: Text.Wrap
color: "#303030"
font.pixelSize: 4*mm
anchors.top: photoImage.bottom
}
ListModel{id:profileModel}
Component{
id:profileItem
Rectangle{
id:profileRect
width:profileView.width
height: 5*mm+profiletextfield.height
Text{
y:mm
font.pixelSize: 3*mm
text:"<b>"+qsTr("profile id")+": </b> "+profileid+"<br>"
color:"black"
}
Text{
id:profiletextfield
x:2*mm
y:3.5*mm
width:parent.width-2.5*mm
wrapMode: Text.Wrap
font.pixelSize: 3*mm
text:profiletext
color:"black"
}
}
}
Component{
id:textcomponent
Text{
id:namelabeltext
width: namelabelflickable.width
height: implicitHeight
font.pixelSize: 3*mm
textFormat:Text.RichText
wrapMode: Text.Wrap
text:"<b>"+qsTr("Description")+": </b> "+(profile.friendica_owner.description)+"<br> <b>"+qsTr("Location")+":</b> "+profile.friendica_owner.location+"<br> <b>"+qsTr("Posts")+":</b> "+profile.friendica_owner.statuses_count+
"<br> <b>"+qsTr("URL")+":</b> <a href='"+ profile.friendica_owner.url+"'>"+profile.friendica_owner.url+"</a><br>"+
"<b>"+qsTr("Created at")+":</b> "+createdAtDate.toLocaleString(Qt.locale())
onLinkActivated: {
Qt.openUrlExternally(link)}
}
}
Rectangle{
id: detailsrectangle
anchors.top: namelabel.bottom
anchors.topMargin: 2*mm
ScrollView{
horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff
frameVisible: true
id:namelabelflickable
width: root.width-10*mm
height:root.height-36*mm//friendsTabView.height-45*mm
x: mm
clip:true
ListView {
id: profileView
header:textcomponent
width:root.width-10*mm
height: root.height
clip: true
spacing: 0
model: profileModel
delegate: profileItem
}
}
}
Component.onCompleted: {
profile.profiles.sort(function(obj1, obj2) {
return obj1.profile_id - obj2.profile_id;
})
for(var i in profile.profiles){var obj=profile.profiles[i];
buildProfiletext(obj,function(profiletext){
profileModel.append({"profileid":obj.profile_id,"profiletext":profiletext})
})
}
}
}

Some files were not shown because too many files have changed in this diff Show More