Friendiqa v0.2.1

This commit is contained in:
LubuWest 2018-04-11 21:50:43 +02:00
parent c85f857afe
commit ee50729e0d
45 changed files with 580 additions and 146 deletions

View File

@ -51,5 +51,10 @@
* Account deletion now also removes news, image data and events from local db * Account deletion now also removes news, image data and events from local db
# Translations # # Translations #
* Italian thanks to Davide de Prisco * Italian thanks to Davide de Prisco
## v0.2.1 ##
* Fix for [issue 4](https://github.com/LubuWest/Friendiqa/issues/4)
* Fix for Friendica [issue 4689](https://github.com/friendica/friendica/issues/4689)
* Long posts are automatically truncated
* Intents for pictures (Send one image from gallery: attach to message, send multiple images: upload to album)

BIN
Friendiqa_v0.2.1.apk Normal file

Binary file not shown.

View File

@ -2,7 +2,7 @@
QML based client for the Friendica Social Network. QML based client for the Friendica Social Network.
Tabs for news (incl. Direct Messages), friends, photos and events. Tabs for news (incl. Direct Messages), friends, photos and events.
OS: currently Linux and Android(4.3). OS: currently Linux and Android (4.3 Jelly Bean).
Source code is a QtCreator project. Source code is a QtCreator project.
## Screenshots ## ## Screenshots ##
@ -20,15 +20,16 @@ QML based client for the Friendica Social Network.
Currently supported: Currently supported:
* Shows Posts from friends, favorited messages, Direct Messages and Notifications * Shows Posts from friends, favorited messages, Direct Messages and Notifications
* Open links in external browser * Open links in external browser
* * Click on contact photo for contact details
Click on contact photo for contact details
* Click on like text for additional contact info * Click on like text for additional contact info
* Deletion, Reposting, Answering of Posts * Deletion, Reposting, Answering of Posts
* Expand truncated news items
* Liking, disliking, favoriting * Liking, disliking, favoriting
* Attending for event posts * Attending for event posts
* Update fetches new posts (up to last 50) since last in local DB * Update fetches new posts (up to last 50) since last in local DB
* More shows older posts from local DB * More shows older posts from local DB
* Create new Message with images or direct messages, Contact/Group access rights(can be stored), smileys * Create new Message with images or direct messages, Contact/Group access rights(can be stored), smileys
* Send image from Android gallery
* Native Android image dialog * Native Android image dialog
ToDo: ToDo:
@ -64,7 +65,7 @@ ToDo:
# Images # # Images #
Currently supported: Currently supported:
* Download public and private own images to local directory * Download public and private own images to local directory
* Upload picture to album with descriptions(public) * Upload picture to album with descriptions(public), send from gallery
* Delete own pictures and albums on client and server * Delete own pictures and albums on client and server
* Show albums in grid, show images in album in grid and fullscreen * Show albums in grid, show images in album in grid and fullscreen
* Show public and private (Friendica 3.6 server required) albums and images of contacts * Show public and private (Friendica 3.6 server required) albums and images of contacts

View File

@ -1,11 +1,17 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.2" android:versionCode="4" android:installLocation="auto"> <manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.2.1" android:versionCode="5" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:vmSafeMode="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Friendiqa" android:icon="@drawable/friendiqa" android:logo="@drawable/friendiqa" android:theme="@android:style/Theme.Holo.Light"> <application android:hardwareAccelerated="true" android:vmSafeMode="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Friendiqa" android:icon="@drawable/friendiqa" android:logo="@drawable/friendiqa" android:theme="@android:style/Theme.Holo.Light">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="androidnative.friendiqa.FriendiqaActivity" android:label="Friendiqa" android:screenOrientation="unspecified" android:launchMode="singleTop"> <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="androidnative.friendiqa.FriendiqaActivity" android:label="Friendiqa" android:screenOrientation="unspecified" android:launchMode="singleInstance" android:taskAffinity="">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/*"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="friendiqa"/> <meta-data android:name="android.app.lib_name" android:value="friendiqa"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/> <meta-data android:name="android.app.repository" android:value="default"/>

0
source-android/android/libcrypto.so Executable file → Normal file
View File

0
source-android/android/libssl.so Executable file → Normal file
View File

View File

@ -2,9 +2,9 @@ package androidnative.friendiqa;
import androidnative.AndroidNativeActivity; import androidnative.AndroidNativeActivity;
/**
* Created by benlau on 8/3/2017.
*/
public class FriendiqaActivity extends AndroidNativeActivity { public class FriendiqaActivity extends AndroidNativeActivity {
public FriendiqaActivity() { public FriendiqaActivity() {
@ -13,4 +13,8 @@ public class FriendiqaActivity extends AndroidNativeActivity {
QT_ANDROID_THEMES = new String[] {""}; QT_ANDROID_THEMES = new String[] {""};
QT_ANDROID_DEFAULT_THEME = ""; QT_ANDROID_DEFAULT_THEME = "";
} }
} }

View File

@ -0,0 +1,205 @@
// from: https://github.com/wkh237/react-native-fetch-blob/blob/master/android/src/main/java/com/RNFetchBlob/Utils/PathResolver.java
// MIT License, see: https://github.com/wkh237/react-native-fetch-blob/blob/master/LICENSE
// original copyright: Copyright (c) 2017 xeiyan@gmail.com
// src slightly modified to be used into Qt Projects: (c) 2017 ekke@ekkes-corner.org
package org.ekkescorner.utils;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.content.ContentUris;
import android.os.Environment;
import android.content.ContentResolver;
import java.io.File;
import java.io.InputStream;
import java.io.FileOutputStream;
public class QSharePathResolver {
public static String getRealPathFromURI(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// Other Providers
else{
try {
InputStream attachment = context.getContentResolver().openInputStream(uri);
if (attachment != null) {
String filename = getContentName(context.getContentResolver(), uri);
if (filename != null) {
File file = new File(context.getCacheDir(), filename);
FileOutputStream tmp = new FileOutputStream(file);
byte[] buffer = new byte[1024];
while (attachment.read(buffer) > 0) {
tmp.write(buffer);
}
tmp.close();
attachment.close();
return file.getAbsolutePath();
}
}
} catch (Exception e) {
// TODO SIGNAL shareError()
return null;
}
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
private static String getContentName(ContentResolver resolver, Uri uri) {
Cursor cursor = resolver.query(uri, null, null, null, null);
cursor.moveToFirst();
int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
if (nameIndex >= 0) {
String name = cursor.getString(nameIndex);
cursor.close();
return name;
}
cursor.close();
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
String result = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
result = cursor.getString(index);
}
}
catch (Exception ex) {
ex.printStackTrace();
return null;
}
finally {
if (cursor != null)
cursor.close();
}
return result;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}

0
source-android/androidnative.pri/ci/qt-android Executable file → Normal file
View File

View File

@ -23,3 +23,8 @@ void AndroidNative::SystemDispatcherProxy::loadClass(QString className)
{ {
SystemDispatcher::instance()->loadClass(className); SystemDispatcher::instance()->loadClass(className);
} }
void AndroidNative::SystemDispatcherProxy::setInitialized()
{
SystemDispatcher::instance()->setInitialized();
}

View File

@ -16,6 +16,8 @@ namespace AndroidNative {
Q_INVOKABLE void loadClass(QString className); Q_INVOKABLE void loadClass(QString className);
Q_INVOKABLE void setInitialized();
signals: signals:
void dispatched(QString type , QVariantMap message); void dispatched(QString type , QVariantMap message);

View File

@ -332,6 +332,16 @@ void AndroidNative::SystemDispatcher::loadClass(QString javaClassName)
dispatch("androidnative.SystemDispatcher.loadClass",message); dispatch("androidnative.SystemDispatcher.loadClass",message);
} }
void AndroidNative::SystemDispatcher::setInitialized()
{
QVariantMap message;
message["Initialized"] = true;
dispatch("androidnative.SystemDispatcher.setInitialized",message);
}
void AndroidNative::SystemDispatcher::registerNatives() void AndroidNative::SystemDispatcher::registerNatives()
{ {
Q_UNUSED(registerNativesCalled); Q_UNUSED(registerNativesCalled);

View File

@ -29,6 +29,9 @@ namespace AndroidNative {
*/ */
Q_INVOKABLE void loadClass(QString javaClassName); Q_INVOKABLE void loadClass(QString javaClassName);
//inform Dispatcher about loaded Environment, Intents can be processed
Q_INVOKABLE void setInitialized();
/// Register JNI native methods. This function must be called in JNI_OnLoad. Otherwise, the messenger will not be working /// Register JNI native methods. This function must be called in JNI_OnLoad. Otherwise, the messenger will not be working
static void registerNatives(); static void registerNatives();

View File

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 127 B

View File

@ -1,5 +1,9 @@
package androidnative; package androidnative;
import android.content.Intent; import android.content.Intent;
import android.util.Log;
import android.app.Activity;
import android.os.*;
import java.util.Map;
/** An alternative Activity class for Qt applicaiton. /** An alternative Activity class for Qt applicaiton.
@ -14,10 +18,38 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt
SystemDispatcher.onActivityResult(requestCode,resultCode,data); SystemDispatcher.onActivityResult(requestCode,resultCode,data);
} }
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
SystemDispatcher.onActivityResume();
if((getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_NEW_TASK) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)) {
SystemDispatcher.onActivityResume();
} else {
Intent data = getIntent();
if ((data != null) && !(data.getBooleanExtra("used",false))){
SystemDispatcher.loadClass("androidnative.ImagePicker");
SystemDispatcher.onActivityResult(0x245285a3,Activity.RESULT_OK,data);
getIntent().replaceExtras(new Bundle());
getIntent().setAction("");
getIntent().setData(null);
getIntent().setFlags(0);
getIntent().putExtra("used", true);
} else {
SystemDispatcher.onActivityResume();
}}
} }
protected void onNewIntent(Intent data) {
super.onNewIntent(data);
SystemDispatcher.loadClass("androidnative.ImagePicker");
SystemDispatcher.onActivityResult(0x245285a3,Activity.RESULT_OK,data);
getIntent().replaceExtras(new Bundle());
getIntent().setAction("");
getIntent().setData(null);
getIntent().setFlags(0);
getIntent().putExtra("used", true);
} // onNewIntent
} }

View File

@ -17,6 +17,9 @@ import android.util.Log;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.content.Intent; import android.content.Intent;
//import android.content.*;
//import android.app.*;
import android.os.*;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -110,6 +113,14 @@ public class SystemDispatcher {
public static String SYSTEM_DISPATCHER_LOAD_CLASS_MESSAGE = "androidnative.SystemDispatcher.loadClass"; public static String SYSTEM_DISPATCHER_LOAD_CLASS_MESSAGE = "androidnative.SystemDispatcher.loadClass";
public static String SYSTEM_DISPATCHER_SET_INITIALIZED_MESSAGE = "androidnative.SystemDispatcher.setInitialized";
public static boolean isIntentPending=false;
public static boolean isInitialized=false;
private static Map waitingIntent;
/** A helper function to dispatch a massage when onResume is invoked in the Activity class /** A helper function to dispatch a massage when onResume is invoked in the Activity class
*/ */
@ -117,6 +128,7 @@ public class SystemDispatcher {
dispatch(ACTIVITY_RESUME_MESSAGE); dispatch(ACTIVITY_RESUME_MESSAGE);
} }
/** A helper function to dispatch a message based on the input argument fron Activity.onActivityResult /** A helper function to dispatch a message based on the input argument fron Activity.onActivityResult
*/ */
public static void onActivityResult (int requestCode, int resultCode, Intent data) { public static void onActivityResult (int requestCode, int resultCode, Intent data) {
@ -126,7 +138,17 @@ public class SystemDispatcher {
message.put("resultCode",resultCode); message.put("resultCode",resultCode);
message.put("data",data); message.put("data",data);
if(isInitialized) {
dispatch(ACTIVITY_RESULT_MESSAGE,message); dispatch(ACTIVITY_RESULT_MESSAGE,message);
waitingIntent=null;
isIntentPending=false;
} else { //onIntent start
waitingIntent = message;
isIntentPending = true;
}
//onIntent end
} }
private static class Payload { private static class Payload {
@ -201,6 +223,18 @@ public class SystemDispatcher {
} }
} }
public static void setInitialized() {
isInitialized = true;
if(isIntentPending) {
isIntentPending = false;
dispatch(ACTIVITY_RESULT_MESSAGE,waitingIntent);
}
}
public static void init() { public static void init() {
SystemDispatcher.addListener(new SystemDispatcher.Listener() { SystemDispatcher.addListener(new SystemDispatcher.Listener() {
public void onDispatched(String type , Map message) { public void onDispatched(String type , Map message) {
@ -210,6 +244,9 @@ public class SystemDispatcher {
String className = (String) message.get("className"); String className = (String) message.get("className");
loadClass(className); loadClass(className);
} }
if (type.equals(SYSTEM_DISPATCHER_SET_INITIALIZED_MESSAGE)) {
setInitialized();
}
} }
}); });

View File

0
source-android/androidnative.pri/tests/instrument/runner/gradlew vendored Executable file → Normal file
View File

View File

@ -40,11 +40,11 @@ function friendicaRequest(login,api,rootwindow,callback) {
if (xhrequest.status=200){ if (xhrequest.status=200){
callback(xhrequest.responseText) callback(xhrequest.responseText)
}else{ }else{
showMessage("Error","API:" +login.server+api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow); showMessage("Error","API:\n" +login.server+api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow);
} }
} }
catch (e){ catch (e){
showMessage("Error", login.server+api+"\n"+e+"\n Return: "+xhrequest.responseText,rootwindow) showMessage("Error", "API:\n" +login.server+api+"\n"+e+"\n Return: "+xhrequest.responseText,rootwindow)
} }
} }
} }
@ -61,11 +61,11 @@ function friendicaPostRequest(login,api,data,method,rootwindow,callback) {
try{ if (xhrequest.responseText!=""){ try{ if (xhrequest.responseText!=""){
callback(xhrequest.responseText) callback(xhrequest.responseText)
}else{ }else{
showMessage("Error",api+" NO RESPONSE",rootwindow) showMessage("Error","API:\n" +api+" NO RESPONSE",rootwindow)
callback(xhrequest.responseText) callback(xhrequest.responseText)
} }
} }
catch (e){showMessage("Error", api+" "+e+"\n Return:"+xhrequest.responseText,rootwindow)} catch (e){showMessage("Error", "API:\n" + +api+" "+e+"\n Return:"+xhrequest.responseText,rootwindow)}
} }
} }
xhrequest.open(method, login.server+api,true,login.username,Qt.atob(login.password)); xhrequest.open(method, login.server+api,true,login.username,Qt.atob(login.password));
@ -88,7 +88,7 @@ function friendicaWebRequest(url,rootwindow,callback) {
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {} if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {}
else if(xhrequest.readyState === XMLHttpRequest.DONE) { else if(xhrequest.readyState === XMLHttpRequest.DONE) {
try{callback(xhrequest.responseText)} try{callback(xhrequest.responseText)}
catch (e){showMessage("Error",url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)} catch (e){showMessage("Error","API:\n" +url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)}
} }
} }
xhrequest.open("GET", url,true); xhrequest.open("GET", url,true);
@ -101,7 +101,7 @@ function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) {
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {} if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {}
else if(xhrequest.readyState === XMLHttpRequest.DONE) { else if(xhrequest.readyState === XMLHttpRequest.DONE) {
try{callback(xhrequest.responseText)} try{callback(xhrequest.responseText)}
catch (e){showMessage("Error",url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)} catch (e){showMessage("Error","Url:\n" +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.open("GET", login.server+"/api/friendica/remoteauth?c_url="+c_url+"&url="+url,true,login.username,Qt.atob(login.password));

View File

@ -38,7 +38,7 @@ function requestFriends(login,database,rootwindow,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('UPDATE contacts SET isFriend=0 where username="'+login.username+'"')}); // clean old friends var result = tx.executeSql('UPDATE contacts SET isFriend=0 where username="'+login.username+'"')}); // clean old friends
Helperjs.friendicaRequest(login,"/api/statuses/friends", rootwindow,function (obj){ Helperjs.friendicaRequest(login,"/api/statuses/friends?count=9999", rootwindow,function (obj){
var friends=JSON.parse(obj); var friends=JSON.parse(obj);
for (var i=0;i<friends.length;i++){ friends[i].isFriend=1} for (var i=0;i<friends.length;i++){ friends[i].isFriend=1}
//try{requestProfile(login,friends,rootwindow,function(friends_profile){callback(friends_profile)})} //try{requestProfile(login,friends,rootwindow,function(friends_profile){callback(friends_profile)})}
@ -98,6 +98,9 @@ function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback)
var newContacts=[]; var newContacts=[];
Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){ Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){
var news=JSON.parse(obj); var news=JSON.parse(obj);
if (news.hasOwnProperty('status')){
Helperjs.showMessage(qsTr("Error"),"API:\n" +login.server+"/api/statuses/friends_timeline"+parameter+"\n Return: \n"+obj,rootwindow)
}
var newContacts=findNewContacts(news,contacts); var newContacts=findNewContacts(news,contacts);
callback(news,newContacts) callback(news,newContacts)
})} })}

View File

@ -327,7 +327,7 @@ function cleanContacts(login,database,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var oldestnewsrs= tx.executeSql('SELECT created_at FROM news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY created_at ASC LIMIT 1'); var oldestnewsrs= tx.executeSql('SELECT created_at FROM news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY created_at ASC LIMIT 1');
var oldestnewsTime=oldestnewsrs.rows.item(0).created_at- 604800000; //contacts can be 7 days old if (oldestnewsrs.rows.length>0){ var oldestnewsTime=oldestnewsrs.rows.item(0).created_at- 604800000;} else{var oldestnewsTime=0} //contacts can be 7 days old
//print(login.username+" älteste news: "+ oldestnewsTime); //print(login.username+" älteste news: "+ oldestnewsTime);
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge<'+oldestnewsTime); // check for friends var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge<'+oldestnewsTime); // check for friends
for (var i=0;i<result.rows.length;i++){ for (var i=0;i<result.rows.length;i++){

View File

@ -171,7 +171,7 @@ StackView{
onEditingFinished:{ onEditingFinished:{
Helperjs.friendicaWebRequest(servername.text+'/api/users/show?screen_name='+username.text,configBackground,function(obj){ Helperjs.friendicaWebRequest(servername.text+'/api/users/show?screen_name='+username.text,configBackground,function(obj){
var screennametest=JSON.parse(obj); var screennametest=JSON.parse(obj);
if (screennametest.status.error){ if (screennametest.hasOwnProperty('status')){
Helperjs.showMessage(qsTr("Error"),qsTr("Nickname not registered at given server!"),configBackground); Helperjs.showMessage(qsTr("Error"),qsTr("Nickname not registered at given server!"),configBackground);
configBackground.registeredUser=false; configBackground.registeredUser=false;
}else{configBackground.registeredUser=true} }else{configBackground.registeredUser=true}
@ -226,7 +226,7 @@ StackView{
Text{ Text{
id: newsTypeField id: newsTypeField
anchors.fill: parent anchors.fill: parent
text:"Timeline" text:"Conversations"
} }
MouseArea{ MouseArea{
anchors.fill:parent anchors.fill:parent
@ -289,7 +289,7 @@ StackView{
var credentials=JSON.parse(obj); var credentials=JSON.parse(obj);
if (credentials.hasOwnProperty('status')){ if (credentials.hasOwnProperty('status')){
Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root) Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
} }
else{ else{
filesystem.Directory=userconfig.imagestore; filesystem.Directory=userconfig.imagestore;
filesystem.makeDir("contacts"); filesystem.makeDir("contacts");
@ -332,7 +332,7 @@ StackView{
password.text=""; password.text="";
imagestore.text=""; imagestore.text="";
maxNews.value=0; maxNews.value=0;
newsTypeField.text="Timeline"; newsTypeField.text="Conversations";
messageIntervalSlider.value=0; messageIntervalSlider.value=0;
userButton.text=qsTr("User"); userButton.text=qsTr("User");
Helperjs.readData(db,"config","",function(storedUsers){ Helperjs.readData(db,"config","",function(storedUsers){
@ -354,7 +354,7 @@ StackView{
password.text="" password.text=""
imagestore.text="" imagestore.text=""
maxNews.value=0 maxNews.value=0
newsTypeField.text="Timeline" newsTypeField.text="Conversations"
messageIntervalSlider.value=0 messageIntervalSlider.value=0
userButton.text=qsTr("User") userButton.text=qsTr("User")
} }

View File

@ -37,4 +37,7 @@ QtObject{
property int backKey: Qt.Key_Back property int backKey: Qt.Key_Back
//property string attachImageDir:filesystem.cameraPath+"/" //property string attachImageDir:filesystem.cameraPath+"/"
property string imagePickQml: "ImagePicker" property string imagePickQml: "ImagePicker"
property string imagePicker:'import QtQuick 2.0; import "qrc:/qml/genericqml";'+
imagePickQml+'{multiple : true;onReady: {attachImageURLs.push(imageUrl);'+
'attachImage(imageUrl)}}'
} }

View File

@ -211,7 +211,7 @@ Rectangle {
Text{ Text{
id:profiletextfield id:profiletextfield
x:2*mm x:2*mm
y:3.5*mm y:4.5*mm
width:parent.width-2.5*mm width:parent.width-2.5*mm
wrapMode: Text.Wrap wrapMode: Text.Wrap
font.pixelSize: 3*mm font.pixelSize: 3*mm

View File

@ -57,6 +57,7 @@ TabView{
signal friendsSignal(var username) signal friendsSignal(var username)
signal contactdetailsSignal(var contact) signal contactdetailsSignal(var contact)
signal eventSignal(var contact) signal eventSignal(var contact)
signal uploadSignal(var urls)
property var news:[] property var news:[]
property var newContacts:[] property var newContacts:[]
@ -161,7 +162,7 @@ TabView{
title: "\uf03a" title: "\uf03a"
id: newstab id: newstab
property string newstabstatus property string newstabstatus
property var conversation property var conversation:[]
source:(root.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" source:(root.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":""
} }
Tab{ Tab{
@ -188,4 +189,11 @@ TabView{
id: configtab id: configtab
source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":"" source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":""
} }
Component.onCompleted: {
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple : true; onReady: {'+
'if(imageUrls.length==1){root.currentIndex=0;newstab.active=true;root.uploadSignal(imageUrls)} else{'+
' root.currentIndex=2;fotostab.active=true;'+
'root.uploadSignal(imageUrls)};}}',root,"imagePicker");
}
} }

View File

@ -39,8 +39,6 @@ Item {
target: SystemDispatcher target: SystemDispatcher
onDispatched: { onDispatched: {
if (type === m_CHOSEN_MESSAGE) { if (type === m_CHOSEN_MESSAGE) {
//imageUrls = message.imageUrls;
//imageUrl = imageUrls[0];
var h=[]; var h=[];
for (var n in message.imageUrls){ for (var n in message.imageUrls){
h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5)) h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5))
@ -54,6 +52,7 @@ Item {
Component.onCompleted: { Component.onCompleted: {
SystemDispatcher.loadClass("androidnative.ImagePicker"); SystemDispatcher.loadClass("androidnative.ImagePicker");
if (root.currentIndex==0){SystemDispatcher.setInitialized();}
} }
} }

View File

@ -209,7 +209,7 @@ Flickable{
id: cancelButton id: cancelButton
text: "\uf057" text: "\uf057"
onClicked: {newstab.newstabstatus=login.newsViewType; onClicked: {newstab.newstabstatus=login.newsViewType;
newsStack.pop()} newsStack.pop(null)}
} }
BlueButton { BlueButton {
id: sendButton id: sendButton
@ -220,10 +220,11 @@ Flickable{
if (directmessage==0){ if (directmessage==0){
statusUpdate(title,body,messageSend.parentId,attachImageURLs)} statusUpdate(title,body,messageSend.parentId,attachImageURLs)}
else {dmUpdate(title,body,"",messageSend.reply_to_user) } else {dmUpdate(title,body,"",messageSend.reply_to_user) }
newstab.newstabstatus=login.newsViewType; newsStack.pop() newstab.newstabstatus=login.newsViewType; newsStack.pop(null)
} }
} }
} }
} }
Component.onCompleted: if(attachImageURLs.length>0){attachImage(attachImageURLs[0])}
} }

View File

@ -36,6 +36,8 @@ import "qrc:/js/news.js" as Newsjs
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
//import AndroidNative 1.0
Item { Item {
Connections{ Connections{
target:newstab target:newstab
@ -44,18 +46,6 @@ 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{ Connections{
target:xhr target:xhr
// onError:{if (data=="contact"){downloadNotice.text=root.newContacts[root.currentContact].name+"... Error!"}} // onError:{if (data=="contact"){downloadNotice.text=root.newContacts[root.currentContact].name+"... Error!"}}
@ -63,6 +53,8 @@ Item {
} }
} }
Timer {id:replytimer; interval: 1000; running: false; repeat: false Timer {id:replytimer; interval: 1000; running: false; repeat: false
onTriggered: { onTriggered: {
if(newstab.newstabstatus=="Conversation"){ if(newstab.newstabstatus=="Conversation"){
@ -123,7 +115,11 @@ Item {
newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1,"login":root.login}}); newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1,"login":root.login}});
} }
function sendUrls(urls){
if((urls.length==1)&&(newsStack.depth<2)){
newsStack.push([newslistRectangle,{item:"qrc:/qml/newsqml/MessageSend.qml",properties:{attachImageURLs:urls}}])
}
}
StackView{ StackView{
id: newsStack id: newsStack
@ -131,6 +127,7 @@ Item {
property int conversationIndex: 0 property int conversationIndex: 0
initialItem:Rectangle { initialItem:Rectangle {
id:newslistRectangle
y:1 y:1
color: "white" color: "white"
@ -340,12 +337,23 @@ Item {
root.messageSignal.connect(onFriendsMessages); root.messageSignal.connect(onFriendsMessages);
root.directmessageSignal.connect(onDirectMessage); root.directmessageSignal.connect(onDirectMessage);
root.newsSignal.connect(showNews); root.newsSignal.connect(showNews);
root.uploadSignal.connect(sendUrls);
try{newsModel.clear()} catch(e){} try{newsModel.clear()} catch(e){}
if(root.news.length>0){showNews(root.news)}
else{ newstab.newstabstatus=login.newsViewType; //print("imageUrls "+JSON.stringify(imageUrls)+" newsstack.depth:"+newsStack.depth);
if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){showNews(dbnews)})} //newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{attachImageURLs:[imageUrl]}})
else{Newsjs.chatsfromdb(db,login.username,function(dbnews){showNews(dbnews)})} // var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
// osSettings.imagePickQml+'{multiple : true; onReady: {'+
// 'if(imageUrls.length==1){root.currentIndex=0;newstab.active=true;root.uploadSignal(imageUrls)} else{'+
// ' root.currentIndex=2;fotostab.active=true;'+
// 'root.uploadSignal(imageUrls)};}}',newstab,"imagePicker");
//SystemDispatcher.setInitialized();
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

@ -34,15 +34,15 @@ import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import "qrc:/js/news.js" as Newsjs import "qrc:/js/news.js" as Newsjs
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml"
Item { Item {
id: newsitem id: newsitem
width: parent.width width: parent.width
height:toprow.height+friendicaActivities.height+controlrow.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm) height:toprow.height+friendicaActivities.height+controlrow.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm)
property int itemindex: index
property string attending: "" property string attending: ""
property int itemindex: index
onAttendingChanged: {attendLabel.visible=true; onAttendingChanged: {attendLabel.visible=true;
attendLabel.text= qsTr("attending: ")+ qsTr(attending)} attendLabel.text= qsTr("attending: ")+ qsTr(attending)}
@ -145,8 +145,9 @@ Item {
textFormat: Text.RichText textFormat: Text.RichText
text:Qt.atob(newsitemobject.statusnet_html) text:Qt.atob(newsitemobject.statusnet_html)
width: newsitem.width-8*mm-2 width: newsitem.width-8*mm-2
height: implicitHeight height: Math.min(implicitHeight,3/4*root.height)
wrapMode: Text.Wrap wrapMode: Text.Wrap
clip:true
onLinkActivated:{ onLinkActivated:{
Qt.openUrlExternally(link)} Qt.openUrlExternally(link)}
Component.onCompleted:{ Component.onCompleted:{
@ -159,6 +160,29 @@ Item {
} }
} }
} }
BlueButton{
width: newsitem.width-8*mm-2
height:10*mm
anchors.bottom: itemMessage.bottom
visible: itemMessage.implicitHeight>3/4*root.height
text:"\uf078"
fontColor:"grey"
border.color: "transparent"
gradient: Gradient {
GradientStop { position: 0.0; color: "transparent" }
GradientStop { position: 0.5; color: "white" }
}
radius:0
onClicked: {
if (text=="\uf078"){
itemMessage.height=itemMessage.implicitHeight+10*mm;text="\uf077"
} else {
itemMessage.height=Math.min(itemMessage.implicitHeight,3/4*root.height);
text="\uf078";
newsView.positionViewAtIndex(index,ListView.Beginning);
}
}
}
} }
} }
} }

View File

@ -64,12 +64,10 @@ Rectangle{
imageUploadModel.append({"imageUrl":url,"description":""}) imageUploadModel.append({"imageUrl":url,"description":""})
} }
z:2 //border.color: "grey"
border.color: "grey" y:1
width: parent.width-4*mm width:root.width-mm
height:parent.height-12*mm height:root.height-5*mm
x:2*mm
y:10*mm
property string directory: "" property string directory: ""
Connections{ Connections{
@ -95,8 +93,12 @@ Rectangle{
anchors.topMargin: 1*mm anchors.topMargin: 1*mm
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 1*mm anchors.rightMargin: 1*mm
spacing:mm spacing:5*mm
Text{
font.pixelSize: 3.5*mm
font.bold: true
text:qsTr("Upload to album")
}
// BlueButton{ // BlueButton{
// id:permButton // id:permButton
// text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" // text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023"
@ -109,7 +111,9 @@ Rectangle{
BlueButton{ BlueButton{
id:closeButton id:closeButton
text: "\uf057" text: "\uf057"
onClicked:{imageDialog.destroy()} onClicked:{photoStack.pop();
//imageDialog.destroy()
}
} }
} }
@ -250,6 +254,9 @@ Rectangle{
albumModel.append({"text":storedAlbums[n]})} albumModel.append({"text":storedAlbums[n]})}
})} })}
catch (e){print(e)} catch (e){print(e)}
if(attachImageURLs.length>0){
for (var n in attachImageURLs){attachImage(attachImageURLs[n])}
}
} }
// BusyIndicator{ // BusyIndicator{
// id: imageBusy // id: imageBusy

View File

@ -37,7 +37,11 @@ import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/photoqml" import "qrc:/qml/photoqml"
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
Rectangle {
StackView{
id: photoStack
anchors.fill:parent
initialItem:Rectangle {
id:fotorectangle id:fotorectangle
y:1 y:1
width:root.width-mm width:root.width-mm
@ -48,15 +52,15 @@ Rectangle {
property bool remoteContact: false property bool remoteContact: false
onNewimagesChanged:{ onNewimagesChanged:{
if(newimages.length>0){ if(fotorectangle.newimages.length>0){
//print("newimages "+JSON.stringify(newimages)); //print("newimages "+JSON.stringify(newimages));
var ownimagelist=[]; var ownimagelist=[];
Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){ Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){
for (var i=0;i<newimages.length;i++){ for (var i=0;i<fotorectangle.newimages.length;i++){
if(albums.indexOf(newimages[i].album)==-1){ if(albums.indexOf(fotorectangle.newimages[i].album)==-1){
filesystem.Directory=root.login.imagestore+"/albums"; filesystem.Directory=root.login.imagestore+"/albums";
filesystem.makeDir(newimages[i].album)} filesystem.makeDir(fotorectangle.newimages[i].album)}
ownimagelist.push(root.login.server+"/api/friendica/photo?scale='0'&photo_id="+newimages[i].id); ownimagelist.push(root.login.server+"/api/friendica/photo?scale='0'&photo_id="+fotorectangle.newimages[i].id);
} }
}) })
xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setLogin(login.username+":"+Qt.atob(login.password));
@ -69,8 +73,8 @@ Rectangle {
} }
onCurrentimagenoChanged:{ onCurrentimagenoChanged:{
if(currentimageno==newimages.length){newImagesProgress.visible=false;showFotos(root.login,""); if(fotorectangle.currentimageno==fotorectangle.newimages.length){newImagesProgress.visible=false;showFotos(root.login,"");
newimages=[];currentimageno=0} fotorectangle.newimages=[];fotorectangle.currentimageno=0}
// download next image // download next image
} }
@ -78,17 +82,17 @@ Rectangle {
target:xhr target:xhr
onDownloadedjson:{ onDownloadedjson:{
if(type=="picturelist"){ if(type=="picturelist"){
currentimageno=currentimageno+1 fotorectangle.currentimageno=fotorectangle.currentimageno+1
Imagejs.storeImagedata(login,db,jsonObject,fotorectangle) Imagejs.storeImagedata(login,db,jsonObject,fotorectangle)
} }
} }
onDownloaded:{ onDownloaded:{
if(type=="picture"){currentimageno=currentimageno+1} if(type=="picture"){fotorectangle.currentimageno=fotorectangle.currentimageno+1}
} }
onError:{if(data=="picturelist"){ onError:{if(data=="picturelist"){
var requestid=url.substring(url.lastIndexOf("=")+1); var requestid=url.substring(url.lastIndexOf("=")+1);
Imagejs.dataRequest(login,requestid,db,xhr,fotorectangle) Imagejs.dataRequest(login,requestid,db,xhr,fotorectangle)
} else {currentimageno=currentimageno+1} } else {fotorectangle.currentimageno=fotorectangle.currentimageno+1}
} }
} }
// Connections{ // Connections{
@ -133,6 +137,10 @@ Rectangle {
}) })
} }
function uploadUrls(urls){
photoStack.push({item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{attachImageURLs:urls}})
}
ProgressBar{ ProgressBar{
id: newImagesProgress id: newImagesProgress
width: 15*mm width: 15*mm
@ -141,7 +149,7 @@ Rectangle {
anchors.right:uploadPhoto.left anchors.right:uploadPhoto.left
anchors.rightMargin:mm anchors.rightMargin:mm
visible: false visible: false
value: currentimageno/newimages.length value: fotorectangle.currentimageno/fotorectangle.newimages.length
} }
BlueButton{ BlueButton{
@ -152,8 +160,9 @@ Rectangle {
anchors.rightMargin:mm anchors.rightMargin:mm
text:"\uf0ee" text:"\uf0ee"
onClicked: { onClicked: {
var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml"); photoStack.push({item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{}});
var imageUpload = component.createObject(fotorectangle); // var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml");
// var imageUpload = component.createObject(fotorectangle);
}} }}
BlueButton{ BlueButton{
@ -168,12 +177,12 @@ Rectangle {
MenuItem { MenuItem {
text: qsTr("All Images") text: qsTr("All Images")
onTriggered: { onTriggered: {
Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){newimages=obj})} Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){fotorectangle.newimages=obj})}
} }
MenuItem { MenuItem {
text: qsTr("Only new") text: qsTr("Only new")
onTriggered: { onTriggered: {
Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){newimages=obj})} Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){fotorectangle.newimages=obj})}
} }
} }
onClicked: {photoupdatemenu.popup()} onClicked: {photoupdatemenu.popup()}
@ -260,7 +269,10 @@ Rectangle {
ListView {anchors.fill: parent; model: visualphotoModel.parts.fullscreen; interactive: false } ListView {anchors.fill: parent; model: visualphotoModel.parts.fullscreen; interactive: false }
WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"} WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"}
Component.onCompleted: { root.fotoSignal.connect(showFotos); Component.onCompleted: {
if (fotostab.phototabstatus=="Images"){showFotos(root.login,"")} root.fotoSignal.connect(showFotos);
root.uploadSignal.connect(uploadUrls);
if (fotostab.phototabstatus=="Images"){showFotos(root.login,"")}
} }
} }
}

View File

@ -40,11 +40,11 @@ function friendicaRequest(login,api,rootwindow,callback) {
if (xhrequest.status=200){ if (xhrequest.status=200){
callback(xhrequest.responseText) callback(xhrequest.responseText)
}else{ }else{
showMessage("Error","API:" +login.server+api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow); showMessage("Error","API:\n" +login.server+api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow);
} }
} }
catch (e){ catch (e){
showMessage("Error", login.server+api+"\n"+e+"\n Return: "+xhrequest.responseText,rootwindow) showMessage("Error", "API:\n" +login.server+api+"\n"+e+"\n Return: "+xhrequest.responseText,rootwindow)
} }
} }
} }
@ -61,11 +61,11 @@ function friendicaPostRequest(login,api,data,method,rootwindow,callback) {
try{ if (xhrequest.responseText!=""){ try{ if (xhrequest.responseText!=""){
callback(xhrequest.responseText) callback(xhrequest.responseText)
}else{ }else{
showMessage("Error",api+" NO RESPONSE",rootwindow) showMessage("Error","API:\n" +api+" NO RESPONSE",rootwindow)
callback(xhrequest.responseText) callback(xhrequest.responseText)
} }
} }
catch (e){showMessage("Error", api+" "+e+"\n Return:"+xhrequest.responseText,rootwindow)} catch (e){showMessage("Error", "API:\n" + +api+" "+e+"\n Return:"+xhrequest.responseText,rootwindow)}
} }
} }
xhrequest.open(method, login.server+api,true,login.username,Qt.atob(login.password)); xhrequest.open(method, login.server+api,true,login.username,Qt.atob(login.password));
@ -88,7 +88,7 @@ function friendicaWebRequest(url,rootwindow,callback) {
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {} if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {}
else if(xhrequest.readyState === XMLHttpRequest.DONE) { else if(xhrequest.readyState === XMLHttpRequest.DONE) {
try{callback(xhrequest.responseText)} try{callback(xhrequest.responseText)}
catch (e){showMessage("Error",url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)} catch (e){showMessage("Error","API:\n" +url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)}
} }
} }
xhrequest.open("GET", url,true); xhrequest.open("GET", url,true);
@ -101,7 +101,7 @@ function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) {
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {} if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {}
else if(xhrequest.readyState === XMLHttpRequest.DONE) { else if(xhrequest.readyState === XMLHttpRequest.DONE) {
try{callback(xhrequest.responseText)} try{callback(xhrequest.responseText)}
catch (e){showMessage("Error",url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)} catch (e){showMessage("Error","Url:\n" +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.open("GET", login.server+"/api/friendica/remoteauth?c_url="+c_url+"&url="+url,true,login.username,Qt.atob(login.password));

View File

@ -38,7 +38,7 @@ function requestFriends(login,database,rootwindow,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('UPDATE contacts SET isFriend=0 where username="'+login.username+'"')}); // clean old friends var result = tx.executeSql('UPDATE contacts SET isFriend=0 where username="'+login.username+'"')}); // clean old friends
Helperjs.friendicaRequest(login,"/api/statuses/friends", rootwindow,function (obj){ Helperjs.friendicaRequest(login,"/api/statuses/friends?count=9999", rootwindow,function (obj){
var friends=JSON.parse(obj); var friends=JSON.parse(obj);
for (var i=0;i<friends.length;i++){ friends[i].isFriend=1} for (var i=0;i<friends.length;i++){ friends[i].isFriend=1}
//try{requestProfile(login,friends,rootwindow,function(friends_profile){callback(friends_profile)})} //try{requestProfile(login,friends,rootwindow,function(friends_profile){callback(friends_profile)})}
@ -98,6 +98,9 @@ function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback)
var newContacts=[]; var newContacts=[];
Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){ Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){
var news=JSON.parse(obj); var news=JSON.parse(obj);
if (news.hasOwnProperty('status')){
Helperjs.showMessage(qsTr("Error"),"API:\n" +login.server+"/api/statuses/friends_timeline"+parameter+"\n Return: \n"+obj,rootwindow)
}
var newContacts=findNewContacts(news,contacts); var newContacts=findNewContacts(news,contacts);
callback(news,newContacts) callback(news,newContacts)
})} })}

View File

@ -327,7 +327,7 @@ function cleanContacts(login,database,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
var oldestnewsrs= tx.executeSql('SELECT created_at FROM news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY created_at ASC LIMIT 1'); var oldestnewsrs= tx.executeSql('SELECT created_at FROM news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY created_at ASC LIMIT 1');
var oldestnewsTime=oldestnewsrs.rows.item(0).created_at- 604800000; //contacts can be 7 days old if (oldestnewsrs.rows.length>0){ var oldestnewsTime=oldestnewsrs.rows.item(0).created_at- 604800000;} else{var oldestnewsTime=0} //contacts can be 7 days old
//print(login.username+" älteste news: "+ oldestnewsTime); //print(login.username+" älteste news: "+ oldestnewsTime);
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge<'+oldestnewsTime); // check for friends var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge<'+oldestnewsTime); // check for friends
for (var i=0;i<result.rows.length;i++){ for (var i=0;i<result.rows.length;i++){

View File

@ -171,7 +171,7 @@ StackView{
onEditingFinished:{ onEditingFinished:{
Helperjs.friendicaWebRequest(servername.text+'/api/users/show?screen_name='+username.text,configBackground,function(obj){ Helperjs.friendicaWebRequest(servername.text+'/api/users/show?screen_name='+username.text,configBackground,function(obj){
var screennametest=JSON.parse(obj); var screennametest=JSON.parse(obj);
if (screennametest.status.error){ if (screennametest.hasOwnProperty('status')){
Helperjs.showMessage(qsTr("Error"),qsTr("Nickname not registered at given server!"),configBackground); Helperjs.showMessage(qsTr("Error"),qsTr("Nickname not registered at given server!"),configBackground);
configBackground.registeredUser=false; configBackground.registeredUser=false;
}else{configBackground.registeredUser=true} }else{configBackground.registeredUser=true}
@ -226,7 +226,7 @@ StackView{
Text{ Text{
id: newsTypeField id: newsTypeField
anchors.fill: parent anchors.fill: parent
text:"Timeline" text:"Conversations"
} }
MouseArea{ MouseArea{
anchors.fill:parent anchors.fill:parent
@ -289,7 +289,7 @@ StackView{
var credentials=JSON.parse(obj); var credentials=JSON.parse(obj);
if (credentials.hasOwnProperty('status')){ if (credentials.hasOwnProperty('status')){
Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root) Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
} }
else{ else{
filesystem.Directory=userconfig.imagestore; filesystem.Directory=userconfig.imagestore;
filesystem.makeDir("contacts"); filesystem.makeDir("contacts");
@ -332,7 +332,7 @@ StackView{
password.text=""; password.text="";
imagestore.text=""; imagestore.text="";
maxNews.value=0; maxNews.value=0;
newsTypeField.text="Timeline"; newsTypeField.text="Conversations";
messageIntervalSlider.value=0; messageIntervalSlider.value=0;
userButton.text=qsTr("User"); userButton.text=qsTr("User");
Helperjs.readData(db,"config","",function(storedUsers){ Helperjs.readData(db,"config","",function(storedUsers){
@ -354,7 +354,7 @@ StackView{
password.text="" password.text=""
imagestore.text="" imagestore.text=""
maxNews.value=0 maxNews.value=0
newsTypeField.text="Timeline" newsTypeField.text="Conversations"
messageIntervalSlider.value=0 messageIntervalSlider.value=0
userButton.text=qsTr("User") userButton.text=qsTr("User")
} }

View File

@ -37,4 +37,7 @@ QtObject{
property int backKey: Qt.Key_Back property int backKey: Qt.Key_Back
//property string attachImageDir:filesystem.cameraPath+"/" //property string attachImageDir:filesystem.cameraPath+"/"
property string imagePickQml: "ImagePicker" property string imagePickQml: "ImagePicker"
property string imagePicker:'import QtQuick 2.0; import "qrc:/qml/genericqml";'+
imagePickQml+'{multiple : true;onReady: {attachImageURLs.push(imageUrl);'+
'attachImage(imageUrl)}}'
} }

View File

@ -211,7 +211,7 @@ Rectangle {
Text{ Text{
id:profiletextfield id:profiletextfield
x:2*mm x:2*mm
y:3.5*mm y:4.5*mm
width:parent.width-2.5*mm width:parent.width-2.5*mm
wrapMode: Text.Wrap wrapMode: Text.Wrap
font.pixelSize: 3*mm font.pixelSize: 3*mm

View File

@ -57,6 +57,7 @@ TabView{
signal friendsSignal(var username) signal friendsSignal(var username)
signal contactdetailsSignal(var contact) signal contactdetailsSignal(var contact)
signal eventSignal(var contact) signal eventSignal(var contact)
signal uploadSignal(var urls)
property var news:[] property var news:[]
property var newContacts:[] property var newContacts:[]
@ -161,7 +162,7 @@ TabView{
title: "\uf03a" title: "\uf03a"
id: newstab id: newstab
property string newstabstatus property string newstabstatus
property var conversation property var conversation:[]
source:(root.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" source:(root.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":""
} }
Tab{ Tab{
@ -188,4 +189,5 @@ TabView{
id: configtab id: configtab
source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":"" source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":""
} }
} }

View File

@ -39,8 +39,6 @@ Item {
target: SystemDispatcher target: SystemDispatcher
onDispatched: { onDispatched: {
if (type === m_CHOSEN_MESSAGE) { if (type === m_CHOSEN_MESSAGE) {
//imageUrls = message.imageUrls;
//imageUrl = imageUrls[0];
var h=[]; var h=[];
for (var n in message.imageUrls){ for (var n in message.imageUrls){
h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5)) h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5))
@ -54,6 +52,7 @@ Item {
Component.onCompleted: { Component.onCompleted: {
SystemDispatcher.loadClass("androidnative.ImagePicker"); SystemDispatcher.loadClass("androidnative.ImagePicker");
if (root.currentIndex==0){SystemDispatcher.setInitialized();}
} }
} }

View File

@ -209,7 +209,7 @@ Flickable{
id: cancelButton id: cancelButton
text: "\uf057" text: "\uf057"
onClicked: {newstab.newstabstatus=login.newsViewType; onClicked: {newstab.newstabstatus=login.newsViewType;
newsStack.pop()} newsStack.pop(null)}
} }
BlueButton { BlueButton {
id: sendButton id: sendButton
@ -220,10 +220,11 @@ Flickable{
if (directmessage==0){ if (directmessage==0){
statusUpdate(title,body,messageSend.parentId,attachImageURLs)} statusUpdate(title,body,messageSend.parentId,attachImageURLs)}
else {dmUpdate(title,body,"",messageSend.reply_to_user) } else {dmUpdate(title,body,"",messageSend.reply_to_user) }
newstab.newstabstatus=login.newsViewType; newsStack.pop() newstab.newstabstatus=login.newsViewType; newsStack.pop(null)
} }
} }
} }
} }
Component.onCompleted: if(attachImageURLs.length>0){attachImage(attachImageURLs[0])}
} }

View File

@ -36,6 +36,8 @@ import "qrc:/js/news.js" as Newsjs
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
//import AndroidNative 1.0
Item { Item {
Connections{ Connections{
target:newstab target:newstab
@ -44,18 +46,6 @@ 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{ Connections{
target:xhr target:xhr
// onError:{if (data=="contact"){downloadNotice.text=root.newContacts[root.currentContact].name+"... Error!"}} // onError:{if (data=="contact"){downloadNotice.text=root.newContacts[root.currentContact].name+"... Error!"}}
@ -63,6 +53,8 @@ Item {
} }
} }
Timer {id:replytimer; interval: 1000; running: false; repeat: false Timer {id:replytimer; interval: 1000; running: false; repeat: false
onTriggered: { onTriggered: {
if(newstab.newstabstatus=="Conversation"){ if(newstab.newstabstatus=="Conversation"){
@ -79,7 +71,7 @@ Item {
function showNews(newsToShow){ function showNews(newsToShow){
try{if (newsStack.depth>1){newsStack.pop()}}catch(e){} try{if (newsStack.depth>1){newsStack.pop()}}catch(e){}
newsBusy.running=false; newsBusy.running = false;
var currentTime= new Date(); var currentTime= new Date();
downloadNotice.text=""; downloadNotice.text="";
var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow}; var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow};
@ -123,7 +115,11 @@ Item {
newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1,"login":root.login}}); newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1,"login":root.login}});
} }
function sendUrls(urls){
if((urls.length==1)&&(newsStack.depth<2)){
newsStack.push([newslistRectangle,{item:"qrc:/qml/newsqml/MessageSend.qml",properties:{attachImageURLs:urls}}])
}
}
StackView{ StackView{
id: newsStack id: newsStack
@ -131,6 +127,7 @@ Item {
property int conversationIndex: 0 property int conversationIndex: 0
initialItem:Rectangle { initialItem:Rectangle {
id:newslistRectangle
y:1 y:1
color: "white" color: "white"
@ -340,12 +337,23 @@ Item {
root.messageSignal.connect(onFriendsMessages); root.messageSignal.connect(onFriendsMessages);
root.directmessageSignal.connect(onDirectMessage); root.directmessageSignal.connect(onDirectMessage);
root.newsSignal.connect(showNews); root.newsSignal.connect(showNews);
root.uploadSignal.connect(sendUrls);
try{newsModel.clear()} catch(e){} try{newsModel.clear()} catch(e){}
if(root.news.length>0){showNews(root.news)}
else{ newstab.newstabstatus=login.newsViewType; //print("imageUrls "+JSON.stringify(imageUrls)+" newsstack.depth:"+newsStack.depth);
if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){showNews(dbnews)})} //newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{attachImageURLs:[imageUrl]}})
else{Newsjs.chatsfromdb(db,login.username,function(dbnews){showNews(dbnews)})} // var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
// osSettings.imagePickQml+'{multiple : true; onReady: {'+
// 'if(imageUrls.length==1){root.currentIndex=0;newstab.active=true;root.uploadSignal(imageUrls)} else{'+
// ' root.currentIndex=2;fotostab.active=true;'+
// 'root.uploadSignal(imageUrls)};}}',newstab,"imagePicker");
//SystemDispatcher.setInitialized();
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

@ -34,15 +34,15 @@ import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import "qrc:/js/news.js" as Newsjs import "qrc:/js/news.js" as Newsjs
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml"
Item { Item {
id: newsitem id: newsitem
width: parent.width width: parent.width
height:toprow.height+friendicaActivities.height+controlrow.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm) height:toprow.height+friendicaActivities.height+controlrow.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm)
property int itemindex: index
property string attending: "" property string attending: ""
property int itemindex: index
onAttendingChanged: {attendLabel.visible=true; onAttendingChanged: {attendLabel.visible=true;
attendLabel.text= qsTr("attending: ")+ qsTr(attending)} attendLabel.text= qsTr("attending: ")+ qsTr(attending)}
@ -145,8 +145,9 @@ Item {
textFormat: Text.RichText textFormat: Text.RichText
text:Qt.atob(newsitemobject.statusnet_html) text:Qt.atob(newsitemobject.statusnet_html)
width: newsitem.width-8*mm-2 width: newsitem.width-8*mm-2
height: implicitHeight height: Math.min(implicitHeight,3/4*root.height)
wrapMode: Text.Wrap wrapMode: Text.Wrap
clip:true
onLinkActivated:{ onLinkActivated:{
Qt.openUrlExternally(link)} Qt.openUrlExternally(link)}
Component.onCompleted:{ Component.onCompleted:{
@ -159,6 +160,29 @@ Item {
} }
} }
} }
BlueButton{
width: newsitem.width-8*mm-2
height:10*mm
anchors.bottom: itemMessage.bottom
visible: itemMessage.implicitHeight>3/4*root.height
text:"\uf078"
fontColor:"grey"
border.color: "transparent"
gradient: Gradient {
GradientStop { position: 0.0; color: "transparent" }
GradientStop { position: 0.5; color: "white" }
}
radius:0
onClicked: {
if (text=="\uf078"){
itemMessage.height=itemMessage.implicitHeight+10*mm;text="\uf077"
} else {
itemMessage.height=Math.min(itemMessage.implicitHeight,3/4*root.height);
text="\uf078";
newsView.positionViewAtIndex(index,ListView.Beginning);
}
}
}
} }
} }
} }

View File

@ -64,12 +64,10 @@ Rectangle{
imageUploadModel.append({"imageUrl":url,"description":""}) imageUploadModel.append({"imageUrl":url,"description":""})
} }
z:2 //border.color: "grey"
border.color: "grey" y:1
width: parent.width-4*mm width:root.width-mm
height:parent.height-12*mm height:root.height-5*mm
x:2*mm
y:10*mm
property string directory: "" property string directory: ""
Connections{ Connections{
@ -95,8 +93,12 @@ Rectangle{
anchors.topMargin: 1*mm anchors.topMargin: 1*mm
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 1*mm anchors.rightMargin: 1*mm
spacing:mm spacing:5*mm
Text{
font.pixelSize: 3.5*mm
font.bold: true
text:qsTr("Upload to album")
}
// BlueButton{ // BlueButton{
// id:permButton // id:permButton
// text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" // text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023"
@ -109,7 +111,9 @@ Rectangle{
BlueButton{ BlueButton{
id:closeButton id:closeButton
text: "\uf057" text: "\uf057"
onClicked:{imageDialog.destroy()} onClicked:{photoStack.pop();
//imageDialog.destroy()
}
} }
} }
@ -250,6 +254,9 @@ Rectangle{
albumModel.append({"text":storedAlbums[n]})} albumModel.append({"text":storedAlbums[n]})}
})} })}
catch (e){print(e)} catch (e){print(e)}
if(attachImageURLs.length>0){
for (var n in attachImageURLs){attachImage(attachImageURLs[n])}
}
} }
// BusyIndicator{ // BusyIndicator{
// id: imageBusy // id: imageBusy

View File

@ -37,7 +37,11 @@ import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/photoqml" import "qrc:/qml/photoqml"
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
Rectangle {
StackView{
id: photoStack
anchors.fill:parent
initialItem:Rectangle {
id:fotorectangle id:fotorectangle
y:1 y:1
width:root.width-mm width:root.width-mm
@ -48,15 +52,15 @@ Rectangle {
property bool remoteContact: false property bool remoteContact: false
onNewimagesChanged:{ onNewimagesChanged:{
if(newimages.length>0){ if(fotorectangle.newimages.length>0){
//print("newimages "+JSON.stringify(newimages)); //print("newimages "+JSON.stringify(newimages));
var ownimagelist=[]; var ownimagelist=[];
Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){ Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){
for (var i=0;i<newimages.length;i++){ for (var i=0;i<fotorectangle.newimages.length;i++){
if(albums.indexOf(newimages[i].album)==-1){ if(albums.indexOf(fotorectangle.newimages[i].album)==-1){
filesystem.Directory=root.login.imagestore+"/albums"; filesystem.Directory=root.login.imagestore+"/albums";
filesystem.makeDir(newimages[i].album)} filesystem.makeDir(fotorectangle.newimages[i].album)}
ownimagelist.push(root.login.server+"/api/friendica/photo?scale='0'&photo_id="+newimages[i].id); ownimagelist.push(root.login.server+"/api/friendica/photo?scale='0'&photo_id="+fotorectangle.newimages[i].id);
} }
}) })
xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setLogin(login.username+":"+Qt.atob(login.password));
@ -69,8 +73,8 @@ Rectangle {
} }
onCurrentimagenoChanged:{ onCurrentimagenoChanged:{
if(currentimageno==newimages.length){newImagesProgress.visible=false;showFotos(root.login,""); if(fotorectangle.currentimageno==fotorectangle.newimages.length){newImagesProgress.visible=false;showFotos(root.login,"");
newimages=[];currentimageno=0} fotorectangle.newimages=[];fotorectangle.currentimageno=0}
// download next image // download next image
} }
@ -78,17 +82,17 @@ Rectangle {
target:xhr target:xhr
onDownloadedjson:{ onDownloadedjson:{
if(type=="picturelist"){ if(type=="picturelist"){
currentimageno=currentimageno+1 fotorectangle.currentimageno=fotorectangle.currentimageno+1
Imagejs.storeImagedata(login,db,jsonObject,fotorectangle) Imagejs.storeImagedata(login,db,jsonObject,fotorectangle)
} }
} }
onDownloaded:{ onDownloaded:{
if(type=="picture"){currentimageno=currentimageno+1} if(type=="picture"){fotorectangle.currentimageno=fotorectangle.currentimageno+1}
} }
onError:{if(data=="picturelist"){ onError:{if(data=="picturelist"){
var requestid=url.substring(url.lastIndexOf("=")+1); var requestid=url.substring(url.lastIndexOf("=")+1);
Imagejs.dataRequest(login,requestid,db,xhr,fotorectangle) Imagejs.dataRequest(login,requestid,db,xhr,fotorectangle)
} else {currentimageno=currentimageno+1} } else {fotorectangle.currentimageno=fotorectangle.currentimageno+1}
} }
} }
// Connections{ // Connections{
@ -133,6 +137,10 @@ Rectangle {
}) })
} }
function uploadUrls(urls){
photoStack.push({item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{attachImageURLs:urls}})
}
ProgressBar{ ProgressBar{
id: newImagesProgress id: newImagesProgress
width: 15*mm width: 15*mm
@ -141,7 +149,7 @@ Rectangle {
anchors.right:uploadPhoto.left anchors.right:uploadPhoto.left
anchors.rightMargin:mm anchors.rightMargin:mm
visible: false visible: false
value: currentimageno/newimages.length value: fotorectangle.currentimageno/fotorectangle.newimages.length
} }
BlueButton{ BlueButton{
@ -152,8 +160,9 @@ Rectangle {
anchors.rightMargin:mm anchors.rightMargin:mm
text:"\uf0ee" text:"\uf0ee"
onClicked: { onClicked: {
var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml"); photoStack.push({item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{}});
var imageUpload = component.createObject(fotorectangle); // var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml");
// var imageUpload = component.createObject(fotorectangle);
}} }}
BlueButton{ BlueButton{
@ -168,12 +177,12 @@ Rectangle {
MenuItem { MenuItem {
text: qsTr("All Images") text: qsTr("All Images")
onTriggered: { onTriggered: {
Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){newimages=obj})} Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){fotorectangle.newimages=obj})}
} }
MenuItem { MenuItem {
text: qsTr("Only new") text: qsTr("Only new")
onTriggered: { onTriggered: {
Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){newimages=obj})} Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){fotorectangle.newimages=obj})}
} }
} }
onClicked: {photoupdatemenu.popup()} onClicked: {photoupdatemenu.popup()}
@ -260,7 +269,10 @@ Rectangle {
ListView {anchors.fill: parent; model: visualphotoModel.parts.fullscreen; interactive: false } ListView {anchors.fill: parent; model: visualphotoModel.parts.fullscreen; interactive: false }
WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"} WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"}
Component.onCompleted: { root.fotoSignal.connect(showFotos); Component.onCompleted: {
if (fotostab.phototabstatus=="Images"){showFotos(root.login,"")} root.fotoSignal.connect(showFotos);
root.uploadSignal.connect(uploadUrls);
if (fotostab.phototabstatus=="Images"){showFotos(root.login,"")}
} }
} }
}