Browse Source

v.0.5

tags/v0.5
LubuWest 2 months ago
parent
commit
d48847d183
100 changed files with 5737 additions and 2132 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. 0
    0
      source-linux/qml/configqml/OSSettingsLinux.qml

+ 71
- 62
CHANGELOG.md View File

@@ -1,33 +1,68 @@
1
-## v0.1##
2 1
 
2
+## v0.5 ##
3
+*  Redesign due to QML Components 1 being deprecated in Qt 5.12: Slideview for News, left Drawer for Settings, message creation in listview header
4
+*  Android Notifications for News, DMs, Replies
5
+*  Global app config separated from account config
3 6
 
4
-# News #
5 7
 
6
-*  Native Android image selector for new message
7
-*  Click on contacts shows contact details on news page
8
-*  Fix problem with news list after deletion of item
8
+## v0.4 ##
9
+*  Background sync for friends timeline (interval on config page must be > 0) for Android > 5
10
+*  Replies timeline
11
+*  Bugfix: App asks for storage permission on first start
9 12
 
10
-# Contacts #
11
-*  Clean contacts with no news
12 13
 
13
-# Images #
14
-*  Upload pictures with description to album (permissions cannot be set due to API problems)
15
-*  Delete pictures or albums from client and server (long press on picture in overview)
16
-*  Fix problem when enlarging photo
14
+## v0.3.4 ##
15
+*  Direct message creation from profile page works again
16
+*  Profile image upload works again
17
+*  Viewing private album pictures of contacts works again
18
+*  On first start servername from https://dir.friendica.social/servers/surprise selected
19
+*  Register button opens webview of registration page on server
17 20
 
18
-# Translations #
19
-*  German, Spanish
20 21
 
22
+## v0.3.3 ##
23
+*  Update for OpenSSL and At
24
+*  Experimental support for Peertube (links are expanded to video widget)
25
+*  Some Unicode emojis
26
+*  Redesign of contact details (click on contact opens in new stack and shows last news)
21 27
 
22 28
 
23
-## v0.1.1##
24
-*  FIX: Spanish translation
25
-*  FIX: Empty Newsview after deletion of first newsitem
29
+## v0.3.2 ##
30
+*  For news containing url ending with mp3, mp4, avi, webm, ogg: media can be played in app
31
+*  Pictures can be renamed or moved to another album
32
+*  Bugfix: random crashes for conversations
33
+*  Bugfix: attach image to message works again
34
+*  Bugfix: check for nickname on Server has been removed due to API change
35
+
26 36
 
37
+## v0.3.1 ##
38
+*  By popular demand: Conversations open in a new stack, like in Twidere
39
+*  Conversations open after (long) press on news, like in Twidere
40
+*  Image attachments are shown below text and can be enlarged, like in Twidere (solves issue #8)
41
+*  New messages are html, line breaks work (solves issue #7)
27 42
 
28 43
 
29
-## v0.1.2#
30
-*  FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above
44
+## v0.3 ##
45
+*  Fix for [issue 6](https://github.com/LubuWest/Friendiqa/issues/6)
46
+*  Refactoring of news part
47
+*  Search button for news
48
+*  Click on hashtag in newsitem starts search for news with that word
49
+*  Public timeline
50
+*  Timeline for selected group
51
+*  Small redesign of SendMessage page
52
+
53
+
54
+## v0.2.2 ##
55
+*  Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5)
56
+*  Link to list of public server on Config Tab
57
+*  Small redesign of SendMessage page
58
+*  Intents for texts/urls (Send text or url from everywhere to create message) 
59
+
60
+
61
+## v0.2.1 ##
62
+*  Fix for [issue 4](https://github.com/LubuWest/Friendiqa/issues/4) 
63
+*  Fix for Friendica [issue 4689](https://github.com/friendica/friendica/issues/4689)
64
+*  Long posts are automatically truncated
65
+*  Intents for pictures (Send one image from gallery: attach to message, send multiple images: upload to album) 
31 66
 
32 67
 
33 68
 ## v0.2 ##
@@ -53,57 +88,31 @@
53 88
 # Translations #
54 89
 *  Italian thanks to Davide de Prisco
55 90
 
56
-## v0.2.1 ##
57
-*  Fix for [issue 4](https://github.com/LubuWest/Friendiqa/issues/4) 
58
-*  Fix for Friendica [issue 4689](https://github.com/friendica/friendica/issues/4689)
59
-*  Long posts are automatically truncated
60
-*  Intents for pictures (Send one image from gallery: attach to message, send multiple images: upload to album) 
61 91
 
62
-## v0.2.2 ##
63
-*  Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5)
64
-*  Link to list of public server on Config Tab
65
-*  Small redesign of SendMessage page
66
-*  Intents for texts/urls (Send text or url from everywhere to create message) 
92
+## v0.1.2##
93
+*  FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above
67 94
 
68 95
 
69
-## v0.3 ##
70
-*  Fix for [issue 6](https://github.com/LubuWest/Friendiqa/issues/6)
71
-*  Refactoring of news part
72
-*  Search button for news
73
-*  Click on hashtag in newsitem starts search for news with that word
74
-*  Public timeline
75
-*  Timeline for selected group
76
-*  Small redesign of SendMessage page
96
+## v0.1.1##
97
+*  FIX: Spanish translation
98
+*  FIX: Empty Newsview after deletion of first newsitem
77 99
 
78
-## v0.3.1 ##
79
-*  By popular demand: Conversations open in a new stack, like in Twidere
80
-*  Conversations open after (long) press on news, like in Twidere
81
-*  Image attachments are shown below text and can be enlarged, like in Twidere (solves issue #8)
82
-*  New messages are html, line breaks work (solves issue #7)
83 100
 
101
+## v0.1##
84 102
 
85
-## v0.3.2 ##
86
-*  For news containing url ending with mp3, mp4, avi, webm, ogg: media can be played in app
87
-*  Pictures can be renamed or moved to another album
88
-*  Bugfix: random crashes for conversations
89
-*  Bugfix: attach image to message works again
90
-*  Bugfix: check for nickname on Server has been removed due to API change
103
+# News #
91 104
 
105
+*  Native Android image selector for new message
106
+*  Click on contacts shows contact details on news page
107
+*  Fix problem with news list after deletion of item
92 108
 
93
-## v0.3.3 ##
94
-*  Update for OpenSSL and At
95
-*  Experimental support for Peertube (links are expanded to video widget)
96
-*  Some Unicode emojis
97
-*  Redesign of contact details (click on contact opens in new stack and shows last news)
109
+# Contacts #
110
+*  Clean contacts with no news
98 111
 
99
-## v0.3.4 ##
100
-*  Direct message creation from profile page works again
101
-*  Profile image upload works again
102
-*  Viewing private album pictures of contacts works again
103
-*  On first start servername from https://dir.friendica.social/servers/surprise selected
104
-*  Register button opens webview of registration page on server
112
+# Images #
113
+*  Upload pictures with description to album (permissions cannot be set due to API problems)
114
+*  Delete pictures or albums from client and server (long press on picture in overview)
115
+*  Fix problem when enlarging photo
105 116
 
106
-## v0.4 ##
107
-*  Background sync for friends timeline (interval on config page must be > 0) for Android > 5
108
-*  Replies timeline
109
-*  Bugfix: App asks for storage permission on first start
117
+# Translations #
118
+*  German, Spanish

+ 16
- 16
README.md View File

@@ -2,7 +2,7 @@
2 2
 
3 3
 QML based client for the Friendica Social Network.
4 4
  Tabs for news (incl. Direct Messages), friends, photos and events.
5
- OS: currently Linux and Android (4.3 Jelly Bean).
5
+ OS: currently Linux and Android (4.3 Jelly Bean, 5.1 for background sync).
6 6
  Source code is a QtCreator project.
7 7
 
8 8
 ## Screenshots ##
@@ -18,9 +18,10 @@ QML based client for the Friendica Social Network.
18 18
 
19 19
 # News #
20 20
 Currently supported:
21
-*  Shows Posts from friends, selected group, replies, favorited messages, public timeline, Direct Messages and notifications
22
-*  Background sync with configurable interval of 15 min to 2h for active contact for friends timeline (Android 5 required)
23
-*  Search button for news
21
+*  Shows Posts from friends, replies, Direct Messages and notifications (in swipe view), selected group, replies, favorited messages, public timeline
22
+*  Background sync with configurable interval of 15 min to 2h for active contact for friends timeline, replies and DMs (Android 5.1 required)
23
+*  Android notifications for new items in friends timeline, replies and DMs
24
+*  Search for news
24 25
 *  Click on hashtag in newsitem starts search for news with that word
25 26
 *  Click on image shows image fullscreen
26 27
 *  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:
39 40
 *  Native Android image dialog
40 41
 
41 42
 ToDo:
42
-
43
-*  Videos and other binary data as attachment (sending)
44
-*  More than one attachment (currently not supported in API)
43
+*  Videos and other binary data as attachment (sending, not supported in API)
44
+*  More than one attachment 
45 45
 *  Attachments for Direct messages (currently not supported in API)
46 46
 
47 47
     
48 48
 # Friends #
49 49
 Currently supported:
50
-
51 50
 *  Tabs for own profiles, friends, other contacts and groups
52 51
 *  Show profile(s) of user and change profile picture
53 52
 *  List of all known contacts with locally downloaded pictures
54 53
 *  Additional information, last messages and other functionality shown in news tab
55
-*  Send direct message, if contact is following
56
-*  Show public and private (Friendica 3.6 required) pictures of contact (screenscraping of contact's website, works only with certain theme)
57
-*  Show public and private (Friendica 3.6 required) events of contact
54
+*  Show public and private pictures of contact (screenscraping of contact's website, works only with certain theme)
55
+*  Show public and private events of contact
58 56
 *  Show members of groups
59 57
 *  Open website of contact or connect page (for other contacts)
60 58
 *  Clean other contacts with no news
61
-     
59
+
62 60
 ToDo:
63 61
 *  More information for contact from description page, possibly private information for friends
64 62
  (needs API change)
@@ -71,7 +69,7 @@ Currently supported:
71 69
 *  Download public and private own images to local directory
72 70
 *  Upload picture to album with descriptions(public), send from gallery
73 71
 *  Delete own pictures and albums on client and server
74
-*   Change name or album of existing picture
72
+*  Change name or album of existing picture
75 73
 *  Show albums in grid, show images in album in grid and fullscreen
76 74
 *  Show public and private (Friendica 3.6 server required) albums and images of contacts
77 75
 *  Pinch to zoom, swipe to scroll
@@ -81,8 +79,9 @@ ToDo:
81 79
 
82 80
 
83 81
 # Events #
82
+Currently supported:
84 83
 *  Download own public events
85
-*  Show public and private events of Friendica contacts (Friendica 3.6 server required)
84
+*  Show public and private events of Friendica contacts (Friendica >3.6 server required)
86 85
 *  List view of events of selected date
87 86
 *  Click on event to show details
88 87
 
@@ -91,11 +90,12 @@ ToDo
91 90
 *  Create events (needs API)
92 91
 
93 92
      
94
-# Config #
93
+# Config/Accounts #
95 94
 Currently supported:
96 95
 *  Multiple accounts
97
-*  Maximum news (deleted after use of Quit button)
98 96
 *  View mode for news (tree or timeline)
97
+*  Maximum news (deleted after use of Quit button)
98
+*  Sync home timeline, replies, DM, Notify yes/no
99 99
 
100 100
 ToDo
101 101
 *  OAuth?

+ 5
- 6
source-android/android/AndroidManifest.xml View File

@@ -1,5 +1,5 @@
1 1
 <?xml version="1.0"?>
2
-<manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.4" android:versionCode="12" android:installLocation="auto">
2
+<manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.5" android:versionCode="13" android:installLocation="auto">
3 3
     <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">
4 4
         <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="">
5 5
             <intent-filter>
@@ -78,13 +78,12 @@
78 78
             <!--  Messages maps -->
79 79
             <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splash"/>
80 80
         </service>
81
-        
82
-        <service android:process=":qt" android:name="androidnative.friendiqa.FriendiqaStopService" android:permission="android.permission.BIND_JOB_SERVICE"
83
-        android:exported="true">
81
+
82
+        <service android:process=":qt" android:name="androidnative.friendiqa.FriendiqaStopService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true">
84 83
             <meta-data android:name="android.app.background_running" android:value="true"/>
85 84
         </service>
86
-        
87
-        
85
+
86
+
88 87
     </application>
89 88
     <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="26"/>
90 89
     <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 {
26 26
     compile 'com.android.support:support-v4:25.3.1'
27 27
 }
28 28
 
29
+dependencies {
30
+    compile 'com.android.support:support-compat:25.3.1'
31
+}
29 32
 
30 33
 android {
31 34
     /*******************************************************

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

@@ -0,0 +1,4 @@
1
+androidBuildToolsVersion=25.0.3
2
+androidCompileSdkVersion=27
3
+buildDir=.build
4
+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 @@
1
+sdk.dir=/home/pankraz/android-sdk_alt

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


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


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


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


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


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


+ 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
38 38
         	// app-defined int constant. The callback method gets the
39 39
         	// result of the request.
40 40
 	} else {
41
-
41
+	
42 42
 	System.loadLibrary("friendiqa");
43 43
         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))) {
44 44
             SystemDispatcher.onActivityResume();

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

@@ -10,12 +10,18 @@ import android.content.Context;
10 10
 import android.content.ComponentName;
11 11
 import android.app.job.JobScheduler;
12 12
 import android.app.job.JobInfo;
13
+import android.app.PendingIntent;
14
+import android.support.v4.app.NotificationCompat; 
15
+import android.support.v4.app.NotificationManagerCompat; 
13 16
 import org.qtproject.qt5.android.QtNative;
14 17
 import androidnative.friendiqa.FriendiqaService;
15 18
 import androidnative.friendiqa.FriendiqaStopService;
19
+import androidnative.friendiqa.FriendiqaActivity;
20
+import androidnative.AndroidNativeActivity;
16 21
 import androidnative.AndroidNativeService;
17 22
 import android.content.Intent;
18 23
 import java.util.Map;
24
+import org.qtproject.friendiqa.R;
19 25
 
20 26
 public class Util {
21 27
 
@@ -24,6 +30,7 @@ public class Util {
24 30
     public static final String SET_TRANSLUCENT_STATUS_BAR = "androidnative.Util.setTranslucentStatusBar";
25 31
     public static final String SET_FULL_SCREEN = "androidnative.Util.setFullScreen";
26 32
     public static final String SET_SCHEDULE = "androidnative.Util.setSchedule";
33
+    public static final String SET_NOTIFICATION = "androidnative.Util.setNotification";
27 34
 
28 35
 
29 36
     static {
@@ -35,6 +42,8 @@ public class Util {
35 42
                     setFullScreen(message);
36 43
                 } else if (type.equals(SET_SCHEDULE)) {
37 44
                     setSchedule(message);
45
+                } else if (type.equals(SET_NOTIFICATION)) {
46
+                    setNotification(message);
38 47
                 }
39 48
             }
40 49
         });
@@ -98,11 +107,39 @@ public class Util {
98 107
 
99 108
     }
100 109
 
110
+    static void setNotification(Map message) {
111
+        //Log.d(TAG,"setNotification");
112
+        Context context;
113
+        //Context appcontext;
114
+        context = QtNative.service().getApplicationContext();
115
+        //appcontext = QtNative.activity().getApplicationContext();
116
+        Intent intent = new Intent(context,FriendiqaActivity.class);
117
+        //intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
118
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
119
+
120
+	final String textTitle = (String) message.get("title");
121
+	final String textContent = (String) message.get("message");
122
+	final int  notificationId = (int) message.get("id");
123
+	NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
124
+        .setSmallIcon(R.drawable.friendiqanotification)
125
+        .setContentIntent(pendingIntent)
126
+        .setContentTitle(textTitle)
127
+        .setContentText(textContent)
128
+        .setStyle(new NotificationCompat.BigTextStyle()
129
+                .bigText(textContent))
130
+        
131
+        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
132
+        .setAutoCancel(true);
133
+
134
+	NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
135
+	notificationManager.notify(notificationId, builder.build());
136
+    }
137
+
101 138
     static void setSchedule(Map message) {
102 139
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
103 140
             return;
104 141
         }
105
-        Log.d(TAG,"Friendiqa schedule Androidnative service");
142
+        //Log.d(TAG,"Friendiqa schedule Androidnative service");
106 143
         final Integer value = (Integer) message.get("value");
107 144
         //final Activity activity = QtNative.activity();
108 145
 	//final Service service = QtNative.service();
@@ -126,7 +163,7 @@ public class Util {
126 163
         jobScheduler.schedule(builder.build());
127 164
         
128 165
         if (QtNative.service() != null){
129
-                Log.d(TAG,"Schedule Stopping Friendiqa Androidnative service");
166
+                //Log.d(TAG,"Schedule Stopping Friendiqa Androidnative service");
130 167
         ComponentName componentStopper = new ComponentName(context, FriendiqaStopService.class);
131 168
         JobInfo.Builder stopbuilder = new JobInfo.Builder(1, componentStopper)
132 169
                  .setMinimumLatency(50)

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

@@ -1,5 +1,6 @@
1 1
 <RCC>
2 2
     <qresource prefix="/">
3
+        <file>qtquickcontrols2.conf</file>
3 4
         <file>qml/friendiqa.qml</file>
4 5
         <file>qml/newsqml/NewsTab.qml</file>
5 6
         <file>qml/newsqml/Newsitem.qml</file>
@@ -16,7 +17,7 @@
16 17
         <file>qml/photoqml/PhotogroupComponent.qml</file>
17 18
         <file>qml/photoqml/PhotoTab.qml</file>
18 19
         <file>qml/configqml/InfoBox.qml</file>
19
-        <file>qml/configqml/ConfigTab.qml</file>
20
+        <file>qml/configqml/ConfigPage.qml</file>
20 21
         <file>js/layout.js</file>
21 22
         <file>js/photoworker.js</file>
22 23
         <file>js/service.js</file>
@@ -27,6 +28,7 @@
27 28
         <file>images/fontawesome-webfont.ttf</file>
28 29
         <file>images/folder-blue.png</file>
29 30
         <file>qml/configqml/OSSettingsAndroid.qml</file>
31
+        <file>qml/genericqml/MButton.qml</file>
30 32
         <file>qml/configqml/OSSettingsLinux.qml</file>
31 33
         <file>qml/newsqml/SmileyDialog.qml</file>
32 34
         <file>js/smiley.js</file>
@@ -225,7 +227,9 @@
225 227
         <file>qml/newsqml/ContactPage.qml</file>
226 228
         <file>qml/newsqml/NewsLink.qml</file>
227 229
         <file>qml/configqml/RegisterPage.qml</file>
228
-        <file>qml/newsqml/NewsYplayer.qml</file>
229
-        <file>js/yplayer.html</file>
230
+        <file>qml/configqml/AccountPage.qml</file>
231
+        <file>qml/newsqml/NewsStack.qml</file>
232
+        <file>qml/configqml/SyncConfig.qml</file>
233
+        <file>qml/configqml/SyncComponent.qml</file>
230 234
     </qresource>
231 235
 </RCC>

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

@@ -51,6 +51,7 @@ signals:
51 51
 
52 52
 public slots:
53 53
     void setAlarm(int time);
54
+    void notify(QString title, QString text, int id);
54 55
 
55 56
 private:
56 57
     int m_time;

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

@@ -29,8 +29,6 @@
29 29
 //  You should have received a copy of the GNU General Public License
30 30
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31 31
 
32
-//#include <QtAndroidExtras/QAndroidJniObject>
33
-//#include <QtAndroidExtras/QAndroidJniEnvironment>
34 32
 #include "alarm.h"
35 33
 #include <QtCore/QDebug>
36 34
 #include "AndroidNative/systemdispatcher.h"
@@ -45,38 +43,20 @@ ALARM::ALARM(QObject *parent) : QObject(parent){}
45 43
 
46 44
 void ALARM::setAlarm(int interval)
47 45
 {
48
-    qDebug() << interval;
49 46
     QVariantMap message;
50 47
     message["value"] = interval;
51 48
     AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util");
52 49
     AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message);
53
-    //AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message);
54
-//    auto activity = QtAndroid::androidActivity();
55
-//    auto packageManager = activity.callObjectMethod("getPackageManager",
56
-//                                                    "()Landroid/content/pm/PackageManager;");
57
-
58
-//    auto activityIntent = packageManager.callObjectMethod("getLaunchIntentForPackage",
59
-//                                                          "(Ljava/lang/String;)Landroid/content/Intent;",
60
-//                                                          activity.callObjectMethod("getPackageName",
61
-//                                                          "()Ljava/lang/String;").object());
62
-
63
-//    auto pendingIntent = QAndroidJniObject::callStaticObjectMethod("android/app/PendingIntent", "getActivity",
64
-//                                                                   "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;",
65
-//                                                                   activity.object(), jint(0), activityIntent.object(),
66
-//                                                                   QAndroidJniObject::getStaticField<jint>("android/content/Intent",
67
-//                                                                                                           "FLAG_ACTIVITY_CLEAR_TOP"));
68
-
69
-//    auto alarmManager = activity.callObjectMethod("getSystemService",
70
-//                                                  "(Ljava/lang/String;)Ljava/lang/Object;",
71
-//                                                  QAndroidJniObject::getStaticObjectField("android/content/Context",
72
-//                                                                                          "ALARM_SERVICE",
73
-//                                                                                          "Ljava/lang/String;").object());
74
-
75
-//    alarmManager.callMethod<void>("set",
76
-//                                  "(IJLandroid/app/PendingIntent;)V",
77
-//                                  QAndroidJniObject::getStaticField<jint>("android/app/AlarmManager", "RTC"),
78
-//                                  jlong(QDateTime::currentMSecsSinceEpoch() + 100), pendingIntent.object());
79
-
80
-
50
+    AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message);
81 51
 }
82 52
 
53
+void ALARM::notify(QString title, QString text, int id)
54
+{
55
+    //qDebug() << "notify "<< title << text;
56
+    QVariantMap message;
57
+    message["title"] = title;
58
+    message["message"] =  text;
59
+    message["id"] =  id;
60
+    AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util");
61
+    AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setNotification", message);
62
+}

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

@@ -0,0 +1,73 @@
1
+//  This file is part of Friendiqa
2
+//  https://git.friendi.ca/lubuwest/Friendiqa
3
+//  Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
4
+//
5
+//  This program is free software: you can redistribute it and/or modify
6
+//  it under the terms of the GNU General Public License as published by
7
+//  the Free Software Foundation, either version 3 of the License, or
8
+//  (at your option) any later version.
9
+//
10
+//  In addition, as a special exception, the copyright holders give
11
+//  permission to link the code of portions of this program with the
12
+//  OpenSSL library under certain conditions as described in each
13
+//  individual source file, and distribute linked combinations including
14
+//  the two.
15
+//
16
+//  You must obey the GNU General Public License in all respects for all
17
+//  of the code used other than OpenSSL. If you modify file(s) with this
18
+//  exception, you may extend this exception to your version of the
19
+//  file(s), but you are not obligated to do so. If you do not wish to do
20
+//  so, delete this exception statement from your version. If you delete
21
+//  this exception statement from all source files in the program, then
22
+//  also delete it here.
23
+//
24
+//  This program is distributed in the hope that it will be useful,
25
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
+//  GNU General Public License for more details.
28
+//
29
+//  You should have received a copy of the GNU General Public License
30
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31
+
32
+//#include <QtAndroidExtras/QAndroidJniObject>
33
+//#include <QtAndroidExtras/QAndroidJniEnvironment>
34
+#include "alarm.h"
35
+#include <QtCore/QDebug>
36
+#include <QtDBus/QtDBus>
37
+//#include "AndroidNative/systemdispatcher.h"
38
+
39
+ALARM *ALARM::instance()
40
+{
41
+    static ALARM alarm;
42
+    return &alarm;
43
+}
44
+
45
+ALARM::ALARM(QObject *parent) : QObject(parent){}
46
+
47
+void ALARM::setAlarm(int interval)
48
+{
49
+    qDebug() << interval;
50
+    QVariantMap message;
51
+    message["value"] = interval;
52
+   // AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util");
53
+   // AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message);
54
+    //AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message);
55
+}
56
+
57
+void ALARM::notify(QString title, QString text, int id)
58
+{
59
+    qDebug() << title << text;
60
+    QVariantMap message;
61
+    message["title"] = title;
62
+    message["message"] =  text;
63
+    QDBusConnection bus = QDBusConnection::sessionBus();
64
+    QDBusInterface dbus_iface("org.freedesktop.Notifications", "/org/freedesktop/Notifications",
65
+                              "org.freedesktop.Notifications", bus);
66
+    QString appname="Friendiqa";
67
+    uint v=12321;
68
+    if (dbus_iface.isValid()){
69
+
70
+        dbus_iface.call("Notify",appname,v,"",title,text,"","",5000);
71
+    }
72
+   // AndroidNative::SystemDispatcher::instance()->dispatch("Notifier.notify", message);
73
+}

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

@@ -32,17 +32,15 @@
32 32
 #include <QApplication>
33 33
 #include <QtQml/QQmlEngine>
34 34
 #include <QAndroidService>
35
-#include <QtAndroid>
36 35
 #include <QtQuick>
37 36
 #include "xhr.h"
38 37
 #include "updatenews.h"
39 38
 #include "filesystem.h"
40 39
 #include "remoteauthasyncimageprovider.h"
41
-#include "alarm.h"
42 40
 #include "AndroidNative/systemdispatcher.h"
43
-#include "AndroidNative/environment.h"
41
+//#include "AndroidNative/environment.h"
44 42
 //#include "AndroidNative/debug.h"
45
-#include "AndroidNative/mediascannerconnection.h"
43
+//#include "AndroidNative/mediascannerconnection.h"
46 44
 
47 45
 
48 46
 #ifdef Q_OS_ANDROID
@@ -66,13 +64,11 @@ int main(int argc, char *argv[]) {
66 64
         UPDATENEWS* updatenews= UPDATENEWS::instance();
67 65
         updatenews->setDatabase();
68 66
         updatenews->login();
69
-        updatenews->timeline();
67
+        updatenews->startsync();
70 68
         app.connect (updatenews,SIGNAL(quitapp()),&app,SLOT(quit()));
71
-        //QtAndroid::androidService().callMethod<void>("stopSelf");
72 69
         return app.exec();
73 70
     }
74 71
     else{
75
-    
76 72
     QApplication app(argc, argv);
77 73
     QQuickView view;
78 74
     QTranslator qtTranslator;
@@ -87,8 +83,8 @@ int main(int argc, char *argv[]) {
87 83
     view.rootContext()->setContextProperty("filesystem", filesystem);
88 84
     ALARM* alarm = ALARM::instance();
89 85
     view.rootContext()->setContextProperty("alarm", alarm);
90
-//    UPDATENEWS* updatenews = UPDATENEWS::instance();
91
-//    view.rootContext()->setContextProperty("updatenews", updatenews);
86
+    UPDATENEWS* updatenews = UPDATENEWS::instance();
87
+    view.rootContext()->setContextProperty("updatenews", updatenews);
92 88
     view.setSource(QUrl("qrc:/qml/friendiqa.qml"));
93 89
     view.show();
94 90
     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()
100 100
        m_imagedir=query.value(3).toString();
101 101
        xhr.setImagedir(m_imagedir);
102 102
        QString isActive=query.value(7).toString();
103
-       m_updateInterval=query.value(5).toInt(); 
104
-       m_api="/api/statuses/friends_timeline";
105
-       xhr.setApi(m_api);
103
+    }
104
+       //m_updateInterval=query.value(5).toInt(); 
105
+
106
+
107
+    QSqlQuery syncquery("SELECT * FROM globaloptions",m_db);
108
+//    QSqlQuery delquery("DELETE FROM globaloptions WHERE k='sync_interval'",m_db);
109
+//    delquery.exec();
110
+    m_updateInterval=0;
111
+    syncindex=0;
112
+    synclist.clear();
113
+       //QSqlQuery syncquery("SELECT * FROM globaloptions WHERE k like 'sync_%' AND v=1",m_db);
114
+    while (syncquery.next()){
115
+        if (syncquery.value(0).toString()=="syncinterval"){
116
+            m_updateInterval=syncquery.value(1).toInt();
117
+        }
118
+        if (syncquery.value(0).toString().left(5)=="sync_" && syncquery.value(1).toInt()==1){
119
+            synclist.append(syncquery.value(0).toString());
120
+            //qDebug() << " sync " << syncquery.value(0).toString() << " " <<syncquery.value(1).toString();
121
+        }
122
+        if (syncquery.value(0).toString().left(7)=="notify_" && syncquery.value(1).toInt()==1){
123
+            notifylist.append(syncquery.value(0).toString());
124
+            //qDebug() << " notify " << syncquery.value(0).toString() << " " <<syncquery.value(1).toString();
125
+        }
126
+    }
127
+      // QSqlQuery notifyquery("SELECT * FROM globaloptions WHERE k like 'notify_%' AND v=1",m_db);
128
+       //qDebug() << "size " << notifyquery.size();
129
+      // while (notifyquery.next()){
130
+        //   notifylist.append(syncquery.value(0).toString());
131
+         //  qDebug() << " notify " << syncquery.value(0).toString();
132
+       //}
133
+}
134
+
135
+void UPDATENEWS::startsync()
136
+{        //qDebug()<<"Friendiqa start syncing " <<synclist.length()<<" index "<<syncindex;
137
+    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
138
+    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
139
+    if (syncindex<synclist.length()){
140
+        if (synclist[syncindex]=="sync_Timeline"){
141
+             timeline();
142
+        } else if (synclist[syncindex]=="sync_Replies") {
143
+            replies();
144
+        } else if (synclist[syncindex]=="sync_DirectMessages") {
145
+            directmessages();
146
+        } else if (synclist[syncindex]=="sync_Notifications") {
147
+            notifications();
148
+        }
149
+    } else if (syncindex==synclist.length()) {
150
+        m_api="";
151
+        if(m_updateInterval!=0){
152
+            syncindex=0;
153
+            synclist.clear();
154
+            m_db.close();
155
+            m_db.removeDatabase(m_db.connectionName());
156
+            emit quitapp();
157
+            alarm.setAlarm(m_updateInterval);
158
+            m_updateInterval=0;
159
+        }
106 160
     }
107 161
 }
108 162
 
109 163
 
110 164
 void UPDATENEWS::timeline()
111 165
 {
112
-    qDebug()<<"Friendiqa start timeline";
113
-    QSqlQuery query("SELECT status_id FROM news WHERE username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
114
-    if (query.isActive() && query.isSelect()){query.first();};
115
-    QString lastid=query.value(0).toString();
166
+    m_api="/api/statuses/friends_timeline";
116 167
     xhr.clearParams();
117
-    xhr.setParam("since_id",lastid);
168
+    xhr.setUrl(m_url);
169
+    xhr.setApi(m_api);
170
+    QSqlQuery query("SELECT status_id FROM news WHERE messagetype=0 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
171
+    if (query.isActive() && query.isSelect()){
172
+        if (query.first()){
173
+            QString lastid=query.value(0).toString();
174
+            xhr.setParam("since_id",lastid);
175
+        }
176
+    }
118 177
     xhr.setParam("count","50");
119 178
     xhr.get();
120 179
     QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
121 180
     QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
181
+    QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
122 182
 }
123 183
 
184
+void UPDATENEWS::replies()
185
+{
186
+    m_api="/api/statuses/replies";
187
+    xhr.clearParams();
188
+    xhr.setUrl(m_url);
189
+    xhr.setApi(m_api);
190
+    QSqlQuery query("SELECT status_id FROM news WHERE messagetype=3 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
191
+    if (query.isActive() && query.isSelect()){
192
+        if (query.first()){
193
+            QString lastid=query.value(0).toString();
194
+            xhr.setParam("since_id",lastid);
195
+        }
196
+    }
197
+    xhr.setParam("count","50");
198
+    xhr.get();
199
+    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
200
+    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
201
+    QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
202
+}
124 203
 
125
-//void UPDATENEWS::startservice(QString type,QVariantMap map)
126
-//{
127
-//    qDebug ()<<"Friediqa start service "<<type;
128
-//    if (type=="androidnativeServiceStarted"){
129
-//        setDatabase();
130
-//        login();
131
-//        timeline();
132
-//    }
133
-//}
204
+void UPDATENEWS::directmessages()
205
+{
206
+    m_api="/api/direct_messages/all";
207
+    xhr.clearParams();
208
+    xhr.setUrl(m_url);
209
+    xhr.setApi(m_api);
210
+    QSqlQuery query("SELECT status_id FROM news WHERE messagetype=1 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
211
+    if (query.isActive() && query.isSelect()){
212
+        if (query.first()){
213
+            QString lastid=query.value(0).toString();
214
+            xhr.setParam("since_id",lastid);
215
+        }
216
+    }
217
+    xhr.get();
218
+    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
219
+    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
220
+    QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
221
+}
134 222
 
135
-void UPDATENEWS::store(QByteArray serverreply,QString apiname)
223
+void UPDATENEWS::notifications()
136 224
 {
137
-    QJsonDocument news;
138
-    qDebug()<<apiname << news;
139
-    QJsonParseError jsonerror;
140
-    news=QJsonDocument::fromJson(serverreply,&jsonerror);
141
-    if (news.isArray()){
142
-        for (int i=0; i < news.array().count();i++){
143
-            QJsonValue newsitem=news[i];
144
-            QSqlQuery query(m_db);
145
-            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 (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
146
-            query.bindValue(0,username);
147
-            query.bindValue(1,"0");
148
-            query.bindValue(2, newsitem["text"].toString().toUtf8().toBase64());
149
-            QString sourcedate=newsitem["created_at"].toString();
150
-            QString formateddate=sourcedate.mid(0,3)+", "+sourcedate.mid(8,3)+sourcedate.mid(4,3)+sourcedate.mid(25,5)+sourcedate.mid(10,15);
151
-            query.bindValue(3,QDateTime::fromString(formateddate,Qt::RFC2822Date).toMSecsSinceEpoch() );
152
-            if(newsitem["in_reply_to_status_id"]!=QJsonValue::Null){query.bindValue(4, newsitem["in_reply_to_status_id"].toInt());};
153
-            query.bindValue(5,newsitem["source"]);
154
-            query.bindValue(6,newsitem["id"].toInt());
155
-            if(newsitem["in_reply_to_user_id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["in_reply_to_user_id"].toInt());};
156
-            query.bindValue(8,newsitem["geo"]);
157
-            query.bindValue( 9, newsitem["favorited"].toInt());
158
-            query.bindValue(10, newsitem["user"]["id"].toInt());
159
-            query.bindValue(11, newsitem["statusnet_html"].toString().toUtf8().toBase64());
160
-            query.bindValue(12, newsitem["statusnet_conversation_id"].toInt());
161
-            QJsonArray likeArray;QJsonArray dislikeArray;QJsonArray attendyesArray;QJsonArray attendnoArray;QJsonArray attendmaybeArray;
162
-            if (newsitem.toObject().contains("friendica_activities")){
163
-                for (int a=0; a < newsitem["friendica_activities"]["like"].toArray().count();a++){
164
-                    likeArray.append(newsitem["friendica_activities"]["like"][a]["url"].toString());
225
+    m_api="/api/friendica/notifications";
226
+    xhr.clearParams();
227
+    xhr.setUrl(m_url);
228
+    xhr.setApi(m_api);
229
+    xhr.get();
230
+    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
231
+    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
232
+    QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
233
+}
234
+
235
+
236
+void UPDATENEWS::store(QByteArray serverreply,QString apiname)
237
+{   if (apiname!=m_api || xhr.downloadtype()!=""){} else {
238
+        QJsonDocument news;
239
+        //qDebug()<<apiname << serverreply;
240
+        QJsonParseError jsonerror;
241
+        news=QJsonDocument::fromJson(serverreply,&jsonerror);
242
+        if (news.isArray()){
243
+            for (int i=0; i < news.array().count();i++){
244
+                QJsonValue newsitem=news[i];
245
+                if (apiname=="/api/friendica/notifications"){
246
+                    QSqlQuery testquery("SELECT status_id FROM news WHERE status_id=" + QString::number(newsitem["id"].toInt()) + " AND messagetype=2 AND username='"+ username +"'",m_db);
247
+                    if (testquery.first()) {continue;}
165 248
                 }
166
-                for (int b=0; b < newsitem["friendica_activities"]["dislike"].toArray().count();b++){
167
-                    dislikeArray.append(newsitem["friendica_activities"]["dislike"][b]["url"].toString());
249
+                QSqlQuery query(m_db);
250
+                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 (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
251
+                query.bindValue(0,username);
252
+                query.bindValue(1,"0");
253
+                query.bindValue(2, newsitem["text"].toString().toUtf8().toBase64());
254
+                QString sourcedate=newsitem["created_at"].toString();
255
+                QString formateddate=sourcedate.mid(0,3)+", "+sourcedate.mid(8,3)+sourcedate.mid(4,3)+sourcedate.mid(25,5)+sourcedate.mid(10,15);
256
+                query.bindValue(3,QDateTime::fromString(formateddate,Qt::RFC2822Date).toMSecsSinceEpoch() );
257
+                if(newsitem["in_reply_to_status_id"]!=QJsonValue::Null){query.bindValue(4, newsitem["in_reply_to_status_id"].toInt());}
258
+                query.bindValue(5,newsitem["source"]);
259
+                query.bindValue(6,newsitem["id"].toInt());
260
+                if(newsitem["in_reply_to_user_id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["in_reply_to_user_id"].toInt());}
261
+                query.bindValue(8,newsitem["geo"]);
262
+                query.bindValue( 9, newsitem["favorited"].toInt());
263
+                query.bindValue(10, newsitem["user"]["id"].toInt());
264
+                query.bindValue(11, newsitem["statusnet_html"].toString().toUtf8().toBase64());
265
+                query.bindValue(12, newsitem["statusnet_conversation_id"].toInt());
266
+                QJsonArray likeArray;QJsonArray dislikeArray;QJsonArray attendyesArray;QJsonArray attendnoArray;QJsonArray attendmaybeArray;
267
+                if (newsitem.toObject().contains("friendica_activities")){
268
+                    for (int a=0; a < newsitem["friendica_activities"]["like"].toArray().count();a++){
269
+                        likeArray.append(newsitem["friendica_activities"]["like"][a]["url"].toString());
270
+                    }
271
+                    for (int b=0; b < newsitem["friendica_activities"]["dislike"].toArray().count();b++){
272
+                        dislikeArray.append(newsitem["friendica_activities"]["dislike"][b]["url"].toString());
273
+                    }
274
+                    for (int c=0; c < newsitem["friendica_activities"]["attendyes"].toArray().count();c++){
275
+                        attendyesArray.append(newsitem["friendica_activities"]["attendyes"][c]["url"].toString());
276
+                    }
277
+                    for (int d=0; d < newsitem["friendica_activities"]["attendno"].toArray().count();d++){
278
+                        attendnoArray.append(newsitem["friendica_activities"]["attendno"][d]["url"].toString());
279
+                    }
280
+                    for (int e = 0; e < newsitem["friendica_activities"]["attendmaybe"].toArray().count();e++){
281
+                        attendmaybeArray.append(newsitem["friendica_activities"]["attendmaybe"][e]["url"].toString());
282
+                    }
283
+                 }
284
+                QJsonArray friendica_activities; friendica_activities={likeArray,dislikeArray,attendyesArray,attendnoArray,attendmaybeArray};
285
+                QJsonDocument activities; activities.setArray(friendica_activities);
286
+                query.bindValue(13,activities.toJson(QJsonDocument::Compact).toBase64());
287
+                query.bindValue(14,"[]");
288
+
289
+                if (newsitem["attachments"]!=QJsonValue::Undefined){
290
+                    query.bindValue(15, QJsonDocument(newsitem["attachments"].toArray()).toJson(QJsonDocument::Compact).toBase64());
291
+                }else {
292
+                    query.bindValue(15, "");
168 293
                 }
169
-                for (int c=0; c < newsitem["friendica_activities"]["attendyes"].toArray().count();c++){
170
-                    attendyesArray.append(newsitem["friendica_activities"]["attendyes"][c]["url"].toString());
294
+
295
+                if (newsitem["friendica_author"]!=QJsonValue::Undefined){
296
+                    query.bindValue(16, newsitem["friendica_author"]["url"]);
297
+                }else {
298
+                    query.bindValue(16, newsitem["user"]["url"]);
299
+                   }
300
+
301
+                if (apiname=="/api/statuses/replies"){
302
+                    query.bindValue(1,"3");
303
+                }
304
+                if (apiname == "/api/direct_messages/all"){
305
+                    query.bindValue(1,"1");
306
+                    query.bindValue(5,"Friendica");
307
+                    if(newsitem["recipient"]["id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["recipient"]["id"].toInt());}
308
+                    query.bindValue(10, newsitem["sender_id"].toInt());
309
+                    query.bindValue(11, newsitem["text"].toString().toUtf8().toBase64());
310
+                    if(newsitem["friendica_parent_uri"]!=QJsonValue::Null){ query.bindValue(12,newsitem["friendica_parent_uri"]);}
311
+                    query.bindValue(16, newsitem["sender"]["url"]);
312
+                }
313
+                if (apiname == "/api/friendica/notifications"){
314
+                    query.bindValue(1,"2");
315
+                    query.bindValue(3,QDateTime::fromString(newsitem["date"].toString(),"yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch());
316
+                    query.bindValue(5,"Friendica");
317
+                    QJsonObject cleancontact= findNotificationContact(newsitem["url"].toString());
318
+                    query.bindValue(10, cleancontact["id"].toInt());
319
+                    query.bindValue(11, newsitem["msg_html"].toString().toUtf8().toBase64());
320
+                    if(newsitem["parent"]!=QJsonValue::Null){ query.bindValue(12,newsitem["parent"]);}
321
+                    query.bindValue(16, newsitem["url"]);
322
+                }
323
+
324
+                if(!(query.exec())) {qDebug()<<query.lastError();}
325
+
326
+                // notifications
327
+                if (apiname=="/api/statuses/friends_timeline"){
328
+                    if(notifylist.contains("notify_Timeline")){
329
+                        alarm.notify("Home: "+ newsitem["user"]["name"].toString(),newsitem["text"].toString(),0);
330
+                    }
331
+                }
332
+                if (apiname=="/api/statuses/replies"){
333
+                    if(notifylist.contains("notify_Replies")){
334
+                        alarm.notify("Replies: "+newsitem["user"]["name"].toString(),newsitem["text"].toString(),1);
335
+                    }
336
+                }
337
+                if (apiname=="/api/direct_messages/all"){
338
+                    if(notifylist.contains("notify_DirectMessages")){
339
+                        alarm.notify("DirectMessage: "+newsitem["sender"]["name"].toString(),newsitem["text"].toString(),2);
340
+                    }
171 341
                 }
172
-                for (int d=0; d < newsitem["friendica_activities"]["attendno"].toArray().count();d++){
173
-                    attendnoArray.append(newsitem["friendica_activities"]["attendno"][d]["url"].toString());
342
+                if (apiname=="/api/friendica/notifications"){
343
+                    if(notifylist.contains("notify_Notifications")){
344
+                        alarm.notify("Notification: "+newsitem["name"].toString(),newsitem["text"].toString(),3);
345
+                    }
174 346
                 }
175
-                for (int e = 0; e < newsitem["friendica_activities"]["attendmaybe"].toArray().count();e++){
176
-                    attendmaybeArray.append(newsitem["friendica_activities"]["attendmaybe"][e]["url"].toString());
347
+            }
348
+            QList<QJsonValue> newcontacts=findNewContacts(news);
349
+            //qDebug()<< "new contacts count " << newcontacts.size();
350
+            if (newcontacts.size()>0){
351
+                updateContacts(newcontacts);
352
+                startImagedownload();
353
+
354
+            } else {
355
+                if(m_updateInterval!=0){
356
+                    syncindex+=1;
357
+                    startsync();
177 358
                 }
178
-             };
179
-            QJsonArray friendica_activities; friendica_activities={likeArray,dislikeArray,attendyesArray,attendnoArray,attendmaybeArray};
180
-            QJsonDocument activities; activities.setArray(friendica_activities);
181
-            query.bindValue(13,activities.toJson(QJsonDocument::Compact).toBase64());
182
-            query.bindValue(14,"[]");
183
-
184
-            if (newsitem["attachments"]!=QJsonValue::Undefined){
185
-                query.bindValue(15, QJsonDocument(newsitem["attachments"].toArray()).toJson(QJsonDocument::Compact).toBase64());
186
-            };
187
-
188
-            query.bindValue(16, newsitem["friendica_owner"]["url"]);
189
-            query.exec() ;
359
+            }
360
+        }
361
+        else {
362
+            qDebug()<< "Friendiqa updatenews error " << serverreply;
363
+            emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply));
364
+            syncindex+=1;
365
+            startsync();
190 366
         }
191 367
     }
192
-    else {
193
-        qDebug()<< "Friendiqa updatenews error";
194
-        emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply));
195
-        if(m_updateInterval!=0){
196
-            m_db.close();
197
-            m_db.removeDatabase(m_db.connectionName());
198
-            emit quitapp();
199
-            alarm.setAlarm(m_updateInterval);
200
-        };
201
-    }
202
-    QList<QJsonValue> newcontacts=findNewContacts(news);
203
-    updateContacts(newcontacts);
204
-    startImagedownload();
205
-    connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
206 368
 
207 369
 }
208 370
 
371
+
372
+
209 373
 void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index){
210 374
     if (downloadtype=="contactlist"){
211 375
         QSqlQuery testquery("SELECT profile_image FROM contacts WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db);
212
-        testquery.exec();
376
+        testquery.first();
213 377
         //qDebug()<< "update imageurl for " <<imageurl << " from " <<testquery.value(0).toString() <<" to "<< filename <<" index " << index << " newcontactnames.length " <<newcontactnames.length();
214 378
         QSqlQuery query("UPDATE contacts SET profile_image='"+ filename +"' WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db);
215 379
         query.exec();
216 380
         if (index==(newcontactnames.length()-1)){
381
+            newcontactnames.clear();
382
+            newcontactimagelinks.clear();
217 383
             if(m_updateInterval!=0){
218
-                m_db.close();
219
-                m_db.removeDatabase(m_db.connectionName());
220
-                emit quitapp();
221
-                alarm.setAlarm(m_updateInterval);
222
-            };
384
+                syncindex+=1;
385
+                startsync();
386
+            }
223 387
         }
224 388
     }
225 389
 }
226 390
 
391
+QJsonObject UPDATENEWS::findNotificationContact(QString contacturl){
392
+    QSqlQuery query("SELECT id,url FROM contacts WHERE url='"+contacturl+"' AND username='"+ username+"'",m_db);
393
+    query.first();
394
+    QJsonObject contact{
395
+        {"id", query.value(0).toInt()},
396
+        {"url", query.value(1).toString()}
397
+    };
398
+    return contact;
399
+}
400
+
227 401
 QList <QJsonValue> UPDATENEWS::findNewContacts(QJsonDocument news){
228 402
     QSqlQuery query("SELECT profile_image_url FROM contacts",m_db);
229 403
     QList<QString> imageurls;
@@ -231,46 +405,46 @@ QList <QJsonValue> UPDATENEWS::findNewContacts(QJsonDocument news){
231 405
         imageurls.append(query.value(0).toString());
232 406
     }
233 407
     QList<QJsonValue> newcontacts;
234
-    qDebug()<<"updatenews findcontacts count "<<news.array().count();
408
+    //qDebug()<<"updatenews findcontacts news count "<<news.array().count();
235 409
 
236 410
     for (int i=0; i<news.array().count();i++){
237 411
         //main contacts
238
-        if(imageurls.contains(news[i]["user"]["profile_image_url"].toString()) || newcontactimagelinks.contains(news[i]["user"]["profile_image_url"].toString())){
412
+        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))){
239 413
             }
240 414
         else{
241 415
             newcontacts.append(news[i]["user"]);
242
-            newcontactimagelinks.append(news[i]["user"]["profile_image_url"].toString());
416
+            newcontactimagelinks.append(news[i]["user"]["profile_image_url"].toString().section('?',0,0));
243 417
             newcontactnames.append(news[i]["user"]["screen_name"].toString());
244 418
         }
245 419
         //like/dislike contacts
246 420
         if (news[i].toObject().contains("friendica_activities") ){
247 421
             for (int a=0; a < news[i]["friendica_activities"]["like"].toArray().count();a++){
248
-                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())){
422
+                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))){
249 423
                     }
250 424
                 else{
251 425
                     newcontacts.append(news[i]["friendica_activities"]["like"][a]);
252
-                    newcontactimagelinks.append(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString());
426
+                    newcontactimagelinks.append(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0));
253 427
                     newcontactnames.append(news[i]["friendica_activities"][a]["screen_name"].toString());
254 428
                 }
255 429
             }
256 430
             for (int b=0; b < news[i]["friendica_activities"]["dislike"].toArray().count();b++){
257
-                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())){
431
+                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))){
258 432
                     }
259 433
                 else{
260 434
                     newcontacts.append(news[i]["friendica_activities"]["dislike"][b]);
261
-                    newcontactimagelinks.append(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString());
435
+                    newcontactimagelinks.append(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0));
262 436
                     newcontactnames.append(news[i]["friendica_activities"][b]["screen_name"].toString());
263 437
                 }
264 438
             }
265 439
         }
266 440
         //owner contacts
267
-        if (news[i].toObject().contains("friendica_owner") ){
268
-            if(imageurls.contains(news[i]["friendica_owner"]["profile_image_url"].toString()) || newcontactimagelinks.contains(news[i]["friendica_owner"]["profile_image_url"].toString())){
441
+        if (news[i].toObject().contains("friendica_author") ){
442
+            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))){
269 443
                 }
270 444
             else{
271
-                newcontacts.append(news[i]["friendica_owner"]);
272
-                newcontactimagelinks.append(news[i]["friendica_owner"]["profile_image_url"].toString());
273
-                newcontactnames.append(news[i]["friendica_owner"]["screen_name"].toString());
445
+                newcontacts.append(news[i]["friendica_author"]);
446
+                newcontactimagelinks.append(news[i]["friendica_author"]["profile_image_url"].toString().section('?',0,0));
447
+                newcontactnames.append(news[i]["friendica_author"]["screen_name"].toString());
274 448
             }
275 449
           }
276 450
     }
@@ -296,8 +470,8 @@ void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
296 470
             query.bindValue(2, contact["screen_name"]);
297 471
             query.bindValue(3, contact["location"]);
298 472
             query.bindValue(4, currentTime);
299
-            query.bindValue(5, contact["profile_image_url"]);
300
-            if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());};
473
+            query.bindValue(5, contact["profile_image_url"].toString().section('?',0,0));
474
+            if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());}
301 475
             query.bindValue(7,contact["protected"].toBool());
302 476
             query.bindValue(8,contact["followers_count"].toInt());
303 477
             query.bindValue(9,contact["friends_count"].toInt());
@@ -317,7 +491,7 @@ void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
317 491
             query.bindValue(21,contact["network"]);
318 492
             qint64 timestamp=0;
319 493
             QString timestamphelper=contact["profile_image_url"].toString();
320
-            try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){};
494
+            try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}
321 495
             query.bindValue(22,timestamp);
322 496
         }
323 497
 
@@ -334,8 +508,8 @@ void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
334 508
             query.bindValue(3, contact["screen_name"]);
335 509
             query.bindValue(4, contact["location"]);
336 510
             query.bindValue(5, currentTime);
337
-            query.bindValue(6, contact["profile_image_url"]);
338
-            if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());};
511
+            query.bindValue(6, contact["profile_image_url"].toString().section('?',0,0));
512
+            if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());}
339 513
             query.bindValue(8,"none");
340 514
             query.bindValue(9, contact["url"].toString());
341 515
             query.bindValue(10,contact["protected"].toBool());
@@ -358,19 +532,12 @@ void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
358 532
             query.bindValue(25, 0);
359 533
             qint64 timestamp=0;
360 534
             QString timestamphelper=contact["profile_image_url"].toString();
361
-            try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){};
535
+            try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}
362 536
             query.bindValue(26,timestamp);
363 537
 
364 538
         }
365 539
         query.exec() ;
366 540
     }
367
-        emit this->success(m_api);
368
-    if ((contacts.count()==0) && (m_updateInterval!=0)){
369
-        m_db.close();
370
-        m_db.removeDatabase(m_db.connectionName());
371
-        emit quitapp();
372
-        alarm.setAlarm(m_updateInterval);
373
-    };
374 541
 }
375 542
 
376 543
 QString UPDATENEWS::url() const
@@ -380,6 +547,7 @@ QString UPDATENEWS::url() const
380 547
 
381 548
 void UPDATENEWS::startImagedownload()
382 549
 {
550
+    //qDebug() << "start image download";
383 551
     xhr.setDownloadtype("contactlist");
384 552
     xhr.setFilelist(newcontactimagelinks);
385 553
     xhr.setContactlist(newcontactnames);
@@ -389,11 +557,12 @@ void UPDATENEWS::startImagedownload()
389 557
 
390 558
 void UPDATENEWS::showError(QString data, QString url,QString api, int code )
391 559
 {
560
+    qDebug() << "showerror " << api << " data " << data;
392 561
     emit this->error(api,data);
393
-    if(m_updateInterval!=0){
394
-        m_db.close();
395
-        m_db.removeDatabase(m_db.connectionName());
396
-        emit quitapp();
397
-        alarm.setAlarm(m_updateInterval);
398
-    };
562
+    if (api!=m_api || xhr.downloadtype()!=""){} else{
563
+        if(m_updateInterval!=0){
564
+            syncindex+=1;
565
+            startsync();
566
+        }
567
+    }
399 568
 }

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

@@ -37,7 +37,7 @@
37 37
 #include <QSqlDatabase>
38 38
 #include "xhr.h"
39 39
 #include "alarm.h"
40
-#include "AndroidNative/systemdispatcher.h"
40
+//#include "AndroidNative/systemdispatcher.h"
41 41
 
42 42
 class UPDATENEWS : public QObject
43 43
 {
@@ -64,6 +64,10 @@ public slots:
64 64
     void setDatabase();
65 65
     void login();
66 66
     void timeline();
67
+    void replies();
68
+    void startsync();
69
+    void directmessages();
70
+    void notifications();
67 71
     //void startservice(QString type,QVariantMap map);
68 72
     void startImagedownload();
69 73
     void updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index);
@@ -76,8 +80,12 @@ private:
76 80
     QString m_imagedir;
77 81
     QString m_login;
78 82
     QString username;
83
+    int syncindex;
79 84
     QSqlDatabase m_db;
85
+    QList<QString> synclist;
86
+    QList <QString> notifylist;
80 87
     QList<QJsonValue> findNewContacts(QJsonDocument news);
88
+    QJsonObject findNotificationContact(QString imagelink);
81 89
     int m_updateInterval;
82 90
     //void timeline();
83 91
     //void store(QByteArray serverreply,QString apiname);

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

@@ -154,7 +154,7 @@ QString XHR::downloadtype() const
154 154
     return m_downloadtype;
155 155
 }
156 156
 
157
-QString XHR::networktype() const
157
+QString XHR::networktype()
158 158
 {
159 159
     return nc.bearerTypeFamily() + nc.bearerTypeName();
160 160
 }
@@ -184,7 +184,6 @@ void XHR::download()
184 184
         request.setRawHeader("Authorization", headerData.toLocal8Bit());
185 185
     }
186 186
     request.setUrl(requrl);
187
-    //qDebug() << requrl;
188 187
     reply = manager.get(request);
189 188
     reply->ignoreSslErrors();
190 189
     connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead);
@@ -202,10 +201,11 @@ void XHR::get()
202 201
     while(i.hasNext()) {
203 202
         i.next();
204 203
         query.addQueryItem(i.key(), i.value());
204
+        //qDebug()<<i.key() << " value "<< i.value();
205 205
     }
206 206
 
207 207
     QUrl requrl(m_url+m_api);
208
-    //qDebug() << requrl;
208
+    //qDebug() << "API "<< requrl<<m_api;
209 209
     requrl.setQuery(query);
210 210
     QByteArray loginData = m_login.toLocal8Bit().toBase64();
211 211
     QString headerData = "Basic " + loginData;
@@ -229,7 +229,7 @@ void XHR::getlist()
229 229
         else {
230 230
             XHR::setUrl(m_filelist.at(dlindex));}
231 231
         XHR::download();
232
-    } else {dlindex=0;}
232
+    } else {dlindex=0;m_downloadtype="";m_contactlist.clear();m_filelist.clear();}
233 233
 }
234 234
 
235 235
 
@@ -297,6 +297,7 @@ void XHR::onReplySuccess()
297 297
 
298 298
 void XHR::onRequestFinished()
299 299
 {
300
+    qDebug()<<"download requestFinished ";
300 301
     // Save the file here
301 302
     if (buffer.isNull()){qDebug() << "File empty"<<m_url; buffer.clear(); emit this->error(m_downloadtype,m_url,m_api,1);}
302 303
     else if (m_downloadtype=="picturelist") {

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

@@ -49,7 +49,7 @@ class XHR : public QObject
49 49
     Q_PROPERTY(QList<QString> contactlist READ contactlist WRITE setContactlist NOTIFY contactlistChanged)
50 50
     Q_PROPERTY(QList<QString> filelist READ filelist WRITE setFilelist NOTIFY filelistChanged)
51 51
     Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged)
52
-    Q_PROPERTY(QString networktype READ networktype NOTIFY networktypeChanged)
52
+    Q_PROPERTY(QString networktype READ networktype() NOTIFY networktypeChanged)
53 53
 
54 54
 
55 55
 public:
@@ -65,7 +65,7 @@ public:
65 65
     QList<QString> filelist() const;
66 66
     QString imagedir() const;
67 67
     QString downloadtype() const;
68
-    QString networktype() const;
68
+    QString networktype();
69 69
 
70 70
 signals:
71 71
     void urlChanged();
@@ -98,6 +98,7 @@ public slots:
98 98
     void get();
99 99
     void getlist();
100 100
     void download();
101
+
101 102
 //    void networktype();
102 103
 
103 104
 private slots:

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

@@ -125,10 +125,11 @@ function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) {
125 125
 
126 126
 function readData(database,table,username,callback,filter,filtervalue, sort) { // reads and applies data from DB
127 127
  if (filter){
128
- var where = " AND "+ filter +" = '" + filtervalue+"'";
128
+    if (username){var where = " AND "+ filter +" = '" + filtervalue+"'";} else{
129
+     var where = " WHERE "+ filter +" = '" + filtervalue+"'";}
129 130
  } else { var where="";}
130 131
  if (username){
131
- var user = ' where username= "'+ username +'"';
132
+    var user = ' where username= "'+ username +'"';
132 133
  } else { var user='';}
133 134
 
134 135
  if (sort){
@@ -138,7 +139,7 @@ function readData(database,table,username,callback,filter,filtervalue, sort) { /
138 139
  if(!db) { return; }
139 140
  db.transaction( function(tx) {
140 141
      //print('select * from '+table+user+where+sortparam);
141
-        var rsArray=[];
142
+     var rsArray=[];
142 143
      var rs = tx.executeSql('select * from '+table+user+where+sortparam);
143 144
      for(var i = 0; i < rs.rows.length; i++) {
144 145
          rsArray.push(rs.rows.item(i))
@@ -165,7 +166,7 @@ var where = " AND "+ filter +" = '" + filtervalue+"'";
165 166
  });
166 167
 }
167 168
 
168
-function showMessage(header,message,rootwindow){print(message);
169
+function showMessage(header,message,rootwindow){//print(message);
169 170
     var cleanmessage=message.replace(/"/g,"-");
170 171
     if(cleanmessage.length>200){cleanmessage=cleanmessage.slice(0,200)+'...'}
171 172
     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) {
36 36
 }
37 37
 function displayFriends(obj){
38 38
      for (var i=0; i<obj.length; i++){
39
-                print(obj[i]);
39
+                //print(obj[i]);
40 40
                 if (obj[i]) {friendsModel.append({"friendName": obj[i]});
41 41
                 };
42 42
          

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

@@ -65,16 +65,21 @@ function requestGroups(login,database,rootwindow,callback){
65 65
         });
66 66
 })}
67 67
 
68
-function listFriends(login,database,callback){
68
+function listFriends(login,database,callback,filter){
69 69
     var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
70
-        db.transaction( function(tx) {
71
-             var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'); // check for friends
72
-             var contactlist=[];
73
-             for (var i=0;i<result.rows.length;i++){
74
-                 contactlist.push(result.rows.item(i))
75
-             }
76
-             callback(contactlist)
77
-        });
70
+    var filtertext='';
71
+    try {filtertext=' AND screen_name like "' + filter+'%"'}catch(e){}
72
+    db.transaction( function(tx) {
73
+        //var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'+filtertext);
74
+        //print('SELECT * from contacts WHERE username="'+login.username+'"'+filtertext);
75
+        var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'+filtertext);
76
+        // check for friends
77
+        var contactlist=[];
78
+        for (var i=0;i<result.rows.length;i++){
79
+            contactlist.push(result.rows.item(i))
80
+        }
81
+        callback(contactlist)
82
+    });
78 83
 }
79 84
 
80 85
 function deleteGroup(login,database,rootwindow,group, callback){
@@ -88,14 +93,14 @@ function deleteGroup(login,database,rootwindow,group, callback){
88 93
         });
89 94
 }})}
90 95
 
91
-function getLastNews(login,database){
92
-var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
93
-var lastnewsid=0;
94
-db.transaction( function(tx) {
95
-        var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id  DESC LIMIT 1');
96
-        try{lastnewsid=result.rows.item(0).status_id;}catch(e){};
97
-        return lastnewsid
98
-    })
96
+function getLastNews(login,database,callback){
97
+    var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
98
+    var lastnewsid=0;
99
+    db.transaction( function(tx) {
100
+            var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id  DESC LIMIT 1');
101
+            try{lastnewsid=result.rows.item(0).status_id;}catch(e){print(e)};
102
+            callback(lastnewsid)
103
+        })
99 104
 }
100 105
 
101 106
 
@@ -163,11 +168,11 @@ function findNewContacts(news,contacts){
163 168
             }
164 169
          }
165 170
 
166
-         if(news[i].hasOwnProperty('friendica_owner')){
167
-             var owner_url=news[i].friendica_owner.url;
171
+         if(news[i].hasOwnProperty('friendica_author')){
172
+             var owner_url=news[i].friendica_author.url;
168 173
              if(contacts.indexOf(owner_url)==-1 &&  !(inArray(newContacts,"url",owner_url))){
169
-                 news[i].friendica_owner.isFriend=0;
170
-                 newContacts.push(news[i].friendica_owner);
174
+                 news[i].friendica_author.isFriend=0;
175
+                 newContacts.push(news[i].friendica_author);
171 176
                  }
172 177
          }
173 178
     }
@@ -178,7 +183,7 @@ function storeNews(login,database,news,rootwindow){
178 183
 // save news after contacts download, call next function
179 184
     var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
180 185
     for (var i=0;i<news.length;i++){
181
-        //print('store news data for ' + news[i].id+JSON.stringify(news[i].friendica_activities));
186
+        //print('store news data for ' + news[i].id+JSON.stringify(news[i].friendica_author));
182 187
         //var ausdruck=news[i];
183 188
         var likearray=[];var dislikearray=[];var attendyesarray=[];var attendnoarray=[];var attendmaybearray=[];
184 189
         if(news[i].hasOwnProperty('friendica_activities')){
@@ -191,12 +196,12 @@ function storeNews(login,database,news,rootwindow){
191 196
         var friendica_activities=[likearray,dislikearray,attendyesarray,attendnoarray,attendmaybearray]
192 197
         var attachments="";if (news[i].attachments){attachments=Qt.btoa(JSON.stringify(news[i].attachments))}
193 198
         db.transaction( function(tx) {
194
-            var result = tx.executeSql('SELECT * from news where username="'+login.username+'" AND status_id = "'+news[i].id+'" AND messagetype=0'); // check for news id
199
+            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
195 200
             if(result.rows.length === 1) {// use update
196 201
                 //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')
197
-                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');
202
+                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');
198 203
             } else {// use insert
199
-                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])}})
204
+                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])}})
200 205
             }
201 206
    // getDirectMessage(login,database,rootwindow,callback)
202 207
 }
@@ -260,35 +265,41 @@ function getActivitiesUserData(allcontacts,userUrlArray){//print(JSON.stringify(
260 265
     return helpArray
261 266
 }
262 267
 
263
-function newsfromdb(database,user,callback,contact,stop_time){
268
+function newsfromdb(database,login,messagetype,callback,contact,stop_time){
264 269
 // return news before stop_time (used by More button), in brackets of 20 entries, or by specified contact
265 270
     var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
266 271
     db.transaction( function(tx) {
267
-    if (!stop_time){var stop="";
268
-        try{var rs = tx.executeSql('select created_at from news WHERE username="'+user+'" ORDER BY created_at DESC LIMIT 1');
269
-        stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
270
-    else{var stop="<"+stop_time}
271
-    var contactfilter="";if(contact){contactfilter=" AND (uid='"+contact+"' OR friendica_owner='"+contact+"')"}
272
-    //print('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
273
-    var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
274
-    var newsArray=[];
275
-    var allcontacts=getAllContacts(database,user);
276
-    for(var i = 0; i < newsrs.rows.length; i++) {
277
-        newsArray.push(newsrs.rows.item(i));
278
-        newsArray[i].statusnet_html=Qt.atob(newsArray[i].statusnet_html);
279
-        newsArray[i].text=Qt.atob(newsArray[i].text);
280
-        newsArray[i].id=newsArray[i].status_id;
281
-        newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts);
282
-        if (newsArray[i].attachments!==null){newsArray[i].attachments=JSON.parse(Qt.atob(newsArray[i].attachments))};
283
-    }
284
-  callback(newsArray)});
272
+        var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id  DESC LIMIT 1');
273
+        try{var lastid=result.rows.item(0).status_id;}catch(e){var lastid=0};
274
+
275
+        if (!stop_time){var stop="";
276
+            try{var rs = tx.executeSql('select created_at from news WHERE username="'+login.username+'" AND messagetype="'+messagetype+'" ORDER BY created_at DESC LIMIT 1');
277
+            stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
278
+        else{var stop="<"+stop_time}
279
+        var contactfilter="";if(contact){contactfilter=" AND (uid='"+contact+"' OR friendica_owner='"+contact+"')"}
280
+        //print('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
281
+        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');
282
+        var newsArray=[];
283
+        var allcontacts=getAllContacts(database,login.username);
284
+
285
+        for(var i = 0; i < newsrs.rows.length; i++) {
286
+            newsArray.push(newsrs.rows.item(i));
287
+            newsArray[i].statusnet_html=Qt.atob(newsArray[i].statusnet_html);
288
+            newsArray[i].text=Qt.atob(newsArray[i].text);
289
+            newsArray[i].id=newsArray[i].status_id;
290
+            newsArray[i].friendica_author=newsArray[i].friendica_owner
291
+            newsArray[i]=fetchUsersForNews(database,login.username,newsArray[i],allcontacts);
292
+            if (newsArray[i].attachments!="" && newsArray[i].attachments!==null){newsArray[i].attachments=JSON.parse(Qt.atob(newsArray[i].attachments))};
293
+        }
294
+    callback(newsArray,lastid)});
285 295
 }
286 296
 
287
-function fetchUsersForNews(database,username,news,allcontacts){//print(JSON.stringify(news))
297
+
298
+function fetchUsersForNews(database,username,news,allcontacts){//print("fetchusers "+JSON.stringify(news))
288 299
     news.user=objFromArray(allcontacts,"id",news.uid);
289 300
     if(news.in_reply_to_user_id){news.reply_user=objFromArray(allcontacts,"id",news.in_reply_to_user_id)}
290 301
     //news.friendica_owner_object=objFromArray(allcontacts,"url",news.friendica_owner);
291
-    news.friendica_owner=objFromArray(allcontacts,"url",news.friendica_owner);
302
+    news.friendica_author=objFromArray(allcontacts,"url",news.friendica_author);
292 303
     if (news.messagetype==0){
293 304
        var friendicaArray=JSON.parse(Qt.atob(news.friendica_activities));
294 305
         delete news.friendica_activities;
@@ -413,7 +424,7 @@ function conversationfromdb(database,user,conversationId,callback){
413 424
             newsArray[i].text=Qt.atob(newsArray[i].text);
414 425
             newsArray[i].id=newsArray[i].status_id;
415 426
             newsArray[i]=fetchUsersForNews(database,user,newsArray[i],allcontacts);
416
-            if (newsArray[i].attachments!==null){newsArray[i].attachments=JSON.parse(Qt.atob(newsArray[i].attachments))};
427
+            if (helpernews.attachments!="" && newsArray[i].attachments!==null){newsArray[i].attachments=JSON.parse(Qt.atob(newsArray[i].attachments))};
417 428
         }
418 429
     callback(newsArray)})
419 430
 }
@@ -443,32 +454,36 @@ function requestFavorites(login,database,contacts,rootwindow,callback){
443 454
 //            callback(newsArray);
444 455
 // }})}
445 456
 
446
-function chatsfromdb(database,user,callback,stop_time){
457
+function chatsfromdb(database,login,messagetype,callback,stop_time){
458
+
447 459
     var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
448 460
     db.transaction( function(tx) {
449 461
     if (!stop_time){var stop="";
450
-        try{var rs = tx.executeSql('select created_at from news WHERE username="'+username+'" ORDER BY created_at DESC LIMIT 1');
462
+        try{var rs = tx.executeSql('select created_at from news WHERE username="'+login.username+'" AND messagetype="'+messagetype+'" ORDER BY created_at DESC LIMIT 1');
451 463
         stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
452 464
     else{var stop="<"+stop_time}
453
-     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');
465
+    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');
466
+    var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id  DESC LIMIT 1');
467
+    try{var lastid=result.rows.item(0).status_id;}catch(e){var lastid=0};
454 468
     var conversations=[];
455 469
     for(var i = 0; i < conversationsrs.rows.length; i++) {
456 470
         conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id);
457 471
      }
458 472
     var newsArray=[];
459
-    var allcontacts=getAllContacts(database,user);
473
+    var allcontacts=getAllContacts(database,login.username);
474
+
460 475
     for(var j = 0; j< conversations.length; j++) {
461
-        var newsrs=tx.executeSql('select * from news WHERE username="'+user+'"  AND statusnet_conversation_id="'+conversations[j] +'" ORDER BY created_at ASC');
476
+        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');
462 477
         var helpernews=newsrs.rows.item(0);
463 478
         helpernews.newscount=newsrs.rows.length;
464
-        helpernews=fetchUsersForNews(database,user,helpernews,allcontacts);
479
+        helpernews=fetchUsersForNews(database,login.username,helpernews,allcontacts);
465 480
         helpernews.statusnet_html=Qt.atob(helpernews.statusnet_html);
466 481
         helpernews.text=Qt.atob(helpernews.text);
467 482
         helpernews.id=helpernews.status_id;
468
-        if (helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
483
+        if (helpernews.attachments!="" && helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
469 484
         newsArray.push(helpernews);
470 485
     }
471
-    callback(newsArray);
486
+    callback(newsArray,lastid);
472 487
 })}
473 488
 
474 489
 
@@ -495,7 +510,7 @@ function allchatsfromdb(database,user,callback){
495 510
         helpernews.statusnet_html=Qt.atob(helpernews.statusnet_html);
496 511
         helpernews.text=Qt.atob(helpernews.text);
497 512
         helpernews.id=helpernews.status_id;
498
-        if (helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
513
+        if (helpernews.attachments!="" && helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
499 514
         newsArray.push(helpernews);
500 515
         countArray.push(newsrs.rows.length)
501 516
     }
@@ -520,7 +535,7 @@ function oldchatfromdb(database,user,conversationId,lastpost,allcontacts,callbac
520 535
     helpernews.statusnet_html=Qt.atob(helpernews.statusnet_html);
521 536
     helpernews.text=Qt.atob(helpernews.text);
522 537
     helpernews.id=helpernews.status_id;
523
-    if (helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
538
+    if (helpernews.attachments!="" && helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))};
524 539
     callback(helpernews,newscount);}
525 540
 //    var conversationobject={news:helpernews,newscount:newscount};
526 541
 //    return conversationobject;

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

@@ -53,9 +53,12 @@ else{
53 53
 //            newsitemobject.user.profile_image_url="";
54 54
 //            newsitemobject.user.name="";
55 55
 //        }
56
-        var forumname="";try{if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_owner')&&((newsitemobject.friendica_owner.url)!=(newsitemobject.user.url))){
57
-            //print(newsitemobject.friendica_owner+" Friendica Owner "+JSON.stringify(newsitemobject));
58
-            forumname=" via "+newsitemobject.friendica_owner.name
56
+        var forumname="";
57
+        try{if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_author')&&
58
+                    ((newsitemobject.friendica_author.url)!=(newsitemobject.user.url))&&((newsitemobject.friendica_author.url)!=null)){
59
+            print(" Friendica Author "+JSON.stringify(newsitemobject.friendica_author));
60
+            forumname=" via "+newsitemobject.user.name;
61
+            newsitemobject.user=newsitemobject.friendica_author;
59 62
         }}catch(e){print("forum name "+e)}
60 63
         var likeText="";var dislikeText="";var attendyesText="";var attendnoText="";var attendmaybeText="";  var self={};
61 64
         try{if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_activities')){
@@ -166,7 +169,6 @@ else{
166 169
 //      }
167 170
 
168 171
         newsitemobject.attachmentList=attachmentList;
169
-
170 172
         var seconds=(msg.currentTime-newsitemobject.created_at)/1000;
171 173
         var timestring="";
172 174
         if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");}

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

@@ -38,7 +38,7 @@
38 38
 
39 39
 function initDatabase(database) { // initialize the database object
40 40
     var db =Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
41
-    print('initDatabase()'+database[0]+database[1]+database[2]+database[3])
41
+    //print('initDatabase()'+database[0]+database[1]+database[2]+database[3])
42 42
     db.transaction( function(tx) {
43 43
         //var version=tx.executeSql('PRAGMA user_version');print(JSON.stringify(version.rows.item(0)))
44 44
         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
194 194
      //print(JSON.stringify(obj));
195 195
      var result = tx.executeSql('SELECT * from config WHERE username="'+obj.username+'"');
196 196
      if(result.rows.length === 1) {// use update
197
-        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 +'"');
197
+        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 +'"');
198 198
         var result3 = tx.executeSql('UPDATE config SET isActive=1 WHERE username !="'+obj.username +'"');
199
-        var result4 = tx.executeSql('UPDATE config SET maxnews='+obj.maxnews);
200 199
       } else {// use insert print('... does not exists, create it')
201
-        var result2 = tx.executeSql('INSERT INTO config VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)', [obj.server, obj.username, obj.password, obj.imagestore, obj.maxnews, obj.interval,obj.newsViewType,0,"[[],[],[],[]]",0,"","",""]);
200
+        var result2 = tx.executeSql('INSERT INTO config VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)', [obj.server, obj.username, obj.password, obj.imagestore, 0, 0,obj.newsViewType,0,"[[],[],[],[]]",0,"","",""]);
202 201
         var result3 = tx.executeSql('UPDATE config SET isActive=1 WHERE username !="'+obj.username +'"');
203
-        var result4 = tx.executeSql('UPDATE config SET maxnews='+obj.maxnews);
204 202
         }
205 203
  })}
206 204
 
@@ -283,7 +281,7 @@ function readConfig(database,callback,filter,filtervalue) { // reads config
283 281
             for(var i = 0; i < rs.rows.length; i++) {
284 282
                 rsArray.push(rs.rows.item(i))
285 283
             }
286
-        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};
284
+        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};
287 285
             } else {var rsObject=""}
288 286
         callback(rsObject)}}
289 287
     )
@@ -318,6 +316,7 @@ function updateglobaloptions(database,key,value){
318 316
                 result = tx.executeSql('INSERT INTO globaloptions (k,v) VALUES (?,?)', [key,value])
319 317
         }
320 318
     })
319
+    root.globaloptions[key]=value;
321 320
  }
322 321
 
323 322
 function deleteConfig(database,userobj,callback) { // delete user data from DB
@@ -338,8 +337,9 @@ function deleteConfig(database,userobj,callback) { // delete user data from DB
338 337
 function  cleanNews(database,callback){
339 338
      var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
340 339
       db.transaction( function(tx) {
341
-             var maxnewsrs = tx.executeSql("SELECT DISTINCT maxnews FROM config");
342
-             var maxnews=maxnewsrs.rows.item(0).maxnews;
340
+             //var maxnewsrs = tx.executeSql("SELECT DISTINCT maxnews FROM config");
341
+             var maxnewsrs = tx.executeSql("SELECT v FROM globaloptions WHERE k='max_news'");
342
+          var maxnews=1000; if(maxnewsrs.rows.length>0){ maxnews=maxnewsrs.rows.item(0).v};
343 343
              var newscountrs = tx.executeSql('SELECT COUNT(*) from news');
344 344
              var newscount = newscountrs.rows.item(0)["COUNT(*)"];//print("newscount "+newscount)
345 345
              if (newscount>maxnews){
@@ -384,6 +384,7 @@ function updateContactInDB(login,database,isFriend,contact){// for newstab and f
384 384
 }
385 385
 
386 386
 function processNews(api,data){
387
+    //print(api + data);
387 388
     try{var newslist=JSON.parse(data)} catch(e){newsBusy.running=false;};
388 389
     if (data==""){}
389 390
     else if (typeof(newslist)=='undefined'){
@@ -393,6 +394,7 @@ function processNews(api,data){
393 394
         Helperjs.showMessage(qsTr("JSON status Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root)
394 395
     }
395 396
     else if (!(Array.isArray(newslist))){
397
+        //print("processNews not array"+newslist+JSON.stringify(newslist));
396 398
         replytimer.restart()
397 399
     }
398 400
     else {
@@ -407,6 +409,8 @@ function processNews(api,data){
407 409
                 newslist[n].uid=newslist[n].sender.id;
408 410
                 newslist[n].statusnet_conversation_id=newslist[n].friendica_parent_uri;
409 411
                 newslist[n].user=cleanUser(newslist[n].sender);
412
+                newslist[n].friendica_owner=newslist[n].user;
413
+                newslist[n].friendica_author=newslist[n].user;
410 414
                 newslist[n].statusnet_html=newslist[n].text;
411 415
         }}
412 416
         else if (api=="/api/friendica/notifications"){
@@ -418,6 +422,8 @@ function processNews(api,data){
418 422
                     newslist[n].user={"profile_image_url": newslist[n].photo,"name": newslist[n].name," url":newslist[n].url, "created_at":newslist[n].date};
419 423
                     newslist[n].user=cleanUser(newslist[n].user);
420 424
                 }
425
+                newslist[n].friendica_author=newslist[n].user;
426
+                newslist[n].friendica_owner=newslist[n].user;
421 427
                 newslist[n].statusnet_html=newslist[n].msg_html;
422 428
                 newslist[n].text=newslist[n].msg;
423 429
             }
@@ -427,8 +433,9 @@ function processNews(api,data){
427 433
             var commentCount=[];
428 434
             for (var n in newslist){
429 435
                 newslist[n].created_at=Date.parse(Newsjs.cleanDate(newslist[n].created_at));
430
-                newslist[n].messagetype=0;
431
-                newslist[n].user=cleanUser(newslist[n].user)
436
+                if (api=="/api/statuses/replies"){newslist[n].messagetype=3}else{newslist[n].messagetype=0;}
437
+                newslist[n].friendica_author=cleanUser(newslist[n].friendica_author);
438
+                newslist[n].user=cleanUser(newslist[n].user);
432 439
                 if(newslist[n].in_reply_to_user_id){newslist[n].reply_user=Newsjs.objFromArray(allcontacts,"id",newslist[n].in_reply_to_user_id)}
433 440
                 //print (JSON.stringify(newslist[n].user))
434 441
                 if(newslist[n].hasOwnProperty('friendica_activities')){
@@ -448,8 +455,8 @@ function processNews(api,data){
448 455
                             newslist[n].friendica_activities.attendmaybe[r]=cleanUser(newslist[n].friendica_activities.attendmaybe[r]);
449 456
                         }
450 457
                 }
451
-                if(!(newslist[n].hasOwnProperty('friendica_owner'))){
452
-                    newslist[n].friendica_owner=newslist[n].user
458
+                if(!(newslist[n].hasOwnProperty('friendica_author'))){
459
+                    newslist[n].friendica_author=newslist[n].user
453 460
                 }
454 461
                 var conversationindex=conversationIds.indexOf(newslist[n].statusnet_conversation_id);
455 462
 
@@ -488,11 +495,13 @@ function processNews(api,data){
488 495
         else if (api=="/api/statuses/user_timeline"){
489 496
             newstab.contactposts=newslist
490 497
         }
491
-        else if (newstab.newstabstatus==="Conversations"){
492
-            showNews(chatlist);root.news=newslist}
493
-        else {showNews(newslist);root.news=newslist};
498
+        else if ((api!="/api/direct_messages/all")&&(api!="/api/friendica/notifications")&&(newstab.newstabstatus==="Conversations")){
499
+            showNews(chatlist);root.news=newslist
500
+        }
501
+        else {
502
+            showNews(newslist);root.news=newslist};
494 503
 
495
-        var newstabarray=["Conversations","Favorites","Timeline","DirectMessage"];
504
+        var newstabarray=["Conversations","Favorites","Timeline","DirectMessage","Replies"];
496 505
         if (newstabarray.indexOf(newstab.newstabstatus)>-1){contacttimer.start()}
497 506
     }
498 507
 
@@ -509,26 +518,28 @@ function cleanUser(user){
509 518
 }
510 519
 
511 520
 function updateView(viewtype){
512
-    newsBusy.running=true;
521
+    //messageSend.state="";
522
+    //newsBusy.running=true;
513 523
     //downloadNotice.text="xhr start "+Date.now()
514 524
     switch(viewtype){
515 525
         case "Conversations":
516
-            var lastnews=Newsjs.getLastNews(login,db);
517
-            xhr.setLogin(login.username+":"+Qt.atob(login.password));
518
-            xhr.setUrl(login.server);
519
-            xhr.setApi("/api/statuses/friends_timeline");
520
-            xhr.clearParams();
521
-            xhr.setParam("since_id",lastnews);
522
-            xhr.setParam("count",50)
526
+            Newsjs.getLastNews(login,db,function(lastnews){
527
+                xhr.setLogin(login.username+":"+Qt.atob(login.password));
528
+                xhr.setUrl(login.server);
529
+                xhr.setApi("/api/statuses/friends_timeline");
530
+                xhr.clearParams();
531
+                xhr.setParam("since_id",lastnews);
532
+                xhr.setParam("count",50)});
523 533
             break;
524 534
         case "Timeline":
525
-            var lastnews=Newsjs.getLastNews(login,db);
526
-            xhr.setLogin(login.username+":"+Qt.atob(login.password));
527
-            xhr.setUrl(login.server);
528
-            xhr.setApi("/api/statuses/friends_timeline");
529
-            xhr.clearParams();
530
-            xhr.setParam("since_id",lastnews);
531
-            xhr.setParam("count",50)
535
+            var lastnews=Newsjs.getLastNews(login,db,function(lastnews){
536
+                xhr.setLogin(login.username+":"+Qt.atob(login.password));
537
+                xhr.setUrl(login.server);
538
+                xhr.setApi("/api/statuses/friends_timeline");
539
+                xhr.clearParams();
540
+                xhr.setParam("since_id",lastnews);
541
+                xhr.setParam("count",50)
542
+            });
532 543
             break;
533 544
         case "Search":
534 545
             xhr.setLogin(login.username+":"+Qt.atob(login.password));
@@ -566,14 +577,15 @@ function updateView(viewtype){
566 577
             xhr.clearParams();
567 578
             break;
568 579
         default:
569
-            var lastnews=Newsjs.getLastNews(login,db);
570
-            xhr.setLogin(login.username+":"+Qt.atob(login.password));
571
-            xhr.setUrl(login.server);
572
-            xhr.setApi("/api/statuses/friends_timeline");
573
-            xhr.clearParams();
574
-            xhr.setParam("since_id",lastnews);
575
-            xhr.setParam("count",50)
576
-            newstab.newstabstatus="Conversations";
580
+            Newsjs.getLastNews(login,db,function(lastnews){
581
+                xhr.setLogin(login.username+":"+Qt.atob(login.password));
582
+                xhr.setUrl(login.server);
583
+                xhr.setApi("/api/statuses/friends_timeline");
584
+                xhr.clearParams();
585
+                xhr.setParam("since_id",lastnews);
586
+                xhr.setParam("count",50)
587
+                newstab.newstabstatus="Conversations";
588
+            });
577 589
     }
578 590
 
579 591
     xhr.get();

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

@@ -29,8 +29,8 @@
29 29
 //  You should have received a copy of the GNU General Public License
30 30
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31 31
 
32
-import QtQuick 2.0
33
-import QtQuick.Controls 1.4
32
+import QtQuick 2.11
33
+//import QtQuick.Controls 2.4
34 34
 
35 35
 Item {
36 36
     id: calendarDay

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

@@ -30,10 +30,10 @@
30 30
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31 31
 
32 32
 import QtQuick 2.0
33
-import QtQuick.Controls 2.3
33
+import QtQuick.Controls 2.4
34 34
 import QtQml 2.2
35 35
 import Qt.labs.calendar 1.0
36
-import QtQuick.Controls 1.2 as Oldcontrol
36
+//import QtQuick.Controls 1.2 as Oldcontrol
37 37
 import QtQuick.Layouts 1.3
38 38
 import "qrc:/js/service.js" as Service
39 39
 import "qrc:/js/helper.js" as Helperjs
@@ -42,9 +42,10 @@ import "qrc:/qml/genericqml"
42 42
 
43 43
 Rectangle {
44 44
     id:calendarrectangle
45
-    y:1
46
-    width:root.width-mm
47
-    height:root.height-5*mm
45
+//    y:1
46
+//    width:root.width-mm
47
+//    height:root.height-5*mm
48
+    anchors.fill: parent
48 49
     color: '#fff'
49 50
     property date currentTime: new Date()
50 51
     property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000
@@ -83,30 +84,35 @@ Rectangle {
83 84
        }
84 85
 
85 86
 
86
-    BlueButton{
87
+    MButton{
87 88
         id:  updateEvents
88 89
         anchors.top: parent.top
89 90
         anchors.topMargin: 0.5*mm
90 91
         anchors.right:calendartabstatusButton.left
91 92
         anchors.rightMargin:mm
93
+        height: 6*mm
94
+        width: 8*mm
92 95
         text:"\uf021"
93 96
         onClicked: {
94
-            
95 97
             Service.getEvents(db,login, calendartab,function(){
96 98
                showEvents("")
97 99
     })}}
98 100
 
99
-    BlueButton{
101
+    MButton{
100 102
         id:  calendartabstatusButton
101 103
         anchors.top: parent.top
102 104
         anchors.topMargin: 0.5*mm
103 105
         anchors.right: parent.right
104 106
         anchors.rightMargin:2*mm
107
+        height: 6*mm
108
+        width: Math.max(10*mm,implicitWidth)
105 109
         text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus
106
-        Oldcontrol.Menu {
110
+        Menu {
107 111
             id:calendartabmenu
108
-            Oldcontrol.MenuItem {
112
+            width: 40*mm
113
+            MenuItem {
109 114
                 text: qsTr("Own Calendar")
115
+                font.pixelSize: 3*mm
110 116
                 onTriggered: {
111 117
                     calendartab.calendartabstatus="Events";
112 118
                    // calendartabstatusButton.text=qsTr("own Calendar");
@@ -146,6 +152,7 @@ Rectangle {
146 152
                 DayOfWeekRow{
147 153
                     locale: monthgrid.locale
148 154
                     Layout.fillWidth: true
155
+                    font.pixelSize: 3*mm
149 156
                 }
150 157
 
151 158
                 MonthGrid {

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

@@ -30,7 +30,7 @@
30 30
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31 31
 
32 32
 import QtQuick 2.0
33
-import QtQuick.Controls 1.2
33
+import QtQuick.Controls 2.4
34 34
 import "qrc:/js/service.js" as Service
35 35
 import "qrc:/js/helper.js" as Helperjs
36 36
 import "qrc:/qml/genericqml"
@@ -45,12 +45,14 @@ Rectangle{
45 45
     y:mm
46 46
     property var daylist:[]
47 47
 
48
-    BlueButton{
48
+    MButton{
49 49
        id:closeButton
50 50
        anchors.top: parent.top
51 51
        anchors.topMargin: 1*mm
52 52
        anchors.right: parent.right
53 53
        anchors.rightMargin: 1*mm
54
+       height: 6*mm
55
+       width: 8*mm
54 56
        text: "\uf057"
55 57
        onClicked:{eventList.destroy()}
56 58
     }

+ 463
- 0
source-android/qml/configqml/AccountPage.qml View File

@@ -0,0 +1,463 @@
1
+//  This file is part of Friendiqa
2
+//  https://git.friendi.ca/lubuwest/Friendiqa
3
+//  Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
4
+//
5
+//  This program is free software: you can redistribute it and/or modify
6
+//  it under the terms of the GNU General Public License as published by
7
+//  the Free Software Foundation, either version 3 of the License, or
8
+//  (at your option) any later version.
9
+//
10
+//  In addition, as a special exception, the copyright holders give
11
+//  permission to link the code of portions of this program with the
12
+//  OpenSSL library under certain conditions as described in each
13
+//  individual source file, and distribute linked combinations including
14
+//  the two.
15
+//
16
+//  You must obey the GNU General Public License in all respects for all
17
+//  of the code used other than OpenSSL. If you modify file(s) with this
18
+//  exception, you may extend this exception to your version of the
19
+//  file(s), but you are not obligated to do so. If you do not wish to do
20
+//  so, delete this exception statement from your version. If you delete
21
+//  this exception statement from all source files in the program, then
22
+//  also delete it here.
23
+//
24
+//  This program is distributed in the hope that it will be useful,
25
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
+//  GNU General Public License for more details.
28
+//
29
+//  You should have received a copy of the GNU General Public License
30
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31
+
32
+import QtQuick 2.7
33
+import QtQuick.Dialogs 1.2
34
+import QtQuick.Controls 2.4
35
+
36
+import "qrc:/js/service.js" as Service
37
+import "qrc:/js/layout.js" as Layoutjs
38
+import "qrc:/js/helper.js" as Helperjs
39
+import "qrc:/qml/configqml"
40
+import "qrc:/qml/genericqml"
41
+
42
+Page{
43
+        id:accountPage
44
+        width: root.width
45
+        height: root.height
46
+        property var users:[]
47
+        property var userdata: ({})
48
+
49
+        function setServericon(server){
50
+           try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",accountPage, function (obj){
51
+               var serverdata = JSON.parse(obj);
52
+               servericon.visible=true;
53
+               servericon.source=serverdata.site.logo})} catch(e){print(e)}
54
+        }
55
+
56
+        Button{
57
+            id:userButton
58
+            height: 8*mm
59
+            text:qsTr("User")
60
+            font.pixelSize: 3*mm
61
+            x: mm
62
+            y: mm
63
+            width: root.width/2
64
+            onClicked:{
65
+                var useritems="";
66
+                for (var i=0;i<accountPage.users.length;i++){
67
+
68
+                    useritems=useritems+"MenuItem{font.pixelSize: 3*mm; text:'"+accountPage.users[i].username+
69
+                        "'; onTriggered: {Service.readConfig(db,function(obj){
70
+                        userButton.text=obj.username;
71
+                        servername.text=obj.server;
72
+                        accountPage.setServericon(obj.server);
73
+                        username.text= obj.username;
74
+                        password.text=Qt.atob(obj.password);
75
+                        imagestore.text=obj.imagestore;
76
+                        newsTypeField.text=obj.newsViewType;
77
+                        if( obj.isActive==0){userButton.font.bold='true'} else {userButton.font.bold='false'}
78
+                        },'username','"+ accountPage.users[i].username+"')}}"
79
+                    }
80
+                var menuString="import QtQuick.Controls 2.4;import 'qrc:/js/service.js' as Service; Menu {"+useritems+"}";
81
+                var userlistObject=Qt.createQmlObject(menuString,accountPage,"usermenuOutput")
82
+                userlistObject.popup()  }
83
+            }
84
+
85
+    Text {
86
+        text: qsTr("Server")
87
+        font.pixelSize:3*mm
88
+        x: 4*mm; y: 10*mm
89
+    }
90
+    Text {
91
+        text: qsTr("Nickname")
92
+        font.pixelSize:3*mm
93
+        x: 4*mm; y: 20*mm
94
+    }
95
+
96
+    Text {
97
+        text: qsTr("Password")
98
+        font.pixelSize:3*mm
99
+        x: 4*mm; y: 30*mm
100
+      }
101
+    Text {
102
+        text: qsTr("Image dir.")
103
+        font.pixelSize:3*mm
104
+        x: 4*mm; y: 40*mm
105
+     }
106
+
107
+//    Text {
108
+//        text: qsTr("Max. News")
109
+//        font.pixelSize:3*mm
110
+//        x: 4*mm; y: 50*mm
111
+//     }
112
+    Text {
113
+        text: qsTr("News as")
114
+        font.pixelSize:3*mm
115
+        x: 4*mm; y: 50*mm
116
+    }
117
+
118
+      
119
+//    Text {
120
+//          text: qsTr("Show Website")
121
+//          x: 4*mm; y:80*mm; width: 20*mm
122
+//    }
123
+
124
+    Image{
125
+        id:servericon
126
+        x:4*mm;y:13.5*mm
127
+        width:5*mm; height: 5*mm
128
+        visible: false
129
+        source:""
130
+        MouseArea{
131
+            anchors.fill:parent
132
+            onClicked:{
133
+                Service.showServerConfig(servername.text, accountPage, function(configString){
134
+                var serverconfigObject=Qt.createQmlObject(configString,accountPage,"serverconfigOutput");})
135
+            }
136
+        }
137
+    }
138
+
139
+    Button{
140
+        id:serverSearchButton
141
+        text:"\uf002"
142
+        font.pixelSize: 3*mm
143
+        x:4*mm
144
+        y:13.5*mm
145
+        width: 5*mm; height:5*mm
146
+        visible: servericon.visible?false:true
147
+        onClicked:{Qt.openUrlExternally(Qt.resolvedUrl("https://dir.friendica.social/servers"))}
148
+    }
149
+
150
+    Rectangle{color: "light grey";  x: 10*mm; y: 13.5*mm; width: root.width-12*mm; height: 5*mm;}
151
+    Flickable {
152
+        id: servernameFlickable
153
+        x: 10*mm; y: 13.5*mm; width: root.width-12*mm; height: 5*mm;
154
+        contentWidth: servername.paintedWidth
155
+        contentHeight: servername.paintedHeight
156
+        clip: true
157
+        TextEdit {
158
+            id: servername
159
+            width: servernameFlickable.width
160
+            height: servernameFlickable.height
161
+            focus: true
162
+            font.pixelSize:3*mm
163
+            text:"https://"
164
+            onEditingFinished:{
165
+                 if((servername.text).substring(0,11) =="https://http"){
166
+                     serverstring.text= (serverstring.text).substring(8)
167
+                 }
168
+               accountPage.setServericon(servername.text)
169
+             }
170
+            onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,servernameFlickable)
171
+        }
172
+    }
173
+
174
+    Rectangle{
175
+        color: "light grey"
176
+        x: 4*mm; y: 23.5*mm; width: root.width-14*mm; height: 5*mm;
177
+        TextInput {
178
+            id: username
179
+            anchors.fill: parent
180
+            font.pixelSize:3*mm
181
+            selectByMouse: true
182
+            onEditingFinished:{
183
+                if (username.text.indexOf('@')>-1){
184
+                    Helperjs.showMessage(qsTr("Error"),qsTr("Nicknames containing @ symbol currently not supported"),accountPage)
185
+                }
186
+            }
187
+         }
188
+    }
189
+    Button {
190
+        x: root.width-9*mm; y: 23.5*mm; width:5*mm; height:5*mm
191
+        text: "\uf234"
192
+        font.pixelSize: 3*mm
193
+        onClicked: {
194
+            configStack.push({item:"qrc:/qml/configqml/RegisterPage.qml",properties:{url:servername.text+"/register?nickname="+username.getText(0,username.length)}})
195
+        }
196
+    }
197
+
198
+    Rectangle{
199
+        color: "light grey"
200
+         x: 4*mm; y: 33.5*mm; width: root.width-6*mm; height: 5*mm;
201
+         TextInput {
202
+             id: password
203
+             anchors.fill: parent
204
+             font.pixelSize:3*mm
205
+             selectByMouse: true
206
+             echoMode: TextInput.PasswordEchoOnEdit
207
+        }
208
+    }
209
+
210
+    Rectangle{color: "light grey"; x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm;}
211
+    Flickable {
212
+         id: imagestoreFlickable
213
+         x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm;
214
+         clip: true
215
+         TextInput {
216
+             id: imagestore
217
+             width: imagestoreFlickable.width
218
+             height: imagestoreFlickable.height
219
+             font.pixelSize:3*mm
220
+             wrapMode: TextEdit.NoWrap
221
+             onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,imagestoreFlickable)
222
+         }
223
+     }
224
+
225
+    FileDialog {
226
+        id: imagestoreDialog
227
+        title: "Please choose a directory"
228
+        folder: shortcuts.pictures
229
+        selectFolder: true
230
+        onAccepted: {
231
+            var imagestoreString=imagestoreDialog.folder.toString();
232
+            imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/"
233
+            imagestore.text=imagestoreString
234
+        }
235
+    }
236
+
237
+     Button {
238
+            x: root.width-9*mm; y: 43.5*mm; width: 5*mm; height: 5*mm;
239
+            text: "..."
240
+            font.pixelSize: 3*mm
241
+            onClicked:
242
+         {imagestoreDialog.open()}
243
+     }
244
+
245
+
246
+//    Slider{ id: maxNews
247
+//        x:19*mm; y: 53.5*mm;width: root.width/2;height:5*mm
248
+//        from: 0;to:2000; stepSize: 100
249
+//    }
250
+
251
+
252
+//    Rectangle{color: "light grey"; x: 4*mm; y: 53.5*mm; width: 9*mm; height: 5*mm;
253
+//        TextEdit{id:maxNewsText;
254
+//            anchors.fill: parent
255
+//            font.pixelSize:3*mm
256
+//            verticalAlignment:TextEdit.AlignRight
257
+//            text:maxNews.value
258
+//            focus: true
259
+//            selectByMouse: true
260
+//        }
261
+//    }
262
+
263
+    Rectangle{
264
+         x: 4*mm; y: 53.5*mm; width: newsTypeField.contentWidth+2*mm; height: 5*mm;
265
+         color:"light grey"
266
+         Text{
267
+             id: newsTypeField
268
+             anchors.fill: parent
269
+             font.pixelSize:3*mm
270
+             text:"Conversations"
271
+        }
272
+        MouseArea{
273
+            anchors.fill:parent
274
+            onClicked:newstypemenu.popup()
275
+        }
276
+    }
277
+
278
+    BusyIndicator{
279
+        id: accountBusy
280
+         anchors.horizontalCenter: parent.horizontalCenter
281
+         y: 63.5*mm
282
+         width:10*mm
283
+         height: 10*mm
284
+         running: false
285
+    }
286
+//    CheckBox{
287
+//        id:showwebsiteCheckbox
288
+//        x:35*mm;y:80*mm
289
+//        onClicked:{
290
+//            if (checked==true){
291
+//                Service.updateglobaloptions(root.db,"showWebsiteForLinks","true")
292
+//                root.globaloptions.showWebsiteForLinks="true"
293
+//            }
294
+//            else {
295
+//                Service.updateglobaloptions(root.db,"showWebsiteForLinks","false")
296
+//                root.globaloptions.showWebsiteForLinks="false"
297
+//            }
298
+//        }
299
+//    }
300
+
301
+    Button {
302
+    x: 4*mm; y: 63.5*mm
303
+    height: 8*mm
304
+    text: qsTr("Confirm")
305
+    font.pixelSize: 3*mm
306
+    onClicked:{
307
+        accountBusy.running=true;
308
+         var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text, maxnews:"",interval:  "",newsViewType:newsTypeField.text};
309
+         var errormessage="";
310
+         if (servername.text==""){errormessage=qsTr("No server given! ")}
311
+         else if (username.text==""){errormessage+=qsTr("No nickname given! ")}
312
+         else if (password.text=="") {errormessage+=qsTr("No password given! ")}
313
+         else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
314
+         //else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")}
315
+         else {errormessage=""}
316
+         if (errormessage=="") {
317
+             Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){
318
+                accountBusy.running=false;
319
+                 var credentials=JSON.parse(obj);
320
+                 if (credentials.hasOwnProperty('status')){
321
+                     Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
322
+                 }
323
+                 else{
324
+                     filesystem.Directory=userconfig.imagestore;
325
+                     filesystem.makeDir("contacts");
326
+                     filesystem.makeDir("albums");
327
+                     Service.storeConfig(db,userconfig);
328
+                     Service.readConfig(db,function(userconfig){
329
+                         Helperjs.readData(db,"config","",function(storedUsers){
330
+                            storedUsers.sort(function(obj1, obj2) {
331
+                                return obj1.isActive - obj2.isActive;
332
+                            });
333
+                         accountPage.users=storedUsers});
334
+                         //reset values
335
+                         root.login=userconfig;
336
+                         root.news=[];
337
+                     },"isActive",0);
338
+
339
+                     //Service.requestProfile(userconfig,db,root,function(nc){root.newContacts=nc});
340
+                     Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.name+"\nScreen Name: "+credentials.screen_name,root)
341
+                 }
342
+             });
343
+
344
+        }
345
+         else {Helperjs.showMessage(qsTr("Error"), errormessage,root)}
346
+    }}
347
+
348
+
349
+
350
+    Button {
351
+    x: parent.width/2+2*mm; y: mm; width: 5*mm; height: 8*mm;
352
+    text: "-"
353
+    font.pixelSize: 3*mm
354
+    onClicked:{
355
+        var userconfig={server: servername.text, username: username.text, password: Qt.btoa(password.text)};
356
+        Service.deleteConfig(db,userconfig,function(){
357
+           filesystem.Directory=imagestore.text+"contacts";
358
+           filesystem.rmDir();
359
+           filesystem.Directory=imagestore.text+"albums";
360
+           filesystem.rmDir();
361
+           servername.text="https://";
362
+           servericon.visible=false;
363
+           servericon.source="";
364
+           username.text="";
365
+           password.text="";
366
+           imagestore.text="";
367
+           //maxNews.value=0;
368
+           newsTypeField.text="Conversations";
369
+           //messageIntervalSlider.value=30;
370
+           userButton.text=qsTr("User");
371
+           Helperjs.readData(db,"config","",function(storedUsers){
372
+             storedUsers.sort(function(obj1, obj2) {
373
+                 return obj1.isActive - obj2.isActive;
374
+             })
375
+             accountPage.users=storedUsers;})
376
+       })
377
+    }}
378
+
379
+    Button {
380
+    x: parent.width/2+8*mm; y: mm; width: 5*mm; height: 8*mm;
381
+    text: "+"
382
+    font.pixelSize: 3*mm
383
+    onClicked:{
384
+        servername.text="https://"
385
+        servericon.visible=false;
386
+        servericon.source="";
387
+        username.text=""
388
+        password.text=""
389
+        imagestore.text=""
390
+        //maxNews.value=0
391
+        newsTypeField.text="Conversations"
392
+        //messageIntervalSlider.value=30
393
+        userButton.text=qsTr("User")
394
+       }
395
+     }
396
+
397
+    Button {
398
+        x: parent.width/2+14*mm; y: mm; width: 5*mm; height: 8*mm;
399
+        text: "?"
400
+        font.pixelSize: 3*mm
401
+        onClicked:{
402
+                    root.push("qrc:/qml/configqml/InfoBox.qml");
403
+           }
404
+         }
405
+    Button{
406
+        id:closeButton
407
+        height: 8*mm
408
+        anchors.top: parent.top
409
+        anchors.topMargin: 1*mm