From d48847d183da9479abde2890c25bb15ec710e542 Mon Sep 17 00:00:00 2001 From: LubuWest Date: Tue, 25 Jun 2019 20:59:10 +0200 Subject: [PATCH] v.0.5 --- CHANGELOG.md | 145 ++-- README.md | 32 +- source-android/android/AndroidManifest.xml | 11 +- source-android/android/build.gradle | 3 + source-android/android/gradle.properties | 4 + source-android/android/libcrypto.so | Bin source-android/android/libssl.so | Bin source-android/android/local.properties | 1 + .../drawable-hdpi/friendiqanotification.png | Bin 0 -> 460 bytes .../drawable-mdpi/friendiqanotification.png | Bin 0 -> 430 bytes .../drawable-xhdpi/friendiqanotification.png | Bin 0 -> 540 bytes .../drawable-xxhdpi/friendiqanotification.png | Bin 0 -> 718 bytes .../friendiqanotification.png | Bin 0 -> 892 bytes .../res/drawable/friendiqanotification.png | Bin 0 -> 892 bytes .../androidnative/AndroidNativeActivity.java | 2 +- .../java/src/androidnative/Util.java | 41 +- source-android/application.qrc | 10 +- source-android/common/alarm.h | 1 + source-android/common/alarmandroid.cpp | 42 +- source-android/common/alarmlinux.cpp | 73 ++ source-android/common/friendiqa.cpp | 14 +- source-android/common/updatenews.cpp | 415 ++++++++---- source-android/common/updatenews.h | 10 +- source-android/common/xhr.cpp | 9 +- source-android/common/xhr.h | 5 +- source-android/js/helper.js | 9 +- source-android/js/layout.js | 2 +- source-android/js/news.js | 129 ++-- source-android/js/newsworker.js | 10 +- source-android/js/service.js | 90 +-- .../qml/calendarqml/CalendarDay.qml | 4 +- .../qml/calendarqml/CalendarTab.qml | 27 +- source-android/qml/calendarqml/EventList.qml | 6 +- source-android/qml/configqml/AccountPage.qml | 463 +++++++++++++ source-android/qml/configqml/ConfigPage.qml | 227 +++++++ source-android/qml/configqml/InfoBox.qml | 26 +- .../qml/configqml/OSSettingsLinux.qml | 2 +- source-android/qml/configqml/RegisterPage.qml | 11 +- .../qml/configqml/SyncComponent.qml | 87 +++ source-android/qml/configqml/SyncConfig.qml | 101 +++ .../qml/contactqml/ContactComponent.qml | 5 +- .../contactqml/ContactDetailsComponent.qml | 27 +- source-android/qml/contactqml/Contactlist.qml | 7 +- source-android/qml/contactqml/FriendsTab.qml | 137 ++-- .../qml/contactqml/GroupComponent.qml | 49 +- .../qml/contactqml/ProfileComponent.qml | 51 +- source-android/qml/friendiqa.qml | 333 ++++++++-- source-android/qml/genericqml/BlueButton.qml | 2 +- source-android/qml/genericqml/ImagePicker.qml | 2 +- .../qml/genericqml/ImagePickerLinux.qml | 5 +- .../qml/genericqml/IntentReceiver.qml | 11 +- source-android/qml/genericqml/LinuxSync.qml | 22 + source-android/qml/genericqml/MButton.qml | 39 ++ .../qml/genericqml/PermissionDialog.qml | 6 +- source-android/qml/genericqml/Search.qml | 2 +- source-android/qml/newsqml/ContactPage.qml | 41 +- source-android/qml/newsqml/Conversation.qml | 130 ++-- source-android/qml/newsqml/MessageSend.qml | 382 ++++++++--- source-android/qml/newsqml/NewsStack.qml | 579 ++++++++++++++++ source-android/qml/newsqml/NewsTab.qml | 436 +++--------- source-android/qml/newsqml/Newsitem.qml | 76 ++- .../qml/newsqml/PermissionDialog.qml | 15 +- source-android/qml/newsqml/SmileyDialog.qml | 95 +-- .../qml/photoqml/ImageUploadDialog.qml | 12 +- source-android/qml/photoqml/PhotoTab.qml | 45 +- source-android/qtquickcontrols2.conf | 14 + source-android/translations/friendiqa-de.qm | Bin 11880 -> 12176 bytes source-android/translations/friendiqa-de.ts | 591 +++++++++++------ source-android/translations/friendiqa-es.qm | Bin 8471 -> 8224 bytes source-android/translations/friendiqa-es.ts | 609 ++++++++++------- source-android/translations/friendiqa-it.qm | Bin 7636 -> 7542 bytes source-android/translations/friendiqa-it.ts | 621 +++++++++++------- source-linux/application.qrc | 9 +- source-linux/common/alarm.h | 2 +- source-linux/common/alarmandroid.cpp | 46 +- source-linux/common/alarmlinux.cpp | 73 ++ source-linux/common/filesystem.cpp | 2 +- source-linux/common/filesystem.h | 2 +- source-linux/common/friendiqa.cpp | 35 +- .../common/remoteauthasyncimageprovider.cpp | 2 +- .../common/remoteauthasyncimageprovider.h | 2 +- source-linux/common/updatenews.cpp | 399 ++++++++--- source-linux/common/updatenews.h | 45 +- source-linux/common/uploadableimage.cpp | 2 +- source-linux/common/uploadableimage.h | 2 +- source-linux/common/xhr.cpp | 20 +- source-linux/common/xhr.h | 7 +- source-linux/friendiqa.pro | 6 +- source-linux/js/helper.js | 9 +- source-linux/js/layout.js | 2 +- source-linux/js/news.js | 129 ++-- source-linux/js/newsworker.js | 10 +- source-linux/js/service.js | 90 +-- source-linux/qml/calendarqml/CalendarDay.qml | 4 +- source-linux/qml/calendarqml/CalendarTab.qml | 27 +- source-linux/qml/calendarqml/EventList.qml | 6 +- source-linux/qml/configqml/AccountPage.qml | 463 +++++++++++++ source-linux/qml/configqml/ConfigPage.qml | 227 +++++++ source-linux/qml/configqml/InfoBox.qml | 26 +- .../qml/configqml/OSSettingsLinux.qml | 2 +- source-linux/qml/configqml/RegisterPage.qml | 11 +- source-linux/qml/configqml/SyncComponent.qml | 87 +++ source-linux/qml/configqml/SyncConfig.qml | 101 +++ .../qml/contactqml/ContactComponent.qml | 5 +- .../contactqml/ContactDetailsComponent.qml | 27 +- source-linux/qml/contactqml/Contactlist.qml | 7 +- source-linux/qml/contactqml/FriendsTab.qml | 137 ++-- .../qml/contactqml/GroupComponent.qml | 49 +- .../qml/contactqml/ProfileComponent.qml | 51 +- source-linux/qml/friendiqa.qml | 357 +++++++--- source-linux/qml/genericqml/BlueButton.qml | 2 +- source-linux/qml/genericqml/ImagePicker.qml | 2 +- .../qml/genericqml/ImagePickerLinux.qml | 5 +- .../qml/genericqml/IntentReceiver.qml | 11 +- source-linux/qml/genericqml/LinuxSync.qml | 22 + source-linux/qml/genericqml/MButton.qml | 39 ++ .../qml/genericqml/PermissionDialog.qml | 6 +- source-linux/qml/genericqml/Search.qml | 2 +- source-linux/qml/newsqml/ContactPage.qml | 41 +- source-linux/qml/newsqml/Conversation.qml | 130 ++-- source-linux/qml/newsqml/MessageSend.qml | 382 ++++++++--- source-linux/qml/newsqml/NewsStack.qml | 579 ++++++++++++++++ source-linux/qml/newsqml/NewsTab.qml | 436 +++--------- source-linux/qml/newsqml/Newsitem.qml | 76 ++- source-linux/qml/newsqml/PermissionDialog.qml | 15 +- source-linux/qml/newsqml/SmileyDialog.qml | 95 +-- .../qml/photoqml/ImageUploadDialog.qml | 12 +- source-linux/qml/photoqml/PhotoTab.qml | 45 +- source-linux/qtquickcontrols2.conf | 14 + source-linux/translations/friendiqa-de.qm | Bin 11880 -> 12176 bytes source-linux/translations/friendiqa-de.ts | 591 +++++++++++------ source-linux/translations/friendiqa-es.qm | Bin 8471 -> 8224 bytes source-linux/translations/friendiqa-es.ts | 609 ++++++++++------- source-linux/translations/friendiqa-it.qm | Bin 7636 -> 7542 bytes source-linux/translations/friendiqa-it.ts | 621 +++++++++++------- 135 files changed, 8879 insertions(+), 3693 deletions(-) create mode 100644 source-android/android/gradle.properties mode change 100755 => 100644 source-android/android/libcrypto.so mode change 100755 => 100644 source-android/android/libssl.so create mode 100644 source-android/android/local.properties create mode 100644 source-android/android/res/drawable-hdpi/friendiqanotification.png create mode 100644 source-android/android/res/drawable-mdpi/friendiqanotification.png create mode 100644 source-android/android/res/drawable-xhdpi/friendiqanotification.png create mode 100644 source-android/android/res/drawable-xxhdpi/friendiqanotification.png create mode 100644 source-android/android/res/drawable-xxxhdpi/friendiqanotification.png create mode 100644 source-android/android/res/drawable/friendiqanotification.png create mode 100644 source-android/common/alarmlinux.cpp create mode 100644 source-android/qml/configqml/AccountPage.qml create mode 100644 source-android/qml/configqml/ConfigPage.qml create mode 100644 source-android/qml/configqml/SyncComponent.qml create mode 100644 source-android/qml/configqml/SyncConfig.qml create mode 100644 source-android/qml/genericqml/LinuxSync.qml create mode 100644 source-android/qml/genericqml/MButton.qml create mode 100644 source-android/qml/newsqml/NewsStack.qml create mode 100644 source-android/qtquickcontrols2.conf create mode 100644 source-linux/common/alarmlinux.cpp create mode 100644 source-linux/qml/configqml/AccountPage.qml create mode 100644 source-linux/qml/configqml/ConfigPage.qml create mode 100644 source-linux/qml/configqml/SyncComponent.qml create mode 100644 source-linux/qml/configqml/SyncConfig.qml create mode 100644 source-linux/qml/genericqml/LinuxSync.qml create mode 100644 source-linux/qml/genericqml/MButton.qml create mode 100644 source-linux/qml/newsqml/NewsStack.qml create mode 100644 source-linux/qtquickcontrols2.conf diff --git a/CHANGELOG.md b/CHANGELOG.md index d1ebb21..0f2f3f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,33 +1,68 @@ -## v0.1## + +## v0.5 ## +* Redesign due to QML Components 1 being deprecated in Qt 5.12: Slideview for News, left Drawer for Settings, message creation in listview header +* Android Notifications for News, DMs, Replies +* Global app config separated from account config -# News # - -* Native Android image selector for new message -* Click on contacts shows contact details on news page -* Fix problem with news list after deletion of item - -# Contacts # -* Clean contacts with no news - -# Images # -* Upload pictures with description to album (permissions cannot be set due to API problems) -* Delete pictures or albums from client and server (long press on picture in overview) -* Fix problem when enlarging photo - -# Translations # -* German, Spanish +## v0.4 ## +* Background sync for friends timeline (interval on config page must be > 0) for Android > 5 +* Replies timeline +* Bugfix: App asks for storage permission on first start - -## v0.1.1## -* FIX: Spanish translation -* FIX: Empty Newsview after deletion of first newsitem +## v0.3.4 ## +* Direct message creation from profile page works again +* Profile image upload works again +* Viewing private album pictures of contacts works again +* On first start servername from https://dir.friendica.social/servers/surprise selected +* Register button opens webview of registration page on server +## v0.3.3 ## +* Update for OpenSSL and At +* Experimental support for Peertube (links are expanded to video widget) +* Some Unicode emojis +* Redesign of contact details (click on contact opens in new stack and shows last news) -## v0.1.2# -* FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above + +## v0.3.2 ## +* For news containing url ending with mp3, mp4, avi, webm, ogg: media can be played in app +* Pictures can be renamed or moved to another album +* Bugfix: random crashes for conversations +* Bugfix: attach image to message works again +* Bugfix: check for nickname on Server has been removed due to API change + + +## v0.3.1 ## +* By popular demand: Conversations open in a new stack, like in Twidere +* Conversations open after (long) press on news, like in Twidere +* Image attachments are shown below text and can be enlarged, like in Twidere (solves issue #8) +* New messages are html, line breaks work (solves issue #7) + + +## v0.3 ## +* Fix for [issue 6](https://github.com/LubuWest/Friendiqa/issues/6) +* Refactoring of news part +* Search button for news +* Click on hashtag in newsitem starts search for news with that word +* Public timeline +* Timeline for selected group +* Small redesign of SendMessage page + + +## v0.2.2 ## +* Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5) +* Link to list of public server on Config Tab +* Small redesign of SendMessage page +* Intents for texts/urls (Send text or url from everywhere to create message) + + +## v0.2.1 ## +* Fix for [issue 4](https://github.com/LubuWest/Friendiqa/issues/4) +* Fix for Friendica [issue 4689](https://github.com/friendica/friendica/issues/4689) +* Long posts are automatically truncated +* Intents for pictures (Send one image from gallery: attach to message, send multiple images: upload to album) ## v0.2 ## @@ -53,57 +88,31 @@ # Translations # * Italian thanks to Davide de Prisco -## v0.2.1 ## -* Fix for [issue 4](https://github.com/LubuWest/Friendiqa/issues/4) -* Fix for Friendica [issue 4689](https://github.com/friendica/friendica/issues/4689) -* Long posts are automatically truncated -* Intents for pictures (Send one image from gallery: attach to message, send multiple images: upload to album) -## v0.2.2 ## -* Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5) -* Link to list of public server on Config Tab -* Small redesign of SendMessage page -* Intents for texts/urls (Send text or url from everywhere to create message) +## v0.1.2## +* FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above -## v0.3 ## -* Fix for [issue 6](https://github.com/LubuWest/Friendiqa/issues/6) -* Refactoring of news part -* Search button for news -* Click on hashtag in newsitem starts search for news with that word -* Public timeline -* Timeline for selected group -* Small redesign of SendMessage page - -## v0.3.1 ## -* By popular demand: Conversations open in a new stack, like in Twidere -* Conversations open after (long) press on news, like in Twidere -* Image attachments are shown below text and can be enlarged, like in Twidere (solves issue #8) -* New messages are html, line breaks work (solves issue #7) +## v0.1.1## +* FIX: Spanish translation +* FIX: Empty Newsview after deletion of first newsitem -## v0.3.2 ## -* For news containing url ending with mp3, mp4, avi, webm, ogg: media can be played in app -* Pictures can be renamed or moved to another album -* Bugfix: random crashes for conversations -* Bugfix: attach image to message works again -* Bugfix: check for nickname on Server has been removed due to API change +## v0.1## +# News # -## v0.3.3 ## -* Update for OpenSSL and At -* Experimental support for Peertube (links are expanded to video widget) -* Some Unicode emojis -* Redesign of contact details (click on contact opens in new stack and shows last news) +* Native Android image selector for new message +* Click on contacts shows contact details on news page +* Fix problem with news list after deletion of item -## v0.3.4 ## -* Direct message creation from profile page works again -* Profile image upload works again -* Viewing private album pictures of contacts works again -* On first start servername from https://dir.friendica.social/servers/surprise selected -* Register button opens webview of registration page on server +# Contacts # +* Clean contacts with no news -## v0.4 ## -* Background sync for friends timeline (interval on config page must be > 0) for Android > 5 -* Replies timeline -* Bugfix: App asks for storage permission on first start +# Images # +* Upload pictures with description to album (permissions cannot be set due to API problems) +* Delete pictures or albums from client and server (long press on picture in overview) +* Fix problem when enlarging photo + +# Translations # +* German, Spanish diff --git a/README.md b/README.md index b373f84..28ae545 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ QML based client for the Friendica Social Network. Tabs for news (incl. Direct Messages), friends, photos and events. - OS: currently Linux and Android (4.3 Jelly Bean). + OS: currently Linux and Android (4.3 Jelly Bean, 5.1 for background sync). Source code is a QtCreator project. ## Screenshots ## @@ -18,9 +18,10 @@ QML based client for the Friendica Social Network. # News # Currently supported: -* Shows Posts from friends, selected group, replies, favorited messages, public timeline, Direct Messages and notifications -* Background sync with configurable interval of 15 min to 2h for active contact for friends timeline (Android 5 required) -* Search button for news +* Shows Posts from friends, replies, Direct Messages and notifications (in swipe view), selected group, replies, favorited messages, public timeline +* Background sync with configurable interval of 15 min to 2h for active contact for friends timeline, replies and DMs (Android 5.1 required) +* Android notifications for new items in friends timeline, replies and DMs +* Search for news * Click on hashtag in newsitem starts search for news with that word * Click on image shows image fullscreen * For news containing urls ending with mp3, mp4, avi, webm, ogg or to a Peertube instance: media can be played in the app @@ -39,26 +40,23 @@ Currently supported: * Native Android image dialog ToDo: - -* Videos and other binary data as attachment (sending) -* More than one attachment (currently not supported in API) +* Videos and other binary data as attachment (sending, not supported in API) +* More than one attachment * Attachments for Direct messages (currently not supported in API) # Friends # Currently supported: - * Tabs for own profiles, friends, other contacts and groups * Show profile(s) of user and change profile picture * List of all known contacts with locally downloaded pictures * Additional information, last messages and other functionality shown in news tab -* Send direct message, if contact is following -* Show public and private (Friendica 3.6 required) pictures of contact (screenscraping of contact's website, works only with certain theme) -* Show public and private (Friendica 3.6 required) events of contact +* Show public and private pictures of contact (screenscraping of contact's website, works only with certain theme) +* Show public and private events of contact * Show members of groups * Open website of contact or connect page (for other contacts) * Clean other contacts with no news - + ToDo: * More information for contact from description page, possibly private information for friends (needs API change) @@ -71,7 +69,7 @@ Currently supported: * Download public and private own images to local directory * Upload picture to album with descriptions(public), send from gallery * Delete own pictures and albums on client and server -* Change name or album of existing picture +* Change name or album of existing picture * Show albums in grid, show images in album in grid and fullscreen * Show public and private (Friendica 3.6 server required) albums and images of contacts * Pinch to zoom, swipe to scroll @@ -81,8 +79,9 @@ ToDo: # Events # +Currently supported: * Download own public events -* Show public and private events of Friendica contacts (Friendica 3.6 server required) +* Show public and private events of Friendica contacts (Friendica >3.6 server required) * List view of events of selected date * Click on event to show details @@ -91,11 +90,12 @@ ToDo * Create events (needs API) -# Config # +# Config/Accounts # Currently supported: * Multiple accounts -* Maximum news (deleted after use of Quit button) * View mode for news (tree or timeline) +* Maximum news (deleted after use of Quit button) +* Sync home timeline, replies, DM, Notify yes/no ToDo * OAuth? diff --git a/source-android/android/AndroidManifest.xml b/source-android/android/AndroidManifest.xml index 516839e..d71d476 100644 --- a/source-android/android/AndroidManifest.xml +++ b/source-android/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + @@ -78,13 +78,12 @@ - - + + - - + + diff --git a/source-android/android/build.gradle b/source-android/android/build.gradle index 8d9aacb..f4f2592 100644 --- a/source-android/android/build.gradle +++ b/source-android/android/build.gradle @@ -26,6 +26,9 @@ dependencies { compile 'com.android.support:support-v4:25.3.1' } +dependencies { + compile 'com.android.support:support-compat:25.3.1' +} android { /******************************************************* diff --git a/source-android/android/gradle.properties b/source-android/android/gradle.properties new file mode 100644 index 0000000..45a105a --- /dev/null +++ b/source-android/android/gradle.properties @@ -0,0 +1,4 @@ +androidBuildToolsVersion=25.0.3 +androidCompileSdkVersion=27 +buildDir=.build +qt5AndroidDir=/home/pankraz/Qt/5.11.1/android_armv7/src/android/java diff --git a/source-android/android/libcrypto.so b/source-android/android/libcrypto.so old mode 100755 new mode 100644 diff --git a/source-android/android/libssl.so b/source-android/android/libssl.so old mode 100755 new mode 100644 diff --git a/source-android/android/local.properties b/source-android/android/local.properties new file mode 100644 index 0000000..ada6c98 --- /dev/null +++ b/source-android/android/local.properties @@ -0,0 +1 @@ +sdk.dir=/home/pankraz/android-sdk_alt diff --git a/source-android/android/res/drawable-hdpi/friendiqanotification.png b/source-android/android/res/drawable-hdpi/friendiqanotification.png new file mode 100644 index 0000000000000000000000000000000000000000..cb78f92009d22e266d8674f1acd60494e2864f47 GIT binary patch literal 460 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBSc;uILpXq-h9ji|$mcBZh%9Dc zVC@89#@vj#zkq_0C9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NHH)ldV0Dz zhD5Z!owm`7*-@Zvf2^L1lG3zW+44T=3+)`6Ze%8k=6qrivukgiTidZ#Oeri$C-hS0 zLMJ9OA)bqCj?Ue{@vMyR+}%g}s@Uwx%G2so&xt+Loci8DcOvuMdo!Yn88-0CEWPUP zVyvqmK2s+{Bzm7}j>(2c(TCiaHv^el@*D57sEc??hdmZ7OZ$=N@-=DU?Rydl3^tt6 zzjtz|ZfQ(Ac5fxi_cpGDCP36AEYx3Hx-;cf_S3tE_wLM{{_Ek1kaPKNZ+{((?yji! zb)DJmdQ(eOi8te5Y^358Hy|o-dSrX0_wxi}{{H!ksx}7r&X8D|!kZC(pmW3XOG`CY zU$EtiHs?NQo5kx><9#DTrtZOim*!pHbQ2dF%KVE%TvLCjkQ=$cJHHLu|QDa!O;T~!XS(i|{Z7p?%ERujd# zZwvtN1HAwYi`4#)@fI=DE9ZzqpEmlY0Pt_Cx0f2Tc#U^o5uh6%R)Yk#<@Eox; zTceUP>-lxS?$O(U7pnavKX-!Vx$Hf3hGSx-X43q>5whef3tNCJj{pDw literal 0 HcmV?d00001 diff --git a/source-android/android/res/drawable-xhdpi/friendiqanotification.png b/source-android/android/res/drawable-xhdpi/friendiqanotification.png new file mode 100644 index 0000000000000000000000000000000000000000..5fe8bbdc2b75dd52c77ea127686e9c3780cf5bc6 GIT binary patch literal 540 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTCmSQK*5Dp-y;YjHK@;M7UB8wRq z*pon*(V}YRZJ?lJiEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$QVa}?Gd*1# zLoyoQ&an1o4is=Zzc*`v}WZY_gu+Gtu_xp)>RN-x+Pb&amUp3%wn(Q#zJ1*aM zUeYr2_H?M;yEpfJRAIxHy3kurEfx;KtPAws1b&VZNNG@gV0NHR_u^OiLJ5c21`TG3 z47t1P91@z>Oz2HdQ&*lkU%iau@vo@73;%azrk$EQ{|Ni*!wf#EN|`>N*So&vzLmAj z?cEwXjvVIiarg3L>W=)^k`P#wJ$0Kz=>&*rhZt_PFm4fCFSIelQzx)C@5ee(_8(D< zS2#XJr3zLEeB1F2@!_-Ls;}{@ aVY;Ina=5yC-Y;NGGI+ZBxvX4nJ za0`PlBg3pY5yvwN?y=t+-9?|g&j|b#{?grkVEKvaEvI7EymAO{m@fK$r*2&*L?^-w zG?td_S^NE^AM$dO>e~+(7<}sgZ^y**|EsK`%yhSnf95~V)vQ{;9em$f#@fWhPous+ zZT0Ctm#oa?YwXxfB=3}KwYH=$7Ia$|_C@{7o%xjt&Fn@MxC!Skza2Lhf1GbHyMC`+ z?%NlQbvyhwEB{nYTk(r?v$?~Y>~)dPl0w<7`t6&x??#xT@j(?7E)SevDHbhLcnbLFo(U-pmKJk198P zemi}ONf>uY23Lfqg@0L{RhCC?YUc&p&L83bm)$>?bSXl2#a4f33+_F>2Ek$5Y}RxM uEQ!1GJh@tCh2xHGA6G`D_0PS#kBKKVuR-L^5jSAkWAJqKb6Mw<&;$T3m@j7l literal 0 HcmV?d00001 diff --git a/source-android/android/res/drawable-xxxhdpi/friendiqanotification.png b/source-android/android/res/drawable-xxxhdpi/friendiqanotification.png new file mode 100644 index 0000000000000000000000000000000000000000..ea3879db0748930f55047c37c5244a6411f672a1 GIT binary patch literal 892 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m+AU64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq!<{OetNn% zhE&XXd)L+@G*RaG$M^qtep4%4%;ChX#opf3CRNo~v#@R1thudg7HnN zi39}ndqhV3S6nyKreOxVz-NXeIfpaM9hD3l&Av7yi;G_sX85sXhG(BPzrp9cNL$BK z{*FKuK6PBHk|iqE%Q4!Veyp%o;(_7^7h5I$IxZoE0fzhv&lr!OnTjNsy>os?sk}x` z{qKZy_OKh*E@+3{>N@h~eg4+`Zq_iT!nfShmaqN)`FdO5U->A#19w+jyPY&M{ns_E z(e%TQGY699ZWr!j(3h6~kpG0Suk8B1&E0QjZGN=+CYSf=i4#BOw>O?WAami%?qfQB zWmkS0c=Z44FSXz#;3h1t|Ff=RT_fvP76v=LHEaGaP@BO1xIlOLKMz+gJ*?^t?= z?cNG^hTuw>C8EqW$NtCkp6*5tN1%_z8s38f{D3$p@Et3ut+dS#ON5~|IpBh z3F)VbBkZQf-Hp2Xp4n)(^1X>`vKsbXQhu>~(EX_M%nK*%jlMy?@WIdAi`;(+uN9 zU(eoGDqza7dLO9y^YMA+HOoz$^IwYGsNBHm@cI8gvkj&1xmVT2YVv+DQ oLdt^W4SUytX=?B9Y^Y;+vafw@bJv<`U`}E1boFyt=akR{0PQP(1ONa4 literal 0 HcmV?d00001 diff --git a/source-android/android/res/drawable/friendiqanotification.png b/source-android/android/res/drawable/friendiqanotification.png new file mode 100644 index 0000000000000000000000000000000000000000..ea3879db0748930f55047c37c5244a6411f672a1 GIT binary patch literal 892 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m+AU64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq!<{OetNn% zhE&XXd)L+@G*RaG$M^qtep4%4%;ChX#opf3CRNo~v#@R1thudg7HnN zi39}ndqhV3S6nyKreOxVz-NXeIfpaM9hD3l&Av7yi;G_sX85sXhG(BPzrp9cNL$BK z{*FKuK6PBHk|iqE%Q4!Veyp%o;(_7^7h5I$IxZoE0fzhv&lr!OnTjNsy>os?sk}x` z{qKZy_OKh*E@+3{>N@h~eg4+`Zq_iT!nfShmaqN)`FdO5U->A#19w+jyPY&M{ns_E z(e%TQGY699ZWr!j(3h6~kpG0Suk8B1&E0QjZGN=+CYSf=i4#BOw>O?WAami%?qfQB zWmkS0c=Z44FSXz#;3h1t|Ff=RT_fvP76v=LHEaGaP@BO1xIlOLKMz+gJ*?^t?= z?cNG^hTuw>C8EqW$NtCkp6*5tN1%_z8s38f{D3$p@Et3ut+dS#ON5~|IpBh z3F)VbBkZQf-Hp2Xp4n)(^1X>`vKsbXQhu>~(EX_M%nK*%jlMy?@WIdAi`;(+uN9 zU(eoGDqza7dLO9y^YMA+HOoz$^IwYGsNBHm@cI8gvkj&1xmVT2YVv+DQ oLdt^W4SUytX=?B9Y^Y;+vafw@bJv<`U`}E1boFyt=akR{0PQP(1ONa4 literal 0 HcmV?d00001 diff --git a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java index 4d9d745..5832b90 100644 --- a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java +++ b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java @@ -38,7 +38,7 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt // app-defined int constant. The callback method gets the // result of the request. } else { - + System.loadLibrary("friendiqa"); if((getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_NEW_TASK) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) || (getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))) { SystemDispatcher.onActivityResume(); diff --git a/source-android/androidnative.pri/java/src/androidnative/Util.java b/source-android/androidnative.pri/java/src/androidnative/Util.java index 6ff5819..500da26 100644 --- a/source-android/androidnative.pri/java/src/androidnative/Util.java +++ b/source-android/androidnative.pri/java/src/androidnative/Util.java @@ -10,12 +10,18 @@ import android.content.Context; import android.content.ComponentName; import android.app.job.JobScheduler; import android.app.job.JobInfo; +import android.app.PendingIntent; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; import org.qtproject.qt5.android.QtNative; import androidnative.friendiqa.FriendiqaService; import androidnative.friendiqa.FriendiqaStopService; +import androidnative.friendiqa.FriendiqaActivity; +import androidnative.AndroidNativeActivity; import androidnative.AndroidNativeService; import android.content.Intent; import java.util.Map; +import org.qtproject.friendiqa.R; public class Util { @@ -24,6 +30,7 @@ public class Util { public static final String SET_TRANSLUCENT_STATUS_BAR = "androidnative.Util.setTranslucentStatusBar"; public static final String SET_FULL_SCREEN = "androidnative.Util.setFullScreen"; public static final String SET_SCHEDULE = "androidnative.Util.setSchedule"; + public static final String SET_NOTIFICATION = "androidnative.Util.setNotification"; static { @@ -35,6 +42,8 @@ public class Util { setFullScreen(message); } else if (type.equals(SET_SCHEDULE)) { setSchedule(message); + } else if (type.equals(SET_NOTIFICATION)) { + setNotification(message); } } }); @@ -98,11 +107,39 @@ public class Util { } + static void setNotification(Map message) { + //Log.d(TAG,"setNotification"); + Context context; + //Context appcontext; + context = QtNative.service().getApplicationContext(); + //appcontext = QtNative.activity().getApplicationContext(); + Intent intent = new Intent(context,FriendiqaActivity.class); + //intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + + final String textTitle = (String) message.get("title"); + final String textContent = (String) message.get("message"); + final int notificationId = (int) message.get("id"); + NotificationCompat.Builder builder = new NotificationCompat.Builder(context) + .setSmallIcon(R.drawable.friendiqanotification) + .setContentIntent(pendingIntent) + .setContentTitle(textTitle) + .setContentText(textContent) + .setStyle(new NotificationCompat.BigTextStyle() + .bigText(textContent)) + + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setAutoCancel(true); + + NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); + notificationManager.notify(notificationId, builder.build()); + } + static void setSchedule(Map message) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { return; } - Log.d(TAG,"Friendiqa schedule Androidnative service"); + //Log.d(TAG,"Friendiqa schedule Androidnative service"); final Integer value = (Integer) message.get("value"); //final Activity activity = QtNative.activity(); //final Service service = QtNative.service(); @@ -126,7 +163,7 @@ public class Util { jobScheduler.schedule(builder.build()); if (QtNative.service() != null){ - Log.d(TAG,"Schedule Stopping Friendiqa Androidnative service"); + //Log.d(TAG,"Schedule Stopping Friendiqa Androidnative service"); ComponentName componentStopper = new ComponentName(context, FriendiqaStopService.class); JobInfo.Builder stopbuilder = new JobInfo.Builder(1, componentStopper) .setMinimumLatency(50) diff --git a/source-android/application.qrc b/source-android/application.qrc index 9bb98a7..6f2b8d7 100644 --- a/source-android/application.qrc +++ b/source-android/application.qrc @@ -1,5 +1,6 @@ + qtquickcontrols2.conf qml/friendiqa.qml qml/newsqml/NewsTab.qml qml/newsqml/Newsitem.qml @@ -16,7 +17,7 @@ qml/photoqml/PhotogroupComponent.qml qml/photoqml/PhotoTab.qml qml/configqml/InfoBox.qml - qml/configqml/ConfigTab.qml + qml/configqml/ConfigPage.qml js/layout.js js/photoworker.js js/service.js @@ -27,6 +28,7 @@ images/fontawesome-webfont.ttf images/folder-blue.png qml/configqml/OSSettingsAndroid.qml + qml/genericqml/MButton.qml qml/configqml/OSSettingsLinux.qml qml/newsqml/SmileyDialog.qml js/smiley.js @@ -225,7 +227,9 @@ qml/newsqml/ContactPage.qml qml/newsqml/NewsLink.qml qml/configqml/RegisterPage.qml - qml/newsqml/NewsYplayer.qml - js/yplayer.html + qml/configqml/AccountPage.qml + qml/newsqml/NewsStack.qml + qml/configqml/SyncConfig.qml + qml/configqml/SyncComponent.qml diff --git a/source-android/common/alarm.h b/source-android/common/alarm.h index a3b3ede..bd66f04 100644 --- a/source-android/common/alarm.h +++ b/source-android/common/alarm.h @@ -51,6 +51,7 @@ signals: public slots: void setAlarm(int time); + void notify(QString title, QString text, int id); private: int m_time; diff --git a/source-android/common/alarmandroid.cpp b/source-android/common/alarmandroid.cpp index 49dc694..b1fcbfd 100644 --- a/source-android/common/alarmandroid.cpp +++ b/source-android/common/alarmandroid.cpp @@ -29,8 +29,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//#include -//#include #include "alarm.h" #include #include "AndroidNative/systemdispatcher.h" @@ -45,38 +43,20 @@ ALARM::ALARM(QObject *parent) : QObject(parent){} void ALARM::setAlarm(int interval) { - qDebug() << interval; QVariantMap message; message["value"] = interval; AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util"); AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message); - //AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message); -// auto activity = QtAndroid::androidActivity(); -// auto packageManager = activity.callObjectMethod("getPackageManager", -// "()Landroid/content/pm/PackageManager;"); - -// auto activityIntent = packageManager.callObjectMethod("getLaunchIntentForPackage", -// "(Ljava/lang/String;)Landroid/content/Intent;", -// activity.callObjectMethod("getPackageName", -// "()Ljava/lang/String;").object()); - -// auto pendingIntent = QAndroidJniObject::callStaticObjectMethod("android/app/PendingIntent", "getActivity", -// "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;", -// activity.object(), jint(0), activityIntent.object(), -// QAndroidJniObject::getStaticField("android/content/Intent", -// "FLAG_ACTIVITY_CLEAR_TOP")); - -// auto alarmManager = activity.callObjectMethod("getSystemService", -// "(Ljava/lang/String;)Ljava/lang/Object;", -// QAndroidJniObject::getStaticObjectField("android/content/Context", -// "ALARM_SERVICE", -// "Ljava/lang/String;").object()); - -// alarmManager.callMethod("set", -// "(IJLandroid/app/PendingIntent;)V", -// QAndroidJniObject::getStaticField("android/app/AlarmManager", "RTC"), -// jlong(QDateTime::currentMSecsSinceEpoch() + 100), pendingIntent.object()); - - + AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message); } +void ALARM::notify(QString title, QString text, int id) +{ + //qDebug() << "notify "<< title << text; + QVariantMap message; + message["title"] = title; + message["message"] = text; + message["id"] = id; + AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util"); + AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setNotification", message); +} diff --git a/source-android/common/alarmlinux.cpp b/source-android/common/alarmlinux.cpp new file mode 100644 index 0000000..c9b0a57 --- /dev/null +++ b/source-android/common/alarmlinux.cpp @@ -0,0 +1,73 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//#include +//#include +#include "alarm.h" +#include +#include +//#include "AndroidNative/systemdispatcher.h" + +ALARM *ALARM::instance() +{ + static ALARM alarm; + return &alarm; +} + +ALARM::ALARM(QObject *parent) : QObject(parent){} + +void ALARM::setAlarm(int interval) +{ + qDebug() << interval; + QVariantMap message; + message["value"] = interval; + // AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util"); + // AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message); + //AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message); +} + +void ALARM::notify(QString title, QString text, int id) +{ + qDebug() << title << text; + QVariantMap message; + message["title"] = title; + message["message"] = text; + QDBusConnection bus = QDBusConnection::sessionBus(); + QDBusInterface dbus_iface("org.freedesktop.Notifications", "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", bus); + QString appname="Friendiqa"; + uint v=12321; + if (dbus_iface.isValid()){ + + dbus_iface.call("Notify",appname,v,"",title,text,"","",5000); + } + // AndroidNative::SystemDispatcher::instance()->dispatch("Notifier.notify", message); +} diff --git a/source-android/common/friendiqa.cpp b/source-android/common/friendiqa.cpp index 361cf88..36077d2 100644 --- a/source-android/common/friendiqa.cpp +++ b/source-android/common/friendiqa.cpp @@ -32,17 +32,15 @@ #include #include #include -#include #include #include "xhr.h" #include "updatenews.h" #include "filesystem.h" #include "remoteauthasyncimageprovider.h" -#include "alarm.h" #include "AndroidNative/systemdispatcher.h" -#include "AndroidNative/environment.h" +//#include "AndroidNative/environment.h" //#include "AndroidNative/debug.h" -#include "AndroidNative/mediascannerconnection.h" +//#include "AndroidNative/mediascannerconnection.h" #ifdef Q_OS_ANDROID @@ -66,13 +64,11 @@ int main(int argc, char *argv[]) { UPDATENEWS* updatenews= UPDATENEWS::instance(); updatenews->setDatabase(); updatenews->login(); - updatenews->timeline(); + updatenews->startsync(); app.connect (updatenews,SIGNAL(quitapp()),&app,SLOT(quit())); - //QtAndroid::androidService().callMethod("stopSelf"); return app.exec(); } else{ - QApplication app(argc, argv); QQuickView view; QTranslator qtTranslator; @@ -87,8 +83,8 @@ int main(int argc, char *argv[]) { view.rootContext()->setContextProperty("filesystem", filesystem); ALARM* alarm = ALARM::instance(); view.rootContext()->setContextProperty("alarm", alarm); -// UPDATENEWS* updatenews = UPDATENEWS::instance(); -// view.rootContext()->setContextProperty("updatenews", updatenews); + UPDATENEWS* updatenews = UPDATENEWS::instance(); + view.rootContext()->setContextProperty("updatenews", updatenews); view.setSource(QUrl("qrc:/qml/friendiqa.qml")); view.show(); view.connect(view.rootContext()->engine(), SIGNAL(quit()), &app, SLOT(quit())); diff --git a/source-android/common/updatenews.cpp b/source-android/common/updatenews.cpp index 008f92e..b86a172 100644 --- a/source-android/common/updatenews.cpp +++ b/source-android/common/updatenews.cpp @@ -100,130 +100,304 @@ void UPDATENEWS::login() m_imagedir=query.value(3).toString(); xhr.setImagedir(m_imagedir); QString isActive=query.value(7).toString(); - m_updateInterval=query.value(5).toInt(); - m_api="/api/statuses/friends_timeline"; - xhr.setApi(m_api); + } + //m_updateInterval=query.value(5).toInt(); + + + QSqlQuery syncquery("SELECT * FROM globaloptions",m_db); +// QSqlQuery delquery("DELETE FROM globaloptions WHERE k='sync_interval'",m_db); +// delquery.exec(); + m_updateInterval=0; + syncindex=0; + synclist.clear(); + //QSqlQuery syncquery("SELECT * FROM globaloptions WHERE k like 'sync_%' AND v=1",m_db); + while (syncquery.next()){ + if (syncquery.value(0).toString()=="syncinterval"){ + m_updateInterval=syncquery.value(1).toInt(); + } + if (syncquery.value(0).toString().left(5)=="sync_" && syncquery.value(1).toInt()==1){ + synclist.append(syncquery.value(0).toString()); + //qDebug() << " sync " << syncquery.value(0).toString() << " " <error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply)); - if(m_updateInterval!=0){ - m_db.close(); - m_db.removeDatabase(m_db.connectionName()); - emit quitapp(); - alarm.setAlarm(m_updateInterval); - }; + xhr.setParam("count","50"); + xhr.get(); + QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString))); + QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int))); + QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int))); +} + +void UPDATENEWS::directmessages() +{ + m_api="/api/direct_messages/all"; + xhr.clearParams(); + xhr.setUrl(m_url); + xhr.setApi(m_api); + QSqlQuery query("SELECT status_id FROM news WHERE messagetype=1 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db); + if (query.isActive() && query.isSelect()){ + if (query.first()){ + QString lastid=query.value(0).toString(); + xhr.setParam("since_id",lastid); + } + } + xhr.get(); + QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString))); + QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int))); + QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int))); +} + +void UPDATENEWS::notifications() +{ + m_api="/api/friendica/notifications"; + xhr.clearParams(); + xhr.setUrl(m_url); + xhr.setApi(m_api); + xhr.get(); + QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString))); + QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int))); + QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int))); +} + + +void UPDATENEWS::store(QByteArray serverreply,QString apiname) +{ if (apiname!=m_api || xhr.downloadtype()!=""){} else { + QJsonDocument news; + //qDebug()< newcontacts=findNewContacts(news); + //qDebug()<< "new contacts count " << newcontacts.size(); + if (newcontacts.size()>0){ + updateContacts(newcontacts); + startImagedownload(); + + } else { + if(m_updateInterval!=0){ + syncindex+=1; + startsync(); + } + } + } + else { + qDebug()<< "Friendiqa updatenews error " << serverreply; + emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply)); + syncindex+=1; + startsync(); + } } - QList newcontacts=findNewContacts(news); - updateContacts(newcontacts); - startImagedownload(); - connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int))); } + + void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index){ if (downloadtype=="contactlist"){ QSqlQuery testquery("SELECT profile_image FROM contacts WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db); - testquery.exec(); + testquery.first(); //qDebug()<< "update imageurl for " < UPDATENEWS::findNewContacts(QJsonDocument news){ QSqlQuery query("SELECT profile_image_url FROM contacts",m_db); QList imageurls; @@ -231,46 +405,46 @@ QList UPDATENEWS::findNewContacts(QJsonDocument news){ imageurls.append(query.value(0).toString()); } QList newcontacts; - qDebug()<<"updatenews findcontacts count "< contacts){ query.bindValue(2, contact["screen_name"]); query.bindValue(3, contact["location"]); query.bindValue(4, currentTime); - query.bindValue(5, contact["profile_image_url"]); - if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());}; + query.bindValue(5, contact["profile_image_url"].toString().section('?',0,0)); + if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());} query.bindValue(7,contact["protected"].toBool()); query.bindValue(8,contact["followers_count"].toInt()); query.bindValue(9,contact["friends_count"].toInt()); @@ -317,7 +491,7 @@ void UPDATENEWS::updateContacts(QList contacts){ query.bindValue(21,contact["network"]); qint64 timestamp=0; QString timestamphelper=contact["profile_image_url"].toString(); - try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}; + try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){} query.bindValue(22,timestamp); } @@ -334,8 +508,8 @@ void UPDATENEWS::updateContacts(QList contacts){ query.bindValue(3, contact["screen_name"]); query.bindValue(4, contact["location"]); query.bindValue(5, currentTime); - query.bindValue(6, contact["profile_image_url"]); - if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());}; + query.bindValue(6, contact["profile_image_url"].toString().section('?',0,0)); + if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());} query.bindValue(8,"none"); query.bindValue(9, contact["url"].toString()); query.bindValue(10,contact["protected"].toBool()); @@ -358,19 +532,12 @@ void UPDATENEWS::updateContacts(QList contacts){ query.bindValue(25, 0); qint64 timestamp=0; QString timestamphelper=contact["profile_image_url"].toString(); - try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}; + try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){} query.bindValue(26,timestamp); } query.exec() ; } - emit this->success(m_api); - if ((contacts.count()==0) && (m_updateInterval!=0)){ - m_db.close(); - m_db.removeDatabase(m_db.connectionName()); - emit quitapp(); - alarm.setAlarm(m_updateInterval); - }; } QString UPDATENEWS::url() const @@ -380,6 +547,7 @@ QString UPDATENEWS::url() const void UPDATENEWS::startImagedownload() { + //qDebug() << "start image download"; xhr.setDownloadtype("contactlist"); xhr.setFilelist(newcontactimagelinks); xhr.setContactlist(newcontactnames); @@ -389,11 +557,12 @@ void UPDATENEWS::startImagedownload() void UPDATENEWS::showError(QString data, QString url,QString api, int code ) { + qDebug() << "showerror " << api << " data " << data; emit this->error(api,data); - if(m_updateInterval!=0){ - m_db.close(); - m_db.removeDatabase(m_db.connectionName()); - emit quitapp(); - alarm.setAlarm(m_updateInterval); - }; + if (api!=m_api || xhr.downloadtype()!=""){} else{ + if(m_updateInterval!=0){ + syncindex+=1; + startsync(); + } + } } diff --git a/source-android/common/updatenews.h b/source-android/common/updatenews.h index 1acc52c..74acf20 100644 --- a/source-android/common/updatenews.h +++ b/source-android/common/updatenews.h @@ -37,7 +37,7 @@ #include #include "xhr.h" #include "alarm.h" -#include "AndroidNative/systemdispatcher.h" +//#include "AndroidNative/systemdispatcher.h" class UPDATENEWS : public QObject { @@ -64,6 +64,10 @@ public slots: void setDatabase(); void login(); void timeline(); + void replies(); + void startsync(); + void directmessages(); + void notifications(); //void startservice(QString type,QVariantMap map); void startImagedownload(); void updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index); @@ -76,8 +80,12 @@ private: QString m_imagedir; QString m_login; QString username; + int syncindex; QSqlDatabase m_db; + QList synclist; + QList notifylist; QList findNewContacts(QJsonDocument news); + QJsonObject findNotificationContact(QString imagelink); int m_updateInterval; //void timeline(); //void store(QByteArray serverreply,QString apiname); diff --git a/source-android/common/xhr.cpp b/source-android/common/xhr.cpp index 7df4deb..fd29d29 100644 --- a/source-android/common/xhr.cpp +++ b/source-android/common/xhr.cpp @@ -154,7 +154,7 @@ QString XHR::downloadtype() const return m_downloadtype; } -QString XHR::networktype() const +QString XHR::networktype() { return nc.bearerTypeFamily() + nc.bearerTypeName(); } @@ -184,7 +184,6 @@ void XHR::download() request.setRawHeader("Authorization", headerData.toLocal8Bit()); } request.setUrl(requrl); - //qDebug() << requrl; reply = manager.get(request); reply->ignoreSslErrors(); connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead); @@ -202,10 +201,11 @@ void XHR::get() while(i.hasNext()) { i.next(); query.addQueryItem(i.key(), i.value()); + //qDebug()<error(m_downloadtype,m_url,m_api,1);} else if (m_downloadtype=="picturelist") { diff --git a/source-android/common/xhr.h b/source-android/common/xhr.h index ad50a60..9141a84 100644 --- a/source-android/common/xhr.h +++ b/source-android/common/xhr.h @@ -49,7 +49,7 @@ class XHR : public QObject Q_PROPERTY(QList contactlist READ contactlist WRITE setContactlist NOTIFY contactlistChanged) Q_PROPERTY(QList filelist READ filelist WRITE setFilelist NOTIFY filelistChanged) Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged) - Q_PROPERTY(QString networktype READ networktype NOTIFY networktypeChanged) + Q_PROPERTY(QString networktype READ networktype() NOTIFY networktypeChanged) public: @@ -65,7 +65,7 @@ public: QList filelist() const; QString imagedir() const; QString downloadtype() const; - QString networktype() const; + QString networktype(); signals: void urlChanged(); @@ -98,6 +98,7 @@ public slots: void get(); void getlist(); void download(); + // void networktype(); private slots: diff --git a/source-android/js/helper.js b/source-android/js/helper.js index 1a22e3d..3bcb523 100644 --- a/source-android/js/helper.js +++ b/source-android/js/helper.js @@ -125,10 +125,11 @@ function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) { function readData(database,table,username,callback,filter,filtervalue, sort) { // reads and applies data from DB if (filter){ - var where = " AND "+ filter +" = '" + filtervalue+"'"; + if (username){var where = " AND "+ filter +" = '" + filtervalue+"'";} else{ + var where = " WHERE "+ filter +" = '" + filtervalue+"'";} } else { var where="";} if (username){ - var user = ' where username= "'+ username +'"'; + var user = ' where username= "'+ username +'"'; } else { var user='';} if (sort){ @@ -138,7 +139,7 @@ function readData(database,table,username,callback,filter,filtervalue, sort) { / if(!db) { return; } db.transaction( function(tx) { //print('select * from '+table+user+where+sortparam); - var rsArray=[]; + var rsArray=[]; var rs = tx.executeSql('select * from '+table+user+where+sortparam); for(var i = 0; i < rs.rows.length; i++) { rsArray.push(rs.rows.item(i)) @@ -165,7 +166,7 @@ var where = " AND "+ filter +" = '" + filtervalue+"'"; }); } -function showMessage(header,message,rootwindow){print(message); +function showMessage(header,message,rootwindow){//print(message); var cleanmessage=message.replace(/"/g,"-"); if(cleanmessage.length>200){cleanmessage=cleanmessage.slice(0,200)+'...'} var messageString='import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:"'+header+'";standardButtons: StandardButton.Ok; text:" '+cleanmessage+'"}'; diff --git a/source-android/js/layout.js b/source-android/js/layout.js index bdc27b3..6431819 100644 --- a/source-android/js/layout.js +++ b/source-android/js/layout.js @@ -36,7 +36,7 @@ function showFriends(db) { } function displayFriends(obj){ for (var i=0; i0'); // check for friends - var contactlist=[]; - for (var i=0;i0'+filtertext); + //print('SELECT * from contacts WHERE username="'+login.username+'"'+filtertext); + var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'+filtertext); + // check for friends + var contactlist=[]; + for (var i=0;i0){ maxnews=maxnewsrs.rows.item(0).v}; var newscountrs = tx.executeSql('SELECT COUNT(*) from news'); var newscount = newscountrs.rows.item(0)["COUNT(*)"];//print("newscount "+newscount) if (newscount>maxnews){ @@ -384,6 +384,7 @@ function updateContactInDB(login,database,isFriend,contact){// for newstab and f } function processNews(api,data){ + //print(api + data); try{var newslist=JSON.parse(data)} catch(e){newsBusy.running=false;}; if (data==""){} else if (typeof(newslist)=='undefined'){ @@ -393,6 +394,7 @@ function processNews(api,data){ Helperjs.showMessage(qsTr("JSON status Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root) } else if (!(Array.isArray(newslist))){ + //print("processNews not array"+newslist+JSON.stringify(newslist)); replytimer.restart() } else { @@ -407,6 +409,8 @@ function processNews(api,data){ newslist[n].uid=newslist[n].sender.id; newslist[n].statusnet_conversation_id=newslist[n].friendica_parent_uri; newslist[n].user=cleanUser(newslist[n].sender); + newslist[n].friendica_owner=newslist[n].user; + newslist[n].friendica_author=newslist[n].user; newslist[n].statusnet_html=newslist[n].text; }} else if (api=="/api/friendica/notifications"){ @@ -418,6 +422,8 @@ function processNews(api,data){ newslist[n].user={"profile_image_url": newslist[n].photo,"name": newslist[n].name," url":newslist[n].url, "created_at":newslist[n].date}; newslist[n].user=cleanUser(newslist[n].user); } + newslist[n].friendica_author=newslist[n].user; + newslist[n].friendica_owner=newslist[n].user; newslist[n].statusnet_html=newslist[n].msg_html; newslist[n].text=newslist[n].msg; } @@ -427,8 +433,9 @@ function processNews(api,data){ var commentCount=[]; for (var n in newslist){ newslist[n].created_at=Date.parse(Newsjs.cleanDate(newslist[n].created_at)); - newslist[n].messagetype=0; - newslist[n].user=cleanUser(newslist[n].user) + if (api=="/api/statuses/replies"){newslist[n].messagetype=3}else{newslist[n].messagetype=0;} + newslist[n].friendica_author=cleanUser(newslist[n].friendica_author); + newslist[n].user=cleanUser(newslist[n].user); if(newslist[n].in_reply_to_user_id){newslist[n].reply_user=Newsjs.objFromArray(allcontacts,"id",newslist[n].in_reply_to_user_id)} //print (JSON.stringify(newslist[n].user)) if(newslist[n].hasOwnProperty('friendica_activities')){ @@ -448,8 +455,8 @@ function processNews(api,data){ newslist[n].friendica_activities.attendmaybe[r]=cleanUser(newslist[n].friendica_activities.attendmaybe[r]); } } - if(!(newslist[n].hasOwnProperty('friendica_owner'))){ - newslist[n].friendica_owner=newslist[n].user + if(!(newslist[n].hasOwnProperty('friendica_author'))){ + newslist[n].friendica_author=newslist[n].user } var conversationindex=conversationIds.indexOf(newslist[n].statusnet_conversation_id); @@ -488,11 +495,13 @@ function processNews(api,data){ else if (api=="/api/statuses/user_timeline"){ newstab.contactposts=newslist } - else if (newstab.newstabstatus==="Conversations"){ - showNews(chatlist);root.news=newslist} - else {showNews(newslist);root.news=newslist}; + else if ((api!="/api/direct_messages/all")&&(api!="/api/friendica/notifications")&&(newstab.newstabstatus==="Conversations")){ + showNews(chatlist);root.news=newslist + } + else { + showNews(newslist);root.news=newslist}; - var newstabarray=["Conversations","Favorites","Timeline","DirectMessage"]; + var newstabarray=["Conversations","Favorites","Timeline","DirectMessage","Replies"]; if (newstabarray.indexOf(newstab.newstabstatus)>-1){contacttimer.start()} } @@ -509,26 +518,28 @@ function cleanUser(user){ } function updateView(viewtype){ - newsBusy.running=true; + //messageSend.state=""; + //newsBusy.running=true; //downloadNotice.text="xhr start "+Date.now() switch(viewtype){ case "Conversations": - var lastnews=Newsjs.getLastNews(login,db); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/friends_timeline"); - xhr.clearParams(); - xhr.setParam("since_id",lastnews); - xhr.setParam("count",50) + Newsjs.getLastNews(login,db,function(lastnews){ + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.setUrl(login.server); + xhr.setApi("/api/statuses/friends_timeline"); + xhr.clearParams(); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50)}); break; case "Timeline": - var lastnews=Newsjs.getLastNews(login,db); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/friends_timeline"); - xhr.clearParams(); - xhr.setParam("since_id",lastnews); - xhr.setParam("count",50) + var lastnews=Newsjs.getLastNews(login,db,function(lastnews){ + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.setUrl(login.server); + xhr.setApi("/api/statuses/friends_timeline"); + xhr.clearParams(); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50) + }); break; case "Search": xhr.setLogin(login.username+":"+Qt.atob(login.password)); @@ -566,14 +577,15 @@ function updateView(viewtype){ xhr.clearParams(); break; default: - var lastnews=Newsjs.getLastNews(login,db); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/friends_timeline"); - xhr.clearParams(); - xhr.setParam("since_id",lastnews); - xhr.setParam("count",50) - newstab.newstabstatus="Conversations"; + Newsjs.getLastNews(login,db,function(lastnews){ + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.setUrl(login.server); + xhr.setApi("/api/statuses/friends_timeline"); + xhr.clearParams(); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50) + newstab.newstabstatus="Conversations"; + }); } xhr.get(); diff --git a/source-android/qml/calendarqml/CalendarDay.qml b/source-android/qml/calendarqml/CalendarDay.qml index cff48f2..cfc1488 100644 --- a/source-android/qml/calendarqml/CalendarDay.qml +++ b/source-android/qml/calendarqml/CalendarDay.qml @@ -29,8 +29,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.0 -import QtQuick.Controls 1.4 +import QtQuick 2.11 +//import QtQuick.Controls 2.4 Item { id: calendarDay diff --git a/source-android/qml/calendarqml/CalendarTab.qml b/source-android/qml/calendarqml/CalendarTab.qml index 919745f..10b4e78 100644 --- a/source-android/qml/calendarqml/CalendarTab.qml +++ b/source-android/qml/calendarqml/CalendarTab.qml @@ -30,10 +30,10 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 2.3 +import QtQuick.Controls 2.4 import QtQml 2.2 import Qt.labs.calendar 1.0 -import QtQuick.Controls 1.2 as Oldcontrol +//import QtQuick.Controls 1.2 as Oldcontrol import QtQuick.Layouts 1.3 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs @@ -42,9 +42,10 @@ import "qrc:/qml/genericqml" Rectangle { id:calendarrectangle - y:1 - width:root.width-mm - height:root.height-5*mm +// y:1 +// width:root.width-mm +// height:root.height-5*mm + anchors.fill: parent color: '#fff' property date currentTime: new Date() property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000 @@ -83,30 +84,35 @@ Rectangle { } - BlueButton{ + MButton{ id: updateEvents anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right:calendartabstatusButton.left anchors.rightMargin:mm + height: 6*mm + width: 8*mm text:"\uf021" onClicked: { - Service.getEvents(db,login, calendartab,function(){ showEvents("") })}} - BlueButton{ + MButton{ id: calendartabstatusButton anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right: parent.right anchors.rightMargin:2*mm + height: 6*mm + width: Math.max(10*mm,implicitWidth) text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus - Oldcontrol.Menu { + Menu { id:calendartabmenu - Oldcontrol.MenuItem { + width: 40*mm + MenuItem { text: qsTr("Own Calendar") + font.pixelSize: 3*mm onTriggered: { calendartab.calendartabstatus="Events"; // calendartabstatusButton.text=qsTr("own Calendar"); @@ -146,6 +152,7 @@ Rectangle { DayOfWeekRow{ locale: monthgrid.locale Layout.fillWidth: true + font.pixelSize: 3*mm } MonthGrid { diff --git a/source-android/qml/calendarqml/EventList.qml b/source-android/qml/calendarqml/EventList.qml index 8a98bef..5028ae7 100644 --- a/source-android/qml/calendarqml/EventList.qml +++ b/source-android/qml/calendarqml/EventList.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -45,12 +45,14 @@ Rectangle{ y:mm property var daylist:[] - BlueButton{ + MButton{ id:closeButton anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm + height: 6*mm + width: 8*mm text: "\uf057" onClicked:{eventList.destroy()} } diff --git a/source-android/qml/configqml/AccountPage.qml b/source-android/qml/configqml/AccountPage.qml new file mode 100644 index 0000000..f593ed1 --- /dev/null +++ b/source-android/qml/configqml/AccountPage.qml @@ -0,0 +1,463 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick 2.7 +import QtQuick.Dialogs 1.2 +import QtQuick.Controls 2.4 + +import "qrc:/js/service.js" as Service +import "qrc:/js/layout.js" as Layoutjs +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/configqml" +import "qrc:/qml/genericqml" + +Page{ + id:accountPage + width: root.width + height: root.height + property var users:[] + property var userdata: ({}) + + function setServericon(server){ + try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",accountPage, function (obj){ + var serverdata = JSON.parse(obj); + servericon.visible=true; + servericon.source=serverdata.site.logo})} catch(e){print(e)} + } + + Button{ + id:userButton + height: 8*mm + text:qsTr("User") + font.pixelSize: 3*mm + x: mm + y: mm + width: root.width/2 + onClicked:{ + var useritems=""; + for (var i=0;i-1){ + Helperjs.showMessage(qsTr("Error"),qsTr("Nicknames containing @ symbol currently not supported"),accountPage) + } + } + } + } + Button { + x: root.width-9*mm; y: 23.5*mm; width:5*mm; height:5*mm + text: "\uf234" + font.pixelSize: 3*mm + onClicked: { + configStack.push({item:"qrc:/qml/configqml/RegisterPage.qml",properties:{url:servername.text+"/register?nickname="+username.getText(0,username.length)}}) + } + } + + Rectangle{ + color: "light grey" + x: 4*mm; y: 33.5*mm; width: root.width-6*mm; height: 5*mm; + TextInput { + id: password + anchors.fill: parent + font.pixelSize:3*mm + selectByMouse: true + echoMode: TextInput.PasswordEchoOnEdit + } + } + + Rectangle{color: "light grey"; x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm;} + Flickable { + id: imagestoreFlickable + x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm; + clip: true + TextInput { + id: imagestore + width: imagestoreFlickable.width + height: imagestoreFlickable.height + font.pixelSize:3*mm + wrapMode: TextEdit.NoWrap + onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,imagestoreFlickable) + } + } + + FileDialog { + id: imagestoreDialog + title: "Please choose a directory" + folder: shortcuts.pictures + selectFolder: true + onAccepted: { + var imagestoreString=imagestoreDialog.folder.toString(); + imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/" + imagestore.text=imagestoreString + } + } + + Button { + x: root.width-9*mm; y: 43.5*mm; width: 5*mm; height: 5*mm; + text: "..." + font.pixelSize: 3*mm + onClicked: + {imagestoreDialog.open()} + } + + +// Slider{ id: maxNews +// x:19*mm; y: 53.5*mm;width: root.width/2;height:5*mm +// from: 0;to:2000; stepSize: 100 +// } + + +// Rectangle{color: "light grey"; x: 4*mm; y: 53.5*mm; width: 9*mm; height: 5*mm; +// TextEdit{id:maxNewsText; +// anchors.fill: parent +// font.pixelSize:3*mm +// verticalAlignment:TextEdit.AlignRight +// text:maxNews.value +// focus: true +// selectByMouse: true +// } +// } + + Rectangle{ + x: 4*mm; y: 53.5*mm; width: newsTypeField.contentWidth+2*mm; height: 5*mm; + color:"light grey" + Text{ + id: newsTypeField + anchors.fill: parent + font.pixelSize:3*mm + text:"Conversations" + } + MouseArea{ + anchors.fill:parent + onClicked:newstypemenu.popup() + } + } + + BusyIndicator{ + id: accountBusy + anchors.horizontalCenter: parent.horizontalCenter + y: 63.5*mm + width:10*mm + height: 10*mm + running: false + } +// CheckBox{ +// id:showwebsiteCheckbox +// x:35*mm;y:80*mm +// onClicked:{ +// if (checked==true){ +// Service.updateglobaloptions(root.db,"showWebsiteForLinks","true") +// root.globaloptions.showWebsiteForLinks="true" +// } +// else { +// Service.updateglobaloptions(root.db,"showWebsiteForLinks","false") +// root.globaloptions.showWebsiteForLinks="false" +// } +// } +// } + + Button { + x: 4*mm; y: 63.5*mm + height: 8*mm + text: qsTr("Confirm") + font.pixelSize: 3*mm + onClicked:{ + accountBusy.running=true; + var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text, maxnews:"",interval: "",newsViewType:newsTypeField.text}; + var errormessage=""; + if (servername.text==""){errormessage=qsTr("No server given! ")} + else if (username.text==""){errormessage+=qsTr("No nickname given! ")} + else if (password.text=="") {errormessage+=qsTr("No password given! ")} + else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")} + //else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")} + else {errormessage=""} + if (errormessage=="") { + Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){ + accountBusy.running=false; + var credentials=JSON.parse(obj); + if (credentials.hasOwnProperty('status')){ + Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root) + } + else{ + filesystem.Directory=userconfig.imagestore; + filesystem.makeDir("contacts"); + filesystem.makeDir("albums"); + Service.storeConfig(db,userconfig); + Service.readConfig(db,function(userconfig){ + Helperjs.readData(db,"config","",function(storedUsers){ + storedUsers.sort(function(obj1, obj2) { + return obj1.isActive - obj2.isActive; + }); + accountPage.users=storedUsers}); + //reset values + root.login=userconfig; + root.news=[]; + },"isActive",0); + + //Service.requestProfile(userconfig,db,root,function(nc){root.newContacts=nc}); + Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.name+"\nScreen Name: "+credentials.screen_name,root) + } + }); + + } + else {Helperjs.showMessage(qsTr("Error"), errormessage,root)} + }} + + + + Button { + x: parent.width/2+2*mm; y: mm; width: 5*mm; height: 8*mm; + text: "-" + font.pixelSize: 3*mm + onClicked:{ + var userconfig={server: servername.text, username: username.text, password: Qt.btoa(password.text)}; + Service.deleteConfig(db,userconfig,function(){ + filesystem.Directory=imagestore.text+"contacts"; + filesystem.rmDir(); + filesystem.Directory=imagestore.text+"albums"; + filesystem.rmDir(); + servername.text="https://"; + servericon.visible=false; + servericon.source=""; + username.text=""; + password.text=""; + imagestore.text=""; + //maxNews.value=0; + newsTypeField.text="Conversations"; + //messageIntervalSlider.value=30; + userButton.text=qsTr("User"); + Helperjs.readData(db,"config","",function(storedUsers){ + storedUsers.sort(function(obj1, obj2) { + return obj1.isActive - obj2.isActive; + }) + accountPage.users=storedUsers;}) + }) + }} + + Button { + x: parent.width/2+8*mm; y: mm; width: 5*mm; height: 8*mm; + text: "+" + font.pixelSize: 3*mm + onClicked:{ + servername.text="https://" + servericon.visible=false; + servericon.source=""; + username.text="" + password.text="" + imagestore.text="" + //maxNews.value=0 + newsTypeField.text="Conversations" + //messageIntervalSlider.value=30 + userButton.text=qsTr("User") + } + } + + Button { + x: parent.width/2+14*mm; y: mm; width: 5*mm; height: 8*mm; + text: "?" + font.pixelSize: 3*mm + onClicked:{ + root.push("qrc:/qml/configqml/InfoBox.qml"); + } + } + Button{ + id:closeButton + height: 8*mm + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{root.pop()} + } + Menu { + id:newstypemenu + MenuItem { + font.pixelSize: 3*mm + text: qsTr("Timeline") + onTriggered: {newsTypeField.text="Timeline"} + } + MenuItem { + font.pixelSize: 3*mm + text: qsTr("Conversations") + onTriggered: {newsTypeField.text="Conversations"} + } + } + + Component.onCompleted: { + try{Helperjs.readData(db,"config","",function(storedUsers){ + storedUsers.sort(function(obj1, obj2) { + return obj1.isActive - obj2.isActive; + }) + accountPage.users=storedUsers; + Service.readConfig(db,function(obj){ + userButton.text=obj.username; + servername.text=obj.server; + accountPage.setServericon(obj.server); + username.text= obj.username; + password.text=Qt.atob(obj.password); + imagestore.text=obj.imagestore; + //maxNews.value=obj.maxnews; + newsTypeField.text=obj.newsViewType; + //messageIntervalSlider.value=obj.timerInterval; + if( obj.isActive==0){userButton.font.bold='true'} else {userButton.font.bold='false'} + },"isActive",0) + }) +// Service.readGlobaloptions(db,function(go){ +// if (root.globaloptions.showWebsiteForLinks!="false"){showwebsiteCheckbox.checked=true} +// }) + + } + catch (e){print(e) +// Helperjs.friendicaWebRequest("https://dir.friendica.social/servers/surprise",accountPage,function(html){ +// print(html); +// var bpos=html.indexOf("base "); +// var baseurl=html.substring(html.indexOf("http",bpos),html.indexOf('"',html.indexOf("http",bpos))); +// servername.text=baseurl +// }) + } + } +} diff --git a/source-android/qml/configqml/ConfigPage.qml b/source-android/qml/configqml/ConfigPage.qml new file mode 100644 index 0000000..7593d81 --- /dev/null +++ b/source-android/qml/configqml/ConfigPage.qml @@ -0,0 +1,227 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick 2.11 +import QtQuick.Dialogs 1.2 +import QtQuick.Controls 2.4 + +import "qrc:/js/service.js" as Service +//import "qrc:/js/layout.js" as Layoutjs +//import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/configqml" +import "qrc:/qml/genericqml" + +Page{ + //anchors.fill: parent + width:root.width + height:root.height + //contentHeight: configBackground.height + //boundsBehavior: Flickable.StopAtBounds + +// Rectangle{ +// id:configBackground +// color: "white" +// anchors.fill: parent +// width:parent.width +// height:Math.max(90*mm,root.height-12*mm) +// property var users:[] +// property bool registeredUser: true +// property var userdata: ({}) + +// Text { +// text: qsTr("Image dir.") +// //text: qsTr("Max. News") +// font.pixelSize:3*mm +// x: 4*mm; y: 10*mm +// } + Text { + text: qsTr("Max. News") + //text: qsTr("News as") + font.pixelSize:3*mm + x: 4*mm; y:10*mm + } + + +// Text { +// text: qsTr("Show Website") +// x: 4*mm; y: 40*mm; width: 20*mm +// } + + +// Rectangle{color: "light grey"; x: 4*mm; y: 13.5*mm; width: root.width-14*mm; height: 5*mm;} +// Flickable { +// id: imagestoreFlickable +// x: 4*mm; y: 13.5*mm; width: root.width-14*mm; height: 5*mm; +// clip: true +// TextInput { +// id: imagestore +// width: imagestoreFlickable.width +// height: imagestoreFlickable.height +// font.pixelSize:3*mm +// wrapMode: TextEdit.NoWrap +// onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,imagestoreFlickable) +// } +// } + +// FileDialog { +// id: imagestoreDialog +// title: "Please choose a directory" +// folder: shortcuts.pictures +// selectFolder: true +// onAccepted: { +// var imagestoreString=imagestoreDialog.folder.toString(); +// imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/" +// imagestore.text=imagestoreString +// } +// } + +// Button { +// x: root.width-9*mm; y: 13.5*mm; width: 7*mm; height: 8*mm; +// text: "..." +// onClicked: +// {imagestoreDialog.open()} +// } + + + Slider{ id: maxNews + x:19*mm; y: 13.5*mm;width: root.width/2;height:5*mm + from: 0;to:2000; stepSize: 100 + value: root.globaloptions.hasOwnProperty("max_news")?root.globaloptions.max_news:1000 + } + + + Rectangle{color: "light grey"; x: 4*mm; y: 13.5*mm; width: 9*mm; height: 5*mm; + radius: 0.5*mm + TextEdit{id:maxNewsText; + anchors.fill: parent + font.pixelSize:3*mm + verticalAlignment:TextEdit.AlignRight + text:maxNews.value + focus: true + selectByMouse: true + onTextChanged: { + Service.updateglobaloptions(root.db,"max_news",text); + } + } + } + + Rectangle{ + x: 4*mm; y:23.5*mm; width: parent.width - 14*mm; height: 5*mm; + color:"light grey" + radius: 0.5*mm + Text{ + anchors.fill: parent + font.pixelSize:3*mm + text:qsTr("Sync") + } + MouseArea{ + anchors.fill:parent + onClicked:root.push("qrc:qml/configqml/SyncConfig.qml"); + } + } +// Slider{ id: messageIntervalSlider +// x:22*mm; y: 73.5*mm;width: root.width/2;height:5*mm +// from: 0;to:120; stepSize: 15 +// } +// Rectangle{ +// x: 4*mm; y: 73.5*mm; width: 9*mm; height: 5*mm; +// TextEdit{ +// id: messageIntervalField +// anchors.fill: parent +// font.pixelSize:3*mm +// verticalAlignment:TextEdit.AlignRight +// text:messageIntervalSlider.value +// focus: true +// selectByMouse: true +// } +// } +// Text{x: 14*mm; y: 73.5*mm; width: 5*mm; height: 5*mm; +// font.pixelSize:3*mm +// text:qsTr("Min.") +// } + +// CheckBox{ +// id:showwebsiteCheckbox +// x:35*mm;y:80*mm +// onClicked:{ +// if (checked==true){ +// Service.updateglobaloptions(root.db,"showWebsiteForLinks","true") +// root.globaloptions.showWebsiteForLinks="true" +// } +// else { +// Service.updateglobaloptions(root.db,"showWebsiteForLinks","false") +// root.globaloptions.showWebsiteForLinks="false" +// } +// } +// } + + MButton { + anchors.right: closeButton.left; anchors.rightMargin: mm; + anchors.top: parent.top + anchors.topMargin: 1*mm + width: 8*mm; height: 6*mm; + text: "?" + font.pixelSize: 3*mm + onClicked:{ + root.push("qrc:/qml/configqml/InfoBox.qml"); + } + } + MButton{ + id:closeButton + height: 6*mm + width :8*mm + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{root.pop()} + } +// Menu { +// id:newstypemenu +// MenuItem { +// text: qsTr("Timeline") +// onTriggered: {newsTypeField.text="Timeline"} +// } +// MenuItem { +// text: qsTr("Conversations") +// onTriggered: {newsTypeField.text="Conversations"} +// } +// } + +// Component.onCompleted: { +// Service.readGlobaloptions(db,function(go){ +// if(go.hasOwnProperty("max_news")){maxNews.value=go.max_news}else{maxNews.value=1000} +// //if (root.globaloptions.showWebsiteForLinks!="false"){showwebsiteCheckbox.checked=true} +// }) +// } +} diff --git a/source-android/qml/configqml/InfoBox.qml b/source-android/qml/configqml/InfoBox.qml index 7cf6306..31a9c57 100644 --- a/source-android/qml/configqml/InfoBox.qml +++ b/source-android/qml/configqml/InfoBox.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import "qrc:/qml/genericqml" Rectangle{ @@ -41,11 +41,12 @@ Rectangle{ anchors.top:closeButton.bottom anchors.topMargin: mm textFormat: Text.RichText - width: parent.width + width: root.width-mm wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: "Friendiqa v0.4
Licensed under GPL 3 with the exception of OpenSSL
"+ + text: "Friendiqa v0.5
Licensed under GPL 3 with the exception of OpenSSL
"+ "Profile https://freunde.ma-nic.de/profile/friendiqa
"+ "Sourcecode: https://git.friendi.ca/LubuWest/Friendiqa
"+ + "Privacy Policy: http://git.friendi.ca/lubuwest/Friendiqa/src/branch/master/PrivacyPolicy.md
"+ "Most of C++ code by Fabio
"+ "QML and Javascript code by Marco
"+ "Qt Framework www.qt.io
"+ @@ -56,13 +57,16 @@ Rectangle{ onLinkActivated:{ Qt.openUrlExternally(link)} } - BlueButton{ - id:closeButton - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - onClicked:{configStack.pop()} + Button{ + id:closeButton + height: 6*mm + width: 8*mm + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{root.pop()} } } diff --git a/source-android/qml/configqml/OSSettingsLinux.qml b/source-android/qml/configqml/OSSettingsLinux.qml index 37fc606..f2bd73c 100644 --- a/source-android/qml/configqml/OSSettingsLinux.qml +++ b/source-android/qml/configqml/OSSettingsLinux.qml @@ -34,7 +34,7 @@ QtObject{ property real appWidth: 500 property real appHeight: 500 property int backKey: Qt.Key_Escape - property string osType: "Android" + property string osType: "Linux" //property string attachImageDir:filesystem.homePath+"/Pictures/" property string imagePickQml: "ImagePickerLinux" } diff --git a/source-android/qml/configqml/RegisterPage.qml b/source-android/qml/configqml/RegisterPage.qml index 299a086..35ab326 100644 --- a/source-android/qml/configqml/RegisterPage.qml +++ b/source-android/qml/configqml/RegisterPage.qml @@ -30,6 +30,7 @@ // along with this program. If not, see . import QtQuick 2.9 +import QtQuick.Controls 2.5 import QtWebView 1.1 import "qrc:/qml/genericqml" @@ -45,17 +46,21 @@ Rectangle{ width:parent.width y:7*mm MouseArea {anchors.fill:parent; - onClicked:{print(url)} + onClicked:{ + //print(url) + } } - onLoadingChanged: print(loadProgress) + //onLoadingChanged: print(loadProgress) } - BlueButton{ + Button{ id:closeButton + height:8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm text: "\uf057" + font.pixelSize: 3*mm onClicked:{configStack.pop()} } } diff --git a/source-android/qml/configqml/SyncComponent.qml b/source-android/qml/configqml/SyncComponent.qml new file mode 100644 index 0000000..05be915 --- /dev/null +++ b/source-android/qml/configqml/SyncComponent.qml @@ -0,0 +1,87 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import "qrc:/qml/configqml" +import "qrc:/js/service.js" as Service + +Rectangle{ + color: "#EEEEEE" //Material.Grey + property string adapter: "" + width: parent.width + height: 12*mm + Label{ + x: mm + y: 0.5*mm + font.pixelSize:3*mm + text: qsTr(adapter) + } + CheckBox{ + id: syncCheckbox + x: mm + y: 5*mm + width:20*mm + checked:(globaloptions["sync_"+adapter]==1)?true:false + //style: CheckBoxStyle { + text: qsTr("sync") + font.pixelSize:3*mm + onClicked: { + toggle(); + if(syncCheckbox.checked==true){ + Service.updateglobaloptions(root.db,"sync_"+adapter,0);syncCheckbox.checked=false; + } + else{ + Service.updateglobaloptions(root.db,"sync_"+adapter,1);syncCheckbox.checked=true; + } + } + } + CheckBox{ + id: notifyCheckbox + x:25*mm + y: 5*mm + width:25*mm + enabled: adapter!="Notifications" + checked:(globaloptions["notify_"+adapter]==1)?true:false + text: qsTr("notify") + font.pixelSize:3*mm + onClicked: { + toggle(); + if(notifyCheckbox.checked==true){ + Service.updateglobaloptions(root.db,"notify_"+adapter,0);notifyCheckbox.checked=false; + } + else{ + Service.updateglobaloptions(root.db,"notify_"+adapter,1);notifyCheckbox.checked=true; + } + } + } +} diff --git a/source-android/qml/configqml/SyncConfig.qml b/source-android/qml/configqml/SyncConfig.qml new file mode 100644 index 0000000..9f42fe8 --- /dev/null +++ b/source-android/qml/configqml/SyncConfig.qml @@ -0,0 +1,101 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import "qrc:/qml/configqml" +import "qrc:/js/service.js" as Service + +Rectangle{ + color:"white" + width:root.width + height:root.height + Text { + text: qsTr("Sync Interval (0=None)") + font.pixelSize:3*mm + //visible: false + x: 4*mm; y: 10*mm; //width:35*mm;wrapMode: Text.Wrap + } + + Slider{ id: messageIntervalSlider + x:22*mm; y: 13.5*mm;width: root.width/2;height:5*mm + value: globaloptions.syncinterval + from: 0;to:120; stepSize: 15 + } + Rectangle{ + x: 4*mm; y: 13.5*mm; width: 9*mm; height: 5*mm; + TextEdit{ + id: messageIntervalField + anchors.fill: parent + font.pixelSize:3*mm + verticalAlignment:TextEdit.AlignRight + text:messageIntervalSlider.value + focus: true + selectByMouse: true + onTextChanged: { + Service.updateglobaloptions(root.db,"syncinterval",text); + if(osSettings.osType=="Android" && text !=0){ + alarm.setAlarm(text); + } else if(osSettings.osType=="Linux" && text !=0){ + + } + } + } + } + Text{x: 14*mm; y: 13.5*mm; width: 5*mm; height: 5*mm; + font.pixelSize:3*mm + text:qsTr("Min.") + } + + Column{ + y:22*mm + width: parent.width + spacing:mm + //anchors.fill: parent + SyncComponent{adapter:"Timeline"} + SyncComponent{adapter:"Replies"} + SyncComponent{ adapter:"DirectMessages"} + SyncComponent{ adapter:"Notifications"} + } + + Button{ + id:closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + height: 6*mm + width: 8*mm + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{root.pop()} + } +} diff --git a/source-android/qml/contactqml/ContactComponent.qml b/source-android/qml/contactqml/ContactComponent.qml index 2e4aabe..3ddcb19 100644 --- a/source-android/qml/contactqml/ContactComponent.qml +++ b/source-android/qml/contactqml/ContactComponent.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.4 import "qrc:/qml/genericqml" Item { @@ -83,7 +83,8 @@ Item { MouseArea{ anchors.fill: parent onClicked:{ - root.currentIndex=0; + rootstack.currentIndex=0; + bar.currentIndex=0; root.contactdetailsSignal(contact) } } diff --git a/source-android/qml/contactqml/ContactDetailsComponent.qml b/source-android/qml/contactqml/ContactDetailsComponent.qml index e2b5d37..cd5112c 100644 --- a/source-android/qml/contactqml/ContactDetailsComponent.qml +++ b/source-android/qml/contactqml/ContactDetailsComponent.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.4 import "qrc:/qml/genericqml" Item { @@ -78,7 +78,7 @@ Rectangle{ ScrollView{ horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff - frameVisible: true + //frameVisible: true id:namelabelflickable width: root.width-10*mm height:root.height-50*mm @@ -105,8 +105,10 @@ Rectangle{ x: mm spacing:4 - BlueButton{ + MButton{ id:photobutton + height: 6*mm + width: 8*mm text: "\uf03e" // "Photos" visible:(contact.network=="dfrn") onClicked:{ @@ -118,8 +120,10 @@ Rectangle{ } } - BlueButton{ + MButton{ id:messagebutton + height: 6*mm + width: 8*mm text: "\uf0e6" //"Messages" onClicked:{ root.currentIndex=0; @@ -129,23 +133,26 @@ Rectangle{ } } - BlueButton{ + MButton{ id:dmbutton visible: (contact.following=="true") + height: 6*mm + width: 8*mm text: "\uf040" //"DM" onClicked:{ root.currentIndex=0; - //newstab.active=true; root.directmessageSignal(contact.screen_name); contactLargeComponent.destroy(); } } - BlueButton{ + Button{ id:eventbutton visible:(contact.network=="dfrn") - text:"\uf073" + height: 6*mm + width: 8*mm + text:"\uf073" //Events onClicked:{ root.currentIndex=3; calendartab.active=true; @@ -155,8 +162,10 @@ Rectangle{ } } - BlueButton{ + Button{ id: closeButton + height: 6*mm + width: 8*mm text: "\uf057" //"close" onClicked:{contactLargeComponent.destroy(); } diff --git a/source-android/qml/contactqml/Contactlist.qml b/source-android/qml/contactqml/Contactlist.qml index 66c07e7..67564ca 100644 --- a/source-android/qml/contactqml/Contactlist.qml +++ b/source-android/qml/contactqml/Contactlist.qml @@ -31,6 +31,7 @@ // List of people import QtQuick 2.0 +import QtQuick.Controls 2.5 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -109,13 +110,15 @@ Rectangle { } } - BlueButton { + MButton { id: closeButton + height:6* mm + width: 8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm - color:"white" + //color:"white" text: "\uf057" onClicked: { groupModelAppend(contacts,function(){ diff --git a/source-android/qml/contactqml/FriendsTab.qml b/source-android/qml/contactqml/FriendsTab.qml index 601787d..41741e7 100644 --- a/source-android/qml/contactqml/FriendsTab.qml +++ b/source-android/qml/contactqml/FriendsTab.qml @@ -29,9 +29,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.0 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.11 +import QtQuick.Controls 2.4 +//import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.11 import QtQuick.LocalStorage 2.0 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs @@ -69,14 +70,37 @@ Rectangle { callback(profile) } - TabView{ + TabBar { + id: friendsbar + width: parent.width + height: 9*mm + position:TabBar.Header + currentIndex: 1 + TabButton { + text: qsTr("Me") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Friends") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Contacts") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Groups") + font.pixelSize: 2*mm + } + } + StackLayout{ id:friendsTabView - tabPosition: Qt.TopEdge + //anchors.fill: parent x:mm - y:mm - width: root.width-2*mm - height: root.height-10*mm - currentIndex: 1 + y:10*mm + width: parent.width-2*mm + height: parent.height-10*mm + currentIndex: friendsbar.currentIndex signal contactsSignal(var contact) signal groupsSignal(var username) onCurrentIndexChanged:{ @@ -88,27 +112,28 @@ Rectangle { } else if (currentIndex==3){groupsSignal(root.login.username)} } - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle { - color: "white" - implicitWidth: root.width/4-2*mm - implicitHeight: 4*mm - Text { id: text - anchors.centerIn: parent - text: styleData.title - color: "dark grey" - font.pixelSize:2.5*mm - font.bold: styleData.selected - } - } - frame: Rectangle { color: "light grey" } - tabsAlignment:Qt.AlignHCenter - } +// style: TabViewStyle { +// frameOverlap: 1 +// tab: Rectangle { +// color: "white" +// implicitWidth: root.width/4-2*mm +// implicitHeight: 4*mm +// Text { id: text +// anchors.centerIn: parent +// text: styleData.title +// color: "dark grey" +// font.pixelSize:2.5*mm +// font.bold: styleData.selected +// } +// } +// frame: Rectangle { color: "light grey" } +// tabsAlignment:Qt.AlignHCenter +// } - Tab{ + Item{ id:profileGridTab - title: qsTr("Me") + Layout.fillWidth:true + Layout.fillHeight: true Component.onCompleted:{ showProfile(function(profile){ var component = Qt.createComponent("qrc:/qml/contactqml/ProfileComponent.qml"); @@ -117,11 +142,11 @@ Rectangle { } } - Tab{ - title: qsTr("Friends") - Rectangle{ + Item{ id: friendsGridTab - property int currentContact:0 + Layout.fillWidth:true + Layout.fillHeight: true + property int currentContact: 0 function showFriends(contact){ try {friendsModel.clear()} catch(e){print(e)}; Helperjs.readData(root.db,"contacts",login.username,function(friendsobject){ @@ -140,17 +165,21 @@ Rectangle { onDownloaded:{ if(type=="contactlist"){ //print(url+" "+filename+" "+i) - currentContact=i+1; - if(currentContact==root.newContacts.length){showFriends(root.login.username)} + friendsGridTab.currentContact=i+1; + if(friendsGridTab.currentContact==root.newContacts.length){ + friendsGridTab.showFriends(root.login.username) + } } } } - BlueButton { + MButton { id: updateFriendsButton text: "\uf021" anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right + height: 6*mm + width: 8*mm onClicked: { try {friendsModel.clear()} catch(e){print(e)}; //root.contactLoadType="friends"; @@ -167,8 +196,8 @@ Rectangle { anchors.top: parent.top anchors.right:updateFriendsButton.left anchors.rightMargin:mm - visible: (currentContact!=(root.newContacts.length))?true:false - value: currentContact/root.newContacts.length + visible: (friendsGridTab.currentContact!=(root.newContacts.length))?true:false + value: friendsGridTab.currentContact/root.newContacts.length } //GridView { @@ -196,13 +225,11 @@ Rectangle { root.newContacts=[] } } - } - Tab{ - title: qsTr("Contacts") - - Rectangle{ + Item{ id: contactsGridTab + Layout.fillWidth:true + Layout.fillHeight: true function showContacts(contact){ try {contactsModel.clear()} catch(e){print(e)}; Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){ @@ -213,12 +240,14 @@ Rectangle { } },"isFriend",0,"screen_name ASC"); } - BlueButton { + MButton { id: cleanButton text: "\uf021" anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right + height: 6*mm + width: 8*mm onClicked: { Service.cleanContacts(root.login,root.db,function(){ try {contactsModel.clear()} catch(e){print(e)}; @@ -252,11 +281,13 @@ Rectangle { friendsTabView.contactsSignal.connect(showContacts); } } - } - Tab{ - title: qsTr("Groups") - Rectangle{ + + + Item{ id: groupsGridTab + Layout.fillWidth:true + Layout.fillHeight: true + function showGroups(username){ try {groupsModel.clear()} catch(e){print(e)}; Helperjs.readData(db, "groups",root.login.username,function(groupsobject){ @@ -289,16 +320,18 @@ Rectangle { showGroups(root.login.username)}); } } - BlueButton { + MButton { id: updateGroupsButton text: "\uf021" anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right anchors.rightMargin: mm + height: 6*mm + width: 8*mm onClicked: { Newsjs.requestGroups(root.login,root.db,root,function(){ - showGroups(root.login.username)})} + groupsGridTab.showGroups(root.login.username)})} } // BlueButton { // id: newGroupButton @@ -351,9 +384,9 @@ Rectangle { friendsTabView.groupsSignal.connect(showGroups); } } - } - } + +} Component.onCompleted: { - root.contactdetailsSignal.connect(showContactdetails); + //root.contactdetailsSignal.connect(showContactdetails); } } diff --git a/source-android/qml/contactqml/GroupComponent.qml b/source-android/qml/contactqml/GroupComponent.qml index 04097b7..4d33790 100644 --- a/source-android/qml/contactqml/GroupComponent.qml +++ b/source-android/qml/contactqml/GroupComponent.qml @@ -29,7 +29,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.0 +import QtQuick 2.11 +import QtQuick.Controls 2.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs import "qrc:/qml/genericqml" @@ -76,15 +77,34 @@ Item { } } - BlueButton{ + + MButton{ + id: closeButton + visible: false + width: 8*mm + height: 6*mm + anchors.left: infobutton.right + anchors.margins: mm + anchors.top: parent.top + + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{groupComponent.state=""; + if (group.new){groupsModel.remove(index)} + } + } + + MButton{ id:infobutton - width: 5*mm - height: 5*mm - color:"transparent" + width: 4*mm + height: 6*mm + + //color:"transparent" text:"?" + font.pixelSize: 3*mm anchors.left: photoImage.right - anchors.leftMargin: 3 - anchors.topMargin: 3 + anchors.leftMargin: mm + anchors.topMargin: mm anchors.top: parent.top onClicked:{ //if(group.new){ @@ -109,7 +129,7 @@ Item { Rectangle{ id: detailsrectangle anchors.top: namelabelRect.bottom - anchors.topMargin: 2*mm + anchors.topMargin: mm opacity: 0 Component { @@ -165,7 +185,7 @@ Item { x:1 //anchors.top: parent.top width: root.width-10*mm - height:groupsView.height -31*mm + height:groupsView.height - 24*mm clip: true spacing: 2 model: groupModel @@ -178,12 +198,7 @@ Item { anchors.top: groupListView.bottom anchors.topMargin: mm spacing: mm - BlueButton{ - id: closeButton - text: "\uf057" - onClicked:{groupComponent.state=""; - if (group.new){groupsModel.remove(index)} - } + } // BlueButton{ @@ -232,7 +247,7 @@ Item { // groupsModel.remove(index)}) // } // } - } + } Component.onCompleted:{if(group.new){groupComponent.state="large"}} } @@ -242,11 +257,13 @@ Item { name: "large" PropertyChanges { target: namelabel; font.pixelSize: 4*mm; width:groupsView.width; readOnly:false} PropertyChanges { target: namelabelRect; height: 4.5*mm} + PropertyChanges { target: closeButton; visible: true} PropertyChanges { target: groupComponent; z: 2 } PropertyChanges { target: wrapper; width:groupsView.width;height:groupsView.height -2*mm-1} PropertyChanges { target: photoImage; width:15*mm;height:15*mm } PropertyChanges { target:groupComponent.GridView.view ;contentY:groupComponent.y;contentX:groupComponent.x;interactive:false} PropertyChanges { target: detailsrectangle; opacity:1 } + PropertyChanges { target: infobutton; visible: false} } ] } diff --git a/source-android/qml/contactqml/ProfileComponent.qml b/source-android/qml/contactqml/ProfileComponent.qml index 0357bfb..a2b5b09 100644 --- a/source-android/qml/contactqml/ProfileComponent.qml +++ b/source-android/qml/contactqml/ProfileComponent.qml @@ -30,13 +30,14 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.4 import "qrc:/qml/genericqml" import "qrc:/js/service.js" as Service Rectangle { - width:root.width-2*mm - height:root.height-14*mm +// width:parent.width-2*mm +// height:parent.height-14*mm + anchors.fill:parent color:"white" property var profile:({}) property var attachImageURLs:[] @@ -102,12 +103,15 @@ Rectangle { callback(profiletext) } - BlueButton { + MButton { id: update + height: 6*mm + width: 8*mm anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right text: "\uf021" + font.pixelSize: 3*mm onClicked: { Service.requestProfile(root.login,root.db,root,function(nc){ root.newContacts=nc; @@ -132,8 +136,9 @@ Rectangle { Image { id: photoImage - x:mm - y:mm + anchors.top: parent.top + anchors.topMargin: mm + anchors.left: parent.left width: 15*mm height:15*mm source: "file://"+profile.friendica_owner.profile_image @@ -170,11 +175,13 @@ Rectangle { font.pixelSize: 4*mm } - BlueButton{ + MButton{ id:updatebutton - height: 5*mm + height: 6*mm + width:8*mm visible: "file://"+profile.friendica_owner.profile_image!= photoImage.source text:qsTr("Update") + font.pixelSize: 3*mm anchors.left: photoImage.right anchors.leftMargin: 0.5*mm anchors.topMargin: mm @@ -184,7 +191,7 @@ Rectangle { Label { id: namelabel x: mm - width: root.width-6*mm + width: parent.width-6*mm height: 3*mm text:(Qt.atob(profile.friendica_owner.name))+" (@"+profile.friendica_owner.screen_name+")" elide:Text.ElideRight @@ -230,7 +237,7 @@ Rectangle { font.pixelSize: 3*mm textFormat:Text.RichText wrapMode: Text.Wrap - text:""+qsTr("Description")+": "+(profile.friendica_owner.description)+"
"+qsTr("Location")+": "+profile.friendica_owner.location+"
"+qsTr("Posts")+": "+profile.friendica_owner.statuses_count+ + text:""+qsTr("Description")+": "+(Qt.atob(profile.friendica_owner.description))+"
"+qsTr("Location")+": "+profile.friendica_owner.location+"
"+qsTr("Posts")+": "+profile.friendica_owner.statuses_count+ "
"+qsTr("URL")+": "+profile.friendica_owner.url+"
"+ ""+qsTr("Created at")+": "+createdAtDate.toLocaleString(Qt.locale()) onLinkActivated: { @@ -238,32 +245,32 @@ Rectangle { } } - Rectangle{ - id: detailsrectangle - anchors.top: namelabel.bottom - anchors.topMargin: 2*mm +// Rectangle{ +// id: detailsrectangle + ScrollView{ - horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff - frameVisible: true + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff id:namelabelflickable - width: root.width-10*mm - height:root.height-36*mm//friendsTabView.height-45*mm + anchors.top: namelabel.bottom + anchors.topMargin: 2*mm + width: parent.width-mm + height:parent.height-22*mm//friendsTabView.height-45*mm x: mm clip:true ListView { id: profileView header:textcomponent - width:root.width-10*mm - height: root.height - clip: true +// width:parent.width +// height: root.height +// clip: true spacing: 0 model: profileModel delegate: profileItem } } - } +// } Component.onCompleted: { profile.profiles.sort(function(obj1, obj2) { diff --git a/source-android/qml/friendiqa.qml b/source-android/qml/friendiqa.qml index ba8034f..c061520 100644 --- a/source-android/qml/friendiqa.qml +++ b/source-android/qml/friendiqa.qml @@ -32,37 +32,27 @@ import QtQuick 2.5 import QtQuick.LocalStorage 2.0 import QtQuick.Window 2.0 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.4 -//import QtQuick.Controls 2.3 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 1.11 import "qrc:/js/news.js" as Newsjs import "qrc:/js/service.js" as Service -import "qrc:/qml/genericqml" -import "qrc:/qml/newsqml" -import "qrc:/qml/contactqml" -import "qrc:/qml/photoqml" -import "qrc:/qml/calendarqml" -import "qrc:/qml/configqml" -TabView{ +StackView{ id:root property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettingsAndroid.qml");return tmp.createObject(root)} - //IntentReceiver{} - tabPosition: Qt.BottomEdge width: osSettings.appWidth height:osSettings.appHeight - focus:true - property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000] property var login: Service.readActiveConfig(db) property var globaloptions: ({}) //Service.readGlobaloptions(db) property var contactlist: [] - property real mm: Screen.pixelDensity + property real mm: osSettings.osType=="Android"?Screen.pixelDensity:Screen.pixelDensity*1.5 signal messageSignal(var friend) signal fotoSignal(var username, var friend) signal directmessageSignal(var friend) signal newsSignal(var news) + signal newstypeSignal(var type) signal friendsSignal(var username) signal contactdetailsSignal(var contact) signal eventSignal(var contact) @@ -75,8 +65,8 @@ TabView{ property bool imagePicking: false onLoginChanged:{ - if(login==""){root.currentIndex=4} - else{ + if(login==""){root.push("qrc:/qml/configqml/AccountPage.qml")} + else{root.push(rootStackItem) newstab.newstabstatus=login.newsViewType; Newsjs.getCurrentContacts(login,db,function(contacts){ contactlist=contacts})} @@ -121,7 +111,7 @@ TabView{ newstab.active=true; if (newstab.newstabstatus!=login.newsViewType){ newstab.newstabstatus=login.newsViewType; - if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){ + if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,0,function(dbnews){ newsSignal(dbnews) })} else{ @@ -140,64 +130,273 @@ TabView{ event.accepted = true }} - - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle { - color: styleData.selected?"sky blue":"light blue" - //border.color: "light grey" - implicitWidth: root.width/5 - implicitHeight: 5*mm - Text { id: text - anchors.centerIn: parent - text: styleData.title - color: "black" - font.family: fontAwesome.name - font.pixelSize: 3*mm + Drawer{ + id: leftDrawer + width: 0.66* root.width + height: root.height + edge: Qt.LeftEdge + position: 1.0 + Column{ + x:mm + width:parent.width-mm + Label{ + text: login.hasOwnProperty("username")?login.username:"" + font.pixelSize: 4*mm + width: parent.width + height: 6*mm } - } - frame: Rectangle { color: "light grey" } - tabsAlignment:Qt.AlignHCenter - } +// Label{ +// text:login.hasOwnProperty("server")?"@"+login.server:"" +// font.pixelSize: 5*mm +// width: parent.width +// } + + Label{ + text: "\uf021 " + qsTr("Refresh") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("refresh") +// updatenews.setDatabase(); +// updatenews.login(); +// updatenews.startsync(); + } + } + } + + + Label{ + text: "\uf1da " + qsTr("Timeline") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("timeline") + } + } + } + + Label{ + text: "\uf086 " + qsTr("Conversations") + width: parent.width + font.pixelSize: 4*mm + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("conversation") + } + } + } + + Label{ + text: "\uf005 " + qsTr("Favorites") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("favorites") + } + } + } + Label{ + text: "\uf0ec " + qsTr("Replies") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("replies") + } + } + } + + + Label{ + text: "\uf0ac " + qsTr("Public Timeline") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("publictimeline") + } + } + } + + Label{ + text: "\uf0c0 " + qsTr("Group news") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("groupnews") + } + } + } + + Label{ + text: "\uf002 " + qsTr("Search") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("search") + } + } + } + + Label{ + text: "\uf085 "+ qsTr("Settings") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked: {root.push("qrc:qml/configqml/ConfigPage.qml"); + leftDrawer.close() + } + } + } + Label{ + text: "\uf2bb " + qsTr("Accounts") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked: {root.push("qrc:qml/configqml/AccountPage.qml"); + leftDrawer.close() + } + } + } + + Label{ - Tab{ - title: "\uf03a" - id: newstab - property string newstabstatus - property var conversation:[] - property var contactposts:[] - source:(root.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" - } - Tab{ - title: "\uf0c0" - id: friendstab - source: (root.currentIndex==1)?"qrc:/qml/contactqml/FriendsTab.qml":"" - } - Tab{ - title: "\uf03e" - id: fotostab - property string phototabstatus:"Images" - source: (root.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":"" - } - Tab{ - title: "\uf073" - id: calendartab - property string calendartabstatus:"Events" - source: (root.currentIndex==3)?"qrc:/qml/calendarqml/CalendarTab.qml":"" + text: "\uf08b " +qsTr("Quit") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + Service.cleanNews(root.db,function(){ + Service.cleanContacts(root.login,root.db,function(){ + Qt.quit()}) + }) + } + } + } + + } } - Tab{ - title:"\uf085" - id: configtab - source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":"" - } + + + + Item{ + id:rootStackItem + //anchors.fill:parent + states: State { + name: "fullscreen"; + PropertyChanges { target: bar; height:0 } + PropertyChanges { target: rootstack; height:parent.height } + } + + transitions: Transition { + PropertyAnimation { properties: "height"; + easing.type: Easing.InOutQuad + duration: 1000 + } + } + TabBar { + id: bar + width: parent.width + height: 7*mm + position:TabBar.Footer + anchors.top: rootstack.bottom + onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex + TabButton { + text: "\uf03a" + font.pixelSize: 3*mm + height: 6*mm + } + TabButton { + text: "\uf0c0" + font.pixelSize: 3*mm + height: 6*mm + } + TabButton { + text: "\uf03e" + font.pixelSize: 3*mm + height: 6*mm + } + + TabButton { + text: "\uf073" + font.pixelSize: 3*mm + height: 6*mm + } + } + + StackLayout{ + id:rootstack + width:parent.width + height: parent.height-7*mm + currentIndex:bar.currentIndex + + + Loader{ + id: newstab + Layout.fillWidth:true + Layout.fillHeight: true + property string newstabstatus + property var conversation:[] + property var contactposts:[] + source:(rootstack.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" + } + Loader{ + id: friendstab + Layout.fillWidth:true + Layout.fillHeight: true + source: (rootstack.currentIndex==1)?"qrc:/qml/contactqml/FriendsTab.qml":"" + } + Loader{ + id: fotostab + property string phototabstatus:"Images" + Layout.fillWidth:true + Layout.fillHeight: true + source: (rootstack.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":"" + } + Loader{ + id: calendartab + property string calendartabstatus:"Events" + Layout.fillWidth:true + Layout.fillHeight: true + source: (rootstack.currentIndex==3)?"qrc:/qml/calendarqml/CalendarTab.qml":"" + } + + } Component.onCompleted: { Service.readGlobaloptions(db,function(go){globaloptions=go}) - //print(xhr.networktype); + //print(xhr.networktype()); if(osSettings.osType=="Android"){ var component = Qt.createComponent("qrc:/qml/genericqml/IntentReceiver.qml"); var IntentReceiverQml = component.createObject(root); - + } else if (osSettings.osType=="Linux"){ + var component = Qt.createComponent("qrc:/qml/genericqml/LinuxSync.qml"); + var LinuxSyncQml = component.createObject(root); } } } +} diff --git a/source-android/qml/genericqml/BlueButton.qml b/source-android/qml/genericqml/BlueButton.qml index 3db1ecc..997db9b 100644 --- a/source-android/qml/genericqml/BlueButton.qml +++ b/source-android/qml/genericqml/BlueButton.qml @@ -64,7 +64,7 @@ Rectangle{ states: [ State { name: "Pressed" - PropertyChanges { target: blueButton; color: "sky blue"} } + PropertyChanges { target: blueButton; color: "white"} } ] transitions: [ Transition { to:"*" diff --git a/source-android/qml/genericqml/ImagePicker.qml b/source-android/qml/genericqml/ImagePicker.qml index e62305a..d414c1f 100644 --- a/source-android/qml/genericqml/ImagePicker.qml +++ b/source-android/qml/genericqml/ImagePicker.qml @@ -38,7 +38,7 @@ Item { Connections { target: SystemDispatcher onDispatched: { - if (type === m_CHOSEN_MESSAGE) { + if ((type === m_CHOSEN_MESSAGE) && (root.imagePicking==true)) { var h=[]; for (var n in message.imageUrls){ h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5)) diff --git a/source-android/qml/genericqml/ImagePickerLinux.qml b/source-android/qml/genericqml/ImagePickerLinux.qml index c5e3051..cd3b182 100644 --- a/source-android/qml/genericqml/ImagePickerLinux.qml +++ b/source-android/qml/genericqml/ImagePickerLinux.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import Qt.labs.folderlistmodel 2.1 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs @@ -60,8 +60,9 @@ Rectangle{ wrapMode: Text.Wrap text: directory } - BlueButton{ + Button{ id:closeButton + height: 8*mm anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right: parent.right diff --git a/source-android/qml/genericqml/IntentReceiver.qml b/source-android/qml/genericqml/IntentReceiver.qml index 69ec590..1ceaacf 100644 --- a/source-android/qml/genericqml/IntentReceiver.qml +++ b/source-android/qml/genericqml/IntentReceiver.qml @@ -23,14 +23,14 @@ Item { } imageUrls=h; if(imageUrls.length==1){ - root.currentIndex=0;newstab.active=true; + rootstack.currentIndex=0;newstab.active=true; root.uploadSignal(imageUrls) } else{ - root.currentIndex=2;fotostab.active=true; + rootstack.currentIndex=2;fotostab.active=true; root.uploadSignal(imageUrls) } } else if (type==m_TEXT_MESSAGE){ - root.currentIndex=0;newstab.active=true; + rootstack.currentIndex=0;newstab.active=true; root.sendtextSignal(message) } } @@ -38,9 +38,8 @@ Item { Component.onCompleted: { SystemDispatcher.setInitialized(); - print("timer " + login.timerInterval) - if (login.timerInterval !=0){ - alarm.setAlarm(login.timerInterval); + if (root.globaloptions.hasOwnProperty("syncinterval") && root.globaloptions.syncinterval !=null && root.globaloptions.syncinterval !=0){ + alarm.setAlarm(root.globaloptions.syncinterval); } } } diff --git a/source-android/qml/genericqml/LinuxSync.qml b/source-android/qml/genericqml/LinuxSync.qml new file mode 100644 index 0000000..0e6d84d --- /dev/null +++ b/source-android/qml/genericqml/LinuxSync.qml @@ -0,0 +1,22 @@ +import QtQuick 2.4 + + +Item { + Timer{ + id:syncTimer + repeat: true + onTriggered: { + updatenews.setDatabase(); + updatenews.login(); + updatenews.startsync(); + } + } + + Component.onCompleted: { + if (root.globaloptions.hasOwnProperty("syncinterval") && root.globaloptions.syncinterval !=null && root.globaloptions.syncinterval !=0){ + syncTimer.interval=root.globaloptions.syncinterval*60000; + syncTimer.start() + } + } +} + diff --git a/source-android/qml/genericqml/MButton.qml b/source-android/qml/genericqml/MButton.qml new file mode 100644 index 0000000..08932ae --- /dev/null +++ b/source-android/qml/genericqml/MButton.qml @@ -0,0 +1,39 @@ +// This file is part of Friendiqa +// https://github.com/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick.Controls 2.4 +Button{ + id: mButton + width: Math.max(text.width+2*mm,8*mm) + height: 6*mm + //color: Material.grey + font.pixelSize: 3*mm +} diff --git a/source-android/qml/genericqml/PermissionDialog.qml b/source-android/qml/genericqml/PermissionDialog.qml index 61a05cc..8faaad8 100644 --- a/source-android/qml/genericqml/PermissionDialog.qml +++ b/source-android/qml/genericqml/PermissionDialog.qml @@ -29,7 +29,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.0 +import QtQuick 2.11 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -178,7 +178,7 @@ Rectangle{ else {groupstatus="neutral"} } } } - BlueButton{ + MButton{ x:0.5*mm anchors.bottom: parent.bottom anchors.bottomMargin:1 @@ -190,7 +190,7 @@ Rectangle{ Service.savePermissions(db,perms) } } - BlueButton{ + MButton{ x:contactView.width+2*mm anchors.bottom: parent.bottom anchors.bottomMargin:1 diff --git a/source-android/qml/genericqml/Search.qml b/source-android/qml/genericqml/Search.qml index 3ed2b6e..835e7be 100644 --- a/source-android/qml/genericqml/Search.qml +++ b/source-android/qml/genericqml/Search.qml @@ -54,7 +54,7 @@ Rectangle { anchors.top:parent.top anchors.topMargin: 0.5*mm width:parent.width-2*mm - height: 7*mm //Math.max( searchText.contentHeight,5*mm) + height: 4*mm //Math.max( searchText.contentHeight,5*mm) TextInput { id: searchText diff --git a/source-android/qml/newsqml/ContactPage.qml b/source-android/qml/newsqml/ContactPage.qml index 6fe470d..e3c7ead 100644 --- a/source-android/qml/newsqml/ContactPage.qml +++ b/source-android/qml/newsqml/ContactPage.qml @@ -31,7 +31,7 @@ import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -43,7 +43,7 @@ Rectangle { ListView { id: contactView x:mm - y:8*mm + y:9*mm width: contactList.width-4*mm height:contactList.height-10*mm clip: true @@ -90,35 +90,48 @@ Rectangle { y: mm spacing:4 - BlueButton{ + MButton{ id:photobutton + height: 6*mm + width: 8*mm text: "\uf03e" // "Photos" + //font.pixelSize: 3*mm visible:(contact.network=="dfrn") - onClicked:{print(createdAtDate + " contact.created_at"+contact.created_at) + onClicked:{ + rootstack.currentIndex=2; + bar.currentIndex=2; fotostab.phototabstatus="Contact"; - currentIndex=2; - fotostab.active=true; + + //fotostab.active=true; fotoSignal(root.login,contact) ; newsStack.pop(); } } - BlueButton{ + MButton{ id:dmbutton + height: 6*mm + width: 8*mm visible: (contact.following=="true") text: "\uf040" //"DM" + //font.pixelSize: 3*mm onClicked:{ - currentIndex=0; - directmessageSignal(contact.screen_name) + rootstack.currentIndex=0; + newsSwipeview.currentIndex=2; + directmessageSignal(contact) } } - BlueButton{ + MButton{ id:eventbutton visible:(contact.network=="dfrn") + height: 6*mm + width: 8*mm text:"\uf073" + //font.pixelSize: 3*mm onClicked:{ - currentIndex=3; + rootstack.currentIndex=3; + bar.currentIndex=3; calendartab.calendartabstatus="Friend" eventSignal(contact); newsStack.pop() @@ -179,14 +192,16 @@ Rectangle { source: "qrc:/js/newsworker.js" } - BlueButton { + MButton { id: closeButton - width:10*mm + height: 6*mm + width: 8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm text: "\uf057" + //font.pixelSize: 3*mm onClicked: { newsStack.pop() } diff --git a/source-android/qml/newsqml/Conversation.qml b/source-android/qml/newsqml/Conversation.qml index 8157383..c3fc24a 100644 --- a/source-android/qml/newsqml/Conversation.qml +++ b/source-android/qml/newsqml/Conversation.qml @@ -31,9 +31,10 @@ // ConversationView with button import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" +import "qrc:/qml/newsqml" Rectangle { id:conversationList @@ -56,7 +57,7 @@ Rectangle { height:conversationList.height-10*mm clip: true spacing: 0 - footer: footerReply + footer: MessageSend{conversation:true}//footerReply model: conversationModel delegate: Newsitem{} } @@ -89,68 +90,70 @@ Rectangle { } } - Component { id:footerReply - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - color:"lightgrey" - width:conversationView.width - height:Math.max(replyText.contentHeight+2*mm,6*mm) - Rectangle{ - color: "white" - radius:0.5*mm - anchors.left: parent.left - anchors.leftMargin:mm - anchors.top:parent.top - anchors.topMargin: 0.5*mm - width:parent.width-12*mm - height:Math.max( replyText.contentHeight,5*mm) +// Component { id:footerReply +// Rectangle{ +// border.color: "#EEEEEE" +// border.width: 1 +// color:"lightgrey" +// width:conversationView.width +// height:Math.max(replyText.contentHeight+2*mm,6*mm) +// Rectangle{ +// color: "white" +// radius:0.5*mm +// anchors.left: parent.left +// anchors.leftMargin:mm +// anchors.top:parent.top +// anchors.topMargin: 0.5*mm +// width:parent.width-12*mm +// height:Math.max( replyText.contentHeight,5*mm) - TextInput { - id: replyText - font.pixelSize: 3*mm - wrapMode: Text.Wrap - anchors.fill: parent - selectByMouse: true - onHeightChanged: conversationView.contentY+=4.5*mm - } - } +// TextInput { +// id: replyText +// font.pixelSize: 3*mm +// wrapMode: Text.Wrap +// anchors.fill: parent +// selectByMouse: true +// onHeightChanged: conversationView.contentY+=4.5*mm +// } +// } - BlueButton { - id: sendButton - text: "\uf1d9" - anchors.right: parent.right - anchors.rightMargin:mm - anchors.top:parent.top - anchors.topMargin: 0.5*mm - color:"white" - onClicked: { try{ - var body=replyText.getText(0,replyText.length); - newsBusy.running=true; - replyText.text="" - xhr.clearParams(); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - if (conversationModel.get(0).newsitemobject.messagetype==0){ +// Button { +// id: sendButton +// height: 8*mm +// width:8*mm +// text: "\uf1d9" +// anchors.right: parent.right +// anchors.rightMargin:mm +// anchors.top:parent.top +// anchors.topMargin: 0.5*mm +// //color:"white" +// onClicked: { try{ +// var body=replyText.getText(0,replyText.length); +// newsBusy.running=true; +// replyText.text="" +// xhr.clearParams(); +// xhr.setLogin(login.username+":"+Qt.atob(login.password)); +// if (conversationModel.get(0).newsitemobject.messagetype==0){ - //xhr.url= login.server + "/api/statuses/update.json"; - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/update"); - xhr.setParam("source", "Friendiqa"); - xhr.setParam("status", body); - xhr.setParam("in_reply_to_status_id", conversationModel.get(conversationModel.count-1).newsitemobject.id)} - else {//xhr.url= login.server + "/api/direct_messages/new.json"; - xhr.setUrl(login.server); - xhr.setApi("/api/direct_messages/new"); - xhr.setParam("text", body); - xhr.setParam("screen_name",conversationModel.get(conversationModel.count-1).newsitemobject.screen_name); - xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.id) - } - xhr.post(); - } catch(e){Helperjs.showMessage("Error",e.toString(),root)} - } - } - } - } +// //xhr.url= login.server + "/api/statuses/update.json"; +// xhr.setUrl(login.server); +// xhr.setApi("/api/statuses/update"); +// xhr.setParam("source", "Friendiqa"); +// xhr.setParam("status", body); +// xhr.setParam("in_reply_to_status_id", conversationModel.get(conversationModel.count-1).newsitemobject.id)} +// else {//xhr.url= login.server + "/api/direct_messages/new.json"; +// xhr.setUrl(login.server); +// xhr.setApi("/api/direct_messages/new"); +// xhr.setParam("text", body); +// xhr.setParam("screen_name",conversationModel.get(conversationModel.count-1).newsitemobject.screen_name); +// xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.id) +// } +// xhr.post(); +// } catch(e){Helperjs.showMessage("Error",e.toString(),root)} +// } +// } +// } +// } @@ -161,9 +164,10 @@ Rectangle { source: "qrc:/js/newsworker.js" } - BlueButton { + MButton { id: closeButton - width:10*mm + height: 6*mm + width: 8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right diff --git a/source-android/qml/newsqml/MessageSend.qml b/source-android/qml/newsqml/MessageSend.qml index 6d6ded6..37b46a9 100644 --- a/source-android/qml/newsqml/MessageSend.qml +++ b/source-android/qml/newsqml/MessageSend.qml @@ -31,24 +31,28 @@ // message.qml // message with buttons -import QtQuick 2.0 -import QtQuick.Controls 1.4 +import QtQuick 2.4 +import QtQuick.Controls 2.4 //import QtQuick.Dialogs 1.2 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/smiley.js" as Smileyjs +import "qrc:/js/news.js" as Newsjs import "qrc:/qml/genericqml" Rectangle{ - color:"white" -// width:root.width-5*mm -// height:root.height-12*mm - //anchors.fill: parent + color:"#EEEEEE" + width:parent.width + height: (newsSwipeview.stacktype!="Notifications")?messageColumn.height+mm:0 + id:messageSend + visible:(newsSwipeview.stacktype!="Notifications")?true:false property string parentId: "" + //property var parentObject:({}) + property bool conversation: false property string reply_to_user:"" property alias bodyMessage: bodyField.text property var attachImageURLs: []; - property int directmessage: 0; + //property int directmessage: 0; property var contacts: [] property var groups: [] property var contact_allow:login.permissions[0] @@ -56,14 +60,48 @@ Rectangle{ property var group_allow:login.permissions[2] property var group_deny:login.permissions[3] - function attachImage(url){ print("attachImage "+url) + onReply_to_userChanged: { + if (reply_to_user!=""){ + receiverLabel.visible=true + } + } + + function directmessagePrepare(friend){ + messageSend.state="active"; + reply_to_user=friend.screen_name; + receiverLabel.text=qsTr("to:")+ " "+ friend.screen_name; + } + + + function sendUrls(urls){ + if((urls.length==1 && attachImageURLs.length==0)){ + attachImage(urls); + attachImageURLs.push(urls); + messageSend.state="active"; + } + } + + function sendtext(text){ + if(text){ + if (text.subject=="undefined"){text.subject=""} + if(text.plaintext.lastIndexOf(".jpg")>-1 || text.plaintext.lastIndexOf(".jpeg")>-1 || text.plaintext.lastIndexOf(".png")>-1 || text.plaintext.lastIndexOf(".gif")>-1){ + text.plaintext=""} + bodyField.text=text.subject+"\n"+text.plaintext; + messageSend.state="active"; + } + } + + + + function attachImage(url){ var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment'+attachImageURLs.length+'; source:"'+ url.toString()+'"; x:2*mm; width: 45*mm; height: 45*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+ url+'"),1); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage"); - } + } function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { //xhr.url= login.server + "/api/statuses/update.json"; + newsBusy.running=true; xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setUrl(login.server); xhr.setApi("/api/statuses/update"); @@ -81,6 +119,7 @@ Rectangle{ } function dmUpdate(title,text,replyto,screen_name,attachImageURL) { + newsBusy.running=true; //xhr.url= login.server + "/api/direct_messages/new.json"; xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setUrl(login.server); @@ -93,103 +132,193 @@ Rectangle{ xhr.post(); } - Flickable{ - anchors.fill: parent - contentHeight: messageColumn.height - boundsBehavior: Flickable.StopAtBounds - id:messageSend + function setParent(newsitemobject){ + //print("Newsobject "+newsitemobject.id+ " "+JSON.stringify(newsitemobject.user)); + if (newsitemobject!=""){ + messageSend.state="conversation" + reply_to_user=newsitemobject.user.screen_name; + receiverLabel.text=qsTr("to:")+ " "+ newsitemobject.user.screen_name; + parentId=newsitemobject.id + } else { + messageSend.state="" + reply_to_user=""; + receiverLabel.text=qsTr("to:"); + parentId=""; + bodyField.text=""; + attachImageURLs.pop(); + try{imageAttachment.destroy()}catch(e){} + } + } + + function contactmenu(letter){ + Newsjs.listFriends(login,db,function(contacts){ + var contactitems=""; + for (var i=0;i1){ + contacts[i].screen_name=contacts[i].screen_name+"+"+contacts[i].cid + } + contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+ + "'; onTriggered:{if (newsSwipeview.stacktype=='DirectMessages'){reply_to_user='"+ + contacts[i].screen_name+"'} else {bodyField.insert("+ + bodyField.cursorPosition+",' "+contacts[i].screen_name.substring(1)+" ');bodyField.cursorPosition=bodyField.cursorPosition+"+contacts[i].screen_name.length+"}}}" + //} + } + var menuString="import QtQuick.Controls 2.4; Menu {width:40*mm; font.pixelSize: 3*mm; "+contactitems+"}"; + var contactlistObject=Qt.createQmlObject(menuString,messageColumn,"contactmenuOutput"); + if (contacts.length>0){contactlistObject.popup()} + },letter); + } +// Flickable{ +// anchors.fill: parent +// contentHeight: messageColumn.height +// boundsBehavior: Flickable.StopAtBounds + Column { + y:0.5*mm id:messageColumn spacing: 0.5*mm width: parent.width + height: 10*mm//implicitHeight + Label{ + id:receiverLabel + x: 0.5*mm + width: parent.width-mm + font.pixelSize: 3*mm + text: newsSwipeview.stacktype=="DirectMessages"?qsTr("to:")+ " "+ reply_to_user:"" + visible:false// ((parentId !== "") || (newsStack.parent.stacktype=="DirectMessages")) + MouseArea{ + anchors.fill: parent + onClicked:{} + } + } TextField { id: titleField - width: parent.width + x: 0.5*mm + width: parent.width-mm + font.pixelSize: 3*mm placeholderText: qsTr("Title (optional)") - visible: parentId === "" + visible: false//(parentId === "") && (bodyField.length>1) + onVisibleChanged: if ((visible==true)&&(conversation==true)){ + conversationView.contentY=conversationView.contentY+titleField.height + } } + + Rectangle{ color: "white" radius: 0.5*mm x:mm width: parent.width-2*mm - height:Math.max(bodyField.contentHeight+2*mm,10*mm) + height:Math.max(bodyField.contentHeight+4*mm,10*mm) TextArea { id: bodyField anchors.fill: parent font.pixelSize: 3*mm + font.family: "Noto Sans" wrapMode: Text.Wrap selectByMouse: true + placeholderText: conversation?"": qsTr("What's on your mind?") textFormat: TextEdit.RichText //TextEdit.PlainText + onLineCountChanged: (conversation==true)?conversationView.contentY=conversationView.contentY+3*mm:newsView.contentY=newsView.contentY+3*mm onLinkActivated:{Qt.openUrlExternally(link)} - } - } - - - Row{ - spacing: 2 - width: parent.width - CheckBox{ - id:dmCheckbox - text:"DM" - enabled: false - checked: (directmessage==1)?true:false - onClicked:{ - if(dmCheckbox.checkedState==Qt.Checked){directmessage=1} - else if(dmCheckbox.checkedState==Qt.Unchecked){directmessage=0} - } - } - - BlueButton{ - text:"\uf0c1" - onClicked: { - if(bodyField.selectedText==""){Helperjs.showMessage("Error","No text selected",messageSend)} - else{urlTextEdit.text=""; - urlRectangle.visible=true}} - } - } - Rectangle{ - id:urlRectangle - height: 7*mm //parent.height - width:parent.width-2*mm - visible:false - TextField{ - id:urlTextEdit - width:parent.width-7*mm - height:parent.height - } - BlueButton{ - anchors.left:urlTextEdit.right - anchors.leftMargin:mm - text:"\u2713" - onClicked: {if(urlTextEdit.text!=""){ - var start = bodyField.selectionStart; - var text=bodyField.selectedText - if(text.lastIndexOf(".jpg")>-1 || text.lastIndexOf(".jpeg")>-1 || text.lastIndexOf(".png")>-1){text=""} - text = "[url="+urlTextEdit.text+"]" + text + "[/url]"; - bodyField.remove(start,bodyField.selectionEnd); - bodyField.insert(start,text);} - urlRectangle.visible=false} + onActiveFocusChanged:{ + if (activeFocus==true){ + if (conversation==true){ + setParent(conversationModel.get(0).newsitemobject); + messageSend.state="conversation" + } else{ + messageSend.state="active" + } } } - Row{ - spacing:2 - BlueButton{id:permButton - visible: (directmessage==1)?false:true - text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" - onClicked: { permissionDialog.visible=true;} + onTextChanged:{ + if (text!=""){ + //print(getText(bodyField.cursorPosition-2,bodyField.cursorPosition) +" preedit: "+ preeditText+cursorPosition); + var regex1 = /@[a-z]/;var regex2 = /![a-z]/; + //print(text.substring(cursorPosition-2,cursorPosition)); + //if (regex.test(getText(bodyField.cursorPosition-2,bodyField.cursorPosition)) || regex.test(preeditText) || regex.test(text)){ + if (regex1.test(getText(bodyField.cursorPosition-2,bodyField.cursorPosition)+preeditText) || regex2.test(getText(bodyField.cursorPosition-2,bodyField.cursorPosition)+preeditText)){ + var letter=(getText(bodyField.cursorPosition-2,bodyField.cursorPosition)).match(/[a-z]/); + contactmenu(letter) + } + }} } - BlueButton { + } + + +// Row{ +// spacing: 2 +// width: parent.width +// CheckBox{ +// id:dmCheckbox +// text:"DM" +// enabled: false +// checked: (directmessage==1)?true:false +// onClicked:{ +// if(dmCheckbox.checkedState==Qt.Checked){directmessage=1} +// else if(dmCheckbox.checkedState==Qt.Unchecked){directmessage=0} +// } +// } + +// Button{ +// text:"\uf0c1" +// height:8*mm +// onClicked: { +// if(bodyField.selectedText==""){Helperjs.showMessage("Error","No text selected",messageSend)} +// else{urlTextEdit.text=""; +// urlRectangle.visible=true}} +// } +// } +// Rectangle{ +// id:urlRectangle +// height: 7*mm //parent.height +// width:parent.width-2*mm +// visible:false +// TextField{ +// id:urlTextEdit +// width:parent.width-7*mm +// height:parent.height +// } +// Button{ +// anchors.left:urlTextEdit.right +// anchors.leftMargin:mm +// height:8*mm +// text:"\u2713" +// onClicked: {if(urlTextEdit.text!=""){ +// var start = bodyField.selectionStart; +// var text=bodyField.selectedText +// if(text.lastIndexOf(".jpg")>-1 || text.lastIndexOf(".jpeg")>-1 || text.lastIndexOf(".png")>-1){text=""} +// text = "[url="+urlTextEdit.text+"]" + text + "[/url]"; +// bodyField.remove(start,bodyField.selectionEnd); +// bodyField.insert(start,text);} +// urlRectangle.visible=false} +// } +// } + Row{ + id:buttonRow + visible:false //(bodyField.length>1)||(attachImageURLs.length>0) + spacing: mm + height: 12*mm + MButton{id:permButton + visible: (newsSwipeview.stacktype!=="DirectMessages") + height: 6*mm + width: 7*mm + text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" + onClicked: { if (permissionDialog.visible==false){permissionDialog.visible=true} else{permissionDialog.visible=false}} + } + MButton { id: attachButton + height: 6*mm + width: 7*mm text: "\uf03e" - visible:(directmessage==0) + visible:(newsSwipeview.stacktype!="DirectMessages") onClicked: { if (attachImageURLs.length>0){//Server currently accepts only one attachment Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn) } else{ - // root.imagePicking=true; + root.imagePicking=false; var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+ 'attachImage(imageUrl)}}',root,"imagePicker"); @@ -197,55 +326,102 @@ Rectangle{ } } } - BlueButton{ - id:contactButton - text:"\uf234" - visible:(directmessage==0) - onClicked:{ - var contactitems=""; - for (var i=0;i1){ - contacts[i].screen_name=contacts[i].screen_name+"+"+contacts[i].cid - } - contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"'; onTriggered: bodyField.insert("+bodyField.cursorPosition+",' @"+contacts[i].screen_name+" ')}" - }} - var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}"; - var contactlistObject=Qt.createQmlObject(menuString,messageColumn,"contactmenuOutput") - contactlistObject.popup() } - } - BlueButton{ + MButton{ id:smileyButton text: "\uf118" - onClicked: {smileyDialog.visible=true} + height: 6*mm + width: 7*mm + onClicked: {if (smileyDialog.visible==false){smileyDialog.visible=true} else{smileyDialog.visible=false}} } - BlueButton { + MButton { id: cancelButton + height: 6*mm + width: 7*mm text: "\uf057" onClicked: { - newstab.newstabstatus=login.newsViewType; - newsStack.pop(null) + bodyField.text=""; + messageSend.state=""; + permissionDialog.visible=false; + receiverLabel.visible=false; + reply_to_user=""; + attachImage(""); + attachImageURLs.pop(); } - } - BlueButton { + } + MButton { id: sendButton + height: 6*mm + width: 7*mm text: "\uf1d9" onClicked: { var title=titleField.text.replace("\"","\'"); var body=bodyField.getFormattedText(0,bodyField.length); var dmbody=bodyField.getText(0,bodyField.length); - if (directmessage==0){ + if (newsSwipeview.stacktype!=="DirectMessages"){ statusUpdate(title,body,parentId,attachImageURLs)} - else {dmUpdate(title,dmbody,parentId,reply_to_user) } - newstab.newstabstatus=login.newsViewType; newsStack.pop(null) + else { + if (reply_to_user!=""){dmUpdate(title,dmbody,parentId,reply_to_user)} + else{Helperjs.showMessage(qsTr("Error"),qsTr("No receiver supplied!"),root)} + } + if (conversation==true){ + newstab.newstabstatus=login.newsViewType; newsStack.pop(null) + } } } } PermissionDialog{id:permissionDialog;x:mm;visible: false} SmileyDialog{id:smileyDialog;x:mm;visible: false} } - Component.onCompleted: if(attachImageURLs.length>0){attachImage(attachImageURLs[0])} -} + Component.onCompleted:{ + // + //parentId=conversationModel.get(conversationModel.count-1).newsitemobject.id + //if(attachImageURLs.length>0){attachImage(attachImageURLs[0])} + newsStack.replySignal.connect(setParent); + root.directmessageSignal.connect(directmessagePrepare); + root.uploadSignal.connect(sendUrls); + root.sendtextSignal.connect(sendtext); + } + + states: [ State { + name: "active" + PropertyChanges { + target: messageColumn; height: implicitHeight + } + PropertyChanges { + target: buttonRow; visible:true + } + PropertyChanges { + target: titleField; visible:(newsSwipeview.stacktype!="DirectMessages")//true + } + PropertyChanges { + target: receiverLabel; visible:(newsSwipeview.stacktype=="DirectMessages"); + } + }, + State { + name: "conversation" + PropertyChanges { + target: messageColumn; height: implicitHeight + } + PropertyChanges { + target: buttonRow; visible:true + } + PropertyChanges { + target: titleField; visible:(newsSwipeview.stacktype!="DirectMessages") + } + +// PropertyChanges { +// target: receiverLabel; visible:true; text:qsTr("to")+": "+ conversationModel.get(0).newsitemobject.user.name +// } + +// PropertyChanges { +// target: messageSend; reply_to_user: conversationModel.get(0).newsitemobject.user.screen_name +// } + +// PropertyChanges { +// target: messageSend; parentId: conversationModel.get(0).newsitemobject.status_id +// } + } ] } +//} diff --git a/source-android/qml/newsqml/NewsStack.qml b/source-android/qml/newsqml/NewsStack.qml new file mode 100644 index 0000000..5cf9d95 --- /dev/null +++ b/source-android/qml/newsqml/NewsStack.qml @@ -0,0 +1,579 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import "qrc:/js/news.js" as Newsjs +import "qrc:/js/helper.js" as Helperjs +import "qrc:/js/service.js" as Service + +StackView{ + id: newsStack + anchors.fill: parent + property string updateMethodNews: "refresh" + property var allchats: ({}) + signal replySignal(var newsobject) + property int lastnewsid:0 + + function newstypeHandling(newstype){ + newsBusy.running=true; + replySignal(""); + //messagesend.state=""; + newsModel.clear(); + switch(newstype){ + case "timeline": + newstab.newstabstatus="Timeline"; + try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews) + })}catch(e){Helperjs.showMessage("Error",e,root)}; + break; + case "conversation": + newstab.newstabstatus="Conversations"; + Newsjs.chatsfromdb(root.db,root.login,0,function(news,lastid){ + lastnewsid=lastid; + showNews(news)}); + break; + case "favorites": + newsStack.updateMethodNews="refresh"; + newstab.newstabstatus="Favorites"; + Service.updateView("Favorites"); + break; + case "replies": + newsStack.updateMethodNews="refresh"; + newstab.newstabstatus="Replies"; + Service.updateView("Replies"); + break; + case "publictimeline": + newsStack.updateMethodNews="refresh"; + newstab.newstabstatus="Public Timeline"; + Service.updateView("Public Timeline"); + break; + case "groupnews": + newsStack.updateMethodNews="refresh"; + Service.showGroups(); + break; + case "search": + newsView.anchors.topMargin=7*mm; + newsBusy.running=false; + var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml"); + var searchItem = component.createObject(newsStack,{y:mm,width:root.width,height: 5*mm}); + break; + case "refresh": + if (newstab.newstabstatus=="Timeline"){ + newsStack.updateMethodNews="append" + } else {newsStack.updateMethodNews="refresh"} + //root.contactLoadType="news"; + if (newsSwipeview.stacktype=="Home"){ + Service.updateView(newstab.newstabstatus) + } + else if (newsSwipeview.stacktype=="DirectMessage"){ + Service.updateView("Direct Messages") + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications") + } + break; + default: + if (newstab.newstabstatus=="Timeline"){ + newsStack.updateMethodNews="append" + } else {newsStack.updateMethodNews="refresh"} + //root.contactLoadType="news"; + if (newsSwipeview.stacktype=="Home"){ + Service.updateView(newstab.newstabstatus) + } + else if (newsSwipeview.stacktype=="Directmessage"){ + Service.updateView("Direct Messages") + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications") + } + } + } + + + function showNews(newsToShow){ + try{ + if (newsStack.depth>1){newsStack.pop()} + }catch(e){} + newsBusy.running=false; + var currentTime= new Date(); + // downloadNotice.text=downloadNotice.text + "\n shownews start "+ Date.now(); + //print("appendnews "+JSON.stringify(newsToShow)) + var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow,'method':newsStack.updateMethodNews, 'options':globaloptions}; + newsWorker.sendMessage(msg); + //newsStack.appendNews=false + } + + function showContact(contact){ //print(JSON.stringify(contact)); + //newstab.newstabstatus="Contact"; + newsStack.push("qrc:/qml/newsqml/ContactPage.qml",{"contact": contact}); + } + + function search(term){//print("Search "+term) + if (term!=""){ + newstab.newstabstatus="Search"; + newsBusy.running=true; + newsStack.updateMethodNews="refresh"; + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.setUrl(login.server); + xhr.setApi("/api/search"); + xhr.clearParams(); + xhr.setParam("q",term) + xhr.get();} + newsView.anchors.topMargin=mm + } + + Connections{ + target:xhr + onError:{ + Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root); + } + onSuccess:{ + // downloadNotice.text=downloadNotice.text+ "\n xhr finished "+Date.now(); + Service.processNews(api,data); + } + } + + Timer {id:replytimer; interval: 1000; running: false; repeat: false + onTriggered: { + newsBusy.running=true; + if(newstab.newstabstatus=="Conversation"){ + showConversation(newsStack.timelineIndex-1,newsModel.get(0).newsitemobject)} + else{ + if (newstab.newstabstatus=="Timeline"){ + newsStack.updateMethodNews="append" + } else {newsStack.updateMethodNews="refresh"} + if (newsSwipeview.stacktype=="Home"){ + Service.updateView(newstab.newstabstatus) + } + else if (newsSwipeview.stacktype=="DirectMessages"){ + Service.updateView("Direct Messages") + } + else if (newsSwipeview.stacktype=="Replies"){ + Service.updateView("Replies") + } + replySignal("") + //Service.updateView(newstab.newstabstatus) + } + } + } + + initialItem: Rectangle { + id:newslistRectangle + y:1 + color: "white" + +// Button{ +// id:newstabstatusButton +// anchors.top: parent.top +// anchors.topMargin: 0.5*mm +// height: 8*mm +// text: qsTr(newstab.newstabstatus) +// visible: newsStack.parent.stacktype=="standard" +// onClicked: {print(newsStack.parent.stacktype); +// newstabmenu.popup(2*mm,6*mm) +// } + +// Menu{id:newstabmenu +// width: 40*mm + +// delegate:MenuItem{ +// contentItem: Text{ +// font.pixelSize: 3.5*mm +// text:parent.text +// } +// background: Rectangle { +// implicitWidth: 40*mm; implicitHeight: 5*mm +// color: "#ffffff" +// border.color: "grey" +// } +// } +// Action { +// text: qsTr("Timeline") +// onTriggered: { + +// } +// Action { +// text: qsTr("Conversations") +// onTriggered:{ +// //newsModel.clear(); +// newstab.newstabstatus="Conversations"; +// Newsjs.chatsfromdb(db,root.login,function(news){showNews(news)}) +// } +// } +// Action { +// text: qsTr("Favorites") +// onTriggered:{ +// newsStack.updateMethodNews="refresh"; +// newstab.newstabstatus="Favorites"; +// Service.updateView("Favorites") +// } +// } +// Action { +// text: qsTr("Replies") +// onTriggered:{ +// newsStack.updateMethodNews="refresh"; +// newstab.newstabstatus="Replies"; +// Service.updateView("Replies") +// } +// } +// Action { +// text: qsTr("Public timeline") +// onTriggered:{ +// newsStack.updateMethodNews="refresh"; +// newstab.newstabstatus="Public Timeline"; +// Service.updateView("Public Timeline") +// } +// } + +//// Action { +//// text: qsTr("Direct Messages") +//// onTriggered:{ +//// newsStack.updateMethodNews="refresh"; +//// newstab.newstabstatus="Direct Messages"; +//// Service.updateView("Direct Messages") +//// } +//// } +//// Action { +//// text: qsTr("Notifications") +//// onTriggered:{ +//// newsStack.updateMethodNews="refresh"; +//// newstab.newstabstatus="Notifications"; +//// Service.updateView("Notifications") +//// } +//// } +// Action { + +// text: qsTr("Group news") +// onTriggered: +// { +// newsStack.updateMethodNews="refresh"; +// Service.showGroups(); +// } +// } +// Action { + +// text: qsTr("Settings") +// onTriggered: +// { +// leftDrawer.open() +// } +// } + +// Action { +// text: qsTr("Quit") +// onTriggered:{ +// Service.cleanNews(root.db,function(){ +// Service.cleanContacts(root.login,root.db,function(){ +// Qt.quit()}) +// }) +// } +// } +// } +// } + +// Row{ +// spacing: mm +// anchors.top: parent.top +// anchors.topMargin: 0.5*mm +// anchors.right: parent.right + +// Button { +// id: searchButton +// height: 8*mm +// text: "\uf002" +// visible: newsStack.parent.stacktype=="standard" +// onClicked: { +// newsView.anchors.topMargin=18*mm; +// var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml"); +// var searchItem = component.createObject(newsStack,{y:8*mm,width:root.width,height: 8*mm}); +// } +// } + +// Button { +// id: newMessageButton +// text: "\uf040" +// height: 8*mm +// onClicked: { +// var groups=[]; +// Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){ +// groups=groupobject +// }); +// newstab.newstabstatus="SendMessage"; +// Helperjs.readData(root.db,"contacts",root.login.username,function(friends){ +// newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"contacts": friends,"login":root.login}) +// },"isFriend",1); +// } +// } +// BlueButton { +// id: quitButton +// text: "\uf08b" +// onClicked: {Service.cleanNews(root.db,function(){ +// Service.cleanContacts(root.login,root.db,function(){ +// Qt.quit() }) +// })} +// } +// Button { +// id: update +// height: 8*mm +// text: "\uf021" +// onClicked: { +// if (newstab.newstabstatus=="Timeline"){ +// newsStack.updateMethodNews="append" +// } else {newsStack.updateMethodNews="refresh"} +// //root.contactLoadType="news"; +// if (newsStack.parent.stacktype=="standard"){ +// Service.updateView(newstab.newstabstatus) +// } +// else if (newsStack.parent.stacktype=="directmessage"){ +// Service.updateView("Direct Messages") +// } +// else if (newsStack.parent.stacktype=="notifications"){ +// Service.updateView("Notifications") +// } +// } +// } + +// } + Component { id:footerComponent + Rectangle{ + border.color: "#EEEEEE" + border.width: 1 + width:newsView.width + height:6*mm + Text{ + font.pixelSize: 1.5*mm + anchors.centerIn: parent + text:qsTr("More") + } + MouseArea{anchors.fill:parent + onClicked:{ + var currentTime= new Date(); + var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; + var messagetype=0; + switch(newsSwipeview.stacktype){ + case "Home":messagetype=0;break; + case "DirectMessages": messagetype=1;break; + case "Notifications":messagetype=2;break; + case "Replies":messagetype=3;break; + default:messagetype=0; + } + if(newstab.newstabstatus=="Timeline"){ + Newsjs.newsfromdb(root.db,root.login, messagetype,function(news){ + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions}; + newsWorker.sendMessage(msg); + },false,lastnews_id)} + if(newstab.newstabstatus=="Conversations"){ + Newsjs.chatsfromdb(root.db,root.login, messagetype,function(news){ + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions}; + newsWorker.sendMessage(msg); + },lastnews_id)} +// else if(newstab.newstabstatus=="Contact"){ +// Newsjs.newsfromdb(root.db,root.login, function(news){ +// var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; +// newsWorker.sendMessage(msg); +// },newsModel.get(newsModel.count-1).newsitemobject.uid,lastnews_id)} + else if (newstab.newstabstatus=="Notifications"){} + else{ + //newsStack.appendNews=true; + xhr.setParam("max_id",newsModel.get(newsModel.count-1).newsitemobject.id-1); + xhr.get() + }} + } + } + } + + + +// Label{ +// text:qsTr(stacktype) +// font.pixelSize: 3* mm +// anchors.horizontalCenter: parent.horizontalCenter +// anchors.margins: mm +// } + + ListView { + id: newsView + property real oldContentY:0 + property bool viewdragged: false + anchors.fill: parent + anchors.margins: mm + //anchors.topMargin: 6*mm +// anchors.leftMargin: mm; anchors.rightMargin: mm +// anchors.bottomMargin: mm + clip: true + spacing: 0 + header: MessageSend{id:messagesend;onHeightChanged: newsView.positionViewAtBeginning()} + footer: footerComponent + model: newsModel + delegate: Newsitem{} + onDragStarted: oldContentY=contentY + onDragEnded: { + if(verticalOvershoot<-5*mm){ + viewdragged=true + } + else{ + if((contentY-oldContentY)>15*mm){ + swipeIndicator.visible=false; + newsSwipeview.height=rootStackItem.height; + newsSwipeview.y=0; + rootStackItem.state="fullscreen" + } + else if ((contentY-oldContentY)<-15*mm){ + swipeIndicator.visible=true; + newsSwipeview.height=rootStackItem.height-12*mm; + newsSwipeview.y=5*mm; + rootStackItem.state="" + } + } + } + onViewdraggedChanged: { + if (viewdragged){ + var onlynew=true; + newsBusy.running=true; + if (newstab.newstabstatus=="Timeline"){ + newsStack.updateMethodNews="append" + } else {newsStack.updateMethodNews="refresh"} + //root.contactLoadType="news"; + if (newsSwipeview.stacktype=="Home"){ + Newsjs.getLastNews(root.login,root.db,function(currentlastnews){ + if (currentlastnews>lastnewsid){ + if(newstab.newstabstatus=="Timeline"){ + try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews) + })}catch(e){Helperjs.showMessage("Error",e,root)}; + } + if(newstab.newstabstatus=="Conversations"){ + Newsjs.chatsfromdb(db,root.login,0,function(news,lastid){ + lastnewsid=lastid; + showNews(news)}); + } + } else { + Service.updateView(newstab.newstabstatus) + } + }); + } + else if (newsSwipeview.stacktype=="DirectMessages"){ + Service.updateView("Direct Messages") + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications") + } + else if (newsSwipeview.stacktype=="Replies"){ + Service.updateView("Replies") + } + viewdragged=false + }} + } + + ListModel{id: newsModel} + + WorkerScript { + id: newsWorker + source: "qrc:/js/newsworker.js" + } + + BusyIndicator{ + id: newsBusy + anchors.horizontalCenter: parent.horizontalCenter + anchors.top:parent.top + anchors.topMargin: 2*mm + width:10*mm + height: 10*mm + } + Rectangle{ + id:downloadNotice + property alias text: noticeText.text + color:"white" + border.color:"grey" + z:1 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom:parent.bottom + anchors.bottomMargin: 2*mm + width: noticeText.width+2*mm + height: noticeText.height+2*mm + visible: (downloadNotice.text!="") + + Text{ + id:noticeText + color: "grey" + anchors.centerIn: parent + width: contentWidth + height: contentHeight + font.pixelSize: 2*mm + text:"" + } + } + + Component.onCompleted: { + //print(newsSwipeview.stacktype); + root.newstypeSignal.connect(newstypeHandling); + root.messageSignal.connect(onFriendsMessages); + root.contactdetailsSignal.connect(showContact); + root.newsSignal.connect(showNews); + + try{newsModel.clear()} catch(e){} + swipeIndicator.visible=true; + newsSwipeview.height=rootStackItem.height-12*mm; + newsSwipeview.y=5*mm; + rootStackItem.state="" + +// xhr.setLogin(login.username+":"+Qt.atob(login.password)); +// xhr.setUrl(login.server); +// if((newsStack.parent.stacktype=="standard") && (root.news.length>0)){ +// showNews(root.news) +// } + //else{ + newstab.newstabstatus=login.newsViewType; + var messagetype=0; + switch(newsSwipeview.stacktype){ + case "Home":messagetype=0;break; + case "DirectMessages": messagetype=1;break; + case "Notifications":messagetype=2;break; + case "Replies":messagetype=3;break; + default:messagetype=0; + } + if((login.newsViewType=="Conversations")&&(newsSwipeview.stacktype=="Home")){ + Newsjs.chatsfromdb(db,login,messagetype,function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews); + }) + } + else{Newsjs.newsfromdb(db,login,messagetype,function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews) + })} + //} + } + } +} diff --git a/source-android/qml/newsqml/NewsTab.qml b/source-android/qml/newsqml/NewsTab.qml index f4a18e2..248bee5 100644 --- a/source-android/qml/newsqml/NewsTab.qml +++ b/source-android/qml/newsqml/NewsTab.qml @@ -29,37 +29,16 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls 2.3 as QC2 +import QtQuick 2.11 +import QtQuick.Controls 2.4 //import QtQuick.Controls.Styles 2.3 -import QtQuick.Dialogs 1.3 -import "qrc:/qml/genericqml" +//import QtQuick.Dialogs 1.3 +import "qrc:/qml/newsqml" import "qrc:/js/news.js" as Newsjs import "qrc:/js/helper.js" as Helperjs import "qrc:/js/service.js" as Service - -import AndroidNative 1.0 - Item { - Connections{ - target:newstab - onNewstabstatusChanged:{ - newstabstatusButton.text= qsTr(newstab.newstabstatus) - } - } - - Connections{ - target:xhr - onError:{ - Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root); - } - onSuccess:{ - // downloadNotice.text=downloadNotice.text+ "\n xhr finished "+Date.now(); - Service.processNews(api,data); - } - } // Connections{ // target:xhr @@ -80,43 +59,18 @@ Item { // } - Timer {id:replytimer; interval: 1000; running: false; repeat: false - onTriggered: { - if(newstab.newstabstatus=="Conversation"){ - showConversation(newsStack.timelineIndex-1,newsModel.get(0).newsitemobject)} - else{ - Service.updateView(newstab.newstabstatus) - } - } - } + Timer {id:contacttimer; interval: 50; running: false; repeat: false - onTriggered: { + onTriggered: {//print("Contacttimer "+JSON.stringify(root.news)); // downloadNotice.text=downloadNotice.text + "\n contactTimer start "+ Date.now() root.newContacts=Newsjs.findNewContacts(root.news,root.contactlist); Newsjs.storeNews(login,db,root.news,root) } } - - - function showNews(newsToShow){ - try{ - if (newsStack.depth>1){newsStack.pop()} - }catch(e){} - newsBusy.running=false; - var currentTime= new Date(); - // downloadNotice.text=downloadNotice.text + "\n shownews start "+ Date.now(); - //print("appendnews "+newsStack.appendNews +JSON.stringify(newsToShow)) - var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow,'method':newsStack.updateMethodNews, 'options':globaloptions}; - newsWorker.sendMessage(msg); - //newsStack.appendNews=false - } - - - function showConversation(conversationIndex,newsitemobject){ - if(newsitemobject.messagetype==0){ + if(newsitemobject.messagetype==0 || newsitemobject.messagetype==3){ xhr.clearParams(); xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setUrl(login.server); @@ -134,31 +88,12 @@ Item { } } - function showContact(contact){ - newstab.newstabstatus="Contact"; - newsStack.push({item:"qrc:/qml/newsqml/ContactPage.qml",properties:{"contact": contact}}); - } - - function search(term){//print("Search "+term) - if (term!=""){ - newstab.newstabstatus="Search"; - newsBusy.running=true; - newsStack.updateMethodNews="refresh"; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/search"); - xhr.clearParams(); - xhr.setParam("q",term) - xhr.get();} - newsView.anchors.topMargin=7*mm - } - function onFriendsMessages(friend){ newstab.newstabstatus="Contact" - Newsjs.newsfromdb(db,root.login.username, function(dbnews){ + Newsjs.newsfromdb(db,root.login.username, 0,function(dbnews){ if (dbnews.length==0){ - Newsjs.newsfromdb(db,login.username,function(forumnews){ + Newsjs.newsfromdb(db,login.username,0,function(forumnews){ showNews(forumnews) },friend.url) } @@ -166,303 +101,84 @@ Item { },friend.id) } - function onDirectMessage(friend){ - //newstab.newstabstatus="SendMessage" ,"login":login , - newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1, "login":root.login}}); - } - - function sendUrls(urls){print(root.currentIndex==0); - if((urls.length==1)&&(newsStack.depth<2)){ - newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"attachImageURLs":urls}}) + Label{ + text:"\uf0c9 " + font.pixelSize: 5* mm + anchors.left: parent.left + anchors.margins: mm + color: "#B0BEC5" + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.open() + } } } - - function sendtext(text){ - if(text&&(newsStack.depth<2)){ - if (text.subject=="undefined"){text.subject=""} - if(text.plaintext.lastIndexOf(".jpg")>-1 || text.plaintext.lastIndexOf(".jpeg")>-1 || text.plaintext.lastIndexOf(".png")>-1 || text.plaintext.lastIndexOf(".gif")>-1){ - text.plaintext=""} - newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"bodyMessage":text.subject+"\n"+text.plaintext}}) - } + Label{ + text:qsTr(newsSwipeview.stacktype) + font.pixelSize: 3* mm + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 2*mm } + SwipeView{ + id: newsSwipeview + property string stacktype:"Home" + currentIndex: 0 + width: parent.width + height: parent.height-6*mm + y: 5*mm + function onDirectMessage(friend){currentIndex=2} - StackView{ - id: newsStack - anchors.fill:parent - property string updateMethodNews: "refresh" - property var allchats: ({}) - initialItem:Rectangle { - id:newslistRectangle - y:1 - color: "white" - - BlueButton{ - id:newstabstatusButton - anchors.top: parent.top - anchors.topMargin: 0.5*mm - text: qsTr(newstab.newstabstatus) - onClicked: {newstabmenu.popup(2*mm,6*mm)} - - QC2.Menu{id:newstabmenu - width: 40*mm - - delegate:QC2.MenuItem{ - contentItem: Text{ - font.pixelSize: 3.5*mm - text:parent.text - } - background: Rectangle { - implicitWidth: 40*mm; implicitHeight: 5*mm - color: "#ffffff" - border.color: "grey" - } - } - QC2.Action { - text: qsTr("Timeline") - onTriggered: { - newstab.newstabstatus="Timeline"; - //newsModel.clear(); - try{ Newsjs.newsfromdb(root.db,root.login.username, function(dbnews){ - showNews(dbnews) - })}catch(e){Helperjs.showMessage("Error",e,root)}} - } - QC2.Action { - text: qsTr("Conversations") - onTriggered:{ - //newsModel.clear(); - newstab.newstabstatus="Conversations"; - Newsjs.chatsfromdb(db,root.login.username,function(news){showNews(news)}) - } - } - QC2.Action { - text: qsTr("Favorites") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Favorites"; - Service.updateView("Favorites") - } - } - QC2.Action { - text: qsTr("Replies") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Replies"; - Service.updateView("Replies") - } - } - QC2.Action { - text: qsTr("Public timeline") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Public Timeline"; - Service.updateView("Public Timeline") - } - } - - QC2.Action { - text: qsTr("Direct Messages") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Direct Messages"; - Service.updateView("Direct Messages") - } - } - QC2.Action { - text: qsTr("Notifications") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Notifications"; - Service.updateView("Notifications") - } - } - QC2.Action { - - text: qsTr("Group news") - onTriggered: - { - newsStack.updateMethodNews="refresh"; - Service.showGroups(); - } - } - QC2.Action { - text: qsTr("Quit") - onTriggered:{ - Service.cleanNews(root.db,function(){ - Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) - }) - } - } + transitions: Transition { + PropertyAnimation { properties: "height"; + easing.type: Easing.InOutQuad + duration: 1000 } } - Row{ - spacing: mm - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right: parent.right - - BlueButton { - id: searchButton - text: "\uf002" - onClicked: { - newsView.anchors.topMargin=18*mm; - var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml"); - var searchItem = component.createObject(newsStack,{y:8*mm,width:root.width,height: 8*mm}); - } - } - - BlueButton { - id: newMessageButton - text: "\uf040" - onClicked: { - var groups=[]; - Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){ - groups=groupobject - }); - newstab.newstabstatus="SendMessage"; - Helperjs.readData(root.db,"contacts",root.login.username,function(friends){ - newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"contacts": friends,"login":root.login}) - },"isFriend",1); - } - } -// BlueButton { -// id: quitButton -// text: "\uf08b" -// onClicked: {Service.cleanNews(root.db,function(){ -// Service.cleanContacts(root.login,root.db,function(){ -// Qt.quit() }) -// })} -// } - BlueButton { - id: update - text: "\uf021" - onClicked: { - if (newstab.newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else {newsStack.updateMethodNews="refresh"} - //root.contactLoadType="news"; - Service.updateView(newstab.newstabstatus) + onCurrentIndexChanged: { + switch(currentIndex){ + case 0: stacktype="Home";break; + case 1: stacktype="Replies";break; + case 2: stacktype="DirectMessages";break; + case 3: stacktype="Notifications";break; + default: stacktype="Home"; } } - + //anchors.fill: parent + Loader{ + id: friendstimeline + source:(newsSwipeview.currentIndex==0)? "qrc:/qml/newsqml/NewsStack.qml":"" + //onLoaded: newsSwipeview.stacktype="Home" } - Component { id:footerComponent - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - width:newsView.width - height:6*mm - Text{ - font.pixelSize: 1.5*mm - anchors.centerIn: parent - text:qsTr("More") - } - MouseArea{anchors.fill:parent - onClicked:{ - var currentTime= new Date(); - var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; - if(newstab.newstabstatus=="Timeline"){ - Newsjs.newsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions}; - newsWorker.sendMessage(msg); - },false,lastnews_id)} - if(newstab.newstabstatus=="Conversations"){ - Newsjs.chatsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions}; - newsWorker.sendMessage(msg); - },lastnews_id)} -// else if(newstab.newstabstatus=="Contact"){ -// Newsjs.newsfromdb(root.db,root.login.username, function(news){ -// var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; -// newsWorker.sendMessage(msg); -// },newsModel.get(newsModel.count-1).newsitemobject.uid,lastnews_id)} - else if (newstab.newstabstatus=="Notifications"){} - else{ - //newsStack.appendNews=true; - xhr.setParam("max_id",newsModel.get(newsModel.count-1).newsitemobject.id-1); - xhr.get() - }} - } - } + Loader{ + id: replies + //property string stacktype:"Replies" + source:(newsSwipeview.currentIndex==1)? "qrc:/qml/newsqml/NewsStack.qml":"" + //onLoaded: newsSwipeview.stacktype="Replies" } - - - ListView { - id: newsView - anchors.fill: parent - anchors.topMargin: 7*root.mm - anchors.leftMargin: 3*root.mm; anchors.rightMargin: root.mm - anchors.bottomMargin: 1*root.mm - clip: true - spacing: 0 - footer: footerComponent - model: newsModel - delegate: Newsitem{} - //onContentYChanged:{if(contentY<-8*mm&&contentY>(-8*mm-1)){print("refreshing"); - onDragEnded:{if(contentY<-5*mm){ - var onlynew=true; - Service.updateView(newstab.newstabstatus) - }} + Loader{ + id: directmessages + property var friend:({}) + source:(newsSwipeview.currentIndex==2)? "qrc:/qml/newsqml/NewsStack.qml":"" + //onLoaded: newsSwipeview.stacktype="DirectMessages" } - - ListModel{id: newsModel} - - WorkerScript { - id: newsWorker - source: "qrc:/js/newsworker.js" - } - - BusyIndicator{ - id: newsBusy - anchors.horizontalCenter: newsView.horizontalCenter - anchors.top:newsView.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - } - Rectangle{ - id:downloadNotice - property alias text: noticeText.text - color:"white" - border.color:"grey" - z:1 - anchors.horizontalCenter: newsView.horizontalCenter - anchors.bottom:newsView.bottom - anchors.bottomMargin: 2*mm - width: noticeText.width+2*mm - height: noticeText.height+2*mm - visible: (downloadNotice.text!="") - - Text{ - id:noticeText - color: "grey" - anchors.centerIn: parent - width: contentWidth - height: contentHeight - font.pixelSize: 2*mm - text:"" - } - } - - Component.onCompleted: { - root.messageSignal.connect(onFriendsMessages); - root.directmessageSignal.connect(onDirectMessage); - root.contactdetailsSignal.connect(showContact); - root.newsSignal.connect(showNews); - root.uploadSignal.connect(sendUrls); - root.sendtextSignal.connect(sendtext); - try{newsModel.clear()} catch(e){} -// xhr.setLogin(login.username+":"+Qt.atob(login.password)); -// xhr.setUrl(login.server); - if(root.news.length>0){showNews(root.news)} - else{ newstab.newstabstatus=login.newsViewType; - if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){showNews(dbnews)})} - else{Newsjs.chatsfromdb(db,login.username,function(dbnews){ - showNews(dbnews); - })} - } + Loader{ + id: notifications + //property string stacktype:"Notifications" + source:(newsSwipeview.currentIndex==3)? "qrc:/qml/newsqml/NewsStack.qml":"" + //onLoaded: newsSwipeview.stacktype="Notifications" } - } - } + Component.onCompleted: {root.directmessageSignal.connect(onDirectMessage);} + } + + PageIndicator { + id: swipeIndicator + count: newsSwipeview.count + currentIndex: newsSwipeview.currentIndex + + anchors.bottom: newsSwipeview.bottom + anchors.horizontalCenter: parent.horizontalCenter + } + } diff --git a/source-android/qml/newsqml/Newsitem.qml b/source-android/qml/newsqml/Newsitem.qml index 72f5980..8dabc67 100644 --- a/source-android/qml/newsqml/Newsitem.qml +++ b/source-android/qml/newsqml/Newsitem.qml @@ -30,8 +30,8 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.4 +//import QtQuick.Controls.Styles 1.4 import "qrc:/js/news.js" as Newsjs import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -62,7 +62,7 @@ Item { Rectangle{ width:newsitem.width height:newsitem.height-1 - color: (newsitemobject.messagetype==1)?"#ffe6e6" : "white" + color: "white"//(newsitemobject.messagetype==1)?"#ffe6e6" : "white" Row{id:toprow Column { @@ -102,8 +102,7 @@ Item { Label { id:messageTypeLabel color: "grey" - text: if (newsitemobject.messagetype==0){qsTr("Source: ")+newsitemobject.source - } else if (newsitemobject.messagetype==1){ qsTr("Direct Message")} else {" Notification"} + text: if (newsitemobject.messagetype==1){ qsTr("Direct Message")} else if(newsitemobject.messagetype==2) {" Notification"} else {qsTr("Source: ")+newsitemobject.source} font.pixelSize: 1.5*mm } Label { @@ -117,6 +116,7 @@ Item { id:replytoLabel color: "grey" font.pixelSize: 1.5*mm + font.family: "Noto Sans" horizontalAlignment: Label.AlignRight text: try {qsTr("In reply to ")+newsitemobject.reply_user.screen_name }catch(e){" "} @@ -160,6 +160,7 @@ Item { linkColor: "light green" id: itemMessage textFormat: Text.RichText + font.family: "Noto Sans" text: newsitemobject.statusnet_html//newsitemobject.attachmentList.length>0?newsitemobject.text : newsitemobject.statusnet_html width: newsitem.width-8*mm-2 height: implicitHeight @@ -178,7 +179,6 @@ Item { }} if (newsitemobject.attachmentList.length>0){ - for(var attachments in newsitemobject.attachmentList){// (newsitemobject.attachmentList[attachments].url); if(newsitemobject.attachmentList[attachments].mimetype.substring(0,5)=="image"){ var component = Qt.createComponent("qrc:/qml/newsqml/NewsImage.qml"); @@ -191,8 +191,7 @@ Item { else {//print(newsitemobject.attachmentList[attachments].url+" Type: "+newsitemobject.attachmentList[attachments].mimetype) var component = Qt.createComponent("qrc:/qml/newsqml/NewsVideo.qml"); var videoQml = component.createObject(messageColumn,{"source":newsitemobject.attachmentList[attachments].url,"mimetype":newsitemobject.attachmentList[attachments].mimetype}); -} - + } } } } @@ -289,9 +288,9 @@ Item { CheckBox{ id:likeCheckbox width:10*mm - visible: (newsitemobject.messagetype==0)? true:false + visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false checked:(friendica_activities.self.liked==1)?true:false - style: CheckBoxStyle { + //style: CheckBoxStyle { indicator: Rectangle{ implicitWidth: 10*mm implicitHeight:3*mm @@ -299,11 +298,11 @@ Item { anchors.centerIn: parent font.pixelSize: 2.5*mm font.family:fontAwesome.name - color:control.checked?"black": "grey" - text:control.checked?"\uf118"+"!":"\uf118" + color:likeCheckbox.checked?"black": "grey" + text:likeCheckbox.checked?"\uf118"+"!":"\uf118" } } - } + //} onClicked: { if(likeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"like",newsitemobject.id,root);dislikeCheckbox.checked=false; model.friendica_activities.self.liked=0 } else{Newsjs.like(root.login,root.db,0,"like",newsitemobject.id,root); model.friendica_activities.self.liked=1}} @@ -311,9 +310,9 @@ Item { CheckBox{ id: dislikeCheckbox width:10*mm - visible: (newsitemobject.messagetype==0)? true:false + visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false checked: (friendica_activities.self.disliked==1)?true:false - style: CheckBoxStyle { + //style: CheckBoxStyle { indicator: Rectangle{ implicitWidth: 10*mm implicitHeight:3*mm @@ -321,11 +320,11 @@ Item { anchors.centerIn: parent font.pixelSize: 2.5*mm font.family:fontAwesome.name - color:control.checked?"black": "grey" - text: control.checked?"\uf119"+"!":"\uf119" + color:dislikeCheckbox.checked?"black": "grey" + text: dislikeCheckbox.checked?"\uf119"+"!":"\uf119" } } - } + //} onClicked: { if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.id,root);likeCheckbox.checked=false; model.friendica_activities.self.disliked=0} else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.id,root); model.friendica_activities.self.disliked=1}} @@ -333,20 +332,20 @@ Item { CheckBox { id:favoritedCheckbox - visible:(newsitemobject.messagetype==0) + visible:((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3)) width: 10*mm - style: CheckBoxStyle { + //style: CheckBoxStyle { indicator:Rectangle{ x:4*mm width: 3*mm implicitHeight:4*mm Text{ - color: control.checked?"black":"grey" + color: favoritedCheckbox.checked?"black":"grey" font.pixelSize: 2.5*mm text:"\uf005" } } - } + //} checked:(newsitemobject.favorited>0) onClicked:{ if(favoritedCheckbox.checkedState==Qt.Checked){ @@ -401,21 +400,29 @@ Item { Menu { id:newsmenu - MenuItem { + width: 30*mm + delegate: MenuItem{ + contentItem: Text{ + font.pixelSize: 3*mm + text: parent.text + } + } + Action{ text: qsTr("Reply") onTriggered: { var directmessage=0; if (newsitemobject.messagetype==1){ directmessage=1} - newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"reply_to_user": newsitemobject.user.screen_name,"parentId":newsitemobject.id,"login":root.login,"directmessage":directmessage}); + replySignal(newsitemobject) + //newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"reply_to_user": newsitemobject.user.screen_name,"parentId":newsitemobject.id,"login":root.login,"directmessage":directmessage}); } } - MenuItem { + Action { text: qsTr("DM") onTriggered: { root.directmessageSignal(newsitemobject.user.screen_name); } } - MenuItem { + Action { text: qsTr("Repost") onTriggered: { Newsjs.retweetNews(root.login,db,newsitemobject.id,root,function(reply){ @@ -423,7 +430,7 @@ Item { }) } } - MenuItem { + Action { text: qsTr("Conversation") onTriggered: { conversationsymbol.color="black"; @@ -435,24 +442,31 @@ Item { Menu{ title: qsTr("Attending") - MenuItem{ + width: 20*mm + delegate: MenuItem{ + contentItem: Text{ + font.pixelSize: 3*mm + text: parent.text + } + } + Action{ text:qsTr("yes") onTriggered: {Newsjs.attend(root.login,db,"yes",newsitemobject.id,root,function(){ model.friendica_activities.self.attending="yes";attending="yes"}) } } - MenuItem{text:qsTr("maybe") + Action{text:qsTr("maybe") onTriggered: {Newsjs.attend(root.login,db,"maybe",newsitemobject.id,root,function(){ model.friendica_activities.self.attending="maybe";attending="maybe"}) } } - MenuItem{text:qsTr("no") + Action{text:qsTr("no") onTriggered: {Newsjs.attend(root.login,db,"no",newsitemobject.id,root,function(){ model.friendica_activities.self.attending="no";attending="no"})} } } - MenuItem { + Action { text: qsTr("Delete") onTriggered: { Newsjs.deleteNews(root.login,root.db,newsitemobject.id,newsitemobject.messagetype,root,function(reply){ diff --git a/source-android/qml/newsqml/PermissionDialog.qml b/source-android/qml/newsqml/PermissionDialog.qml index f1a66c3..23aa704 100644 --- a/source-android/qml/newsqml/PermissionDialog.qml +++ b/source-android/qml/newsqml/PermissionDialog.qml @@ -30,6 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 +import QtQuick.Controls 2.3 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -37,7 +38,7 @@ import "qrc:/qml/genericqml" Rectangle{ id:permissionDialog x: mm - width: messageColumn.width-5*mm + width: messageColumn.width-3*mm height:root.height/3 function updatePerms(){ for (var i=0;i. -import QtQuick 2.7 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 1.11 +//import QtQuick.Controls.Styles 1.4 import "qrc:/js/smiley.js" as Smileyjs import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -42,8 +43,10 @@ Rectangle{ width: messageColumn.width-5*mm height:root.height/2 - BlueButton{ + Button{ id:closeButton + height: 6*mm + width: 8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right @@ -52,34 +55,57 @@ Rectangle{ onClicked:{smileyDialog.visible=false} } - TabView{ + + TabBar { + id: smileybar + width: parent.width + height: 9*mm + position:TabBar.Header + TabButton { + text:qsTr("Unicode") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Standard") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Addon") + font.pixelSize: 2*mm + } + + TabButton { + text: qsTr("Adult") + font.pixelSize: 2*mm + } + } + + + StackLayout{ id:smileyTabView - tabPosition: Qt.BottomEdge + currentIndex: smileybar.currentIndex anchors.top: closeButton.bottom anchors.topMargin: 1*mm width: smileyDialog.width-2*mm height: smileyDialog.height-7*mm - currentIndex: 0 - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle { - color: "white" - implicitWidth: smileyTabView.width/4-2*mm - implicitHeight: 4*mm - Text { id: text - anchors.centerIn: parent - text: styleData.title - color: "dark grey" - font.pixelSize:2.5*mm - font.bold: styleData.selected - } - } - frame: Rectangle { color: "light grey" } - tabsAlignment:Qt.AlignHCenter - } +// style: TabViewStyle { +// frameOverlap: 1 +// tab: Rectangle { +// color: "white" +// implicitWidth: smileyTabView.width/4-2*mm +// implicitHeight: 4*mm +// Text { id: text +// anchors.centerIn: parent +// text: styleData.title +// color: "dark grey" +// font.pixelSize:2.5*mm +// font.bold: styleData.selected +// } +// } +// frame: Rectangle { color: "light grey" } +// tabsAlignment:Qt.AlignHCenter +// } - Tab{ - title: qsTr("Unicode") Rectangle{ id: htmlGridTab GridView { @@ -101,9 +127,7 @@ Rectangle{ } } } - } - Tab{ - title: qsTr("Standard") + Rectangle{ id: coreGridTab GridView { @@ -127,9 +151,7 @@ Rectangle{ } } } - } - Tab{ - title: qsTr("Addon") + Rectangle{ id: addonGridTab GridView { @@ -151,9 +173,8 @@ Rectangle{ } } } - } - Tab{ - title: qsTr("Adult") + + Rectangle{ id: adultGridTab GridView { @@ -175,7 +196,7 @@ Rectangle{ } } } - } + @@ -218,6 +239,4 @@ Rectangle{ } } } - - } diff --git a/source-android/qml/photoqml/ImageUploadDialog.qml b/source-android/qml/photoqml/ImageUploadDialog.qml index a36aeed..9302135 100644 --- a/source-android/qml/photoqml/ImageUploadDialog.qml +++ b/source-android/qml/photoqml/ImageUploadDialog.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/image.js" as Imagejs import "qrc:/qml/genericqml" @@ -132,9 +132,11 @@ function updateImage(){ // } // } - BlueButton{ + Button{ id:closeButton + height: 8*mm text: "\uf057" + font.pixelSize: 3*mm onClicked:{photoStack.pop(); //imageDialog.destroy() } @@ -236,7 +238,7 @@ function updateImage(){ source:"qrc:/images/addImage.png" MouseArea{ anchors.fill: parent - onClicked:{print(imagePicking) + onClicked:{ imagePicking=true; var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+ @@ -264,10 +266,12 @@ function updateImage(){ ListModel{id:albumModel} - BlueButton{ + Button{ id:uploadButton + height: 8*mm x:4*mm; y:root.width/2+18*mm //40*mm text: imageId==""?qsTr("Upload"):qsTr("Change") + font.pixelSize: 3*mm onClicked:{ if(album.currentText==""){Helperjs.showMessage(qsTr("Error"),qsTr(" No album name given"), imageDialog)} else if (imageId!=""){uploadBusy.running=true; updateImage()} diff --git a/source-android/qml/photoqml/PhotoTab.qml b/source-android/qml/photoqml/PhotoTab.qml index 4ebacac..7c54269 100644 --- a/source-android/qml/photoqml/PhotoTab.qml +++ b/source-android/qml/photoqml/PhotoTab.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.4 import QtQml.Models 2.1 import "qrc:/js/image.js" as Imagejs import "qrc:/js/helper.js" as Helperjs @@ -40,12 +40,13 @@ import "qrc:/qml/genericqml" StackView{ id: photoStack - anchors.fill:parent + //anchors.fill:parent initialItem:Rectangle { id:fotorectangle - y:1 - width:root.width-mm - height:root.height-5*mm + anchors.fill:parent +// y:1 +// width:root.width-mm +// height:root.height-5*mm color: '#fff' property var newimages:[] property int currentimageno: 0 @@ -141,14 +142,14 @@ StackView{ function updatepic(method,type,id){ if(method=="update"){ Helperjs.readData(db,"imageData",login.username,function(url){ - photoStack.push({ - item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{attachImageURLs:[url[0].location+url[0].filename],imageId:id,currentAlbum:url[0].album} - }) + photoStack.push( + "qrc:/qml/photoqml/ImageUploadDialog.qml",{"attachImageURLs":[url[0].location+url[0].filename],"imageId":id,"currentAlbum":url[0].album} + ) },"id",id)} } function uploadUrls(urls){ - photoStack.push({item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{attachImageURLs:urls}}) + photoStack.push("qrc:/qml/photoqml/ImageUploadDialog.qml",{"attachImageURLs":urls}) } ProgressBar{ @@ -162,35 +163,43 @@ StackView{ value: fotorectangle.currentimageno/fotorectangle.newimages.length } - BlueButton{ + MButton{ id: uploadPhoto anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right:updatePhotolist.left anchors.rightMargin:mm + height: 6*mm + width: 8*mm text:"\uf0ee" - onClicked: {print(root.imagePicking) - photoStack.push({item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{}}); + onClicked: { + photoStack.push("qrc:/qml/photoqml/ImageUploadDialog.qml"); // var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml"); // var imageUpload = component.createObject(fotorectangle); }} - BlueButton{ + MButton{ id: updatePhotolist anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right:phototabstatusButton.left anchors.rightMargin:mm + height: 6*mm + width: 8*mm text:"\uf0ed" + Menu { id:photoupdatemenu + width:40*mm MenuItem { text: qsTr("All Images") + font.pixelSize: 3*mm onTriggered: { Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){fotorectangle.newimages=obj})} } MenuItem { text: qsTr("Only new") + font.pixelSize: 3*mm onTriggered: { Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){fotorectangle.newimages=obj})} } @@ -198,17 +207,21 @@ StackView{ onClicked: {photoupdatemenu.popup()} } - BlueButton{ + MButton{ id: phototabstatusButton anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right: parent.right anchors.rightMargin:2*mm + height: 6*mm + width: Math.max(10*mm,implicitWidth) text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus Menu { id:phototabmenu + width: 40*mm MenuItem { text: qsTr("Own Images") + font.pixelSize: 3*mm onTriggered: { fotostab.phototabstatus="Images"; // phototabstatusButton.text=qsTr("Own images"); @@ -267,8 +280,10 @@ StackView{ ListView { width: parent.width; height:parent.height; model: visualphotoModel.parts.browser; interactive: false } - BlueButton { + MButton { id: backButton + height: 6*mm + width: 8*mm text: "\uf057" x: parent.width - backButton.width - 3*mm y: -backButton.height - 4*mm diff --git a/source-android/qtquickcontrols2.conf b/source-android/qtquickcontrols2.conf new file mode 100644 index 0000000..3222ebf --- /dev/null +++ b/source-android/qtquickcontrols2.conf @@ -0,0 +1,14 @@ +[Controls] +Style=Material + +[Universal] +Theme=System +Accent=Red + +[Material] +Theme=Light +Accent=LightBlue +Primary=BlueGrey,50 +Background=Grey,50 +Variant=Dense + diff --git a/source-android/translations/friendiqa-de.qm b/source-android/translations/friendiqa-de.qm index ec5be92fa8c3fa69a82916cafe71892772655592..642a1803ab9025ee55856b3e37cffcd5991dcd8e 100644 GIT binary patch delta 2465 zcmZ8ieRNax8Gh2_-kW=qG^P1~wG;v^w8au(Yo~mbmL6ITXe+c6PLV;H-j+z3&?Z59 zHq18bVYBrV7AN2`bOIZ-I+!_ltmr-*OZf;L$`bYZY z_x|3G=Y8JymtJ~c=f<7RcnM&70?4rdLIt4I15yK!Tcu<16ynRkbO+EJ1k83F<%e{1 znSk~SK;d732Y*Do1$<`?ko{dC{s-o1*Rga9gsN=7a{xl^W4u48W8BdRVFe50Dug~J zn;C;}qy`Z4A)J1L%?I!;165Dq4QSp|p~*y-0)MEcoTuA<}YsfenFfZ0Qcp1ua;{RHt>=wDig z{ZfR)3osB|!1|sMT&$&RQ}4p3Wi7<*hVMVTAIQHaYkuwqz;ZroV9#?5+?6#P`5j

%y^|>71F5|nQXL-NC`02_=spujdXS5mrXRZW_Qzqd|ii93B zEi#^C+#9BSJ#i*bE|^{@J4nL{)2S`}<^cDgB**l}VFm~rOlR+Z8!!}@E@}7n zKGVlRcA(_zm^&3ce}MJ4C{Hr^Us-S@hp1E1AnX-X;3Y zkDC)SN&(w%%+Fu^fV2D3eE2N4Q@o|4dAE+v9P{gar$}VbeDY2bn|axMx*?kdPnbXZ z7k4N-PtGrPazu~I`Hz!G(KGVB?Ki3DavjZY>1dg(qq9NY@VD=AB=Nt<{+-hHXQt%BQRSxu3N{M z*IJJmBHWp^)(@*XnNP6^cJ566fUWZSKFNDy7^Pif|CO7H6s-vWbLtXL3tp?G+V2m?Lecwt?P}ttV@alA zaMG+y!wPX;rr~4JlWA~BrJ06WsVviAGat(|{K?#%Y52RmHq)?3nP5mNt1~^mP$pEF zYnh$tvB5Go)3C+;%}m4H)(O3|SnF)#1u`V^gr39>(YsEm35VJO?V4%^BUfk+su4pJ zVRXO?4^LZoiou5<0*LUVqKoGc+RfU^iTs!vyF-47U&bX%Jd=G_>aulMDEK;7F($wW z50*3QRe*7*a>4RM~wwXi0PQ z!H>=4?H$W2hQiT6Tep_lrfF6a?${a*siA0^g_$fgv2XjEBBR1)dMAD>dMt{bKpS4- zNlWvRap!b4D`gK;si?+fjDdOdl|(cSa$8q`5(GMZ+JjNX9d|kxj6c5REMI;5Hl02X zH#o<(^o}%fx*aT|ZAb{}STXy3v6f)K?`aBjsKG!;olx_?uCnn(u1_s>OKa4&E;X`w zf~VJAQ9q%+f<}&B6Zm#Lu~GGP`6mRAvR$6$rY()eGnn}2G^e{!jYb2Z_K8~XIgR6$ Jx>EeG_bz-6n<^8yV*_Bq-lCUTe>Cmf&xXTN~y>-t$>wE8gSvR|V z#yYc~h}3I{OjSfoE|GQx5m!uPzNlb&0`L$~>H(q>ClNnVL7`E>_^m{aD@4675Y1l= zd_v^^jwlv&J27(sF(aagB0eRiU=@*}L%}$Km^aYRAJIz8q6VUvCB)RKiHz5XY5o>X zQ;6L-ohYG}*d0y4W5hP9h%6bzw)Q9LnM>?_#93|<_gf7JUZDJb_lVdl3Pw+)!u_*A zNJoX=3<2iTo102OgcQ_m2%(?!b7<=PASNRP1)qZPcA9o-D2Qz)$HwCzAX2$AK-4Fh zyb+iz@iBSVVj^?Bf@w+QllBs&HIc9RE>ZFT@*hTgW+BycUZNg{sL_df?7MWM09)$S zO1H90vHz5~h?SM~NN9^3WSU8&=OP>Hb|Ga^QAZc8 zK9KF-je>a!=12xYWPIgge7t8VY~o7Cz*oL*?8NWs`y3>$+@ z#Fa7J6ANyBj^XcY!-i@ZV`45QtYNZE(L|~yX4t|#h#Sm|zdsnKn!?nEPTs=Q`S-ht zG$)z5P813hjL%`VY{6|=GjpH@+DNQqPVNQK_@9|mxjry&W^UKKO_a2TwTz3w2IsLk zdqFh0l+CxLK^yl|$05!*5f{*3#q|Ce!S)U%9J zO$uOwPq^3|6gF<-`o0gP>(_H5W}tD}WUip(F7S75`Bf_>EaqyiLR_MY+hAbOcq_N% z;WA8?#_g}gMiM4+hnsMs%s;uNoOTdAqY0#D5k;-m?7Q(RPIg&yumz&j4Du@ve6xaa zjhd4SMi52XHKzuGP;{)Oxi|_9Px6TwX1wp<6F&k0%XYrV@fZabD=4TG)QwdzuAQIx z(+V8$7;mp`1JP@|t24fboBz=NB?e65*BnP3t$z>y^;|H{ST4kU^$>xAFt_y_j=e&V z#)B!h`6*skkpDn%PJe(2JA~@b`rvO>CNyoqX4o;pk+qYt@+RSU``;jbR!fZoAi|Ma zCdCd7$=W%V^VswrZQY5RAo4)F>4!V`|C?XZS$0=JoriS;FJ1g`V256(#DE;t`Z4l=uy<9LFbr$Qr!Qp5)P`~y# z;lcH1d4`gGQ5ZOA*fqL>j1<}5@Od0oVVNisWfcat3)O)Frmw({E_ct9 z9g}UPfo05V;pR?bTDWE*`2NJa}hr8O+#Bei3NHAG#E{Vf_!^+QMv%;eSY_`A4 z8=*q*II@zBTqKbQte|uI zU0pzDh?^C^i@~NpjU+cM#rraNL_9y`9BAQEvXialqRUn(yDD6wTUzWD-4(7<$s>jc zrM^HUUNbeE$kOiSCCyvm-aI}#-1PA2;bsHhKio8?mxP;__-vH-9Fn(l%x5`) zo9RO}&y7JDLzs{eIGAARdTlhn?tc~&YGR@ybZ|l>6 + + AccountPage + + + + + User + Name + + + + Server + Server + + + + Nickname + Kurzname + + + + Password + Passwort + + + + Image dir. + Bildverz. + + + + News as + Anzeige + + + + + + Error + Fehler + + + + Nicknames containing @ symbol currently not supported + Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. + + + + Confirm + Bestätigen + + + + No server given! + Kein Server angegeben! + + + + No nickname given! + Kein Kurzname angegeben! + + + + No password given! + Kein Passwort angegeben! + + + + No image directory given! + Kein Verzeichnis für Bilder angegeben! + + + + Wrong password! + Falsches Passwort! + + + + Success + Bestätigt + + + + Name + Name + + + + Timeline + Chronologisch + + + + Conversations + Unterhaltungen + + CalendarTab - + Events Termine - + Own Calendar Eigener Kalender - ConfigTab + ConfigPage - - - - User - Name - - - - Server - Server - - - - Nickname - Kurzname - - - - Password - Passwort - - - - Image dir. - Bildverz. - - - + Max. News Max. Nachr. - + + Sync + Autom. Aktualisierung + + + + ConfigTab + + User + Name + + + Server + Server + + + Nickname + Kurzname + + + Password + Passwort + + + Image dir. + Bildverz. + + + Max. News + Max. Nachr. + + News as - Anzeige + Anzeige Interval (0=None) Intervall (0=keins) - - - Error - Fehler + Fehler Nickname not registered at given server! Name auf der Seite nicht registriert! - Confirm - Bestätigen + Bestätigen - No server given! - Kein Server angegeben! + Kein Server angegeben! - No nickname given! - Kein Kurzname angegeben! + Kein Kurzname angegeben! - Nickname not registered at given server! - Name auf der Seite nicht registriert! + Name auf der Seite nicht registriert! No username given! Kein Nutzername angegeben! - Sync Interval (0=None) - Akt.-intervall (0=keine) + Akt.-intervall (0=keine) - Nicknames containing @ symbol currently not supported - Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. + Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. - Min. - Min. + Min. - No password given! - Kein Passwort angegeben! + Kein Passwort angegeben! - No image directory given! - Kein Verzeichnis für Bilder angegeben! + Kein Verzeichnis für Bilder angegeben! - No maximum news number given! - Maximale News-Anzahl nicht angegeben! + Maximale News-Anzahl nicht angegeben! - Wrong password! - Falsches Passwort! + Falsches Passwort! - Success - Bestätigt + Bestätigt - Name - Name + Name - Timeline - Chronologisch + Chronologisch - Conversations - Unterhaltungen + Unterhaltungen @@ -197,27 +280,27 @@ Kontaktanfrage - + Description Beschreibung - + Location Ort - + Posts Beiträge - + URL Profilseite - + Created at Erstellt @@ -225,22 +308,22 @@ FriendsTab - + Me Ich - + Friends Freunde - + Contacts Kontakte - + Groups Gruppen @@ -272,27 +355,27 @@ Bild - + Description Beschreibung - + Upload Hochladen - + Change Ändern - + Error Fehler - + No album name given Kein Albumname angegeben @@ -300,22 +383,54 @@ MessageSend - + + + + + to: + an: + + + Title (optional) Überschrift (optional) - + + What's on your mind? + Woran denkst du gerade? + + + + Error Fehler - + Only one attachment supported at the moment. Remove other attachment first! Nur ein Anhang derzeit unterstützt. Lösche zuerst den anderen Anhang! + + + No receiver supplied! + Kein Empfänger angegeben! + + + + NewsStack + + + Network Error + Netzwerk-Fehler + + + + More + Mehr + NewsTab @@ -324,63 +439,52 @@ Lade Profilbild für - More - Mehr + Mehr - Timeline - Chronologisch + Chronologisch Error Fehler - Favorites - Markierte News + Markierte News - Conversations - Unterhaltungen + Unterhaltungen - Network Error - Netzwerk-Fehler + Netzwerk-Fehler - Replies - Interaktionen + Interaktionen - Public timeline - Gemeinschaft + Gemeinschaft - Direct Messages - Direktnachrichten + Direktnachrichten - Notifications - Meldungen + Meldungen - Group news - News Gruppe + News Gruppe - Quit - Schliessen + Schliessen @@ -396,7 +500,7 @@ Quelle: - + Direct Message Direktnachricht @@ -411,65 +515,60 @@ Kommentare - + Attending: Teilnahme: - + Reply Antworten - + DM Direktnachricht - + Repost Teilen - + Success! Erledigt! - + Conversation Unterhaltung - + Attending Teilnahme - + yes ja - + maybe vielleicht - + no nein - + Delete Löschen - - - Post - - PermissionDialog @@ -487,28 +586,28 @@ PhotoTab - + 's images s Bilder - + All Images Alle Bilder - + Only new Nur neue - - + + Own Images Eigene Bilder - + More Mehr @@ -516,222 +615,222 @@ ProfileComponent - + profile name Profilname - + is default Hauptprofil - + hide friends Verberge Freunde - + profile photo Profilbild - + profile thumb Mini-Profilbild - + publish öffentlich - + publish in network Öffentlich im Netzwerk - + description Beschreibung - + date of birth Geburtstag - + address Adresse - + city Stadt - + region Region - + postal code Postleitzahl - + country Land - + hometown Heimatstadt - + gender Geschlecht - + marital status Beziehungsstatus - + married with verheiratet mit - + married since verheiratet seit - + sexual Sex - + politics Politik - + religion Religion - + public keywords öffentliche Schlagwörter - + private keywords private Schlagwörter - + likes Vorlieben - + dislikes Abneigungen - + about über - + music Musik - + book Bücher - + tv TV - + film Filme - + interest Interessen - + romance Liebschaften - + work Arbeit - + education Bildung - + social networks Soziale Netzwerke - + homepage Homepage - + Update Aktualisieren - + profile id Profil-Nummer - + Description Beschreibung - + Location Ort - + Posts Beiträge - + URL Profilseite - + Created at Erstellt @@ -739,101 +838,183 @@ SmileyDialog - + Unicode Unicode - + Standard Standard - + Addon Addon - + Adult XXX + + SyncComponent + + + sync + akt. + + + + notify + benachr. + + + + SyncConfig + + + Sync Interval (0=None) + Akt.-intervall (0=keine) + + + + Min. + Min. + + + + friendiqa + + + Refresh + Aktualisieren + + + + Timeline + Chronologisch + + + + Conversations + Unterhaltungen + + + + Favorites + Markierte News + + + + Replies + Interaktionen + + + + Public Timeline + öff. Timeline + + + + Group news + News Gruppe + + + + Search + Suche + + + + Settings + Einstellungen + + + + Accounts + Konten + + + + Quit + Schliessen + + newsworker - + likes this. mag das. - + like this. mögen das. - + doesn't like this. mag das nicht. - + don't like this. mögen das nicht. - + will attend. nehmen teil. - + persons will attend. Personen nehmen teil. - + will not attend. nimmt nicht teil. - + persons will not attend. Personen nehmen nicht teil. - + may attend. nimmt vielleicht teil. - + persons may attend. Personen nehmen vielleicht teil. - + yes ja - + no nein - + maybe vielleicht - + seconds Sekunden - - @@ -842,51 +1023,53 @@ + + ago her - + minute Minute - + minutes Minuten - + hour Stunde - + hours Stunden - + day Tag - + days Tage - + month Monat - + months Monate - + years @@ -898,12 +1081,12 @@ Fehler - + Undefined Array Error Antwort-Array ungültig - + JSON status Error Server-Antwort: Fehler diff --git a/source-android/translations/friendiqa-es.qm b/source-android/translations/friendiqa-es.qm index be15226a3a25bdfecb3d184c2dae3035cbd43557..840815743aeec3d5dcc0be5385f5ec9ff266eb17 100644 GIT binary patch delta 1509 zcmZ8fYiv_x7=G4szH@84-gfCI#^5GIwhU0JX~yQd!A88Sn#m;#xRtJ}ou#w1!(>6L zd=GP~Yts>G8+O^L@{GpZ9y; z=Y0=W9j@G$lk5WcJwSFjz}$em4iJ5Sb%%xphk=F&ojn>#2Q_rG0HN=Iyd=>25@8BR zeoVT5(KQBEvmG#fqoM6A*h)KgN!r6~R@NJ-=7Ri$o;QG+8#J(O-#to^iUSO_l7>W-7hAGaw^eb{I#nsf= z$+a8Yw^4G(aDe;ep{-PqN5h==xm!{NFlQ0ZE>J-Q4!(@LM7m%3L)%C%PxHr1`sm)l z4^M*ZvpV?;N9sthkN- z+sx#vhXCh%W_7vAsROLUZX!8vk_h`adu7fyD``LMSf*d#@RKMw<0+tI6&l5@m!tm=&l&D`Attus_o)Nivl^$3o=9aD^ zeY3c*(+e2=V&yvO(D{Q{({PO(h>6dAPYvc@7Ehic=jProsq^lk-PkD|O^*FY53ZKp z8>QI_`5KCS8rqwr5nnbXipZ{)XA*ejM?-&6T%(5KWepX#hW0n)^bn=VxN6qBeoLfrsrHf=Kl;FekF6&Z~+Tlx$5TnYrcZz7qyvnH_s+=2E1}Cml zqD~`HrPRrgk=+>};YwroXIIIIaZ_R6R_c7Q$=5eUx(?IntT-*R&2*(QMxzXyD}JNV zm~WcHHP!V0x;dV%p!ZLh_YP8i>Cd~hgY}}N;V54_1!Tzyb->Pf$}N>2<(i}l0}X`!Adl^5uVM)`k|Zh5{wVnlx2oasxJdXC$nma$5s zQr#A935RCQYEp{RKE)-fetUr;*9D)A*C+ger`1loC*ztv?TCqLlK03ho5I0pb2#Q# zuh|wU8P_fOE_H?7l1WL9vb-n48-tN>G$_(!GosfxiXykKS=`Ltp$hGYBLKfdR|qp- tebB!t@RVLW8=Va=T4&=E2qONULaGlY65(hluGgrI@{-%{r5Cs+*+21)oV5S| delta 1606 zcmZ9KeM}p57{?#D``t@lXrYv~rOl2&vW)>ULnDMqU@WlAQKE<}#5qg3*4t=L+T+DU zt%2#H+p;BRbT~kqps=APkQkW$p&Q!(6_==Se`wsB$u^^VL0Gb6!v}7TV}CTCKJU-- z{as(_`#s>lD0|3@p0OAEOtN~!F0c;yJy7mIpHvw?8M!rE~nj0YW2f(Tzz^=EE zhXCTIux_VD_cV}-Hvy84XiRMbvIYAmOaR%By)5qmnL3HN0``IFZPRLr?enu&|B({xlY1>zU_%!b@+{R~O^fD1EId2Efm2w0%Vw z8%mz~D`6KhkvW9F)r$ko#G39!rM8lslw^R!pGk4^rx@=g`&;{QP9`~gJc3HKA>;Um z`&)C^dq{UTJ^?8rXT1t4@G4XOu?^qqE>r(HlHbQn_PmGNqrHybasCYe z>MFlCK7t?NxBP(#tTSxmPc))p=~oPm=YBv*I}CC0DO`XF7&LyUkt;In`78@1yki*e z#tTT;Fmd$`K0%=ohVt;DVIx@`z^7?3cKvt@73nc$4s_xm$y7ZshaYpk>D>kNQX+17179vjf>P*Ne}n3Gl<2J7q)dIVfi7VmMAdn2i#{|= zXX(w~Xs_P%kZiqqojg&v&L;(SNBm(?h{%c%6+==?5u;+G;8%o@)G9`Vm>6vpqZtB= z66)Xgo8cqy!3hu`3>TptB&4jGd8gXIq!!AM!C?|G`1AN=A?$CL!YyGT zBDTeZNK3dujA|1z9+`BVRO`2PaZjopj6?7GgsIh=ESs-4%h?rIzrwE3M~7D?dx*zI z*W%5OEaBpw)>o}It{+wSbXE;I3OUw?CoI0&Kgqdn%VsGm1{9%6jK%yRF}B#}VZxx} zvE}TGj%>0NQDu9^vU|i@^4Nme(CDuaS@2JshA?^6z^PgbO$6!0sO99cQS?krAK fq_Ef|MZ^`egU+nwA$aveV|32i%#M0pf06$H4o + + AccountPage + + + + + User + Usuario + + + + Server + Servidor + + + + Nickname + Usuario + + + + Password + Contraseña + + + + Image dir. + Dir. de imágenes + + + + News as + Noticias como + + + + + + Error + Error + + + + Nicknames containing @ symbol currently not supported + + + + + Confirm + Confirmar + + + + No server given! + ¡Servidor no encontrado! + + + + No nickname given! + ¡Usuario incorrecto! + + + + No password given! + ¡Contraseña incorrecta! + + + + No image directory given! + ¡No se ha encontrado el directorio de imágenes! + + + + Wrong password! + ¡Contraseña incorrecta! + + + + Success + éxito! + + + + Name + Nombre + + + + Timeline + Cronología + + + + Conversations + Conversaciones + + CalendarTab - + Events Eventos - + Own Calendar Calendario propio - ConfigTab + ConfigPage - - - - User - Usuario - - - - Server - Servidor - - - - Nickname - Usuario - - - - Password - Contraseña - - - - Image dir. - Dir. de imágenes - - - + Max. News Nº Max. de noticias. - + + Sync + + + + + ConfigTab + + User + Usuario + + + Server + Servidor + + + Nickname + Usuario + + + Password + Contraseña + + + Image dir. + Dir. de imágenes + + + Max. News + Nº Max. de noticias. + + News as - Noticias como + Noticias como Interval (0=None) Intervalo (0=ningún) - - - Error - Error + Error - Confirm - Confirmar + Confirmar - No server given! - ¡Servidor no encontrado! + ¡Servidor no encontrado! - No nickname given! - ¡Usuario incorrecto! + ¡Usuario incorrecto! - Nickname not registered at given server! - ¡Usuario incorrecto! + ¡Usuario incorrecto! No username given! ¡Usuario incorrecto! - - Sync Interval (0=None) - - - - - Nicknames containing @ symbol currently not supported - - - - - Min. - - - - No password given! - ¡Contraseña incorrecta! + ¡Contraseña incorrecta! - No image directory given! - ¡No se ha encontrado el directorio de imágenes! + ¡No se ha encontrado el directorio de imágenes! - No maximum news number given! - ¡Nº máximo de noticias incorrecto! + ¡Nº máximo de noticias incorrecto! - Wrong password! - ¡Contraseña incorrecta! + ¡Contraseña incorrecta! - Success - éxito! + éxito! - Name - Nombre + Nombre - Timeline - Cronología + Cronología - Conversations - Conversaciones + Conversaciones @@ -193,27 +264,27 @@ Conectar - + Description Descripción - + Location Localización - + Posts Mensajes - + URL URL - + Created at Creado en @@ -221,22 +292,22 @@ FriendsTab - + Me Yo - + Friends Amigos - + Contacts Contactos - + Groups Grupos @@ -257,27 +328,27 @@ imagen - + Description Descripción - + Upload Subir - + Change Cambiar - + Error Error - + No album name given ¡Nombre del álbum no encontrado! @@ -285,22 +356,54 @@ MessageSend - + + + + + to: + + + + Title (optional) Título (opcional) - + + What's on your mind? + + + + + Error Error - + Only one attachment supported at the moment. Remove other attachment first! Solo se admite adjuntar un solo archivo en este momento. ¡Elimine y deje un archivo adjunto! + + + No receiver supplied! + + + + + NewsStack + + + Network Error + Fallo de red + + + + More + Mas + NewsTab @@ -309,63 +412,48 @@ Descargar la imagen del perfil para - More - Mas + Mas - Timeline - Cronología + Cronología Error Error - Favorites - Favoritos + Favoritos - Conversations - Conversaciones + Conversaciones - Network Error - Fallo de red + Fallo de red - - Replies - - - - Public timeline - Cronología pública + Cronología pública - Direct Messages - Mensaje directo + Mensaje directo - Notifications - Notificaciones + Notificaciones - Group news - Grupos + Grupos - Quit - Salida + Salida @@ -381,7 +469,7 @@ Fuente: - + Direct Message Mensaje directo @@ -396,65 +484,60 @@ comentarios - + Attending: Asistiendo: - + Reply Respuesta - + DM Mensaje directo - + Repost Volver a publicar - + Success! éxito! - + Conversation Conversación - + Attending Asistiendo - + yes si - + maybe quizás - + no no - + Delete Borrar - - - Post - - PermissionDialog @@ -472,28 +555,28 @@ PhotoTab - + 's images s Imágenes - + All Images Todas las imagenes - + Only new Solo nueva - - + + Own Images Mis imágenes - + More Mas @@ -501,324 +584,406 @@ ProfileComponent - + profile name Nombre de perfil - + is default - + hide friends - + profile photo - + profile thumb - + publish - + publish in network - + description - + date of birth - + address - + city - + region - + postal code - + country - + hometown - + gender - + marital status - + married with - + married since - + sexual - + politics - + religion - + public keywords - + private keywords - + likes - + dislikes - + about - + music - + book - + tv - + film - + interest - + romance - + work - + education - + social networks - + homepage - + Update - + profile id - + Description - Descripción + Descripción - + Location - Localización + Localización - + Posts - Mensajes + Mensajes - + URL - URL + URL - + Created at - Creado en + Creado en SmileyDialog - + Unicode Unicode - + Standard Standard - + Addon Addon - + Adult XXX + + SyncComponent + + + sync + + + + + notify + + + + + SyncConfig + + + Sync Interval (0=None) + + + + + Min. + + + + + friendiqa + + + Refresh + + + + + Timeline + Cronología + + + + Conversations + Conversaciones + + + + Favorites + Favoritos + + + + Replies + + + + + Public Timeline + Cronología pública + + + + Group news + Grupos + + + + Search + Busca + + + + Settings + Ajustes + + + + Accounts + + + + + Quit + Salida + + newsworker - + likes this. le gusta esto. - + like this. me gusta esto. - + doesn't like this. no de ése. - + don't like this. no me gusta. - + will attend. asistirá. - + persons will attend. Personas que asistirán. - + will not attend. no asistirá. - + persons will not attend. Personas que no asistirán.. - + may attend. Puede asistir. - + persons may attend. Personas que pueden asistir. - + yes si - + no no - + maybe quizás - + seconds Segundos - - @@ -827,51 +992,53 @@ + + ago hace - + minute Minuto - + minutes Minutos - + hour Hora - + hours Horas - + day Dia - + days Dias - + month Mes - + months Meses - + years Años @@ -883,12 +1050,12 @@ Error - + Undefined Array Error - + JSON status Error diff --git a/source-android/translations/friendiqa-it.qm b/source-android/translations/friendiqa-it.qm index 0094b47778b7ddcc15d5b0a4deb03b8d15cafa9c..bb3841b48aa4525cec7e39be7a33d2d7af4f9d4f 100644 GIT binary patch delta 1545 zcmZuwe{54_6g}O0-}}{e?S6HekTAoX8~c$)SWq?w+maz_JGGJF1Y&95O0j#5Ygc6v zY6KH8EQ7p7Mi^?4g$)!E`wys5Ns2nuCSO%>dsI*bV_=JCOUMfyEC2oe@AdW1z$vn70N9%>ad^z|Q@I>wx4q z;1CTg-37Kj7sy`;*7iDJ?K99Z4fbd~fDBmr3#$1bgfWhC3cDfPA)?5Q#_B%-?xukS zGuUu?8<4jH8$MY@ID{vTY$t&|2FkC@<4ttzOi`oV28ve=%mX%Gcm%K?Ml_<6{m=X6O;g^}{QET{b z@B$^}{N>41k_0>WsZC!3mMVTW8(=Hse~H8ZY0yB2p9uw7i!)5V{WeYVDXYn+@hoq# z1BnwZ-4&)<>S*#Dk@M+Pa7bM7S~H+571wW}30w)Wt@C%9kcqpm(*#9(#dGJ$kq_b1BGB#+Sc%OmJMk(E%OL>3GOWvgX!k=YNGIW;$zmq*#6gL?t z*Bj{EEpPqiRkFHR?w_CpX;S_uNKTXtD8cC~WEB+kaVp4)=J6>5g&WGg56bDzOep7v zsbOwZnV9{H8oX}BSRD<}VP(q#JyDdQ5^k)ee^kWi>7}OcQ|X6MaLg(OZ1aYM{qtTCTsHyu z@6{80s=p_&BdhI~ha&9;8HsZ&<-N2YCUM9=XWoV@SeeZJ58{Q5kf z=lfvQ*y@8hiERM8AISUx5UPP}*~Gl}f!Y>2?=n%mY@#y`1b+i^G@$7N!jFK&Da!Mh z=)M51@?F5T-b9BL+zUlO+Lz$Yeg|*|!1pnfcMALivJ<&`Q2O+Ja%?iub_^Siz79Bh zu;JuN!ZEzmQ3v1;6D_`n_zgBU4HCf$6UA;5ou$|^QUcg7L2EI9+yUrqL@4W)iLQ1; zmCu2^XOK8yAOUxGdSCltz$}Ejl1InwZ_i@lKM~QNl@gKcNOWT%jWyNZ-xvi}z4Lj%z;} z2KWgR#by&7lU!#fNy}d4Mv9_<0~!B_N3LF@M*ZTz zD6NWbG*P%^qGPA{eRDYxUL&5Z&ZK%iDSvOW&KjvI_%FpDm#PxUgSf=}VUbL93`wtD zew!rUC+#1m1gS&%x}KDnbKO#ZkuEAC7Ue~1%#EAKFEUa1%CftEAzdz5hB}Ej=d=vp z{F{`Wmw~=zG)R92w;(`@2QxY@+$9AxYvS=<+NsTHt?s2um{Vf?aFQGhW4$t$3fOj7 zub1zjLMLryf6)pu_uAA-5AFC@n?6`Zh4O7}!xSeyZ(?@PUVDTlb-V3{Ju#X*!~TVf z2FUqSCE02iqHe`{#GxRJC{z)~&qBb6Gf!9~j}~rFgPZ(y#&TC_iglY=lScda4yth_EbB@nu0#stSxp2kwlTFTQSj2MK&LlGgUj^A5TZX3Xk>-ppYo}6 zO4{{Mr(zVeLN~Va^9$#DH96$psfJ=9IjpqmayS;MQz9mhf?552e6G>Om8T9m&TUOK zeSA%-IlvdDnm71Iw&50vQ@y^t6*I#b?ZU$18FQ9`_RSG39F({Fb-h)K)X(BMxJPW_ zjUv}`qTr>Gl8cXLt(a$Dr$&@ORIXBV-5*r+ + + AccountPage + + + + + User + Utente + + + + Server + Server + + + + Nickname + Utente + + + + Password + Password + + + + Image dir. + Directory immagini + + + + News as + News come + + + + + + Error + Errore + + + + Nicknames containing @ symbol currently not supported + + + + + Confirm + Conferma + + + + No server given! + Nessun server inserito! + + + + No nickname given! + Nessun utente inserito! + + + + No password given! + Nessuna password inserita! + + + + No image directory given! + Nessuna directory immagini inserita! + + + + Wrong password! + + + + + Success + Ha funzionato! + + + + Name + Nome + + + + Timeline + Cronologia + + + + Conversations + Conversazioni + + CalendarTab - + Events Eventi - + Own Calendar Calendario - ConfigTab + ConfigPage - - - - User - Utente - - - - Server - Server - - - - Nickname - Utente - - - - Password - Password - - - - Image dir. - Directory immagini - - - + Max. News Nº Max. di notizie - + + Sync + + + + + ConfigTab + + User + Utente + + + Server + Server + + + Nickname + Utente + + + Password + Password + + + Image dir. + Directory immagini + + + Max. News + Nº Max. di notizie + + News as - News come + News come Interval (0=None) Intervallo (0=nessuno) - - - Error - Errore + Errore - Confirm - Conferma + Conferma - No server given! - Nessun server inserito! + Nessun server inserito! - No nickname given! - Nessun utente inserito! - - - - Nickname not registered at given server! - + Nessun utente inserito! No username given! Nessun utente inserito! - - Sync Interval (0=None) - - - - - Nicknames containing @ symbol currently not supported - - - - - Min. - - - - No password given! - Nessuna password inserita! + Nessuna password inserita! - No image directory given! - Nessuna directory immagini inserita! + Nessuna directory immagini inserita! - No maximum news number given! - Nessun numero massimo di news inserito! + Nessun numero massimo di news inserito! - - Wrong password! - - - - Success - Ha funzionato! + Ha funzionato! - - Name - - - - Timeline - Cronologia + Cronologia - Conversations - Conversazioni + Conversazioni @@ -193,27 +252,27 @@ Connetti - + Description Descrizione - + Location Località - + Posts Messaggi - + URL URL - + Created at Creato il @@ -221,22 +280,22 @@ FriendsTab - + Me - + Friends Amici - + Contacts Contatti - + Groups Gruppi @@ -257,27 +316,27 @@ Immagine - + Description Descrizione - + Upload Carica - + Change - + Error Errore - + No album name given Nessun nome album inserito! @@ -285,22 +344,54 @@ MessageSend - + + + + + to: + + + + Title (optional) Titolo (opzionale) - + + What's on your mind? + + + + + Error Errore - + Only one attachment supported at the moment. Remove other attachment first! Solo un allegato è attualmente supportato. Rimuovere prima gli altri allegati! + + + No receiver supplied! + + + + + NewsStack + + + Network Error + + + + + More + Ancora + NewsTab @@ -309,63 +400,36 @@ Download immagine profilo per - More - Ancora + Ancora - Timeline - Cronologia + Cronologia Error Errore - Favorites - Favoriti + Favoriti - Conversations - Conversazioni + Conversazioni - - Network Error - - - - - Replies - - - - - Public timeline - - - - Direct Messages - Messaggio diretto + Messaggio diretto - Notifications - Notifiche + Notifiche - Group news - Gruppi - - - - Quit - + Gruppi @@ -381,7 +445,7 @@ Codice: - + Direct Message Messaggio diretto @@ -396,65 +460,60 @@ commenti - + Attending: Attendi: - + Reply Risposta - + DM Messaggio diretto - + Repost Condividi - + Success! Ha funzionato! - + Conversation Conversazione - + Attending Attendi - + yes si - + maybe potrebbe - + no no - + Delete Cancella - - - Post - - PermissionDialog @@ -472,28 +531,28 @@ PhotoTab - + 's images Immagini - + All Images - + Only new - - + + Own Images Mie immagini - + More Ancora @@ -501,324 +560,406 @@ ProfileComponent - + profile name - + is default - + hide friends - + profile photo - + profile thumb - + publish - + publish in network - + description - + date of birth - + address - + city - + region - + postal code - + country - + hometown - + gender - + marital status - + married with - + married since - + sexual - + politics - + religion - + public keywords - + private keywords - + likes - + dislikes - + about - + music - + book - + tv - + film - + interest - + romance - + work - + education - + social networks - + homepage - + Update - + profile id - + Description - Descrizione + Descrizione - + Location - Località + Località - + Posts - Messaggi + Messaggi - + URL - URL + URL - + Created at - Creato il + Creato il SmileyDialog - + Unicode Unicode - + Standard Standard - + Addon Addon - + Adult XXX + + SyncComponent + + + sync + + + + + notify + + + + + SyncConfig + + + Sync Interval (0=None) + Intervallo (0=nessuno) + + + + Min. + Min. + + + + friendiqa + + + Refresh + + + + + Timeline + Cronologia + + + + Conversations + Conversazioni + + + + Favorites + Favoriti + + + + Replies + + + + + Public Timeline + + + + + Group news + Gruppi + + + + Search + Cerca + + + + Settings + Configurazione + + + + Accounts + + + + + Quit + + + newsworker - + likes this. mi piace. - + like this. mi piace. - + doesn't like this. non mi piace. - + don't like this. non mi piace. - + will attend. attendere. - + persons will attend. Persone che attendono. - + will not attend. non aspettare. - + persons will not attend. Persone che non aspettano. - + may attend. puoi attendere. - + persons may attend. Persone che possono attendere. - + yes si - + no no - + maybe potrebbe - + seconds secondi - - @@ -827,51 +968,53 @@ + + ago fa - + minute minuti - + minutes minuti - + hour ora - + hours ore - + day giorno - + days giorni - + month mese - + months mesi - + years anni @@ -883,12 +1026,12 @@ Errore - + Undefined Array Error - + JSON status Error diff --git a/source-linux/application.qrc b/source-linux/application.qrc index d890962..9e0b393 100644 --- a/source-linux/application.qrc +++ b/source-linux/application.qrc @@ -1,5 +1,6 @@ + qtquickcontrols2.conf qml/friendiqa.qml qml/newsqml/NewsTab.qml qml/newsqml/Newsitem.qml @@ -16,7 +17,7 @@ qml/photoqml/PhotogroupComponent.qml qml/photoqml/PhotoTab.qml qml/configqml/InfoBox.qml - qml/configqml/ConfigTab.qml + qml/configqml/ConfigPage.qml js/layout.js js/photoworker.js js/service.js @@ -225,5 +226,11 @@ qml/newsqml/ContactPage.qml qml/newsqml/NewsLink.qml qml/configqml/RegisterPage.qml + qml/configqml/AccountPage.qml + qml/newsqml/NewsStack.qml + qml/configqml/SyncConfig.qml + qml/configqml/SyncComponent.qml + qml/genericqml/MButton.qml + qml/genericqml/LinuxSync.qml diff --git a/source-linux/common/alarm.h b/source-linux/common/alarm.h index f223c1c..bd66f04 100644 --- a/source-linux/common/alarm.h +++ b/source-linux/common/alarm.h @@ -49,9 +49,9 @@ signals: void alarmChanged(QString url); - public slots: void setAlarm(int time); + void notify(QString title, QString text, int id); private: int m_time; diff --git a/source-linux/common/alarmandroid.cpp b/source-linux/common/alarmandroid.cpp index 66d2c59..b1fcbfd 100644 --- a/source-linux/common/alarmandroid.cpp +++ b/source-linux/common/alarmandroid.cpp @@ -29,10 +29,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//#include -//#include #include "alarm.h" #include +#include "AndroidNative/systemdispatcher.h" ALARM *ALARM::instance() { @@ -44,33 +43,20 @@ ALARM::ALARM(QObject *parent) : QObject(parent){} void ALARM::setAlarm(int interval) { - qDebug() << interval; -// auto activity = QtAndroid::androidActivity(); -// auto packageManager = activity.callObjectMethod("getPackageManager", -// "()Landroid/content/pm/PackageManager;"); - -// auto activityIntent = packageManager.callObjectMethod("getLaunchIntentForPackage", -// "(Ljava/lang/String;)Landroid/content/Intent;", -// activity.callObjectMethod("getPackageName", -// "()Ljava/lang/String;").object()); - -// auto pendingIntent = QAndroidJniObject::callStaticObjectMethod("android/app/PendingIntent", "getActivity", -// "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;", -// activity.object(), jint(0), activityIntent.object(), -// QAndroidJniObject::getStaticField("android/content/Intent", -// "FLAG_ACTIVITY_CLEAR_TOP")); - -// auto alarmManager = activity.callObjectMethod("getSystemService", -// "(Ljava/lang/String;)Ljava/lang/Object;", -// QAndroidJniObject::getStaticObjectField("android/content/Context", -// "ALARM_SERVICE", -// "Ljava/lang/String;").object()); - -// alarmManager.callMethod("set", -// "(IJLandroid/app/PendingIntent;)V", -// QAndroidJniObject::getStaticField("android/app/AlarmManager", "RTC"), -// jlong(QDateTime::currentMSecsSinceEpoch() + 100), pendingIntent.object()); - - + QVariantMap message; + message["value"] = interval; + AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util"); + AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message); + AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message); } +void ALARM::notify(QString title, QString text, int id) +{ + //qDebug() << "notify "<< title << text; + QVariantMap message; + message["title"] = title; + message["message"] = text; + message["id"] = id; + AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util"); + AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setNotification", message); +} diff --git a/source-linux/common/alarmlinux.cpp b/source-linux/common/alarmlinux.cpp new file mode 100644 index 0000000..c9b0a57 --- /dev/null +++ b/source-linux/common/alarmlinux.cpp @@ -0,0 +1,73 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//#include +//#include +#include "alarm.h" +#include +#include +//#include "AndroidNative/systemdispatcher.h" + +ALARM *ALARM::instance() +{ + static ALARM alarm; + return &alarm; +} + +ALARM::ALARM(QObject *parent) : QObject(parent){} + +void ALARM::setAlarm(int interval) +{ + qDebug() << interval; + QVariantMap message; + message["value"] = interval; + // AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util"); + // AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message); + //AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message); +} + +void ALARM::notify(QString title, QString text, int id) +{ + qDebug() << title << text; + QVariantMap message; + message["title"] = title; + message["message"] = text; + QDBusConnection bus = QDBusConnection::sessionBus(); + QDBusInterface dbus_iface("org.freedesktop.Notifications", "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", bus); + QString appname="Friendiqa"; + uint v=12321; + if (dbus_iface.isValid()){ + + dbus_iface.call("Notify",appname,v,"",title,text,"","",5000); + } + // AndroidNative::SystemDispatcher::instance()->dispatch("Notifier.notify", message); +} diff --git a/source-linux/common/filesystem.cpp b/source-linux/common/filesystem.cpp index 719f0b7..c1668e4 100644 --- a/source-linux/common/filesystem.cpp +++ b/source-linux/common/filesystem.cpp @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify diff --git a/source-linux/common/filesystem.h b/source-linux/common/filesystem.h index 5057e16..c8baae8 100644 --- a/source-linux/common/filesystem.h +++ b/source-linux/common/filesystem.h @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify diff --git a/source-linux/common/friendiqa.cpp b/source-linux/common/friendiqa.cpp index c24d687..3eccb3c 100644 --- a/source-linux/common/friendiqa.cpp +++ b/source-linux/common/friendiqa.cpp @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify @@ -31,19 +31,21 @@ #include #include +//#include +//#include #include -#include #include "xhr.h" -#include "filesystem.h" #include "updatenews.h" +#include "filesystem.h" #include "remoteauthasyncimageprovider.h" +//#include "alarm.h" //#include "AndroidNative/systemdispatcher.h" //#include "AndroidNative/environment.h" //#include "AndroidNative/debug.h" //#include "AndroidNative/mediascannerconnection.h" -#ifdef Q_OS_ANDROID +#ifdef Q_OS_ANDROID #include #include JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { @@ -57,26 +59,39 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { int main(int argc, char *argv[]) { + //qDebug()<< "argv Friendiqa"<< argv[0] <<" argv2" <setDatabase(); + updatenews->login(); + updatenews->startsync(); + //app.connect (updatenews,SIGNAL(quitapp()),&app,SLOT(quit())); + //QtAndroid::androidService().callMethod("stopSelf"); + //return app.exec(); + } + else{ QApplication app(argc, argv); QQuickView view; QTranslator qtTranslator; qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations"); app.installTranslator(&qtTranslator); - QtWebView::initialize(); - RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider; + RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider; view.engine()->addImageProvider("remoteauthimage",imageProvider); view.rootContext()->setContextProperty("remoteauth", imageProvider); - auto offlineStoragePath=QUrl::fromLocalFile(view.engine()->offlineStorageDatabaseFilePath("Friendiqa")); - view.rootContext()->setContextProperty("offlineStoragePath", offlineStoragePath); -// XHR* xhr = XHR::instance(); -// view.rootContext()->setContextProperty("xhr", xhr); + XHR* xhr = XHR::instance(); + view.rootContext()->setContextProperty("xhr", xhr); FILESYSTEM* filesystem = FILESYSTEM::instance(); view.rootContext()->setContextProperty("filesystem", filesystem); + ALARM* alarm = ALARM::instance(); + view.rootContext()->setContextProperty("alarm", alarm); UPDATENEWS* updatenews = UPDATENEWS::instance(); view.rootContext()->setContextProperty("updatenews", updatenews); view.setSource(QUrl("qrc:/qml/friendiqa.qml")); view.show(); view.connect(view.rootContext()->engine(), SIGNAL(quit()), &app, SLOT(quit())); return app.exec(); + } } diff --git a/source-linux/common/remoteauthasyncimageprovider.cpp b/source-linux/common/remoteauthasyncimageprovider.cpp index 09bd9f6..66a8b03 100644 --- a/source-linux/common/remoteauthasyncimageprovider.cpp +++ b/source-linux/common/remoteauthasyncimageprovider.cpp @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify diff --git a/source-linux/common/remoteauthasyncimageprovider.h b/source-linux/common/remoteauthasyncimageprovider.h index bbe4383..f028ada 100644 --- a/source-linux/common/remoteauthasyncimageprovider.h +++ b/source-linux/common/remoteauthasyncimageprovider.h @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify diff --git a/source-linux/common/updatenews.cpp b/source-linux/common/updatenews.cpp index 08e02c1..b86a172 100644 --- a/source-linux/common/updatenews.cpp +++ b/source-linux/common/updatenews.cpp @@ -45,7 +45,8 @@ #include #include #include -//#include "xhr.h" +//#include "AndroidNative/systemdispatcher.h" + UPDATENEWS *UPDATENEWS::instance() @@ -75,16 +76,12 @@ void UPDATENEWS::setDatabase() QString db_url=qe.offlineStorageDatabaseFilePath("Friendiqa"); m_db = QSqlDatabase::addDatabase("QSQLITE"); m_db.setDatabaseName(QUrl("file://"+db_url+".sqlite").toLocalFile()); - qDebug() << db_url; + //qDebug() << db_url; if (!m_db.open()) { qDebug() << "Error: connection with database fail " << m_db.lastError(); } - else - { - qDebug() << "Database: connection ok"; - } } @@ -103,100 +100,304 @@ void UPDATENEWS::login() m_imagedir=query.value(3).toString(); xhr.setImagedir(m_imagedir); QString isActive=query.value(7).toString(); - updateInterval=query.value(5).toInt(); - //UPDATENEWS::connect(&UPDATENEWS::getLogin,SIGNAL(loginChanged(QString)),this,SLOT(XHR::login(QString))); - - m_api="/api/statuses/friends_timeline"; - xhr.setApi(m_api); - if(updateInterval!=0){alarm.setAlarm(updateInterval);}; + } + //m_updateInterval=query.value(5).toInt(); + + + QSqlQuery syncquery("SELECT * FROM globaloptions",m_db); +// QSqlQuery delquery("DELETE FROM globaloptions WHERE k='sync_interval'",m_db); +// delquery.exec(); + m_updateInterval=0; + syncindex=0; + synclist.clear(); + //QSqlQuery syncquery("SELECT * FROM globaloptions WHERE k like 'sync_%' AND v=1",m_db); + while (syncquery.next()){ + if (syncquery.value(0).toString()=="syncinterval"){ + m_updateInterval=syncquery.value(1).toInt(); + } + if (syncquery.value(0).toString().left(5)=="sync_" && syncquery.value(1).toInt()==1){ + synclist.append(syncquery.value(0).toString()); + //qDebug() << " sync " << syncquery.value(0).toString() << " " < newcontacts=findNewContacts(news); + //qDebug()<< "new contacts count " << newcontacts.size(); + if (newcontacts.size()>0){ + updateContacts(newcontacts); + startImagedownload(); + + } else { + if(m_updateInterval!=0){ + syncindex+=1; + startsync(); + } + } + } + else { + qDebug()<< "Friendiqa updatenews error " << serverreply; + emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply)); + syncindex+=1; + startsync(); } } - else {emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply));} - QList newcontacts=findNewContacts(news); - updateContacts(newcontacts); - startImagedownload(); - connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int))); } + + void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index){ if (downloadtype=="contactlist"){ - QSqlQuery query("UPDATE contacts SET imageLocation='"+ filename +"' WHERE imageurl ='"+imageurl+ "' AND username = '" +username+"'",m_db); + QSqlQuery testquery("SELECT profile_image FROM contacts WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db); + testquery.first(); + //qDebug()<< "update imageurl for " < UPDATENEWS::findNewContacts(QJsonDocument news){ QSqlQuery query("SELECT profile_image_url FROM contacts",m_db); QList imageurls; @@ -204,46 +405,46 @@ QList UPDATENEWS::findNewContacts(QJsonDocument news){ imageurls.append(query.value(0).toString()); } QList newcontacts; - //qDebug()< contacts){ for (int i=0; i < contacts.count();i++){ QJsonValue contact=contacts[i]; QSqlQuery query(m_db); - qDebug() << "updatecontact " << contact["screen_name"]; + //qDebug() << "updatecontact " << contact["screen_name"]; QSqlQuery testquery("SELECT url FROM contacts WHERE username='"+ username +"' AND url='" + contact["url"].toString() +"'",m_db); if (testquery.first()){ query.prepare("UPDATE contacts SET id=?, name=?, screen_name=?, location=?,imageAge=?," @@ -269,8 +470,8 @@ void UPDATENEWS::updateContacts(QList contacts){ query.bindValue(2, contact["screen_name"]); query.bindValue(3, contact["location"]); query.bindValue(4, currentTime); - query.bindValue(5, contact["profile_image_url"]); - if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());}; + query.bindValue(5, contact["profile_image_url"].toString().section('?',0,0)); + if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());} query.bindValue(7,contact["protected"].toBool()); query.bindValue(8,contact["followers_count"].toInt()); query.bindValue(9,contact["friends_count"].toInt()); @@ -290,7 +491,7 @@ void UPDATENEWS::updateContacts(QList contacts){ query.bindValue(21,contact["network"]); qint64 timestamp=0; QString timestamphelper=contact["profile_image_url"].toString(); - try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}; + try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){} query.bindValue(22,timestamp); } @@ -307,8 +508,8 @@ void UPDATENEWS::updateContacts(QList contacts){ query.bindValue(3, contact["screen_name"]); query.bindValue(4, contact["location"]); query.bindValue(5, currentTime); - query.bindValue(6, contact["profile_image_url"]); - if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());}; + query.bindValue(6, contact["profile_image_url"].toString().section('?',0,0)); + if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());} query.bindValue(8,"none"); query.bindValue(9, contact["url"].toString()); query.bindValue(10,contact["protected"].toBool()); @@ -331,12 +532,12 @@ void UPDATENEWS::updateContacts(QList contacts){ query.bindValue(25, 0); qint64 timestamp=0; QString timestamphelper=contact["profile_image_url"].toString(); - try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}; + try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){} query.bindValue(26,timestamp); } + query.exec() ; } - emit this->success(m_api); } QString UPDATENEWS::url() const @@ -346,6 +547,7 @@ QString UPDATENEWS::url() const void UPDATENEWS::startImagedownload() { + //qDebug() << "start image download"; xhr.setDownloadtype("contactlist"); xhr.setFilelist(newcontactimagelinks); xhr.setContactlist(newcontactnames); @@ -355,5 +557,12 @@ void UPDATENEWS::startImagedownload() void UPDATENEWS::showError(QString data, QString url,QString api, int code ) { + qDebug() << "showerror " << api << " data " << data; emit this->error(api,data); + if (api!=m_api || xhr.downloadtype()!=""){} else{ + if(m_updateInterval!=0){ + syncindex+=1; + startsync(); + } + } } diff --git a/source-linux/common/updatenews.h b/source-linux/common/updatenews.h index 63e7fe2..74acf20 100644 --- a/source-linux/common/updatenews.h +++ b/source-linux/common/updatenews.h @@ -37,6 +37,7 @@ #include #include "xhr.h" #include "alarm.h" +//#include "AndroidNative/systemdispatcher.h" class UPDATENEWS : public QObject { @@ -53,38 +54,25 @@ public: signals: -// void loginChanged(QString login); void urlChanged(QString url); void success(QString api); void error(QString api, QString content); - //void apiChanged(QString api); - - -// //network -// void success(QByteArray data, QString api); -// void error(QString data, QString url,QString api, int code); -// //network + void quitapp(); public slots: void setUrl(QString url); - //void setLogin(); - //QString login(); void setDatabase(); void login(); void timeline(); + void replies(); + void startsync(); + void directmessages(); + void notifications(); + //void startservice(QString type,QVariantMap map); void startImagedownload(); void updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index); void store(QByteArray serverreply,QString apiname); void showError(QString data, QString url,QString api, int code); -// //network -// void onReplyError(QNetworkReply::NetworkError code); -// void onReplySuccess(); -// void onReadyRead(); -// void onSSLError(const QList &errors); -// void setParam(QString name, QString value); -// void clearParams(); -// void get(); -// //network private: QString m_url; @@ -92,9 +80,13 @@ private: QString m_imagedir; QString m_login; QString username; + int syncindex; QSqlDatabase m_db; + QList synclist; + QList notifylist; QList findNewContacts(QJsonDocument news); - int updateInterval; + QJsonObject findNotificationContact(QString imagelink); + int m_updateInterval; //void timeline(); //void store(QByteArray serverreply,QString apiname); void updateContacts(QList contacts); @@ -103,19 +95,6 @@ private: ALARM alarm; QList newcontactimagelinks; QList newcontactnames; - - - -// //network -// QHash params; -// QHash files; -// QByteArray buffer; -// QNetworkAccessManager manager; -// QNetworkRequest request; -// QNetworkReply *reply; -// QNetworkConfiguration nc; -// QString bufferToString(); -// //network }; #endif // UPDATENEWS_H diff --git a/source-linux/common/uploadableimage.cpp b/source-linux/common/uploadableimage.cpp index ef7bc77..7ef3524 100644 --- a/source-linux/common/uploadableimage.cpp +++ b/source-linux/common/uploadableimage.cpp @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify diff --git a/source-linux/common/uploadableimage.h b/source-linux/common/uploadableimage.h index fc7c10a..665bf82 100644 --- a/source-linux/common/uploadableimage.h +++ b/source-linux/common/uploadableimage.h @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify diff --git a/source-linux/common/xhr.cpp b/source-linux/common/xhr.cpp index 84afb5a..fd29d29 100644 --- a/source-linux/common/xhr.cpp +++ b/source-linux/common/xhr.cpp @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify @@ -154,7 +154,7 @@ QString XHR::downloadtype() const return m_downloadtype; } -QString XHR::networktype() const +QString XHR::networktype() { return nc.bearerTypeFamily() + nc.bearerTypeName(); } @@ -184,7 +184,6 @@ void XHR::download() request.setRawHeader("Authorization", headerData.toLocal8Bit()); } request.setUrl(requrl); - //qDebug() << requrl; reply = manager.get(request); reply->ignoreSslErrors(); connect(reply, &QNetworkReply::readyRead,this, &XHR::onReadyRead); @@ -202,10 +201,11 @@ void XHR::get() while(i.hasNext()) { i.next(); query.addQueryItem(i.key(), i.value()); + //qDebug()< iparams(params); while(iparams.hasNext()) { iparams.next(); - qDebug() << "\t add param " << iparams.key() << " : " << iparams.value(); + //qDebug() << "\t add param " << iparams.key() << " : " << iparams.value(); QHttpPart textPart; textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + iparams.key() + "\"")); @@ -256,7 +256,7 @@ void XHR::post() ifiles.next(); uimg.setSource(ifiles.value()); - qDebug() << "\t image: " << uimg.mimetype() << ", " << ifiles.key(); + //qDebug() << "\t image: " << uimg.mimetype() << ", " << ifiles.key(); QHttpPart imagePart; imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(uimg.mimetype())); @@ -290,14 +290,14 @@ void XHR::onReplyError(QNetworkReply::NetworkError code) void XHR::onReplySuccess() { qDebug() << "!"; - //emit this->success( bufferToString(), m_api); - emit this->success( buffer, m_api); + emit this->success(buffer, m_api); buffer.clear(); // reply->deleteLater(); } void XHR::onRequestFinished() { + qDebug()<<"download requestFinished "; // Save the file here if (buffer.isNull()){qDebug() << "File empty"<error(m_downloadtype,m_url,m_api,1);} else if (m_downloadtype=="picturelist") { diff --git a/source-linux/common/xhr.h b/source-linux/common/xhr.h index 5f4b9d9..9141a84 100644 --- a/source-linux/common/xhr.h +++ b/source-linux/common/xhr.h @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa +// https://github.com/lubuwest/Friendiqa // Copyright (C) 2017 Marco R. // // This program is free software: you can redistribute it and/or modify @@ -49,7 +49,7 @@ class XHR : public QObject Q_PROPERTY(QList contactlist READ contactlist WRITE setContactlist NOTIFY contactlistChanged) Q_PROPERTY(QList filelist READ filelist WRITE setFilelist NOTIFY filelistChanged) Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged) - Q_PROPERTY(QString networktype READ networktype NOTIFY networktypeChanged) + Q_PROPERTY(QString networktype READ networktype() NOTIFY networktypeChanged) public: @@ -65,7 +65,7 @@ public: QList filelist() const; QString imagedir() const; QString downloadtype() const; - QString networktype() const; + QString networktype(); signals: void urlChanged(); @@ -98,6 +98,7 @@ public slots: void get(); void getlist(); void download(); + // void networktype(); private slots: diff --git a/source-linux/friendiqa.pro b/source-linux/friendiqa.pro index 0ea8282..e4f9de6 100644 --- a/source-linux/friendiqa.pro +++ b/source-linux/friendiqa.pro @@ -13,7 +13,7 @@ TEMPLATE = app TARGET = friendiqa CONFIG += release -QT += qml quick gui widgets sql webview +QT += qml quick gui widgets sql webview dbus SOURCES += common/friendiqa.cpp \ common/uploadableimage.cpp \ @@ -21,7 +21,7 @@ SOURCES += common/friendiqa.cpp \ common/filesystem.cpp \ common/remoteauthasyncimageprovider.cpp \ common/updatenews.cpp \ - common/alarmandroid.cpp + common/alarmlinux.cpp RESOURCES = application.qrc @@ -55,3 +55,5 @@ DISTFILES += \ qml/photoqml/*.qml \ qml/configqml/*.qml \ js/*.js \ + qml/newsqml/NewsStack.qml \ + qml/configqml/SyncComponent.qml diff --git a/source-linux/js/helper.js b/source-linux/js/helper.js index 1a22e3d..3bcb523 100644 --- a/source-linux/js/helper.js +++ b/source-linux/js/helper.js @@ -125,10 +125,11 @@ function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) { function readData(database,table,username,callback,filter,filtervalue, sort) { // reads and applies data from DB if (filter){ - var where = " AND "+ filter +" = '" + filtervalue+"'"; + if (username){var where = " AND "+ filter +" = '" + filtervalue+"'";} else{ + var where = " WHERE "+ filter +" = '" + filtervalue+"'";} } else { var where="";} if (username){ - var user = ' where username= "'+ username +'"'; + var user = ' where username= "'+ username +'"'; } else { var user='';} if (sort){ @@ -138,7 +139,7 @@ function readData(database,table,username,callback,filter,filtervalue, sort) { / if(!db) { return; } db.transaction( function(tx) { //print('select * from '+table+user+where+sortparam); - var rsArray=[]; + var rsArray=[]; var rs = tx.executeSql('select * from '+table+user+where+sortparam); for(var i = 0; i < rs.rows.length; i++) { rsArray.push(rs.rows.item(i)) @@ -165,7 +166,7 @@ var where = " AND "+ filter +" = '" + filtervalue+"'"; }); } -function showMessage(header,message,rootwindow){print(message); +function showMessage(header,message,rootwindow){//print(message); var cleanmessage=message.replace(/"/g,"-"); if(cleanmessage.length>200){cleanmessage=cleanmessage.slice(0,200)+'...'} var messageString='import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:"'+header+'";standardButtons: StandardButton.Ok; text:" '+cleanmessage+'"}'; diff --git a/source-linux/js/layout.js b/source-linux/js/layout.js index bdc27b3..6431819 100644 --- a/source-linux/js/layout.js +++ b/source-linux/js/layout.js @@ -36,7 +36,7 @@ function showFriends(db) { } function displayFriends(obj){ for (var i=0; i0'); // check for friends - var contactlist=[]; - for (var i=0;i0'+filtertext); + //print('SELECT * from contacts WHERE username="'+login.username+'"'+filtertext); + var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'+filtertext); + // check for friends + var contactlist=[]; + for (var i=0;i0){ maxnews=maxnewsrs.rows.item(0).v}; var newscountrs = tx.executeSql('SELECT COUNT(*) from news'); var newscount = newscountrs.rows.item(0)["COUNT(*)"];//print("newscount "+newscount) if (newscount>maxnews){ @@ -384,6 +384,7 @@ function updateContactInDB(login,database,isFriend,contact){// for newstab and f } function processNews(api,data){ + //print(api + data); try{var newslist=JSON.parse(data)} catch(e){newsBusy.running=false;}; if (data==""){} else if (typeof(newslist)=='undefined'){ @@ -393,6 +394,7 @@ function processNews(api,data){ Helperjs.showMessage(qsTr("JSON status Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root) } else if (!(Array.isArray(newslist))){ + //print("processNews not array"+newslist+JSON.stringify(newslist)); replytimer.restart() } else { @@ -407,6 +409,8 @@ function processNews(api,data){ newslist[n].uid=newslist[n].sender.id; newslist[n].statusnet_conversation_id=newslist[n].friendica_parent_uri; newslist[n].user=cleanUser(newslist[n].sender); + newslist[n].friendica_owner=newslist[n].user; + newslist[n].friendica_author=newslist[n].user; newslist[n].statusnet_html=newslist[n].text; }} else if (api=="/api/friendica/notifications"){ @@ -418,6 +422,8 @@ function processNews(api,data){ newslist[n].user={"profile_image_url": newslist[n].photo,"name": newslist[n].name," url":newslist[n].url, "created_at":newslist[n].date}; newslist[n].user=cleanUser(newslist[n].user); } + newslist[n].friendica_author=newslist[n].user; + newslist[n].friendica_owner=newslist[n].user; newslist[n].statusnet_html=newslist[n].msg_html; newslist[n].text=newslist[n].msg; } @@ -427,8 +433,9 @@ function processNews(api,data){ var commentCount=[]; for (var n in newslist){ newslist[n].created_at=Date.parse(Newsjs.cleanDate(newslist[n].created_at)); - newslist[n].messagetype=0; - newslist[n].user=cleanUser(newslist[n].user) + if (api=="/api/statuses/replies"){newslist[n].messagetype=3}else{newslist[n].messagetype=0;} + newslist[n].friendica_author=cleanUser(newslist[n].friendica_author); + newslist[n].user=cleanUser(newslist[n].user); if(newslist[n].in_reply_to_user_id){newslist[n].reply_user=Newsjs.objFromArray(allcontacts,"id",newslist[n].in_reply_to_user_id)} //print (JSON.stringify(newslist[n].user)) if(newslist[n].hasOwnProperty('friendica_activities')){ @@ -448,8 +455,8 @@ function processNews(api,data){ newslist[n].friendica_activities.attendmaybe[r]=cleanUser(newslist[n].friendica_activities.attendmaybe[r]); } } - if(!(newslist[n].hasOwnProperty('friendica_owner'))){ - newslist[n].friendica_owner=newslist[n].user + if(!(newslist[n].hasOwnProperty('friendica_author'))){ + newslist[n].friendica_author=newslist[n].user } var conversationindex=conversationIds.indexOf(newslist[n].statusnet_conversation_id); @@ -488,11 +495,13 @@ function processNews(api,data){ else if (api=="/api/statuses/user_timeline"){ newstab.contactposts=newslist } - else if (newstab.newstabstatus==="Conversations"){ - showNews(chatlist);root.news=newslist} - else {showNews(newslist);root.news=newslist}; + else if ((api!="/api/direct_messages/all")&&(api!="/api/friendica/notifications")&&(newstab.newstabstatus==="Conversations")){ + showNews(chatlist);root.news=newslist + } + else { + showNews(newslist);root.news=newslist}; - var newstabarray=["Conversations","Favorites","Timeline","DirectMessage"]; + var newstabarray=["Conversations","Favorites","Timeline","DirectMessage","Replies"]; if (newstabarray.indexOf(newstab.newstabstatus)>-1){contacttimer.start()} } @@ -509,26 +518,28 @@ function cleanUser(user){ } function updateView(viewtype){ - newsBusy.running=true; + //messageSend.state=""; + //newsBusy.running=true; //downloadNotice.text="xhr start "+Date.now() switch(viewtype){ case "Conversations": - var lastnews=Newsjs.getLastNews(login,db); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/friends_timeline"); - xhr.clearParams(); - xhr.setParam("since_id",lastnews); - xhr.setParam("count",50) + Newsjs.getLastNews(login,db,function(lastnews){ + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.setUrl(login.server); + xhr.setApi("/api/statuses/friends_timeline"); + xhr.clearParams(); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50)}); break; case "Timeline": - var lastnews=Newsjs.getLastNews(login,db); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/friends_timeline"); - xhr.clearParams(); - xhr.setParam("since_id",lastnews); - xhr.setParam("count",50) + var lastnews=Newsjs.getLastNews(login,db,function(lastnews){ + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.setUrl(login.server); + xhr.setApi("/api/statuses/friends_timeline"); + xhr.clearParams(); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50) + }); break; case "Search": xhr.setLogin(login.username+":"+Qt.atob(login.password)); @@ -566,14 +577,15 @@ function updateView(viewtype){ xhr.clearParams(); break; default: - var lastnews=Newsjs.getLastNews(login,db); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/friends_timeline"); - xhr.clearParams(); - xhr.setParam("since_id",lastnews); - xhr.setParam("count",50) - newstab.newstabstatus="Conversations"; + Newsjs.getLastNews(login,db,function(lastnews){ + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.setUrl(login.server); + xhr.setApi("/api/statuses/friends_timeline"); + xhr.clearParams(); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50) + newstab.newstabstatus="Conversations"; + }); } xhr.get(); diff --git a/source-linux/qml/calendarqml/CalendarDay.qml b/source-linux/qml/calendarqml/CalendarDay.qml index cff48f2..cfc1488 100644 --- a/source-linux/qml/calendarqml/CalendarDay.qml +++ b/source-linux/qml/calendarqml/CalendarDay.qml @@ -29,8 +29,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.0 -import QtQuick.Controls 1.4 +import QtQuick 2.11 +//import QtQuick.Controls 2.4 Item { id: calendarDay diff --git a/source-linux/qml/calendarqml/CalendarTab.qml b/source-linux/qml/calendarqml/CalendarTab.qml index 919745f..10b4e78 100644 --- a/source-linux/qml/calendarqml/CalendarTab.qml +++ b/source-linux/qml/calendarqml/CalendarTab.qml @@ -30,10 +30,10 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 2.3 +import QtQuick.Controls 2.4 import QtQml 2.2 import Qt.labs.calendar 1.0 -import QtQuick.Controls 1.2 as Oldcontrol +//import QtQuick.Controls 1.2 as Oldcontrol import QtQuick.Layouts 1.3 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs @@ -42,9 +42,10 @@ import "qrc:/qml/genericqml" Rectangle { id:calendarrectangle - y:1 - width:root.width-mm - height:root.height-5*mm +// y:1 +// width:root.width-mm +// height:root.height-5*mm + anchors.fill: parent color: '#fff' property date currentTime: new Date() property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000 @@ -83,30 +84,35 @@ Rectangle { } - BlueButton{ + MButton{ id: updateEvents anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right:calendartabstatusButton.left anchors.rightMargin:mm + height: 6*mm + width: 8*mm text:"\uf021" onClicked: { - Service.getEvents(db,login, calendartab,function(){ showEvents("") })}} - BlueButton{ + MButton{ id: calendartabstatusButton anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right: parent.right anchors.rightMargin:2*mm + height: 6*mm + width: Math.max(10*mm,implicitWidth) text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus - Oldcontrol.Menu { + Menu { id:calendartabmenu - Oldcontrol.MenuItem { + width: 40*mm + MenuItem { text: qsTr("Own Calendar") + font.pixelSize: 3*mm onTriggered: { calendartab.calendartabstatus="Events"; // calendartabstatusButton.text=qsTr("own Calendar"); @@ -146,6 +152,7 @@ Rectangle { DayOfWeekRow{ locale: monthgrid.locale Layout.fillWidth: true + font.pixelSize: 3*mm } MonthGrid { diff --git a/source-linux/qml/calendarqml/EventList.qml b/source-linux/qml/calendarqml/EventList.qml index 8a98bef..5028ae7 100644 --- a/source-linux/qml/calendarqml/EventList.qml +++ b/source-linux/qml/calendarqml/EventList.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -45,12 +45,14 @@ Rectangle{ y:mm property var daylist:[] - BlueButton{ + MButton{ id:closeButton anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm + height: 6*mm + width: 8*mm text: "\uf057" onClicked:{eventList.destroy()} } diff --git a/source-linux/qml/configqml/AccountPage.qml b/source-linux/qml/configqml/AccountPage.qml new file mode 100644 index 0000000..f593ed1 --- /dev/null +++ b/source-linux/qml/configqml/AccountPage.qml @@ -0,0 +1,463 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick 2.7 +import QtQuick.Dialogs 1.2 +import QtQuick.Controls 2.4 + +import "qrc:/js/service.js" as Service +import "qrc:/js/layout.js" as Layoutjs +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/configqml" +import "qrc:/qml/genericqml" + +Page{ + id:accountPage + width: root.width + height: root.height + property var users:[] + property var userdata: ({}) + + function setServericon(server){ + try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",accountPage, function (obj){ + var serverdata = JSON.parse(obj); + servericon.visible=true; + servericon.source=serverdata.site.logo})} catch(e){print(e)} + } + + Button{ + id:userButton + height: 8*mm + text:qsTr("User") + font.pixelSize: 3*mm + x: mm + y: mm + width: root.width/2 + onClicked:{ + var useritems=""; + for (var i=0;i-1){ + Helperjs.showMessage(qsTr("Error"),qsTr("Nicknames containing @ symbol currently not supported"),accountPage) + } + } + } + } + Button { + x: root.width-9*mm; y: 23.5*mm; width:5*mm; height:5*mm + text: "\uf234" + font.pixelSize: 3*mm + onClicked: { + configStack.push({item:"qrc:/qml/configqml/RegisterPage.qml",properties:{url:servername.text+"/register?nickname="+username.getText(0,username.length)}}) + } + } + + Rectangle{ + color: "light grey" + x: 4*mm; y: 33.5*mm; width: root.width-6*mm; height: 5*mm; + TextInput { + id: password + anchors.fill: parent + font.pixelSize:3*mm + selectByMouse: true + echoMode: TextInput.PasswordEchoOnEdit + } + } + + Rectangle{color: "light grey"; x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm;} + Flickable { + id: imagestoreFlickable + x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm; + clip: true + TextInput { + id: imagestore + width: imagestoreFlickable.width + height: imagestoreFlickable.height + font.pixelSize:3*mm + wrapMode: TextEdit.NoWrap + onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,imagestoreFlickable) + } + } + + FileDialog { + id: imagestoreDialog + title: "Please choose a directory" + folder: shortcuts.pictures + selectFolder: true + onAccepted: { + var imagestoreString=imagestoreDialog.folder.toString(); + imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/" + imagestore.text=imagestoreString + } + } + + Button { + x: root.width-9*mm; y: 43.5*mm; width: 5*mm; height: 5*mm; + text: "..." + font.pixelSize: 3*mm + onClicked: + {imagestoreDialog.open()} + } + + +// Slider{ id: maxNews +// x:19*mm; y: 53.5*mm;width: root.width/2;height:5*mm +// from: 0;to:2000; stepSize: 100 +// } + + +// Rectangle{color: "light grey"; x: 4*mm; y: 53.5*mm; width: 9*mm; height: 5*mm; +// TextEdit{id:maxNewsText; +// anchors.fill: parent +// font.pixelSize:3*mm +// verticalAlignment:TextEdit.AlignRight +// text:maxNews.value +// focus: true +// selectByMouse: true +// } +// } + + Rectangle{ + x: 4*mm; y: 53.5*mm; width: newsTypeField.contentWidth+2*mm; height: 5*mm; + color:"light grey" + Text{ + id: newsTypeField + anchors.fill: parent + font.pixelSize:3*mm + text:"Conversations" + } + MouseArea{ + anchors.fill:parent + onClicked:newstypemenu.popup() + } + } + + BusyIndicator{ + id: accountBusy + anchors.horizontalCenter: parent.horizontalCenter + y: 63.5*mm + width:10*mm + height: 10*mm + running: false + } +// CheckBox{ +// id:showwebsiteCheckbox +// x:35*mm;y:80*mm +// onClicked:{ +// if (checked==true){ +// Service.updateglobaloptions(root.db,"showWebsiteForLinks","true") +// root.globaloptions.showWebsiteForLinks="true" +// } +// else { +// Service.updateglobaloptions(root.db,"showWebsiteForLinks","false") +// root.globaloptions.showWebsiteForLinks="false" +// } +// } +// } + + Button { + x: 4*mm; y: 63.5*mm + height: 8*mm + text: qsTr("Confirm") + font.pixelSize: 3*mm + onClicked:{ + accountBusy.running=true; + var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text, maxnews:"",interval: "",newsViewType:newsTypeField.text}; + var errormessage=""; + if (servername.text==""){errormessage=qsTr("No server given! ")} + else if (username.text==""){errormessage+=qsTr("No nickname given! ")} + else if (password.text=="") {errormessage+=qsTr("No password given! ")} + else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")} + //else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")} + else {errormessage=""} + if (errormessage=="") { + Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){ + accountBusy.running=false; + var credentials=JSON.parse(obj); + if (credentials.hasOwnProperty('status')){ + Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root) + } + else{ + filesystem.Directory=userconfig.imagestore; + filesystem.makeDir("contacts"); + filesystem.makeDir("albums"); + Service.storeConfig(db,userconfig); + Service.readConfig(db,function(userconfig){ + Helperjs.readData(db,"config","",function(storedUsers){ + storedUsers.sort(function(obj1, obj2) { + return obj1.isActive - obj2.isActive; + }); + accountPage.users=storedUsers}); + //reset values + root.login=userconfig; + root.news=[]; + },"isActive",0); + + //Service.requestProfile(userconfig,db,root,function(nc){root.newContacts=nc}); + Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.name+"\nScreen Name: "+credentials.screen_name,root) + } + }); + + } + else {Helperjs.showMessage(qsTr("Error"), errormessage,root)} + }} + + + + Button { + x: parent.width/2+2*mm; y: mm; width: 5*mm; height: 8*mm; + text: "-" + font.pixelSize: 3*mm + onClicked:{ + var userconfig={server: servername.text, username: username.text, password: Qt.btoa(password.text)}; + Service.deleteConfig(db,userconfig,function(){ + filesystem.Directory=imagestore.text+"contacts"; + filesystem.rmDir(); + filesystem.Directory=imagestore.text+"albums"; + filesystem.rmDir(); + servername.text="https://"; + servericon.visible=false; + servericon.source=""; + username.text=""; + password.text=""; + imagestore.text=""; + //maxNews.value=0; + newsTypeField.text="Conversations"; + //messageIntervalSlider.value=30; + userButton.text=qsTr("User"); + Helperjs.readData(db,"config","",function(storedUsers){ + storedUsers.sort(function(obj1, obj2) { + return obj1.isActive - obj2.isActive; + }) + accountPage.users=storedUsers;}) + }) + }} + + Button { + x: parent.width/2+8*mm; y: mm; width: 5*mm; height: 8*mm; + text: "+" + font.pixelSize: 3*mm + onClicked:{ + servername.text="https://" + servericon.visible=false; + servericon.source=""; + username.text="" + password.text="" + imagestore.text="" + //maxNews.value=0 + newsTypeField.text="Conversations" + //messageIntervalSlider.value=30 + userButton.text=qsTr("User") + } + } + + Button { + x: parent.width/2+14*mm; y: mm; width: 5*mm; height: 8*mm; + text: "?" + font.pixelSize: 3*mm + onClicked:{ + root.push("qrc:/qml/configqml/InfoBox.qml"); + } + } + Button{ + id:closeButton + height: 8*mm + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{root.pop()} + } + Menu { + id:newstypemenu + MenuItem { + font.pixelSize: 3*mm + text: qsTr("Timeline") + onTriggered: {newsTypeField.text="Timeline"} + } + MenuItem { + font.pixelSize: 3*mm + text: qsTr("Conversations") + onTriggered: {newsTypeField.text="Conversations"} + } + } + + Component.onCompleted: { + try{Helperjs.readData(db,"config","",function(storedUsers){ + storedUsers.sort(function(obj1, obj2) { + return obj1.isActive - obj2.isActive; + }) + accountPage.users=storedUsers; + Service.readConfig(db,function(obj){ + userButton.text=obj.username; + servername.text=obj.server; + accountPage.setServericon(obj.server); + username.text= obj.username; + password.text=Qt.atob(obj.password); + imagestore.text=obj.imagestore; + //maxNews.value=obj.maxnews; + newsTypeField.text=obj.newsViewType; + //messageIntervalSlider.value=obj.timerInterval; + if( obj.isActive==0){userButton.font.bold='true'} else {userButton.font.bold='false'} + },"isActive",0) + }) +// Service.readGlobaloptions(db,function(go){ +// if (root.globaloptions.showWebsiteForLinks!="false"){showwebsiteCheckbox.checked=true} +// }) + + } + catch (e){print(e) +// Helperjs.friendicaWebRequest("https://dir.friendica.social/servers/surprise",accountPage,function(html){ +// print(html); +// var bpos=html.indexOf("base "); +// var baseurl=html.substring(html.indexOf("http",bpos),html.indexOf('"',html.indexOf("http",bpos))); +// servername.text=baseurl +// }) + } + } +} diff --git a/source-linux/qml/configqml/ConfigPage.qml b/source-linux/qml/configqml/ConfigPage.qml new file mode 100644 index 0000000..7593d81 --- /dev/null +++ b/source-linux/qml/configqml/ConfigPage.qml @@ -0,0 +1,227 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick 2.11 +import QtQuick.Dialogs 1.2 +import QtQuick.Controls 2.4 + +import "qrc:/js/service.js" as Service +//import "qrc:/js/layout.js" as Layoutjs +//import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/configqml" +import "qrc:/qml/genericqml" + +Page{ + //anchors.fill: parent + width:root.width + height:root.height + //contentHeight: configBackground.height + //boundsBehavior: Flickable.StopAtBounds + +// Rectangle{ +// id:configBackground +// color: "white" +// anchors.fill: parent +// width:parent.width +// height:Math.max(90*mm,root.height-12*mm) +// property var users:[] +// property bool registeredUser: true +// property var userdata: ({}) + +// Text { +// text: qsTr("Image dir.") +// //text: qsTr("Max. News") +// font.pixelSize:3*mm +// x: 4*mm; y: 10*mm +// } + Text { + text: qsTr("Max. News") + //text: qsTr("News as") + font.pixelSize:3*mm + x: 4*mm; y:10*mm + } + + +// Text { +// text: qsTr("Show Website") +// x: 4*mm; y: 40*mm; width: 20*mm +// } + + +// Rectangle{color: "light grey"; x: 4*mm; y: 13.5*mm; width: root.width-14*mm; height: 5*mm;} +// Flickable { +// id: imagestoreFlickable +// x: 4*mm; y: 13.5*mm; width: root.width-14*mm; height: 5*mm; +// clip: true +// TextInput { +// id: imagestore +// width: imagestoreFlickable.width +// height: imagestoreFlickable.height +// font.pixelSize:3*mm +// wrapMode: TextEdit.NoWrap +// onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,imagestoreFlickable) +// } +// } + +// FileDialog { +// id: imagestoreDialog +// title: "Please choose a directory" +// folder: shortcuts.pictures +// selectFolder: true +// onAccepted: { +// var imagestoreString=imagestoreDialog.folder.toString(); +// imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/" +// imagestore.text=imagestoreString +// } +// } + +// Button { +// x: root.width-9*mm; y: 13.5*mm; width: 7*mm; height: 8*mm; +// text: "..." +// onClicked: +// {imagestoreDialog.open()} +// } + + + Slider{ id: maxNews + x:19*mm; y: 13.5*mm;width: root.width/2;height:5*mm + from: 0;to:2000; stepSize: 100 + value: root.globaloptions.hasOwnProperty("max_news")?root.globaloptions.max_news:1000 + } + + + Rectangle{color: "light grey"; x: 4*mm; y: 13.5*mm; width: 9*mm; height: 5*mm; + radius: 0.5*mm + TextEdit{id:maxNewsText; + anchors.fill: parent + font.pixelSize:3*mm + verticalAlignment:TextEdit.AlignRight + text:maxNews.value + focus: true + selectByMouse: true + onTextChanged: { + Service.updateglobaloptions(root.db,"max_news",text); + } + } + } + + Rectangle{ + x: 4*mm; y:23.5*mm; width: parent.width - 14*mm; height: 5*mm; + color:"light grey" + radius: 0.5*mm + Text{ + anchors.fill: parent + font.pixelSize:3*mm + text:qsTr("Sync") + } + MouseArea{ + anchors.fill:parent + onClicked:root.push("qrc:qml/configqml/SyncConfig.qml"); + } + } +// Slider{ id: messageIntervalSlider +// x:22*mm; y: 73.5*mm;width: root.width/2;height:5*mm +// from: 0;to:120; stepSize: 15 +// } +// Rectangle{ +// x: 4*mm; y: 73.5*mm; width: 9*mm; height: 5*mm; +// TextEdit{ +// id: messageIntervalField +// anchors.fill: parent +// font.pixelSize:3*mm +// verticalAlignment:TextEdit.AlignRight +// text:messageIntervalSlider.value +// focus: true +// selectByMouse: true +// } +// } +// Text{x: 14*mm; y: 73.5*mm; width: 5*mm; height: 5*mm; +// font.pixelSize:3*mm +// text:qsTr("Min.") +// } + +// CheckBox{ +// id:showwebsiteCheckbox +// x:35*mm;y:80*mm +// onClicked:{ +// if (checked==true){ +// Service.updateglobaloptions(root.db,"showWebsiteForLinks","true") +// root.globaloptions.showWebsiteForLinks="true" +// } +// else { +// Service.updateglobaloptions(root.db,"showWebsiteForLinks","false") +// root.globaloptions.showWebsiteForLinks="false" +// } +// } +// } + + MButton { + anchors.right: closeButton.left; anchors.rightMargin: mm; + anchors.top: parent.top + anchors.topMargin: 1*mm + width: 8*mm; height: 6*mm; + text: "?" + font.pixelSize: 3*mm + onClicked:{ + root.push("qrc:/qml/configqml/InfoBox.qml"); + } + } + MButton{ + id:closeButton + height: 6*mm + width :8*mm + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{root.pop()} + } +// Menu { +// id:newstypemenu +// MenuItem { +// text: qsTr("Timeline") +// onTriggered: {newsTypeField.text="Timeline"} +// } +// MenuItem { +// text: qsTr("Conversations") +// onTriggered: {newsTypeField.text="Conversations"} +// } +// } + +// Component.onCompleted: { +// Service.readGlobaloptions(db,function(go){ +// if(go.hasOwnProperty("max_news")){maxNews.value=go.max_news}else{maxNews.value=1000} +// //if (root.globaloptions.showWebsiteForLinks!="false"){showwebsiteCheckbox.checked=true} +// }) +// } +} diff --git a/source-linux/qml/configqml/InfoBox.qml b/source-linux/qml/configqml/InfoBox.qml index 7cf6306..31a9c57 100644 --- a/source-linux/qml/configqml/InfoBox.qml +++ b/source-linux/qml/configqml/InfoBox.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import "qrc:/qml/genericqml" Rectangle{ @@ -41,11 +41,12 @@ Rectangle{ anchors.top:closeButton.bottom anchors.topMargin: mm textFormat: Text.RichText - width: parent.width + width: root.width-mm wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: "Friendiqa v0.4
Licensed under GPL 3 with the exception of OpenSSL
"+ + text: "Friendiqa v0.5
Licensed under GPL 3 with the exception of OpenSSL
"+ "Profile https://freunde.ma-nic.de/profile/friendiqa
"+ "Sourcecode: https://git.friendi.ca/LubuWest/Friendiqa
"+ + "Privacy Policy: http://git.friendi.ca/lubuwest/Friendiqa/src/branch/master/PrivacyPolicy.md
"+ "Most of C++ code by Fabio
"+ "QML and Javascript code by Marco
"+ "Qt Framework www.qt.io
"+ @@ -56,13 +57,16 @@ Rectangle{ onLinkActivated:{ Qt.openUrlExternally(link)} } - BlueButton{ - id:closeButton - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - onClicked:{configStack.pop()} + Button{ + id:closeButton + height: 6*mm + width: 8*mm + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{root.pop()} } } diff --git a/source-linux/qml/configqml/OSSettingsLinux.qml b/source-linux/qml/configqml/OSSettingsLinux.qml index 37fc606..f2bd73c 100644 --- a/source-linux/qml/configqml/OSSettingsLinux.qml +++ b/source-linux/qml/configqml/OSSettingsLinux.qml @@ -34,7 +34,7 @@ QtObject{ property real appWidth: 500 property real appHeight: 500 property int backKey: Qt.Key_Escape - property string osType: "Android" + property string osType: "Linux" //property string attachImageDir:filesystem.homePath+"/Pictures/" property string imagePickQml: "ImagePickerLinux" } diff --git a/source-linux/qml/configqml/RegisterPage.qml b/source-linux/qml/configqml/RegisterPage.qml index 299a086..35ab326 100644 --- a/source-linux/qml/configqml/RegisterPage.qml +++ b/source-linux/qml/configqml/RegisterPage.qml @@ -30,6 +30,7 @@ // along with this program. If not, see . import QtQuick 2.9 +import QtQuick.Controls 2.5 import QtWebView 1.1 import "qrc:/qml/genericqml" @@ -45,17 +46,21 @@ Rectangle{ width:parent.width y:7*mm MouseArea {anchors.fill:parent; - onClicked:{print(url)} + onClicked:{ + //print(url) + } } - onLoadingChanged: print(loadProgress) + //onLoadingChanged: print(loadProgress) } - BlueButton{ + Button{ id:closeButton + height:8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm text: "\uf057" + font.pixelSize: 3*mm onClicked:{configStack.pop()} } } diff --git a/source-linux/qml/configqml/SyncComponent.qml b/source-linux/qml/configqml/SyncComponent.qml new file mode 100644 index 0000000..05be915 --- /dev/null +++ b/source-linux/qml/configqml/SyncComponent.qml @@ -0,0 +1,87 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import "qrc:/qml/configqml" +import "qrc:/js/service.js" as Service + +Rectangle{ + color: "#EEEEEE" //Material.Grey + property string adapter: "" + width: parent.width + height: 12*mm + Label{ + x: mm + y: 0.5*mm + font.pixelSize:3*mm + text: qsTr(adapter) + } + CheckBox{ + id: syncCheckbox + x: mm + y: 5*mm + width:20*mm + checked:(globaloptions["sync_"+adapter]==1)?true:false + //style: CheckBoxStyle { + text: qsTr("sync") + font.pixelSize:3*mm + onClicked: { + toggle(); + if(syncCheckbox.checked==true){ + Service.updateglobaloptions(root.db,"sync_"+adapter,0);syncCheckbox.checked=false; + } + else{ + Service.updateglobaloptions(root.db,"sync_"+adapter,1);syncCheckbox.checked=true; + } + } + } + CheckBox{ + id: notifyCheckbox + x:25*mm + y: 5*mm + width:25*mm + enabled: adapter!="Notifications" + checked:(globaloptions["notify_"+adapter]==1)?true:false + text: qsTr("notify") + font.pixelSize:3*mm + onClicked: { + toggle(); + if(notifyCheckbox.checked==true){ + Service.updateglobaloptions(root.db,"notify_"+adapter,0);notifyCheckbox.checked=false; + } + else{ + Service.updateglobaloptions(root.db,"notify_"+adapter,1);notifyCheckbox.checked=true; + } + } + } +} diff --git a/source-linux/qml/configqml/SyncConfig.qml b/source-linux/qml/configqml/SyncConfig.qml new file mode 100644 index 0000000..9f42fe8 --- /dev/null +++ b/source-linux/qml/configqml/SyncConfig.qml @@ -0,0 +1,101 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import "qrc:/qml/configqml" +import "qrc:/js/service.js" as Service + +Rectangle{ + color:"white" + width:root.width + height:root.height + Text { + text: qsTr("Sync Interval (0=None)") + font.pixelSize:3*mm + //visible: false + x: 4*mm; y: 10*mm; //width:35*mm;wrapMode: Text.Wrap + } + + Slider{ id: messageIntervalSlider + x:22*mm; y: 13.5*mm;width: root.width/2;height:5*mm + value: globaloptions.syncinterval + from: 0;to:120; stepSize: 15 + } + Rectangle{ + x: 4*mm; y: 13.5*mm; width: 9*mm; height: 5*mm; + TextEdit{ + id: messageIntervalField + anchors.fill: parent + font.pixelSize:3*mm + verticalAlignment:TextEdit.AlignRight + text:messageIntervalSlider.value + focus: true + selectByMouse: true + onTextChanged: { + Service.updateglobaloptions(root.db,"syncinterval",text); + if(osSettings.osType=="Android" && text !=0){ + alarm.setAlarm(text); + } else if(osSettings.osType=="Linux" && text !=0){ + + } + } + } + } + Text{x: 14*mm; y: 13.5*mm; width: 5*mm; height: 5*mm; + font.pixelSize:3*mm + text:qsTr("Min.") + } + + Column{ + y:22*mm + width: parent.width + spacing:mm + //anchors.fill: parent + SyncComponent{adapter:"Timeline"} + SyncComponent{adapter:"Replies"} + SyncComponent{ adapter:"DirectMessages"} + SyncComponent{ adapter:"Notifications"} + } + + Button{ + id:closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + height: 6*mm + width: 8*mm + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{root.pop()} + } +} diff --git a/source-linux/qml/contactqml/ContactComponent.qml b/source-linux/qml/contactqml/ContactComponent.qml index 2e4aabe..3ddcb19 100644 --- a/source-linux/qml/contactqml/ContactComponent.qml +++ b/source-linux/qml/contactqml/ContactComponent.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.4 import "qrc:/qml/genericqml" Item { @@ -83,7 +83,8 @@ Item { MouseArea{ anchors.fill: parent onClicked:{ - root.currentIndex=0; + rootstack.currentIndex=0; + bar.currentIndex=0; root.contactdetailsSignal(contact) } } diff --git a/source-linux/qml/contactqml/ContactDetailsComponent.qml b/source-linux/qml/contactqml/ContactDetailsComponent.qml index e2b5d37..cd5112c 100644 --- a/source-linux/qml/contactqml/ContactDetailsComponent.qml +++ b/source-linux/qml/contactqml/ContactDetailsComponent.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.4 import "qrc:/qml/genericqml" Item { @@ -78,7 +78,7 @@ Rectangle{ ScrollView{ horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff - frameVisible: true + //frameVisible: true id:namelabelflickable width: root.width-10*mm height:root.height-50*mm @@ -105,8 +105,10 @@ Rectangle{ x: mm spacing:4 - BlueButton{ + MButton{ id:photobutton + height: 6*mm + width: 8*mm text: "\uf03e" // "Photos" visible:(contact.network=="dfrn") onClicked:{ @@ -118,8 +120,10 @@ Rectangle{ } } - BlueButton{ + MButton{ id:messagebutton + height: 6*mm + width: 8*mm text: "\uf0e6" //"Messages" onClicked:{ root.currentIndex=0; @@ -129,23 +133,26 @@ Rectangle{ } } - BlueButton{ + MButton{ id:dmbutton visible: (contact.following=="true") + height: 6*mm + width: 8*mm text: "\uf040" //"DM" onClicked:{ root.currentIndex=0; - //newstab.active=true; root.directmessageSignal(contact.screen_name); contactLargeComponent.destroy(); } } - BlueButton{ + Button{ id:eventbutton visible:(contact.network=="dfrn") - text:"\uf073" + height: 6*mm + width: 8*mm + text:"\uf073" //Events onClicked:{ root.currentIndex=3; calendartab.active=true; @@ -155,8 +162,10 @@ Rectangle{ } } - BlueButton{ + Button{ id: closeButton + height: 6*mm + width: 8*mm text: "\uf057" //"close" onClicked:{contactLargeComponent.destroy(); } diff --git a/source-linux/qml/contactqml/Contactlist.qml b/source-linux/qml/contactqml/Contactlist.qml index 66c07e7..67564ca 100644 --- a/source-linux/qml/contactqml/Contactlist.qml +++ b/source-linux/qml/contactqml/Contactlist.qml @@ -31,6 +31,7 @@ // List of people import QtQuick 2.0 +import QtQuick.Controls 2.5 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -109,13 +110,15 @@ Rectangle { } } - BlueButton { + MButton { id: closeButton + height:6* mm + width: 8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm - color:"white" + //color:"white" text: "\uf057" onClicked: { groupModelAppend(contacts,function(){ diff --git a/source-linux/qml/contactqml/FriendsTab.qml b/source-linux/qml/contactqml/FriendsTab.qml index 601787d..41741e7 100644 --- a/source-linux/qml/contactqml/FriendsTab.qml +++ b/source-linux/qml/contactqml/FriendsTab.qml @@ -29,9 +29,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.0 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.11 +import QtQuick.Controls 2.4 +//import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.11 import QtQuick.LocalStorage 2.0 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs @@ -69,14 +70,37 @@ Rectangle { callback(profile) } - TabView{ + TabBar { + id: friendsbar + width: parent.width + height: 9*mm + position:TabBar.Header + currentIndex: 1 + TabButton { + text: qsTr("Me") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Friends") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Contacts") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Groups") + font.pixelSize: 2*mm + } + } + StackLayout{ id:friendsTabView - tabPosition: Qt.TopEdge + //anchors.fill: parent x:mm - y:mm - width: root.width-2*mm - height: root.height-10*mm - currentIndex: 1 + y:10*mm + width: parent.width-2*mm + height: parent.height-10*mm + currentIndex: friendsbar.currentIndex signal contactsSignal(var contact) signal groupsSignal(var username) onCurrentIndexChanged:{ @@ -88,27 +112,28 @@ Rectangle { } else if (currentIndex==3){groupsSignal(root.login.username)} } - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle { - color: "white" - implicitWidth: root.width/4-2*mm - implicitHeight: 4*mm - Text { id: text - anchors.centerIn: parent - text: styleData.title - color: "dark grey" - font.pixelSize:2.5*mm - font.bold: styleData.selected - } - } - frame: Rectangle { color: "light grey" } - tabsAlignment:Qt.AlignHCenter - } +// style: TabViewStyle { +// frameOverlap: 1 +// tab: Rectangle { +// color: "white" +// implicitWidth: root.width/4-2*mm +// implicitHeight: 4*mm +// Text { id: text +// anchors.centerIn: parent +// text: styleData.title +// color: "dark grey" +// font.pixelSize:2.5*mm +// font.bold: styleData.selected +// } +// } +// frame: Rectangle { color: "light grey" } +// tabsAlignment:Qt.AlignHCenter +// } - Tab{ + Item{ id:profileGridTab - title: qsTr("Me") + Layout.fillWidth:true + Layout.fillHeight: true Component.onCompleted:{ showProfile(function(profile){ var component = Qt.createComponent("qrc:/qml/contactqml/ProfileComponent.qml"); @@ -117,11 +142,11 @@ Rectangle { } } - Tab{ - title: qsTr("Friends") - Rectangle{ + Item{ id: friendsGridTab - property int currentContact:0 + Layout.fillWidth:true + Layout.fillHeight: true + property int currentContact: 0 function showFriends(contact){ try {friendsModel.clear()} catch(e){print(e)}; Helperjs.readData(root.db,"contacts",login.username,function(friendsobject){ @@ -140,17 +165,21 @@ Rectangle { onDownloaded:{ if(type=="contactlist"){ //print(url+" "+filename+" "+i) - currentContact=i+1; - if(currentContact==root.newContacts.length){showFriends(root.login.username)} + friendsGridTab.currentContact=i+1; + if(friendsGridTab.currentContact==root.newContacts.length){ + friendsGridTab.showFriends(root.login.username) + } } } } - BlueButton { + MButton { id: updateFriendsButton text: "\uf021" anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right + height: 6*mm + width: 8*mm onClicked: { try {friendsModel.clear()} catch(e){print(e)}; //root.contactLoadType="friends"; @@ -167,8 +196,8 @@ Rectangle { anchors.top: parent.top anchors.right:updateFriendsButton.left anchors.rightMargin:mm - visible: (currentContact!=(root.newContacts.length))?true:false - value: currentContact/root.newContacts.length + visible: (friendsGridTab.currentContact!=(root.newContacts.length))?true:false + value: friendsGridTab.currentContact/root.newContacts.length } //GridView { @@ -196,13 +225,11 @@ Rectangle { root.newContacts=[] } } - } - Tab{ - title: qsTr("Contacts") - - Rectangle{ + Item{ id: contactsGridTab + Layout.fillWidth:true + Layout.fillHeight: true function showContacts(contact){ try {contactsModel.clear()} catch(e){print(e)}; Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){ @@ -213,12 +240,14 @@ Rectangle { } },"isFriend",0,"screen_name ASC"); } - BlueButton { + MButton { id: cleanButton text: "\uf021" anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right + height: 6*mm + width: 8*mm onClicked: { Service.cleanContacts(root.login,root.db,function(){ try {contactsModel.clear()} catch(e){print(e)}; @@ -252,11 +281,13 @@ Rectangle { friendsTabView.contactsSignal.connect(showContacts); } } - } - Tab{ - title: qsTr("Groups") - Rectangle{ + + + Item{ id: groupsGridTab + Layout.fillWidth:true + Layout.fillHeight: true + function showGroups(username){ try {groupsModel.clear()} catch(e){print(e)}; Helperjs.readData(db, "groups",root.login.username,function(groupsobject){ @@ -289,16 +320,18 @@ Rectangle { showGroups(root.login.username)}); } } - BlueButton { + MButton { id: updateGroupsButton text: "\uf021" anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right anchors.rightMargin: mm + height: 6*mm + width: 8*mm onClicked: { Newsjs.requestGroups(root.login,root.db,root,function(){ - showGroups(root.login.username)})} + groupsGridTab.showGroups(root.login.username)})} } // BlueButton { // id: newGroupButton @@ -351,9 +384,9 @@ Rectangle { friendsTabView.groupsSignal.connect(showGroups); } } - } - } + +} Component.onCompleted: { - root.contactdetailsSignal.connect(showContactdetails); + //root.contactdetailsSignal.connect(showContactdetails); } } diff --git a/source-linux/qml/contactqml/GroupComponent.qml b/source-linux/qml/contactqml/GroupComponent.qml index 04097b7..4d33790 100644 --- a/source-linux/qml/contactqml/GroupComponent.qml +++ b/source-linux/qml/contactqml/GroupComponent.qml @@ -29,7 +29,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.0 +import QtQuick 2.11 +import QtQuick.Controls 2.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs import "qrc:/qml/genericqml" @@ -76,15 +77,34 @@ Item { } } - BlueButton{ + + MButton{ + id: closeButton + visible: false + width: 8*mm + height: 6*mm + anchors.left: infobutton.right + anchors.margins: mm + anchors.top: parent.top + + text: "\uf057" + font.pixelSize: 3*mm + onClicked:{groupComponent.state=""; + if (group.new){groupsModel.remove(index)} + } + } + + MButton{ id:infobutton - width: 5*mm - height: 5*mm - color:"transparent" + width: 4*mm + height: 6*mm + + //color:"transparent" text:"?" + font.pixelSize: 3*mm anchors.left: photoImage.right - anchors.leftMargin: 3 - anchors.topMargin: 3 + anchors.leftMargin: mm + anchors.topMargin: mm anchors.top: parent.top onClicked:{ //if(group.new){ @@ -109,7 +129,7 @@ Item { Rectangle{ id: detailsrectangle anchors.top: namelabelRect.bottom - anchors.topMargin: 2*mm + anchors.topMargin: mm opacity: 0 Component { @@ -165,7 +185,7 @@ Item { x:1 //anchors.top: parent.top width: root.width-10*mm - height:groupsView.height -31*mm + height:groupsView.height - 24*mm clip: true spacing: 2 model: groupModel @@ -178,12 +198,7 @@ Item { anchors.top: groupListView.bottom anchors.topMargin: mm spacing: mm - BlueButton{ - id: closeButton - text: "\uf057" - onClicked:{groupComponent.state=""; - if (group.new){groupsModel.remove(index)} - } + } // BlueButton{ @@ -232,7 +247,7 @@ Item { // groupsModel.remove(index)}) // } // } - } + } Component.onCompleted:{if(group.new){groupComponent.state="large"}} } @@ -242,11 +257,13 @@ Item { name: "large" PropertyChanges { target: namelabel; font.pixelSize: 4*mm; width:groupsView.width; readOnly:false} PropertyChanges { target: namelabelRect; height: 4.5*mm} + PropertyChanges { target: closeButton; visible: true} PropertyChanges { target: groupComponent; z: 2 } PropertyChanges { target: wrapper; width:groupsView.width;height:groupsView.height -2*mm-1} PropertyChanges { target: photoImage; width:15*mm;height:15*mm } PropertyChanges { target:groupComponent.GridView.view ;contentY:groupComponent.y;contentX:groupComponent.x;interactive:false} PropertyChanges { target: detailsrectangle; opacity:1 } + PropertyChanges { target: infobutton; visible: false} } ] } diff --git a/source-linux/qml/contactqml/ProfileComponent.qml b/source-linux/qml/contactqml/ProfileComponent.qml index 0357bfb..a2b5b09 100644 --- a/source-linux/qml/contactqml/ProfileComponent.qml +++ b/source-linux/qml/contactqml/ProfileComponent.qml @@ -30,13 +30,14 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.4 import "qrc:/qml/genericqml" import "qrc:/js/service.js" as Service Rectangle { - width:root.width-2*mm - height:root.height-14*mm +// width:parent.width-2*mm +// height:parent.height-14*mm + anchors.fill:parent color:"white" property var profile:({}) property var attachImageURLs:[] @@ -102,12 +103,15 @@ Rectangle { callback(profiletext) } - BlueButton { + MButton { id: update + height: 6*mm + width: 8*mm anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right text: "\uf021" + font.pixelSize: 3*mm onClicked: { Service.requestProfile(root.login,root.db,root,function(nc){ root.newContacts=nc; @@ -132,8 +136,9 @@ Rectangle { Image { id: photoImage - x:mm - y:mm + anchors.top: parent.top + anchors.topMargin: mm + anchors.left: parent.left width: 15*mm height:15*mm source: "file://"+profile.friendica_owner.profile_image @@ -170,11 +175,13 @@ Rectangle { font.pixelSize: 4*mm } - BlueButton{ + MButton{ id:updatebutton - height: 5*mm + height: 6*mm + width:8*mm visible: "file://"+profile.friendica_owner.profile_image!= photoImage.source text:qsTr("Update") + font.pixelSize: 3*mm anchors.left: photoImage.right anchors.leftMargin: 0.5*mm anchors.topMargin: mm @@ -184,7 +191,7 @@ Rectangle { Label { id: namelabel x: mm - width: root.width-6*mm + width: parent.width-6*mm height: 3*mm text:(Qt.atob(profile.friendica_owner.name))+" (@"+profile.friendica_owner.screen_name+")" elide:Text.ElideRight @@ -230,7 +237,7 @@ Rectangle { font.pixelSize: 3*mm textFormat:Text.RichText wrapMode: Text.Wrap - text:""+qsTr("Description")+": "+(profile.friendica_owner.description)+"
"+qsTr("Location")+": "+profile.friendica_owner.location+"
"+qsTr("Posts")+": "+profile.friendica_owner.statuses_count+ + text:""+qsTr("Description")+": "+(Qt.atob(profile.friendica_owner.description))+"
"+qsTr("Location")+": "+profile.friendica_owner.location+"
"+qsTr("Posts")+": "+profile.friendica_owner.statuses_count+ "
"+qsTr("URL")+": "+profile.friendica_owner.url+"
"+ ""+qsTr("Created at")+": "+createdAtDate.toLocaleString(Qt.locale()) onLinkActivated: { @@ -238,32 +245,32 @@ Rectangle { } } - Rectangle{ - id: detailsrectangle - anchors.top: namelabel.bottom - anchors.topMargin: 2*mm +// Rectangle{ +// id: detailsrectangle + ScrollView{ - horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff - frameVisible: true + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff id:namelabelflickable - width: root.width-10*mm - height:root.height-36*mm//friendsTabView.height-45*mm + anchors.top: namelabel.bottom + anchors.topMargin: 2*mm + width: parent.width-mm + height:parent.height-22*mm//friendsTabView.height-45*mm x: mm clip:true ListView { id: profileView header:textcomponent - width:root.width-10*mm - height: root.height - clip: true +// width:parent.width +// height: root.height +// clip: true spacing: 0 model: profileModel delegate: profileItem } } - } +// } Component.onCompleted: { profile.profiles.sort(function(obj1, obj2) { diff --git a/source-linux/qml/friendiqa.qml b/source-linux/qml/friendiqa.qml index d023bb2..034cd86 100644 --- a/source-linux/qml/friendiqa.qml +++ b/source-linux/qml/friendiqa.qml @@ -32,37 +32,27 @@ import QtQuick 2.5 import QtQuick.LocalStorage 2.0 import QtQuick.Window 2.0 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.4 -//import QtQuick.Controls 2.3 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 1.11 import "qrc:/js/news.js" as Newsjs import "qrc:/js/service.js" as Service -import "qrc:/qml/genericqml" -import "qrc:/qml/newsqml" -import "qrc:/qml/contactqml" -import "qrc:/qml/photoqml" -import "qrc:/qml/calendarqml" -import "qrc:/qml/configqml" -TabView{ +StackView{ id:root property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettingsLinux.qml");return tmp.createObject(root)} - //IntentReceiver{} - tabPosition: Qt.BottomEdge width: osSettings.appWidth height:osSettings.appHeight - focus:true - property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000] property var login: Service.readActiveConfig(db) property var globaloptions: ({}) //Service.readGlobaloptions(db) property var contactlist: [] - property real mm: Screen.pixelDensity + property real mm: osSettings.osType=="Android"?Screen.pixelDensity:Screen.pixelDensity*1.5 signal messageSignal(var friend) signal fotoSignal(var username, var friend) signal directmessageSignal(var friend) signal newsSignal(var news) + signal newstypeSignal(var type) signal friendsSignal(var username) signal contactdetailsSignal(var contact) signal eventSignal(var contact) @@ -75,8 +65,8 @@ TabView{ property bool imagePicking: false onLoginChanged:{ - if(login==""){root.currentIndex=4} - else{ + if(login==""){root.push("qrc:/qml/configqml/AccountPage.qml")} + else{root.push(rootStackItem) newstab.newstabstatus=login.newsViewType; Newsjs.getCurrentContacts(login,db,function(contacts){ contactlist=contacts})} @@ -100,18 +90,18 @@ TabView{ } -// Connections{ -// target:xhr -// onDownloaded:{ -// if(type=="contactlist"){ -// var database=LocalStorage.openDatabaseSync(root.db[0],root.db[1],root.db[2],root.db[3]); -// var result; -// database.transaction( function(tx) { -// result = tx.executeSql('UPDATE contacts SET profile_image="'+filename+'" where profile_image_url="'+url+'"'); -// }) -// } -// } -// } + Connections{ + target:xhr + onDownloaded:{ + if(type=="contactlist"){ + var database=LocalStorage.openDatabaseSync(root.db[0],root.db[1],root.db[2],root.db[3]); + var result; + database.transaction( function(tx) { + result = tx.executeSql('UPDATE contacts SET profile_image="'+filename+'" where profile_image_url="'+url+'"'); + }) + } + } + } FontLoader{id: fontAwesome; source: "qrc:/images/fontawesome-webfont.ttf"} @@ -121,7 +111,7 @@ TabView{ newstab.active=true; if (newstab.newstabstatus!=login.newsViewType){ newstab.newstabstatus=login.newsViewType; - if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){ + if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,0,function(dbnews){ newsSignal(dbnews) })} else{ @@ -140,64 +130,273 @@ TabView{ event.accepted = true }} - - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle { - color: styleData.selected?"sky blue":"light blue" - //border.color: "light grey" - implicitWidth: root.width/5 - implicitHeight: 5*mm - Text { id: text - anchors.centerIn: parent - text: styleData.title - color: "black" - font.family: fontAwesome.name - font.pixelSize: 3*mm + Drawer{ + id: leftDrawer + width: 0.66* root.width + height: root.height + edge: Qt.LeftEdge + position: 1.0 + Column{ + x:mm + width:parent.width-mm + Label{ + text: login.hasOwnProperty("username")?login.username:"" + font.pixelSize: 4*mm + width: parent.width + height: 6*mm } - } - frame: Rectangle { color: "light grey" } - tabsAlignment:Qt.AlignHCenter - } +// Label{ +// text:login.hasOwnProperty("server")?"@"+login.server:"" +// font.pixelSize: 5*mm +// width: parent.width +// } + + Label{ + text: "\uf021 " + qsTr("Refresh") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("refresh") +// updatenews.setDatabase(); +// updatenews.login(); +// updatenews.startsync(); + } + } + } + + + Label{ + text: "\uf1da " + qsTr("Timeline") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("timeline") + } + } + } + + Label{ + text: "\uf086 " + qsTr("Conversations") + width: parent.width + font.pixelSize: 4*mm + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("conversation") + } + } + } + + Label{ + text: "\uf005 " + qsTr("Favorites") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("favorites") + } + } + } + Label{ + text: "\uf0ec " + qsTr("Replies") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("replies") + } + } + } + + + Label{ + text: "\uf0ac " + qsTr("Public Timeline") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("publictimeline") + } + } + } + + Label{ + text: "\uf0c0 " + qsTr("Group news") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("groupnews") + } + } + } + + Label{ + text: "\uf002 " + qsTr("Search") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.close(); + newstypeSignal("search") + } + } + } + + Label{ + text: "\uf085 "+ qsTr("Settings") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked: {root.push("qrc:qml/configqml/ConfigPage.qml"); + leftDrawer.close() + } + } + } + Label{ + text: "\uf2bb " + qsTr("Accounts") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked: {root.push("qrc:qml/configqml/AccountPage.qml"); + leftDrawer.close() + } + } + } + + Label{ - Tab{ - title: "\uf03a" - id: newstab - property string newstabstatus - property var conversation:[] - property var contactposts:[] - source:(root.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" - } - Tab{ - title: "\uf0c0" - id: friendstab - source: (root.currentIndex==1)?"qrc:/qml/contactqml/FriendsTab.qml":"" - } - Tab{ - title: "\uf03e" - id: fotostab - property string phototabstatus:"Images" - source: (root.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":"" - } - Tab{ - title: "\uf073" - id: calendartab - property string calendartabstatus:"Events" - source: (root.currentIndex==3)?"qrc:/qml/calendarqml/CalendarTab.qml":"" + text: "\uf08b " +qsTr("Quit") + font.pixelSize: 4*mm + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + Service.cleanNews(root.db,function(){ + Service.cleanContacts(root.login,root.db,function(){ + Qt.quit()}) + }) + } + } + } + + } } - Tab{ - title:"\uf085" - id: configtab - source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":"" - } + + + + Item{ + id:rootStackItem + //anchors.fill:parent + states: State { + name: "fullscreen"; + PropertyChanges { target: bar; height:0 } + PropertyChanges { target: rootstack; height:parent.height } + } + + transitions: Transition { + PropertyAnimation { properties: "height"; + easing.type: Easing.InOutQuad + duration: 1000 + } + } + TabBar { + id: bar + width: parent.width + height: 7*mm + position:TabBar.Footer + anchors.top: rootstack.bottom + onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex + TabButton { + text: "\uf03a" + font.pixelSize: 3*mm + height: 6*mm + } + TabButton { + text: "\uf0c0" + font.pixelSize: 3*mm + height: 6*mm + } + TabButton { + text: "\uf03e" + font.pixelSize: 3*mm + height: 6*mm + } + + TabButton { + text: "\uf073" + font.pixelSize: 3*mm + height: 6*mm + } + } + + StackLayout{ + id:rootstack + width:parent.width + height: parent.height-7*mm + currentIndex:bar.currentIndex + + + Loader{ + id: newstab + Layout.fillWidth:true + Layout.fillHeight: true + property string newstabstatus + property var conversation:[] + property var contactposts:[] + source:(rootstack.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" + } + Loader{ + id: friendstab + Layout.fillWidth:true + Layout.fillHeight: true + source: (rootstack.currentIndex==1)?"qrc:/qml/contactqml/FriendsTab.qml":"" + } + Loader{ + id: fotostab + property string phototabstatus:"Images" + Layout.fillWidth:true + Layout.fillHeight: true + source: (rootstack.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":"" + } + Loader{ + id: calendartab + property string calendartabstatus:"Events" + Layout.fillWidth:true + Layout.fillHeight: true + source: (rootstack.currentIndex==3)?"qrc:/qml/calendarqml/CalendarTab.qml":"" + } + + } Component.onCompleted: { Service.readGlobaloptions(db,function(go){globaloptions=go}) - //print(xhr.networktype); + //print(xhr.networktype()); if(osSettings.osType=="Android"){ var component = Qt.createComponent("qrc:/qml/genericqml/IntentReceiver.qml"); var IntentReceiverQml = component.createObject(root); - + } else if (osSettings.osType=="Linux"){ + var component = Qt.createComponent("qrc:/qml/genericqml/LinuxSync.qml"); + var LinuxSyncQml = component.createObject(root); } } } +} diff --git a/source-linux/qml/genericqml/BlueButton.qml b/source-linux/qml/genericqml/BlueButton.qml index 3db1ecc..997db9b 100644 --- a/source-linux/qml/genericqml/BlueButton.qml +++ b/source-linux/qml/genericqml/BlueButton.qml @@ -64,7 +64,7 @@ Rectangle{ states: [ State { name: "Pressed" - PropertyChanges { target: blueButton; color: "sky blue"} } + PropertyChanges { target: blueButton; color: "white"} } ] transitions: [ Transition { to:"*" diff --git a/source-linux/qml/genericqml/ImagePicker.qml b/source-linux/qml/genericqml/ImagePicker.qml index e62305a..d414c1f 100644 --- a/source-linux/qml/genericqml/ImagePicker.qml +++ b/source-linux/qml/genericqml/ImagePicker.qml @@ -38,7 +38,7 @@ Item { Connections { target: SystemDispatcher onDispatched: { - if (type === m_CHOSEN_MESSAGE) { + if ((type === m_CHOSEN_MESSAGE) && (root.imagePicking==true)) { var h=[]; for (var n in message.imageUrls){ h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5)) diff --git a/source-linux/qml/genericqml/ImagePickerLinux.qml b/source-linux/qml/genericqml/ImagePickerLinux.qml index c5e3051..cd3b182 100644 --- a/source-linux/qml/genericqml/ImagePickerLinux.qml +++ b/source-linux/qml/genericqml/ImagePickerLinux.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import Qt.labs.folderlistmodel 2.1 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs @@ -60,8 +60,9 @@ Rectangle{ wrapMode: Text.Wrap text: directory } - BlueButton{ + Button{ id:closeButton + height: 8*mm anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right: parent.right diff --git a/source-linux/qml/genericqml/IntentReceiver.qml b/source-linux/qml/genericqml/IntentReceiver.qml index 69ec590..1ceaacf 100644 --- a/source-linux/qml/genericqml/IntentReceiver.qml +++ b/source-linux/qml/genericqml/IntentReceiver.qml @@ -23,14 +23,14 @@ Item { } imageUrls=h; if(imageUrls.length==1){ - root.currentIndex=0;newstab.active=true; + rootstack.currentIndex=0;newstab.active=true; root.uploadSignal(imageUrls) } else{ - root.currentIndex=2;fotostab.active=true; + rootstack.currentIndex=2;fotostab.active=true; root.uploadSignal(imageUrls) } } else if (type==m_TEXT_MESSAGE){ - root.currentIndex=0;newstab.active=true; + rootstack.currentIndex=0;newstab.active=true; root.sendtextSignal(message) } } @@ -38,9 +38,8 @@ Item { Component.onCompleted: { SystemDispatcher.setInitialized(); - print("timer " + login.timerInterval) - if (login.timerInterval !=0){ - alarm.setAlarm(login.timerInterval); + if (root.globaloptions.hasOwnProperty("syncinterval") && root.globaloptions.syncinterval !=null && root.globaloptions.syncinterval !=0){ + alarm.setAlarm(root.globaloptions.syncinterval); } } } diff --git a/source-linux/qml/genericqml/LinuxSync.qml b/source-linux/qml/genericqml/LinuxSync.qml new file mode 100644 index 0000000..0e6d84d --- /dev/null +++ b/source-linux/qml/genericqml/LinuxSync.qml @@ -0,0 +1,22 @@ +import QtQuick 2.4 + + +Item { + Timer{ + id:syncTimer + repeat: true + onTriggered: { + updatenews.setDatabase(); + updatenews.login(); + updatenews.startsync(); + } + } + + Component.onCompleted: { + if (root.globaloptions.hasOwnProperty("syncinterval") && root.globaloptions.syncinterval !=null && root.globaloptions.syncinterval !=0){ + syncTimer.interval=root.globaloptions.syncinterval*60000; + syncTimer.start() + } + } +} + diff --git a/source-linux/qml/genericqml/MButton.qml b/source-linux/qml/genericqml/MButton.qml new file mode 100644 index 0000000..08932ae --- /dev/null +++ b/source-linux/qml/genericqml/MButton.qml @@ -0,0 +1,39 @@ +// This file is part of Friendiqa +// https://github.com/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick.Controls 2.4 +Button{ + id: mButton + width: Math.max(text.width+2*mm,8*mm) + height: 6*mm + //color: Material.grey + font.pixelSize: 3*mm +} diff --git a/source-linux/qml/genericqml/PermissionDialog.qml b/source-linux/qml/genericqml/PermissionDialog.qml index 61a05cc..8faaad8 100644 --- a/source-linux/qml/genericqml/PermissionDialog.qml +++ b/source-linux/qml/genericqml/PermissionDialog.qml @@ -29,7 +29,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.0 +import QtQuick 2.11 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -178,7 +178,7 @@ Rectangle{ else {groupstatus="neutral"} } } } - BlueButton{ + MButton{ x:0.5*mm anchors.bottom: parent.bottom anchors.bottomMargin:1 @@ -190,7 +190,7 @@ Rectangle{ Service.savePermissions(db,perms) } } - BlueButton{ + MButton{ x:contactView.width+2*mm anchors.bottom: parent.bottom anchors.bottomMargin:1 diff --git a/source-linux/qml/genericqml/Search.qml b/source-linux/qml/genericqml/Search.qml index 3ed2b6e..835e7be 100644 --- a/source-linux/qml/genericqml/Search.qml +++ b/source-linux/qml/genericqml/Search.qml @@ -54,7 +54,7 @@ Rectangle { anchors.top:parent.top anchors.topMargin: 0.5*mm width:parent.width-2*mm - height: 7*mm //Math.max( searchText.contentHeight,5*mm) + height: 4*mm //Math.max( searchText.contentHeight,5*mm) TextInput { id: searchText diff --git a/source-linux/qml/newsqml/ContactPage.qml b/source-linux/qml/newsqml/ContactPage.qml index 6fe470d..e3c7ead 100644 --- a/source-linux/qml/newsqml/ContactPage.qml +++ b/source-linux/qml/newsqml/ContactPage.qml @@ -31,7 +31,7 @@ import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -43,7 +43,7 @@ Rectangle { ListView { id: contactView x:mm - y:8*mm + y:9*mm width: contactList.width-4*mm height:contactList.height-10*mm clip: true @@ -90,35 +90,48 @@ Rectangle { y: mm spacing:4 - BlueButton{ + MButton{ id:photobutton + height: 6*mm + width: 8*mm text: "\uf03e" // "Photos" + //font.pixelSize: 3*mm visible:(contact.network=="dfrn") - onClicked:{print(createdAtDate + " contact.created_at"+contact.created_at) + onClicked:{ + rootstack.currentIndex=2; + bar.currentIndex=2; fotostab.phototabstatus="Contact"; - currentIndex=2; - fotostab.active=true; + + //fotostab.active=true; fotoSignal(root.login,contact) ; newsStack.pop(); } } - BlueButton{ + MButton{ id:dmbutton + height: 6*mm + width: 8*mm visible: (contact.following=="true") text: "\uf040" //"DM" + //font.pixelSize: 3*mm onClicked:{ - currentIndex=0; - directmessageSignal(contact.screen_name) + rootstack.currentIndex=0; + newsSwipeview.currentIndex=2; + directmessageSignal(contact) } } - BlueButton{ + MButton{ id:eventbutton visible:(contact.network=="dfrn") + height: 6*mm + width: 8*mm text:"\uf073" + //font.pixelSize: 3*mm onClicked:{ - currentIndex=3; + rootstack.currentIndex=3; + bar.currentIndex=3; calendartab.calendartabstatus="Friend" eventSignal(contact); newsStack.pop() @@ -179,14 +192,16 @@ Rectangle { source: "qrc:/js/newsworker.js" } - BlueButton { + MButton { id: closeButton - width:10*mm + height: 6*mm + width: 8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm text: "\uf057" + //font.pixelSize: 3*mm onClicked: { newsStack.pop() } diff --git a/source-linux/qml/newsqml/Conversation.qml b/source-linux/qml/newsqml/Conversation.qml index 8157383..c3fc24a 100644 --- a/source-linux/qml/newsqml/Conversation.qml +++ b/source-linux/qml/newsqml/Conversation.qml @@ -31,9 +31,10 @@ // ConversationView with button import QtQuick 2.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" +import "qrc:/qml/newsqml" Rectangle { id:conversationList @@ -56,7 +57,7 @@ Rectangle { height:conversationList.height-10*mm clip: true spacing: 0 - footer: footerReply + footer: MessageSend{conversation:true}//footerReply model: conversationModel delegate: Newsitem{} } @@ -89,68 +90,70 @@ Rectangle { } } - Component { id:footerReply - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - color:"lightgrey" - width:conversationView.width - height:Math.max(replyText.contentHeight+2*mm,6*mm) - Rectangle{ - color: "white" - radius:0.5*mm - anchors.left: parent.left - anchors.leftMargin:mm - anchors.top:parent.top - anchors.topMargin: 0.5*mm - width:parent.width-12*mm - height:Math.max( replyText.contentHeight,5*mm) +// Component { id:footerReply +// Rectangle{ +// border.color: "#EEEEEE" +// border.width: 1 +// color:"lightgrey" +// width:conversationView.width +// height:Math.max(replyText.contentHeight+2*mm,6*mm) +// Rectangle{ +// color: "white" +// radius:0.5*mm +// anchors.left: parent.left +// anchors.leftMargin:mm +// anchors.top:parent.top +// anchors.topMargin: 0.5*mm +// width:parent.width-12*mm +// height:Math.max( replyText.contentHeight,5*mm) - TextInput { - id: replyText - font.pixelSize: 3*mm - wrapMode: Text.Wrap - anchors.fill: parent - selectByMouse: true - onHeightChanged: conversationView.contentY+=4.5*mm - } - } +// TextInput { +// id: replyText +// font.pixelSize: 3*mm +// wrapMode: Text.Wrap +// anchors.fill: parent +// selectByMouse: true +// onHeightChanged: conversationView.contentY+=4.5*mm +// } +// } - BlueButton { - id: sendButton - text: "\uf1d9" - anchors.right: parent.right - anchors.rightMargin:mm - anchors.top:parent.top - anchors.topMargin: 0.5*mm - color:"white" - onClicked: { try{ - var body=replyText.getText(0,replyText.length); - newsBusy.running=true; - replyText.text="" - xhr.clearParams(); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - if (conversationModel.get(0).newsitemobject.messagetype==0){ +// Button { +// id: sendButton +// height: 8*mm +// width:8*mm +// text: "\uf1d9" +// anchors.right: parent.right +// anchors.rightMargin:mm +// anchors.top:parent.top +// anchors.topMargin: 0.5*mm +// //color:"white" +// onClicked: { try{ +// var body=replyText.getText(0,replyText.length); +// newsBusy.running=true; +// replyText.text="" +// xhr.clearParams(); +// xhr.setLogin(login.username+":"+Qt.atob(login.password)); +// if (conversationModel.get(0).newsitemobject.messagetype==0){ - //xhr.url= login.server + "/api/statuses/update.json"; - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/update"); - xhr.setParam("source", "Friendiqa"); - xhr.setParam("status", body); - xhr.setParam("in_reply_to_status_id", conversationModel.get(conversationModel.count-1).newsitemobject.id)} - else {//xhr.url= login.server + "/api/direct_messages/new.json"; - xhr.setUrl(login.server); - xhr.setApi("/api/direct_messages/new"); - xhr.setParam("text", body); - xhr.setParam("screen_name",conversationModel.get(conversationModel.count-1).newsitemobject.screen_name); - xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.id) - } - xhr.post(); - } catch(e){Helperjs.showMessage("Error",e.toString(),root)} - } - } - } - } +// //xhr.url= login.server + "/api/statuses/update.json"; +// xhr.setUrl(login.server); +// xhr.setApi("/api/statuses/update"); +// xhr.setParam("source", "Friendiqa"); +// xhr.setParam("status", body); +// xhr.setParam("in_reply_to_status_id", conversationModel.get(conversationModel.count-1).newsitemobject.id)} +// else {//xhr.url= login.server + "/api/direct_messages/new.json"; +// xhr.setUrl(login.server); +// xhr.setApi("/api/direct_messages/new"); +// xhr.setParam("text", body); +// xhr.setParam("screen_name",conversationModel.get(conversationModel.count-1).newsitemobject.screen_name); +// xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.id) +// } +// xhr.post(); +// } catch(e){Helperjs.showMessage("Error",e.toString(),root)} +// } +// } +// } +// } @@ -161,9 +164,10 @@ Rectangle { source: "qrc:/js/newsworker.js" } - BlueButton { + MButton { id: closeButton - width:10*mm + height: 6*mm + width: 8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right diff --git a/source-linux/qml/newsqml/MessageSend.qml b/source-linux/qml/newsqml/MessageSend.qml index 6d6ded6..37b46a9 100644 --- a/source-linux/qml/newsqml/MessageSend.qml +++ b/source-linux/qml/newsqml/MessageSend.qml @@ -31,24 +31,28 @@ // message.qml // message with buttons -import QtQuick 2.0 -import QtQuick.Controls 1.4 +import QtQuick 2.4 +import QtQuick.Controls 2.4 //import QtQuick.Dialogs 1.2 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/smiley.js" as Smileyjs +import "qrc:/js/news.js" as Newsjs import "qrc:/qml/genericqml" Rectangle{ - color:"white" -// width:root.width-5*mm -// height:root.height-12*mm - //anchors.fill: parent + color:"#EEEEEE" + width:parent.width + height: (newsSwipeview.stacktype!="Notifications")?messageColumn.height+mm:0 + id:messageSend + visible:(newsSwipeview.stacktype!="Notifications")?true:false property string parentId: "" + //property var parentObject:({}) + property bool conversation: false property string reply_to_user:"" property alias bodyMessage: bodyField.text property var attachImageURLs: []; - property int directmessage: 0; + //property int directmessage: 0; property var contacts: [] property var groups: [] property var contact_allow:login.permissions[0] @@ -56,14 +60,48 @@ Rectangle{ property var group_allow:login.permissions[2] property var group_deny:login.permissions[3] - function attachImage(url){ print("attachImage "+url) + onReply_to_userChanged: { + if (reply_to_user!=""){ + receiverLabel.visible=true + } + } + + function directmessagePrepare(friend){ + messageSend.state="active"; + reply_to_user=friend.screen_name; + receiverLabel.text=qsTr("to:")+ " "+ friend.screen_name; + } + + + function sendUrls(urls){ + if((urls.length==1 && attachImageURLs.length==0)){ + attachImage(urls); + attachImageURLs.push(urls); + messageSend.state="active"; + } + } + + function sendtext(text){ + if(text){ + if (text.subject=="undefined"){text.subject=""} + if(text.plaintext.lastIndexOf(".jpg")>-1 || text.plaintext.lastIndexOf(".jpeg")>-1 || text.plaintext.lastIndexOf(".png")>-1 || text.plaintext.lastIndexOf(".gif")>-1){ + text.plaintext=""} + bodyField.text=text.subject+"\n"+text.plaintext; + messageSend.state="active"; + } + } + + + + function attachImage(url){ var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment'+attachImageURLs.length+'; source:"'+ url.toString()+'"; x:2*mm; width: 45*mm; height: 45*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+ url+'"),1); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage"); - } + } function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { //xhr.url= login.server + "/api/statuses/update.json"; + newsBusy.running=true; xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setUrl(login.server); xhr.setApi("/api/statuses/update"); @@ -81,6 +119,7 @@ Rectangle{ } function dmUpdate(title,text,replyto,screen_name,attachImageURL) { + newsBusy.running=true; //xhr.url= login.server + "/api/direct_messages/new.json"; xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setUrl(login.server); @@ -93,103 +132,193 @@ Rectangle{ xhr.post(); } - Flickable{ - anchors.fill: parent - contentHeight: messageColumn.height - boundsBehavior: Flickable.StopAtBounds - id:messageSend + function setParent(newsitemobject){ + //print("Newsobject "+newsitemobject.id+ " "+JSON.stringify(newsitemobject.user)); + if (newsitemobject!=""){ + messageSend.state="conversation" + reply_to_user=newsitemobject.user.screen_name; + receiverLabel.text=qsTr("to:")+ " "+ newsitemobject.user.screen_name; + parentId=newsitemobject.id + } else { + messageSend.state="" + reply_to_user=""; + receiverLabel.text=qsTr("to:"); + parentId=""; + bodyField.text=""; + attachImageURLs.pop(); + try{imageAttachment.destroy()}catch(e){} + } + } + + function contactmenu(letter){ + Newsjs.listFriends(login,db,function(contacts){ + var contactitems=""; + for (var i=0;i1){ + contacts[i].screen_name=contacts[i].screen_name+"+"+contacts[i].cid + } + contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+ + "'; onTriggered:{if (newsSwipeview.stacktype=='DirectMessages'){reply_to_user='"+ + contacts[i].screen_name+"'} else {bodyField.insert("+ + bodyField.cursorPosition+",' "+contacts[i].screen_name.substring(1)+" ');bodyField.cursorPosition=bodyField.cursorPosition+"+contacts[i].screen_name.length+"}}}" + //} + } + var menuString="import QtQuick.Controls 2.4; Menu {width:40*mm; font.pixelSize: 3*mm; "+contactitems+"}"; + var contactlistObject=Qt.createQmlObject(menuString,messageColumn,"contactmenuOutput"); + if (contacts.length>0){contactlistObject.popup()} + },letter); + } +// Flickable{ +// anchors.fill: parent +// contentHeight: messageColumn.height +// boundsBehavior: Flickable.StopAtBounds + Column { + y:0.5*mm id:messageColumn spacing: 0.5*mm width: parent.width + height: 10*mm//implicitHeight + Label{ + id:receiverLabel + x: 0.5*mm + width: parent.width-mm + font.pixelSize: 3*mm + text: newsSwipeview.stacktype=="DirectMessages"?qsTr("to:")+ " "+ reply_to_user:"" + visible:false// ((parentId !== "") || (newsStack.parent.stacktype=="DirectMessages")) + MouseArea{ + anchors.fill: parent + onClicked:{} + } + } TextField { id: titleField - width: parent.width + x: 0.5*mm + width: parent.width-mm + font.pixelSize: 3*mm placeholderText: qsTr("Title (optional)") - visible: parentId === "" + visible: false//(parentId === "") && (bodyField.length>1) + onVisibleChanged: if ((visible==true)&&(conversation==true)){ + conversationView.contentY=conversationView.contentY+titleField.height + } } + + Rectangle{ color: "white" radius: 0.5*mm x:mm width: parent.width-2*mm - height:Math.max(bodyField.contentHeight+2*mm,10*mm) + height:Math.max(bodyField.contentHeight+4*mm,10*mm) TextArea { id: bodyField anchors.fill: parent font.pixelSize: 3*mm + font.family: "Noto Sans" wrapMode: Text.Wrap selectByMouse: true + placeholderText: conversation?"": qsTr("What's on your mind?") textFormat: TextEdit.RichText //TextEdit.PlainText + onLineCountChanged: (conversation==true)?conversationView.contentY=conversationView.contentY+3*mm:newsView.contentY=newsView.contentY+3*mm onLinkActivated:{Qt.openUrlExternally(link)} - } - } - - - Row{ - spacing: 2 - width: parent.width - CheckBox{ - id:dmCheckbox - text:"DM" - enabled: false - checked: (directmessage==1)?true:false - onClicked:{ - if(dmCheckbox.checkedState==Qt.Checked){directmessage=1} - else if(dmCheckbox.checkedState==Qt.Unchecked){directmessage=0} - } - } - - BlueButton{ - text:"\uf0c1" - onClicked: { - if(bodyField.selectedText==""){Helperjs.showMessage("Error","No text selected",messageSend)} - else{urlTextEdit.text=""; - urlRectangle.visible=true}} - } - } - Rectangle{ - id:urlRectangle - height: 7*mm //parent.height - width:parent.width-2*mm - visible:false - TextField{ - id:urlTextEdit - width:parent.width-7*mm - height:parent.height - } - BlueButton{ - anchors.left:urlTextEdit.right - anchors.leftMargin:mm - text:"\u2713" - onClicked: {if(urlTextEdit.text!=""){ - var start = bodyField.selectionStart; - var text=bodyField.selectedText - if(text.lastIndexOf(".jpg")>-1 || text.lastIndexOf(".jpeg")>-1 || text.lastIndexOf(".png")>-1){text=""} - text = "[url="+urlTextEdit.text+"]" + text + "[/url]"; - bodyField.remove(start,bodyField.selectionEnd); - bodyField.insert(start,text);} - urlRectangle.visible=false} + onActiveFocusChanged:{ + if (activeFocus==true){ + if (conversation==true){ + setParent(conversationModel.get(0).newsitemobject); + messageSend.state="conversation" + } else{ + messageSend.state="active" + } } } - Row{ - spacing:2 - BlueButton{id:permButton - visible: (directmessage==1)?false:true - text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" - onClicked: { permissionDialog.visible=true;} + onTextChanged:{ + if (text!=""){ + //print(getText(bodyField.cursorPosition-2,bodyField.cursorPosition) +" preedit: "+ preeditText+cursorPosition); + var regex1 = /@[a-z]/;var regex2 = /![a-z]/; + //print(text.substring(cursorPosition-2,cursorPosition)); + //if (regex.test(getText(bodyField.cursorPosition-2,bodyField.cursorPosition)) || regex.test(preeditText) || regex.test(text)){ + if (regex1.test(getText(bodyField.cursorPosition-2,bodyField.cursorPosition)+preeditText) || regex2.test(getText(bodyField.cursorPosition-2,bodyField.cursorPosition)+preeditText)){ + var letter=(getText(bodyField.cursorPosition-2,bodyField.cursorPosition)).match(/[a-z]/); + contactmenu(letter) + } + }} } - BlueButton { + } + + +// Row{ +// spacing: 2 +// width: parent.width +// CheckBox{ +// id:dmCheckbox +// text:"DM" +// enabled: false +// checked: (directmessage==1)?true:false +// onClicked:{ +// if(dmCheckbox.checkedState==Qt.Checked){directmessage=1} +// else if(dmCheckbox.checkedState==Qt.Unchecked){directmessage=0} +// } +// } + +// Button{ +// text:"\uf0c1" +// height:8*mm +// onClicked: { +// if(bodyField.selectedText==""){Helperjs.showMessage("Error","No text selected",messageSend)} +// else{urlTextEdit.text=""; +// urlRectangle.visible=true}} +// } +// } +// Rectangle{ +// id:urlRectangle +// height: 7*mm //parent.height +// width:parent.width-2*mm +// visible:false +// TextField{ +// id:urlTextEdit +// width:parent.width-7*mm +// height:parent.height +// } +// Button{ +// anchors.left:urlTextEdit.right +// anchors.leftMargin:mm +// height:8*mm +// text:"\u2713" +// onClicked: {if(urlTextEdit.text!=""){ +// var start = bodyField.selectionStart; +// var text=bodyField.selectedText +// if(text.lastIndexOf(".jpg")>-1 || text.lastIndexOf(".jpeg")>-1 || text.lastIndexOf(".png")>-1){text=""} +// text = "[url="+urlTextEdit.text+"]" + text + "[/url]"; +// bodyField.remove(start,bodyField.selectionEnd); +// bodyField.insert(start,text);} +// urlRectangle.visible=false} +// } +// } + Row{ + id:buttonRow + visible:false //(bodyField.length>1)||(attachImageURLs.length>0) + spacing: mm + height: 12*mm + MButton{id:permButton + visible: (newsSwipeview.stacktype!=="DirectMessages") + height: 6*mm + width: 7*mm + text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" + onClicked: { if (permissionDialog.visible==false){permissionDialog.visible=true} else{permissionDialog.visible=false}} + } + MButton { id: attachButton + height: 6*mm + width: 7*mm text: "\uf03e" - visible:(directmessage==0) + visible:(newsSwipeview.stacktype!="DirectMessages") onClicked: { if (attachImageURLs.length>0){//Server currently accepts only one attachment Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn) } else{ - // root.imagePicking=true; + root.imagePicking=false; var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+ 'attachImage(imageUrl)}}',root,"imagePicker"); @@ -197,55 +326,102 @@ Rectangle{ } } } - BlueButton{ - id:contactButton - text:"\uf234" - visible:(directmessage==0) - onClicked:{ - var contactitems=""; - for (var i=0;i1){ - contacts[i].screen_name=contacts[i].screen_name+"+"+contacts[i].cid - } - contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"'; onTriggered: bodyField.insert("+bodyField.cursorPosition+",' @"+contacts[i].screen_name+" ')}" - }} - var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}"; - var contactlistObject=Qt.createQmlObject(menuString,messageColumn,"contactmenuOutput") - contactlistObject.popup() } - } - BlueButton{ + MButton{ id:smileyButton text: "\uf118" - onClicked: {smileyDialog.visible=true} + height: 6*mm + width: 7*mm + onClicked: {if (smileyDialog.visible==false){smileyDialog.visible=true} else{smileyDialog.visible=false}} } - BlueButton { + MButton { id: cancelButton + height: 6*mm + width: 7*mm text: "\uf057" onClicked: { - newstab.newstabstatus=login.newsViewType; - newsStack.pop(null) + bodyField.text=""; + messageSend.state=""; + permissionDialog.visible=false; + receiverLabel.visible=false; + reply_to_user=""; + attachImage(""); + attachImageURLs.pop(); } - } - BlueButton { + } + MButton { id: sendButton + height: 6*mm + width: 7*mm text: "\uf1d9" onClicked: { var title=titleField.text.replace("\"","\'"); var body=bodyField.getFormattedText(0,bodyField.length); var dmbody=bodyField.getText(0,bodyField.length); - if (directmessage==0){ + if (newsSwipeview.stacktype!=="DirectMessages"){ statusUpdate(title,body,parentId,attachImageURLs)} - else {dmUpdate(title,dmbody,parentId,reply_to_user) } - newstab.newstabstatus=login.newsViewType; newsStack.pop(null) + else { + if (reply_to_user!=""){dmUpdate(title,dmbody,parentId,reply_to_user)} + else{Helperjs.showMessage(qsTr("Error"),qsTr("No receiver supplied!"),root)} + } + if (conversation==true){ + newstab.newstabstatus=login.newsViewType; newsStack.pop(null) + } } } } PermissionDialog{id:permissionDialog;x:mm;visible: false} SmileyDialog{id:smileyDialog;x:mm;visible: false} } - Component.onCompleted: if(attachImageURLs.length>0){attachImage(attachImageURLs[0])} -} + Component.onCompleted:{ + // + //parentId=conversationModel.get(conversationModel.count-1).newsitemobject.id + //if(attachImageURLs.length>0){attachImage(attachImageURLs[0])} + newsStack.replySignal.connect(setParent); + root.directmessageSignal.connect(directmessagePrepare); + root.uploadSignal.connect(sendUrls); + root.sendtextSignal.connect(sendtext); + } + + states: [ State { + name: "active" + PropertyChanges { + target: messageColumn; height: implicitHeight + } + PropertyChanges { + target: buttonRow; visible:true + } + PropertyChanges { + target: titleField; visible:(newsSwipeview.stacktype!="DirectMessages")//true + } + PropertyChanges { + target: receiverLabel; visible:(newsSwipeview.stacktype=="DirectMessages"); + } + }, + State { + name: "conversation" + PropertyChanges { + target: messageColumn; height: implicitHeight + } + PropertyChanges { + target: buttonRow; visible:true + } + PropertyChanges { + target: titleField; visible:(newsSwipeview.stacktype!="DirectMessages") + } + +// PropertyChanges { +// target: receiverLabel; visible:true; text:qsTr("to")+": "+ conversationModel.get(0).newsitemobject.user.name +// } + +// PropertyChanges { +// target: messageSend; reply_to_user: conversationModel.get(0).newsitemobject.user.screen_name +// } + +// PropertyChanges { +// target: messageSend; parentId: conversationModel.get(0).newsitemobject.status_id +// } + } ] } +//} diff --git a/source-linux/qml/newsqml/NewsStack.qml b/source-linux/qml/newsqml/NewsStack.qml new file mode 100644 index 0000000..5cf9d95 --- /dev/null +++ b/source-linux/qml/newsqml/NewsStack.qml @@ -0,0 +1,579 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2017 Marco R. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import "qrc:/js/news.js" as Newsjs +import "qrc:/js/helper.js" as Helperjs +import "qrc:/js/service.js" as Service + +StackView{ + id: newsStack + anchors.fill: parent + property string updateMethodNews: "refresh" + property var allchats: ({}) + signal replySignal(var newsobject) + property int lastnewsid:0 + + function newstypeHandling(newstype){ + newsBusy.running=true; + replySignal(""); + //messagesend.state=""; + newsModel.clear(); + switch(newstype){ + case "timeline": + newstab.newstabstatus="Timeline"; + try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews) + })}catch(e){Helperjs.showMessage("Error",e,root)}; + break; + case "conversation": + newstab.newstabstatus="Conversations"; + Newsjs.chatsfromdb(root.db,root.login,0,function(news,lastid){ + lastnewsid=lastid; + showNews(news)}); + break; + case "favorites": + newsStack.updateMethodNews="refresh"; + newstab.newstabstatus="Favorites"; + Service.updateView("Favorites"); + break; + case "replies": + newsStack.updateMethodNews="refresh"; + newstab.newstabstatus="Replies"; + Service.updateView("Replies"); + break; + case "publictimeline": + newsStack.updateMethodNews="refresh"; + newstab.newstabstatus="Public Timeline"; + Service.updateView("Public Timeline"); + break; + case "groupnews": + newsStack.updateMethodNews="refresh"; + Service.showGroups(); + break; + case "search": + newsView.anchors.topMargin=7*mm; + newsBusy.running=false; + var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml"); + var searchItem = component.createObject(newsStack,{y:mm,width:root.width,height: 5*mm}); + break; + case "refresh": + if (newstab.newstabstatus=="Timeline"){ + newsStack.updateMethodNews="append" + } else {newsStack.updateMethodNews="refresh"} + //root.contactLoadType="news"; + if (newsSwipeview.stacktype=="Home"){ + Service.updateView(newstab.newstabstatus) + } + else if (newsSwipeview.stacktype=="DirectMessage"){ + Service.updateView("Direct Messages") + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications") + } + break; + default: + if (newstab.newstabstatus=="Timeline"){ + newsStack.updateMethodNews="append" + } else {newsStack.updateMethodNews="refresh"} + //root.contactLoadType="news"; + if (newsSwipeview.stacktype=="Home"){ + Service.updateView(newstab.newstabstatus) + } + else if (newsSwipeview.stacktype=="Directmessage"){ + Service.updateView("Direct Messages") + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications") + } + } + } + + + function showNews(newsToShow){ + try{ + if (newsStack.depth>1){newsStack.pop()} + }catch(e){} + newsBusy.running=false; + var currentTime= new Date(); + // downloadNotice.text=downloadNotice.text + "\n shownews start "+ Date.now(); + //print("appendnews "+JSON.stringify(newsToShow)) + var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow,'method':newsStack.updateMethodNews, 'options':globaloptions}; + newsWorker.sendMessage(msg); + //newsStack.appendNews=false + } + + function showContact(contact){ //print(JSON.stringify(contact)); + //newstab.newstabstatus="Contact"; + newsStack.push("qrc:/qml/newsqml/ContactPage.qml",{"contact": contact}); + } + + function search(term){//print("Search "+term) + if (term!=""){ + newstab.newstabstatus="Search"; + newsBusy.running=true; + newsStack.updateMethodNews="refresh"; + xhr.setLogin(login.username+":"+Qt.atob(login.password)); + xhr.setUrl(login.server); + xhr.setApi("/api/search"); + xhr.clearParams(); + xhr.setParam("q",term) + xhr.get();} + newsView.anchors.topMargin=mm + } + + Connections{ + target:xhr + onError:{ + Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root); + } + onSuccess:{ + // downloadNotice.text=downloadNotice.text+ "\n xhr finished "+Date.now(); + Service.processNews(api,data); + } + } + + Timer {id:replytimer; interval: 1000; running: false; repeat: false + onTriggered: { + newsBusy.running=true; + if(newstab.newstabstatus=="Conversation"){ + showConversation(newsStack.timelineIndex-1,newsModel.get(0).newsitemobject)} + else{ + if (newstab.newstabstatus=="Timeline"){ + newsStack.updateMethodNews="append" + } else {newsStack.updateMethodNews="refresh"} + if (newsSwipeview.stacktype=="Home"){ + Service.updateView(newstab.newstabstatus) + } + else if (newsSwipeview.stacktype=="DirectMessages"){ + Service.updateView("Direct Messages") + } + else if (newsSwipeview.stacktype=="Replies"){ + Service.updateView("Replies") + } + replySignal("") + //Service.updateView(newstab.newstabstatus) + } + } + } + + initialItem: Rectangle { + id:newslistRectangle + y:1 + color: "white" + +// Button{ +// id:newstabstatusButton +// anchors.top: parent.top +// anchors.topMargin: 0.5*mm +// height: 8*mm +// text: qsTr(newstab.newstabstatus) +// visible: newsStack.parent.stacktype=="standard" +// onClicked: {print(newsStack.parent.stacktype); +// newstabmenu.popup(2*mm,6*mm) +// } + +// Menu{id:newstabmenu +// width: 40*mm + +// delegate:MenuItem{ +// contentItem: Text{ +// font.pixelSize: 3.5*mm +// text:parent.text +// } +// background: Rectangle { +// implicitWidth: 40*mm; implicitHeight: 5*mm +// color: "#ffffff" +// border.color: "grey" +// } +// } +// Action { +// text: qsTr("Timeline") +// onTriggered: { + +// } +// Action { +// text: qsTr("Conversations") +// onTriggered:{ +// //newsModel.clear(); +// newstab.newstabstatus="Conversations"; +// Newsjs.chatsfromdb(db,root.login,function(news){showNews(news)}) +// } +// } +// Action { +// text: qsTr("Favorites") +// onTriggered:{ +// newsStack.updateMethodNews="refresh"; +// newstab.newstabstatus="Favorites"; +// Service.updateView("Favorites") +// } +// } +// Action { +// text: qsTr("Replies") +// onTriggered:{ +// newsStack.updateMethodNews="refresh"; +// newstab.newstabstatus="Replies"; +// Service.updateView("Replies") +// } +// } +// Action { +// text: qsTr("Public timeline") +// onTriggered:{ +// newsStack.updateMethodNews="refresh"; +// newstab.newstabstatus="Public Timeline"; +// Service.updateView("Public Timeline") +// } +// } + +//// Action { +//// text: qsTr("Direct Messages") +//// onTriggered:{ +//// newsStack.updateMethodNews="refresh"; +//// newstab.newstabstatus="Direct Messages"; +//// Service.updateView("Direct Messages") +//// } +//// } +//// Action { +//// text: qsTr("Notifications") +//// onTriggered:{ +//// newsStack.updateMethodNews="refresh"; +//// newstab.newstabstatus="Notifications"; +//// Service.updateView("Notifications") +//// } +//// } +// Action { + +// text: qsTr("Group news") +// onTriggered: +// { +// newsStack.updateMethodNews="refresh"; +// Service.showGroups(); +// } +// } +// Action { + +// text: qsTr("Settings") +// onTriggered: +// { +// leftDrawer.open() +// } +// } + +// Action { +// text: qsTr("Quit") +// onTriggered:{ +// Service.cleanNews(root.db,function(){ +// Service.cleanContacts(root.login,root.db,function(){ +// Qt.quit()}) +// }) +// } +// } +// } +// } + +// Row{ +// spacing: mm +// anchors.top: parent.top +// anchors.topMargin: 0.5*mm +// anchors.right: parent.right + +// Button { +// id: searchButton +// height: 8*mm +// text: "\uf002" +// visible: newsStack.parent.stacktype=="standard" +// onClicked: { +// newsView.anchors.topMargin=18*mm; +// var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml"); +// var searchItem = component.createObject(newsStack,{y:8*mm,width:root.width,height: 8*mm}); +// } +// } + +// Button { +// id: newMessageButton +// text: "\uf040" +// height: 8*mm +// onClicked: { +// var groups=[]; +// Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){ +// groups=groupobject +// }); +// newstab.newstabstatus="SendMessage"; +// Helperjs.readData(root.db,"contacts",root.login.username,function(friends){ +// newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"contacts": friends,"login":root.login}) +// },"isFriend",1); +// } +// } +// BlueButton { +// id: quitButton +// text: "\uf08b" +// onClicked: {Service.cleanNews(root.db,function(){ +// Service.cleanContacts(root.login,root.db,function(){ +// Qt.quit() }) +// })} +// } +// Button { +// id: update +// height: 8*mm +// text: "\uf021" +// onClicked: { +// if (newstab.newstabstatus=="Timeline"){ +// newsStack.updateMethodNews="append" +// } else {newsStack.updateMethodNews="refresh"} +// //root.contactLoadType="news"; +// if (newsStack.parent.stacktype=="standard"){ +// Service.updateView(newstab.newstabstatus) +// } +// else if (newsStack.parent.stacktype=="directmessage"){ +// Service.updateView("Direct Messages") +// } +// else if (newsStack.parent.stacktype=="notifications"){ +// Service.updateView("Notifications") +// } +// } +// } + +// } + Component { id:footerComponent + Rectangle{ + border.color: "#EEEEEE" + border.width: 1 + width:newsView.width + height:6*mm + Text{ + font.pixelSize: 1.5*mm + anchors.centerIn: parent + text:qsTr("More") + } + MouseArea{anchors.fill:parent + onClicked:{ + var currentTime= new Date(); + var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; + var messagetype=0; + switch(newsSwipeview.stacktype){ + case "Home":messagetype=0;break; + case "DirectMessages": messagetype=1;break; + case "Notifications":messagetype=2;break; + case "Replies":messagetype=3;break; + default:messagetype=0; + } + if(newstab.newstabstatus=="Timeline"){ + Newsjs.newsfromdb(root.db,root.login, messagetype,function(news){ + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions}; + newsWorker.sendMessage(msg); + },false,lastnews_id)} + if(newstab.newstabstatus=="Conversations"){ + Newsjs.chatsfromdb(root.db,root.login, messagetype,function(news){ + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions}; + newsWorker.sendMessage(msg); + },lastnews_id)} +// else if(newstab.newstabstatus=="Contact"){ +// Newsjs.newsfromdb(root.db,root.login, function(news){ +// var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; +// newsWorker.sendMessage(msg); +// },newsModel.get(newsModel.count-1).newsitemobject.uid,lastnews_id)} + else if (newstab.newstabstatus=="Notifications"){} + else{ + //newsStack.appendNews=true; + xhr.setParam("max_id",newsModel.get(newsModel.count-1).newsitemobject.id-1); + xhr.get() + }} + } + } + } + + + +// Label{ +// text:qsTr(stacktype) +// font.pixelSize: 3* mm +// anchors.horizontalCenter: parent.horizontalCenter +// anchors.margins: mm +// } + + ListView { + id: newsView + property real oldContentY:0 + property bool viewdragged: false + anchors.fill: parent + anchors.margins: mm + //anchors.topMargin: 6*mm +// anchors.leftMargin: mm; anchors.rightMargin: mm +// anchors.bottomMargin: mm + clip: true + spacing: 0 + header: MessageSend{id:messagesend;onHeightChanged: newsView.positionViewAtBeginning()} + footer: footerComponent + model: newsModel + delegate: Newsitem{} + onDragStarted: oldContentY=contentY + onDragEnded: { + if(verticalOvershoot<-5*mm){ + viewdragged=true + } + else{ + if((contentY-oldContentY)>15*mm){ + swipeIndicator.visible=false; + newsSwipeview.height=rootStackItem.height; + newsSwipeview.y=0; + rootStackItem.state="fullscreen" + } + else if ((contentY-oldContentY)<-15*mm){ + swipeIndicator.visible=true; + newsSwipeview.height=rootStackItem.height-12*mm; + newsSwipeview.y=5*mm; + rootStackItem.state="" + } + } + } + onViewdraggedChanged: { + if (viewdragged){ + var onlynew=true; + newsBusy.running=true; + if (newstab.newstabstatus=="Timeline"){ + newsStack.updateMethodNews="append" + } else {newsStack.updateMethodNews="refresh"} + //root.contactLoadType="news"; + if (newsSwipeview.stacktype=="Home"){ + Newsjs.getLastNews(root.login,root.db,function(currentlastnews){ + if (currentlastnews>lastnewsid){ + if(newstab.newstabstatus=="Timeline"){ + try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews) + })}catch(e){Helperjs.showMessage("Error",e,root)}; + } + if(newstab.newstabstatus=="Conversations"){ + Newsjs.chatsfromdb(db,root.login,0,function(news,lastid){ + lastnewsid=lastid; + showNews(news)}); + } + } else { + Service.updateView(newstab.newstabstatus) + } + }); + } + else if (newsSwipeview.stacktype=="DirectMessages"){ + Service.updateView("Direct Messages") + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications") + } + else if (newsSwipeview.stacktype=="Replies"){ + Service.updateView("Replies") + } + viewdragged=false + }} + } + + ListModel{id: newsModel} + + WorkerScript { + id: newsWorker + source: "qrc:/js/newsworker.js" + } + + BusyIndicator{ + id: newsBusy + anchors.horizontalCenter: parent.horizontalCenter + anchors.top:parent.top + anchors.topMargin: 2*mm + width:10*mm + height: 10*mm + } + Rectangle{ + id:downloadNotice + property alias text: noticeText.text + color:"white" + border.color:"grey" + z:1 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom:parent.bottom + anchors.bottomMargin: 2*mm + width: noticeText.width+2*mm + height: noticeText.height+2*mm + visible: (downloadNotice.text!="") + + Text{ + id:noticeText + color: "grey" + anchors.centerIn: parent + width: contentWidth + height: contentHeight + font.pixelSize: 2*mm + text:"" + } + } + + Component.onCompleted: { + //print(newsSwipeview.stacktype); + root.newstypeSignal.connect(newstypeHandling); + root.messageSignal.connect(onFriendsMessages); + root.contactdetailsSignal.connect(showContact); + root.newsSignal.connect(showNews); + + try{newsModel.clear()} catch(e){} + swipeIndicator.visible=true; + newsSwipeview.height=rootStackItem.height-12*mm; + newsSwipeview.y=5*mm; + rootStackItem.state="" + +// xhr.setLogin(login.username+":"+Qt.atob(login.password)); +// xhr.setUrl(login.server); +// if((newsStack.parent.stacktype=="standard") && (root.news.length>0)){ +// showNews(root.news) +// } + //else{ + newstab.newstabstatus=login.newsViewType; + var messagetype=0; + switch(newsSwipeview.stacktype){ + case "Home":messagetype=0;break; + case "DirectMessages": messagetype=1;break; + case "Notifications":messagetype=2;break; + case "Replies":messagetype=3;break; + default:messagetype=0; + } + if((login.newsViewType=="Conversations")&&(newsSwipeview.stacktype=="Home")){ + Newsjs.chatsfromdb(db,login,messagetype,function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews); + }) + } + else{Newsjs.newsfromdb(db,login,messagetype,function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews) + })} + //} + } + } +} diff --git a/source-linux/qml/newsqml/NewsTab.qml b/source-linux/qml/newsqml/NewsTab.qml index f4a18e2..248bee5 100644 --- a/source-linux/qml/newsqml/NewsTab.qml +++ b/source-linux/qml/newsqml/NewsTab.qml @@ -29,37 +29,16 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls 2.3 as QC2 +import QtQuick 2.11 +import QtQuick.Controls 2.4 //import QtQuick.Controls.Styles 2.3 -import QtQuick.Dialogs 1.3 -import "qrc:/qml/genericqml" +//import QtQuick.Dialogs 1.3 +import "qrc:/qml/newsqml" import "qrc:/js/news.js" as Newsjs import "qrc:/js/helper.js" as Helperjs import "qrc:/js/service.js" as Service - -import AndroidNative 1.0 - Item { - Connections{ - target:newstab - onNewstabstatusChanged:{ - newstabstatusButton.text= qsTr(newstab.newstabstatus) - } - } - - Connections{ - target:xhr - onError:{ - Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root); - } - onSuccess:{ - // downloadNotice.text=downloadNotice.text+ "\n xhr finished "+Date.now(); - Service.processNews(api,data); - } - } // Connections{ // target:xhr @@ -80,43 +59,18 @@ Item { // } - Timer {id:replytimer; interval: 1000; running: false; repeat: false - onTriggered: { - if(newstab.newstabstatus=="Conversation"){ - showConversation(newsStack.timelineIndex-1,newsModel.get(0).newsitemobject)} - else{ - Service.updateView(newstab.newstabstatus) - } - } - } + Timer {id:contacttimer; interval: 50; running: false; repeat: false - onTriggered: { + onTriggered: {//print("Contacttimer "+JSON.stringify(root.news)); // downloadNotice.text=downloadNotice.text + "\n contactTimer start "+ Date.now() root.newContacts=Newsjs.findNewContacts(root.news,root.contactlist); Newsjs.storeNews(login,db,root.news,root) } } - - - function showNews(newsToShow){ - try{ - if (newsStack.depth>1){newsStack.pop()} - }catch(e){} - newsBusy.running=false; - var currentTime= new Date(); - // downloadNotice.text=downloadNotice.text + "\n shownews start "+ Date.now(); - //print("appendnews "+newsStack.appendNews +JSON.stringify(newsToShow)) - var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow,'method':newsStack.updateMethodNews, 'options':globaloptions}; - newsWorker.sendMessage(msg); - //newsStack.appendNews=false - } - - - function showConversation(conversationIndex,newsitemobject){ - if(newsitemobject.messagetype==0){ + if(newsitemobject.messagetype==0 || newsitemobject.messagetype==3){ xhr.clearParams(); xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setUrl(login.server); @@ -134,31 +88,12 @@ Item { } } - function showContact(contact){ - newstab.newstabstatus="Contact"; - newsStack.push({item:"qrc:/qml/newsqml/ContactPage.qml",properties:{"contact": contact}}); - } - - function search(term){//print("Search "+term) - if (term!=""){ - newstab.newstabstatus="Search"; - newsBusy.running=true; - newsStack.updateMethodNews="refresh"; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/search"); - xhr.clearParams(); - xhr.setParam("q",term) - xhr.get();} - newsView.anchors.topMargin=7*mm - } - function onFriendsMessages(friend){ newstab.newstabstatus="Contact" - Newsjs.newsfromdb(db,root.login.username, function(dbnews){ + Newsjs.newsfromdb(db,root.login.username, 0,function(dbnews){ if (dbnews.length==0){ - Newsjs.newsfromdb(db,login.username,function(forumnews){ + Newsjs.newsfromdb(db,login.username,0,function(forumnews){ showNews(forumnews) },friend.url) } @@ -166,303 +101,84 @@ Item { },friend.id) } - function onDirectMessage(friend){ - //newstab.newstabstatus="SendMessage" ,"login":login , - newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1, "login":root.login}}); - } - - function sendUrls(urls){print(root.currentIndex==0); - if((urls.length==1)&&(newsStack.depth<2)){ - newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"attachImageURLs":urls}}) + Label{ + text:"\uf0c9 " + font.pixelSize: 5* mm + anchors.left: parent.left + anchors.margins: mm + color: "#B0BEC5" + MouseArea{ + anchors.fill: parent + onClicked:{ + leftDrawer.open() + } } } - - function sendtext(text){ - if(text&&(newsStack.depth<2)){ - if (text.subject=="undefined"){text.subject=""} - if(text.plaintext.lastIndexOf(".jpg")>-1 || text.plaintext.lastIndexOf(".jpeg")>-1 || text.plaintext.lastIndexOf(".png")>-1 || text.plaintext.lastIndexOf(".gif")>-1){ - text.plaintext=""} - newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"bodyMessage":text.subject+"\n"+text.plaintext}}) - } + Label{ + text:qsTr(newsSwipeview.stacktype) + font.pixelSize: 3* mm + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 2*mm } + SwipeView{ + id: newsSwipeview + property string stacktype:"Home" + currentIndex: 0 + width: parent.width + height: parent.height-6*mm + y: 5*mm + function onDirectMessage(friend){currentIndex=2} - StackView{ - id: newsStack - anchors.fill:parent - property string updateMethodNews: "refresh" - property var allchats: ({}) - initialItem:Rectangle { - id:newslistRectangle - y:1 - color: "white" - - BlueButton{ - id:newstabstatusButton - anchors.top: parent.top - anchors.topMargin: 0.5*mm - text: qsTr(newstab.newstabstatus) - onClicked: {newstabmenu.popup(2*mm,6*mm)} - - QC2.Menu{id:newstabmenu - width: 40*mm - - delegate:QC2.MenuItem{ - contentItem: Text{ - font.pixelSize: 3.5*mm - text:parent.text - } - background: Rectangle { - implicitWidth: 40*mm; implicitHeight: 5*mm - color: "#ffffff" - border.color: "grey" - } - } - QC2.Action { - text: qsTr("Timeline") - onTriggered: { - newstab.newstabstatus="Timeline"; - //newsModel.clear(); - try{ Newsjs.newsfromdb(root.db,root.login.username, function(dbnews){ - showNews(dbnews) - })}catch(e){Helperjs.showMessage("Error",e,root)}} - } - QC2.Action { - text: qsTr("Conversations") - onTriggered:{ - //newsModel.clear(); - newstab.newstabstatus="Conversations"; - Newsjs.chatsfromdb(db,root.login.username,function(news){showNews(news)}) - } - } - QC2.Action { - text: qsTr("Favorites") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Favorites"; - Service.updateView("Favorites") - } - } - QC2.Action { - text: qsTr("Replies") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Replies"; - Service.updateView("Replies") - } - } - QC2.Action { - text: qsTr("Public timeline") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Public Timeline"; - Service.updateView("Public Timeline") - } - } - - QC2.Action { - text: qsTr("Direct Messages") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Direct Messages"; - Service.updateView("Direct Messages") - } - } - QC2.Action { - text: qsTr("Notifications") - onTriggered:{ - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Notifications"; - Service.updateView("Notifications") - } - } - QC2.Action { - - text: qsTr("Group news") - onTriggered: - { - newsStack.updateMethodNews="refresh"; - Service.showGroups(); - } - } - QC2.Action { - text: qsTr("Quit") - onTriggered:{ - Service.cleanNews(root.db,function(){ - Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) - }) - } - } + transitions: Transition { + PropertyAnimation { properties: "height"; + easing.type: Easing.InOutQuad + duration: 1000 } } - Row{ - spacing: mm - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right: parent.right - - BlueButton { - id: searchButton - text: "\uf002" - onClicked: { - newsView.anchors.topMargin=18*mm; - var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml"); - var searchItem = component.createObject(newsStack,{y:8*mm,width:root.width,height: 8*mm}); - } - } - - BlueButton { - id: newMessageButton - text: "\uf040" - onClicked: { - var groups=[]; - Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){ - groups=groupobject - }); - newstab.newstabstatus="SendMessage"; - Helperjs.readData(root.db,"contacts",root.login.username,function(friends){ - newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"contacts": friends,"login":root.login}) - },"isFriend",1); - } - } -// BlueButton { -// id: quitButton -// text: "\uf08b" -// onClicked: {Service.cleanNews(root.db,function(){ -// Service.cleanContacts(root.login,root.db,function(){ -// Qt.quit() }) -// })} -// } - BlueButton { - id: update - text: "\uf021" - onClicked: { - if (newstab.newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else {newsStack.updateMethodNews="refresh"} - //root.contactLoadType="news"; - Service.updateView(newstab.newstabstatus) + onCurrentIndexChanged: { + switch(currentIndex){ + case 0: stacktype="Home";break; + case 1: stacktype="Replies";break; + case 2: stacktype="DirectMessages";break; + case 3: stacktype="Notifications";break; + default: stacktype="Home"; } } - + //anchors.fill: parent + Loader{ + id: friendstimeline + source:(newsSwipeview.currentIndex==0)? "qrc:/qml/newsqml/NewsStack.qml":"" + //onLoaded: newsSwipeview.stacktype="Home" } - Component { id:footerComponent - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - width:newsView.width - height:6*mm - Text{ - font.pixelSize: 1.5*mm - anchors.centerIn: parent - text:qsTr("More") - } - MouseArea{anchors.fill:parent - onClicked:{ - var currentTime= new Date(); - var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; - if(newstab.newstabstatus=="Timeline"){ - Newsjs.newsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions}; - newsWorker.sendMessage(msg); - },false,lastnews_id)} - if(newstab.newstabstatus=="Conversations"){ - Newsjs.chatsfromdb(root.db,root.login.username, function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions}; - newsWorker.sendMessage(msg); - },lastnews_id)} -// else if(newstab.newstabstatus=="Contact"){ -// Newsjs.newsfromdb(root.db,root.login.username, function(news){ -// var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; -// newsWorker.sendMessage(msg); -// },newsModel.get(newsModel.count-1).newsitemobject.uid,lastnews_id)} - else if (newstab.newstabstatus=="Notifications"){} - else{ - //newsStack.appendNews=true; - xhr.setParam("max_id",newsModel.get(newsModel.count-1).newsitemobject.id-1); - xhr.get() - }} - } - } + Loader{ + id: replies + //property string stacktype:"Replies" + source:(newsSwipeview.currentIndex==1)? "qrc:/qml/newsqml/NewsStack.qml":"" + //onLoaded: newsSwipeview.stacktype="Replies" } - - - ListView { - id: newsView - anchors.fill: parent - anchors.topMargin: 7*root.mm - anchors.leftMargin: 3*root.mm; anchors.rightMargin: root.mm - anchors.bottomMargin: 1*root.mm - clip: true - spacing: 0 - footer: footerComponent - model: newsModel - delegate: Newsitem{} - //onContentYChanged:{if(contentY<-8*mm&&contentY>(-8*mm-1)){print("refreshing"); - onDragEnded:{if(contentY<-5*mm){ - var onlynew=true; - Service.updateView(newstab.newstabstatus) - }} + Loader{ + id: directmessages + property var friend:({}) + source:(newsSwipeview.currentIndex==2)? "qrc:/qml/newsqml/NewsStack.qml":"" + //onLoaded: newsSwipeview.stacktype="DirectMessages" } - - ListModel{id: newsModel} - - WorkerScript { - id: newsWorker - source: "qrc:/js/newsworker.js" - } - - BusyIndicator{ - id: newsBusy - anchors.horizontalCenter: newsView.horizontalCenter - anchors.top:newsView.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - } - Rectangle{ - id:downloadNotice - property alias text: noticeText.text - color:"white" - border.color:"grey" - z:1 - anchors.horizontalCenter: newsView.horizontalCenter - anchors.bottom:newsView.bottom - anchors.bottomMargin: 2*mm - width: noticeText.width+2*mm - height: noticeText.height+2*mm - visible: (downloadNotice.text!="") - - Text{ - id:noticeText - color: "grey" - anchors.centerIn: parent - width: contentWidth - height: contentHeight - font.pixelSize: 2*mm - text:"" - } - } - - Component.onCompleted: { - root.messageSignal.connect(onFriendsMessages); - root.directmessageSignal.connect(onDirectMessage); - root.contactdetailsSignal.connect(showContact); - root.newsSignal.connect(showNews); - root.uploadSignal.connect(sendUrls); - root.sendtextSignal.connect(sendtext); - try{newsModel.clear()} catch(e){} -// xhr.setLogin(login.username+":"+Qt.atob(login.password)); -// xhr.setUrl(login.server); - if(root.news.length>0){showNews(root.news)} - else{ newstab.newstabstatus=login.newsViewType; - if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){showNews(dbnews)})} - else{Newsjs.chatsfromdb(db,login.username,function(dbnews){ - showNews(dbnews); - })} - } + Loader{ + id: notifications + //property string stacktype:"Notifications" + source:(newsSwipeview.currentIndex==3)? "qrc:/qml/newsqml/NewsStack.qml":"" + //onLoaded: newsSwipeview.stacktype="Notifications" } - } - } + Component.onCompleted: {root.directmessageSignal.connect(onDirectMessage);} + } + + PageIndicator { + id: swipeIndicator + count: newsSwipeview.count + currentIndex: newsSwipeview.currentIndex + + anchors.bottom: newsSwipeview.bottom + anchors.horizontalCenter: parent.horizontalCenter + } + } diff --git a/source-linux/qml/newsqml/Newsitem.qml b/source-linux/qml/newsqml/Newsitem.qml index 72f5980..8dabc67 100644 --- a/source-linux/qml/newsqml/Newsitem.qml +++ b/source-linux/qml/newsqml/Newsitem.qml @@ -30,8 +30,8 @@ // along with this program. If not, see . import QtQuick 2.0 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.4 +//import QtQuick.Controls.Styles 1.4 import "qrc:/js/news.js" as Newsjs import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -62,7 +62,7 @@ Item { Rectangle{ width:newsitem.width height:newsitem.height-1 - color: (newsitemobject.messagetype==1)?"#ffe6e6" : "white" + color: "white"//(newsitemobject.messagetype==1)?"#ffe6e6" : "white" Row{id:toprow Column { @@ -102,8 +102,7 @@ Item { Label { id:messageTypeLabel color: "grey" - text: if (newsitemobject.messagetype==0){qsTr("Source: ")+newsitemobject.source - } else if (newsitemobject.messagetype==1){ qsTr("Direct Message")} else {" Notification"} + text: if (newsitemobject.messagetype==1){ qsTr("Direct Message")} else if(newsitemobject.messagetype==2) {" Notification"} else {qsTr("Source: ")+newsitemobject.source} font.pixelSize: 1.5*mm } Label { @@ -117,6 +116,7 @@ Item { id:replytoLabel color: "grey" font.pixelSize: 1.5*mm + font.family: "Noto Sans" horizontalAlignment: Label.AlignRight text: try {qsTr("In reply to ")+newsitemobject.reply_user.screen_name }catch(e){" "} @@ -160,6 +160,7 @@ Item { linkColor: "light green" id: itemMessage textFormat: Text.RichText + font.family: "Noto Sans" text: newsitemobject.statusnet_html//newsitemobject.attachmentList.length>0?newsitemobject.text : newsitemobject.statusnet_html width: newsitem.width-8*mm-2 height: implicitHeight @@ -178,7 +179,6 @@ Item { }} if (newsitemobject.attachmentList.length>0){ - for(var attachments in newsitemobject.attachmentList){// (newsitemobject.attachmentList[attachments].url); if(newsitemobject.attachmentList[attachments].mimetype.substring(0,5)=="image"){ var component = Qt.createComponent("qrc:/qml/newsqml/NewsImage.qml"); @@ -191,8 +191,7 @@ Item { else {//print(newsitemobject.attachmentList[attachments].url+" Type: "+newsitemobject.attachmentList[attachments].mimetype) var component = Qt.createComponent("qrc:/qml/newsqml/NewsVideo.qml"); var videoQml = component.createObject(messageColumn,{"source":newsitemobject.attachmentList[attachments].url,"mimetype":newsitemobject.attachmentList[attachments].mimetype}); -} - + } } } } @@ -289,9 +288,9 @@ Item { CheckBox{ id:likeCheckbox width:10*mm - visible: (newsitemobject.messagetype==0)? true:false + visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false checked:(friendica_activities.self.liked==1)?true:false - style: CheckBoxStyle { + //style: CheckBoxStyle { indicator: Rectangle{ implicitWidth: 10*mm implicitHeight:3*mm @@ -299,11 +298,11 @@ Item { anchors.centerIn: parent font.pixelSize: 2.5*mm font.family:fontAwesome.name - color:control.checked?"black": "grey" - text:control.checked?"\uf118"+"!":"\uf118" + color:likeCheckbox.checked?"black": "grey" + text:likeCheckbox.checked?"\uf118"+"!":"\uf118" } } - } + //} onClicked: { if(likeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"like",newsitemobject.id,root);dislikeCheckbox.checked=false; model.friendica_activities.self.liked=0 } else{Newsjs.like(root.login,root.db,0,"like",newsitemobject.id,root); model.friendica_activities.self.liked=1}} @@ -311,9 +310,9 @@ Item { CheckBox{ id: dislikeCheckbox width:10*mm - visible: (newsitemobject.messagetype==0)? true:false + visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false checked: (friendica_activities.self.disliked==1)?true:false - style: CheckBoxStyle { + //style: CheckBoxStyle { indicator: Rectangle{ implicitWidth: 10*mm implicitHeight:3*mm @@ -321,11 +320,11 @@ Item { anchors.centerIn: parent font.pixelSize: 2.5*mm font.family:fontAwesome.name - color:control.checked?"black": "grey" - text: control.checked?"\uf119"+"!":"\uf119" + color:dislikeCheckbox.checked?"black": "grey" + text: dislikeCheckbox.checked?"\uf119"+"!":"\uf119" } } - } + //} onClicked: { if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.id,root);likeCheckbox.checked=false; model.friendica_activities.self.disliked=0} else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.id,root); model.friendica_activities.self.disliked=1}} @@ -333,20 +332,20 @@ Item { CheckBox { id:favoritedCheckbox - visible:(newsitemobject.messagetype==0) + visible:((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3)) width: 10*mm - style: CheckBoxStyle { + //style: CheckBoxStyle { indicator:Rectangle{ x:4*mm width: 3*mm implicitHeight:4*mm Text{ - color: control.checked?"black":"grey" + color: favoritedCheckbox.checked?"black":"grey" font.pixelSize: 2.5*mm text:"\uf005" } } - } + //} checked:(newsitemobject.favorited>0) onClicked:{ if(favoritedCheckbox.checkedState==Qt.Checked){ @@ -401,21 +400,29 @@ Item { Menu { id:newsmenu - MenuItem { + width: 30*mm + delegate: MenuItem{ + contentItem: Text{ + font.pixelSize: 3*mm + text: parent.text + } + } + Action{ text: qsTr("Reply") onTriggered: { var directmessage=0; if (newsitemobject.messagetype==1){ directmessage=1} - newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"reply_to_user": newsitemobject.user.screen_name,"parentId":newsitemobject.id,"login":root.login,"directmessage":directmessage}); + replySignal(newsitemobject) + //newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"reply_to_user": newsitemobject.user.screen_name,"parentId":newsitemobject.id,"login":root.login,"directmessage":directmessage}); } } - MenuItem { + Action { text: qsTr("DM") onTriggered: { root.directmessageSignal(newsitemobject.user.screen_name); } } - MenuItem { + Action { text: qsTr("Repost") onTriggered: { Newsjs.retweetNews(root.login,db,newsitemobject.id,root,function(reply){ @@ -423,7 +430,7 @@ Item { }) } } - MenuItem { + Action { text: qsTr("Conversation") onTriggered: { conversationsymbol.color="black"; @@ -435,24 +442,31 @@ Item { Menu{ title: qsTr("Attending") - MenuItem{ + width: 20*mm + delegate: MenuItem{ + contentItem: Text{ + font.pixelSize: 3*mm + text: parent.text + } + } + Action{ text:qsTr("yes") onTriggered: {Newsjs.attend(root.login,db,"yes",newsitemobject.id,root,function(){ model.friendica_activities.self.attending="yes";attending="yes"}) } } - MenuItem{text:qsTr("maybe") + Action{text:qsTr("maybe") onTriggered: {Newsjs.attend(root.login,db,"maybe",newsitemobject.id,root,function(){ model.friendica_activities.self.attending="maybe";attending="maybe"}) } } - MenuItem{text:qsTr("no") + Action{text:qsTr("no") onTriggered: {Newsjs.attend(root.login,db,"no",newsitemobject.id,root,function(){ model.friendica_activities.self.attending="no";attending="no"})} } } - MenuItem { + Action { text: qsTr("Delete") onTriggered: { Newsjs.deleteNews(root.login,root.db,newsitemobject.id,newsitemobject.messagetype,root,function(reply){ diff --git a/source-linux/qml/newsqml/PermissionDialog.qml b/source-linux/qml/newsqml/PermissionDialog.qml index f1a66c3..23aa704 100644 --- a/source-linux/qml/newsqml/PermissionDialog.qml +++ b/source-linux/qml/newsqml/PermissionDialog.qml @@ -30,6 +30,7 @@ // along with this program. If not, see . import QtQuick 2.0 +import QtQuick.Controls 2.3 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -37,7 +38,7 @@ import "qrc:/qml/genericqml" Rectangle{ id:permissionDialog x: mm - width: messageColumn.width-5*mm + width: messageColumn.width-3*mm height:root.height/3 function updatePerms(){ for (var i=0;i. -import QtQuick 2.7 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 1.11 +//import QtQuick.Controls.Styles 1.4 import "qrc:/js/smiley.js" as Smileyjs import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -42,8 +43,10 @@ Rectangle{ width: messageColumn.width-5*mm height:root.height/2 - BlueButton{ + Button{ id:closeButton + height: 6*mm + width: 8*mm anchors.top: parent.top anchors.topMargin: 1*mm anchors.right: parent.right @@ -52,34 +55,57 @@ Rectangle{ onClicked:{smileyDialog.visible=false} } - TabView{ + + TabBar { + id: smileybar + width: parent.width + height: 9*mm + position:TabBar.Header + TabButton { + text:qsTr("Unicode") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Standard") + font.pixelSize: 2*mm + } + TabButton { + text: qsTr("Addon") + font.pixelSize: 2*mm + } + + TabButton { + text: qsTr("Adult") + font.pixelSize: 2*mm + } + } + + + StackLayout{ id:smileyTabView - tabPosition: Qt.BottomEdge + currentIndex: smileybar.currentIndex anchors.top: closeButton.bottom anchors.topMargin: 1*mm width: smileyDialog.width-2*mm height: smileyDialog.height-7*mm - currentIndex: 0 - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle { - color: "white" - implicitWidth: smileyTabView.width/4-2*mm - implicitHeight: 4*mm - Text { id: text - anchors.centerIn: parent - text: styleData.title - color: "dark grey" - font.pixelSize:2.5*mm - font.bold: styleData.selected - } - } - frame: Rectangle { color: "light grey" } - tabsAlignment:Qt.AlignHCenter - } +// style: TabViewStyle { +// frameOverlap: 1 +// tab: Rectangle { +// color: "white" +// implicitWidth: smileyTabView.width/4-2*mm +// implicitHeight: 4*mm +// Text { id: text +// anchors.centerIn: parent +// text: styleData.title +// color: "dark grey" +// font.pixelSize:2.5*mm +// font.bold: styleData.selected +// } +// } +// frame: Rectangle { color: "light grey" } +// tabsAlignment:Qt.AlignHCenter +// } - Tab{ - title: qsTr("Unicode") Rectangle{ id: htmlGridTab GridView { @@ -101,9 +127,7 @@ Rectangle{ } } } - } - Tab{ - title: qsTr("Standard") + Rectangle{ id: coreGridTab GridView { @@ -127,9 +151,7 @@ Rectangle{ } } } - } - Tab{ - title: qsTr("Addon") + Rectangle{ id: addonGridTab GridView { @@ -151,9 +173,8 @@ Rectangle{ } } } - } - Tab{ - title: qsTr("Adult") + + Rectangle{ id: adultGridTab GridView { @@ -175,7 +196,7 @@ Rectangle{ } } } - } + @@ -218,6 +239,4 @@ Rectangle{ } } } - - } diff --git a/source-linux/qml/photoqml/ImageUploadDialog.qml b/source-linux/qml/photoqml/ImageUploadDialog.qml index a36aeed..9302135 100644 --- a/source-linux/qml/photoqml/ImageUploadDialog.qml +++ b/source-linux/qml/photoqml/ImageUploadDialog.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.4 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/image.js" as Imagejs import "qrc:/qml/genericqml" @@ -132,9 +132,11 @@ function updateImage(){ // } // } - BlueButton{ + Button{ id:closeButton + height: 8*mm text: "\uf057" + font.pixelSize: 3*mm onClicked:{photoStack.pop(); //imageDialog.destroy() } @@ -236,7 +238,7 @@ function updateImage(){ source:"qrc:/images/addImage.png" MouseArea{ anchors.fill: parent - onClicked:{print(imagePicking) + onClicked:{ imagePicking=true; var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+ @@ -264,10 +266,12 @@ function updateImage(){ ListModel{id:albumModel} - BlueButton{ + Button{ id:uploadButton + height: 8*mm x:4*mm; y:root.width/2+18*mm //40*mm text: imageId==""?qsTr("Upload"):qsTr("Change") + font.pixelSize: 3*mm onClicked:{ if(album.currentText==""){Helperjs.showMessage(qsTr("Error"),qsTr(" No album name given"), imageDialog)} else if (imageId!=""){uploadBusy.running=true; updateImage()} diff --git a/source-linux/qml/photoqml/PhotoTab.qml b/source-linux/qml/photoqml/PhotoTab.qml index 4ebacac..7c54269 100644 --- a/source-linux/qml/photoqml/PhotoTab.qml +++ b/source-linux/qml/photoqml/PhotoTab.qml @@ -30,7 +30,7 @@ // along with this program. If not, see . import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.4 import QtQml.Models 2.1 import "qrc:/js/image.js" as Imagejs import "qrc:/js/helper.js" as Helperjs @@ -40,12 +40,13 @@ import "qrc:/qml/genericqml" StackView{ id: photoStack - anchors.fill:parent + //anchors.fill:parent initialItem:Rectangle { id:fotorectangle - y:1 - width:root.width-mm - height:root.height-5*mm + anchors.fill:parent +// y:1 +// width:root.width-mm +// height:root.height-5*mm color: '#fff' property var newimages:[] property int currentimageno: 0 @@ -141,14 +142,14 @@ StackView{ function updatepic(method,type,id){ if(method=="update"){ Helperjs.readData(db,"imageData",login.username,function(url){ - photoStack.push({ - item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{attachImageURLs:[url[0].location+url[0].filename],imageId:id,currentAlbum:url[0].album} - }) + photoStack.push( + "qrc:/qml/photoqml/ImageUploadDialog.qml",{"attachImageURLs":[url[0].location+url[0].filename],"imageId":id,"currentAlbum":url[0].album} + ) },"id",id)} } function uploadUrls(urls){ - photoStack.push({item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{attachImageURLs:urls}}) + photoStack.push("qrc:/qml/photoqml/ImageUploadDialog.qml",{"attachImageURLs":urls}) } ProgressBar{ @@ -162,35 +163,43 @@ StackView{ value: fotorectangle.currentimageno/fotorectangle.newimages.length } - BlueButton{ + MButton{ id: uploadPhoto anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right:updatePhotolist.left anchors.rightMargin:mm + height: 6*mm + width: 8*mm text:"\uf0ee" - onClicked: {print(root.imagePicking) - photoStack.push({item:"qrc:/qml/photoqml/ImageUploadDialog.qml",properties:{}}); + onClicked: { + photoStack.push("qrc:/qml/photoqml/ImageUploadDialog.qml"); // var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml"); // var imageUpload = component.createObject(fotorectangle); }} - BlueButton{ + MButton{ id: updatePhotolist anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right:phototabstatusButton.left anchors.rightMargin:mm + height: 6*mm + width: 8*mm text:"\uf0ed" + Menu { id:photoupdatemenu + width:40*mm MenuItem { text: qsTr("All Images") + font.pixelSize: 3*mm onTriggered: { Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){fotorectangle.newimages=obj})} } MenuItem { text: qsTr("Only new") + font.pixelSize: 3*mm onTriggered: { Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){fotorectangle.newimages=obj})} } @@ -198,17 +207,21 @@ StackView{ onClicked: {photoupdatemenu.popup()} } - BlueButton{ + MButton{ id: phototabstatusButton anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right: parent.right anchors.rightMargin:2*mm + height: 6*mm + width: Math.max(10*mm,implicitWidth) text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus Menu { id:phototabmenu + width: 40*mm MenuItem { text: qsTr("Own Images") + font.pixelSize: 3*mm onTriggered: { fotostab.phototabstatus="Images"; // phototabstatusButton.text=qsTr("Own images"); @@ -267,8 +280,10 @@ StackView{ ListView { width: parent.width; height:parent.height; model: visualphotoModel.parts.browser; interactive: false } - BlueButton { + MButton { id: backButton + height: 6*mm + width: 8*mm text: "\uf057" x: parent.width - backButton.width - 3*mm y: -backButton.height - 4*mm diff --git a/source-linux/qtquickcontrols2.conf b/source-linux/qtquickcontrols2.conf new file mode 100644 index 0000000..3222ebf --- /dev/null +++ b/source-linux/qtquickcontrols2.conf @@ -0,0 +1,14 @@ +[Controls] +Style=Material + +[Universal] +Theme=System +Accent=Red + +[Material] +Theme=Light +Accent=LightBlue +Primary=BlueGrey,50 +Background=Grey,50 +Variant=Dense + diff --git a/source-linux/translations/friendiqa-de.qm b/source-linux/translations/friendiqa-de.qm index ec5be92fa8c3fa69a82916cafe71892772655592..642a1803ab9025ee55856b3e37cffcd5991dcd8e 100644 GIT binary patch delta 2465 zcmZ8ieRNax8Gh2_-kW=qG^P1~wG;v^w8au(Yo~mbmL6ITXe+c6PLV;H-j+z3&?Z59 zHq18bVYBrV7AN2`bOIZ-I+!_ltmr-*OZf;L$`bYZY z_x|3G=Y8JymtJ~c=f<7RcnM&70?4rdLIt4I15yK!Tcu<16ynRkbO+EJ1k83F<%e{1 znSk~SK;d732Y*Do1$<`?ko{dC{s-o1*Rga9gsN=7a{xl^W4u48W8BdRVFe50Dug~J zn;C;}qy`Z4A)J1L%?I!;165Dq4QSp|p~*y-0)MEcoTuA<}YsfenFfZ0Qcp1ua;{RHt>=wDig z{ZfR)3osB|!1|sMT&$&RQ}4p3Wi7<*hVMVTAIQHaYkuwqz;ZroV9#?5+?6#P`5j

%y^|>71F5|nQXL-NC`02_=spujdXS5mrXRZW_Qzqd|ii93B zEi#^C+#9BSJ#i*bE|^{@J4nL{)2S`}<^cDgB**l}VFm~rOlR+Z8!!}@E@}7n zKGVlRcA(_zm^&3ce}MJ4C{Hr^Us-S@hp1E1AnX-X;3Y zkDC)SN&(w%%+Fu^fV2D3eE2N4Q@o|4dAE+v9P{gar$}VbeDY2bn|axMx*?kdPnbXZ z7k4N-PtGrPazu~I`Hz!G(KGVB?Ki3DavjZY>1dg(qq9NY@VD=AB=Nt<{+-hHXQt%BQRSxu3N{M z*IJJmBHWp^)(@*XnNP6^cJ566fUWZSKFNDy7^Pif|CO7H6s-vWbLtXL3tp?G+V2m?Lecwt?P}ttV@alA zaMG+y!wPX;rr~4JlWA~BrJ06WsVviAGat(|{K?#%Y52RmHq)?3nP5mNt1~^mP$pEF zYnh$tvB5Go)3C+;%}m4H)(O3|SnF)#1u`V^gr39>(YsEm35VJO?V4%^BUfk+su4pJ zVRXO?4^LZoiou5<0*LUVqKoGc+RfU^iTs!vyF-47U&bX%Jd=G_>aulMDEK;7F($wW z50*3QRe*7*a>4RM~wwXi0PQ z!H>=4?H$W2hQiT6Tep_lrfF6a?${a*siA0^g_$fgv2XjEBBR1)dMAD>dMt{bKpS4- zNlWvRap!b4D`gK;si?+fjDdOdl|(cSa$8q`5(GMZ+JjNX9d|kxj6c5REMI;5Hl02X zH#o<(^o}%fx*aT|ZAb{}STXy3v6f)K?`aBjsKG!;olx_?uCnn(u1_s>OKa4&E;X`w zf~VJAQ9q%+f<}&B6Zm#Lu~GGP`6mRAvR$6$rY()eGnn}2G^e{!jYb2Z_K8~XIgR6$ Jx>EeG_bz-6n<^8yV*_Bq-lCUTe>Cmf&xXTN~y>-t$>wE8gSvR|V z#yYc~h}3I{OjSfoE|GQx5m!uPzNlb&0`L$~>H(q>ClNnVL7`E>_^m{aD@4675Y1l= zd_v^^jwlv&J27(sF(aagB0eRiU=@*}L%}$Km^aYRAJIz8q6VUvCB)RKiHz5XY5o>X zQ;6L-ohYG}*d0y4W5hP9h%6bzw)Q9LnM>?_#93|<_gf7JUZDJb_lVdl3Pw+)!u_*A zNJoX=3<2iTo102OgcQ_m2%(?!b7<=PASNRP1)qZPcA9o-D2Qz)$HwCzAX2$AK-4Fh zyb+iz@iBSVVj^?Bf@w+QllBs&HIc9RE>ZFT@*hTgW+BycUZNg{sL_df?7MWM09)$S zO1H90vHz5~h?SM~NN9^3WSU8&=OP>Hb|Ga^QAZc8 zK9KF-je>a!=12xYWPIgge7t8VY~o7Cz*oL*?8NWs`y3>$+@ z#Fa7J6ANyBj^XcY!-i@ZV`45QtYNZE(L|~yX4t|#h#Sm|zdsnKn!?nEPTs=Q`S-ht zG$)z5P813hjL%`VY{6|=GjpH@+DNQqPVNQK_@9|mxjry&W^UKKO_a2TwTz3w2IsLk zdqFh0l+CxLK^yl|$05!*5f{*3#q|Ce!S)U%9J zO$uOwPq^3|6gF<-`o0gP>(_H5W}tD}WUip(F7S75`Bf_>EaqyiLR_MY+hAbOcq_N% z;WA8?#_g}gMiM4+hnsMs%s;uNoOTdAqY0#D5k;-m?7Q(RPIg&yumz&j4Du@ve6xaa zjhd4SMi52XHKzuGP;{)Oxi|_9Px6TwX1wp<6F&k0%XYrV@fZabD=4TG)QwdzuAQIx z(+V8$7;mp`1JP@|t24fboBz=NB?e65*BnP3t$z>y^;|H{ST4kU^$>xAFt_y_j=e&V z#)B!h`6*skkpDn%PJe(2JA~@b`rvO>CNyoqX4o;pk+qYt@+RSU``;jbR!fZoAi|Ma zCdCd7$=W%V^VswrZQY5RAo4)F>4!V`|C?XZS$0=JoriS;FJ1g`V256(#DE;t`Z4l=uy<9LFbr$Qr!Qp5)P`~y# z;lcH1d4`gGQ5ZOA*fqL>j1<}5@Od0oVVNisWfcat3)O)Frmw({E_ct9 z9g}UPfo05V;pR?bTDWE*`2NJa}hr8O+#Bei3NHAG#E{Vf_!^+QMv%;eSY_`A4 z8=*q*II@zBTqKbQte|uI zU0pzDh?^C^i@~NpjU+cM#rraNL_9y`9BAQEvXialqRUn(yDD6wTUzWD-4(7<$s>jc zrM^HUUNbeE$kOiSCCyvm-aI}#-1PA2;bsHhKio8?mxP;__-vH-9Fn(l%x5`) zo9RO}&y7JDLzs{eIGAARdTlhn?tc~&YGR@ybZ|l>6 + + AccountPage + + + + + User + Name + + + + Server + Server + + + + Nickname + Kurzname + + + + Password + Passwort + + + + Image dir. + Bildverz. + + + + News as + Anzeige + + + + + + Error + Fehler + + + + Nicknames containing @ symbol currently not supported + Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. + + + + Confirm + Bestätigen + + + + No server given! + Kein Server angegeben! + + + + No nickname given! + Kein Kurzname angegeben! + + + + No password given! + Kein Passwort angegeben! + + + + No image directory given! + Kein Verzeichnis für Bilder angegeben! + + + + Wrong password! + Falsches Passwort! + + + + Success + Bestätigt + + + + Name + Name + + + + Timeline + Chronologisch + + + + Conversations + Unterhaltungen + + CalendarTab - + Events Termine - + Own Calendar Eigener Kalender - ConfigTab + ConfigPage - - - - User - Name - - - - Server - Server - - - - Nickname - Kurzname - - - - Password - Passwort - - - - Image dir. - Bildverz. - - - + Max. News Max. Nachr. - + + Sync + Autom. Aktualisierung + + + + ConfigTab + + User + Name + + + Server + Server + + + Nickname + Kurzname + + + Password + Passwort + + + Image dir. + Bildverz. + + + Max. News + Max. Nachr. + + News as - Anzeige + Anzeige Interval (0=None) Intervall (0=keins) - - - Error - Fehler + Fehler Nickname not registered at given server! Name auf der Seite nicht registriert! - Confirm - Bestätigen + Bestätigen - No server given! - Kein Server angegeben! + Kein Server angegeben! - No nickname given! - Kein Kurzname angegeben! + Kein Kurzname angegeben! - Nickname not registered at given server! - Name auf der Seite nicht registriert! + Name auf der Seite nicht registriert! No username given! Kein Nutzername angegeben! - Sync Interval (0=None) - Akt.-intervall (0=keine) + Akt.-intervall (0=keine) - Nicknames containing @ symbol currently not supported - Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. + Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. - Min. - Min. + Min. - No password given! - Kein Passwort angegeben! + Kein Passwort angegeben! - No image directory given! - Kein Verzeichnis für Bilder angegeben! + Kein Verzeichnis für Bilder angegeben! - No maximum news number given! - Maximale News-Anzahl nicht angegeben! + Maximale News-Anzahl nicht angegeben! - Wrong password! - Falsches Passwort! + Falsches Passwort! - Success - Bestätigt + Bestätigt - Name - Name + Name - Timeline - Chronologisch + Chronologisch - Conversations - Unterhaltungen + Unterhaltungen @@ -197,27 +280,27 @@ Kontaktanfrage - + Description Beschreibung - + Location Ort - + Posts Beiträge - + URL Profilseite - + Created at Erstellt @@ -225,22 +308,22 @@ FriendsTab - + Me Ich - + Friends Freunde - + Contacts Kontakte - + Groups Gruppen @@ -272,27 +355,27 @@ Bild - + Description Beschreibung - + Upload Hochladen - + Change Ändern - + Error Fehler - + No album name given Kein Albumname angegeben @@ -300,22 +383,54 @@ MessageSend - + + + + + to: + an: + + + Title (optional) Überschrift (optional) - + + What's on your mind? + Woran denkst du gerade? + + + + Error Fehler - + Only one attachment supported at the moment. Remove other attachment first! Nur ein Anhang derzeit unterstützt. Lösche zuerst den anderen Anhang! + + + No receiver supplied! + Kein Empfänger angegeben! + + + + NewsStack + + + Network Error + Netzwerk-Fehler + + + + More + Mehr + NewsTab @@ -324,63 +439,52 @@ Lade Profilbild für - More - Mehr + Mehr - Timeline - Chronologisch + Chronologisch Error Fehler - Favorites - Markierte News + Markierte News - Conversations - Unterhaltungen + Unterhaltungen - Network Error - Netzwerk-Fehler + Netzwerk-Fehler - Replies - Interaktionen + Interaktionen - Public timeline - Gemeinschaft + Gemeinschaft - Direct Messages - Direktnachrichten + Direktnachrichten - Notifications - Meldungen + Meldungen - Group news - News Gruppe + News Gruppe - Quit - Schliessen + Schliessen @@ -396,7 +500,7 @@ Quelle: - + Direct Message Direktnachricht @@ -411,65 +515,60 @@ Kommentare - + Attending: Teilnahme: - + Reply Antworten - + DM Direktnachricht - + Repost Teilen - + Success! Erledigt! - + Conversation Unterhaltung - + Attending Teilnahme - + yes ja - + maybe vielleicht - + no nein - + Delete Löschen - - - Post - - PermissionDialog @@ -487,28 +586,28 @@ PhotoTab - + 's images s Bilder - + All Images Alle Bilder - + Only new Nur neue - - + + Own Images Eigene Bilder - + More Mehr @@ -516,222 +615,222 @@ ProfileComponent - + profile name Profilname - + is default Hauptprofil - + hide friends Verberge Freunde - + profile photo Profilbild - + profile thumb Mini-Profilbild - + publish öffentlich - + publish in network Öffentlich im Netzwerk - + description Beschreibung - + date of birth Geburtstag - + address Adresse - + city Stadt - + region Region - + postal code Postleitzahl - + country Land - + hometown Heimatstadt - + gender Geschlecht - + marital status Beziehungsstatus - + married with verheiratet mit - + married since verheiratet seit - + sexual Sex - + politics Politik - + religion Religion - + public keywords öffentliche Schlagwörter - + private keywords private Schlagwörter - + likes Vorlieben - + dislikes Abneigungen - + about über - + music Musik - + book Bücher - + tv TV - + film Filme - + interest Interessen - + romance Liebschaften - + work Arbeit - + education Bildung - + social networks Soziale Netzwerke - + homepage Homepage - + Update Aktualisieren - + profile id Profil-Nummer - + Description Beschreibung - + Location Ort - + Posts Beiträge - + URL Profilseite - + Created at Erstellt @@ -739,101 +838,183 @@ SmileyDialog - + Unicode Unicode - + Standard Standard - + Addon Addon - + Adult XXX + + SyncComponent + + + sync + akt. + + + + notify + benachr. + + + + SyncConfig + + + Sync Interval (0=None) + Akt.-intervall (0=keine) + + + + Min. + Min. + + + + friendiqa + + + Refresh + Aktualisieren + + + + Timeline + Chronologisch + + + + Conversations + Unterhaltungen + + + + Favorites + Markierte News + + + + Replies + Interaktionen + + + + Public Timeline + öff. Timeline + + + + Group news + News Gruppe + + + + Search + Suche + + + + Settings + Einstellungen + + + + Accounts + Konten + + + + Quit + Schliessen + + newsworker - + likes this. mag das. - + like this. mögen das. - + doesn't like this. mag das nicht. - + don't like this. mögen das nicht. - + will attend. nehmen teil. - + persons will attend. Personen nehmen teil. - + will not attend. nimmt nicht teil. - + persons will not attend. Personen nehmen nicht teil. - + may attend. nimmt vielleicht teil. - + persons may attend. Personen nehmen vielleicht teil. - + yes ja - + no nein - + maybe vielleicht - + seconds Sekunden - - @@ -842,51 +1023,53 @@ + + ago her - + minute Minute - + minutes Minuten - + hour Stunde - + hours Stunden - + day Tag - + days Tage - + month Monat - + months Monate - + years @@ -898,12 +1081,12 @@ Fehler - + Undefined Array Error Antwort-Array ungültig - + JSON status Error Server-Antwort: Fehler diff --git a/source-linux/translations/friendiqa-es.qm b/source-linux/translations/friendiqa-es.qm index be15226a3a25bdfecb3d184c2dae3035cbd43557..840815743aeec3d5dcc0be5385f5ec9ff266eb17 100644 GIT binary patch delta 1509 zcmZ8fYiv_x7=G4szH@84-gfCI#^5GIwhU0JX~yQd!A88Sn#m;#xRtJ}ou#w1!(>6L zd=GP~Yts>G8+O^L@{GpZ9y; z=Y0=W9j@G$lk5WcJwSFjz}$em4iJ5Sb%%xphk=F&ojn>#2Q_rG0HN=Iyd=>25@8BR zeoVT5(KQBEvmG#fqoM6A*h)KgN!r6~R@NJ-=7Ri$o;QG+8#J(O-#to^iUSO_l7>W-7hAGaw^eb{I#nsf= z$+a8Yw^4G(aDe;ep{-PqN5h==xm!{NFlQ0ZE>J-Q4!(@LM7m%3L)%C%PxHr1`sm)l z4^M*ZvpV?;N9sthkN- z+sx#vhXCh%W_7vAsROLUZX!8vk_h`adu7fyD``LMSf*d#@RKMw<0+tI6&l5@m!tm=&l&D`Attus_o)Nivl^$3o=9aD^ zeY3c*(+e2=V&yvO(D{Q{({PO(h>6dAPYvc@7Ehic=jProsq^lk-PkD|O^*FY53ZKp z8>QI_`5KCS8rqwr5nnbXipZ{)XA*ejM?-&6T%(5KWepX#hW0n)^bn=VxN6qBeoLfrsrHf=Kl;FekF6&Z~+Tlx$5TnYrcZz7qyvnH_s+=2E1}Cml zqD~`HrPRrgk=+>};YwroXIIIIaZ_R6R_c7Q$=5eUx(?IntT-*R&2*(QMxzXyD}JNV zm~WcHHP!V0x;dV%p!ZLh_YP8i>Cd~hgY}}N;V54_1!Tzyb->Pf$}N>2<(i}l0}X`!Adl^5uVM)`k|Zh5{wVnlx2oasxJdXC$nma$5s zQr#A935RCQYEp{RKE)-fetUr;*9D)A*C+ger`1loC*ztv?TCqLlK03ho5I0pb2#Q# zuh|wU8P_fOE_H?7l1WL9vb-n48-tN>G$_(!GosfxiXykKS=`Ltp$hGYBLKfdR|qp- tebB!t@RVLW8=Va=T4&=E2qONULaGlY65(hluGgrI@{-%{r5Cs+*+21)oV5S| delta 1606 zcmZ9KeM}p57{?#D``t@lXrYv~rOl2&vW)>ULnDMqU@WlAQKE<}#5qg3*4t=L+T+DU zt%2#H+p;BRbT~kqps=APkQkW$p&Q!(6_==Se`wsB$u^^VL0Gb6!v}7TV}CTCKJU-- z{as(_`#s>lD0|3@p0OAEOtN~!F0c;yJy7mIpHvw?8M!rE~nj0YW2f(Tzz^=EE zhXCTIux_VD_cV}-Hvy84XiRMbvIYAmOaR%By)5qmnL3HN0``IFZPRLr?enu&|B({xlY1>zU_%!b@+{R~O^fD1EId2Efm2w0%Vw z8%mz~D`6KhkvW9F)r$ko#G39!rM8lslw^R!pGk4^rx@=g`&;{QP9`~gJc3HKA>;Um z`&)C^dq{UTJ^?8rXT1t4@G4XOu?^qqE>r(HlHbQn_PmGNqrHybasCYe z>MFlCK7t?NxBP(#tTSxmPc))p=~oPm=YBv*I}CC0DO`XF7&LyUkt;In`78@1yki*e z#tTT;Fmd$`K0%=ohVt;DVIx@`z^7?3cKvt@73nc$4s_xm$y7ZshaYpk>D>kNQX+17179vjf>P*Ne}n3Gl<2J7q)dIVfi7VmMAdn2i#{|= zXX(w~Xs_P%kZiqqojg&v&L;(SNBm(?h{%c%6+==?5u;+G;8%o@)G9`Vm>6vpqZtB= z66)Xgo8cqy!3hu`3>TptB&4jGd8gXIq!!AM!C?|G`1AN=A?$CL!YyGT zBDTeZNK3dujA|1z9+`BVRO`2PaZjopj6?7GgsIh=ESs-4%h?rIzrwE3M~7D?dx*zI z*W%5OEaBpw)>o}It{+wSbXE;I3OUw?CoI0&Kgqdn%VsGm1{9%6jK%yRF}B#}VZxx} zvE}TGj%>0NQDu9^vU|i@^4Nme(CDuaS@2JshA?^6z^PgbO$6!0sO99cQS?krAK fq_Ef|MZ^`egU+nwA$aveV|32i%#M0pf06$H4o + + AccountPage + + + + + User + Usuario + + + + Server + Servidor + + + + Nickname + Usuario + + + + Password + Contraseña + + + + Image dir. + Dir. de imágenes + + + + News as + Noticias como + + + + + + Error + Error + + + + Nicknames containing @ symbol currently not supported + + + + + Confirm + Confirmar + + + + No server given! + ¡Servidor no encontrado! + + + + No nickname given! + ¡Usuario incorrecto! + + + + No password given! + ¡Contraseña incorrecta! + + + + No image directory given! + ¡No se ha encontrado el directorio de imágenes! + + + + Wrong password! + ¡Contraseña incorrecta! + + + + Success + éxito! + + + + Name + Nombre + + + + Timeline + Cronología + + + + Conversations + Conversaciones + + CalendarTab - + Events Eventos - + Own Calendar Calendario propio - ConfigTab + ConfigPage - - - - User - Usuario - - - - Server - Servidor - - - - Nickname - Usuario - - - - Password - Contraseña - - - - Image dir. - Dir. de imágenes - - - + Max. News Nº Max. de noticias. - + + Sync + + + + + ConfigTab + + User + Usuario + + + Server + Servidor + + + Nickname + Usuario + + + Password + Contraseña + + + Image dir. + Dir. de imágenes + + + Max. News + Nº Max. de noticias. + + News as - Noticias como + Noticias como Interval (0=None) Intervalo (0=ningún) - - - Error - Error + Error - Confirm - Confirmar + Confirmar - No server given! - ¡Servidor no encontrado! + ¡Servidor no encontrado! - No nickname given! - ¡Usuario incorrecto! + ¡Usuario incorrecto! - Nickname not registered at given server! - ¡Usuario incorrecto! + ¡Usuario incorrecto! No username given! ¡Usuario incorrecto! - - Sync Interval (0=None) - - - - - Nicknames containing @ symbol currently not supported - - - - - Min. - - - - No password given! - ¡Contraseña incorrecta! + ¡Contraseña incorrecta! - No image directory given! - ¡No se ha encontrado el directorio de imágenes! + ¡No se ha encontrado el directorio de imágenes! - No maximum news number given! - ¡Nº máximo de noticias incorrecto! + ¡Nº máximo de noticias incorrecto! - Wrong password! - ¡Contraseña incorrecta! + ¡Contraseña incorrecta! - Success - éxito! + éxito! - Name - Nombre + Nombre - Timeline - Cronología + Cronología - Conversations - Conversaciones + Conversaciones @@ -193,27 +264,27 @@ Conectar - + Description Descripción - + Location Localización - + Posts Mensajes - + URL URL - + Created at Creado en @@ -221,22 +292,22 @@ FriendsTab - + Me Yo - + Friends Amigos - + Contacts Contactos - + Groups Grupos @@ -257,27 +328,27 @@ imagen - + Description Descripción - + Upload Subir - + Change Cambiar - + Error Error - + No album name given ¡Nombre del álbum no encontrado! @@ -285,22 +356,54 @@ MessageSend - + + + + + to: + + + + Title (optional) Título (opcional) - + + What's on your mind? + + + + + Error Error - + Only one attachment supported at the moment. Remove other attachment first! Solo se admite adjuntar un solo archivo en este momento. ¡Elimine y deje un archivo adjunto! + + + No receiver supplied! + + + + + NewsStack + + + Network Error + Fallo de red + + + + More + Mas + NewsTab @@ -309,63 +412,48 @@ Descargar la imagen del perfil para - More - Mas + Mas - Timeline - Cronología + Cronología Error Error - Favorites - Favoritos + Favoritos - Conversations - Conversaciones + Conversaciones - Network Error - Fallo de red + Fallo de red - - Replies - - - - Public timeline - Cronología pública + Cronología pública - Direct Messages - Mensaje directo + Mensaje directo - Notifications - Notificaciones + Notificaciones - Group news - Grupos + Grupos - Quit - Salida + Salida @@ -381,7 +469,7 @@ Fuente: - + Direct Message Mensaje directo @@ -396,65 +484,60 @@ comentarios - + Attending: Asistiendo: - + Reply Respuesta - + DM Mensaje directo - + Repost Volver a publicar - + Success! éxito! - + Conversation Conversación - + Attending Asistiendo - + yes si - + maybe quizás - + no no - + Delete Borrar - - - Post - - PermissionDialog @@ -472,28 +555,28 @@ PhotoTab - + 's images s Imágenes - + All Images Todas las imagenes - + Only new Solo nueva - - + + Own Images Mis imágenes - + More Mas @@ -501,324 +584,406 @@ ProfileComponent - + profile name Nombre de perfil - + is default - + hide friends - + profile photo - + profile thumb - + publish - + publish in network - + description - + date of birth - + address - + city - + region - + postal code - + country - + hometown - + gender - + marital status - + married with - + married since - + sexual - + politics - + religion - + public keywords - + private keywords - + likes - + dislikes - + about - + music - + book - + tv - + film - + interest - + romance - + work - + education - + social networks - + homepage - + Update - + profile id - + Description - Descripción + Descripción - + Location - Localización + Localización - + Posts - Mensajes + Mensajes - + URL - URL + URL - + Created at - Creado en + Creado en SmileyDialog - + Unicode Unicode - + Standard Standard - + Addon Addon - + Adult XXX + + SyncComponent + + + sync + + + + + notify + + + + + SyncConfig + + + Sync Interval (0=None) + + + + + Min. + + + + + friendiqa + + + Refresh + + + + + Timeline + Cronología + + + + Conversations + Conversaciones + + + + Favorites + Favoritos + + + + Replies + + + + + Public Timeline + Cronología pública + + + + Group news + Grupos + + + + Search + Busca + + + + Settings + Ajustes + + + + Accounts + + + + + Quit + Salida + + newsworker - + likes this. le gusta esto. - + like this. me gusta esto. - + doesn't like this. no de ése. - + don't like this. no me gusta. - + will attend. asistirá. - + persons will attend. Personas que asistirán. - + will not attend. no asistirá. - + persons will not attend. Personas que no asistirán.. - + may attend. Puede asistir. - + persons may attend. Personas que pueden asistir. - + yes si - + no no - + maybe quizás - + seconds Segundos - - @@ -827,51 +992,53 @@ + + ago hace - + minute Minuto - + minutes Minutos - + hour Hora - + hours Horas - + day Dia - + days Dias - + month Mes - + months Meses - + years Años @@ -883,12 +1050,12 @@ Error - + Undefined Array Error - + JSON status Error diff --git a/source-linux/translations/friendiqa-it.qm b/source-linux/translations/friendiqa-it.qm index 0094b47778b7ddcc15d5b0a4deb03b8d15cafa9c..bb3841b48aa4525cec7e39be7a33d2d7af4f9d4f 100644 GIT binary patch delta 1545 zcmZuwe{54_6g}O0-}}{e?S6HekTAoX8~c$)SWq?w+maz_JGGJF1Y&95O0j#5Ygc6v zY6KH8EQ7p7Mi^?4g$)!E`wys5Ns2nuCSO%>dsI*bV_=JCOUMfyEC2oe@AdW1z$vn70N9%>ad^z|Q@I>wx4q z;1CTg-37Kj7sy`;*7iDJ?K99Z4fbd~fDBmr3#$1bgfWhC3cDfPA)?5Q#_B%-?xukS zGuUu?8<4jH8$MY@ID{vTY$t&|2FkC@<4ttzOi`oV28ve=%mX%Gcm%K?Ml_<6{m=X6O;g^}{QET{b z@B$^}{N>41k_0>WsZC!3mMVTW8(=Hse~H8ZY0yB2p9uw7i!)5V{WeYVDXYn+@hoq# z1BnwZ-4&)<>S*#Dk@M+Pa7bM7S~H+571wW}30w)Wt@C%9kcqpm(*#9(#dGJ$kq_b1BGB#+Sc%OmJMk(E%OL>3GOWvgX!k=YNGIW;$zmq*#6gL?t z*Bj{EEpPqiRkFHR?w_CpX;S_uNKTXtD8cC~WEB+kaVp4)=J6>5g&WGg56bDzOep7v zsbOwZnV9{H8oX}BSRD<}VP(q#JyDdQ5^k)ee^kWi>7}OcQ|X6MaLg(OZ1aYM{qtTCTsHyu z@6{80s=p_&BdhI~ha&9;8HsZ&<-N2YCUM9=XWoV@SeeZJ58{Q5kf z=lfvQ*y@8hiERM8AISUx5UPP}*~Gl}f!Y>2?=n%mY@#y`1b+i^G@$7N!jFK&Da!Mh z=)M51@?F5T-b9BL+zUlO+Lz$Yeg|*|!1pnfcMALivJ<&`Q2O+Ja%?iub_^Siz79Bh zu;JuN!ZEzmQ3v1;6D_`n_zgBU4HCf$6UA;5ou$|^QUcg7L2EI9+yUrqL@4W)iLQ1; zmCu2^XOK8yAOUxGdSCltz$}Ejl1InwZ_i@lKM~QNl@gKcNOWT%jWyNZ-xvi}z4Lj%z;} z2KWgR#by&7lU!#fNy}d4Mv9_<0~!B_N3LF@M*ZTz zD6NWbG*P%^qGPA{eRDYxUL&5Z&ZK%iDSvOW&KjvI_%FpDm#PxUgSf=}VUbL93`wtD zew!rUC+#1m1gS&%x}KDnbKO#ZkuEAC7Ue~1%#EAKFEUa1%CftEAzdz5hB}Ej=d=vp z{F{`Wmw~=zG)R92w;(`@2QxY@+$9AxYvS=<+NsTHt?s2um{Vf?aFQGhW4$t$3fOj7 zub1zjLMLryf6)pu_uAA-5AFC@n?6`Zh4O7}!xSeyZ(?@PUVDTlb-V3{Ju#X*!~TVf z2FUqSCE02iqHe`{#GxRJC{z)~&qBb6Gf!9~j}~rFgPZ(y#&TC_iglY=lScda4yth_EbB@nu0#stSxp2kwlTFTQSj2MK&LlGgUj^A5TZX3Xk>-ppYo}6 zO4{{Mr(zVeLN~Va^9$#DH96$psfJ=9IjpqmayS;MQz9mhf?552e6G>Om8T9m&TUOK zeSA%-IlvdDnm71Iw&50vQ@y^t6*I#b?ZU$18FQ9`_RSG39F({Fb-h)K)X(BMxJPW_ zjUv}`qTr>Gl8cXLt(a$Dr$&@ORIXBV-5*r+ + + AccountPage + + + + + User + Utente + + + + Server + Server + + + + Nickname + Utente + + + + Password + Password + + + + Image dir. + Directory immagini + + + + News as + News come + + + + + + Error + Errore + + + + Nicknames containing @ symbol currently not supported + + + + + Confirm + Conferma + + + + No server given! + Nessun server inserito! + + + + No nickname given! + Nessun utente inserito! + + + + No password given! + Nessuna password inserita! + + + + No image directory given! + Nessuna directory immagini inserita! + + + + Wrong password! + + + + + Success + Ha funzionato! + + + + Name + Nome + + + + Timeline + Cronologia + + + + Conversations + Conversazioni + + CalendarTab - + Events Eventi - + Own Calendar Calendario - ConfigTab + ConfigPage - - - - User - Utente - - - - Server - Server - - - - Nickname - Utente - - - - Password - Password - - - - Image dir. - Directory immagini - - - + Max. News Nº Max. di notizie - + + Sync + + + + + ConfigTab + + User + Utente + + + Server + Server + + + Nickname + Utente + + + Password + Password + + + Image dir. + Directory immagini + + + Max. News + Nº Max. di notizie + + News as - News come + News come Interval (0=None) Intervallo (0=nessuno) - - - Error - Errore + Errore - Confirm - Conferma + Conferma - No server given! - Nessun server inserito! + Nessun server inserito! - No nickname given! - Nessun utente inserito! - - - - Nickname not registered at given server! - + Nessun utente inserito! No username given! Nessun utente inserito! - - Sync Interval (0=None) - - - - - Nicknames containing @ symbol currently not supported - - - - - Min. - - - - No password given! - Nessuna password inserita! + Nessuna password inserita! - No image directory given! - Nessuna directory immagini inserita! + Nessuna directory immagini inserita! - No maximum news number given! - Nessun numero massimo di news inserito! + Nessun numero massimo di news inserito! - - Wrong password! - - - - Success - Ha funzionato! + Ha funzionato! - - Name - - - - Timeline - Cronologia + Cronologia - Conversations - Conversazioni + Conversazioni @@ -193,27 +252,27 @@ Connetti - + Description Descrizione - + Location Località - + Posts Messaggi - + URL URL - + Created at Creato il @@ -221,22 +280,22 @@ FriendsTab - + Me - + Friends Amici - + Contacts Contatti - + Groups Gruppi @@ -257,27 +316,27 @@ Immagine - + Description Descrizione - + Upload Carica - + Change - + Error Errore - + No album name given Nessun nome album inserito! @@ -285,22 +344,54 @@ MessageSend - + + + + + to: + + + + Title (optional) Titolo (opzionale) - + + What's on your mind? + + + + + Error Errore - + Only one attachment supported at the moment. Remove other attachment first! Solo un allegato è attualmente supportato. Rimuovere prima gli altri allegati! + + + No receiver supplied! + + + + + NewsStack + + + Network Error + + + + + More + Ancora + NewsTab @@ -309,63 +400,36 @@ Download immagine profilo per - More - Ancora + Ancora - Timeline - Cronologia + Cronologia Error Errore - Favorites - Favoriti + Favoriti - Conversations - Conversazioni + Conversazioni - - Network Error - - - - - Replies - - - - - Public timeline - - - - Direct Messages - Messaggio diretto + Messaggio diretto - Notifications - Notifiche + Notifiche - Group news - Gruppi - - - - Quit - + Gruppi @@ -381,7 +445,7 @@ Codice: - + Direct Message Messaggio diretto @@ -396,65 +460,60 @@ commenti - + Attending: Attendi: - + Reply Risposta - + DM Messaggio diretto - + Repost Condividi - + Success! Ha funzionato! - + Conversation Conversazione - + Attending Attendi - + yes si - + maybe potrebbe - + no no - + Delete Cancella - - - Post - - PermissionDialog @@ -472,28 +531,28 @@ PhotoTab - + 's images Immagini - + All Images - + Only new - - + + Own Images Mie immagini - + More Ancora @@ -501,324 +560,406 @@ ProfileComponent - + profile name - + is default - + hide friends - + profile photo - + profile thumb - + publish - + publish in network - + description - + date of birth - + address - + city - + region - + postal code - + country - + hometown - + gender - + marital status - + married with - + married since - + sexual - + politics - + religion - + public keywords - + private keywords - + likes - + dislikes - + about - + music - + book - + tv - + film - + interest - + romance - + work - + education - + social networks - + homepage - + Update - + profile id - + Description - Descrizione + Descrizione - + Location - Località + Località - + Posts - Messaggi + Messaggi - + URL - URL + URL - + Created at - Creato il + Creato il SmileyDialog - + Unicode Unicode - + Standard Standard - + Addon Addon - + Adult XXX + + SyncComponent + + + sync + + + + + notify + + + + + SyncConfig + + + Sync Interval (0=None) + Intervallo (0=nessuno) + + + + Min. + Min. + + + + friendiqa + + + Refresh + + + + + Timeline + Cronologia + + + + Conversations + Conversazioni + + + + Favorites + Favoriti + + + + Replies + + + + + Public Timeline + + + + + Group news + Gruppi + + + + Search + Cerca + + + + Settings + Configurazione + + + + Accounts + + + + + Quit + + + newsworker - + likes this. mi piace. - + like this. mi piace. - + doesn't like this. non mi piace. - + don't like this. non mi piace. - + will attend. attendere. - + persons will attend. Persone che attendono. - + will not attend. non aspettare. - + persons will not attend. Persone che non aspettano. - + may attend. puoi attendere. - + persons may attend. Persone che possono attendere. - + yes si - + no no - + maybe potrebbe - + seconds secondi - - @@ -827,51 +968,53 @@ + + ago fa - + minute minuti - + minutes minuti - + hour ora - + hours ore - + day giorno - + days giorni - + month mese - + months mesi - + years anni @@ -883,12 +1026,12 @@ Errore - + Undefined Array Error - + JSON status Error