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,4 +1,4 @@
## v0.1#
## v0.1##
# News #
@ -20,10 +20,36 @@
## v0.1.1#
## v0.1.1##
* FIX: Spanish translation
* 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.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:
* Shows Posts from friends, favorited messages, Direct Messages and Notifications
* 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
* Deletion, Reposting, Answering of Posts
* Liking, disliking, favoriting
@ -32,8 +33,7 @@ Currently supported:
ToDo:
* Move picture download into a background process
* Videos and other binary data as attachment (sending and receiving, currently not supported in API)
* Videos and other binary data as attachment (sending and receiving)
* More than one attachment (currently not supported in API)
* Rich text editing in Send Dialog
* Attachments for Direct messages (currently not supported in API)
@ -42,47 +42,54 @@ ToDo:
# Friends #
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
* Large friend item for addional information and functionality
* Large friend item for additional information and functionality
* Show news of contact from local database
* Send direct message, if contact is following
* Show public pictures of contact (screenscraping of contact's website, works only with certain theme)
* 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)
* Clean other contacts with no news
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
(needs API change)
# Images #
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
* Upload pictures to albums with description
* Delete pictures on client and server
* Show albums and images of contacts
* Show public and private (Friendica 3.6 server required) albums and images of contacts
* Pinch to zoom, swipe to scroll
ToDo:
* Private images of friends
* Support for all themes of friends
* Change name or album of existing picture
* Upload private images
# Events #
* download own public events and show public events of Friendica contacts
* list view of events of selected date
* click on event to show details
* Download own public events
* Show public and private events of Friendica contacts (Friendica 3.6 server required)
* List view of events of selected date
* Click on event to show details
ToDo
* private events
* Show own private events (needs API)
* Create events (needs API)
# Config #
Currently supported:
* 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)
ToDo
@ -97,12 +104,14 @@ ToDo
# Translations #
* German, Spanish
* German, Spanish, Italian
# Install #
* 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)
## License ##
Pubished under the [GPL v3](http://gplv3.fsf.org).
## License ##
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"?>
<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">
<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>

View File

@ -210,13 +210,13 @@
<file>translations/friendiqa-es.qm</file>
<file>translations/friendiqa-es.ts</file>
<file>qml/photoqml/ImageUploadDialog.qml</file>
<file>qml/genericqml/ImageDialog.qml</file>
<file>qml/genericqml/PermissionDialog.qml</file>
<file>images/addImage.png</file>
<file>common/imageselectandroid.h</file>
<file>common/imageselectandroid.cpp</file>
<file>qml/genericqml/ImagePicker.qml</file>
<file>common/quickandroid.h</file>
<file>common/quickandroid.cpp</file>
<file>qml/genericqml/ImagePickerLinux.qml</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>
</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"
FILESYSTEM *FILESYSTEM::instance()
@ -29,12 +60,12 @@ QString FILESYSTEM::homePath() const
return homeDir;
}
QString FILESYSTEM::cameraPath() const
{
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>());
return dcim.toString();
}
//QString FILESYSTEM::cameraPath() const
//{
//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>());
// return dcim.toString();
//}
//bool FILESYSTEM::direxist(QString Directory) const
@ -83,46 +114,46 @@ QFileInfoList FILESYSTEM::fileList()
return dir.entryInfoList();
}
void FILESYSTEM::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;");
//void FILESYSTEM::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>());
// 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";
}
}
// 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 FILESYSTEM::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 resultUri = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex);
QString imageSelect = "file://" + resultUri.toString();
emit imageselected(imageSelect);
}
else
{
qDebug() << "Select error";
}
}
//void FILESYSTEM::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 resultUri = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex);
// QString imageSelect = "file://" + resultUri.toString();
// emit imageselected(imageSelect);
// }
// else
// {
// 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
#define FILESYSTEM_H
#include <QDir>
#include <QObject>
#include <QtAndroidExtras>
#include <QAndroidActivityResultReceiver>
//#include <QtAndroidExtras>
//#include <QAndroidActivityResultReceiver>
class FILESYSTEM : public QObject, public QAndroidActivityResultReceiver
class FILESYSTEM : public QObject//, public QAndroidActivityResultReceiver
{
Q_OBJECT
Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged)
//Q_PROPERTY(bool direxist READ direxist)
Q_PROPERTY(QString homePath READ homePath)
Q_PROPERTY(QString cameraPath READ cameraPath)
//Q_PROPERTY(QString cameraPath READ cameraPath)
public:
@ -23,11 +54,11 @@ public:
QFileInfoList fileList();
//bool direxist(QString Directory);
QString homePath() const;
QString cameraPath() const;
virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data);
//QString cameraPath() const;
// virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data);
signals:
void imageselected(QString);
//void imageselected(QString);
void directoryChanged();
//void fileListContent(QList data);
void success(QString data);
@ -37,7 +68,7 @@ public slots:
void makeDir(QString name);
void rmDir();
void rmFile(QString name);
void searchImage();
//void searchImage();
//void fileList();
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 <QtQml/QQmlEngine>
#include <QtQuick>
#include "xhr.h"
#include "filesystem.h"
//#include "qadrawableprovider.h"
//#include "androidnative.pri/cpp/AndroidNative/systemdispatcher.h"
#include "remoteauthasyncimageprovider.h"
#include "AndroidNative/systemdispatcher.h"
#include "AndroidNative/environment.h"
#include "AndroidNative/debug.h"
//#include "AndroidNative/debug.h"
#include "AndroidNative/mediascannerconnection.h"
//#include "debugwrapper.h"
#ifdef Q_OS_ANDROID
#include <QtAndroidExtras/QAndroidJniObject>
@ -30,9 +60,9 @@ int main(int argc, char *argv[]) {
QTranslator qtTranslator;
qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations");
app.installTranslator(&qtTranslator);
// qmlRegisterType<QASystemDispatcher>("SystemDispatcher", 0, 1, "SystemDispatcher");
RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider;
view.engine()->addImageProvider("remoteauthimage",imageProvider);
view.rootContext()->setContextProperty("remoteauth", imageProvider);
XHR* xhr = XHR::instance();
view.rootContext()->setContextProperty("xhr", xhr);
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"

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
#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 <QTextCodec>
#include <QUrlQuery>
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QList>
#include <QDataStream>
#include <QJsonDocument>
#include <QJsonObject>
#include "uploadableimage.h"
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)
{
if (downloadtype!=m_downloadtype) {
@ -67,6 +121,21 @@ QString XHR::filename() const
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
{
return m_downloadtype;
@ -91,9 +160,14 @@ void XHR::clearParams()
void XHR::download()
{
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);
reply = manager.get(request);
// reply->ignoreSslErrors();
reply->ignoreSslErrors();
connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead);
//connect(reply,SIGNAL(downloadProgress(qint64,qint64)), this,SLOT(updateDownloadProgress(qint64,qint64)));
connect(reply, &QNetworkReply::finished,this, &XHR::onRequestFinished);
@ -117,9 +191,6 @@ void XHR::get()
QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData;
request.setRawHeader("Authorization", headerData.toLocal8Bit());
// QNetworkCookieJar* cJar = new QNetworkCookieJar;
// manager.setCookieJar(cJar);
request.setUrl(requrl);
reply = manager.get(request);
@ -129,6 +200,20 @@ void XHR::get()
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()
{
qDebug() << "start post to " << m_url;
@ -178,7 +263,7 @@ void XHR::post()
void XHR::onReplyError(QNetworkReply::NetworkError code)
{
qDebug() << code;
emit this->error( bufferToString(), (int) code);
emit this->error( bufferToString(), m_url, (int) code);
buffer.clear();
reply->deleteLater();
}
@ -194,14 +279,45 @@ void XHR::onReplySuccess()
void XHR::onRequestFinished()
{
// Save the file here
//qDebug() << "buffer downloaded "<<buffer;
if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,1);}
else {QFile file(m_filename);
if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,m_url,1);}
else if (m_downloadtype=="picturelist") {
QJsonDocument jsonResponse = QJsonDocument::fromJson(buffer);
QJsonObject jsonObject = jsonResponse.object();
int arraystart=buffer.indexOf('{"data":"')+8;
int arraylength=buffer.indexOf('"',9)-arraystart;
QByteArray b64=buffer.mid(arraystart,arraylength);
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);
emit this->downloaded(m_downloadtype,m_url,m_filename,dlindex);
if(downloadtype()=="contactlist"){dlindex=dlindex+1;XHR::getlist();}
//reply->deleteLater();
}
}
@ -210,15 +326,6 @@ void XHR::onReadyRead()
{
qDebug() << ".";
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)

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
#define XHR_H
@ -5,6 +36,7 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QObject>
#include <QJsonObject>
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 login READ login WRITE setLogin NOTIFY loginChanged)
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)
@ -23,27 +58,38 @@ public:
QString url() const;
QString login() const;
QString filename() const;
QList<QString> contactlist() const;
QList<QString> filelist() const;
QString imagedir() const;
QString downloadtype() const;
signals:
void urlChanged();
void loginChanged();
void filenameChanged();
void contactlistChanged();
void filelistChanged();
void imagedirChanged();
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 error(QString data, int code);
void error(QString data, QString url, int code);
public slots:
void setUrl(QString url);
void setLogin(QString login);
void setDownloadtype(QString downloadtype);
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 setImageFileParam(QString name, QString url);
void clearParams();
void post();
void get();
void getlist();
void download();
private slots:
@ -62,6 +108,10 @@ private:
QString m_downloadtype;
QHash<QString, QString> params;
QHash<QString, QString> files;
QList<QString> m_filelist;
QList<QString> m_contactlist;
QString m_imagedir;
int dlindex;
QNetworkAccessManager manager;
QNetworkRequest request;

View File

@ -21,6 +21,7 @@ SOURCES += common/friendiqa.cpp \
common/uploadableimage.cpp \
common/xhr.cpp \
common/filesystem.cpp \
common/remoteauthasyncimageprovider.cpp
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
@ -42,7 +43,8 @@ TRANSLATIONS += translations/friendiqa-de.ts \
HEADERS += \
common/uploadableimage.h \
common/xhr.h \
common/filesystem.h
common/filesystem.h \
common/remoteauthasyncimageprovider.h
DISTFILES += \
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) {
msg.model.clear();
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
.import QtQuick.LocalStorage 2.0 as Sql
@ -64,6 +95,20 @@ function friendicaWebRequest(url,rootwindow,callback) {
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
if (filter){
var where = " AND "+ filter +" = '" + filtervalue+"'";
@ -107,7 +152,8 @@ var where = " AND "+ filter +" = '" + filtervalue+"'";
}
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 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) {
Service.readActiveConfig(db,function(login){
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
.import QtQuick.LocalStorage 2.0 as Sql
.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){
var friends=JSON.parse(obj);
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){
// retrieve, save and return groups. Other features currently not implemented
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){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=1'); // check for friends
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'); // check for friends
var contactlist=[];
for (var i=0;i<result.rows.length;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
try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})}
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 newContacts=findNewContacts(news,contacts);
callback(news,newContacts)
@ -166,8 +201,9 @@ function getDirectMessage(login,database,rootwindow,callback){
});
}
})
if(login.newsViewType=="Timeline"){newsfromdb(database,login.username,callback)}
else{chatsfromdb(database,login.username,callback)}
callback()
// if(login.newsViewType=="Timeline"){newsfromdb(database,login.username,callback)}
// else{chatsfromdb(database,login.username,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=[];
for (var i=0;i<userUrlArray.length;i++){
Helperjs.readData(database,"contacts",username,function(userdata){
helpArray.push(userdata[0]);
},"url",userUrlArray[i]);
helpArray.push(objFromArray(allcontacts,"url",userUrlArray[i]));
// Helperjs.readData(database,"contacts",username,function(userdata){
// helpArray.push(userdata[0]);
// },"url",userUrlArray[i]);
}
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');
stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
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');
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 allcontacts=[];
Helperjs.readData(database,"contacts",username,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i));
newsArray[i]=fetchUsersForNews(database,username,newsArray[i])
newsArray[i]=fetchUsersForNews(database,username,newsArray[i],allcontacts)
}
callback(newsArray)});
}
function fetchUsersForNews(database,username,news){//print(JSON.stringify(news))
Helperjs.readData(database,"contacts",username,function(userdata){
news.user=userdata[0];
//print("Fetch user"+JSON.stringify(news.user));
},"id",news.uid);
if(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);
}
function fetchUsersForNews(database,username,news,allcontacts){//print(JSON.stringify(news))
news.user=objFromArray(allcontacts,"id",news.uid);
if(news.in_reply_to_user_id){news.reply_user=objFromArray(allcontacts,"id",news.in_reply_to_user_id)}
news.friendica_owner_object=objFromArray(allcontacts,"url",news.friendica_owner);
// Helperjs.readData(database,"contacts",username,function(userdata){
// news.user=userdata[0];
// //print("Fetch user"+JSON.stringify(news.user));
// },"id",news.uid);
// if(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){
for(var j=0;j<news.friendica_activities.length;j++)
{var friendicaArray=JSON.parse(Qt.atob(news.friendica_activities));
// print("Array: "+friendicaArray[1]);
news.like=getActivitiesUserData(database,username,friendicaArray[0]);
news.dislike=getActivitiesUserData(database,username,friendicaArray[1]);
news.attendyes=getActivitiesUserData(database,username,friendicaArray[2]);
news.attendno=getActivitiesUserData(database,username,friendicaArray[3]);
news.attendmaybe=getActivitiesUserData(database,username,friendicaArray[4]);
news.like=getActivitiesUserData(database,username,allcontacts,friendicaArray[0]);
news.dislike=getActivitiesUserData(database,username,allcontacts,friendicaArray[1]);
news.attendyes=getActivitiesUserData(database,username,allcontacts,friendicaArray[2]);
news.attendno=getActivitiesUserData(database,username,allcontacts,friendicaArray[3]);
news.attendmaybe=getActivitiesUserData(database,username,allcontacts,friendicaArray[4]);
}
Helperjs.readData(database,"contacts",username,function(friendica_owner_data){
news.friendica_owner_object=friendica_owner_data[0];
//print("Fetch friendica_owner"+JSON.stringify(news.friendica_owner));
},"url",news.friendica_owner);
// Helperjs.readData(database,"contacts",username,function(friendica_owner_data){
// news.friendica_owner_object=friendica_owner_data[0];
// //print("Fetch friendica_owner"+JSON.stringify(news.friendica_owner));
// },"url",news.friendica_owner);
}
return news
}
@ -268,9 +311,11 @@ function deleteNews(login,database,newsid,messagetype,rootwindow,callback){
function retweetNews(login,database,newsid,rootwindow,callback){
Helperjs.friendicaPostRequest(login,"/api/statuses/retweet?id="+newsid,"","POST", rootwindow,function (obj){
var answer=JSON.parse(obj);
if(answer.status.error){Helperjs.showMessage("Repost",answer.status.code,rootwindow);}
else{Helperjs.showMessage("Repost",obj,rootwindow)}
})}
if(answer.hasOwnProperty('status'))//('error' in answer.status)
{Helperjs.showMessage("Repost",answer.status.code,rootwindow);}
else{Helperjs.showMessage("Repost",answer.text,rootwindow)}
})
}
function favorite(login,favorite,newsid,rootwindow){
// toggle favorites
@ -299,7 +344,7 @@ function likerequest(login,database,verb,newsid,rootwindow){
//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);
})}
else{print("likerequest"+obj)}})
else{}})
}
function like(login,database,toggle,verb,newsid,rootwindow){
@ -353,11 +398,14 @@ function conversationfromdb(database,user,conversationId,callback){
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 newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; 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)})
}
function requestFavorites(login,database,contacts,rootwindow,callback){
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');
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i));
newsArray[i]=fetchUsersForNews(database,user,newsArray[i]);
newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts);
callback(newsArray);
}})}
@ -393,11 +443,13 @@ function chatsfromdb(database,user,callback,stop_time){
conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id);
}
var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
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 helpernews=newsrs.rows.item(0);
helpernews.newscount=newsrs.rows.length;
helpernews=fetchUsersForNews(database,user,helpernews);
helpernews=fetchUsersForNews(database,user,helpernews,allcontacts);
//var chatArray=[];
// for (var k=0;k<newsrs.rows.length;k++){
// var helperchat=newsrs.rows.item(k);
@ -419,7 +471,16 @@ function inArray(list, prop, val) {
} 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
function objFromArray(list, prop, val) {
if (list.length > 0 ) {
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) {
if(msg.deleteId!==undefined)
{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) {
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}
for (var j=msg.firstalbum;j<limit;j++){
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
}else{
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()
};
}

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
.import QtQuick.LocalStorage 2.0 as Sql
.import "qrc:/js/helper.js" as Helperjs
.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
function initDatabase(database) { // initialize the database object
@ -153,9 +42,10 @@ function initDatabase(database) { // initialize the database object
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 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 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 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){
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.friendicaRemoteAuthRequest(login,login.server+"/cal/"+login.username+"/json",login.server+"/profile/"+login.username,rootwindow,function(obj){
var events = JSON.parse(obj);
db.transaction( function(tx) {
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
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)
})}
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){
// check server with given credentials
@ -295,14 +258,15 @@ try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, functio
db.transaction( function(tx) {
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){
var serverData = JSON.parse(obj);var serverAddons=JSON.stringify(serverData.plugins).replace(/"/g,"");
db.transaction( function(tx) {
var result = tx.executeSql('UPDATE config SET addons="'+ serverAddons+'" WHERE username="'+login.username +'"')})
// Helperjs.friendicaRequest(login,"/friendica/json",rootwindow, function (obj){
// var serverData = JSON.parse(obj);var serverAddons=JSON.stringify(serverData.plugins).replace(/"/g,"");
// db.transaction( function(tx) {
// var result = tx.executeSql('UPDATE config SET addons="'+ serverAddons+'" WHERE username="'+login.username +'"')})
// })
callback(serverconfigString);
})})}
catch (e){callback (e);
})}
catch (e){callback (e);
}}
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]);
if(!db) { return; }
db.transaction( function(tx) {
var rs = tx.executeSql('delete from config'+where);
callback(rs);
var rs1 = tx.executeSql('delete from config'+where);
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){
// Newsjs.getCurrentContacts(login,db,function(contacts){
// contactlist=contacts});
if (contactLoadType=="news"){
if(root.news.length==0){}
else{// show news
Newsjs.storeNews(login,db,news,root,function(dbnews){
if(login.newsViewType=="Timeline"){
Newsjs.newsfromdb(db,login.username,function(dbnews){
root.newsSignal(dbnews);
newstab.newstabstatus=login.newsViewType
})}
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
root.friendsSignal(login.username);
@ -408,37 +383,18 @@ function processNews(callback){
}
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 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]);
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=[];
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){};
//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;
result = tx.executeSql('SELECT * from contacts where username="'+login.username+'" AND url = "'+contact.url+'"'); // check for news url
if(result.rows.length === 1) {// use update
result = tx.executeSql('UPDATE contacts SET id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",imageAge='+currentTime+', profile_image_url="'+contact.profile_image_url+'", description="'+Qt.btoa(contact.description)+'", profile_image="'+imagename+'", protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ Date.parse(Newsjs.cleanDate(contact.created_at))+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+', 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
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=[
{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.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.Controls 2.1
import QtQuick.Controls 2.3
import QtQml 2.2
import Qt.labs.calendar 1.0
import QtQuick.Controls 1.2 as Oldcontrol
import QtQuick.Layouts 1.3
import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs
@ -26,8 +58,8 @@ Rectangle {
eventdays=dayArray})
}
else if (friend!=""){
calendartab.calendartabstatus=friend.substring(friend.lastIndexOf("/")+1,friend.length)
Service.requestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){
calendartab.calendartabstatus=friend.url.substring(friend.url.lastIndexOf("/")+1,friend.url.length)
Service.newRequestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){
events=eventArray;
eventdays=dayArray})
}
@ -71,11 +103,9 @@ Rectangle {
anchors.right: parent.right
anchors.rightMargin:2*mm
text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus
onClicked: {calendartabmenu.popup()}
}
Menu {
Oldcontrol.Menu {
id:calendartabmenu
MenuItem {
Oldcontrol.MenuItem {
text: qsTr("Own Calendar")
onTriggered: {
calendartab.calendartabstatus="Events";
@ -83,6 +113,9 @@ Rectangle {
showEvents("")}
}
}
onClicked: {calendartabmenu.popup()}
}
ListView{
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.Controls 1.2
import "qrc:/js/service.js" as Service
@ -39,8 +70,7 @@ Rectangle{
}
Component.onCompleted:{
//print(JSON.stringify(daylist))
for (var i=0; i<daylist.length;i++){//print(JSON.stringify(events[daylist[i]]));
for (var i=0; i<daylist.length;i++){
var liststate="";if(daylist.length<2){liststate="large"}
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.Dialogs 1.2
import QtQuick.Controls 1.2
@ -23,11 +54,15 @@ StackView{
width:parent.width
height:Math.max(90*mm,root.height-12*mm)
property var users:[]
property bool registeredUser: true
property var userdata: ({})
function setServericon(server){
try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){
var serverdata = JSON.parse(obj);
servericon.source=serverdata.site.logo})} catch(e){print(e)}
}
BlueButton{
id:userButton
text:qsTr("User")
@ -39,6 +74,7 @@ StackView{
useritems=useritems+"MenuItem{text:'"+configBackground.users[i].username+
"'; onTriggered: {Service.readConfig(db,function(obj){
configBackground.registeredUser=true;
userButton.text=obj.username;
servername.text=obj.server;
configBackground.setServericon(obj.server);
@ -60,7 +96,7 @@ StackView{
x: 4*mm; y: 10*mm
}
Text {
text: qsTr("User")
text: qsTr("Nickname")
x: 4*mm; y: 20*mm
}
@ -132,8 +168,18 @@ StackView{
id: username
anchors.fill: parent
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{
color: "light grey"
x: 25*mm; y: 30*mm; width: root.width/2; height: 5*mm;
@ -232,20 +278,24 @@ 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 errormessage="";
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 (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")}
else {errormessage=""}
if (errormessage=="") {
Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){
var credentials=JSON.parse(obj);
if (credentials.hasOwnProperty('status')){
Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
}
else{
filesystem.Directory=userconfig.imagestore;
filesystem.makeDir("contacts");
filesystem.makeDir("albums");
Service.storeConfig(db,userconfig);
Service.readConfig(db,function(userconfig){
Service.getServerConfig(db,userconfig,root, function(obj){
var serverString=obj;
var serverconfigObject=Qt.createQmlObject(serverString,configBackground,"serverconfigOutput");
Helperjs.readData(db,"config","",function(storedUsers){
storedUsers.sort(function(obj1, obj2) {
return obj1.isActive - obj2.isActive;
@ -254,12 +304,15 @@ StackView{
userButton.color="black"
//reset values
root.login=userconfig;
newstab.newstabstatus=userconfig.newsViewType;
root.currentIndex=0;
newstab.active=true;
})},"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 {
@ -272,6 +325,7 @@ StackView{
filesystem.rmDir();
filesystem.Directory=imagestore.text+"albums";
filesystem.rmDir();
configBackground.registeredUser=true;
servername.text="https://...";
servericon.source="";
username.text="";
@ -293,6 +347,7 @@ StackView{
x: root.width/2+8*mm; y: mm; width: 5*mm; height: 5*mm;
text: "+"
onClicked:{
configBackground.registeredUser=true;
servername.text="https://..."
servericon.source="";
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.Controls 1.2
import "qrc:/qml/genericqml"
@ -12,9 +43,9 @@ Rectangle{
textFormat: Text.RichText
width: parent.width
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>"+
"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>"+
"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>"+

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 2.0
QtObject{
property int appWidth: Screen.desktopAvailableWidth
property int appHeight: Screen.desktopAvailableHeight
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
QtObject{
property real appWidth: 500
property real appHeight: 500
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.Controls 1.3
import "qrc:/qml/genericqml"
@ -19,7 +50,7 @@ Rectangle {
y:1
width: 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"}}
}

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.Controls 1.3
import "qrc:/qml/genericqml"
@ -8,7 +39,7 @@ x:mm
y:mm
property var contact:{}
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 {
id: wrapper
@ -50,7 +81,7 @@ Rectangle{
frameVisible: true
id:namelabelflickable
width: root.width-10*mm
height:root.height-50*mm//friendsTabView.height-45*mm
height:root.height-50*mm
x: mm
clip:true
Text{
@ -82,7 +113,7 @@ Rectangle{
fotostab.phototabstatus="Contact";
root.currentIndex=2;
fotostab.active=true;
root.fotoSignal(contact) ;
root.fotoSignal(root.login,contact) ;
contactLargeComponent.destroy();
}
}
@ -93,7 +124,7 @@ Rectangle{
onClicked:{
root.currentIndex=0;
newstab.active=true;
root.messageSignal(contact.id) ;
root.messageSignal(contact) ;
contactLargeComponent.destroy();
}
}
@ -119,7 +150,7 @@ Rectangle{
root.currentIndex=3;
calendartab.active=true;
calendartab.calendartabstatus="Friend"
root.eventSignal(contact.url);
root.eventSignal(contact);
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
import QtQuick 2.0
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.Controls 1.2
import QtQuick.Controls.Styles 1.4
import QtQuick.LocalStorage 2.0
import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/news.js" as Newsjs
import "qrc:/js/service.js" as Service
@ -14,15 +46,28 @@ Rectangle {
function showContactdetails(contact){
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if(contact.isFriend){
friendsTabView.currentIndex=0;
friendsTabView.currentIndex=1;
var contactDetails = component.createObject(friendstab,{"contact": contact})
}
else{friendsTabView.currentIndex=1;
else{friendsTabView.currentIndex=2;
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{
id:friendsTabView
@ -31,23 +76,23 @@ Rectangle {
y:mm
width: root.width-2*mm
height: root.height-10*mm
currentIndex: 0
currentIndex: 1
signal contactsSignal(var contact)
signal groupsSignal(var username)
onCurrentIndexChanged:{
if (currentIndex==0){
if (currentIndex==1){
contactsSignal("")
}
else if (currentIndex==1){
else if (currentIndex==2){
contactsSignal("")
}
else if (currentIndex==2){groupsSignal(root.login.username)}
else if (currentIndex==3){groupsSignal(root.login.username)}
}
style: TabViewStyle {
frameOverlap: 1
tab: Rectangle {
color: "white"
implicitWidth: root.width/3-2*mm
implicitWidth: root.width/4-2*mm
implicitHeight: 4*mm
Text { id: text
anchors.centerIn: parent
@ -61,24 +106,43 @@ Rectangle {
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{
title: qsTr("Friends")
Rectangle{
id: friendsGridTab
property int currentContact:0
function showFriends(contact){
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++){
if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid
}
friendsModel.append({"contact":friendsobject[i]});
}
},"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 {
id: updateFriendsButton
text: "\uf021"
@ -101,8 +165,8 @@ Rectangle {
anchors.top: parent.top
anchors.right:updateFriendsButton.left
anchors.rightMargin:mm
visible: (root.currentContact!=root.newContacts.length)?true:false
value: root.currentContact/root.newContacts.length
visible: (currentContact!=(root.newContacts.length))?true:false
value: currentContact/root.newContacts.length
}
GridView {
@ -126,7 +190,8 @@ Rectangle {
Component.onCompleted: {
root.friendsSignal.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("json",group);
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{

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 "qrc:/js/helper.js" as Helperjs
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.LocalStorage 2.0
import QtQuick.Window 2.0
@ -14,12 +45,13 @@ TabView{
width: osSettings.appWidth
height:osSettings.appHeight
focus:true
property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000]
property var login: Service.readActiveConfig(db)
property var contactlist: []
property real mm: Screen.pixelDensity
signal messageSignal(var friend)
signal fotoSignal(var friend)
signal fotoSignal(var login, var friend)
signal directmessageSignal(var friend)
signal newsSignal(var news)
signal friendsSignal(var username)
@ -28,7 +60,6 @@ TabView{
property var news:[]
property var newContacts:[]
property int currentContact: 0
property string contactLoadType: ""
onLoginChanged:{
@ -38,9 +69,26 @@ TabView{
Newsjs.getCurrentContacts(login,db,function(contacts){
contactlist=contacts})}
}
onNewContactsChanged:{//print(JSON.stringify(newContacts));
if(newContacts.length>0){// download first contact image and update db
Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])}
onNewContactsChanged:{
if(newContacts.length>0){// download contact images and update db
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!=""){
Service.processNews(function(){
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{
target:xhr
onDownloaded:{if(data=="contact"){contacttimer.stop();root.currentContact=root.currentContact+1}}
}
Connections{
target:xhr
onError:{print("Error"+data);
if (data=="contact"){
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) {
//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()})}
}}
result = tx.executeSql('UPDATE contacts SET profile_image="'+filename+'" where profile_image_url="'+url+'"');
})
}
}
}
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: {
if (event.key === osSettings.backKey) {
if (currentIndex==0){
@ -103,7 +127,10 @@ TabView{
})}
}
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 {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
Rectangle{
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.Controls 1.2
import Qt.labs.folderlistmodel 2.1
@ -14,7 +45,11 @@ Rectangle{
x:2*mm
y:10*mm
property string directory: ""
property bool multiSelection: false
property bool multiple: false
property string imageUrl: ""
property var imageUrls: []
signal ready();
function pickImage() {}
Text{
id:directoryText
@ -32,7 +67,7 @@ Rectangle{
anchors.right: parent.right
anchors.rightMargin: 1*mm
text: "\uf057"
onClicked:{imageDialog.destroy()}
onClicked:{ready();imageDialog.destroy()}
}
ListView {
@ -123,22 +158,25 @@ Rectangle{
directory=fileURL
}
else{
if (multiSelection!=true){
attachImageURLs.push(fileURL);
attachImage(fileURL);
if (multiple!=true){
//attachImageURLs.push(fileURL);
//attachImage(fileURL);
imageUrls.push(fileURL);
imageUrl=fileURL;
ready();
imageDialog.destroy()
}
else {
if(selected.visible==true){
attachImageURLs.splice(attachImageURLs.indexOf(fileURL,1))
imageUrls.splice(imageUrls.indexOf(fileURL,1))
selected.visible=false
}
else{
attachImageURLs.push(fileURL);
imageUrls.push(fileURL);
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 "qrc:/js/service.js" as Service
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
import QtQuick 2.0
import QtQuick.Controls 1.2
@ -104,7 +135,6 @@ Rectangle {
xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.status_id)
}
xhr.post();
//replyText.text=""
} 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
import QtQuick 2.0
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 with buttons
import QtQuick 2.0
@ -123,15 +154,6 @@ Flickable{
}
Row{
ImagePicker {
id: imagePicker;
multiple : false
onReady: {
attachImageURLs.push(imagePicker.imageUrl);
attachImage(imagePicker.imageUrl)
}
}
spacing:2
BlueButton{id:permButton
visible: (directmessage==1)?false:true
@ -149,9 +171,9 @@ Flickable{
Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn)
}
else{
//var defaultDirectory="file://"+osSettings.attachImageDir;
//var component = Qt.createComponent("qrc:/qml/genericqml/ImageDialog.qml");
//var imagedialog = component.createObject(messageSend,{"directory": defaultDirectory});
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+
'attachImage(imageUrl)}}',messageSend,"imagePicker");
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.Controls 1.2
import "qrc:/qml/genericqml"
@ -13,21 +44,21 @@ Item {
}
}
Connections{
target:root
onCurrentContactChanged:{
if (root.newContacts.length>0){
if(root.currentContact<root.newContacts.length){
downloadNotice.text= qsTr("Download profile image for ")+ root.newContacts[root.currentContact].name;
//print(root.newContacts[root.currentContact].name)
}
}else{downloadNotice.text=""}
}
}
// Connections{
// target:root
// onCurrentContactChanged:{
// if (root.newContacts.length>0){
// if(root.currentContact<root.newContacts.length){
// downloadNotice.text= qsTr("Download profile image for ")+ root.newContacts[root.currentContact].name;
// //print(root.newContacts[root.currentContact].name)
// }
// }else{downloadNotice.text=""}
// }
// }
Connections{
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
}
}
@ -40,7 +71,7 @@ Item {
var onlynew=true;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){
root.contactLoadType="news";
root.news=rns;root.newContacts=rnc;root.currentContact=0})
root.news=rns;root.newContacts=rnc;})
}
}
}
@ -61,10 +92,10 @@ Item {
newsStack.conversationIndex= conversationIndex;
if(newsitemobject.messagetype==0){
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){
root.news=newsarray;root.newContacts=[];root.currentContact=1;
root.news=newsarray;root.newContacts=[];
})}
}
@ -77,7 +108,14 @@ Item {
function onFriendsMessages(friend){
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){
@ -127,7 +165,10 @@ Item {
BlueButton {
id: quitButton
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 {
id: update
@ -139,12 +180,12 @@ Item {
var onlynew=true;
//print("newstab "+ JSON.stringify(contactlist));
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(ns,nc){
root.news=ns;root.newContacts=nc;root.currentContact=0;
root.news=ns;root.newContacts=nc;
if (ns.length==0){// update last 20 existing news for changes and likes
onlynew=false;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){
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";
var onlynew=true;
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
onlynew=false;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){
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";
newsBusy.running=true;
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.newsSignal.connect(showNews);
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)})}
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.Controls 1.4
import QtQuick.Controls.Styles 1.4
@ -35,7 +66,7 @@ Item {
Image {
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
width: 7*mm
height: 7*mm
@ -295,10 +326,7 @@ Item {
anchors.fill:parent
onClicked:{
conversationsymbol.color="black";
//Newsjs.conversationfromdb(db,login.username,newsitemobject.conversation_id,function(conversation){
var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml");
// var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray});
var conversationItem = component.createObject(friendicaActivities); showConversation(index,newsitemobject)
}
}
@ -334,7 +362,6 @@ Item {
text: qsTr("Conversation")
onTriggered: {
conversationsymbol.color="black";
//Newsjs.conversationfromdb(db,login.username,newsitemobject.conversation_id,function(conversation){
var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml");
var conversationItem = component.createObject(friendicaActivities,{"news":newsitemobject.chatArray});
showConversation(index,newsitemobject)

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 "qrc:/js/service.js" as Service
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.Controls 1.2
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.Controls 1.4
import "qrc:/js/service.js" as Service
@ -6,7 +37,7 @@ import "qrc:/qml/genericqml"
Rectangle{
id:imageDialog
//property var attachImageURLs: []
property var attachImageURLs: []
property var contacts: []
property var groups: []
property var contact_allow:login.permissions[0]
@ -21,15 +52,18 @@ Rectangle{
xhr.clearParams();
xhr.setParam("desc",imageUploadModel.get(inumber).description);
xhr.setParam("album", album.currentText);
xhr.setParam("contact_allow","27");
if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))};
if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))};
//if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))};
//if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))};
//if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))};
if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))};
//if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))};
xhr.setImageFileParam("media", imageUploadModel.get(inumber).imageUrl );
xhr.post();
}
function attachImage(url){
imageUploadModel.append({"imageUrl":url,"description":""})
}
z:2
border.color: "grey"
width: parent.width-4*mm
@ -38,19 +72,6 @@ Rectangle{
y:10*mm
property string directory: ""
ImagePicker {
id: imagePicker;
multiple : true
onReady: {//var urlstring=decodeURIComponent(imagePicker.imageUrl);
//var fileurl="file://"+urlstring.substring(5);
for (var n in imagePicker.imageUrls){
imageUploadModel.append({"imageUrl":imagePicker.imageUrls[n].toString(),"description":""})
}
}
}
Connections{
target:xhr
onError:{print(data)}//if (data=="image"){Helperjs.showMessage()}}
@ -172,10 +193,9 @@ Rectangle{
MouseArea{
anchors.fill: parent
onClicked:{
//var defaultDirectory="file://"+osSettings.attachImageDir;
//var component = Qt.createComponent("qrc:/qml/genericqml/ImageDialog.qml");
//var imagedialog = component.createObject(imageDialog,{"directory": defaultDirectory, "multiSelection": true})
// filesystem.search
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+
'attachImage(imageUrl)}}',imageDialog,"imagePicker");
imagePicker.pickImage()
}
}
@ -226,7 +246,6 @@ Rectangle{
Component.onCompleted:{
albumModel.append({"text":""});
try{Helperjs.readField("album",db,"imageData",login.username,function(storedAlbums){
//print(JSON.stringify(storedAlbums))
for (var n in storedAlbums){
albumModel.append({"text":storedAlbums[n]})}
})}

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
Package {
@ -20,12 +51,14 @@ Package {
BusyIndicator { anchors.centerIn: parent; running: realImage.status != Image.Ready }
Image {
id: realImage;
visible: (albumWrapper.state != '')||(index==0)
width: photoWrapper.width; height: photoWrapper.height
antialiasing: true;
asynchronous: true
autoTransform:true
cache: false
fillMode: Image.PreserveAspectFit;
source: imageLocation
source: (albumWrapper.state == '')&&(index>0)?"":imageLocation
}
Rectangle{
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.Dialogs 1.2
import QtQuick.Controls 1.4
import QtQuick.Controls 1.2
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:/qml/photoqml"
import "qrc:/qml/genericqml"
Rectangle {
id:fotorectangle
y:1
width:root.width-mm
height:root.height-5*mm
color: '#fff'
property var newimages:[]
property int currentimageno: 0
property bool remoteContact: false
onNewimagesChanged:{
if(newimages.length>0){
//print("newimages "+JSON.stringify(newimages));
var ownimagelist=[];
Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){
for (var i=0;i<newimages.length;i++){
if(albums.indexOf(newimages[i].album)==-1){
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);
newImagesProgress.visible=true //download first image
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setImagedir(login.imagestore);
xhr.setFilelist(ownimagelist);
xhr.setDownloadtype("picturelist");
xhr.getlist();
newImagesProgress.visible=true
}
}
onCurrentimagenoChanged:{
if(currentimageno<newimages.length){Service.dataRequest(root.login,newimages[currentimageno].id,root.db,fotostab)};
if(currentimageno==newimages.length){newImagesProgress.visible=false;showFotos("");
if(currentimageno==newimages.length){newImagesProgress.visible=false;showFotos(root.login,"");
newimages=[];currentimageno=0}
// download next image
}
Connections{
target:xhr
onDownloaded:{if(data=="picture"){currentimageno=currentimageno+1}}
onDownloadedjson:{
if(type=="picturelist"){
currentimageno=currentimageno+1
Imagejs.storeImagedata(login,db,jsonObject,fotorectangle)
}
}
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{
target:xhr
onError:{if(data=="picture"){print("Error"+data);
currentimageno=currentimageno+1}}
}
// Connections{
// target:filesystem
@ -54,7 +98,7 @@ Rectangle {
// onSuccess:print("Success deleting");
// }
function showFotos(friend){
function showFotos(login,friend){
if(friend=="backButton"){
if(!albumgridview.currentItem){root.currentIndex=0}
if(albumgridview.currentItem.state=='fullscreen'){
@ -65,11 +109,12 @@ Rectangle {
else{
try {photogroupModel.clear()}catch (e){print(e)}
if (friend){
Service.requestFriendsAlbumPictures(login,friend,fotostab,function(albums){
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture':true}
Imagejs.newRequestFriendsAlbumPictures(login,friend,fotorectangle,function(albums,remoteAuthBool){
remoteContact=remoteAuthBool;
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture':true,'friend':friend}
photoWorker.sendMessage(msg);
})
phototabstatusButton.text=qsTr(friend.screen_name.toString())+qsTr("'s images")
phototabstatusButton.text=friend.screen_name+qsTr("\'s images")
}
else {
@ -79,11 +124,12 @@ Rectangle {
photoWorker.sendMessage(msg);
}
})
}}
}
}
}
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
}
//ImageUploadDialog{}
BlueButton{
id: uploadPhoto
anchors.top: parent.top
@ -118,9 +163,20 @@ Rectangle {
anchors.right:phototabstatusButton.left
anchors.rightMargin:mm
text:"\uf0ed"
onClicked: {
Service.requestList(root.login,root.db, fotostab,function(obj){newimages=obj})
Menu {
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{
@ -130,8 +186,6 @@ Rectangle {
anchors.right: parent.right
anchors.rightMargin:2*mm
text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus
onClicked: {phototabmenu.popup()}
}
Menu {
id:phototabmenu
MenuItem {
@ -139,9 +193,12 @@ Rectangle {
onTriggered: {
fotostab.phototabstatus="Images";
// phototabstatusButton.text=qsTr("Own images");
showFotos("")}
showFotos(root.login,"")}
}
}
onClicked: {phototabmenu.popup()}
}
DelegateModel{
id: visualphotoModel
@ -172,13 +229,15 @@ Rectangle {
text:qsTr("More")
}
MouseArea{anchors.fill:parent
onClicked:{
var lastalbum_id=photogroupModel.get(photogroupModel.count-1);
if(photogroupModel.get(photogroupModel.count-1).foreignPictures==false){
Service.requestFriendsAlbumPictures(friend,fotostab,function(albums){
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':lastalbum_id+1,'foreignPicture':true}
onClicked:{print(photogroupModel.get(0).foreignPicture);
var lastalbum_id=photogroupModel.count-1;
if(photogroupModel.get(photogroupModel.count-1).foreignPicture==true){
Imagejs.newRequestFriendsAlbumPictures(login,photogroupModel.get(0).friend,fotorectangle,function(albums,remoteAuthBool){
remoteContact=remoteAuthBool;
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':lastalbum_id+1,'foreignPicture':true,'friend':photogroupModel.get(0).friend}
photoWorker.sendMessage(msg)
})}
})
}
else{Helperjs.readField("album",root.db, "imageData",root.login.username,function(albums){
var msg = { 'model': photogroupModel,'albums':albums,'foreignPicture': false,'firstalbum':lastalbum_id+1};
photoWorker.sendMessage(msg)})}
@ -202,6 +261,6 @@ Rectangle {
WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"}
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.Controls 1.3
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
Package {
@ -72,7 +104,7 @@ Package {
Component.onCompleted:{
try {photoModel.clear()}catch (e){print(e)}
if(foreignPicture){
Service.requestFriendsPictures(albumlink,fotostab,function(obj){
Imagejs.newRequestFriendsPictures(login,albumlink,friend,remoteContact,remoteauth,root,function(obj){
if (obj) {
for (var k=0;k<obj.length;k++){
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){
if (obj) {
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})
}
}

View File

@ -4,12 +4,12 @@
<context>
<name>CalendarTab</name>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="73"/>
<location filename="../qml/calendarqml/CalendarTab.qml" line="105"/>
<source>Events</source>
<translation>Termine</translation>
</message>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="79"/>
<location filename="../qml/calendarqml/CalendarTab.qml" line="109"/>
<source>Own Calendar</source>
<translation>Eigener Kalender</translation>
</message>
@ -17,80 +17,120 @@
<context>
<name>ConfigTab</name>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="33"/>
<location filename="../qml/configqml/ConfigTab.qml" line="63"/>
<location filename="../qml/configqml/ConfigTab.qml" line="283"/>
<location filename="../qml/configqml/ConfigTab.qml" line="304"/>
<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>Name</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="59"/>
<location filename="../qml/configqml/ConfigTab.qml" line="105"/>
<source>Server</source>
<translation>Server</translation>
</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>
<translation>Passwort</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="72"/>
<location filename="../qml/configqml/ConfigTab.qml" line="118"/>
<source>Image dir.</source>
<translation>Bildverz.</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="77"/>
<location filename="../qml/configqml/ConfigTab.qml" line="123"/>
<source>Max. News</source>
<translation>Max. Nachr.</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="81"/>
<location filename="../qml/configqml/ConfigTab.qml" line="127"/>
<source>News as</source>
<translation>Anzeige</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="85"/>
<location filename="../qml/configqml/ConfigTab.qml" line="131"/>
<source>Interval (0=None)</source>
<translation>Intervall (0=keins)</translation>
</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>
<translation>Bestätigen</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="234"/>
<location filename="../qml/configqml/ConfigTab.qml" line="305"/>
<source>No server given! </source>
<translation>Kein Server angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="235"/>
<source>No username given! </source>
<translation>Kein Nutzername angegeben!</translation>
<location filename="../qml/configqml/ConfigTab.qml" line="306"/>
<source>No nickname given! </source>
<translation>Kein Kurzname angegeben!</translation>
</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>
<translation>Kein Passwort angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="237"/>
<location filename="../qml/configqml/ConfigTab.qml" line="309"/>
<source>No image directory given!</source>
<translation>Kein Verzeichnis für Bilder angegeben!</translation>
</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>
<translation>Maximale News-Anzahl nicht angegeben!</translation>
</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>
<translation>Chronologisch</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="323"/>
<location filename="../qml/configqml/ConfigTab.qml" line="403"/>
<source>Conversations</source>
<translation>Unterhaltungen</translation>
</message>
@ -98,7 +138,7 @@
<context>
<name>ContactComponent</name>
<message>
<location filename="../qml/contactqml/ContactComponent.qml" line="8"/>
<location filename="../qml/contactqml/ContactComponent.qml" line="39"/>
<source>Connect</source>
<translation>Kontaktanfrage</translation>
</message>
@ -106,32 +146,32 @@
<context>
<name>ContactDetailsComponent</name>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="11"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="42"/>
<source>Connect</source>
<translation>Kontaktanfrage</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Description</source>
<translation>Beschreibung</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Location</source>
<translation>Ort</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Posts</source>
<translation>Beiträge</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="64"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="95"/>
<source>URL</source>
<translation>Profilseite</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="65"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="96"/>
<source>Created at</source>
<translation>Erstellt</translation>
</message>
@ -139,17 +179,22 @@
<context>
<name>FriendsTab</name>
<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>
<translation>Freunde</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="135"/>
<location filename="../qml/contactqml/FriendsTab.qml" line="200"/>
<source>Contacts</source>
<translation>Kontakte</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="188"/>
<location filename="../qml/contactqml/FriendsTab.qml" line="253"/>
<source>Groups</source>
<translation>Gruppen</translation>
</message>
@ -168,32 +213,32 @@
<context>
<name>ImageUploadDialog</name>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="96"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="127"/>
<source>Album</source>
<translation>Album</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="101"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="132"/>
<source>Image</source>
<translation>Bild</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="106"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="137"/>
<source>Description</source>
<translation>Beschreibung</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="205"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="236"/>
<source>Upload</source>
<translation>Hochladen</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="208"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="208"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source> No album name given</source>
<translation>Kein Albumname angegeben</translation>
</message>
@ -201,17 +246,17 @@
<context>
<name>MessageSend</name>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="67"/>
<location filename="../qml/newsqml/MessageSend.qml" line="98"/>
<source>Title (optional)</source>
<translation>Überschrift (optional)</translation>
</message>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="149"/>
<location filename="../qml/newsqml/MessageSend.qml" line="180"/>
<source>Error</source>
<translation>Fehler</translation>
</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.
Remove other attachment first!</source>
<translation>Nur ein Anhang derzeit unterstützt.
@ -221,32 +266,31 @@
<context>
<name>NewsTab</name>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="21"/>
<source>Download profile image for </source>
<translation>Lade Profilbild für </translation>
<translation type="vanished">Lade Profilbild für </translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="163"/>
<location filename="../qml/newsqml/NewsTab.qml" line="204"/>
<source>More</source>
<translation>Mehr</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="260"/>
<location filename="../qml/newsqml/NewsTab.qml" line="301"/>
<source>Timeline</source>
<translation>Chronologisch</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="269"/>
<location filename="../qml/newsqml/NewsTab.qml" line="310"/>
<source>Favorites</source>
<translation>Markierte News</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="281"/>
<location filename="../qml/newsqml/NewsTab.qml" line="322"/>
<source>Conversations</source>
<translation>Unterhaltungen</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="289"/>
<location filename="../qml/newsqml/NewsTab.qml" line="330"/>
<source>Notifications</source>
<translation>Meldungen</translation>
</message>
@ -254,82 +298,82 @@
<context>
<name>Newsitem</name>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="16"/>
<location filename="../qml/newsqml/Newsitem.qml" line="47"/>
<source>attending: </source>
<translation>Teilnahme</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="68"/>
<location filename="../qml/newsqml/Newsitem.qml" line="99"/>
<source>Source: </source>
<translation>Quelle: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="69"/>
<location filename="../qml/newsqml/Newsitem.qml" line="100"/>
<source>Direct Message</source>
<translation>Direktnachricht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="84"/>
<location filename="../qml/newsqml/Newsitem.qml" line="115"/>
<source>In reply to </source>
<translation>Antwort an </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="96"/>
<location filename="../qml/newsqml/Newsitem.qml" line="127"/>
<source> comments</source>
<translation> Kommentare</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="190"/>
<location filename="../qml/newsqml/Newsitem.qml" line="221"/>
<source>Attending: </source>
<translation>Teilnahme: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="312"/>
<location filename="../qml/newsqml/Newsitem.qml" line="343"/>
<source>Reply</source>
<translation>Antworten</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="320"/>
<location filename="../qml/newsqml/Newsitem.qml" line="351"/>
<source>DM</source>
<translation>Direktnachricht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="326"/>
<location filename="../qml/newsqml/Newsitem.qml" line="357"/>
<source>Repost</source>
<translation>Teilen</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="329"/>
<location filename="../qml/newsqml/Newsitem.qml" line="360"/>
<source>Success!</source>
<translation>Erledigt!</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="334"/>
<location filename="../qml/newsqml/Newsitem.qml" line="365"/>
<source>Conversation</source>
<translation>Unterhaltung</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="345"/>
<location filename="../qml/newsqml/Newsitem.qml" line="376"/>
<source>Attending</source>
<translation>Teilnahme</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="347"/>
<location filename="../qml/newsqml/Newsitem.qml" line="378"/>
<source>yes</source>
<translation>ja</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="352"/>
<location filename="../qml/newsqml/Newsitem.qml" line="383"/>
<source>maybe</source>
<translation>vielleicht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="357"/>
<location filename="../qml/newsqml/Newsitem.qml" line="388"/>
<source>no</source>
<translation>nein</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="364"/>
<location filename="../qml/newsqml/Newsitem.qml" line="395"/>
<source>Delete</source>
<translation>Löschen</translation>
</message>
@ -337,12 +381,12 @@
<context>
<name>PermissionDialog</name>
<message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="35"/>
<location filename="../qml/genericqml/PermissionDialog.qml" line="66"/>
<source>Friends</source>
<translation>Freunde</translation>
</message>
<message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="96"/>
<location filename="../qml/genericqml/PermissionDialog.qml" line="127"/>
<source>Groups</source>
<translation>Gruppen</translation>
</message>
@ -350,36 +394,269 @@
<context>
<name>PhotoTab</name>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="72"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="115"/>
<source>&apos;s images</source>
<translation>s Bilder</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="132"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="138"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="167"/>
<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>
<translation>Eigene Bilder</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="172"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="227"/>
<source>More</source>
<translation>Mehr</translation>
</message>
</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>
<name>SmileyDialog</name>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="51"/>
<location filename="../qml/newsqml/SmileyDialog.qml" line="82"/>
<source>Standard</source>
<translation>Standard</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="77"/>
<location filename="../qml/newsqml/SmileyDialog.qml" line="108"/>
<source>Addon</source>
<translation>Addon</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="101"/>
<location filename="../qml/newsqml/SmileyDialog.qml" line="132"/>
<source>Adult</source>
<translation>XXX</translation>
</message>
@ -387,131 +664,131 @@
<context>
<name>newsworker</name>
<message>
<location filename="../js/newsworker.js" line="26"/>
<location filename="../js/newsworker.js" line="57"/>
<source>likes this.</source>
<translation>mag das.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="27"/>
<location filename="../js/newsworker.js" line="58"/>
<source>like this.</source>
<translation>mögen das.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="30"/>
<location filename="../js/newsworker.js" line="61"/>
<source>doesn&apos;t like this.</source>
<translation>mag das nicht.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="31"/>
<location filename="../js/newsworker.js" line="62"/>
<source>don&apos;t like this.</source>
<translation>mögen das nicht.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="34"/>
<location filename="../js/newsworker.js" line="65"/>
<source>will attend.</source>
<translation>nehmen teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="35"/>
<location filename="../js/newsworker.js" line="66"/>
<source>persons will attend.</source>
<translation>Personen nehmen teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="38"/>
<location filename="../js/newsworker.js" line="69"/>
<source>will not attend.</source>
<translation>nimmt nicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="39"/>
<location filename="../js/newsworker.js" line="70"/>
<source>persons will not attend.</source>
<translation>Personen nehmen nicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="42"/>
<location filename="../js/newsworker.js" line="73"/>
<source>may attend.</source>
<translation>nimmt vielleicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="43"/>
<location filename="../js/newsworker.js" line="74"/>
<source>persons may attend.</source>
<translation>Personen nehmen vielleicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="46"/>
<location filename="../js/newsworker.js" line="77"/>
<source>yes</source>
<translation>ja</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="47"/>
<location filename="../js/newsworker.js" line="78"/>
<source>no</source>
<translation>nein</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="48"/>
<location filename="../js/newsworker.js" line="79"/>
<source>maybe</source>
<translation>vielleicht</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="64"/>
<location filename="../js/newsworker.js" line="95"/>
<source>seconds</source>
<translation>Sekunden</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="64"/>
<location filename="../js/newsworker.js" line="65"/>
<location filename="../js/newsworker.js" line="66"/>
<location filename="../js/newsworker.js" line="67"/>
<location filename="../js/newsworker.js" line="68"/>
<location filename="../js/newsworker.js" line="69"/>
<location filename="../js/newsworker.js" line="70"/>
<location filename="../js/newsworker.js" line="71"/>
<location filename="../js/newsworker.js" line="72"/>
<location filename="../js/newsworker.js" line="73"/>
<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>her</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="65"/>
<location filename="../js/newsworker.js" line="96"/>
<source>minute</source>
<translation>Minute</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="66"/>
<location filename="../js/newsworker.js" line="97"/>
<source>minutes</source>
<translation>Minuten</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="67"/>
<location filename="../js/newsworker.js" line="98"/>
<source>hour</source>
<translation>Stunde</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="68"/>
<location filename="../js/newsworker.js" line="99"/>
<source>hours</source>
<translation>Stunden</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="69"/>
<location filename="../js/newsworker.js" line="100"/>
<source>day</source>
<translation>Tag</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="70"/>
<location filename="../js/newsworker.js" line="101"/>
<source>days</source>
<translation>Tage</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="71"/>
<location filename="../js/newsworker.js" line="102"/>
<source>month</source>
<translation>Monat</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="72"/>
<location filename="../js/newsworker.js" line="103"/>
<source>months</source>
<translation>Monate</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="73"/>
<location filename="../js/newsworker.js" line="104"/>
<source>years</source>
<translation></translation>
</message>

View File

@ -4,12 +4,12 @@
<context>
<name>CalendarTab</name>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="73"/>
<location filename="../qml/calendarqml/CalendarTab.qml" line="105"/>
<source>Events</source>
<translation>Eventos</translation>
</message>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="79"/>
<location filename="../qml/calendarqml/CalendarTab.qml" line="109"/>
<source>Own Calendar</source>
<translation>Calendario propio</translation>
</message>
@ -17,80 +17,120 @@
<context>
<name>ConfigTab</name>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="33"/>
<location filename="../qml/configqml/ConfigTab.qml" line="63"/>
<location filename="../qml/configqml/ConfigTab.qml" line="283"/>
<location filename="../qml/configqml/ConfigTab.qml" line="304"/>
<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>Usuario</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="59"/>
<location filename="../qml/configqml/ConfigTab.qml" line="105"/>
<source>Server</source>
<translation>Servidor</translation>
</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>
<translation>Contraseña</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="72"/>
<location filename="../qml/configqml/ConfigTab.qml" line="118"/>
<source>Image dir.</source>
<translation>Dir. de imágenes</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="77"/>
<location filename="../qml/configqml/ConfigTab.qml" line="123"/>
<source>Max. News</source>
<translation> Max. de noticias.</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="81"/>
<location filename="../qml/configqml/ConfigTab.qml" line="127"/>
<source>News as</source>
<translation>Noticias como</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="85"/>
<location filename="../qml/configqml/ConfigTab.qml" line="131"/>
<source>Interval (0=None)</source>
<translation>Intervalo (0=ningún)</translation>
</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>
<translation>Confirmar</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="234"/>
<location filename="../qml/configqml/ConfigTab.qml" line="305"/>
<source>No server given! </source>
<translation>¡Servidor no encontrado!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="235"/>
<source>No username given! </source>
<translation>¡Usuario incorrecto!</translation>
<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="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>
<translation>¡Contraseña incorrecta!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="237"/>
<location filename="../qml/configqml/ConfigTab.qml" line="309"/>
<source>No image directory given!</source>
<translation>¡No se ha encontrado el directorio de imágenes!</translation>
</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>
<translation>¡ máximo de noticias incorrecto!</translation>
</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>
<translation>Cronología</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="323"/>
<location filename="../qml/configqml/ConfigTab.qml" line="403"/>
<source>Conversations</source>
<translation>Conversaciones</translation>
</message>
@ -98,7 +138,7 @@
<context>
<name>ContactComponent</name>
<message>
<location filename="../qml/contactqml/ContactComponent.qml" line="8"/>
<location filename="../qml/contactqml/ContactComponent.qml" line="39"/>
<source>Connect</source>
<translation>Conectar</translation>
</message>
@ -106,32 +146,32 @@
<context>
<name>ContactDetailsComponent</name>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="11"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="42"/>
<source>Connect</source>
<translation>Conectar</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Description</source>
<translation>Descripción</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Location</source>
<translation>Localización</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="94"/>
<source>Posts</source>
<translation>Mensajes</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="64"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="95"/>
<source>URL</source>
<translation>URL</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="65"/>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="96"/>
<source>Created at</source>
<translation>Creado en</translation>
</message>
@ -139,17 +179,22 @@
<context>
<name>FriendsTab</name>
<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>
<translation>Amigos</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="135"/>
<location filename="../qml/contactqml/FriendsTab.qml" line="200"/>
<source>Contacts</source>
<translation>Contactos</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="188"/>
<location filename="../qml/contactqml/FriendsTab.qml" line="253"/>
<source>Groups</source>
<translation>Grupos</translation>
</message>
@ -157,32 +202,32 @@
<context>
<name>ImageUploadDialog</name>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="96"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="127"/>
<source>Album</source>
<translation>álbum</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="101"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="132"/>
<source>Image</source>
<translation>imagen</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="106"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="137"/>
<source>Description</source>
<translation>Descripción</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="205"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="236"/>
<source>Upload</source>
<translation>Subir</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="208"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="208"/>
<location filename="../qml/photoqml/ImageUploadDialog.qml" line="239"/>
<source> No album name given</source>
<translation>¡Nombre del álbum no encontrado!</translation>
</message>
@ -190,17 +235,17 @@
<context>
<name>MessageSend</name>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="67"/>
<location filename="../qml/newsqml/MessageSend.qml" line="98"/>
<source>Title (optional)</source>
<translation>Título (opcional)</translation>
</message>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="149"/>
<location filename="../qml/newsqml/MessageSend.qml" line="180"/>
<source>Error</source>
<translation>Error</translation>
</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.
Remove other attachment first!</source>
<translation>Solo se admite adjuntar un solo archivo en este momento.
@ -210,32 +255,31 @@
<context>
<name>NewsTab</name>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="21"/>
<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>
<location filename="../qml/newsqml/NewsTab.qml" line="163"/>
<location filename="../qml/newsqml/NewsTab.qml" line="204"/>
<source>More</source>
<translation>Mas</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="260"/>
<location filename="../qml/newsqml/NewsTab.qml" line="301"/>
<source>Timeline</source>
<translation>Cronología</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="269"/>
<location filename="../qml/newsqml/NewsTab.qml" line="310"/>
<source>Favorites</source>
<translation>Favoritos</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="281"/>
<location filename="../qml/newsqml/NewsTab.qml" line="322"/>
<source>Conversations</source>
<translation>Conversaciones</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="289"/>
<location filename="../qml/newsqml/NewsTab.qml" line="330"/>
<source>Notifications</source>
<translation>Notificaciones</translation>
</message>
@ -243,82 +287,82 @@
<context>
<name>Newsitem</name>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="16"/>
<location filename="../qml/newsqml/Newsitem.qml" line="47"/>
<source>attending: </source>
<translation>Asistiendo: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="68"/>
<location filename="../qml/newsqml/Newsitem.qml" line="99"/>
<source>Source: </source>
<translation>Fuente: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="69"/>
<location filename="../qml/newsqml/Newsitem.qml" line="100"/>
<source>Direct Message</source>
<translation>Mensaje directo</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="84"/>
<location filename="../qml/newsqml/Newsitem.qml" line="115"/>
<source>In reply to </source>
<translation>En respuesta a </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="96"/>
<location filename="../qml/newsqml/Newsitem.qml" line="127"/>
<source> comments</source>
<translation> comentarios</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="190"/>
<location filename="../qml/newsqml/Newsitem.qml" line="221"/>
<source>Attending: </source>
<translation>Asistiendo: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="312"/>
<location filename="../qml/newsqml/Newsitem.qml" line="343"/>
<source>Reply</source>
<translation>Respuesta</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="320"/>
<location filename="../qml/newsqml/Newsitem.qml" line="351"/>
<source>DM</source>
<translation>Mensaje directo</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="326"/>
<location filename="../qml/newsqml/Newsitem.qml" line="357"/>
<source>Repost</source>
<translation>Volver a publicar</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="329"/>
<location filename="../qml/newsqml/Newsitem.qml" line="360"/>
<source>Success!</source>
<translation>éxito!</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="334"/>
<location filename="../qml/newsqml/Newsitem.qml" line="365"/>
<source>Conversation</source>
<translation>Conversación</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="345"/>
<location filename="../qml/newsqml/Newsitem.qml" line="376"/>
<source>Attending</source>
<translation>Asistiendo</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="347"/>
<location filename="../qml/newsqml/Newsitem.qml" line="378"/>
<source>yes</source>
<translation>si</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="352"/>
<location filename="../qml/newsqml/Newsitem.qml" line="383"/>
<source>maybe</source>
<translation>quizás</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="357"/>
<location filename="../qml/newsqml/Newsitem.qml" line="388"/>
<source>no</source>
<translation>no</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="364"/>
<location filename="../qml/newsqml/Newsitem.qml" line="395"/>
<source>Delete</source>
<translation>Borrar</translation>
</message>
@ -326,12 +370,12 @@
<context>
<name>PermissionDialog</name>
<message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="35"/>
<location filename="../qml/genericqml/PermissionDialog.qml" line="66"/>
<source>Friends</source>
<translation>Amigos</translation>
</message>
<message>
<location filename="../qml/genericqml/PermissionDialog.qml" line="96"/>
<location filename="../qml/genericqml/PermissionDialog.qml" line="127"/>
<source>Groups</source>
<translation>Grupos</translation>
</message>
@ -339,36 +383,269 @@
<context>
<name>PhotoTab</name>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="72"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="115"/>
<source>&apos;s images</source>
<translation>s Imágenes</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="132"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="138"/>
<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>Mis imágenes</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="172"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="227"/>
<source>More</source>
<translation>Mas</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">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>
<name>SmileyDialog</name>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="51"/>
<location filename="../qml/newsqml/SmileyDialog.qml" line="82"/>
<source>Standard</source>
<translation>Standard</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="77"/>
<location filename="../qml/newsqml/SmileyDialog.qml" line="108"/>
<source>Addon</source>
<translation>Addon</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="101"/>
<location filename="../qml/newsqml/SmileyDialog.qml" line="132"/>
<source>Adult</source>
<translation>XXX</translation>
</message>
@ -376,131 +653,131 @@
<context>
<name>newsworker</name>
<message>
<location filename="../js/newsworker.js" line="26"/>
<location filename="../js/newsworker.js" line="57"/>
<source>likes this.</source>
<translation>le gusta esto.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="27"/>
<location filename="../js/newsworker.js" line="58"/>
<source>like this.</source>
<translation>me gusta esto.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="30"/>
<location filename="../js/newsworker.js" line="61"/>
<source>doesn&apos;t like this.</source>
<translation>no de ése.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="31"/>
<location filename="../js/newsworker.js" line="62"/>
<source>don&apos;t like this.</source>
<translation>no me gusta.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="34"/>
<location filename="../js/newsworker.js" line="65"/>
<source>will attend.</source>
<translation>asistirá.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="35"/>
<location filename="../js/newsworker.js" line="66"/>
<source>persons will attend.</source>
<translation>Personas que asistirán.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="38"/>
<location filename="../js/newsworker.js" line="69"/>
<source>will not attend.</source>
<translation>no asistirá.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="39"/>
<location filename="../js/newsworker.js" line="70"/>
<source>persons will not attend.</source>
<translation>Personas que no asistirán..</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="42"/>
<location filename="../js/newsworker.js" line="73"/>
<source>may attend.</source>
<translation>Puede asistir.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="43"/>
<location filename="../js/newsworker.js" line="74"/>
<source>persons may attend.</source>
<translation>Personas que pueden asistir.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="46"/>
<location filename="../js/newsworker.js" line="77"/>
<source>yes</source>
<translation>si</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="47"/>
<location filename="../js/newsworker.js" line="78"/>
<source>no</source>
<translation>no</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="48"/>
<location filename="../js/newsworker.js" line="79"/>
<source>maybe</source>
<translation>quizás</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="64"/>
<location filename="../js/newsworker.js" line="95"/>
<source>seconds</source>
<translation>Segundos</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="64"/>
<location filename="../js/newsworker.js" line="65"/>
<location filename="../js/newsworker.js" line="66"/>
<location filename="../js/newsworker.js" line="67"/>
<location filename="../js/newsworker.js" line="68"/>
<location filename="../js/newsworker.js" line="69"/>
<location filename="../js/newsworker.js" line="70"/>
<location filename="../js/newsworker.js" line="71"/>
<location filename="../js/newsworker.js" line="72"/>
<location filename="../js/newsworker.js" line="73"/>
<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>hace</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="65"/>
<location filename="../js/newsworker.js" line="96"/>
<source>minute</source>
<translation>Minuto</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="66"/>
<location filename="../js/newsworker.js" line="97"/>
<source>minutes</source>
<translation>Minutos</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="67"/>
<location filename="../js/newsworker.js" line="98"/>
<source>hour</source>
<translation>Hora</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="68"/>
<location filename="../js/newsworker.js" line="99"/>
<source>hours</source>
<translation>Horas</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="69"/>
<location filename="../js/newsworker.js" line="100"/>
<source>day</source>
<translation>Dia</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="70"/>
<location filename="../js/newsworker.js" line="101"/>
<source>days</source>
<translation>Dias</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="71"/>
<location filename="../js/newsworker.js" line="102"/>
<source>month</source>
<translation>Mes</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="72"/>
<location filename="../js/newsworker.js" line="103"/>
<source>months</source>
<translation>Meses</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="73"/>
<location filename="../js/newsworker.js" line="104"/>
<source>years</source>
<translation>Años</translation>
</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>translations/friendiqa-de.qm</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/genericqml/AttachmentDialog.qml</file>
<file>qml/genericqml/ImageDialog.qml</file>
<file>qml/genericqml/PermissionDialog.qml</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>
</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"
FILESYSTEM *FILESYSTEM::instance()
@ -33,7 +64,7 @@ QString FILESYSTEM::homePath() const
//{
//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>());
// 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
#define FILESYSTEM_H
#include <QDir>
#include <QObject>
//#include <QtAndroidExtras>
//#include <QAndroidActivityResultReceiver>
class FILESYSTEM : public QObject
class FILESYSTEM : public QObject//, public QAndroidActivityResultReceiver
{
Q_OBJECT
Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged)
//Q_PROPERTY(bool direxist READ direxist)
Q_PROPERTY(QString homePath READ homePath)
//Q_PROPERTY(QString cameraPath READ cameraPath)
//Q_PROPERTY(QString cameraPath READ cameraPath)
public:
@ -22,9 +54,11 @@ public:
QFileInfoList fileList();
//bool direxist(QString Directory);
QString homePath() const;
QString cameraPath() const;
//QString cameraPath() const;
// virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data);
signals:
//void imageselected(QString);
void directoryChanged();
//void fileListContent(QList data);
void success(QString data);
@ -34,6 +68,7 @@ public slots:
void makeDir(QString name);
void rmDir();
void rmFile(QString name);
//void searchImage();
//void fileList();
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 <QtQml/QQmlEngine>
#include <QtQuick>
#include "xhr.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[]) {
QApplication app(argc, argv);
QQuickView view;
QTranslator qtTranslator;
qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations");
app.installTranslator(&qtTranslator);
RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider;
view.engine()->addImageProvider("remoteauthimage",imageProvider);
view.rootContext()->setContextProperty("remoteauth", imageProvider);
XHR* xhr = XHR::instance();
view.rootContext()->setContextProperty("xhr", xhr);
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"

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
#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 <QTextCodec>
#include <QUrlQuery>
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QList>
#include <QDataStream>
#include <QJsonDocument>
#include <QJsonObject>
#include "uploadableimage.h"
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)
{
if (downloadtype!=m_downloadtype) {
@ -67,6 +121,21 @@ QString XHR::filename() const
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
{
return m_downloadtype;
@ -91,9 +160,14 @@ void XHR::clearParams()
void XHR::download()
{
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);
reply = manager.get(request);
// reply->ignoreSslErrors();
reply->ignoreSslErrors();
connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead);
//connect(reply,SIGNAL(downloadProgress(qint64,qint64)), this,SLOT(updateDownloadProgress(qint64,qint64)));
connect(reply, &QNetworkReply::finished,this, &XHR::onRequestFinished);
@ -117,9 +191,6 @@ void XHR::get()
QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData;
request.setRawHeader("Authorization", headerData.toLocal8Bit());
// QNetworkCookieJar* cJar = new QNetworkCookieJar;
// manager.setCookieJar(cJar);
request.setUrl(requrl);
reply = manager.get(request);
@ -129,6 +200,20 @@ void XHR::get()
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()
{
qDebug() << "start post to " << m_url;
@ -178,7 +263,7 @@ void XHR::post()
void XHR::onReplyError(QNetworkReply::NetworkError code)
{
qDebug() << code;
emit this->error( bufferToString(), (int) code);
emit this->error( bufferToString(), m_url, (int) code);
buffer.clear();
reply->deleteLater();
}
@ -194,14 +279,45 @@ void XHR::onReplySuccess()
void XHR::onRequestFinished()
{
// Save the file here
//qDebug() << "buffer downloaded "<<buffer;
if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,1);}
else {QFile file(m_filename);
if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,m_url,1);}
else if (m_downloadtype=="picturelist") {
QJsonDocument jsonResponse = QJsonDocument::fromJson(buffer);
QJsonObject jsonObject = jsonResponse.object();
int arraystart=buffer.indexOf('{"data":"')+8;
int arraylength=buffer.indexOf('"',9)-arraystart;
QByteArray b64=buffer.mid(arraystart,arraylength);
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);
emit this->downloaded(m_downloadtype,m_url,m_filename,dlindex);
if(downloadtype()=="contactlist"){dlindex=dlindex+1;XHR::getlist();}
//reply->deleteLater();
}
}
@ -210,15 +326,6 @@ void XHR::onReadyRead()
{
qDebug() << ".";
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)

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
#define XHR_H
@ -5,6 +36,7 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QObject>
#include <QJsonObject>
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 login READ login WRITE setLogin NOTIFY loginChanged)
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)
@ -23,27 +58,38 @@ public:
QString url() const;
QString login() const;
QString filename() const;
QList<QString> contactlist() const;
QList<QString> filelist() const;
QString imagedir() const;
QString downloadtype() const;
signals:
void urlChanged();
void loginChanged();
void filenameChanged();
void contactlistChanged();
void filelistChanged();
void imagedirChanged();
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 error(QString data, int code);
void error(QString data, QString url, int code);
public slots:
void setUrl(QString url);
void setLogin(QString login);
void setDownloadtype(QString downloadtype);
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 setImageFileParam(QString name, QString url);
void clearParams();
void post();
void get();
void getlist();
void download();
private slots:
@ -62,6 +108,10 @@ private:
QString m_downloadtype;
QHash<QString, QString> params;
QHash<QString, QString> files;
QList<QString> m_filelist;
QList<QString> m_contactlist;
QString m_imagedir;
int dlindex;
QNetworkAccessManager manager;
QNetworkRequest request;

View File

@ -10,15 +10,16 @@
# - translation filenames have to be changed
# The name of your application
TEMPLATE = app
TARGET = friendiqa
CONFIG += debug
CONFIG += release
QT += qml quick gui widgets
SOURCES += common/friendiqa.cpp \
common/uploadableimage.cpp \
common/xhr.cpp \
common/filesystem.cpp \
common/imagepickerandroid.cpp
common/remoteauthasyncimageprovider.cpp
RESOURCES = application.qrc
@ -31,27 +32,22 @@ OTHER_FILES += qml/friendiqa.qml \
qml/configqml/*.qml
js/*.js
# German translation is enabled as an example. If you aren't
# planning to localize your app, remember to comment out the
# following TRANSLATIONS line. And also do not forget to
# modify the localized app name in the the .desktop file.
TRANSLATIONS += translations/friendiqa-de.ts
TRANSLATIONS += translations/friendiqa-de.ts \
translations/friendiqa-es.ts \
translations/friendiqa-it.ts
HEADERS += \
common/uploadableimage.h \
common/xhr.h \
common/filesystem.h \
common/imagepickerandroid.h
common/remoteauthasyncimageprovider.h
DISTFILES += \
qml/calendarqml/*.qml
translations/*.ts
qml/*.qml
qml/newsqml/*.qml
qml/contactqml/*.qml
qml/photoqml/*.qml
qml/configqml/*.qml
js/*.js
qml/calendarqml/*.qml \
translations/*.ts \
translations/*.qm \
qml/*.qml \
qml/newsqml/*.qml \
qml/contactqml/*.qml \
qml/photoqml/*.qml \
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) {
msg.model.clear();
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
.import QtQuick.LocalStorage 2.0 as Sql
@ -64,6 +95,20 @@ function friendicaWebRequest(url,rootwindow,callback) {
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
if (filter){
var where = " AND "+ filter +" = '" + filtervalue+"'";
@ -107,7 +152,8 @@ var where = " AND "+ filter +" = '" + filtervalue+"'";
}
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 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) {
Service.readActiveConfig(db,function(login){
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
.import QtQuick.LocalStorage 2.0 as Sql
.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){
var friends=JSON.parse(obj);
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){
// retrieve, save and return groups. Other features currently not implemented
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
Helperjs.friendicaRequest(login,"/api/friendica/group_show",rootwindow, function (obj){print(obj);
Helperjs.friendicaRequest(login,"/api/friendica/group_show",rootwindow, function (obj){
var groups=JSON.parse(obj);
db.transaction( function(tx) {
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){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=1'); // check for friends
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'); // check for friends
var contactlist=[];
for (var i=0;i<result.rows.length;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
try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})}
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 newContacts=findNewContacts(news,contacts);
callback(news,newContacts)
@ -86,7 +121,7 @@ function getCurrentContacts(login,database,callback){
callback(contactlist)
}
function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(news))
function findNewContacts(news,contacts){
var newContacts=[];
for (var i=0;i<news.length;i++){
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))){
// news[i].friendica_owner.isFriend=0;
// newContacts.push(news[i].friendica_owner);
// }
var owner_url=news[i].friendica_owner.url;
if(contacts.indexOf(owner_url)==-1 && !(inArray(newContacts,"url",owner_url))){
news[i].friendica_owner.isFriend=0;
newContacts.push(news[i].friendica_owner);
}
}
return newContacts
}
@ -165,8 +201,9 @@ function getDirectMessage(login,database,rootwindow,callback){
});
}
})
if(login.newsViewType=="Timeline"){newsfromdb(database,login.username,callback)}
else{chatsfromdb(database,login.username,callback)}
callback()
// if(login.newsViewType=="Timeline"){newsfromdb(database,login.username,callback)}
// else{chatsfromdb(database,login.username,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=[];
for (var i=0;i<userUrlArray.length;i++){
Helperjs.readData(database,"contacts",username,function(userdata){
helpArray.push(userdata[0]);
},"url",userUrlArray[i]);
helpArray.push(objFromArray(allcontacts,"url",userUrlArray[i]));
// Helperjs.readData(database,"contacts",username,function(userdata){
// helpArray.push(userdata[0]);
// },"url",userUrlArray[i]);
}
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');
stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
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');
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 allcontacts=[];
Helperjs.readData(database,"contacts",username,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i));
newsArray[i]=fetchUsersForNews(database,username,newsArray[i])
newsArray[i]=fetchUsersForNews(database,username,newsArray[i],allcontacts)
}
callback(newsArray)});
}
function fetchUsersForNews(database,username,news){//print(JSON.stringify(news))
Helperjs.readData(database,"contacts",username,function(userdata){
news.user=userdata[0];
//print("Fetch user"+JSON.stringify(news.user));
},"id",news.uid);
if(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);
}
function fetchUsersForNews(database,username,news,allcontacts){//print(JSON.stringify(news))
news.user=objFromArray(allcontacts,"id",news.uid);
if(news.in_reply_to_user_id){news.reply_user=objFromArray(allcontacts,"id",news.in_reply_to_user_id)}
news.friendica_owner_object=objFromArray(allcontacts,"url",news.friendica_owner);
// Helperjs.readData(database,"contacts",username,function(userdata){
// news.user=userdata[0];
// //print("Fetch user"+JSON.stringify(news.user));
// },"id",news.uid);
// if(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){
for(var j=0;j<news.friendica_activities.length;j++)
{var friendicaArray=JSON.parse(Qt.atob(news.friendica_activities));
// print("Array: "+friendicaArray[1]);
news.like=getActivitiesUserData(database,username,friendicaArray[0]);
news.dislike=getActivitiesUserData(database,username,friendicaArray[1]);
news.attendyes=getActivitiesUserData(database,username,friendicaArray[2]);
news.attendno=getActivitiesUserData(database,username,friendicaArray[3]);
news.attendmaybe=getActivitiesUserData(database,username,friendicaArray[4]);
news.like=getActivitiesUserData(database,username,allcontacts,friendicaArray[0]);
news.dislike=getActivitiesUserData(database,username,allcontacts,friendicaArray[1]);
news.attendyes=getActivitiesUserData(database,username,allcontacts,friendicaArray[2]);
news.attendno=getActivitiesUserData(database,username,allcontacts,friendicaArray[3]);
news.attendmaybe=getActivitiesUserData(database,username,allcontacts,friendicaArray[4]);
}
Helperjs.readData(database,"contacts",username,function(friendica_owner_data){
news.friendica_owner_object=friendica_owner_data[0];
//print("Fetch friendica_owner"+JSON.stringify(news.friendica_owner));
},"url",news.friendica_owner);
// Helperjs.readData(database,"contacts",username,function(friendica_owner_data){
// news.friendica_owner_object=friendica_owner_data[0];
// //print("Fetch friendica_owner"+JSON.stringify(news.friendica_owner));
// },"url",news.friendica_owner);
}
return news
}
@ -267,17 +311,17 @@ function deleteNews(login,database,newsid,messagetype,rootwindow,callback){
function retweetNews(login,database,newsid,rootwindow,callback){
Helperjs.friendicaPostRequest(login,"/api/statuses/retweet?id="+newsid,"","POST", rootwindow,function (obj){
var answer=JSON.parse(obj);
if(answer.status.error){Helperjs.showMessage("Repost",answer.status.code,rootwindow);}
else{Helperjs.showMessage("Repost",obj,rootwindow)}
})}
if(answer.hasOwnProperty('status'))//('error' in answer.status)
{Helperjs.showMessage("Repost",answer.status.code,rootwindow);}
else{Helperjs.showMessage("Repost",answer.text,rootwindow)}
})
}
function favorite(login,favorite,newsid,rootwindow){
// toggle favorites
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){
print("Favorite destroyed "+obj);
})}
}
@ -300,7 +344,7 @@ function likerequest(login,database,verb,newsid,rootwindow){
//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);
})}
else{print("likerequest"+obj)}})
else{}})
}
function like(login,database,toggle,verb,newsid,rootwindow){
@ -354,11 +398,14 @@ function conversationfromdb(database,user,conversationId,callback){
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 newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; 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)})
}
function requestFavorites(login,database,contacts,rootwindow,callback){
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');
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i));
newsArray[i]=fetchUsersForNews(database,user,newsArray[i]);
newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts);
callback(newsArray);
}})}
@ -394,11 +443,13 @@ function chatsfromdb(database,user,callback,stop_time){
conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id);
}
var newsArray=[];
var allcontacts=[];
Helperjs.readData(database,"contacts",user,function(obj){allcontacts=obj});
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 helpernews=newsrs.rows.item(0);
helpernews.newscount=newsrs.rows.length;
helpernews=fetchUsersForNews(database,user,helpernews);
helpernews=fetchUsersForNews(database,user,helpernews,allcontacts);
//var chatArray=[];
// for (var k=0;k<newsrs.rows.length;k++){
// var helperchat=newsrs.rows.item(k);
@ -420,7 +471,16 @@ function inArray(list, prop, val) {
} 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
function objFromArray(list, prop, val) {
if (list.length > 0 ) {
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) {
if(msg.deleteId)
if(msg.deleteId!==undefined)
{msg.model.remove(msg.deleteId);
msg.model.sync()
}
@ -16,9 +47,12 @@ else{
newsitemobject.user.profile_image_url="";
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={};
if (newsitemobject.messagetype==0){
try{if (newsitemobject.messagetype==0){
if (newsitemobject.like.length>0){
if (newsitemobject.like.length==1){likeText= Qt.atob(newsitemobject.like[0].name)+" "+ qsTr("likes 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(1)!=-1){self.liked=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 attachmentList=[];if(newsitemobject.attachments){
var attachmentList=[];try{if(newsitemobject.attachments){
var attachArray=JSON.parse(Qt.atob(newsitemobject.attachments));
for (var image in attachArray){if(attachArray[image].mimetype=="image/gif"){
attachmentList.push(attachArray[image])
}
}
}
}}catch(e){print("attachment "+e)}
newsitemobject.attachmentList=attachmentList;
var seconds=(msg.currentTime-newsitemobject.created_at)/1000;
var timestring="";

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) {
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}
for (var j=msg.firstalbum;j<limit;j++){
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
}else{
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()
};
}

View File

@ -1,154 +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
.import QtQuick.LocalStorage 2.0 as Sql
.import "qrc:/js/helper.js" as Helperjs
.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
function initDatabase(database) { // initialize the database object
@ -157,10 +42,12 @@ function initDatabase(database) { // initialize the database object
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 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 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 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){
@ -172,6 +59,7 @@ return (newpermArray)
function getEvents(database,login,rootwindow,callback){
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.friendicaRemoteAuthRequest(login,login.server+"/cal/"+login.username+"/json",login.server+"/profile/"+login.username,rootwindow,function(obj){
var events = JSON.parse(obj);
db.transaction( function(tx) {
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
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)
})}
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){
// check server with given credentials
@ -298,14 +258,15 @@ try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, functio
db.transaction( function(tx) {
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){
var serverData = JSON.parse(obj);var serverAddons=JSON.stringify(serverData.plugins).replace(/"/g,"");
db.transaction( function(tx) {
var result = tx.executeSql('UPDATE config SET addons="'+ serverAddons+'" WHERE username="'+login.username +'"')})
// Helperjs.friendicaRequest(login,"/friendica/json",rootwindow, function (obj){
// var serverData = JSON.parse(obj);var serverAddons=JSON.stringify(serverData.plugins).replace(/"/g,"");
// db.transaction( function(tx) {
// var result = tx.executeSql('UPDATE config SET addons="'+ serverAddons+'" WHERE username="'+login.username +'"')})
// })
callback(serverconfigString);
})})}
catch (e){callback (e);
})}
catch (e){callback (e);
}}
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]);
if(!db) { return; }
db.transaction( function(tx) {
var rs = tx.executeSql('delete from config'+where);
callback(rs);
var rs1 = tx.executeSql('delete from config'+where);
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) {
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
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
for (var i=0;i<result.rows.length;i++){
filesystem.rmFile(result.rows.item(i).profile_image);
@ -373,16 +339,22 @@ function cleanContacts(login,database,callback){
}
function processNews(callback){
// Newsjs.getCurrentContacts(login,db,function(contacts){
// contactlist=contacts});
if (contactLoadType=="news"){
if(root.news.length==0){}
else{// show news
Newsjs.storeNews(login,db,news,root,function(dbnews){
if(login.newsViewType=="Timeline"){
Newsjs.newsfromdb(db,login.username,function(dbnews){
root.newsSignal(dbnews);
newstab.newstabstatus=login.newsViewType
})}
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
root.friendsSignal(login.username);
@ -411,37 +383,18 @@ function processNews(callback){
}
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 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]);
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=[];
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){};
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;
result = tx.executeSql('SELECT * from contacts where username="'+login.username+'" AND url = "'+contact.url+'"'); // check for news url
if(result.rows.length === 1) {// use update
result = tx.executeSql('UPDATE contacts SET id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",imageAge='+currentTime+', profile_image_url="'+contact.profile_image_url+'", description="'+Qt.btoa(contact.description)+'", profile_image="'+imagename+'", protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ Date.parse(Newsjs.cleanDate(contact.created_at))+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+', 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
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=[
{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.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.Controls 2.1
import QtQuick.Controls 2.3
import QtQml 2.2
import Qt.labs.calendar 1.0
import QtQuick.Controls 1.2 as Oldcontrol
import QtQuick.Layouts 1.3
import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs
@ -18,7 +50,7 @@ Rectangle {
property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000
property var events:[]
property var eventdays:[]
onEventdaysChanged: print(JSON.stringify(eventdays))
//onEventdaysChanged: print(JSON.stringify(eventdays))
function showEvents(friend){
if(friend=="backButton"){Service.eventsfromdb(db,login.username,function(eventArray,dayArray){
@ -26,8 +58,8 @@ Rectangle {
eventdays=dayArray})
}
else if (friend!=""){
calendartab.calendartabstatus=friend.substring(friend.lastIndexOf("/")+1,friend.length)
Service.requestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){
calendartab.calendartabstatus=friend.url.substring(friend.url.lastIndexOf("/")+1,friend.url.length)
Service.newRequestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){
events=eventArray;
eventdays=dayArray})
}
@ -71,11 +103,9 @@ Rectangle {
anchors.right: parent.right
anchors.rightMargin:2*mm
text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus
onClicked: {calendartabmenu.popup()}
}
Menu {
Oldcontrol.Menu {
id:calendartabmenu
MenuItem {
Oldcontrol.MenuItem {
text: qsTr("Own Calendar")
onTriggered: {
calendartab.calendartabstatus="Events";
@ -83,6 +113,9 @@ Rectangle {
showEvents("")}
}
}
onClicked: {calendartabmenu.popup()}
}
ListView{
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.Controls 1.2
import "qrc:/js/service.js" as Service
@ -39,8 +70,7 @@ Rectangle{
}
Component.onCompleted:{
//print(JSON.stringify(daylist))
for (var i=0; i<daylist.length;i++){//print(JSON.stringify(events[daylist[i]]));
for (var i=0; i<daylist.length;i++){
var liststate="";if(daylist.length<2){liststate="large"}
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.Dialogs 1.2
import QtQuick.Controls 1.2
import "qrc:/js/service.js" as Service
import "qrc:/js/layout.js" as Layoutjs
import "qrc:/js/helper.js" as Helperjs
@ -22,11 +54,15 @@ StackView{
width:parent.width
height:Math.max(90*mm,root.height-12*mm)
property var users:[]
property bool registeredUser: true
property var userdata: ({})
function setServericon(server){
try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){
var serverdata = JSON.parse(obj);
servericon.source=serverdata.site.logo})} catch(e){print(e)}
}
BlueButton{
id:userButton
text:qsTr("User")
@ -38,6 +74,7 @@ StackView{
useritems=useritems+"MenuItem{text:'"+configBackground.users[i].username+
"'; onTriggered: {Service.readConfig(db,function(obj){
configBackground.registeredUser=true;
userButton.text=obj.username;
servername.text=obj.server;
configBackground.setServericon(obj.server);
@ -59,7 +96,7 @@ StackView{
x: 4*mm; y: 10*mm
}
Text {
text: qsTr("User")
text: qsTr("Nickname")
x: 4*mm; y: 20*mm
}
@ -131,8 +168,18 @@ StackView{
id: username
anchors.fill: parent
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{
color: "light grey"
x: 25*mm; y: 30*mm; width: root.width/2; height: 5*mm;
@ -231,20 +278,24 @@ 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 errormessage="";
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 (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")}
else {errormessage=""}
if (errormessage=="") {
Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){
var credentials=JSON.parse(obj);
if (credentials.hasOwnProperty('status')){
Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
}
else{
filesystem.Directory=userconfig.imagestore;
filesystem.makeDir("contacts");
filesystem.makeDir("albums");
Service.storeConfig(db,userconfig);
Service.readConfig(db,function(userconfig){
Service.getServerConfig(db,userconfig,root, function(obj){
var serverString=obj;
var serverconfigObject=Qt.createQmlObject(serverString,configBackground,"serverconfigOutput");
Helperjs.readData(db,"config","",function(storedUsers){
storedUsers.sort(function(obj1, obj2) {
return obj1.isActive - obj2.isActive;
@ -253,12 +304,15 @@ StackView{
userButton.color="black"
//reset values
root.login=userconfig;
newstab.newstabstatus=userconfig.newsViewType;
root.currentIndex=0;
newstab.active=true;
})},"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 {
@ -271,6 +325,7 @@ StackView{
filesystem.rmDir();
filesystem.Directory=imagestore.text+"albums";
filesystem.rmDir();
configBackground.registeredUser=true;
servername.text="https://...";
servericon.source="";
username.text="";
@ -292,6 +347,7 @@ StackView{
x: root.width/2+8*mm; y: mm; width: 5*mm; height: 5*mm;
text: "+"
onClicked:{
configBackground.registeredUser=true;
servername.text="https://..."
servericon.source="";
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.Controls 1.2
import "qrc:/qml/genericqml"
@ -10,15 +41,18 @@ Rectangle{
anchors.top:closeButton.bottom
anchors.topMargin: mm
textFormat: Text.RichText
wrapMode: Text.Wrap
text: "<b>Friendiqa v0.1 </b><br>Licensed under GPL 3<br> "+
width: parent.width
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>"+
"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>"+
"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>"+
"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:{
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 2.0
QtObject{
property int appWidth: Screen.desktopAvailableWidth
property int appHeight: Screen.desktopAvailableHeight
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
QtObject{
property real appWidth: 500
property real appHeight: 500
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.Controls 1.3
import "qrc:/qml/genericqml"
@ -19,8 +50,8 @@ Rectangle {
y:1
width: 10*mm
height:10*mm
source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url
onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}
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"}}
}
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.Controls 1.3
import "qrc:/qml/genericqml"
@ -8,7 +39,7 @@ x:mm
y:mm
property var contact:{}
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 {
id: wrapper
@ -50,7 +81,7 @@ Rectangle{
frameVisible: true
id:namelabelflickable
width: root.width-10*mm
height:root.height-50*mm//friendsTabView.height-45*mm
height:root.height-50*mm
x: mm
clip:true
Text{
@ -82,7 +113,7 @@ Rectangle{
fotostab.phototabstatus="Contact";
root.currentIndex=2;
fotostab.active=true;
root.fotoSignal(contact) ;
root.fotoSignal(root.login,contact) ;
contactLargeComponent.destroy();
}
}
@ -93,7 +124,7 @@ Rectangle{
onClicked:{
root.currentIndex=0;
newstab.active=true;
root.messageSignal(contact.id) ;
root.messageSignal(contact) ;
contactLargeComponent.destroy();
}
}
@ -119,7 +150,7 @@ Rectangle{
root.currentIndex=3;
calendartab.active=true;
calendartab.calendartabstatus="Friend"
root.eventSignal(contact.url);
root.eventSignal(contact);
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
import QtQuick 2.0
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.Controls 1.2
import QtQuick.Controls.Styles 1.4
import QtQuick.LocalStorage 2.0
import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/news.js" as Newsjs
import "qrc:/js/service.js" as Service
@ -14,15 +46,28 @@ Rectangle {
function showContactdetails(contact){
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if(contact.isFriend){
friendsTabView.currentIndex=0;
friendsTabView.currentIndex=1;
var contactDetails = component.createObject(friendstab,{"contact": contact})
}
else{friendsTabView.currentIndex=1;
else{friendsTabView.currentIndex=2;
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{
id:friendsTabView
@ -31,23 +76,23 @@ Rectangle {
y:mm
width: root.width-2*mm
height: root.height-10*mm
currentIndex: 0
currentIndex: 1
signal contactsSignal(var contact)
signal groupsSignal(var username)
onCurrentIndexChanged:{
if (currentIndex==0){
if (currentIndex==1){
contactsSignal("")
}
else if (currentIndex==1){
else if (currentIndex==2){
contactsSignal("")
}
else if (currentIndex==2){groupsSignal(root.login.username)}
else if (currentIndex==3){groupsSignal(root.login.username)}
}
style: TabViewStyle {
frameOverlap: 1
tab: Rectangle {
color: "white"
implicitWidth: root.width/3-2*mm
implicitWidth: root.width/4-2*mm
implicitHeight: 4*mm
Text { id: text
anchors.centerIn: parent
@ -61,24 +106,43 @@ Rectangle {
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{
title: qsTr("Friends")
Rectangle{
id: friendsGridTab
property int currentContact:0
function showFriends(contact){
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++){
if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid
}
friendsModel.append({"contact":friendsobject[i]});
}
},"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 {
id: updateFriendsButton
text: "\uf021"
@ -101,8 +165,8 @@ Rectangle {
anchors.top: parent.top
anchors.right:updateFriendsButton.left
anchors.rightMargin:mm
visible: (root.currentContact!=root.newContacts.length)?true:false
value: root.currentContact/root.newContacts.length
visible: (currentContact!=(root.newContacts.length))?true:false
value: currentContact/root.newContacts.length
}
GridView {
@ -126,7 +190,8 @@ Rectangle {
Component.onCompleted: {
root.friendsSignal.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("json",group);
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{
@ -242,17 +296,17 @@ Rectangle {
Newsjs.requestGroups(root.login,root.db,root,function(){
showGroups(root.login.username)})}
}
BlueButton {
id: newGroupButton
text: "\uf234"
anchors.top: parent.top
anchors.topMargin: mm
anchors.right: updateGroupsButton.left
anchors.rightMargin: mm
onClicked: {
groupsModel.append({"group": {"new":true}});
}
}
// BlueButton {
// id: newGroupButton
// text: "\uf234"
// anchors.top: parent.top
// anchors.topMargin: mm
// anchors.right: updateGroupsButton.left
// anchors.rightMargin: mm
// onClicked: {
// groupsModel.append({"group": {"new":true}});
// }
// }
GridView {
id: groupsView
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 "qrc:/js/helper.js" as Helperjs
import "qrc:/js/news.js" as Newsjs
@ -56,7 +87,8 @@ Item {
anchors.topMargin: 3
anchors.top: parent.top
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)}
groupmembers=JSON.parse(groups);
for (var user in groupmembers){
@ -64,7 +96,8 @@ Item {
if (userdata[0]){groupModel.append({"groupmember":userdata[0]})}
},"id",groupmembers[user])
} //catch(e){}
},"groupname",group.groupname);}
},"groupname",group.groupname);
//}
groupComponent.state="large"
}
}
@ -109,14 +142,14 @@ Item {
root.contactdetailsSignal(groupmember)
}
}
BlueButton{
anchors.left: memberrectangle.right
anchors.margins: 1*mm
text: "\uf056"
onClicked:{
groupModel.remove(index)
}
}
// BlueButton{
// anchors.left: memberrectangle.right
// anchors.margins: 1*mm
// text: "\uf056"
// onClicked:{
// groupModel.remove(index)
// }
// }
}
}
}
@ -139,54 +172,6 @@ Item {
anchors.top: groupListView.bottom
anchors.topMargin: 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{
id: closeButton
text: "\uf057"
@ -194,6 +179,53 @@ Item {
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"}}

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