Browse Source

v.0.5

tags/v0.5
LubuWest 8 months ago
parent
commit
d48847d183
100 changed files with 5738 additions and 2133 deletions
  1. +71
    -62
      CHANGELOG.md
  2. +16
    -16
      README.md
  3. +5
    -6
      source-android/android/AndroidManifest.xml
  4. +3
    -0
      source-android/android/build.gradle
  5. +4
    -0
      source-android/android/gradle.properties
  6. +0
    -0
      source-android/android/libcrypto.so
  7. +0
    -0
      source-android/android/libssl.so
  8. +1
    -0
      source-android/android/local.properties
  9. BIN
      source-android/android/res/drawable-hdpi/friendiqanotification.png
  10. BIN
      source-android/android/res/drawable-mdpi/friendiqanotification.png
  11. BIN
      source-android/android/res/drawable-xhdpi/friendiqanotification.png
  12. BIN
      source-android/android/res/drawable-xxhdpi/friendiqanotification.png
  13. BIN
      source-android/android/res/drawable-xxxhdpi/friendiqanotification.png
  14. BIN
      source-android/android/res/drawable/friendiqanotification.png
  15. +1
    -1
      source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java
  16. +39
    -2
      source-android/androidnative.pri/java/src/androidnative/Util.java
  17. +7
    -3
      source-android/application.qrc
  18. +1
    -0
      source-android/common/alarm.h
  19. +11
    -31
      source-android/common/alarmandroid.cpp
  20. +73
    -0
      source-android/common/alarmlinux.cpp
  21. +5
    -9
      source-android/common/friendiqa.cpp
  22. +286
    -117
      source-android/common/updatenews.cpp
  23. +9
    -1
      source-android/common/updatenews.h
  24. +5
    -4
      source-android/common/xhr.cpp
  25. +3
    -2
      source-android/common/xhr.h
  26. +5
    -4
      source-android/js/helper.js
  27. +1
    -1
      source-android/js/layout.js
  28. +72
    -57
      source-android/js/news.js
  29. +6
    -4
      source-android/js/newsworker.js
  30. +51
    -39
      source-android/js/service.js
  31. +2
    -2
      source-android/qml/calendarqml/CalendarDay.qml
  32. +17
    -10
      source-android/qml/calendarqml/CalendarTab.qml
  33. +4
    -2
      source-android/qml/calendarqml/EventList.qml
  34. +463
    -0
      source-android/qml/configqml/AccountPage.qml
  35. +227
    -0
      source-android/qml/configqml/ConfigPage.qml
  36. +15
    -11
      source-android/qml/configqml/InfoBox.qml
  37. +1
    -1
      source-android/qml/configqml/OSSettingsLinux.qml
  38. +8
    -3
      source-android/qml/configqml/RegisterPage.qml
  39. +87
    -0
      source-android/qml/configqml/SyncComponent.qml
  40. +101
    -0
      source-android/qml/configqml/SyncConfig.qml
  41. +3
    -2
      source-android/qml/contactqml/ContactComponent.qml
  42. +18
    -9
      source-android/qml/contactqml/ContactDetailsComponent.qml
  43. +5
    -2
      source-android/qml/contactqml/Contactlist.qml
  44. +85
    -52
      source-android/qml/contactqml/FriendsTab.qml
  45. +33
    -16
      source-android/qml/contactqml/GroupComponent.qml
  46. +29
    -22
      source-android/qml/contactqml/ProfileComponent.qml
  47. +267
    -68
      source-android/qml/friendiqa.qml
  48. +1
    -1
      source-android/qml/genericqml/BlueButton.qml
  49. +1
    -1
      source-android/qml/genericqml/ImagePicker.qml
  50. +3
    -2
      source-android/qml/genericqml/ImagePickerLinux.qml
  51. +5
    -6
      source-android/qml/genericqml/IntentReceiver.qml
  52. +22
    -0
      source-android/qml/genericqml/LinuxSync.qml
  53. +39
    -0
      source-android/qml/genericqml/MButton.qml
  54. +3
    -3
      source-android/qml/genericqml/PermissionDialog.qml
  55. +1
    -1
      source-android/qml/genericqml/Search.qml
  56. +28
    -13
      source-android/qml/newsqml/ContactPage.qml
  57. +67
    -63
      source-android/qml/newsqml/Conversation.qml
  58. +274
    -98
      source-android/qml/newsqml/MessageSend.qml
  59. +579
    -0
      source-android/qml/newsqml/NewsStack.qml
  60. +75
    -359
      source-android/qml/newsqml/NewsTab.qml
  61. +45
    -31
      source-android/qml/newsqml/Newsitem.qml
  62. +12
    -3
      source-android/qml/newsqml/PermissionDialog.qml
  63. +57
    -38
      source-android/qml/newsqml/SmileyDialog.qml
  64. +8
    -4
      source-android/qml/photoqml/ImageUploadDialog.qml
  65. +30
    -15
      source-android/qml/photoqml/PhotoTab.qml
  66. +14
    -0
      source-android/qtquickcontrols2.conf
  67. BIN
      source-android/translations/friendiqa-de.qm
  68. +372
    -189
      source-android/translations/friendiqa-de.ts
  69. BIN
      source-android/translations/friendiqa-es.qm
  70. +373
    -206
      source-android/translations/friendiqa-es.ts
  71. BIN
      source-android/translations/friendiqa-it.qm
  72. +367
    -224
      source-android/translations/friendiqa-it.ts
  73. +8
    -1
      source-linux/application.qrc
  74. +1
    -1
      source-linux/common/alarm.h
  75. +16
    -30
      source-linux/common/alarmandroid.cpp
  76. +73
    -0
      source-linux/common/alarmlinux.cpp
  77. +1
    -1
      source-linux/common/filesystem.cpp
  78. +1
    -1
      source-linux/common/filesystem.h
  79. +25
    -10
      source-linux/common/friendiqa.cpp
  80. +1
    -1
      source-linux/common/remoteauthasyncimageprovider.cpp
  81. +1
    -1
      source-linux/common/remoteauthasyncimageprovider.h
  82. +299
    -90
      source-linux/common/updatenews.cpp
  83. +12
    -33
      source-linux/common/updatenews.h
  84. +1
    -1
      source-linux/common/uploadableimage.cpp
  85. +1
    -1
      source-linux/common/uploadableimage.h
  86. +10
    -10
      source-linux/common/xhr.cpp
  87. +4
    -3
      source-linux/common/xhr.h
  88. +4
    -2
      source-linux/friendiqa.pro
  89. +5
    -4
      source-linux/js/helper.js
  90. +1
    -1
      source-linux/js/layout.js
  91. +72
    -57
      source-linux/js/news.js
  92. +6
    -4
      source-linux/js/newsworker.js
  93. +51
    -39
      source-linux/js/service.js
  94. +2
    -2
      source-linux/qml/calendarqml/CalendarDay.qml
  95. +17
    -10
      source-linux/qml/calendarqml/CalendarTab.qml
  96. +4
    -2
      source-linux/qml/calendarqml/EventList.qml
  97. +463
    -0
      source-linux/qml/configqml/AccountPage.qml
  98. +227
    -0
      source-linux/qml/configqml/ConfigPage.qml
  99. +15
    -11
      source-linux/qml/configqml/InfoBox.qml
  100. +1
    -1
      source-linux/qml/configqml/OSSettingsLinux.qml

+ 71
- 62
CHANGELOG.md View File

@@ -1,33 +1,68 @@
## v0.1##

## v0.5 ##
* Redesign due to QML Components 1 being deprecated in Qt 5.12: Slideview for News, left Drawer for Settings, message creation in listview header
* Android Notifications for News, DMs, Replies
* Global app config separated from account config

# News #

* Native Android image selector for new message
* Click on contacts shows contact details on news page
* Fix problem with news list after deletion of item
## v0.4 ##
* Background sync for friends timeline (interval on config page must be > 0) for Android > 5
* Replies timeline
* Bugfix: App asks for storage permission on first start

# Contacts #
* Clean contacts with no news

# Images #
* Upload pictures with description to album (permissions cannot be set due to API problems)
* Delete pictures or albums from client and server (long press on picture in overview)
* Fix problem when enlarging photo
## v0.3.4 ##
* Direct message creation from profile page works again
* Profile image upload works again
* Viewing private album pictures of contacts works again
* On first start servername from https://dir.friendica.social/servers/surprise selected
* Register button opens webview of registration page on server

# Translations #
* German, Spanish

## v0.3.3 ##
* Update for OpenSSL and At
* Experimental support for Peertube (links are expanded to video widget)
* Some Unicode emojis
* Redesign of contact details (click on contact opens in new stack and shows last news)


## v0.1.1##
* FIX: Spanish translation
* FIX: Empty Newsview after deletion of first newsitem
## v0.3.2 ##
* For news containing url ending with mp3, mp4, avi, webm, ogg: media can be played in app
* Pictures can be renamed or moved to another album
* Bugfix: random crashes for conversations
* Bugfix: attach image to message works again
* Bugfix: check for nickname on Server has been removed due to API change


## v0.3.1 ##
* By popular demand: Conversations open in a new stack, like in Twidere
* Conversations open after (long) press on news, like in Twidere
* Image attachments are shown below text and can be enlarged, like in Twidere (solves issue #8)
* New messages are html, line breaks work (solves issue #7)


## v0.1.2#
* FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above
## v0.3 ##
* Fix for [issue 6](https://github.com/LubuWest/Friendiqa/issues/6)
* Refactoring of news part
* Search button for news
* Click on hashtag in newsitem starts search for news with that word
* Public timeline
* Timeline for selected group
* Small redesign of SendMessage page


## v0.2.2 ##
* Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5)
* Link to list of public server on Config Tab
* Small redesign of SendMessage page
* Intents for texts/urls (Send text or url from everywhere to create message)


## 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)


## v0.2 ##
@@ -53,57 +88,31 @@
# Translations #
* 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)

## v0.2.2 ##
* Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5)
* Link to list of public server on Config Tab
* Small redesign of SendMessage page
* Intents for texts/urls (Send text or url from everywhere to create message)
## v0.1.2##
* FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above


## v0.3 ##
* Fix for [issue 6](https://github.com/LubuWest/Friendiqa/issues/6)
* Refactoring of news part
* Search button for news
* Click on hashtag in newsitem starts search for news with that word
* Public timeline
* Timeline for selected group
* Small redesign of SendMessage page
## v0.1.1##
* FIX: Spanish translation
* FIX: Empty Newsview after deletion of first newsitem

## v0.3.1 ##
* By popular demand: Conversations open in a new stack, like in Twidere
* Conversations open after (long) press on news, like in Twidere
* Image attachments are shown below text and can be enlarged, like in Twidere (solves issue #8)
* New messages are html, line breaks work (solves issue #7)

## v0.1##

## v0.3.2 ##
* For news containing url ending with mp3, mp4, avi, webm, ogg: media can be played in app
* Pictures can be renamed or moved to another album
* Bugfix: random crashes for conversations
* Bugfix: attach image to message works again
* Bugfix: check for nickname on Server has been removed due to API change
# News #

* Native Android image selector for new message
* Click on contacts shows contact details on news page
* Fix problem with news list after deletion of item

## v0.3.3 ##
* Update for OpenSSL and At
* Experimental support for Peertube (links are expanded to video widget)
* Some Unicode emojis
* Redesign of contact details (click on contact opens in new stack and shows last news)
# Contacts #
* Clean contacts with no news

## v0.3.4 ##
* Direct message creation from profile page works again
* Profile image upload works again
* Viewing private album pictures of contacts works again
* On first start servername from https://dir.friendica.social/servers/surprise selected
* Register button opens webview of registration page on server
# Images #
* Upload pictures with description to album (permissions cannot be set due to API problems)
* Delete pictures or albums from client and server (long press on picture in overview)
* Fix problem when enlarging photo

## v0.4 ##
* Background sync for friends timeline (interval on config page must be > 0) for Android > 5
* Replies timeline
* Bugfix: App asks for storage permission on first start
# Translations #
* German, Spanish

+ 16
- 16
README.md View File

@@ -2,7 +2,7 @@
QML based client for the Friendica Social Network.
Tabs for news (incl. Direct Messages), friends, photos and events.
OS: currently Linux and Android (4.3 Jelly Bean).
OS: currently Linux and Android (4.3 Jelly Bean, 5.1 for background sync).
Source code is a QtCreator project.
## Screenshots ##
@@ -18,9 +18,10 @@ QML based client for the Friendica Social Network.
# News #
Currently supported:
* Shows Posts from friends, selected group, replies, favorited messages, public timeline, Direct Messages and notifications
* Background sync with configurable interval of 15 min to 2h for active contact for friends timeline (Android 5 required)
* Search button for news
* Shows Posts from friends, replies, Direct Messages and notifications (in swipe view), selected group, replies, favorited messages, public timeline
* Background sync with configurable interval of 15 min to 2h for active contact for friends timeline, replies and DMs (Android 5.1 required)
* Android notifications for new items in friends timeline, replies and DMs
* Search for news
* Click on hashtag in newsitem starts search for news with that word
* Click on image shows image fullscreen
* For news containing urls ending with mp3, mp4, avi, webm, ogg or to a Peertube instance: media can be played in the app
@@ -39,26 +40,23 @@ Currently supported:
* Native Android image dialog
ToDo:
* Videos and other binary data as attachment (sending)
* More than one attachment (currently not supported in API)
* Videos and other binary data as attachment (sending, not supported in API)
* More than one attachment
* Attachments for Direct messages (currently not supported in API)
# Friends #
Currently supported:
* Tabs for own profiles, friends, other contacts and groups
* Show profile(s) of user and change profile picture
* List of all known contacts with locally downloaded pictures
* Additional information, last messages and other functionality shown in news tab
* Send direct message, if contact is following
* 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 public and private pictures of contact (screenscraping of contact's website, works only with certain theme)
* Show public and private 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
(needs API change)
@@ -71,7 +69,7 @@ Currently supported:
* Download public and private own images to local directory
* Upload picture to album with descriptions(public), send from gallery
* Delete own pictures and albums on client and server
* Change name or album of existing picture
* Change name or album of existing picture
* 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
* Pinch to zoom, swipe to scroll
@@ -81,8 +79,9 @@ ToDo:
# Events #
Currently supported:
* Download own public events
* Show public and private events of Friendica contacts (Friendica 3.6 server required)
* 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
@@ -91,11 +90,12 @@ ToDo
* Create events (needs API)
# Config #
# Config/Accounts #
Currently supported:
* Multiple accounts
* Maximum news (deleted after use of Quit button)
* View mode for news (tree or timeline)
* Maximum news (deleted after use of Quit button)
* Sync home timeline, replies, DM, Notify yes/no
ToDo
* OAuth?

+ 5
- 6
source-android/android/AndroidManifest.xml 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.4" android:versionCode="12" android:installLocation="auto">
<manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.5" android:versionCode="13" 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="singleInstance" android:taskAffinity="">
<intent-filter>
@@ -78,13 +78,12 @@
<!-- Messages maps -->
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splash"/>
</service>
<service android:process=":qt" android:name="androidnative.friendiqa.FriendiqaStopService" android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true">

<service android:process=":qt" android:name="androidnative.friendiqa.FriendiqaStopService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true">
<meta-data android:name="android.app.background_running" android:value="true"/>
</service>
</application>
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="26"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>

+ 3
- 0
source-android/android/build.gradle View File

@@ -26,6 +26,9 @@ dependencies {
compile 'com.android.support:support-v4:25.3.1'
}

dependencies {
compile 'com.android.support:support-compat:25.3.1'
}

android {
/*******************************************************

+ 4
- 0
source-android/android/gradle.properties View File

@@ -0,0 +1,4 @@
androidBuildToolsVersion=25.0.3
androidCompileSdkVersion=27
buildDir=.build
qt5AndroidDir=/home/pankraz/Qt/5.11.1/android_armv7/src/android/java

+ 0
- 0
source-android/android/libcrypto.so View File


+ 0
- 0
source-android/android/libssl.so View File


+ 1
- 0
source-android/android/local.properties View File

@@ -0,0 +1 @@
sdk.dir=/home/pankraz/android-sdk_alt

BIN
source-android/android/res/drawable-hdpi/friendiqanotification.png View File

Before After
Width: 36  |  Height: 36  |  Size: 460B

BIN
source-android/android/res/drawable-mdpi/friendiqanotification.png View File

Before After
Width: 24  |  Height: 24  |  Size: 430B

BIN
source-android/android/res/drawable-xhdpi/friendiqanotification.png View File

Before After
Width: 48  |  Height: 48  |  Size: 540B

BIN
source-android/android/res/drawable-xxhdpi/friendiqanotification.png View File

Before After
Width: 72  |  Height: 72  |  Size: 718B

BIN
source-android/android/res/drawable-xxxhdpi/friendiqanotification.png View File

Before After
Width: 96  |  Height: 96  |  Size: 892B

BIN
source-android/android/res/drawable/friendiqanotification.png View File

Before After
Width: 96  |  Height: 96  |  Size: 892B

+ 1
- 1
source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java View File

@@ -38,7 +38,7 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt
// app-defined int constant. The callback method gets the
// result of the request.
} else {
System.loadLibrary("friendiqa");
if((getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_NEW_TASK) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) || (getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))) {
SystemDispatcher.onActivityResume();

+ 39
- 2
source-android/androidnative.pri/java/src/androidnative/Util.java View File

@@ -10,12 +10,18 @@ import android.content.Context;
import android.content.ComponentName;
import android.app.job.JobScheduler;
import android.app.job.JobInfo;
import android.app.PendingIntent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import org.qtproject.qt5.android.QtNative;
import androidnative.friendiqa.FriendiqaService;
import androidnative.friendiqa.FriendiqaStopService;
import androidnative.friendiqa.FriendiqaActivity;
import androidnative.AndroidNativeActivity;
import androidnative.AndroidNativeService;
import android.content.Intent;
import java.util.Map;
import org.qtproject.friendiqa.R;

public class Util {

@@ -24,6 +30,7 @@ public class Util {
public static final String SET_TRANSLUCENT_STATUS_BAR = "androidnative.Util.setTranslucentStatusBar";
public static final String SET_FULL_SCREEN = "androidnative.Util.setFullScreen";
public static final String SET_SCHEDULE = "androidnative.Util.setSchedule";
public static final String SET_NOTIFICATION = "androidnative.Util.setNotification";


static {
@@ -35,6 +42,8 @@ public class Util {
setFullScreen(message);
} else if (type.equals(SET_SCHEDULE)) {
setSchedule(message);
} else if (type.equals(SET_NOTIFICATION)) {
setNotification(message);
}
}
});
@@ -98,11 +107,39 @@ public class Util {

}

static void setNotification(Map message) {
//Log.d(TAG,"setNotification");
Context context;
//Context appcontext;
context = QtNative.service().getApplicationContext();
//appcontext = QtNative.activity().getApplicationContext();
Intent intent = new Intent(context,FriendiqaActivity.class);
//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

final String textTitle = (String) message.get("title");
final String textContent = (String) message.get("message");
final int notificationId = (int) message.get("id");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.friendiqanotification)
.setContentIntent(pendingIntent)
.setContentTitle(textTitle)
.setContentText(textContent)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(textContent))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(notificationId, builder.build());
}

static void setSchedule(Map message) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return;
}
Log.d(TAG,"Friendiqa schedule Androidnative service");
//Log.d(TAG,"Friendiqa schedule Androidnative service");
final Integer value = (Integer) message.get("value");
//final Activity activity = QtNative.activity();
//final Service service = QtNative.service();
@@ -126,7 +163,7 @@ public class Util {
jobScheduler.schedule(builder.build());
if (QtNative.service() != null){
Log.d(TAG,"Schedule Stopping Friendiqa Androidnative service");
//Log.d(TAG,"Schedule Stopping Friendiqa Androidnative service");
ComponentName componentStopper = new ComponentName(context, FriendiqaStopService.class);
JobInfo.Builder stopbuilder = new JobInfo.Builder(1, componentStopper)
.setMinimumLatency(50)

+ 7
- 3
source-android/application.qrc View File

@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/">
<file>qtquickcontrols2.conf</file>
<file>qml/friendiqa.qml</file>
<file>qml/newsqml/NewsTab.qml</file>
<file>qml/newsqml/Newsitem.qml</file>
@@ -16,7 +17,7 @@
<file>qml/photoqml/PhotogroupComponent.qml</file>
<file>qml/photoqml/PhotoTab.qml</file>
<file>qml/configqml/InfoBox.qml</file>
<file>qml/configqml/ConfigTab.qml</file>
<file>qml/configqml/ConfigPage.qml</file>
<file>js/layout.js</file>
<file>js/photoworker.js</file>
<file>js/service.js</file>
@@ -27,6 +28,7 @@
<file>images/fontawesome-webfont.ttf</file>
<file>images/folder-blue.png</file>
<file>qml/configqml/OSSettingsAndroid.qml</file>
<file>qml/genericqml/MButton.qml</file>
<file>qml/configqml/OSSettingsLinux.qml</file>
<file>qml/newsqml/SmileyDialog.qml</file>
<file>js/smiley.js</file>
@@ -225,7 +227,9 @@
<file>qml/newsqml/ContactPage.qml</file>
<file>qml/newsqml/NewsLink.qml</file>
<file>qml/configqml/RegisterPage.qml</file>
<file>qml/newsqml/NewsYplayer.qml</file>
<file>js/yplayer.html</file>
<file>qml/configqml/AccountPage.qml</file>
<file>qml/newsqml/NewsStack.qml</file>
<file>qml/configqml/SyncConfig.qml</file>
<file>qml/configqml/SyncComponent.qml</file>
</qresource>
</RCC>

+ 1
- 0
source-android/common/alarm.h View File

@@ -51,6 +51,7 @@ signals:

public slots:
void setAlarm(int time);
void notify(QString title, QString text, int id);

private:
int m_time;

+ 11
- 31
source-android/common/alarmandroid.cpp View File

@@ -29,8 +29,6 @@
// 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 <QtAndroidExtras/QAndroidJniObject>
//#include <QtAndroidExtras/QAndroidJniEnvironment>
#include "alarm.h"
#include <QtCore/QDebug>
#include "AndroidNative/systemdispatcher.h"
@@ -45,38 +43,20 @@ ALARM::ALARM(QObject *parent) : QObject(parent){}

void ALARM::setAlarm(int interval)
{
qDebug() << interval;
QVariantMap message;
message["value"] = interval;
AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util");
AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message);
//AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message);
// auto activity = QtAndroid::androidActivity();
// auto packageManager = activity.callObjectMethod("getPackageManager",
// "()Landroid/content/pm/PackageManager;");

// auto activityIntent = packageManager.callObjectMethod("getLaunchIntentForPackage",
// "(Ljava/lang/String;)Landroid/content/Intent;",
// activity.callObjectMethod("getPackageName",
// "()Ljava/lang/String;").object());

// auto pendingIntent = QAndroidJniObject::callStaticObjectMethod("android/app/PendingIntent", "getActivity",
// "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;",
// activity.object(), jint(0), activityIntent.object(),
// QAndroidJniObject::getStaticField<jint>("android/content/Intent",
// "FLAG_ACTIVITY_CLEAR_TOP"));

// auto alarmManager = activity.callObjectMethod("getSystemService",
// "(Ljava/lang/String;)Ljava/lang/Object;",
// QAndroidJniObject::getStaticObjectField("android/content/Context",
// "ALARM_SERVICE",
// "Ljava/lang/String;").object());

// alarmManager.callMethod<void>("set",
// "(IJLandroid/app/PendingIntent;)V",
// QAndroidJniObject::getStaticField<jint>("android/app/AlarmManager", "RTC"),
// jlong(QDateTime::currentMSecsSinceEpoch() + 100), pendingIntent.object());


AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message);
}

void ALARM::notify(QString title, QString text, int id)
{
//qDebug() << "notify "<< title << text;
QVariantMap message;
message["title"] = title;
message["message"] = text;
message["id"] = id;
AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util");
AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setNotification", message);
}

+ 73
- 0
source-android/common/alarmlinux.cpp View File

@@ -0,0 +1,73 @@
// This file is part of Friendiqa
// https://git.friendi.ca/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 <QtAndroidExtras/QAndroidJniObject>
//#include <QtAndroidExtras/QAndroidJniEnvironment>
#include "alarm.h"
#include <QtCore/QDebug>
#include <QtDBus/QtDBus>
//#include "AndroidNative/systemdispatcher.h"

ALARM *ALARM::instance()
{
static ALARM alarm;
return &alarm;
}

ALARM::ALARM(QObject *parent) : QObject(parent){}

void ALARM::setAlarm(int interval)
{
qDebug() << interval;
QVariantMap message;
message["value"] = interval;
// AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util");
// AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message);
//AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message);
}

void ALARM::notify(QString title, QString text, int id)
{
qDebug() << title << text;
QVariantMap message;
message["title"] = title;
message["message"] = text;
QDBusConnection bus = QDBusConnection::sessionBus();
QDBusInterface dbus_iface("org.freedesktop.Notifications", "/org/freedesktop/Notifications",
"org.freedesktop.Notifications", bus);
QString appname="Friendiqa";
uint v=12321;
if (dbus_iface.isValid()){

dbus_iface.call("Notify",appname,v,"",title,text,"","",5000);
}
// AndroidNative::SystemDispatcher::instance()->dispatch("Notifier.notify", message);
}

+ 5
- 9
source-android/common/friendiqa.cpp View File

@@ -32,17 +32,15 @@
#include <QApplication>
#include <QtQml/QQmlEngine>
#include <QAndroidService>
#include <QtAndroid>
#include <QtQuick>
#include "xhr.h"
#include "updatenews.h"
#include "filesystem.h"
#include "remoteauthasyncimageprovider.h"
#include "alarm.h"
#include "AndroidNative/systemdispatcher.h"
#include "AndroidNative/environment.h"
//#include "AndroidNative/environment.h"
//#include "AndroidNative/debug.h"
#include "AndroidNative/mediascannerconnection.h"
//#include "AndroidNative/mediascannerconnection.h"


#ifdef Q_OS_ANDROID
@@ -66,13 +64,11 @@ int main(int argc, char *argv[]) {
UPDATENEWS* updatenews= UPDATENEWS::instance();
updatenews->setDatabase();
updatenews->login();
updatenews->timeline();
updatenews->startsync();
app.connect (updatenews,SIGNAL(quitapp()),&app,SLOT(quit()));
//QtAndroid::androidService().callMethod<void>("stopSelf");
return app.exec();
}
else{
QApplication app(argc, argv);
QQuickView view;
QTranslator qtTranslator;
@@ -87,8 +83,8 @@ int main(int argc, char *argv[]) {
view.rootContext()->setContextProperty("filesystem", filesystem);
ALARM* alarm = ALARM::instance();
view.rootContext()->setContextProperty("alarm", alarm);
// UPDATENEWS* updatenews = UPDATENEWS::instance();
// view.rootContext()->setContextProperty("updatenews", updatenews);
UPDATENEWS* updatenews = UPDATENEWS::instance();
view.rootContext()->setContextProperty("updatenews", updatenews);
view.setSource(QUrl("qrc:/qml/friendiqa.qml"));
view.show();
view.connect(view.rootContext()->engine(), SIGNAL(quit()), &app, SLOT(quit()));

+ 286
- 117
source-android/common/updatenews.cpp View File

@@ -100,130 +100,304 @@ void UPDATENEWS::login()
m_imagedir=query.value(3).toString();
xhr.setImagedir(m_imagedir);
QString isActive=query.value(7).toString();
m_updateInterval=query.value(5).toInt();
m_api="/api/statuses/friends_timeline";
xhr.setApi(m_api);
}
//m_updateInterval=query.value(5).toInt();


QSqlQuery syncquery("SELECT * FROM globaloptions",m_db);
// QSqlQuery delquery("DELETE FROM globaloptions WHERE k='sync_interval'",m_db);
// delquery.exec();
m_updateInterval=0;
syncindex=0;
synclist.clear();
//QSqlQuery syncquery("SELECT * FROM globaloptions WHERE k like 'sync_%' AND v=1",m_db);
while (syncquery.next()){
if (syncquery.value(0).toString()=="syncinterval"){
m_updateInterval=syncquery.value(1).toInt();
}
if (syncquery.value(0).toString().left(5)=="sync_" && syncquery.value(1).toInt()==1){
synclist.append(syncquery.value(0).toString());
//qDebug() << " sync " << syncquery.value(0).toString() << " " <<syncquery.value(1).toString();
}
if (syncquery.value(0).toString().left(7)=="notify_" && syncquery.value(1).toInt()==1){
notifylist.append(syncquery.value(0).toString());
//qDebug() << " notify " << syncquery.value(0).toString() << " " <<syncquery.value(1).toString();
}
}
// QSqlQuery notifyquery("SELECT * FROM globaloptions WHERE k like 'notify_%' AND v=1",m_db);
//qDebug() << "size " << notifyquery.size();
// while (notifyquery.next()){
// notifylist.append(syncquery.value(0).toString());
// qDebug() << " notify " << syncquery.value(0).toString();
//}
}

void UPDATENEWS::startsync()
{ //qDebug()<<"Friendiqa start syncing " <<synclist.length()<<" index "<<syncindex;
QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
if (syncindex<synclist.length()){
if (synclist[syncindex]=="sync_Timeline"){
timeline();
} else if (synclist[syncindex]=="sync_Replies") {
replies();
} else if (synclist[syncindex]=="sync_DirectMessages") {
directmessages();
} else if (synclist[syncindex]=="sync_Notifications") {
notifications();
}
} else if (syncindex==synclist.length()) {
m_api="";
if(m_updateInterval!=0){
syncindex=0;
synclist.clear();
m_db.close();
m_db.removeDatabase(m_db.connectionName());
emit quitapp();
alarm.setAlarm(m_updateInterval);
m_updateInterval=0;
}
}
}


void UPDATENEWS::timeline()
{
qDebug()<<"Friendiqa start timeline";
QSqlQuery query("SELECT status_id FROM news WHERE username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
if (query.isActive() && query.isSelect()){query.first();};
QString lastid=query.value(0).toString();
m_api="/api/statuses/friends_timeline";
xhr.clearParams();
xhr.setParam("since_id",lastid);
xhr.setUrl(m_url);
xhr.setApi(m_api);
QSqlQuery query("SELECT status_id FROM news WHERE messagetype=0 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
if (query.isActive() && query.isSelect()){
if (query.first()){
QString lastid=query.value(0).toString();
xhr.setParam("since_id",lastid);
}
}
xhr.setParam("count","50");
xhr.get();
QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}

void UPDATENEWS::replies()
{
m_api="/api/statuses/replies";
xhr.clearParams();
xhr.setUrl(m_url);
xhr.setApi(m_api);
QSqlQuery query("SELECT status_id FROM news WHERE messagetype=3 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
if (query.isActive() && query.isSelect()){
if (query.first()){
QString lastid=query.value(0).toString();
xhr.setParam("since_id",lastid);
}
}
xhr.setParam("count","50");
xhr.get();
QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}

//void UPDATENEWS::startservice(QString type,QVariantMap map)
//{
// qDebug ()<<"Friediqa start service "<<type;
// if (type=="androidnativeServiceStarted"){
// setDatabase();
// login();
// timeline();
// }
//}
void UPDATENEWS::directmessages()
{
m_api="/api/direct_messages/all";
xhr.clearParams();
xhr.setUrl(m_url);
xhr.setApi(m_api);
QSqlQuery query("SELECT status_id FROM news WHERE messagetype=1 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
if (query.isActive() && query.isSelect()){
if (query.first()){
QString lastid=query.value(0).toString();
xhr.setParam("since_id",lastid);
}
}
xhr.get();
QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}

void UPDATENEWS::store(QByteArray serverreply,QString apiname)
void UPDATENEWS::notifications()
{
QJsonDocument news;
qDebug()<<apiname << news;
QJsonParseError jsonerror;
news=QJsonDocument::fromJson(serverreply,&jsonerror);
if (news.isArray()){
for (int i=0; i < news.array().count();i++){
QJsonValue newsitem=news[i];
QSqlQuery query(m_db);
query.prepare("INSERT INTO news (username,messagetype,text,created_at,in_reply_to_status_id,source,status_id,in_reply_to_user_id,geo,favorited,uid,statusnet_html,statusnet_conversation_id,friendica_activities,friendica_activities_self,attachments,friendica_owner) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
query.bindValue(0,username);
query.bindValue(1,"0");
query.bindValue(2, newsitem["text"].toString().toUtf8().toBase64());
QString sourcedate=newsitem["created_at"].toString();
QString formateddate=sourcedate.mid(0,3)+", "+sourcedate.mid(8,3)+sourcedate.mid(4,3)+sourcedate.mid(25,5)+sourcedate.mid(10,15);
query.bindValue(3,QDateTime::fromString(formateddate,Qt::RFC2822Date).toMSecsSinceEpoch() );
if(newsitem["in_reply_to_status_id"]!=QJsonValue::Null){query.bindValue(4, newsitem["in_reply_to_status_id"].toInt());};
query.bindValue(5,newsitem["source"]);
query.bindValue(6,newsitem["id"].toInt());
if(newsitem["in_reply_to_user_id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["in_reply_to_user_id"].toInt());};
query.bindValue(8,newsitem["geo"]);
query.bindValue( 9, newsitem["favorited"].toInt());
query.bindValue(10, newsitem["user"]["id"].toInt());
query.bindValue(11, newsitem["statusnet_html"].toString().toUtf8().toBase64());
query.bindValue(12, newsitem["statusnet_conversation_id"].toInt());
QJsonArray likeArray;QJsonArray dislikeArray;QJsonArray attendyesArray;QJsonArray attendnoArray;QJsonArray attendmaybeArray;
if (newsitem.toObject().contains("friendica_activities")){
for (int a=0; a < newsitem["friendica_activities"]["like"].toArray().count();a++){
likeArray.append(newsitem["friendica_activities"]["like"][a]["url"].toString());
m_api="/api/friendica/notifications";
xhr.clearParams();
xhr.setUrl(m_url);
xhr.setApi(m_api);
xhr.get();
QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}


void UPDATENEWS::store(QByteArray serverreply,QString apiname)
{ if (apiname!=m_api || xhr.downloadtype()!=""){} else {
QJsonDocument news;
//qDebug()<<apiname << serverreply;
QJsonParseError jsonerror;
news=QJsonDocument::fromJson(serverreply,&jsonerror);
if (news.isArray()){
for (int i=0; i < news.array().count();i++){
QJsonValue newsitem=news[i];
if (apiname=="/api/friendica/notifications"){
QSqlQuery testquery("SELECT status_id FROM news WHERE status_id=" + QString::number(newsitem["id"].toInt()) + " AND messagetype=2 AND username='"+ username +"'",m_db);
if (testquery.first()) {continue;}
}
for (int b=0; b < newsitem["friendica_activities"]["dislike"].toArray().count();b++){
dislikeArray.append(newsitem["friendica_activities"]["dislike"][b]["url"].toString());
QSqlQuery query(m_db);
query.prepare("INSERT INTO news (username,messagetype,text,created_at,in_reply_to_status_id,source,status_id,in_reply_to_user_id,geo,favorited,uid,statusnet_html,statusnet_conversation_id,friendica_activities,friendica_activities_self,attachments,friendica_owner) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
query.bindValue(0,username);
query.bindValue(1,"0");
query.bindValue(2, newsitem["text"].toString().toUtf8().toBase64());
QString sourcedate=newsitem["created_at"].toString();
QString formateddate=sourcedate.mid(0,3)+", "+sourcedate.mid(8,3)+sourcedate.mid(4,3)+sourcedate.mid(25,5)+sourcedate.mid(10,15);
query.bindValue(3,QDateTime::fromString(formateddate,Qt::RFC2822Date).toMSecsSinceEpoch() );
if(newsitem["in_reply_to_status_id"]!=QJsonValue::Null){query.bindValue(4, newsitem["in_reply_to_status_id"].toInt());}
query.bindValue(5,newsitem["source"]);
query.bindValue(6,newsitem["id"].toInt());
if(newsitem["in_reply_to_user_id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["in_reply_to_user_id"].toInt());}
query.bindValue(8,newsitem["geo"]);
query.bindValue( 9, newsitem["favorited"].toInt());
query.bindValue(10, newsitem["user"]["id"].toInt());
query.bindValue(11, newsitem["statusnet_html"].toString().toUtf8().toBase64());
query.bindValue(12, newsitem["statusnet_conversation_id"].toInt());
QJsonArray likeArray;QJsonArray dislikeArray;QJsonArray attendyesArray;QJsonArray attendnoArray;QJsonArray attendmaybeArray;
if (newsitem.toObject().contains("friendica_activities")){
for (int a=0; a < newsitem["friendica_activities"]["like"].toArray().count();a++){
likeArray.append(newsitem["friendica_activities"]["like"][a]["url"].toString());
}
for (int b=0; b < newsitem["friendica_activities"]["dislike"].toArray().count();b++){
dislikeArray.append(newsitem["friendica_activities"]["dislike"][b]["url"].toString());
}
for (int c=0; c < newsitem["friendica_activities"]["attendyes"].toArray().count();c++){
attendyesArray.append(newsitem["friendica_activities"]["attendyes"][c]["url"].toString());
}
for (int d=0; d < newsitem["friendica_activities"]["attendno"].toArray().count();d++){
attendnoArray.append(newsitem["friendica_activities"]["attendno"][d]["url"].toString());
}
for (int e = 0; e < newsitem["friendica_activities"]["attendmaybe"].toArray().count();e++){
attendmaybeArray.append(newsitem["friendica_activities"]["attendmaybe"][e]["url"].toString());
}
}
QJsonArray friendica_activities; friendica_activities={likeArray,dislikeArray,attendyesArray,attendnoArray,attendmaybeArray};
QJsonDocument activities; activities.setArray(friendica_activities);
query.bindValue(13,activities.toJson(QJsonDocument::Compact).toBase64());
query.bindValue(14,"[]");

if (newsitem["attachments"]!=QJsonValue::Undefined){
query.bindValue(15, QJsonDocument(newsitem["attachments"].toArray()).toJson(QJsonDocument::Compact).toBase64());
}else {
query.bindValue(15, "");
}
for (int c=0; c < newsitem["friendica_activities"]["attendyes"].toArray().count();c++){
attendyesArray.append(newsitem["friendica_activities"]["attendyes"][c]["url"].toString());

if (newsitem["friendica_author"]!=QJsonValue::Undefined){
query.bindValue(16, newsitem["friendica_author"]["url"]);
}else {
query.bindValue(16, newsitem["user"]["url"]);
}

if (apiname=="/api/statuses/replies"){
query.bindValue(1,"3");
}
if (apiname == "/api/direct_messages/all"){
query.bindValue(1,"1");
query.bindValue(5,"Friendica");
if(newsitem["recipient"]["id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["recipient"]["id"].toInt());}
query.bindValue(10, newsitem["sender_id"].toInt());
query.bindValue(11, newsitem["text"].toString().toUtf8().toBase64());
if(newsitem["friendica_parent_uri"]!=QJsonValue::Null){ query.bindValue(12,newsitem["friendica_parent_uri"]);}
query.bindValue(16, newsitem["sender"]["url"]);
}
if (apiname == "/api/friendica/notifications"){
query.bindValue(1,"2");
query.bindValue(3,QDateTime::fromString(newsitem["date"].toString(),"yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch());
query.bindValue(5,"Friendica");
QJsonObject cleancontact= findNotificationContact(newsitem["url"].toString());
query.bindValue(10, cleancontact["id"].toInt());
query.bindValue(11, newsitem["msg_html"].toString().toUtf8().toBase64());
if(newsitem["parent"]!=QJsonValue::Null){ query.bindValue(12,newsitem["parent"]);}
query.bindValue(16, newsitem["url"]);
}

if(!(query.exec())) {qDebug()<<query.lastError();}

// notifications
if (apiname=="/api/statuses/friends_timeline"){
if(notifylist.contains("notify_Timeline")){
alarm.notify("Home: "+ newsitem["user"]["name"].toString(),newsitem["text"].toString(),0);
}
}
if (apiname=="/api/statuses/replies"){
if(notifylist.contains("notify_Replies")){
alarm.notify("Replies: "+newsitem["user"]["name"].toString(),newsitem["text"].toString(),1);
}
}
if (apiname=="/api/direct_messages/all"){
if(notifylist.contains("notify_DirectMessages")){
alarm.notify("DirectMessage: "+newsitem["sender"]["name"].toString(),newsitem["text"].toString(),2);
}
}
for (int d=0; d < newsitem["friendica_activities"]["attendno"].toArray().count();d++){
attendnoArray.append(newsitem["friendica_activities"]["attendno"][d]["url"].toString());
if (apiname=="/api/friendica/notifications"){
if(notifylist.contains("notify_Notifications")){
alarm.notify("Notification: "+newsitem["name"].toString(),newsitem["text"].toString(),3);
}
}
for (int e = 0; e < newsitem["friendica_activities"]["attendmaybe"].toArray().count();e++){
attendmaybeArray.append(newsitem["friendica_activities"]["attendmaybe"][e]["url"].toString());
}
QList<QJsonValue> newcontacts=findNewContacts(news);
//qDebug()<< "new contacts count " << newcontacts.size();
if (newcontacts.size()>0){
updateContacts(newcontacts);
startImagedownload();

} else {
if(m_updateInterval!=0){
syncindex+=1;
startsync();
}
};
QJsonArray friendica_activities; friendica_activities={likeArray,dislikeArray,attendyesArray,attendnoArray,attendmaybeArray};
QJsonDocument activities; activities.setArray(friendica_activities);
query.bindValue(13,activities.toJson(QJsonDocument::Compact).toBase64());
query.bindValue(14,"[]");

if (newsitem["attachments"]!=QJsonValue::Undefined){
query.bindValue(15, QJsonDocument(newsitem["attachments"].toArray()).toJson(QJsonDocument::Compact).toBase64());
};

query.bindValue(16, newsitem["friendica_owner"]["url"]);
query.exec() ;
}
}
else {
qDebug()<< "Friendiqa updatenews error " << serverreply;
emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply));
syncindex+=1;
startsync();
}
}
else {
qDebug()<< "Friendiqa updatenews error";
emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply));
if(m_updateInterval!=0){
m_db.close();
m_db.removeDatabase(m_db.connectionName());
emit quitapp();
alarm.setAlarm(m_updateInterval);
};
}
QList<QJsonValue> newcontacts=findNewContacts(news);
updateContacts(newcontacts);
startImagedownload();
connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));

}



void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index){
if (downloadtype=="contactlist"){
QSqlQuery testquery("SELECT profile_image FROM contacts WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db);
testquery.exec();
testquery.first();
//qDebug()<< "update imageurl for " <<imageurl << " from " <<testquery.value(0).toString() <<" to "<< filename <<" index " << index << " newcontactnames.length " <<newcontactnames.length();
QSqlQuery query("UPDATE contacts SET profile_image='"+ filename +"' WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db);
query.exec();
if (index==(newcontactnames.length()-1)){
newcontactnames.clear();
newcontactimagelinks.clear();
if(m_updateInterval!=0){
m_db.close();
m_db.removeDatabase(m_db.connectionName());
emit quitapp();
alarm.setAlarm(m_updateInterval);
};
syncindex+=1;
startsync();
}
}
}
}

QJsonObject UPDATENEWS::findNotificationContact(QString contacturl){
QSqlQuery query("SELECT id,url FROM contacts WHERE url='"+contacturl+"' AND username='"+ username+"'",m_db);
query.first();
QJsonObject contact{
{"id", query.value(0).toInt()},
{"url", query.value(1).toString()}
};
return contact;
}

QList <QJsonValue> UPDATENEWS::findNewContacts(QJsonDocument news){
QSqlQuery query("SELECT profile_image_url FROM contacts",m_db);
QList<QString> imageurls;
@@ -231,46 +405,46 @@ QList <QJsonValue> UPDATENEWS::findNewContacts(QJsonDocument news){
imageurls.append(query.value(0).toString());
}
QList<QJsonValue> newcontacts;
qDebug()<<"updatenews findcontacts count "<<news.array().count();
//qDebug()<<"updatenews findcontacts news count "<<news.array().count();

for (int i=0; i<news.array().count();i++){
//main contacts
if(imageurls.contains(news[i]["user"]["profile_image_url"].toString()) || newcontactimagelinks.contains(news[i]["user"]["profile_image_url"].toString())){
if(imageurls.contains(news[i]["user"]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["user"]["profile_image_url"].toString().section('?',0,0))){
}
else{
newcontacts.append(news[i]["user"]);
newcontactimagelinks.append(news[i]["user"]["profile_image_url"].toString());
newcontactimagelinks.append(news[i]["user"]["profile_image_url"].toString().section('?',0,0));
newcontactnames.append(news[i]["user"]["screen_name"].toString());
}
//like/dislike contacts
if (news[i].toObject().contains("friendica_activities") ){
for (int a=0; a < news[i]["friendica_activities"]["like"].toArray().count();a++){
if(imageurls.contains(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString()) || newcontactimagelinks.contains(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString())){
if(imageurls.contains(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0))){
}
else{
newcontacts.append(news[i]["friendica_activities"]["like"][a]);
newcontactimagelinks.append(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString());
newcontactimagelinks.append(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0));
newcontactnames.append(news[i]["friendica_activities"][a]["screen_name"].toString());
}
}
for (int b=0; b < news[i]["friendica_activities"]["dislike"].toArray().count();b++){
if(imageurls.contains(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString()) || newcontactimagelinks.contains(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString())){
if(imageurls.contains(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0))){
}
else{
newcontacts.append(news[i]["friendica_activities"]["dislike"][b]);
newcontactimagelinks.append(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString());
newcontactimagelinks.append(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0));
newcontactnames.append(news[i]["friendica_activities"][b]["screen_name"].toString());
}
}
}
//owner contacts
if (news[i].toObject().contains("friendica_owner") ){
if(imageurls.contains(news[i]["friendica_owner"]["profile_image_url"].toString()) || newcontactimagelinks.contains(news[i]["friendica_owner"]["profile_image_url"].toString())){
if (news[i].toObject().contains("friendica_author") ){
if(imageurls.contains(news[i]["friendica_author"]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_owner"]["profile_image_url"].toString().section('?',0,0))){
}
else{
newcontacts.append(news[i]["friendica_owner"]);
newcontactimagelinks.append(news[i]["friendica_owner"]["profile_image_url"].toString());
newcontactnames.append(news[i]["friendica_owner"]["screen_name"].toString());
newcontacts.append(news[i]["friendica_author"]);
newcontactimagelinks.append(news[i]["friendica_author"]["profile_image_url"].toString().section('?',0,0));
newcontactnames.append(news[i]["friendica_author"]["screen_name"].toString());
}
}
}
@@ -296,8 +470,8 @@ void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
query.bindValue(2, contact["screen_name"]);
query.bindValue(3, contact["location"]);
query.bindValue(4, currentTime);
query.bindValue(5, contact["profile_image_url"]);
if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());};
query.bindValue(5, contact["profile_image_url"].toString().section('?',0,0));
if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());}
query.bindValue(7,contact["protected"].toBool());
query.bindValue(8,contact["followers_count"].toInt());
query.bindValue(9,contact["friends_count"].toInt());
@@ -317,7 +491,7 @@ void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
query.bindValue(21,contact["network"]);
qint64 timestamp=0;
QString timestamphelper=contact["profile_image_url"].toString();
try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){};
try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}
query.bindValue(22,timestamp);
}

@@ -334,8 +508,8 @@ void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
query.bindValue(3, contact["screen_name"]);
query.bindValue(4, contact["location"]);
query.bindValue(5, currentTime);
query.bindValue(6, contact["profile_image_url"]);
if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());};
query.bindValue(6, contact["profile_image_url"].toString().section('?',0,0));
if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());}
query.bindValue(8,"none");
query.bindValue(9, contact["url"].toString());
query.bindValue(10,contact["protected"].toBool());
@@ -358,19 +532,12 @@ void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
query.bindValue(25, 0);
qint64 timestamp=0;
QString timestamphelper=contact["profile_image_url"].toString();
try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){};
try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}
query.bindValue(26,timestamp);

}
query.exec() ;
}
emit this->success(m_api);
if ((contacts.count()==0) && (m_updateInterval!=0)){
m_db.close();
m_db.removeDatabase(m_db.connectionName());
emit quitapp();
alarm.setAlarm(m_updateInterval);
};
}

QString UPDATENEWS::url() const
@@ -380,6 +547,7 @@ QString UPDATENEWS::url() const

void UPDATENEWS::startImagedownload()
{
//qDebug() << "start image download";
xhr.setDownloadtype("contactlist");
xhr.setFilelist(newcontactimagelinks);
xhr.setContactlist(newcontactnames);
@@ -389,11 +557,12 @@ void UPDATENEWS::startImagedownload()

void UPDATENEWS::showError(QString data, QString url,QString api, int code )
{
qDebug() << "showerror " << api << " data " << data;
emit this->error(api,data);
if(m_updateInterval!=0){
m_db.close();
m_db.removeDatabase(m_db.connectionName());
emit quitapp();
alarm.setAlarm(m_updateInterval);
};
if (api!=m_api || xhr.downloadtype()!=""){} else{
if(m_updateInterval!=0){
syncindex+=1;
startsync();
}
}
}

+ 9
- 1
source-android/common/updatenews.h View File

@@ -37,7 +37,7 @@
#include <QSqlDatabase>
#include "xhr.h"
#include "alarm.h"
#include "AndroidNative/systemdispatcher.h"
//#include "AndroidNative/systemdispatcher.h"

class UPDATENEWS : public QObject
{
@@ -64,6 +64,10 @@ public slots:
void setDatabase();
void login();
void timeline();
void replies();
void startsync();
void directmessages();
void notifications();
//void startservice(QString type,QVariantMap map);
void startImagedownload();
void updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index);
@@ -76,8 +80,12 @@ private:
QString m_imagedir;
QString m_login;
QString username;
int syncindex;
QSqlDatabase m_db;
QList<QString> synclist;
QList <QString> notifylist;
QList<QJsonValue> findNewContacts(QJsonDocument news);
QJsonObject findNotificationContact(QString imagelink);
int m_updateInterval;
//void timeline();
//void store(QByteArray serverreply,QString apiname);

+ 5
- 4
source-android/common/xhr.cpp View File

@@ -154,7 +154,7 @@ QString XHR::downloadtype() const
return m_downloadtype;
}

QString XHR::networktype() const
QString XHR::networktype()
{
return nc.bearerTypeFamily() + nc.bearerTypeName();
}
@@ -184,7 +184,6 @@ void XHR::download()
request.setRawHeader("Authorization", headerData.toLocal8Bit());
}
request.setUrl(requrl);
//qDebug() << requrl;
reply = manager.get(request);
reply->ignoreSslErrors();
connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead);
@@ -202,10 +201,11 @@ void XHR::get()
while(i.hasNext()) {
i.next();
query.addQueryItem(i.key(), i.value());
//qDebug()<<i.key() << " value "<< i.value();
}

QUrl requrl(m_url+m_api);
//qDebug() << requrl;
//qDebug() << "API "<< requrl<<m_api;
requrl.setQuery(query);
QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData;
@@ -229,7 +229,7 @@ void XHR::getlist()
else {
XHR::setUrl(m_filelist.at(dlindex));}
XHR::download();
} else {dlindex=0;}
} else {dlindex=0;m_downloadtype="";m_contactlist.clear();m_filelist.clear();}
}


@@ -297,6 +297,7 @@ void XHR::onReplySuccess()

void XHR::onRequestFinished()
{
qDebug()<<"download requestFinished ";
// Save the file here
if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,m_url,m_api,1);}
else if (m_downloadtype=="picturelist") {

+ 3
- 2
source-android/common/xhr.h View File

@@ -49,7 +49,7 @@ class XHR : public QObject
Q_PROPERTY(QList<QString> contactlist READ contactlist WRITE setContactlist NOTIFY contactlistChanged)
Q_PROPERTY(QList<QString> filelist READ filelist WRITE setFilelist NOTIFY filelistChanged)
Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged)
Q_PROPERTY(QString networktype READ networktype NOTIFY networktypeChanged)
Q_PROPERTY(QString networktype READ networktype() NOTIFY networktypeChanged)


public:
@@ -65,7 +65,7 @@ public:
QList<QString> filelist() const;
QString imagedir() const;
QString downloadtype() const;
QString networktype() const;
QString networktype();

signals:
void urlChanged();
@@ -98,6 +98,7 @@ public slots:
void get();
void getlist();
void download();

// void networktype();

private slots:

+ 5
- 4
source-android/js/helper.js View File

@@ -125,10 +125,11 @@ function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) {

function readData(database,table,username,callback,filter,filtervalue, sort) { // reads and applies data from DB
if (filter){
var where = " AND "+ filter +" = '" + filtervalue+"'";
if (username){var where = " AND "+ filter +" = '" + filtervalue+"'";} else{
var where = " WHERE "+ filter +" = '" + filtervalue+"'";}
} else { var where="";}
if (username){
var user = ' where username= "'+ username +'"';
var user = ' where username= "'+ username +'"';
} else { var user='';}

if (sort){
@@ -138,7 +139,7 @@ function readData(database,table,username,callback,filter,filtervalue, sort) { /
if(!db) { return; }
db.transaction( function(tx) {
//print('select * from '+table+user+where+sortparam);
var rsArray=[];
var rsArray=[];
var rs = tx.executeSql('select * from '+table+user+where+sortparam);
for(var i = 0; i < rs.rows.length; i++) {
rsArray.push(rs.rows.item(i))
@@ -165,7 +166,7 @@ var where = " AND "+ filter +" = '" + filtervalue+"'";
});
}

function showMessage(header,message,rootwindow){print(message);
function showMessage(header,message,rootwindow){//print(message);
var cleanmessage=message.replace(/"/g,"-");
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+'"}';

+ 1
- 1
source-android/js/layout.js View File

@@ -36,7 +36,7 @@ function showFriends(db) {
}
function displayFriends(obj){
for (var i=0; i<obj.length; i++){
print(obj[i]);
//print(obj[i]);
if (obj[i]) {friendsModel.append({"friendName": obj[i]});
};

+ 72
- 57
source-android/js/news.js View File

@@ -65,16 +65,21 @@ function requestGroups(login,database,rootwindow,callback){
});
})}

function listFriends(login,database,callback){
function listFriends(login,database,callback,filter){
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>0'); // check for friends
var contactlist=[];
for (var i=0;i<result.rows.length;i++){
contactlist.push(result.rows.item(i))
}
callback(contactlist)
});
var filtertext='';
try {filtertext=' AND screen_name like "' + filter+'%"'}catch(e){}
db.transaction( function(tx) {
//var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'+filtertext);
//print('SELECT * from contacts WHERE username="'+login.username+'"'+filtertext);
var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'+filtertext);
// check for friends
var contactlist=[];
for (var i=0;i<result.rows.length;i++){
contactlist.push(result.rows.item(i))
}
callback(contactlist)
});
}

function deleteGroup(login,database,rootwindow,group, callback){
@@ -88,14 +93,14 @@ function deleteGroup(login,database,rootwindow,group, callback){
});
}})}

function getLastNews(login,database){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
var lastnewsid=0;
db.transaction( function(tx) {
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1');
try{lastnewsid=result.rows.item(0).status_id;}catch(e){};
return lastnewsid
})
function getLastNews(login,database,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
var lastnewsid=0;
db.transaction( function(tx) {
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1');
try{lastnewsid=result.rows.item(0).status_id;}catch(e){print(e)};
callback(lastnewsid)
})
}


@@ -163,11 +168,11 @@ function findNewContacts(news,contacts){
}
}

if(news[i].hasOwnProperty('friendica_owner')){
var owner_url=news[i].friendica_owner.url;
if(news[i].hasOwnProperty('friendica_author')){
var owner_url=news[i].friendica_author.url;
if(contacts.indexOf(owner_url)==-1 && !(inArray(newContacts,"url",owner_url))){
news[i].friendica_owner.isFriend=0;
newContacts.push(news[i].friendica_owner);
news[i].friendica_author.isFriend=0;
newContacts.push(news[i].friendica_author);
}
}
}
@@ -178,7 +183,7 @@ function storeNews(login,database,news,rootwindow){
// save news after contacts download, call next function
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
for (var i=0;i<news.length;i++){
//print('store news data for ' + news[i].id+JSON.stringify(news[i].friendica_activities));
//print('store news data for ' + news[i].id+JSON.stringify(news[i].friendica_author));
//var ausdruck=news[i];
var likearray=[];var dislikearray=[];var attendyesarray=[];var attendnoarray=[];var attendmaybearray=[];
if(news[i].hasOwnProperty('friendica_activities')){
@@ -191,12 +196,12 @@ function storeNews(login,database,news,rootwindow){
var friendica_activities=[likearray,dislikearray,attendyesarray,attendnoarray,attendmaybearray]
var attachments="";if (news[i].attachments){attachments=Qt.btoa(JSON.stringify(news[i].attachments))}
db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from news where username="'+login.username+'" AND status_id = "'+news[i].id+'" AND messagetype=0'); // check for news id
var result = tx.executeSql('SELECT * from news where username="'+login.username+'" AND status_id = "'+news[i].id+'" AND messagetype='+news[i].messagetype); // check for news id
if(result.rows.length === 1) {// use update
//print(news[i].id +' news exists, update it'+'UPDATE news SET username="'+login.username+'", messagetype=0, text="'+Qt.btoa(news[i].text)+'", created_at="'+Date.parse(cleanDate(news[i].created_at))+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].status_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'",friendica_activities="'+Qt.btoa(JSON.stringify(friendica_activities))+'",attachments="'+attachments+'",friendica_owner="'+news[i].friendica_owner.url+'" where username="'+login.username+'" AND status_id="'+news[i].status_id+'" AND messagetype=0')
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=0, text="'+Qt.btoa(news[i].text)+'", created_at="'+news[i].created_at+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].status_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'",friendica_activities="'+Qt.btoa(JSON.stringify(friendica_activities))+'",attachments="'+attachments+'",friendica_owner="'+news[i].friendica_owner.url+'" where username="'+login.username+'" AND status_id="'+news[i].status_id+'" AND messagetype=0');
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype='+news[i].messagetype+', text="'+Qt.btoa(news[i].text)+'", created_at="'+news[i].created_at+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].status_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'",friendica_activities="'+Qt.btoa(JSON.stringify(friendica_activities))+'",attachments="'+attachments+'",friendica_owner="'+news[i].friendica_author.url+'" where username="'+login.username+'" AND status_id="'+news[i].status_id+'" AND messagetype=0');
} else {// use insert
result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,in_reply_to_status_id,source,status_id,in_reply_to_user_id,geo,favorited,uid,statusnet_html,statusnet_conversation_id,friendica_activities,friendica_activities_self,attachments,friendica_owner) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,0,Qt.btoa(news[i].text),news[i].created_at, news[i].in_reply_to_status_id, news[i].source, news[i].id,news[i].in_reply_to_user_id,news[i].geo,news[i].favorited, news[i].user.id,Qt.btoa(news[i].statusnet_html),news[i].statusnet_conversation_id, Qt.btoa(JSON.stringify(friendica_activities)),"[]",attachments,news[i].friendica_owner.url])}})
result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,in_reply_to_status_id,source,status_id,in_reply_to_user_id,geo,favorited,uid,statusnet_html,statusnet_conversation_id,friendica_activities,friendica_activities_self,attachments,friendica_owner) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,news[i].messagetype,Qt.btoa(news[i].text),news[i].created_at, news[i].in_reply_to_status_id, news[i].source, news[i].id,news[i].in_reply_to_user_id,news[i].geo,news[i].favorited, news[i].user.id,Qt.btoa(news[i].statusnet_html),news[i].statusnet_conversation_id, Qt.btoa(JSON.stringify(friendica_activities)),"[]",attachments,news[i].friendica_author.url])}})
}
// getDirectMessage(login,database,rootwindow,callback)
}
@@ -260,35 +265,41 @@ function getActivitiesUserData(allcontacts,userUrlArray){//print(JSON.stringify(
return helpArray
}

function newsfromdb(database,user,callback,contact,stop_time){
function newsfromdb(database,login,messagetype,callback,contact,stop_time){
// return news before stop_time (used by More button), in brackets of 20 entries, or by specified contact
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
if (!stop_time){var stop="";
try{var rs = tx.executeSql('select created_at from news WHERE username="'+user+'" 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+"' 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="'+user+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
var newsArray=[];
var allcontacts=getAllContacts(database,user);
for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i));
newsArray[i].statusnet_html=Qt.atob(newsArray[i].statusnet_html);
newsArray[i].text=Qt.atob(newsArray[i].text);
newsArray[i].id=newsArray[i].status_id;
newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts);
if (newsArray[i].attachments!==null){newsArray[i].attachments=JSON.parse(Qt.atob(newsArray[i].attachments))};
}
callback(newsArray)});
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1');
try{var lastid=result.rows.item(0).status_id;}catch(e){var lastid=0};

if (!stop_time){var stop="";
try{var rs = tx.executeSql('select created_at from news WHERE username="'+login.username+'" AND messagetype="'+messagetype+'" 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+"' 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="'+login.username+'" AND messagetype="'+messagetype+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
var newsArray=[];
var allcontacts=getAllContacts(database,login.username);

for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i));
newsArray[i].statusnet_html=Qt.atob(newsArray[i].statusnet_html);
newsArray[i].text=Qt.atob(newsArray[i].text);
newsArray[i].id=newsArray[i].status_id;
newsArray[i].friendica_author=newsArray[i].friendica_owner
newsArray[i]=fetchUsersForNews(database,login.username,newsArray[i],allcontacts);
if (newsArray[i].attachments!="" && newsArray[i].attachments!==null){newsArray[i].attachments=JSON.parse(Qt.atob(newsArray[i].attachments))};
}
callback(newsArray,lastid)});
}

function fetchUsersForNews(database,username,news,allcontacts){//print(JSON.stringify(news))

function fetchUsersForNews(database,username,news,allcontacts){//print("fetchusers "+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);
news.friendica_owner=objFromArray(allcontacts,"url",news.friendica_owner);
news.friendica_author=objFromArray(allcontacts,"url",news.friendica_author);
if (news.messagetype==0){
var friendicaArray=JSON.parse(Qt.atob(news.friendica_activities));
delete news.friendica_activities;
@@ -413,7 +424,7 @@ function conversationfromdb(database,user,conversationId,callback){
newsArray[i].text=Qt.atob(newsArray[i].text);
newsArray[i].id=newsArray[i].status_id;
newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts);
if (newsArray[i].attachments!==null){newsArray[i].attachments=JSON.parse(Qt.atob(newsArray[i].attachments))};
if (helpernews.attachments!="" && newsArray[i].attachments!==null){newsArray[i].attachments=JSON.parse(Qt.atob(newsArray[i].attachments))};
}
callback(newsArray)})
}
@@ -443,32 +454,36 @@ function requestFavorites(login,database,contacts,rootwindow,callback){
// callback(newsArray);
// }})}

function chatsfromdb(database,user,callback,stop_time){
function chatsfromdb(database,login,messagetype,callback,stop_time){

var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
if (!stop_time){var stop="";
try{var rs = tx.executeSql('select created_at from news WHERE username="'+username+'" ORDER BY created_at DESC LIMIT 1');
try{var rs = tx.executeSql('select created_at from news WHERE username="'+login.username+'" AND messagetype="'+messagetype+'" ORDER BY created_at DESC LIMIT 1');
stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
else{var stop="<"+stop_time}
var conversationsrs=tx.executeSql('select DISTINCT statusnet_conversation_id from news WHERE username="'+user+'" AND created_at'+stop+' ORDER BY created_at DESC LIMIT 20'); //+' ORDER BY created_at DESC LIMIT 20');
var conversationsrs=tx.executeSql('select DISTINCT statusnet_conversation_id from news WHERE username="'+login.username+'" AND created_at'+stop+' AND messagetype="'+messagetype+'" ORDER BY created_at DESC LIMIT 20'); //+' ORDER BY created_at DESC LIMIT 20');
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1');
try{var lastid=result.rows.item(0).status_id;}catch(e){var lastid=0};
var conversations=[];
for(var i = 0; i < conversationsrs.rows.length; i++) {
conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id);
}
var newsArray=[];
var allcontacts=getAllContacts(database,user);
var allcontacts=getAllContacts(database,login.username);

for(var j = 0; j< conversations.length; j++) {
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversations[j] +'" ORDER BY created_at ASC');
var newsrs=tx.executeSql('select * from news WHERE username="'+login.username+'" AND statusnet_conversation_id="'+conversations[j] +'" AND messagetype="'+messagetype+'" ORDER BY created_at ASC');
var helpernews=newsrs.rows.item(0);
helpernews.newscount=newsrs.rows.length;
helpernews=fetchUsersForNews(database,user,helpernews,allcontacts);
helpernews=fetchUsersForNews(database,login.username,helpernews,allcontacts);
helpernews.statusnet_html=Qt.atob(helpernews.statusnet_html);
helpernews.text=Qt.atob(helpernews.text);
helpernews.id=helpernews.status_id;
if (helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
if (helpernews.attachments!="" && helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
newsArray.push(helpernews);
}
callback(newsArray);
callback(newsArray,lastid);
})}


@@ -495,7 +510,7 @@ function allchatsfromdb(database,user,callback){
helpernews.statusnet_html=Qt.atob(helpernews.statusnet_html);
helpernews.text=Qt.atob(helpernews.text);
helpernews.id=helpernews.status_id;
if (helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
if (helpernews.attachments!="" && helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
newsArray.push(helpernews);
countArray.push(newsrs.rows.length)
}
@@ -520,7 +535,7 @@ function oldchatfromdb(database,user,conversationId,lastpost,allcontacts,callbac
helpernews.statusnet_html=Qt.atob(helpernews.statusnet_html);
helpernews.text=Qt.atob(helpernews.text);
helpernews.id=helpernews.status_id;
if (helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
if (helpernews.attachments!="" && helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
callback(helpernews,newscount);}
// var conversationobject={news:helpernews,newscount:newscount};
// return conversationobject;

+ 6
- 4
source-android/js/newsworker.js View File

@@ -53,9 +53,12 @@ else{
// newsitemobject.user.profile_image_url="";
// newsitemobject.user.name="";
// }
var forumname="";try{if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_owner')&&((newsitemobject.friendica_owner.url)!=(newsitemobject.user.url))){
//print(newsitemobject.friendica_owner+" Friendica Owner "+JSON.stringify(newsitemobject));
forumname=" via "+newsitemobject.friendica_owner.name
var forumname="";
try{if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_author')&&
((newsitemobject.friendica_author.url)!=(newsitemobject.user.url))&&((newsitemobject.friendica_author.url)!=null)){
print(" Friendica Author "+JSON.stringify(newsitemobject.friendica_author));
forumname=" via "+newsitemobject.user.name;
newsitemobject.user=newsitemobject.friendica_author;
}}catch(e){print("forum name "+e)}
var likeText="";var dislikeText="";var attendyesText="";var attendnoText="";var attendmaybeText=""; var self={};
try{if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_activities')){
@@ -166,7 +169,6 @@ else{
// }

newsitemobject.attachmentList=attachmentList;

var seconds=(msg.currentTime-newsitemobject.created_at)/1000;
var timestring="";
if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");}

+ 51
- 39
source-android/js/service.js View File

@@ -38,7 +38,7 @@

function initDatabase(database) { // initialize the database object
var db =Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
print('initDatabase()'+database[0]+database[1]+database[2]+database[3])
//print('initDatabase()'+database[0]+database[1]+database[2]+database[3])
db.transaction( function(tx) {
//var version=tx.executeSql('PRAGMA user_version');print(JSON.stringify(version.rows.item(0)))
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)');
@@ -194,13 +194,11 @@ function storeConfig(database,obj) { // stores config to DB
//print(JSON.stringify(obj));
var result = tx.executeSql('SELECT * from config WHERE username="'+obj.username+'"');
if(result.rows.length === 1) {// use update
var result2 = tx.executeSql('UPDATE config SET server="'+obj.server+'",password="'+obj.password+'", imagestore="'+obj.imagestore+'", maxnews='+obj.maxnews+', timerInterval='+obj.interval+', newsViewType="'+obj.newsViewType+'", isActive=0 WHERE username="'+obj.username +'"');
var result2 = tx.executeSql('UPDATE config SET server="'+obj.server+'",password="'+obj.password+'", imagestore="'+obj.imagestore+'", maxnews=0, timerInterval=0, newsViewType="'+obj.newsViewType+'", isActive=0 WHERE username="'+obj.username +'"');
var result3 = tx.executeSql('UPDATE config SET isActive=1 WHERE username !="'+obj.username +'"');
var result4 = tx.executeSql('UPDATE config SET maxnews='+obj.maxnews);
} else {// use insert print('... does not exists, create it')
var result2 = tx.executeSql('INSERT INTO config VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)', [obj.server, obj.username, obj.password, obj.imagestore, obj.maxnews, obj.interval,obj.newsViewType,0,"[[],[],[],[]]",0,"","",""]);
var result2 = tx.executeSql('INSERT INTO config VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)', [obj.server, obj.username, obj.password, obj.imagestore, 0, 0,obj.newsViewType,0,"[[],[],[],[]]",0,"","",""]);
var result3 = tx.executeSql('UPDATE config SET isActive=1 WHERE username !="'+obj.username +'"');
var result4 = tx.executeSql('UPDATE config SET maxnews='+obj.maxnews);
}
})}

@@ -283,7 +281,7 @@ function readConfig(database,callback,filter,filtervalue) { // reads config
for(var i = 0; i < rs.rows.length; i++) {
rsArray.push(rs.rows.item(i))
}
var rsObject={server:rsArray[0].server,username:rsArray[0].username, password:rsArray[0].password,imagestore:rsArray[0].imagestore,maxnews:rsArray[0].maxnews,isActive:rsArray[0].isActive,timerInterval:rsArray[0].timerInterval, newsViewType:rsArray[0].newsViewType,permissions:JSON.parse(rsArray[0].permissions),maxContactAge:rsArray[0].maxContactAge,APIVersion:rsArray[0].APIVersion,addons:rsArray[0].addons};
var rsObject={server:rsArray[0].server,username:rsArray[0].username, password:rsArray[0].password,imagestore:rsArray[0].imagestore,isActive:rsArray[0].isActive, newsViewType:rsArray[0].newsViewType,permissions:JSON.parse(rsArray[0].permissions),maxContactAge:rsArray[0].maxContactAge,APIVersion:rsArray[0].APIVersion,addons:rsArray[0].addons};
} else {var rsObject=""}
callback(rsObject)}}
)
@@ -318,6 +316,7 @@ function updateglobaloptions(database,key,value){
result = tx.executeSql('INSERT INTO globaloptions (k,v) VALUES (?,?)', [key,value])
}
})
root.globaloptions[key]=value;
}

function deleteConfig(database,userobj,callback) { // delete user data from DB
@@ -338,8 +337,9 @@ function deleteConfig(database,userobj,callback) { // delete user data from DB
function cleanNews(database,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
var maxnewsrs = tx.executeSql("SELECT DISTINCT maxnews FROM config");
var maxnews=maxnewsrs.rows.item(0).maxnews;
//var maxnewsrs = tx.executeSql("SELECT DISTINCT maxnews FROM config");
var maxnewsrs = tx.executeSql("SELECT v FROM globaloptions WHERE k='max_news'");
var maxnews=1000; if(maxnewsrs.rows.length>0){ maxnews=maxnewsrs.rows.item(0).v};
var newscountrs = tx.executeSql('SELECT COUNT(*) from news');
var newscount = newscountrs.rows.item(0)["COUNT(*)"];//print("newscount "+newscount)
if (newscount>maxnews){
@@ -384,6 +384,7 @@ function updateContactInDB(login,database,isFriend,contact){// for newstab and f
}

function processNews(api,data){
//print(api + data);
try{var newslist=JSON.parse(data)} catch(e){newsBusy.running=false;};
if (data==""){}
else if (typeof(newslist)=='undefined'){
@@ -393,6 +394,7 @@ function processNews(api,data){
Helperjs.showMessage(qsTr("JSON status Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root)
}
else if (!(Array.isArray(newslist))){
//print("processNews not array"+newslist+JSON.stringify(newslist));
replytimer.restart()
}
else {
@@ -407,6 +409,8 @@ function processNews(api,data){
newslist[n].uid=newslist[n].sender.id;
newslist[n].statusnet_conversation_id=newslist[n].friendica_parent_uri;
newslist[n].user=cleanUser(newslist[n].sender);
newslist[n].friendica_owner=newslist[n].user;
newslist[n].friendica_author=newslist[n].user;
newslist[n].statusnet_html=newslist[n].text;
}}
else if (api=="/api/friendica/notifications"){
@@ -418,6 +422,8 @@ function processNews(api,data){
newslist[n].user={"profile_image_url": newslist[n].photo,"name": newslist[n].name," url":newslist[n].url, "created_at":newslist[n].date};
newslist[n].user=cleanUser(newslist[n].user);
}
newslist[n].friendica_author=newslist[n].user;
newslist[n].friendica_owner=newslist[n].user;
newslist[n].statusnet_html=newslist[n].msg_html;
newslist[n].text=newslist[n].msg;
}
@@ -427,8 +433,9 @@ function processNews(api,data){
var commentCount=[];
for (var n in newslist){
newslist[n].created_at=Date.parse(Newsjs.cleanDate(newslist[n].created_at));
newslist[n].messagetype=0;
newslist[n].user=cleanUser(newslist[n].user)
if (api=="/api/statuses/replies"){newslist[n].messagetype=3}else{newslist[n].messagetype=0;}
newslist[n].friendica_author=cleanUser(newslist[n].friendica_author);
newslist[n].user=cleanUser(newslist[n].user);
if(newslist[n].in_reply_to_user_id){newslist[n].reply_user=Newsjs.objFromArray(allcontacts,"id",newslist[n].in_reply_to_user_id)}
//print (JSON.stringify(newslist[n].user))
if(newslist[n].hasOwnProperty('friendica_activities')){
@@ -448,8 +455,8 @@ function processNews(api,data){
newslist[n].friendica_activities.attendmaybe[r]=cleanUser(newslist[n].friendica_activities.attendmaybe[r]);
}
}
if(!(newslist[n].hasOwnProperty('friendica_owner'))){
newslist[n].friendica_owner=newslist[n].user
if(!(newslist[n].hasOwnProperty('friendica_author'))){
newslist[n].friendica_author=newslist[n].user
}
var conversationindex=conversationIds.indexOf(newslist[n].statusnet_conversation_id);

@@ -488,11 +495,13 @@ function processNews(api,data){
else if (api=="/api/statuses/user_timeline"){
newstab.contactposts=newslist
}
else if (newstab.newstabstatus==="Conversations"){
showNews(chatlist);root.news=newslist}
else {showNews(newslist);root.news=newslist};
else if ((api!="/api/direct_messages/all")&&(api!="/api/friendica/notifications")&&(newstab.newstabstatus==="Conversations")){
showNews(chatlist);root.news=newslist
}
else {
showNews(newslist);root.news=newslist};

var newstabarray=["Conversations","Favorites","Timeline","DirectMessage"];
var newstabarray=["Conversations","Favorites","Timeline","DirectMessage","Replies"];
if (newstabarray.indexOf(newstab.newstabstatus)>-1){contacttimer.start()}
}

@@ -509,26 +518,28 @@ function cleanUser(user){
}

function updateView(viewtype){
newsBusy.running=true;
//messageSend.state="";
//newsBusy.running=true;
//downloadNotice.text="xhr start "+Date.now()
switch(viewtype){
case "Conversations":
var lastnews=Newsjs.getLastNews(login,db);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/statuses/friends_timeline");
xhr.clearParams();
xhr.setParam("since_id",lastnews);
xhr.setParam("count",50)
Newsjs.getLastNews(login,db,function(lastnews){
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/statuses/friends_timeline");
xhr.clearParams();
xhr.setParam("since_id",lastnews);
xhr.setParam("count",50)});
break;
case "Timeline":
var lastnews=Newsjs.getLastNews(login,db);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/statuses/friends_timeline");
xhr.clearParams();
xhr.setParam("since_id",lastnews);
xhr.setParam("count",50)
var lastnews=Newsjs.getLastNews(login,db,function(lastnews){
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/statuses/friends_timeline");
xhr.clearParams();
xhr.setParam("since_id",lastnews);
xhr.setParam("count",50)
});
break;
case "Search":
xhr.setLogin(login.username+":"+Qt.atob(login.password));
@@ -566,14 +577,15 @@ function updateView(viewtype){
xhr.clearParams();
break;
default:
var lastnews=Newsjs.getLastNews(login,db);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/statuses/friends_timeline");
xhr.clearParams();
xhr.setParam("since_id",lastnews);
xhr.setParam("count",50)
newstab.newstabstatus="Conversations";
Newsjs.getLastNews(login,db,function(lastnews){
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/statuses/friends_timeline");
xhr.clearParams();
xhr.setParam("since_id",lastnews);
xhr.setParam("count",50)
newstab.newstabstatus="Conversations";
});
}

xhr.get();

+ 2
- 2
source-android/qml/calendarqml/CalendarDay.qml View File

@@ -29,8 +29,8 @@
// 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 2.11
//import QtQuick.Controls 2.4

Item {
id: calendarDay

+ 17
- 10
source-android/qml/calendarqml/CalendarTab.qml View File

@@ -30,10 +30,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import QtQuick 2.0
import QtQuick.Controls 2.3
import QtQuick.Controls 2.4
import QtQml 2.2
import Qt.labs.calendar 1.0
import QtQuick.Controls 1.2 as Oldcontrol
//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
@@ -42,9 +42,10 @@ import "qrc:/qml/genericqml"

Rectangle {
id:calendarrectangle
y:1
width:root.width-mm
height:root.height-5*mm
// y:1
// width:root.width-mm
// height:root.height-5*mm
anchors.fill: parent
color: '#fff'
property date currentTime: new Date()
property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000
@@ -83,30 +84,35 @@ Rectangle {
}


BlueButton{
MButton{
id: updateEvents
anchors.top: parent.top
anchors.topMargin: 0.5*mm
anchors.right:calendartabstatusButton.left
anchors.rightMargin:mm
height: 6*mm
width: 8*mm
text:"\uf021"
onClicked: {
Service.getEvents(db,login, calendartab,function(){
showEvents("")
})}}

BlueButton{
MButton{
id: calendartabstatusButton
anchors.top: parent.top
anchors.topMargin: 0.5*mm
anchors.right: parent.right
anchors.rightMargin:2*mm
height: 6*mm
width: Math.max(10*mm,implicitWidth)
text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus
Oldcontrol.Menu {
Menu {
id:calendartabmenu
Oldcontrol.MenuItem {
width: 40*mm
MenuItem {
text: qsTr("Own Calendar")
font.pixelSize: 3*mm
onTriggered: {
calendartab.calendartabstatus="Events";
// calendartabstatusButton.text=qsTr("own Calendar");
@@ -146,6 +152,7 @@ Rectangle {
DayOfWeekRow{
locale: monthgrid.locale
Layout.fillWidth: true
font.pixelSize: 3*mm
}

MonthGrid {

+ 4
- 2
source-android/qml/calendarqml/EventList.qml View File

@@ -30,7 +30,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import QtQuick 2.0
import QtQuick.Controls 1.2
import QtQuick.Controls 2.4
import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml"
@@ -45,12 +45,14 @@ Rectangle{
y:mm
property var daylist:[]

BlueButton{
MButton{
id:closeButton
anchors.top: parent.top
anchors.topMargin: 1*mm
anchors.right: parent.right
anchors.rightMargin: 1*mm