diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..71842bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +CMakeLists.txt.user* +friendiqa.pro.user* +IJPSvd.json diff --git a/BackgroundSync.patch b/BackgroundSync.patch new file mode 100644 index 0000000..263f528 --- /dev/null +++ b/BackgroundSync.patch @@ -0,0 +1,11 @@ +--- src/common/alarmlinux.cpp ++++ src/common/alarmlinux.cpp +@@ -67,7 +67,7 @@ + stream << "Description=Run friendiqa background sync" << Qt::endl << Qt::endl; + stream << "[Service]" << Qt::endl; + stream << "Type=oneshot" << Qt::endl; +- stream << "ExecStart=/usr/bin/friendiqa -service" << Qt::endl; ++ stream << "ExecStart=flatpak run de.manic.friendiqa -service" << Qt::endl; + } + + QString nameTimer ="friendiqa-sync.timer"; diff --git a/CHANGELOG.md b/CHANGELOG.md index ab26aef..81cab7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,64 @@ +## v0.6.9 + +* Separate window for new messages with more formatting options +* Replaced all Fontawesome icons with system icons +* Switch between OAuth2 and Basic Auth +* Background sync with systemd-timer and removal of system tray + +## v0.6.8 + +* OAuth2 as signup method +* New translation: Dutch + +## v0.6.7 + +* Upload multiple images for post and add image descriptions +* Block user +* Report user +* Create Calendar entry from post text + +## v0.6.6 + +* Create event +* Delete event +* New sorting of conversations + +## v0.6.5 + +* Fix reply in Friendica 3/2022 version due to API bug +* Image downloads work again +* Some additional emojis + +## v0.6.4 + +* Search for new contacts (hashtags, names) +* Filter contacts +* many new emojis +* Replaced Favorite button with Reply button due to buggy Favourite API +* Rebuild contacts handling due to buggy Contacts API +* Removed permissions for new messages due to buggy Contacts API +* Sync all accounts in background (not only active) + +## v0.6.3 + +* Dark theme +* Account Page: list of largest servers for server field +* Settings page: Tabs for different settings +* Conversation opens on short click on news item +* Linux: Option to Autostart on System start + +## v0.6.2 + +* Follow and Unfollow contacts (Friendica 2021.07 required) +* Linux: App stays in systemtray after close, syncs in background +* bugfix for bulk image upload and download of public images +* bugfix for conversations in timeline + ## v0.6.1 + * Add requestLegacyExternalStorage in AndroidManifest for attachment permissions * Refresh timeline on start for Linux -* DropArea bugfix for Flatpak +* DropArea bugfix for Flatpak ## v0.6 diff --git a/FlatpakAutostart.patch b/FlatpakAutostart.patch new file mode 100644 index 0000000..0905eb1 --- /dev/null +++ b/FlatpakAutostart.patch @@ -0,0 +1,12 @@ +--- source-linux/common/filesystem.cpp ++++ source-linux/common/filesystem.cpp +@@ -165,7 +165,7 @@ + QTextStream stream(&file); + stream << "[Desktop Entry]" << Qt::endl; + stream << "Name=Friendiqa" << Qt::endl; +- stream << "Exec=friendiqa -background %u" << Qt::endl; ++ stream << "Exec=flatpak run de.manic.friendiqa -background %u" << Qt::endl; + stream << "Terminal=false" << Qt::endl; + stream << "Icon=Friendiqa.svg" << Qt::endl; + stream << "Type=Application" << Qt::endl; + diff --git a/LinuxWebview.patch b/LinuxWebview.patch deleted file mode 100644 index 0fb4a2d..0000000 --- a/LinuxWebview.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- source-linux/CMakeLists.txt 2021-05-12 21:27:38.172988268 +0200 -+++ source-linux/CMakeLists.txt 2021-06-22 21:57:17.487089044 +0200 -@@ -13,7 +13,7 @@ - set(CMAKE_INCLUDE_CURRENT_DIR ON) - endif() - --find_package(Qt5 COMPONENTS Widgets Quick Sql DBus WebView REQUIRED) -+find_package(Qt5 COMPONENTS Widgets Quick Sql DBus REQUIRED) - - set(MOC_SOURCES common/uploadableimage.h - common/xhr.h -@@ -38,7 +38,6 @@ - target_link_libraries(friendiqa Qt::Widgets) - target_link_libraries(friendiqa Qt::Quick) - target_link_libraries(friendiqa Qt::Sql) --target_link_libraries(friendiqa Qt::WebView) - target_link_libraries(friendiqa Qt::DBus) - # target_link_libraries(friendiqa Qt::Webengine) - ---- source-linux/js/newsworker.js 2021-06-22 21:40:46.938247380 +0200 -+++ source-linux/js/newsworker.js 2021-06-22 22:00:10.789922846 +0200 -@@ -107,17 +107,7 @@ - if ((videoAttachmentList.length==0) || (videoAttachmentList[videoAttachmentList.length-1].url!=ptvideohelper.url)){videoAttachmentList.push(ptvideohelper)} - } - } -- if (newsitemobject.text.indexOf("youtube.com/watch?v")>-1){ -- var yttext=newsitemobject.text; -- while (yttext.indexOf("youtube.com/watch?v")>-1){ -- var ythelperstringposition=yttext.indexOf("watch?v="); -- var ytposend=findend(yttext,ythelperstringposition); -- var ythelper={mimetype:"video/youtube"} -- ythelper.url=yttext.substring(ythelperstringposition+8,ytposend); -- yttext=yttext.substring(ytposend,yttext.length); -- if ((videoAttachmentList.length==0) || (videoAttachmentList[videoAttachmentList.length-1].url!=ythelper.url)){videoAttachmentList.push(ythelper)} -- } -- } -+ - newsitemobject.videoAttachmentList=videoAttachmentList; - newsitemobject.imageAttachmentList=imageAttachmentList; - if ((msg.options.hasOwnProperty("hide_nsfw"))&&(msg.options.hide_nsfw==1)&&(newsitemobject.text.indexOf("#nsfw")>-1)){ diff --git a/PrivacyPolicy.md b/PrivacyPolicy.md index c15eb20..716bb9e 100644 --- a/PrivacyPolicy.md +++ b/PrivacyPolicy.md @@ -5,5 +5,4 @@ You have probably selected Friendica as your preferred social network because yo Storing some pieces of user data on the device is necessary for some app features, other apps on your device may not access this data (keeping app’s own database storage protected from other apps is guaranteed by Android). The app has been programmed so that stored information contain any personal data (only login data and id number of last seen post will be transferred to servers). Photos from the albums and contact images are stored in a public directory on the device. Other apps may access these files and the Friendiqa needs access to this directory. To send images from the Android gallery the app needs access to picture databases on the device. -This app don’t collect any usage statistics. In addition, no information is sent from your Smartphone to me as a developer or to a website associated with me. -On first start, the website https://dir.friendica.social/servers/surprise is contacted and the selected server shown in the app. +This app doesn’t collect any usage statistics. In addition, no information is sent from your smartphone to me as a developer or to a website associated with me. diff --git a/README.md b/README.md index 9ce7ddc..e80c04c 100644 --- a/README.md +++ b/README.md @@ -1,125 +1,134 @@ -## Friendiqa ## - -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, 5.1 for background sync). - Source code is a QtCreator project. - -## Screenshots ## - -![Newstab](Screenshots/NewsTab.jpg) -![Friendstab](Screenshots/FriendsTab.jpg) -![Photostab](Screenshots/PhotoTab.jpg) -![Eventstab](Screenshots/EventsTab.jpg) -![Configtab](Screenshots/ConfigTab.jpg) - - -## Features ## - -# News # -Currently supported: -* 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 user for friends timeline, replies and DMs (Android 5.1 required) -* Android notifications or Dbus notification (Linux) for new items in friends timeline, replies and DMs -* Search for news -* Click on hashtag in newsitem starts search for news with that word -* Only first photo attachment in post is shown, click for more images and fullscreen image -* Click on video or youtube video shows video fullscreen -* For news containing urls ending with mp3, mp4, avi, webm, ogg or to a Peertube instance: media can be played in the app -* Open links in external browser -* Click on contact photo for contact details and last news -* Click on like text for additional contact info -* Deletion, Reposting, Answering of Posts -* Expand truncated news items -* Liking, disliking, favoriting -* Attending for event posts -* Update fetches new posts (up to last 50) since last in local DB -* More shows older posts from local DB -* Create new Message with images or direct messages, Contact/Group access rights (can be stored), smileys -* Send image from Android gallery -* Send text or urls from other apps to Friendiqa -* Native Android image dialog - -ToDo: -* 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 -* Show follow requests; approve, deny, ignore requests -* Additional information, last messages and other functionality shown in news tab -* 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) -* Groups: create, change, delete - (needs API change) - - -# Images # -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 -* Show albums in grid, show images in album in grid and fullscreen -* Show public albums and images of contacts -* Pinch to zoom, swipe to scroll - -ToDo: -* Upload private images - - -# Events # -Currently supported: -* Show own events -* Show public events of Friendica contacts -* List view of events of selected date -* Click on event to show details - -ToDo -* Create events (needs API) - - -# Config/Accounts # -Currently supported: -* Multiple accounts -* View mode for news (tree or timeline) -* Maximum news (deleted after use of Quit button) -* Sync home timeline, replies, DM, Events, friend requests; Notify yes/no -* Hide #nsfw - -ToDo -* OAuth? - - -# Other # -ToDo -* Video tab -* Translation -* Blingbling - - -# Translations # -* German, Spanish, Italian, Hungarian -* To contribute translations: Have a look at linux-sources/translations/friendiqa-de.ts and open it with an editor. It's an xml file. Change values and send me the file to thomasschmidt45 at gmx.net / do pull request. - -# Install # -* F-Droid binary repository: [https://www.ma-nic.de/fdroid/repo](https://www.ma-nic.de/fdroid/repo) or for those who get the "error getting index file" from F-Droid client due to outdated crypto libraries the url without encryption: [http://www.ma-nic.de/fdroid/repo](http://www.ma-nic.de/fdroid/repo) To include repo in Fdroid: Open config --> package sources --> plus symbol --> paste url -* [Google Playstore](https://play.google.com/store/apps/details?id=org.qtproject.friendiqa) -* Arch User Repository: [https://aur.archlinux.org/packages/friendiqa/](https://aur.archlinux.org/packages/friendiqa/) - - -## License ## -Pubished under the [GPL v3](http://gplv3.fsf.org) with the exception of the Openssl library, which is published under OpenSSL License. - +## Friendiqa + +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, 5.1 for background sync). Source code is a QtCreator project. + +## Screenshots + +![Newstab](Screenshots/NewsTab.jpg) ![Friendstab](Screenshots/FriendsTab.jpg) ![Photostab](Screenshots/PhotoTab.jpg) ![Eventstab](Screenshots/EventsTab.jpg) ![Configtab](Screenshots/ConfigTab.jpg) + +## Features + +# News + +Currently supported: + +* 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 user for friends timeline, replies and DMs (Android 5.1 required) +* Android notifications or Dbus notification (Linux) for new items in friends timeline, replies and DMs +* Search for news +* Click on hashtag in newsitem starts search for news with that word +* Only first photo attachment in post is shown, click for more images and fullscreen image +* Click on video shows video fullscreen +* For news containing urls ending with mp3, mp4, avi, webm, ogg or to a Peertube instance: media can be played in the app +* Open links in external browser +* Click on contact photo for contact details and last news +* Click on like text for additional contact info +* Click on post text opens conversation +* Deletion, Reposting, Answering of Posts +* Expand truncated news items +* Liking, disliking +* Attending for event posts +* Update fetches new posts (up to last 50) since last in local DB +* More shows older posts from local DB +* Create new Message with images or direct messages, smileys in new window +* Send image(s) from Android gallery +* Send text or urls from other apps to Friendiqa +* Native Android image dialog + +ToDo: + +* Videos and other binary data as attachment (sending, not supported in API) +* 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 +* Follow/unfollow or block/unblock contacts +* Search for new contacts according to topic +* Show follow requests; approve, deny, ignore requests +* Additional information, last messages and other functionality shown in news tab +* 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 +* Clean other contacts with no news + +ToDo: + +* More information for contact from description page, possibly private information for friends (needs API change) +* Groups: create, change, delete (needs API change) + +# Images + +Currently supported: + +* Download public own images to local directory (API is currently broken) +* Upload public picture to album with descriptions, send from gallery (API is currently broken) +* Delete own pictures and albums on client and server +* Change name or album of existing picture +* Show albums in grid, show images in album in grid and fullscreen +* Show public albums and images of contacts +* Pinch to zoom, swipe to scroll + +ToDo: + +* Upload private images + +# Events + +Currently supported: + +* Show own events +* Show public events of Friendica contacts +* List view of events of selected date +* Click on event to show details +* Create event +* Delete event + +ToDo + +* Show more details and attendance of events (needs API) + +# Config/Accounts + +Currently supported: + +* Multiple accounts +* Dark Mode +* View mode for news (conversation tree or timeline) +* Maximum news (deleted after use of Quit button) +* Set default news tabs +* Sync home timeline, replies, DM, Events, friend requests; Notify yes/no +* Hide #nsfw +* OAuth2 as authorization method + +# Other + +* on Linux: syncs in background via systemd-timer + +ToDo + +* Video tab +* Translation +* Blingbling + +# Translations + +* German, Spanish, Italian, Hungarian, Dutch +* To contribute translations: + +# Install + +* F-Droid binary repository: or for those who get the "error getting index file" from F-Droid client due to outdated crypto libraries the url without encryption: To include repo in Fdroid: Open config --> package sources --> plus symbol --> paste url +* [Google Playstore](https://play.google.com/store/apps/details?id=org.qtproject.friendiqa) +* Arch User Repository: +* Flatpak: +* Flatpak for Mobile Linux: + +## License + +Pubished under the [GPL v3](http://gplv3.fsf.org) with the exception of the Openssl library, which is published under OpenSSL License. diff --git a/Screenshots/ConfigTab.jpg b/Screenshots/ConfigTab.jpg index 0754a37..ca61dc3 100644 Binary files a/Screenshots/ConfigTab.jpg and b/Screenshots/ConfigTab.jpg differ diff --git a/Screenshots/EventsTab.jpg b/Screenshots/EventsTab.jpg index 06025fd..703860f 100644 Binary files a/Screenshots/EventsTab.jpg and b/Screenshots/EventsTab.jpg differ diff --git a/Screenshots/FriendsTab.jpg b/Screenshots/FriendsTab.jpg index 5d2c9d1..83bbe17 100644 Binary files a/Screenshots/FriendsTab.jpg and b/Screenshots/FriendsTab.jpg differ diff --git a/Screenshots/NewsTab.jpg b/Screenshots/NewsTab.jpg index e8227fc..dc0817d 100644 Binary files a/Screenshots/NewsTab.jpg and b/Screenshots/NewsTab.jpg differ diff --git a/source-linux/CMakeLists.txt b/source-android/CMakeLists.txt similarity index 50% rename from source-linux/CMakeLists.txt rename to source-android/CMakeLists.txt index 5569c2d..c47a156 100644 --- a/source-linux/CMakeLists.txt +++ b/source-android/CMakeLists.txt @@ -1,3 +1,9 @@ +# TEMPLATE = app +# TARGET = friendiqa +# CONFIG += release +# QT += qml quick gui widgets sql webview dbus webengine + + cmake_minimum_required(VERSION 3.1.0) project(friendiqa VERSION 0.6 LANGUAGES CXX) @@ -15,6 +21,8 @@ endif() find_package(Qt5 COMPONENTS Widgets Quick Sql DBus WebView REQUIRED) +#Webview Webengine + set(MOC_SOURCES common/uploadableimage.h common/xhr.h common/filesystem.h @@ -28,7 +36,7 @@ set(SOURCES common/friendiqa.cpp common/filesystem.cpp common/remoteauthasyncimageprovider.cpp common/updatenews.cpp - common/alarmlinux.cpp) + common/alarmandroid.cpp) include_directories(common) @@ -45,3 +53,44 @@ target_link_libraries(friendiqa Qt::DBus) # qt5_use_modules(friendiqa Core Widgets Quick Sql DBus) install(TARGETS friendiqa DESTINATION bin) + +#RESOURCES = application.qrc + +# OTHER_FILES += qml/friendiqa.qml \ +# translations/*.ts \ +# qml/*.qml +# qml/newsqml/*.qml +# qml/contactqml/*.qml +# qml/photoqml/*.qml +# qml/configqml/*.qml +# js/*.js + +#TRANSLATIONS += translations/friendiqa-de.ts \ +# translations/friendiqa-es.ts \ +# translations/friendiqa-it.ts +# HEADERS += \ +# common/uploadableimage.h \ +# common/xhr.h \ +# common/filesystem.h \ +# common/remoteauthasyncimageprovider.h \ +# common/updatenews.h \ +# common/alarm.h + +#DISTFILES += \ +# qml/calendarqml/*.qml \ +# translations/*.ts \ +# translations/*.qm \ +# qml/*.qml \ +# qml/newsqml/*.qml \ +# qml/contactqml/*.qml \ +# qml/photoqml/*.qml \ +# qml/configqml/*.qml \ +# js/*.js \ + + +# target.path=/usr/bin +# desktop.path = /usr/share/applications +# desktop.files = images/de.ma-nic.Friendiqa.desktop +# icon.path = /usr/share/icons/hicolor/scalable/apps +# icon.files = images/Friendiqa.svg +# INSTALLS+=target desktop icon diff --git a/source-android/android/AndroidManifest.xml b/source-android/android/AndroidManifest.xml index 0508782..277b677 100644 --- a/source-android/android/AndroidManifest.xml +++ b/source-android/android/AndroidManifest.xml @@ -1,18 +1,10 @@ - - - - - - - - + + - + android:label="Friendiqa" android:screenOrientation="unspecified" android:launchMode="singleTask" android:taskAffinity="" android:exported="true"> @@ -96,7 +88,7 @@ * minimal - useful for Quick Controls 2 apps, it is much faster than "full" * none - useful for apps that don't use any of the above Qt modules --> - + @@ -138,4 +130,11 @@ + + + + + + + diff --git a/source-android/android/build.gradle b/source-android/android/build.gradle index 9f47fcd..01264a5 100644 --- a/source-android/android/build.gradle +++ b/source-android/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath "com.android.tools.build:gradle:4.1.0" } } @@ -25,7 +25,7 @@ dependencies { } dependencies { - compile 'androidx.appcompat:appcompat:1.1.0' + compile 'androidx.appcompat:appcompat:1.4.2' } android { @@ -44,8 +44,14 @@ android { compileSdkVersion androidCompileSdkVersion.toInteger() - buildToolsVersion '28.0.3' + buildToolsVersion '31.0.0' + compileSdkVersion 33 + defaultConfig { + minSdkVersion 26 + targetSdkVersion 31 + resConfigs "en" + } sourceSets { main { manifest.srcFile 'AndroidManifest.xml' @@ -67,10 +73,6 @@ android { aaptOptions { noCompress 'rcc' } - - defaultConfig { - resConfigs "en" - } } apply from: "androidnative.gradle" setAndroidNativePath("/../androidnative.pri"); diff --git a/source-android/android/gradle.properties b/source-android/android/gradle.properties index bedc041..82755ae 100644 --- a/source-android/android/gradle.properties +++ b/source-android/android/gradle.properties @@ -1,7 +1,4 @@ -# androidBuildToolsVersion=25.0.3 -# androidCompileSdkVersion=26 buildDir=.build -# qt5AndroidDir=/home/pankraz/Qt/5.11.1/android_armv7/src/android/java android.useAndroidX=true android.enableJetifier=true android.enforceUniquePackageName=false diff --git a/source-android/android/gradle/wrapper/gradle-wrapper.properties b/source-android/android/gradle/wrapper/gradle-wrapper.properties index 4b7e1f3..186b715 100644 --- a/source-android/android/gradle/wrapper/gradle-wrapper.properties +++ b/source-android/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/source-android/android/src/FriendiqaService.java b/source-android/android/src/FriendiqaService.java index 9115a03..4dc2dda 100644 --- a/source-android/android/src/FriendiqaService.java +++ b/source-android/android/src/FriendiqaService.java @@ -10,15 +10,15 @@ import org.qtproject.qt5.android.QtNative; //import androidnative.friendiqa.FriendiqaQtService; public class FriendiqaService extends JobService{ - private static String TAG = "AndroidNative"; + private static String TAG = "FriendiqaService"; //Log.e(TAG,"Service"); @Override public boolean onStartJob(JobParameters params) { - //Log.d(TAG,"Friendiqa JobService"); + Log.d(TAG,"Friendiqa JobService"); Context context = this.getApplicationContext(); - AndroidNativeService fs = new AndroidNativeService(); + AndroidNativeService fs = new AndroidNativeService(); fs.startQtService(context); jobFinished(params,false); //Intent serviceIntent = new Intent(this, AndroidNativeService.class); diff --git a/source-android/android/src/FriendiqaStopService.java b/source-android/android/src/FriendiqaStopService.java index e483d62..2851bcd 100644 --- a/source-android/android/src/FriendiqaStopService.java +++ b/source-android/android/src/FriendiqaStopService.java @@ -16,7 +16,7 @@ public class FriendiqaStopService extends JobService{ @Override public boolean onStartJob(JobParameters params) { - //Log.d(TAG,"Friendiqa JobServiceStop"); + Log.d(TAG,"Friendiqa JobServiceStop"); Context context = this.getApplicationContext(); AndroidNativeService fs = new AndroidNativeService(); fs.stopQtService(context); diff --git a/source-android/androidnative.pri/examples/androidnativeexample/Components.qml b/source-android/androidnative.pri/examples/androidnativeexample/Components.qml deleted file mode 100644 index cdd7880..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/Components.qml +++ /dev/null @@ -1,62 +0,0 @@ -import QtQuick 2.2 -import QtQuick.Window 2.1 -import QuickAndroid 0.1 -import QuickAndroid.Styles 0.1 -import "./theme" - -Page { - objectName: "ComponentPage"; - - property var pages: [ - { - name: "Image Picker", - demo: "imagePicker/ImagePickerDemo.qml", - description: "Pick photo via Java language binding" - },{ - name: "Toast", - demo: "toast/ToastDemo.qml", - description: "Toast Demonstration" - },{ - name: "Notification", - demo: "notification/NotificationDemo.qml", - description: "Demonstrate how to use SystemDispatcher to send notification" - },{ - name: "Information", - demo: "info/InfoDemo.qml", - description: "Android System Information" - },{ - name: "Status Bar", - demo: "statusbar/StatusBarDemo.qml", - description: "Config Status Bar" - } - - ]; - - actionBar: ActionBar { - id : actionBar - iconSource: A.drawable("ic_menu",Constants.black87) - title: "AndroidNative Component List" - showIcon: false - actionButtonEnabled: false - } - - VisualDataModel { - id: visualDataModel - delegate: ListItem { - title: modelData.name - subtitle: modelData.description - onClicked: { - present(Qt.resolvedUrl(modelData.demo)); - } - } - - model: pages; - } - - ListView { - anchors.fill: parent - - model : visualDataModel - } - -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/README.md b/source-android/androidnative.pri/examples/androidnativeexample/README.md deleted file mode 100644 index e3a9f38..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/README.md +++ /dev/null @@ -1,25 +0,0 @@ -AndroidNative Example Program -===================== - -Prerequisites -------------- - - * Qt Android SDK >= 5.6 - * Android SDK - -Check this article for how to setup Qt and Android SDK: - -[Getting Started with Qt for Android](http://qt-project.org/doc/qt-5/androidgs.html) - -Build Instruction ------------------ - - 1. Run `qpm install` to get required packages - 1. Open androidnativeexample.pro by Qt Creator - 1. Press the "Projects" tab. Make sure the "Android for xxx" kit has been selected - 1. Plug a Android device to your computer - 1. Press "Build" -> "Run" - 1. The program will be deployed to your device. It is so easy! - -![Screenshot](https://raw.githubusercontent.com/benlau/androidnative.pri/master/docs/screenshots/example1.png) - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/AndroidManifest.xml b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/AndroidManifest.xml deleted file mode 100644 index 5ecf270..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/AndroidManifest.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/androidnative.gradle b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/androidnative.gradle deleted file mode 100644 index 8fe9786..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/androidnative.gradle +++ /dev/null @@ -1,34 +0,0 @@ - -// Obtain androidPackageSourceDir -// androidPackageSourceDir is the absolute path of the folder containing build.gradle and AndroidManifests.xml -// This code also works with androiddeployqt. - -import groovy.json.JsonSlurper - -String getAndroidPackageSourceDir() { - String res = System.getProperty("user.dir"); - - FileTree tree = fileTree(dir: res + "/..").include("android*deployment-settings.json"); - - if (tree.getFiles().size() > 0) { - def inputFile = tree.getFiles().toArray()[0]; - def InputJSON = new JsonSlurper().parseText(inputFile.text); - res = InputJSON["android-package-source-directory"] - } else { - println("android*deployment-settings.json not found. Set androidPackageSourceDir to user.dir"); - } - - return res; -} - -String setAndroidNativePath(String path) { - String androidPackageSourceDir = getAndroidPackageSourceDir(); - String androidNativePath = androidPackageSourceDir + path + "/java/src"; - LinkedHashSet hash = android.sourceSets.main.java.srcDirs; - hash.add(androidNativePath); - android.sourceSets.main.java.srcDirs = hash; -} - -ext { - setAndroidNativePath = this.&setAndroidNativePath; -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/build.gradle b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/build.gradle deleted file mode 100644 index 4ce7902..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/build.gradle +++ /dev/null @@ -1,60 +0,0 @@ - -buildscript { - repositories { - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:1.3.0' - } -} - -allprojects { - repositories { - jcenter() - } -} - -apply plugin: 'com.android.application' - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) -} - -android { - /******************************************************* - * The following variables: - * - androidBuildToolsVersion, - * - androidCompileSdkVersion - * - qt5AndroidDir - holds the path to qt android files - * needed to build any Qt application - * on Android. - * - * are defined in gradle.properties file. This file is - * updated by QtCreator and androiddeployqt tools. - * Changing them manually might break the compilation! - *******************************************************/ - - compileSdkVersion androidCompileSdkVersion.toInteger() - - buildToolsVersion androidBuildToolsVersion - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] - aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] - res.srcDirs = [qt5AndroidDir + '/res', 'res'] - resources.srcDirs = ['src'] - renderscript.srcDirs = ['src'] - assets.srcDirs = ['assets'] - jniLibs.srcDirs = ['libs'] - } - } - lintOptions { - abortOnError false - } -} - -apply from: "androidnative.gradle" -setAndroidNativePath("/../../.."); diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle.properties b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle.properties deleted file mode 100644 index 798b77d..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle.properties +++ /dev/null @@ -1,9 +0,0 @@ -## This file is automatically generated by QtCreator. -# -# This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. - -androidBuildToolsVersion=25.0.3 -androidCompileSdkVersion=25 -buildDir=.build -qt5AndroidDir=/home/pankraz/Qt/5.9.1/android_armv7/src/android/java diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle/wrapper/gradle-wrapper.jar b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 13372ae..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle/wrapper/gradle-wrapper.properties b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 9f2bca4..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Thu Feb 16 01:04:18 HKT 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradlew b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradlew deleted file mode 100644 index 9d82f78..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradlew.bat b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradlew.bat deleted file mode 100644 index aec9973..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/local.properties b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/local.properties deleted file mode 100644 index 4277a61..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/local.properties +++ /dev/null @@ -1,6 +0,0 @@ -## This file is automatically generated by QtCreator. -# -# This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. - -sdk.dir=/home/pankraz/android-sdk_alt diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/drawable/icon.png b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/drawable/icon.png deleted file mode 100644 index 156243d..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/drawable/icon.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/drawable/splash.xml b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/drawable/splash.xml deleted file mode 100644 index c1bd6fc..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/drawable/splash.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/values/apptheme.xml b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/values/apptheme.xml deleted file mode 100644 index 455b965..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/values/apptheme.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/values/libs.xml b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/values/libs.xml deleted file mode 100644 index 4d68673..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/res/values/libs.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - https://download.qt-project.org/ministro/android/qt5/qt-5.4 - - - - - - - - - - - - - - - - - - - - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/src/ExampleActivity.java b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/src/ExampleActivity.java deleted file mode 100644 index ffa8952..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/src/ExampleActivity.java +++ /dev/null @@ -1,16 +0,0 @@ -package androidnative.example; - -import androidnative.AndroidNativeActivity; - -/** - * Created by benlau on 8/3/2017. - */ - -public class ExampleActivity extends AndroidNativeActivity { - public ExampleActivity() { - super(); - - QT_ANDROID_THEMES = new String[] {""}; - QT_ANDROID_DEFAULT_THEME = ""; - } -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/src/ExampleService.java b/source-android/androidnative.pri/examples/androidnativeexample/android-sources/src/ExampleService.java deleted file mode 100644 index 082ff10..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/android-sources/src/ExampleService.java +++ /dev/null @@ -1,96 +0,0 @@ -package androidnative.example; -import androidnative.SystemDispatcher; -import android.app.Notification; -import android.app.NotificationManager; -import android.util.Log; -import android.os.Handler; -import android.app.Activity; -import android.view.View; -import android.content.Context; -import java.util.Map; -import org.qtproject.qt5.android.QtNative; - -public class ExampleService { - - static { - - SystemDispatcher.addListener(new SystemDispatcher.Listener() { - - NotificationManager m_notificationManager; - Notification.Builder m_builder; - - private void notificationManagerNotify(Map data) { - - final Activity activity = QtNative.activity(); - final Map messageData = data; - - Runnable runnable = new Runnable () { - public void run() { - try { - String title = (String) messageData.get("title"); - - String message = (String) messageData.get("message"); - - if (m_notificationManager == null) { - m_notificationManager = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE); - m_builder = new Notification.Builder(activity); - - // Small Icon is a must to make notification works. - // And that is why you need to inherit QtActivity - m_builder.setSmallIcon(R.drawable.icon); - } - - m_builder.setContentTitle(title); - m_builder.setContentText(message); - m_notificationManager.notify(1, m_builder.build()); - - // Test function. Remove it later. - SystemDispatcher.dispatch("Notifier.notifyFinished"); - } catch (Exception e) { - Log.d("",e.getMessage()); - } - - }; - }; - activity.runOnUiThread(runnable); - } - - private void hapticFeedbackPerform(Map data) { - - final Activity activity = QtNative.activity(); - final Map messageData = data; - Runnable runnable = new Runnable () { - public void run() { - int feedbackConstant = (Integer) messageData.get("feedbackConstant"); - int flags = (Integer) messageData.get("flags"); - - Log.d("",String.format("hapticFeedbackPerform(%d,%d)",feedbackConstant,flags)); - - View rootView = activity.getWindow().getDecorView().getRootView(); - rootView.performHapticFeedback(feedbackConstant, flags); - - // Test function. Remove it later. - SystemDispatcher.dispatch("hapticFeedbackPerformFinished"); - }; - }; - activity.runOnUiThread(runnable); - } - - public void onDispatched(String name , Map data) { - - if (name.equals("Notifier.notify")) { - notificationManagerNotify(data); - return; - } else if (name.equals("hapticFeedbackPerform")) { - hapticFeedbackPerform(data); - return; - } - - return; - } - }); - - } - -} - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/androidnativeexample.pro b/source-android/androidnative.pri/examples/androidnativeexample/androidnativeexample.pro deleted file mode 100644 index cec26e5..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/androidnativeexample.pro +++ /dev/null @@ -1,38 +0,0 @@ -TEMPLATE = app - -QT += qml quick - -SOURCES += main.cpp \ - debugwrapper.cpp - -RESOURCES += qml.qrc - -# Additional import path used to resolve QML modules in Qt Creator's code model -QML_IMPORT_PATH += ../.. - -android { - ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources -} - -# include(vendor/vendor.pri) -# Default rules for deployment. -include(deployment.pri) -include(../../androidnative.pri) -include(../../../../../../quickandroid/quickandroid.pri) - -DISTFILES += \ - android-sources/AndroidManifest.xml \ - android-sources/src/quickandroid/example/ExampleService.java \ - README.md \ - android-sources/gradle/wrapper/gradle-wrapper.jar \ - android-sources/gradlew \ - android-sources/res/values/libs.xml \ - android-sources/build.gradle \ - android-sources/gradle/wrapper/gradle-wrapper.properties \ - android-sources/gradlew.bat \ - android-sources/settings.gradle \ - android-sources/src/androidnative/example/ExampleService.java - -HEADERS += \ - ../../README.md \ - debugwrapper.h diff --git a/source-android/androidnative.pri/examples/androidnativeexample/androidnativeexample.pro.user b/source-android/androidnative.pri/examples/androidnativeexample/androidnativeexample.pro.user deleted file mode 100644 index 1693b53..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/androidnativeexample.pro.user +++ /dev/null @@ -1,392 +0,0 @@ - - - - - - EnvironmentId - {8825bc46-5cad-4a59-be78-bf9eeaa7217a} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - true - false - 0 - true - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - - ProjectExplorer.Project.Target.0 - - Android - Android - {8e3757e7-5698-4d0f-9f13-55359b1a832e} - 0 - 0 - 0 - - /home/pankraz/build/debug - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - false - false - - - true - Make - - Qt4ProjectManager.MakeStep - - -w - -r - - false - - - - - true - Anwendungsdaten kopieren - - Qt4ProjectManager.AndroidPackageInstallationStep - - - android-25 - - true - Android-APK erstellen - - QmakeProjectManager.AndroidBuildApkStep - 2 - true - false - - 4 - Build - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - -w - -r - - true - clean - - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - - Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - - /home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/source-android/androidnative.pri/examples/build-androidnativeexample-Android-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - - false - false - false - - - true - Make - - Qt4ProjectManager.MakeStep - - -w - -r - - false - - - - - true - Anwendungsdaten kopieren - - Qt4ProjectManager.AndroidPackageInstallationStep - - - android-25 - - true - Android-APK erstellen - - QmakeProjectManager.AndroidBuildApkStep - 2 - true - false - - 4 - Build - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - -w - -r - - true - clean - - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - - /home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/source-android/androidnative.pri/examples/build-androidnativeexample-Android-Profile - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - true - false - - - true - Make - - Qt4ProjectManager.MakeStep - - -w - -r - - false - - - - - true - Anwendungsdaten kopieren - - Qt4ProjectManager.AndroidPackageInstallationStep - - - android-25 - - true - Android-APK erstellen - - QmakeProjectManager.AndroidBuildApkStep - 2 - true - false - - 4 - Build - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - -w - -r - - true - clean - - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Profile - - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - 3 - - - - true - Deployment auf Android-Gerät - - Qt4ProjectManager.AndroidDeployQtStep - false - - 1 - Deployment - - ProjectExplorer.BuildSteps.Deploy - - 1 - Deployment auf Android-Gerät - Deployment auf Android-Gerät - Qt4ProjectManager.AndroidDeployConfiguration2 - - 1 - - CB5A22HSB9 - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - - - - androidnativeexample - - Qt4ProjectManager.AndroidRunConfiguration:/home/pankraz/ownCloud/clientsync/Friendiqa/v0.005/source-android/androidnative.pri/examples/androidnativeexample/androidnativeexample.pro - androidnativeexample.pro - 3768 - false - true - false - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.FileVersion - 18 - - - Version - 18 - - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/debugwrapper.cpp b/source-android/androidnative.pri/examples/androidnativeexample/debugwrapper.cpp deleted file mode 100644 index 8aaf024..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/debugwrapper.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "debugwrapper.h" -#include "AndroidNative/debug.h" - -DebugWrapper::DebugWrapper(QObject *parent) : QObject(parent) -{ - -} - -long DebugWrapper::getNativeHeapSize() const -{ - return AndroidNative::Debug::getNativeHeapSize(); -} - -long DebugWrapper::getNativeHeapAllocatedSize() const -{ - return AndroidNative::Debug::getNativeHeapAllocatedSize(); -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/debugwrapper.h b/source-android/androidnative.pri/examples/androidnativeexample/debugwrapper.h deleted file mode 100644 index 80c3424..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/debugwrapper.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef DEBUGWRAPPER_H -#define DEBUGWRAPPER_H - -#include - -class DebugWrapper : public QObject -{ - Q_OBJECT -public: - explicit DebugWrapper(QObject *parent = 0); - -signals: - -public slots: - long getNativeHeapSize() const; - - long getNativeHeapAllocatedSize() const; -}; - -#endif // DEBUGWRAPPER_H diff --git a/source-android/androidnative.pri/examples/androidnativeexample/deployment.pri b/source-android/androidnative.pri/examples/androidnativeexample/deployment.pri deleted file mode 100644 index 5441b63..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/deployment.pri +++ /dev/null @@ -1,27 +0,0 @@ -android-no-sdk { - target.path = /data/user/qt - export(target.path) - INSTALLS += target -} else:android { - x86 { - target.path = /libs/x86 - } else: armeabi-v7a { - target.path = /libs/armeabi-v7a - } else { - target.path = /libs/armeabi - } - export(target.path) - INSTALLS += target -} else:unix { - isEmpty(target.path) { - qnx { - target.path = /tmp/$${TARGET}/bin - } else { - target.path = /opt/$${TARGET}/bin - } - export(target.path) - } - INSTALLS += target -} - -export(INSTALLS) diff --git a/source-android/androidnative.pri/examples/androidnativeexample/dialog/DialogDemo.qml b/source-android/androidnative.pri/examples/androidnativeexample/dialog/DialogDemo.qml deleted file mode 100644 index 8ee22be..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/dialog/DialogDemo.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQuick 2.0 -import QuickAndroid 0.1 -import QuickAndroid.Styles 0.1 -import "../theme" - -Page { - actionBar: ActionBar { - id: actionBar - upEnabled: true - title: qsTr("Dialog Demo") - showTitle: true - - onActionButtonClicked: back(); - z: 10 - - } - - Button { - id: label - text : "Press to launch dialog" - anchors.centerIn: parent - onClicked: { - dialog.open(); - } - } - - Dialog { - id: dialog - anchors.centerIn: parent - title: "Dialog" - Text { - text: "Demo" - } - z: 20 - - acceptButtonText: "OK" - } -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/imagePicker/ImagePickerDemo.qml b/source-android/androidnative.pri/examples/androidnativeexample/imagePicker/ImagePickerDemo.qml deleted file mode 100644 index e38c7a3..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/imagePicker/ImagePickerDemo.qml +++ /dev/null @@ -1,77 +0,0 @@ -import QtQuick 2.0 -import QuickAndroid 0.1 -import AndroidNative 1.0 as AN -import "../theme" - -Page { - id: demo - actionBar: ActionBar { - title: "Image Picker Demo" - onActionButtonClicked: back(); - } - - AN.ImagePicker { - id: imagePicker; - multiple : true - } - - Rectangle { - anchors.fill: parent - color: Constants.black100 - - Image { - id: image - anchors.fill: parent - source: imagePicker.imageUrl - fillMode: Image.PreserveAspectFit - visible: imagePicker.imageUrls.length <= 1 - } - - Grid { - columns: 3 - spacing: 0 - visible: !image.visible - - Repeater { - model: imagePicker.imageUrls - delegate: Image { - width: demo.width / 3 - height: width / 4 * 3 - source: modelData - asynchronous: true - fillMode: Image.PreserveAspectCrop - } - } - } - - Column { - anchors.right: parent.right - anchors.rightMargin: 16 * A.dp - anchors.bottom: parent.bottom - anchors.bottomMargin: 32 * A.dp - - spacing: 16 * A.dp - - FloatingActionButton { - iconSource: A.drawable("ic_camera",Constants.black87); - size: Constants.small - backgroundColor: Constants.white100 - onClicked: { - imagePicker.takePhoto(); - } - } - - FloatingActionButton { - iconSource: A.drawable("ic_image",Constants.black87); - size: Constants.small - backgroundColor: Constants.white100 - onClicked: { - imagePicker.pickImage(); - } - } - - } - - } -} - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/info/InfoDemo.qml b/source-android/androidnative.pri/examples/androidnativeexample/info/InfoDemo.qml deleted file mode 100644 index d86a319..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/info/InfoDemo.qml +++ /dev/null @@ -1,55 +0,0 @@ -import QtQuick 2.0 -import QuickAndroid 0.1 -import QuickAndroid.Styles 0.1 -import "../theme" - -Page { - id: page - actionBar: ActionBar { - id: actionBar - upEnabled: true - title: qsTr("Information") - showTitle: true - - onActionButtonClicked: back(); - z: 10 - } - - VisualItemModel { - id: itemModel - - ListItem { - title: "Environment.DIRECTORY_DCIM" - subtitle: Environment.DIRECTORY_DCIM - interactive: false - width: page.width - } - - ListItem { - title: "Debug.getNativeHeapSize" - subtitle: (Debug.getNativeHeapSize() / 1024 / 1024).toFixed(2) + "MB"; - interactive: false - width: page.width - } - - ListItem { - title: "Debug.getNativeHeapAllocatedSize" - subtitle: (Debug.getNativeHeapAllocatedSize() / 1024 / 1024).toFixed(2) + "MB"; - interactive: false - width: page.width - } - - ListItem { - title: "QThread.idealThreadCount" - subtitle: Misc.idealThreadCount; - interactive: false - width: page.width - } - } - - - ListView { - anchors.fill: parent - model: itemModel - } -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/main.cpp b/source-android/androidnative.pri/examples/androidnativeexample/main.cpp deleted file mode 100644 index 062572b..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/main.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include -#include -#include -#include -//#include "qadrawableprovider.h" -#include "AndroidNative/systemdispatcher.h" -#include "AndroidNative/environment.h" -#include "AndroidNative/debug.h" -#include "AndroidNative/mediascannerconnection.h" -#include "debugwrapper.h" - -using namespace AndroidNative; - -#ifdef Q_OS_ANDROID -#include -#include - -JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { - Q_UNUSED(vm); - qDebug("NativeInterface::JNI_OnLoad()"); - - // It must call this function within JNI_OnLoad to enable System Dispatcher - SystemDispatcher::registerNatives(); - return JNI_VERSION_1_6; -} -#endif - -int main(int argc, char *argv[]) -{ -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif - - QGuiApplication app(argc, argv); - app.setApplicationName("Android Native Example"); - app.setOrganizationDomain("com.github.benlau.androidnative"); - - QSettings settings; - - settings.setValue("firstTimeLoading", false); - settings.sync(); - - QVariantMap env; - env["DIRECTORY_DCIM"] = Environment::getExternalStoragePublicDirectory(Environment::DIRECTORY_DCIM); - - QVariantMap misc; - misc["idealThreadCount"] = QThread::idealThreadCount(); - - MediaScannerConnection::scanFile(""); - - SystemDispatcher::instance()->loadClass("androidnative.example.ExampleService"); - - QQmlApplicationEngine engine; - - /* QuickAndroid Initialization */ - engine.addImportPath("qrc:///"); // Add QuickAndroid into the import path - engine.rootContext()->setContextProperty("Environment", env); - engine.rootContext()->setContextProperty("Misc", misc); - engine.rootContext()->setContextProperty("Debug", new DebugWrapper(&engine)); - - /* End of QuickAndroid Initialization */ - - // Extra features: - //QADrawableProvider* provider = new QADrawableProvider(); - //provider->setBasePath("qrc://res"); - //engine.addImageProvider("drawable",provider); - engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); - - return app.exec(); -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/main.qml b/source-android/androidnative.pri/examples/androidnativeexample/main.qml deleted file mode 100644 index 9a08956..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/main.qml +++ /dev/null @@ -1,76 +0,0 @@ -import QtQuick 2.2 -import QtQuick.Window 2.2 -import QuickAndroid 0.1 -import QuickAndroid.Styles 0.1 -import "./theme" - -Window { - id: window; - width: 480 - height: 640 - - color: "#FFFFFF" - - visible: false; - - /* Fast Splash Screen Setup Instruction - - 1. Create a custom theme (apptheme.qml) and set windowBackground to @drawable/splash.xml (Your splash screen drawable) - - 2. Within AndroidManifest.xml, set android.app.splash_screen_drawable to @drawable/splash.xml - - - - - - That will show a splash screen while Qt is loading. However, screen flicker will happen when your Window - item is shown. To prevent screen flicker completely, you could setup your main.qml accoroding to step 3. - - 3. In your main.qml (the one with Window component) - - 3.1. Set Window.color to a color which is similar to splash screen / Theme.windowBackground - - 3.2. Set visible of Window to false until your content is loaded. (Keep Android splash screen while loading) - - 3.3. Use an asynchronous Loader for your content. Set opacity to 0. - - 3.4. Once everything is ready, set Window.visible to true and perform a fade-in animation on Loader - - */ - - Loader { - id: loader - parent: null - width: window.width - height: window.height - asynchronous: true - opacity: 0 - focus: true; - - sourceComponent: PageStack { - id: stack - objectName: "PageStack"; - initialPage: Components { - - onPresented: { - window.visible = true; - A.setTimeout(function() { - loader.parent = window.contentItem; - loader.opacity = 1; - }, 34); - } - } - } - - Behavior on opacity { - NumberAnimation { - duration: 200 - easing.type: Easing.OutQuad; - } - } - } - - Component.onCompleted: { - ThemeManager.currentTheme = AppTheme - } -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/notification/NotificationDemo.qml b/source-android/androidnative.pri/examples/androidnativeexample/notification/NotificationDemo.qml deleted file mode 100644 index 174a5a0..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/notification/NotificationDemo.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.2 -import QtQuick.Window 2.1 -import QuickAndroid 0.1 -import QuickAndroid.Styles 0.1 -import AndroidNative 1.0 as AN -import "../theme" - -Page { - - actionBar: ActionBar { - id : actionBar - title: "Notification" - z: 10 - upEnabled: true - onActionButtonClicked: back(); - } - - Button { - id: label - text : "Press to send notification" - anchors.centerIn: parent - onClicked: { - AN.SystemDispatcher.dispatch("Notifier.notify",{ - title: "Quick Android Example", - message: "Hello!" - }); - } - } - -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/qml.qrc b/source-android/androidnative.pri/examples/androidnativeexample/qml.qrc deleted file mode 100644 index 225e836..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/qml.qrc +++ /dev/null @@ -1,31 +0,0 @@ - - - main.qml - res/drawable-hdpi/icon.png - Components.qml - res/drawable-xxhdpi/ic_menu.png - dialog/DialogDemo.qml - notification/NotificationDemo.qml - theme/AppTheme.qml - theme/qmldir - res/drawable-hdpi/ic_android_black_48dp.png - res/drawable-xxhdpi/ic_android_black_48dp.png - res/drawable-mdpi/ic_android_black_48dp.png - res/drawable-xhdpi/ic_android_black_48dp.png - res/drawable-xxxhdpi/ic_android_black_48dp.png - res/drawable-hdpi/ic_done_black_24dp.png - res/drawable-mdpi/ic_done_black_24dp.png - res/drawable-xhdpi/ic_done_black_24dp.png - res/drawable-xxhdpi/ic_done_black_24dp.png - res/drawable-xxxhdpi/ic_done_black_24dp.png - theme/ActionBarBackground.qml - res/drawable-xxhdpi/ic_keyboard_backspace.png - res/drawable-xxhdpi/ic_arrow_back.png - res/drawable-xxhdpi/ic_image.png - res/drawable-xxhdpi/ic_camera.png - imagePicker/ImagePickerDemo.qml - info/InfoDemo.qml - toast/ToastDemo.qml - statusbar/StatusBarDemo.qml - - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/qpm.json b/source-android/androidnative.pri/examples/androidnativeexample/qpm.json deleted file mode 100644 index 9ff04fd..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/qpm.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "", - "description": "", - "dependencies": [ - "com.github.benlau.quickandroid@0.1.7" - ], - "license": "NONE", - "pri_filename": "", - "webpage": "" -} \ No newline at end of file diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/ic_android_black_48dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/ic_android_black_48dp.png deleted file mode 100644 index 6006b12..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/ic_android_black_48dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/ic_done_black_24dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/ic_done_black_24dp.png deleted file mode 100644 index d4c0607..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/ic_done_black_24dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/icon.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/icon.png deleted file mode 100644 index 156243d..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-hdpi/icon.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-mdpi/ic_android_black_48dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-mdpi/ic_android_black_48dp.png deleted file mode 100644 index 41558f2..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-mdpi/ic_android_black_48dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-mdpi/ic_done_black_24dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-mdpi/ic_done_black_24dp.png deleted file mode 100644 index 5e5e7cf..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-mdpi/ic_done_black_24dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xhdpi/ic_android_black_48dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xhdpi/ic_android_black_48dp.png deleted file mode 100644 index 4f935bf..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xhdpi/ic_android_black_48dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xhdpi/ic_done_black_24dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xhdpi/ic_done_black_24dp.png deleted file mode 100644 index 64a4944..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xhdpi/ic_done_black_24dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_android_black_48dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_android_black_48dp.png deleted file mode 100644 index 149b4ec..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_android_black_48dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_arrow_back.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_arrow_back.png deleted file mode 100644 index 1e88d35..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_arrow_back.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_camera.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_camera.png deleted file mode 100644 index 91f103d..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_camera.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_done_black_24dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_done_black_24dp.png deleted file mode 100644 index c9c0174..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_done_black_24dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_image.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_image.png deleted file mode 100644 index b32faff..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_image.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_keyboard_backspace.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_keyboard_backspace.png deleted file mode 100644 index a49c20c..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_keyboard_backspace.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_menu.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_menu.png deleted file mode 100644 index ab83be5..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxhdpi/ic_menu.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxxhdpi/ic_android_black_48dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxxhdpi/ic_android_black_48dp.png deleted file mode 100644 index ded531f..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxxhdpi/ic_android_black_48dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxxhdpi/ic_done_black_24dp.png b/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxxhdpi/ic_done_black_24dp.png deleted file mode 100644 index 2f6d638..0000000 Binary files a/source-android/androidnative.pri/examples/androidnativeexample/res/drawable-xxxhdpi/ic_done_black_24dp.png and /dev/null differ diff --git a/source-android/androidnative.pri/examples/androidnativeexample/statusbar/StatusBarDemo.qml b/source-android/androidnative.pri/examples/androidnativeexample/statusbar/StatusBarDemo.qml deleted file mode 100644 index 0d82d01..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/statusbar/StatusBarDemo.qml +++ /dev/null @@ -1,47 +0,0 @@ -import QtQuick 2.2 -import QtQuick.Window 2.1 -import QtQuick.Controls 2.1 as QQC2 -import QuickAndroid 0.1 -import QuickAndroid.Styles 0.1 -import AndroidNative 1.0 as AN -import "../theme" - -Page { - - actionBar: ActionBar { - id : actionBar - title: "Status Bar" - z: 10 - upEnabled: true - onActionButtonClicked: back(); - } - - Column { - anchors.centerIn: parent - - QQC2.Switch { - text: "Translucent Status Bar" - checked: false - - onCheckedChanged: { - AN.SystemDispatcher.dispatch("androidnative.Util.setTranslucentStatusBar", {value: checked}); - } - } - - QQC2.Switch { - text: "Status Bar Visible" - checked: true - - onCheckedChanged: { - AN.SystemDispatcher.dispatch("androidnative.Util.setFullScreen", {value: checked}); - } - } - - } - - Component.onCompleted: { - AN.SystemDispatcher.loadClass("androidnative.Util"); - } - - -} diff --git a/source-android/androidnative.pri/examples/androidnativeexample/theme/ActionBarBackground.qml b/source-android/androidnative.pri/examples/androidnativeexample/theme/ActionBarBackground.qml deleted file mode 100644 index 1adb0f1..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/theme/ActionBarBackground.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 -import QuickAndroid 0.1 - -Item { - - MaterialShadow { - asynchronous: true - anchors.fill: parent - depth: 1 - } - - Rectangle { - color: "#cddc39" // Lime 500 - anchors.fill: parent - } -} - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/theme/AppTheme.qml b/source-android/androidnative.pri/examples/androidnativeexample/theme/AppTheme.qml deleted file mode 100644 index 9ee92c2..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/theme/AppTheme.qml +++ /dev/null @@ -1,33 +0,0 @@ -import QtQuick 2.0 -import QuickAndroid 0.1 -import QuickAndroid.Styles 0.1 -pragma Singleton - -Theme { - mediumText.textSize: 18 * A.dp - smallText.textSize : 14 * A.dp - - colorPrimary: "#cddc39" // Lime 500 - textColorPrimary: Constants.black87 - windowBackground: "#eeeeee"; - - // The default icon of ActionBar is a "back" image - actionBar.iconSource: A.drawable("ic_arrow_back",Constants.black87) - - // Background with shadow - actionBar.background: ActionBarBackground { - } - - // actionBar.title.textSize is not allowed in QML. You should declare your own TextMaterial and assign directly. - // or modify text , smallText , mediumText and largetText - actionBar.title : customTextMaterial1; - actionBar.iconSourceSize: Qt.size(24 * A.dp , 24 * A.dp) - - // Custom Style object. - TextMaterial { - id : customTextMaterial1 - textSize: 18 * A.dp - textColor : Constants.black87 - } -} - diff --git a/source-android/androidnative.pri/examples/androidnativeexample/theme/qmldir b/source-android/androidnative.pri/examples/androidnativeexample/theme/qmldir deleted file mode 100644 index 5a1f2f4..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/theme/qmldir +++ /dev/null @@ -1,2 +0,0 @@ -module theme -singleton AppTheme 0.1 AppTheme.qml diff --git a/source-android/androidnative.pri/examples/androidnativeexample/toast/ToastDemo.qml b/source-android/androidnative.pri/examples/androidnativeexample/toast/ToastDemo.qml deleted file mode 100644 index f5e23bd..0000000 --- a/source-android/androidnative.pri/examples/androidnativeexample/toast/ToastDemo.qml +++ /dev/null @@ -1,33 +0,0 @@ -import QtQuick 2.2 -import QtQuick.Window 2.1 -import QuickAndroid 0.1 -import QuickAndroid.Styles 0.1 -import AndroidNative 1.0 as AN -import "../theme" - -Page { - - actionBar: ActionBar { - id : actionBar - title: "Toast" - z: 10 - upEnabled: true - onActionButtonClicked: back(); - } - - AN.Toast { - id: toast - text: "Toast" - longDuration: true - } - - Button { - id: label - text : "Press to show toast" - anchors.centerIn: parent - onClicked: { - toast.show(); - } - } - -} diff --git a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java index ae44267..01833c2 100644 --- a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java +++ b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java @@ -10,6 +10,7 @@ import android.content.Context; import android.Manifest.permission; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; +import androidnative.AndroidNativeService; /** An alternative Activity class for Qt applicaiton. @@ -18,7 +19,8 @@ import androidx.core.content.ContextCompat; public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.QtActivity { public static final int MY_PERMISSIONS_REQUEST_READ_STORAGE = 0x245285a8; - + public static final int MY_PERMISSIONS_REQUEST_POST_NOTIFICATIONS = 0x245285a9; + private static final String TAG = "AndroidNativeActivity"; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -29,6 +31,11 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt protected void onResume() { super.onResume(); + + + + AndroidNativeService fs = new AndroidNativeService(); + fs.startQtService(this); //if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) { // Permission is not granted @@ -75,19 +82,29 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt @Override public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) { + Log.d(TAG,"onRequestPermissionsResult"); switch (requestCode) { case MY_PERMISSIONS_REQUEST_READ_STORAGE: { // If request is cancelled, the result arrays are empty. - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - Map message = new HashMap(); - message.put("multiple",false); - SystemDispatcher.dispatch("androidnative.ImagePicker.pickImage",message); - } else { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Map message = new HashMap(); + message.put("multiple",false); + SystemDispatcher.dispatch("androidnative.ImagePicker.pickImage",message); + } else { + } } + case MY_PERMISSIONS_REQUEST_POST_NOTIFICATIONS: { + // If request is cancelled, the result arrays are empty. + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Map message = new HashMap(); + message.put("multiple",false); + SystemDispatcher.dispatch("androidnative.Util.setPostNotification",message); + } else { + } + } return; } } -} diff --git a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeService.java b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeService.java index 55ef5db..eeca21e 100644 --- a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeService.java +++ b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeService.java @@ -20,14 +20,14 @@ public class AndroidNativeService extends QtService private static String TAG = "AndroidNative"; public void startQtService(Context ctx) { - //Log.d(TAG, "QtActivity active "+String.valueOf(QtNative.activity()!=null)); + Log.d(TAG, "QtActivity active "+String.valueOf(QtNative.activity()!=null)); if (QtNative.activity()==null){ - //Log.d(TAG,"Friendiqasync Stop existing QtService"); + Log.d(TAG,"Friendiqasync Stop existing QtService"); ctx.stopService(new Intent(ctx, AndroidNativeService.class)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - //Log.d(TAG,"Friendiqasync startForegroundService"); + Log.d(TAG,"Friendiqasync startForegroundService"); ctx.startForegroundService(new Intent(ctx, AndroidNativeService.class)); } else { ctx.startService(new Intent(ctx, AndroidNativeService.class)); @@ -35,7 +35,7 @@ public class AndroidNativeService extends QtService } public static void stopQtService(Context ctx) { - //Log.d(TAG,"Friendiqasync QtServiceStop"); + Log.d(TAG,"Friendiqasync QtServiceStop"); ctx.stopService(new Intent(ctx, AndroidNativeService.class)); } @@ -44,11 +44,12 @@ public class AndroidNativeService extends QtService { Context context; context = this.getApplicationContext(); + Log.d(TAG,"Friendiqa onCreate"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 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); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); String CHANNEL_ID = "channel_02"; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Sync Channel", diff --git a/source-android/androidnative.pri/java/src/androidnative/Util.java b/source-android/androidnative.pri/java/src/androidnative/Util.java index 6ea90cf..3d77096 100644 --- a/source-android/androidnative.pri/java/src/androidnative/Util.java +++ b/source-android/androidnative.pri/java/src/androidnative/Util.java @@ -25,6 +25,11 @@ import android.content.Intent; import java.util.Map; import org.qtproject.friendiqa.R; +import android.content.pm.PackageManager; +import android.Manifest; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + public class Util { private static final String TAG = "androidnative.Util"; @@ -33,7 +38,8 @@ public class Util { 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"; - + public static final String SET_POST_NOTIFICATION = "androidnative.Util.setPostNotification"; + public static final int MY_PERMISSIONS_REQUEST_POST_NOTIFICATIONS = 0x245285a9; static { SystemDispatcher.addListener(new SystemDispatcher.Listener() { @@ -46,6 +52,8 @@ public class Util { setSchedule(message); } else if (type.equals(SET_NOTIFICATION)) { setNotification(message); + } else if (type.equals(SET_POST_NOTIFICATION)) { + setPostNotification(message); } } }); @@ -110,14 +118,14 @@ public class Util { } static void setNotification(Map message) { - //Log.d(TAG,"setNotification"); + 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); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); final String textTitle = (String) message.get("title"); final String textContent = (String) message.get("message"); @@ -171,14 +179,23 @@ public class Util { } else { context = QtNative.activity().getApplicationContext(); } + + + + //AndroidNativeService fs = new AndroidNativeService(); + //fs.startQtService(context); + + if (value==0){ JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.cancelAll(); - //Log.d(TAG,"Friendiqasync deleting Androidnative jobscheduler"); + Log.d(TAG,"Friendiqasync deleting Androidnative jobscheduler"); } else { - //Log.d(TAG,"Friendiqasync schedule Androidnative jobscheduler"); + Log.d(TAG,"Friendiqasync schedule Androidnative jobscheduler"); ComponentName component = new ComponentName(context, FriendiqaService.class); JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); + + //Log.d(TAG,"Jobinfolist size " + String.valueOf(jobScheduler.getAllPendingJobs().size())); if (jobScheduler.getAllPendingJobs().size()==0){ JobInfo.Builder builder = new JobInfo.Builder(2, component) @@ -186,7 +203,7 @@ public class Util { .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setPersisted(true) .setPrefetch(true); - //Log.d(TAG,"Friendiqa schedule Androidnative sync schedule"+ (value * ONE_MIN)); + Log.d(TAG,"1 Friendiqa schedule Androidnative sync schedule"+ (value * ONE_MIN)); jobScheduler.schedule(builder.build()); } else { for ( JobInfo jobInfo : jobScheduler.getAllPendingJobs() ) { @@ -197,23 +214,42 @@ public class Util { .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setPersisted(true) .setPrefetch(true); - //Log.d(TAG,"Friendiqa schedule Androidnative sync schedule"+ (value * ONE_MIN)); + Log.d(TAG,"2 Friendiqa schedule Androidnative sync schedule"+ (value * ONE_MIN)); jobScheduler.schedule(builder.build()); } } } //Log.d(TAG,"Active service " + String.valueOf(QtNative.service()!=null)); - if (QtNative.service() != null){ - //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) - .setOverrideDeadline(100); + //if (QtNative.service() != null){ + // 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) + // .setOverrideDeadline(100); - JobScheduler jobStopScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); - jobStopScheduler.schedule(stopbuilder.build()); - } + // JobScheduler jobStopScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); + // jobStopScheduler.schedule(stopbuilder.build()); + //} } + NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); + notificationManager.cancelAll(); //context.stopService(new Intent(context, AndroidNativeService.class)); } + + static void setPostNotification(Map message) { + Log.d(TAG,"setPostNotification"); + Context context; + if (QtNative.activity() == null){ + context = QtNative.service().getApplicationContext(); + } else { + context = QtNative.activity().getApplicationContext(); + } + Activity activity = org.qtproject.qt5.android.QtNative.activity(); + Log.d(TAG,String.valueOf(ContextCompat.checkSelfPermission(context,Manifest.permission.POST_NOTIFICATIONS))); + if (ContextCompat.checkSelfPermission(context,Manifest.permission.POST_NOTIFICATIONS)!= PackageManager.PERMISSION_GRANTED) { + // Permission is not granted + Log.d(TAG,String.valueOf(PackageManager.PERMISSION_GRANTED)); + ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.POST_NOTIFICATIONS},MY_PERMISSIONS_REQUEST_POST_NOTIFICATIONS); + } + } } diff --git a/source-android/application.qrc b/source-android/application.qrc deleted file mode 120000 index 4607047..0000000 --- a/source-android/application.qrc +++ /dev/null @@ -1 +0,0 @@ -../source-linux/application.qrc \ No newline at end of file diff --git a/source-android/common/alarm.h b/source-android/common/alarm.h deleted file mode 120000 index b5e49ca..0000000 --- a/source-android/common/alarm.h +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/alarm.h \ No newline at end of file diff --git a/source-android/common/alarmandroid.cpp b/source-android/common/alarmandroid.cpp deleted file mode 120000 index adb6cb0..0000000 --- a/source-android/common/alarmandroid.cpp +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/alarmandroid.cpp \ No newline at end of file diff --git a/source-android/common/alarmlinux.cpp b/source-android/common/alarmlinux.cpp deleted file mode 120000 index af9de81..0000000 --- a/source-android/common/alarmlinux.cpp +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/alarmlinux.cpp \ No newline at end of file diff --git a/source-android/common/filesystem.cpp b/source-android/common/filesystem.cpp deleted file mode 120000 index 94a7237..0000000 --- a/source-android/common/filesystem.cpp +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/filesystem.cpp \ No newline at end of file diff --git a/source-android/common/filesystem.h b/source-android/common/filesystem.h deleted file mode 120000 index 0ee6500..0000000 --- a/source-android/common/filesystem.h +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/filesystem.h \ No newline at end of file diff --git a/source-android/common/filesystemandroid.cpp b/source-android/common/filesystemandroid.cpp deleted file mode 120000 index dbfaf68..0000000 --- a/source-android/common/filesystemandroid.cpp +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/filesystemandroid.cpp \ No newline at end of file diff --git a/source-android/common/friendiqa.cpp b/source-android/common/friendiqa.cpp index 8193d70..7dc02b5 100644 --- a/source-android/common/friendiqa.cpp +++ b/source-android/common/friendiqa.cpp @@ -36,6 +36,7 @@ #include "xhr.h" #include "updatenews.h" #include "filesystem.h" +#include "oauth.h" #include "remoteauthasyncimageprovider.h" #include "AndroidNative/systemdispatcher.h" @@ -54,13 +55,12 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { Q_DECL_EXPORT int main(int argc, char *argv[]) { - //if (argc>1){qDebug()<< "argc Friendiqa"<< argc <<" argv1" <1) && (qstrcmp(argv[1],"-service")==0)){ - //qDebug()<<"FriendiqaMain Service"; QAndroidService app(argc, argv); UPDATENEWS* updatenews= UPDATENEWS::instance(); updatenews->setDatabase(); updatenews->login(); + updatenews->setSyncAll(true); updatenews->startsync(); app.connect (updatenews,SIGNAL(quitapp()),&app,SLOT(quit())); return app.exec(); @@ -68,7 +68,6 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) { else{ QApplication app(argc, argv); QQmlApplicationEngine view; - //qDebug()<<"FriendiqaMain started"; QTranslator qtTranslator; qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations"); app.installTranslator(&qtTranslator); @@ -83,6 +82,8 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) { view.rootContext()->setContextProperty("alarm", alarm); UPDATENEWS* updatenews = UPDATENEWS::instance(); view.rootContext()->setContextProperty("updatenews", updatenews); + OAuthWrapper* oauth2 = OAuthWrapper::instance(); + view.rootContext()->setContextProperty("oauth2", oauth2); view.load(QUrl("qrc:/qml/friendiqa.qml")); view.connect(view.rootContext()->engine(), SIGNAL(quit()), &app, SLOT(quit())); diff --git a/source-android/common/remoteauthasyncimageprovider.cpp b/source-android/common/remoteauthasyncimageprovider.cpp deleted file mode 120000 index e13424b..0000000 --- a/source-android/common/remoteauthasyncimageprovider.cpp +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/remoteauthasyncimageprovider.cpp \ No newline at end of file diff --git a/source-android/common/remoteauthasyncimageprovider.h b/source-android/common/remoteauthasyncimageprovider.h deleted file mode 120000 index 9a79dbe..0000000 --- a/source-android/common/remoteauthasyncimageprovider.h +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/remoteauthasyncimageprovider.h \ No newline at end of file diff --git a/source-android/common/updatenews.cpp b/source-android/common/updatenews.cpp deleted file mode 120000 index 4d79e7e..0000000 --- a/source-android/common/updatenews.cpp +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/updatenews.cpp \ No newline at end of file diff --git a/source-android/common/updatenews.h b/source-android/common/updatenews.h deleted file mode 120000 index f506bd0..0000000 --- a/source-android/common/updatenews.h +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/updatenews.h \ No newline at end of file diff --git a/source-android/common/uploadableimage.cpp b/source-android/common/uploadableimage.cpp deleted file mode 120000 index 069ff8f..0000000 --- a/source-android/common/uploadableimage.cpp +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/uploadableimage.cpp \ No newline at end of file diff --git a/source-android/common/uploadableimage.h b/source-android/common/uploadableimage.h deleted file mode 120000 index 32396a1..0000000 --- a/source-android/common/uploadableimage.h +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/uploadableimage.h \ No newline at end of file diff --git a/source-android/common/xhr.cpp b/source-android/common/xhr.cpp deleted file mode 120000 index 660c2c7..0000000 --- a/source-android/common/xhr.cpp +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/xhr.cpp \ No newline at end of file diff --git a/source-android/common/xhr.h b/source-android/common/xhr.h deleted file mode 120000 index d383456..0000000 --- a/source-android/common/xhr.h +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/common/xhr.h \ No newline at end of file diff --git a/source-android/friendiqa.pro b/source-android/friendiqa.pro index 40f7006..20ff216 100644 --- a/source-android/friendiqa.pro +++ b/source-android/friendiqa.pro @@ -13,7 +13,7 @@ TEMPLATE = app TARGET = friendiqa CONFIG += release -QT += qml quick gui widgets androidextras sql webview #webengine +QT += core core-private qml quick gui widgets sql androidextras network networkauth include(androidnative.pri/androidnative.pri) @@ -23,7 +23,8 @@ SOURCES += common/friendiqa.cpp \ common/filesystemandroid.cpp \ common/remoteauthasyncimageprovider.cpp \ common/updatenews.cpp \ - common/alarmandroid.cpp + common/alarmandroid.cpp \ + common/oauth.cpp lupdate_only{ SOURCES = qml/friendiqa.qml \ qml/*.qml @@ -38,7 +39,6 @@ SOURCES += common/friendiqa.cpp \ ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android - RESOURCES = application.qrc OTHER_FILES += qml/friendiqa.qml \ @@ -53,7 +53,8 @@ OTHER_FILES += qml/friendiqa.qml \ TRANSLATIONS += translations/friendiqa-de.ts \ translations/friendiqa-es.ts \ translations/friendiqa-it.ts \ - translations/friendiqa-hu.ts + translations/friendiqa-hu.ts \ + translations/friendiqa-nl.ts HEADERS += \ common/uploadableimage.h \ @@ -61,9 +62,11 @@ HEADERS += \ common/filesystem.h \ common/remoteauthasyncimageprovider.h \ common/updatenews.h \ - common/alarm.h + common/alarm.h \ + common/oauth.h DISTFILES += \ + android/gradle.properties \ qml/calendarqml/*.qml \ android/AndroidManifest.xml \ android/gradle/wrapper/gradle-wrapper.jar \ @@ -72,6 +75,7 @@ DISTFILES += \ android/build.gradle \ android/gradle/wrapper/gradle-wrapper.properties \ android/gradlew.bat \ + qml/configqml/ConfigAppearancePage.qml \ translations/*.ts \ translations/*.qm \ qml/*.qml \ @@ -84,5 +88,6 @@ DISTFILES += \ android/src/FriendiqaActivity.java \ android/src/FriendiqaService.java -ANDROID_EXTRA_LIBS = $$PWD/android/arm/libcrypto_1_1.so $$PWD/android/arm/libssl_1_1.so $$PWD/android/arm64/libcrypto_1_1.so $$PWD/android/arm64/libssl_1_1.so +#ANDROID_ABIS = arm64-v8a +android: include(/home/pankraz/android-sdk/android_openssl/openssl.pri) diff --git a/source-android/images b/source-android/images deleted file mode 120000 index f6e087d..0000000 --- a/source-android/images +++ /dev/null @@ -1 +0,0 @@ -../source-linux/images \ No newline at end of file diff --git a/source-android/js b/source-android/js deleted file mode 120000 index d7539d8..0000000 --- a/source-android/js +++ /dev/null @@ -1 +0,0 @@ -../source-linux/js \ No newline at end of file diff --git a/source-android/qml/calendarqml b/source-android/qml/calendarqml deleted file mode 120000 index efa5132..0000000 --- a/source-android/qml/calendarqml +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/qml/calendarqml \ No newline at end of file diff --git a/source-android/qml/configqml b/source-android/qml/configqml deleted file mode 120000 index 1d9fc92..0000000 --- a/source-android/qml/configqml +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/qml/configqml \ No newline at end of file diff --git a/source-android/qml/contactqml b/source-android/qml/contactqml deleted file mode 120000 index 3e93dac..0000000 --- a/source-android/qml/contactqml +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/qml/contactqml \ No newline at end of file diff --git a/source-android/qml/friendiqa.qml b/source-android/qml/friendiqa.qml index 5bea20f..e9c5227 100644 --- a/source-android/qml/friendiqa.qml +++ b/source-android/qml/friendiqa.qml @@ -33,6 +33,7 @@ import QtQuick 2.5 import QtQuick.LocalStorage 2.0 import QtQuick.Window 2.0 import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.12 import QtQuick.Layouts 1.11 import "qrc:/js/news.js" as Newsjs import "qrc:/js/service.js" as Service @@ -42,11 +43,11 @@ import "qrc:/qml/genericqml" ApplicationWindow{ id:root title: "Friendiqa" - property var globaloptions: Service.readGO(db) property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettingsAndroid.qml");return tmp.createObject(root)} visible: true property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000] property var login: Service.readActiveConfig(db) + property var globaloptions: Service.readGO(db) property real fontFactor: root.font.pixelSize/root.font.pointSize property var contactlist: [] property real mm: osSettings.osType=="Android"?Screen.pixelDensity:Screen.pixelDensity*1.5 @@ -57,8 +58,10 @@ ApplicationWindow{ signal newstypeSignal(var type) signal friendsSignal(var username) signal contactdetailsSignal(var contact) + signal contactRefreshSignal() signal searchSignal (var searchterm) signal eventSignal(var contact) + signal eventcreateSignal(var event) signal uploadSignal(var urls) signal sendtextSignal(var intenttext) signal changeimage(var method, var type, var id) @@ -70,10 +73,11 @@ ApplicationWindow{ //property string contactLoadType: "" property bool imagePicking: false + Material.theme: Material.System + function onLoginChanged(login){ - if(login==""){rootstackView.push("qrc:/qml/configqml/AccountPage.qml")} - else{//rootstackView.push(rootstack) - if (login.newsViewType!="" || login.newsViewType!=null){newstab.newstabstatus=login.newsViewType;} + if(login=="" || login==null){rootstackView.push("qrc:/qml/configqml/AccountPage.qml")} + else{ Newsjs.getCurrentContacts(login,db,function(contacts){ contactlist=contacts})} } @@ -81,7 +85,7 @@ ApplicationWindow{ if(newContacts.length>0){// download contact images and update db var contacturls=[]; var contactnames=[]; - for (var link in newContacts){//print("new contact " +newContacts[link].screen_name); + for (var link in newContacts){ contacturls.push(newContacts[link].profile_image_url); contactnames.push(newContacts[link].screen_name); Service.updateContactInDB(login,db,newContacts[link].isFriend,newContacts[link]) @@ -114,7 +118,7 @@ ApplicationWindow{ } - function showContact(contact){ //print(JSON.stringify(contact)); + function showContact(contact){ rootstackView.push("qrc:/qml/newsqml/ContactPage.qml",{"contact": contact}) } @@ -135,18 +139,16 @@ ApplicationWindow{ FontLoader{id: fontAwesome; source: "qrc:/images/fontawesome-webfont.ttf"} - //Keys.onReleased: {//print(event.key + "Backkey"+newstab.conversation.length+" "+root.depth) onClosing: { - //if (event.key === osSettings.backKey) { if (rootstack.currentIndex==0){ newstab.active=true; - if (newstab.newstabstatus!=globaloptions.newsViewType){ + if ((newstab.newstabstatus!="") && (newstab.newstabstatus!=globaloptions.newsViewType)&&(globaloptions.newsViewType!=null)){ newstab.newstabstatus=globaloptions.newsViewType; if(globaloptions.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,0,function(dbnews){ newsSignal(dbnews) })} else{ - Newsjs.chatsfromdb(db,login.username,function(dbnews){ + Newsjs.chatsfromdb(db,login.username,0,function(dbnews){ newsSignal(dbnews) })} close.accepted=false; @@ -156,139 +158,112 @@ ApplicationWindow{ newstab.conversation=[]; close.accepted=false } - else if (root.depth>1){ - root.pop(); + else if (rootstackView.depth>1){ + rootstackView.pop(); + roottoolbar.visible=true; close.accepted=false } else{ Service.cleanNews(root.db,function(){ Service.cleanHashtags(root.db,function(){ Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) + Qt.quit() + }) })}) close.accepted=true } } - else if (rootstack.currentIndex==2){fotoSignal("backButton")} - else {rootstack.currentIndex=0} - //event.accepted = true - //} + else if (rootstack.currentIndex==2){fotoSignal(login.username,"backButton");bar.currentIndex=0;close.accepted=false} + else {rootstack.currentIndex=0;bar.currentIndex=0;close.accepted=false} } - footer:ToolBar{ - //position: ToolBar.Footer + footer:ToolBar{id:roottoolbar background: Rectangle{ anchors.fill: parent - color: "#EEEEEE"//"#F8F8F8" + color: Material.backgroundDimColor } - //RowLayout{ - // anchors.fill: parent - TabBar { - id: bar - width:parent.width - // Layout.fillWidth: true - //width: wideScreen?contentWidth:parent.width-10*mm - //x: 7*mm - onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex - TabButton { - text: "\uf03a" - font.pointSize: osSettings.bigFontSize - background:Rectangle{ - anchors.fill: parent - color: "#EEEEEE" - } - } - TabButton { - text: "\uf0c0" - font.pointSize: osSettings.bigFontSize - background:Rectangle{ - anchors.fill: parent - color: "#EEEEEE" - } - } - TabButton { - text: "\uf03e" - font.pointSize: osSettings.bigFontSize - background:Rectangle{ - anchors.fill: parent - color: "#EEEEEE" - } - } - TabButton { - text: "\uf073" - font.pointSize: osSettings.bigFontSize - background:Rectangle{ - anchors.fill: parent - color: "#EEEEEE" - } + TabBar { + id: bar + width:parent.width + onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex + TabButton { + text: "\uf03a" + font.pointSize: osSettings.bigFontSize + background:Rectangle{ + anchors.fill: parent + color: Material.backgroundDimColor } } - // } + TabButton { + text: "\uf0c0" + font.pointSize: osSettings.bigFontSize + background:Rectangle{ + anchors.fill: parent + color: Material.backgroundDimColor + } + } + TabButton { + text: "\uf03e" + font.pointSize: osSettings.bigFontSize + background:Rectangle{ + anchors.fill: parent + color: Material.backgroundDimColor + } + } + TabButton { + text: "\uf073" + font.pointSize: osSettings.bigFontSize + background:Rectangle{ + anchors.fill: parent + color: Material.backgroundDimColor + } + } + } } - - - // 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 - // } - // } StackView{id:rootstackView width:root.width height: root.height initialItem: StackLayout{ id:rootstack width:rootstackView.width - height: rootstackView.height//-7*mm - //y:wideScreen?7*mm:0 + height: rootstackView.height currentIndex:bar.currentIndex Loader{ id: newstab -// Layout.fillWidth:true -// Layout.fillHeight: true property string newstabstatus property var conversation:[] - source:(rootstack.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" + //onDoubleClicked:{newstypeSignal("refresh")} } 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: { onLoginChanged(login); globaloptions=Service.readGO(db); + if(globaloptions.view_darkmode==1){Material.theme=Material.Dark} + else if (globaloptions.view_darkmode==2){Material.theme=Material.Light} + else {Material.theme=Material.System} //forceActiveFocus(); if(osSettings.osType=="Android"){ var component = Qt.createComponent("qrc:/qml/genericqml/IntentReceiver.qml"); @@ -299,5 +274,4 @@ ApplicationWindow{ var LinuxSyncQml = component.createObject(root); } } - //} } diff --git a/source-android/qml/genericqml b/source-android/qml/genericqml deleted file mode 120000 index 5fdbcc3..0000000 --- a/source-android/qml/genericqml +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/qml/genericqml \ No newline at end of file diff --git a/source-android/qml/newsqml b/source-android/qml/newsqml deleted file mode 120000 index f6ab73f..0000000 --- a/source-android/qml/newsqml +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/qml/newsqml \ No newline at end of file diff --git a/source-android/qml/photoqml b/source-android/qml/photoqml deleted file mode 120000 index 4528ee0..0000000 --- a/source-android/qml/photoqml +++ /dev/null @@ -1 +0,0 @@ -../../source-linux/qml/photoqml \ No newline at end of file diff --git a/source-android/qtquickcontrols2.conf b/source-android/qtquickcontrols2.conf deleted file mode 120000 index 4fb6470..0000000 --- a/source-android/qtquickcontrols2.conf +++ /dev/null @@ -1 +0,0 @@ -../source-linux/qtquickcontrols2.conf \ No newline at end of file diff --git a/source-android/translations b/source-android/translations deleted file mode 120000 index d630c0b..0000000 --- a/source-android/translations +++ /dev/null @@ -1 +0,0 @@ -../source-linux/translations \ No newline at end of file diff --git a/source-linux/application.qrc b/source-linux/application.qrc deleted file mode 100644 index 3e62eeb..0000000 --- a/source-linux/application.qrc +++ /dev/null @@ -1,253 +0,0 @@ - - - qtquickcontrols2.conf - qml/friendiqa.qml - qml/newsqml/NewsStack.qml - qml/newsqml/NewsTab.qml - qml/newsqml/Newsitem.qml - qml/newsqml/MessageSend.qml - qml/newsqml/Conversation.qml - qml/newsqml/FriendicaActivities.qml - qml/newsqml/Hashtag.qml - qml/newsqml/NewsImage.qml - qml/newsqml/NewsVideo.qml - qml/newsqml/ContactPage.qml - qml/newsqml/NewsLink.qml - qml/newsqml/NewsVideoLarge.qml - qml/newsqml/NewsYplayer.qml - qml/newsqml/SmileyDialog.qml - qml/contactqml/FriendsTab.qml - qml/contactqml/GroupComponent.qml - qml/contactqml/ProfileComponent.qml - qml/contactqml/Contactlist.qml - qml/photoqml/PhotoComponent.qml - qml/photoqml/PhotogroupComponent.qml - qml/photoqml/PhotoTab.qml - qml/photoqml/ImageUploadDialog.qml - qml/genericqml/ImagePicker.qml - qml/genericqml/ImagePickerLinux.qml - qml/genericqml/Search.qml - qml/genericqml/IntentReceiver.qml - qml/genericqml/MButton.qml - qml/genericqml/LinuxSync.qml - qml/genericqml/BlueButton.qml - qml/genericqml/ContactComponent.qml - qml/genericqml/PermissionDialog.qml - qml/calendarqml/CalendarTab.qml - qml/calendarqml/CalendarDay.qml - qml/calendarqml/EventList.qml - qml/configqml/RegisterPage.qml - qml/configqml/AccountPage.qml - qml/configqml/SyncConfig.qml - qml/configqml/SyncComponent.qml - qml/configqml/InfoBox.qml - qml/configqml/ConfigPage.qml - qml/configqml/OSSettingsAndroid.qml - qml/configqml/OSSettingsLinux.qml - js/image.js - js/yplayer.html - js/layout.js - js/photoworker.js - js/service.js - js/news.js - js/newsworker.js - js/helper.js - js/smiley.js - translations/friendiqa-it.ts - translations/friendiqa-it.qm - translations/friendiqa-de.qm - translations/friendiqa-de.ts - translations/friendiqa-es.qm - translations/friendiqa-es.ts - images/defaultcontact.jpg - images/fontawesome-webfont.ttf - images/folder-blue.png - images/smileys/animals/bee.gif - images/smileys/animals/bigspider.gif - images/smileys/animals/bunny.gif - images/smileys/animals/bunnyflowers.gif - images/smileys/animals/cat.gif - images/smileys/animals/chick.gif - images/smileys/animals/cow.gif - images/smileys/animals/crab.gif - images/smileys/animals/dog.gif - images/smileys/animals/dolphin.gif - images/smileys/animals/dragonfly.gif - images/smileys/animals/elephant.gif - images/smileys/animals/fish.gif - images/smileys/animals/frog.gif - images/smileys/animals/giraffe.gif - images/smileys/animals/hamster.gif - images/smileys/animals/horse.gif - images/smileys/animals/ladybird.gif - images/smileys/animals/monkey.gif - images/smileys/animals/parrot.gif - images/smileys/animals/pig.gif - images/smileys/animals/sheep.gif - images/smileys/animals/snail.gif - images/smileys/animals/tux.gif - images/smileys/babies/baby.gif - images/smileys/babies/babycot.gif - images/smileys/babies/pregnant.gif - images/smileys/babies/stork.gif - images/smileys/confused/confused.gif - images/smileys/confused/dazed.gif - images/smileys/confused/shrug.gif - images/smileys/confused/stupid.gif - images/smileys/cool/affro.gif - images/smileys/cool/cool.gif - images/smileys/devilangel/angel.gif - images/smileys/devilangel/blondedevil.gif - images/smileys/devilangel/catdevil.gif - images/smileys/devilangel/cherub.gif - images/smileys/devilangel/daseesaw.gif - images/smileys/devilangel/devil.gif - images/smileys/devilangel/graveside.gif - images/smileys/devilangel/saint.gif - images/smileys/devilangel/turnevil.gif - images/smileys/disgust/fartblush.gif - images/smileys/disgust/fartinbed.gif - images/smileys/disgust/toilet.gif - images/smileys/disgust/vomit.gif - images/smileys/drink/tea.gif - images/smileys/drool/drool.gif - images/smileys/fantasy/alienmonster.gif - images/smileys/fantasy/barbarian.gif - images/smileys/fantasy/dinosaur.gif - images/smileys/fantasy/dragon.gif - images/smileys/fantasy/dragonwhelp.gif - images/smileys/fantasy/ghost.gif - images/smileys/fantasy/mummy.gif - images/smileys/fight/2guns.gif - images/smileys/fight/acid.gif - images/smileys/fight/alienfight.gif - images/smileys/fight/alpha.png - images/smileys/fight/army.gif - images/smileys/fight/arrowhead.gif - images/smileys/fight/bfg.gif - images/smileys/fight/bowman.gif - images/smileys/fight/chainsaw.gif - images/smileys/fight/crossbow.gif - images/smileys/fight/crusader.gif - images/smileys/fight/dead.gif - images/smileys/fight/gangs.gif - images/smileys/fight/hammersplat.gif - images/smileys/fight/lasergun.gif - images/smileys/fight/machinegun.gif - images/smileys/fight/marine.gif - images/smileys/fight/sabre.gif - images/smileys/fight/samurai.gif - images/smileys/fight/tank.gif - images/smileys/fight/viking.gif - images/smileys/food/apple.gif - images/smileys/food/banana.gif - images/smileys/food/birthdaycake.gif - images/smileys/food/broccoli.gif - images/smileys/food/cake.gif - images/smileys/food/carrot.gif - images/smileys/food/cooking.gif - images/smileys/food/fryegg.gif - images/smileys/food/popcorn.gif - images/smileys/food/tomato.gif - images/smileys/happy/cloud9.gif - images/smileys/happy/tearsofjoy.gif - images/smileys/laugh/hahaha.gif - images/smileys/laugh/loltv.gif - images/smileys/laugh/rofl.gif - images/smileys/love/iloveyou.gif - images/smileys/love/inlove.gif - images/smileys/love/love.gif - images/smileys/love/lovebear.gif - images/smileys/love/lovebed.gif - images/smileys/love/loveheart.gif - images/smileys/music/dj.gif - images/smileys/music/drums.gif - images/smileys/music/elvis.gif - images/smileys/music/guitar.gif - images/smileys/music/trumpet.gif - images/smileys/music/violin.gif - images/smileys/oldcore/beard.png - images/smileys/oldcore/headbang.gif - images/smileys/oldcore/laughing.gif - images/smileys/oldcore/shaka.gif - images/smileys/oldcore/surprised.gif - images/smileys/oldcore/whitebeard.png - images/smileys/respect/bow.gif - images/smileys/respect/bravo.gif - images/smileys/respect/hailking.gif - images/smileys/respect/number1.gif - images/smileys/sad/crying.png - images/smileys/sad/prisoner.gif - images/smileys/sad/sigh.gif - images/smileys/smoking/smoking.gif - images/smileys/sport/archery.gif - images/smileys/sport/basketball.gif - images/smileys/sport/bowling.gif - images/smileys/sport/cycling.gif - images/smileys/sport/darts.gif - images/smileys/sport/fencing.gif - images/smileys/sport/football.gif - images/smileys/sport/golf.gif - images/smileys/sport/horseriding.gif - images/smileys/sport/juggling.gif - images/smileys/sport/skipping.gif - images/smileys/sport/snooker.gif - images/smileys/sport/surfing.gif - images/smileys/sport/tennis.gif - images/smileys/tired/countsheep.gif - images/smileys/tired/hammock.gif - images/smileys/tired/pillow.gif - images/smileys/tired/yawn.gif - images/smileys/core/beer_mug.gif - images/smileys/core/coffee.gif - images/smileys/core/dislike.gif - images/smileys/core/friendica-16.png - images/smileys/core/like.gif - images/smileys/core/rm-16.png - images/smileys/core/smiley-bangheaddesk.gif - images/smileys/core/smiley-brokenheart.gif - images/smileys/core/smiley-cool.gif - images/smileys/core/smiley-cry.gif - images/smileys/core/smiley-embarassed.gif - images/smileys/core/smiley-facepalm.gif - images/smileys/core/smiley-foot-in-mouth.gif - images/smileys/core/smiley-heart.gif - images/smileys/core/smiley-kiss.gif - images/smileys/core/smiley-laughing.gif - images/smileys/core/smiley-Oo.gif - images/smileys/core/smiley-smile.gif - images/smileys/core/smiley-surprised.gif - images/smileys/core/smiley-thumbsup.gif - images/smileys/core/smiley-tongue-out.gif - images/smileys/core/smiley-undecided.gif - images/smileys/core/smiley-wink.gif - images/smileys/core/smiley-frown.gif - images/smileys/adult/bong.gif - images/smileys/adult/drunk.gif - images/smileys/adult/finger.gif - images/smileys/adult/sperm.gif - images/smileys/adult/tits.gif - images/addImage.png - common/filesystem.cpp - common/filesystem.h - common/friendiqa.cpp - common/uploadableimage.cpp - common/uploadableimage.h - common/xhr.cpp - common/xhr.h - qml/newsqml/MoreComments.qml - qml/newsqml/NewsPhotolist.qml - qml/genericqml/DrawerAccountComponent.qml - qml/configqml/LeftDrawerScrollview.qml - qml/genericqml/LeftDrawerLinux.qml - qml/genericqml/LeftDrawerAndroid.qml - qml/genericqml/DrawerAccountComponentContacts.qml - qml/contactqml/ProfileTab.qml - qml/contactqml/FriendsListTab.qml - qml/contactqml/ContactsListTab.qml - qml/contactqml/GroupsListTab.qml - qml/calendarqml/EventListItem.qml - translations/friendiqa-hu.qm - translations/friendiqa-hu.ts - - diff --git a/source-linux/common/friendiqa.cpp b/source-linux/common/friendiqa.cpp deleted file mode 100644 index 794697c..0000000 --- a/source-linux/common/friendiqa.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// 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 . - -#include -#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/debug.h" -//#include "AndroidNative/mediascannerconnection.h" - - -#ifdef Q_OS_ANDROID -#include -#include -JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { - Q_UNUSED(vm); - qDebug("NativeInterface::JNI_OnLoad()"); // It must call this function within JNI_OnLoad to enable System Dispatcher - - AndroidNative::SystemDispatcher::registerNatives(); - return JNI_VERSION_1_6; - } -#endif - - -int main(int argc, char *argv[]) { - //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{ - //QtWebEngine::initialize(); - QApplication app(argc, argv); - QQmlApplicationEngine view; - //QQuickView view; - //view.setResizeMode(QQuickView::SizeRootObjectToView); - QTranslator qtTranslator; - qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations"); - app.installTranslator(&qtTranslator); - RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider; - view.addImageProvider("remoteauthimage",imageProvider); - view.rootContext()->setContextProperty("remoteauth", imageProvider); - 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.load(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/friendiqa.pro b/source-linux/friendiqa.pro deleted file mode 100644 index a9313c9..0000000 --- a/source-linux/friendiqa.pro +++ /dev/null @@ -1,65 +0,0 @@ -# NOTICE: -# -# Application name defined in TARGET has a corresponding QML filename. -# If name defined in TARGET is changed, the following needs to be done -# to match new name: -# - corresponding QML filename must be changed -# - desktop icon filename must be changed -# - desktop filename must be changed -# - icon definition filename in desktop file must be changed -# - translation filenames have to be changed - -# The name of your application -TEMPLATE = app -TARGET = friendiqa -CONFIG += release -QT += qml quick gui widgets sql webview dbus webengine - -SOURCES += common/friendiqa.cpp \ - common/uploadableimage.cpp \ - common/xhr.cpp \ - common/filesystem.cpp \ - common/remoteauthasyncimageprovider.cpp \ - common/updatenews.cpp \ - common/alarmlinux.cpp - -RESOURCES = application.qrc - -OTHER_FILES += qml/friendiqa.qml \ - translations/*.ts \ - qml/*.qml - qml/newsqml/*.qml - qml/contactqml/*.qml - qml/photoqml/*.qml - qml/configqml/*.qml - js/*.js - -TRANSLATIONS += translations/friendiqa-de.ts \ - translations/friendiqa-es.ts \ - translations/friendiqa-it.ts -HEADERS += \ - common/uploadableimage.h \ - common/xhr.h \ - common/filesystem.h \ - common/remoteauthasyncimageprovider.h \ - common/updatenews.h \ - common/alarm.h - -DISTFILES += \ - qml/calendarqml/*.qml \ - translations/*.ts \ - translations/*.qm \ - qml/*.qml \ - qml/newsqml/*.qml \ - qml/contactqml/*.qml \ - qml/photoqml/*.qml \ - qml/configqml/*.qml \ - js/*.js \ - - -target.path=/usr/bin -desktop.path = /usr/share/applications -desktop.files = images/de.ma-nic.Friendiqa.desktop -icon.path = /usr/share/icons/hicolor/scalable/apps -icon.files = images/Friendiqa.svg -INSTALLS+=target desktop icon diff --git a/source-linux/images/addImage.png b/source-linux/images/addImage.png deleted file mode 100644 index 988f9f1..0000000 Binary files a/source-linux/images/addImage.png and /dev/null differ diff --git a/source-linux/images/fontawesome-webfont.ttf b/source-linux/images/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2..0000000 Binary files a/source-linux/images/fontawesome-webfont.ttf and /dev/null differ diff --git a/source-linux/images/smileys/adult/bong.gif b/source-linux/images/smileys/adult/bong.gif deleted file mode 100644 index 4b67122..0000000 Binary files a/source-linux/images/smileys/adult/bong.gif and /dev/null differ diff --git a/source-linux/images/smileys/adult/drunk.gif b/source-linux/images/smileys/adult/drunk.gif deleted file mode 100644 index 4a1c064..0000000 Binary files a/source-linux/images/smileys/adult/drunk.gif and /dev/null differ diff --git a/source-linux/images/smileys/adult/finger.gif b/source-linux/images/smileys/adult/finger.gif deleted file mode 100644 index d45dcb8..0000000 Binary files a/source-linux/images/smileys/adult/finger.gif and /dev/null differ diff --git a/source-linux/images/smileys/adult/sperm.gif b/source-linux/images/smileys/adult/sperm.gif deleted file mode 100644 index 6ba9219..0000000 Binary files a/source-linux/images/smileys/adult/sperm.gif and /dev/null differ diff --git a/source-linux/images/smileys/adult/tits.gif b/source-linux/images/smileys/adult/tits.gif deleted file mode 100644 index 4c1658c..0000000 Binary files a/source-linux/images/smileys/adult/tits.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/bee.gif b/source-linux/images/smileys/animals/bee.gif deleted file mode 100644 index 206c2e3..0000000 Binary files a/source-linux/images/smileys/animals/bee.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/bigspider.gif b/source-linux/images/smileys/animals/bigspider.gif deleted file mode 100644 index bc43deb..0000000 Binary files a/source-linux/images/smileys/animals/bigspider.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/bunny.gif b/source-linux/images/smileys/animals/bunny.gif deleted file mode 100644 index 402b2b3..0000000 Binary files a/source-linux/images/smileys/animals/bunny.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/bunnyflowers.gif b/source-linux/images/smileys/animals/bunnyflowers.gif deleted file mode 100644 index 6d665e2..0000000 Binary files a/source-linux/images/smileys/animals/bunnyflowers.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/cat.gif b/source-linux/images/smileys/animals/cat.gif deleted file mode 100644 index a612c47..0000000 Binary files a/source-linux/images/smileys/animals/cat.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/chick.gif b/source-linux/images/smileys/animals/chick.gif deleted file mode 100644 index 6bcddcd..0000000 Binary files a/source-linux/images/smileys/animals/chick.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/cow.gif b/source-linux/images/smileys/animals/cow.gif deleted file mode 100644 index 3f94cfa..0000000 Binary files a/source-linux/images/smileys/animals/cow.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/crab.gif b/source-linux/images/smileys/animals/crab.gif deleted file mode 100644 index db5b8ce..0000000 Binary files a/source-linux/images/smileys/animals/crab.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/dog.gif b/source-linux/images/smileys/animals/dog.gif deleted file mode 100644 index 7b28477..0000000 Binary files a/source-linux/images/smileys/animals/dog.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/dolphin.gif b/source-linux/images/smileys/animals/dolphin.gif deleted file mode 100644 index 672ebd7..0000000 Binary files a/source-linux/images/smileys/animals/dolphin.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/dragonfly.gif b/source-linux/images/smileys/animals/dragonfly.gif deleted file mode 100644 index 566e95c..0000000 Binary files a/source-linux/images/smileys/animals/dragonfly.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/elephant.gif b/source-linux/images/smileys/animals/elephant.gif deleted file mode 100644 index 4311e97..0000000 Binary files a/source-linux/images/smileys/animals/elephant.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/fish.gif b/source-linux/images/smileys/animals/fish.gif deleted file mode 100644 index 3a7a584..0000000 Binary files a/source-linux/images/smileys/animals/fish.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/frog.gif b/source-linux/images/smileys/animals/frog.gif deleted file mode 100644 index 85e4b56..0000000 Binary files a/source-linux/images/smileys/animals/frog.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/giraffe.gif b/source-linux/images/smileys/animals/giraffe.gif deleted file mode 100644 index 4c95ea4..0000000 Binary files a/source-linux/images/smileys/animals/giraffe.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/hamster.gif b/source-linux/images/smileys/animals/hamster.gif deleted file mode 100644 index 96c7323..0000000 Binary files a/source-linux/images/smileys/animals/hamster.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/horse.gif b/source-linux/images/smileys/animals/horse.gif deleted file mode 100644 index 9103abf..0000000 Binary files a/source-linux/images/smileys/animals/horse.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/ladybird.gif b/source-linux/images/smileys/animals/ladybird.gif deleted file mode 100644 index 69444a9..0000000 Binary files a/source-linux/images/smileys/animals/ladybird.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/monkey.gif b/source-linux/images/smileys/animals/monkey.gif deleted file mode 100644 index b9b338d..0000000 Binary files a/source-linux/images/smileys/animals/monkey.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/parrot.gif b/source-linux/images/smileys/animals/parrot.gif deleted file mode 100644 index ae6faf6..0000000 Binary files a/source-linux/images/smileys/animals/parrot.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/pig.gif b/source-linux/images/smileys/animals/pig.gif deleted file mode 100644 index bdc68e8..0000000 Binary files a/source-linux/images/smileys/animals/pig.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/sheep.gif b/source-linux/images/smileys/animals/sheep.gif deleted file mode 100644 index 8fafc11..0000000 Binary files a/source-linux/images/smileys/animals/sheep.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/snail.gif b/source-linux/images/smileys/animals/snail.gif deleted file mode 100644 index 3bdb44c..0000000 Binary files a/source-linux/images/smileys/animals/snail.gif and /dev/null differ diff --git a/source-linux/images/smileys/animals/tux.gif b/source-linux/images/smileys/animals/tux.gif deleted file mode 100644 index 08e006e..0000000 Binary files a/source-linux/images/smileys/animals/tux.gif and /dev/null differ diff --git a/source-linux/images/smileys/babies/baby.gif b/source-linux/images/smileys/babies/baby.gif deleted file mode 100644 index d105afb..0000000 Binary files a/source-linux/images/smileys/babies/baby.gif and /dev/null differ diff --git a/source-linux/images/smileys/babies/babycot.gif b/source-linux/images/smileys/babies/babycot.gif deleted file mode 100644 index 750f6df..0000000 Binary files a/source-linux/images/smileys/babies/babycot.gif and /dev/null differ diff --git a/source-linux/images/smileys/babies/pregnant.gif b/source-linux/images/smileys/babies/pregnant.gif deleted file mode 100644 index d97f476..0000000 Binary files a/source-linux/images/smileys/babies/pregnant.gif and /dev/null differ diff --git a/source-linux/images/smileys/babies/stork.gif b/source-linux/images/smileys/babies/stork.gif deleted file mode 100644 index de2371d..0000000 Binary files a/source-linux/images/smileys/babies/stork.gif and /dev/null differ diff --git a/source-linux/images/smileys/confused/confused.gif b/source-linux/images/smileys/confused/confused.gif deleted file mode 100644 index 8f1b79a..0000000 Binary files a/source-linux/images/smileys/confused/confused.gif and /dev/null differ diff --git a/source-linux/images/smileys/confused/dazed.gif b/source-linux/images/smileys/confused/dazed.gif deleted file mode 100644 index f5e7ec2..0000000 Binary files a/source-linux/images/smileys/confused/dazed.gif and /dev/null differ diff --git a/source-linux/images/smileys/confused/shrug.gif b/source-linux/images/smileys/confused/shrug.gif deleted file mode 100644 index 31ce007..0000000 Binary files a/source-linux/images/smileys/confused/shrug.gif and /dev/null differ diff --git a/source-linux/images/smileys/confused/stupid.gif b/source-linux/images/smileys/confused/stupid.gif deleted file mode 100644 index c17170a..0000000 Binary files a/source-linux/images/smileys/confused/stupid.gif and /dev/null differ diff --git a/source-linux/images/smileys/cool/affro.gif b/source-linux/images/smileys/cool/affro.gif deleted file mode 100644 index f06166b..0000000 Binary files a/source-linux/images/smileys/cool/affro.gif and /dev/null differ diff --git a/source-linux/images/smileys/cool/cool.gif b/source-linux/images/smileys/cool/cool.gif deleted file mode 100644 index 05ba9f1..0000000 Binary files a/source-linux/images/smileys/cool/cool.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/beer_mug.gif b/source-linux/images/smileys/core/beer_mug.gif deleted file mode 100644 index 9a3e051..0000000 Binary files a/source-linux/images/smileys/core/beer_mug.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/coffee.gif b/source-linux/images/smileys/core/coffee.gif deleted file mode 100644 index 7e20371..0000000 Binary files a/source-linux/images/smileys/core/coffee.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/dislike.gif b/source-linux/images/smileys/core/dislike.gif deleted file mode 100644 index 7777942..0000000 Binary files a/source-linux/images/smileys/core/dislike.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/friendica-16.png b/source-linux/images/smileys/core/friendica-16.png deleted file mode 100644 index 745b7ac..0000000 Binary files a/source-linux/images/smileys/core/friendica-16.png and /dev/null differ diff --git a/source-linux/images/smileys/core/like.gif b/source-linux/images/smileys/core/like.gif deleted file mode 100644 index f71d032..0000000 Binary files a/source-linux/images/smileys/core/like.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/rm-16.png b/source-linux/images/smileys/core/rm-16.png deleted file mode 100644 index 9361ef2..0000000 Binary files a/source-linux/images/smileys/core/rm-16.png and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-Oo.gif b/source-linux/images/smileys/core/smiley-Oo.gif deleted file mode 100644 index a15d974..0000000 Binary files a/source-linux/images/smileys/core/smiley-Oo.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-bangheaddesk.gif b/source-linux/images/smileys/core/smiley-bangheaddesk.gif deleted file mode 100644 index 91ccb8b..0000000 Binary files a/source-linux/images/smileys/core/smiley-bangheaddesk.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-brokenheart.gif b/source-linux/images/smileys/core/smiley-brokenheart.gif deleted file mode 100644 index 971b57f..0000000 Binary files a/source-linux/images/smileys/core/smiley-brokenheart.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-cool.gif b/source-linux/images/smileys/core/smiley-cool.gif deleted file mode 100644 index cee1c1a..0000000 Binary files a/source-linux/images/smileys/core/smiley-cool.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-cry.gif b/source-linux/images/smileys/core/smiley-cry.gif deleted file mode 100644 index 06e6ca2..0000000 Binary files a/source-linux/images/smileys/core/smiley-cry.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-embarassed.gif b/source-linux/images/smileys/core/smiley-embarassed.gif deleted file mode 100644 index adc12e7..0000000 Binary files a/source-linux/images/smileys/core/smiley-embarassed.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-facepalm.gif b/source-linux/images/smileys/core/smiley-facepalm.gif deleted file mode 100644 index 7243703..0000000 Binary files a/source-linux/images/smileys/core/smiley-facepalm.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-foot-in-mouth.gif b/source-linux/images/smileys/core/smiley-foot-in-mouth.gif deleted file mode 100644 index b444e57..0000000 Binary files a/source-linux/images/smileys/core/smiley-foot-in-mouth.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-frown.gif b/source-linux/images/smileys/core/smiley-frown.gif deleted file mode 100644 index 9ff1985..0000000 Binary files a/source-linux/images/smileys/core/smiley-frown.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-heart.gif b/source-linux/images/smileys/core/smiley-heart.gif deleted file mode 100644 index 6a11e70..0000000 Binary files a/source-linux/images/smileys/core/smiley-heart.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-kiss.gif b/source-linux/images/smileys/core/smiley-kiss.gif deleted file mode 100644 index cc35661..0000000 Binary files a/source-linux/images/smileys/core/smiley-kiss.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-laughing.gif b/source-linux/images/smileys/core/smiley-laughing.gif deleted file mode 100644 index 1bf29de..0000000 Binary files a/source-linux/images/smileys/core/smiley-laughing.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-smile.gif b/source-linux/images/smileys/core/smiley-smile.gif deleted file mode 100644 index b9bff40..0000000 Binary files a/source-linux/images/smileys/core/smiley-smile.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-surprised.gif b/source-linux/images/smileys/core/smiley-surprised.gif deleted file mode 100644 index b074653..0000000 Binary files a/source-linux/images/smileys/core/smiley-surprised.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-thumbsup.gif b/source-linux/images/smileys/core/smiley-thumbsup.gif deleted file mode 100644 index 1bc6b12..0000000 Binary files a/source-linux/images/smileys/core/smiley-thumbsup.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-tongue-out.gif b/source-linux/images/smileys/core/smiley-tongue-out.gif deleted file mode 100644 index 48867dc..0000000 Binary files a/source-linux/images/smileys/core/smiley-tongue-out.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-undecided.gif b/source-linux/images/smileys/core/smiley-undecided.gif deleted file mode 100644 index 2802979..0000000 Binary files a/source-linux/images/smileys/core/smiley-undecided.gif and /dev/null differ diff --git a/source-linux/images/smileys/core/smiley-wink.gif b/source-linux/images/smileys/core/smiley-wink.gif deleted file mode 100644 index e1cefb0..0000000 Binary files a/source-linux/images/smileys/core/smiley-wink.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/angel.gif b/source-linux/images/smileys/devilangel/angel.gif deleted file mode 100644 index 8e58541..0000000 Binary files a/source-linux/images/smileys/devilangel/angel.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/blondedevil.gif b/source-linux/images/smileys/devilangel/blondedevil.gif deleted file mode 100644 index 09e7e68..0000000 Binary files a/source-linux/images/smileys/devilangel/blondedevil.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/catdevil.gif b/source-linux/images/smileys/devilangel/catdevil.gif deleted file mode 100644 index 269d719..0000000 Binary files a/source-linux/images/smileys/devilangel/catdevil.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/cherub.gif b/source-linux/images/smileys/devilangel/cherub.gif deleted file mode 100644 index 40872e0..0000000 Binary files a/source-linux/images/smileys/devilangel/cherub.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/daseesaw.gif b/source-linux/images/smileys/devilangel/daseesaw.gif deleted file mode 100644 index 1c04b2e..0000000 Binary files a/source-linux/images/smileys/devilangel/daseesaw.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/devil.gif b/source-linux/images/smileys/devilangel/devil.gif deleted file mode 100644 index 2b56797..0000000 Binary files a/source-linux/images/smileys/devilangel/devil.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/graveside.gif b/source-linux/images/smileys/devilangel/graveside.gif deleted file mode 100644 index 0e90935..0000000 Binary files a/source-linux/images/smileys/devilangel/graveside.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/saint.gif b/source-linux/images/smileys/devilangel/saint.gif deleted file mode 100644 index 52c22c4..0000000 Binary files a/source-linux/images/smileys/devilangel/saint.gif and /dev/null differ diff --git a/source-linux/images/smileys/devilangel/turnevil.gif b/source-linux/images/smileys/devilangel/turnevil.gif deleted file mode 100644 index 1490c0f..0000000 Binary files a/source-linux/images/smileys/devilangel/turnevil.gif and /dev/null differ diff --git a/source-linux/images/smileys/disgust/fartblush.gif b/source-linux/images/smileys/disgust/fartblush.gif deleted file mode 100644 index 4160a1f..0000000 Binary files a/source-linux/images/smileys/disgust/fartblush.gif and /dev/null differ diff --git a/source-linux/images/smileys/disgust/fartinbed.gif b/source-linux/images/smileys/disgust/fartinbed.gif deleted file mode 100644 index 5553649..0000000 Binary files a/source-linux/images/smileys/disgust/fartinbed.gif and /dev/null differ diff --git a/source-linux/images/smileys/disgust/toilet.gif b/source-linux/images/smileys/disgust/toilet.gif deleted file mode 100644 index 092d7ca..0000000 Binary files a/source-linux/images/smileys/disgust/toilet.gif and /dev/null differ diff --git a/source-linux/images/smileys/disgust/vomit.gif b/source-linux/images/smileys/disgust/vomit.gif deleted file mode 100644 index 6e7e727..0000000 Binary files a/source-linux/images/smileys/disgust/vomit.gif and /dev/null differ diff --git a/source-linux/images/smileys/drink/tea.gif b/source-linux/images/smileys/drink/tea.gif deleted file mode 100644 index 474b989..0000000 Binary files a/source-linux/images/smileys/drink/tea.gif and /dev/null differ diff --git a/source-linux/images/smileys/drool/drool.gif b/source-linux/images/smileys/drool/drool.gif deleted file mode 100644 index 4093df6..0000000 Binary files a/source-linux/images/smileys/drool/drool.gif and /dev/null differ diff --git a/source-linux/images/smileys/fantasy/alienmonster.gif b/source-linux/images/smileys/fantasy/alienmonster.gif deleted file mode 100644 index e0ca7f6..0000000 Binary files a/source-linux/images/smileys/fantasy/alienmonster.gif and /dev/null differ diff --git a/source-linux/images/smileys/fantasy/barbarian.gif b/source-linux/images/smileys/fantasy/barbarian.gif deleted file mode 100644 index de8a068..0000000 Binary files a/source-linux/images/smileys/fantasy/barbarian.gif and /dev/null differ diff --git a/source-linux/images/smileys/fantasy/dinosaur.gif b/source-linux/images/smileys/fantasy/dinosaur.gif deleted file mode 100644 index e8c625c..0000000 Binary files a/source-linux/images/smileys/fantasy/dinosaur.gif and /dev/null differ diff --git a/source-linux/images/smileys/fantasy/dragon.gif b/source-linux/images/smileys/fantasy/dragon.gif deleted file mode 100644 index fd28fbf..0000000 Binary files a/source-linux/images/smileys/fantasy/dragon.gif and /dev/null differ diff --git a/source-linux/images/smileys/fantasy/dragonwhelp.gif b/source-linux/images/smileys/fantasy/dragonwhelp.gif deleted file mode 100644 index dbc4555..0000000 Binary files a/source-linux/images/smileys/fantasy/dragonwhelp.gif and /dev/null differ diff --git a/source-linux/images/smileys/fantasy/ghost.gif b/source-linux/images/smileys/fantasy/ghost.gif deleted file mode 100644 index 4c5d85d..0000000 Binary files a/source-linux/images/smileys/fantasy/ghost.gif and /dev/null differ diff --git a/source-linux/images/smileys/fantasy/mummy.gif b/source-linux/images/smileys/fantasy/mummy.gif deleted file mode 100644 index 50e1dfb..0000000 Binary files a/source-linux/images/smileys/fantasy/mummy.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/2guns.gif b/source-linux/images/smileys/fight/2guns.gif deleted file mode 100644 index 9e1b663..0000000 Binary files a/source-linux/images/smileys/fight/2guns.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/acid.gif b/source-linux/images/smileys/fight/acid.gif deleted file mode 100644 index fa55f67..0000000 Binary files a/source-linux/images/smileys/fight/acid.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/alienfight.gif b/source-linux/images/smileys/fight/alienfight.gif deleted file mode 100644 index 9d5e879..0000000 Binary files a/source-linux/images/smileys/fight/alienfight.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/alpha.png b/source-linux/images/smileys/fight/alpha.png deleted file mode 100644 index 09e3f23..0000000 Binary files a/source-linux/images/smileys/fight/alpha.png and /dev/null differ diff --git a/source-linux/images/smileys/fight/army.gif b/source-linux/images/smileys/fight/army.gif deleted file mode 100644 index 7506700..0000000 Binary files a/source-linux/images/smileys/fight/army.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/arrowhead.gif b/source-linux/images/smileys/fight/arrowhead.gif deleted file mode 100644 index f4572c4..0000000 Binary files a/source-linux/images/smileys/fight/arrowhead.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/bfg.gif b/source-linux/images/smileys/fight/bfg.gif deleted file mode 100644 index c2ba9d0..0000000 Binary files a/source-linux/images/smileys/fight/bfg.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/bowman.gif b/source-linux/images/smileys/fight/bowman.gif deleted file mode 100644 index 2f1f8f0..0000000 Binary files a/source-linux/images/smileys/fight/bowman.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/chainsaw.gif b/source-linux/images/smileys/fight/chainsaw.gif deleted file mode 100644 index 71f757c..0000000 Binary files a/source-linux/images/smileys/fight/chainsaw.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/crossbow.gif b/source-linux/images/smileys/fight/crossbow.gif deleted file mode 100644 index 20874f3..0000000 Binary files a/source-linux/images/smileys/fight/crossbow.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/crusader.gif b/source-linux/images/smileys/fight/crusader.gif deleted file mode 100644 index 95848ae..0000000 Binary files a/source-linux/images/smileys/fight/crusader.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/dead.gif b/source-linux/images/smileys/fight/dead.gif deleted file mode 100644 index 31adaba..0000000 Binary files a/source-linux/images/smileys/fight/dead.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/gangs.gif b/source-linux/images/smileys/fight/gangs.gif deleted file mode 100644 index 2c655b1..0000000 Binary files a/source-linux/images/smileys/fight/gangs.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/hammersplat.gif b/source-linux/images/smileys/fight/hammersplat.gif deleted file mode 100644 index 95bd540..0000000 Binary files a/source-linux/images/smileys/fight/hammersplat.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/lasergun.gif b/source-linux/images/smileys/fight/lasergun.gif deleted file mode 100644 index f3f82cb..0000000 Binary files a/source-linux/images/smileys/fight/lasergun.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/machinegun.gif b/source-linux/images/smileys/fight/machinegun.gif deleted file mode 100644 index 1cff5cc..0000000 Binary files a/source-linux/images/smileys/fight/machinegun.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/marine.gif b/source-linux/images/smileys/fight/marine.gif deleted file mode 100644 index 88fd2e0..0000000 Binary files a/source-linux/images/smileys/fight/marine.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/sabre.gif b/source-linux/images/smileys/fight/sabre.gif deleted file mode 100644 index e623968..0000000 Binary files a/source-linux/images/smileys/fight/sabre.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/samurai.gif b/source-linux/images/smileys/fight/samurai.gif deleted file mode 100644 index 8b24385..0000000 Binary files a/source-linux/images/smileys/fight/samurai.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/tank.gif b/source-linux/images/smileys/fight/tank.gif deleted file mode 100644 index f1d969d..0000000 Binary files a/source-linux/images/smileys/fight/tank.gif and /dev/null differ diff --git a/source-linux/images/smileys/fight/viking.gif b/source-linux/images/smileys/fight/viking.gif deleted file mode 100644 index 4908edd..0000000 Binary files a/source-linux/images/smileys/fight/viking.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/apple.gif b/source-linux/images/smileys/food/apple.gif deleted file mode 100644 index 969d4ca..0000000 Binary files a/source-linux/images/smileys/food/apple.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/banana.gif b/source-linux/images/smileys/food/banana.gif deleted file mode 100644 index d990d19..0000000 Binary files a/source-linux/images/smileys/food/banana.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/birthdaycake.gif b/source-linux/images/smileys/food/birthdaycake.gif deleted file mode 100644 index 30ebceb..0000000 Binary files a/source-linux/images/smileys/food/birthdaycake.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/broccoli.gif b/source-linux/images/smileys/food/broccoli.gif deleted file mode 100644 index f379889..0000000 Binary files a/source-linux/images/smileys/food/broccoli.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/cake.gif b/source-linux/images/smileys/food/cake.gif deleted file mode 100644 index 22d0ebd..0000000 Binary files a/source-linux/images/smileys/food/cake.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/carrot.gif b/source-linux/images/smileys/food/carrot.gif deleted file mode 100644 index 387b94c..0000000 Binary files a/source-linux/images/smileys/food/carrot.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/cooking.gif b/source-linux/images/smileys/food/cooking.gif deleted file mode 100644 index e62fea0..0000000 Binary files a/source-linux/images/smileys/food/cooking.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/fryegg.gif b/source-linux/images/smileys/food/fryegg.gif deleted file mode 100644 index bd1b4ff..0000000 Binary files a/source-linux/images/smileys/food/fryegg.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/popcorn.gif b/source-linux/images/smileys/food/popcorn.gif deleted file mode 100644 index b0ea697..0000000 Binary files a/source-linux/images/smileys/food/popcorn.gif and /dev/null differ diff --git a/source-linux/images/smileys/food/tomato.gif b/source-linux/images/smileys/food/tomato.gif deleted file mode 100644 index 0e3dadd..0000000 Binary files a/source-linux/images/smileys/food/tomato.gif and /dev/null differ diff --git a/source-linux/images/smileys/happy/cloud9.gif b/source-linux/images/smileys/happy/cloud9.gif deleted file mode 100644 index 801c1a3..0000000 Binary files a/source-linux/images/smileys/happy/cloud9.gif and /dev/null differ diff --git a/source-linux/images/smileys/happy/tearsofjoy.gif b/source-linux/images/smileys/happy/tearsofjoy.gif deleted file mode 100644 index 5de3117..0000000 Binary files a/source-linux/images/smileys/happy/tearsofjoy.gif and /dev/null differ diff --git a/source-linux/images/smileys/laugh/hahaha.gif b/source-linux/images/smileys/laugh/hahaha.gif deleted file mode 100644 index 37aa92a..0000000 Binary files a/source-linux/images/smileys/laugh/hahaha.gif and /dev/null differ diff --git a/source-linux/images/smileys/laugh/loltv.gif b/source-linux/images/smileys/laugh/loltv.gif deleted file mode 100644 index 3de6f77..0000000 Binary files a/source-linux/images/smileys/laugh/loltv.gif and /dev/null differ diff --git a/source-linux/images/smileys/laugh/rofl.gif b/source-linux/images/smileys/laugh/rofl.gif deleted file mode 100644 index a3bb03d..0000000 Binary files a/source-linux/images/smileys/laugh/rofl.gif and /dev/null differ diff --git a/source-linux/images/smileys/love/iloveyou.gif b/source-linux/images/smileys/love/iloveyou.gif deleted file mode 100644 index 7007515..0000000 Binary files a/source-linux/images/smileys/love/iloveyou.gif and /dev/null differ diff --git a/source-linux/images/smileys/love/inlove.gif b/source-linux/images/smileys/love/inlove.gif deleted file mode 100644 index 30357af..0000000 Binary files a/source-linux/images/smileys/love/inlove.gif and /dev/null differ diff --git a/source-linux/images/smileys/love/love.gif b/source-linux/images/smileys/love/love.gif deleted file mode 100644 index d8f0d5b..0000000 Binary files a/source-linux/images/smileys/love/love.gif and /dev/null differ diff --git a/source-linux/images/smileys/love/lovebear.gif b/source-linux/images/smileys/love/lovebear.gif deleted file mode 100644 index d13fd18..0000000 Binary files a/source-linux/images/smileys/love/lovebear.gif and /dev/null differ diff --git a/source-linux/images/smileys/love/lovebed.gif b/source-linux/images/smileys/love/lovebed.gif deleted file mode 100644 index c5783e0..0000000 Binary files a/source-linux/images/smileys/love/lovebed.gif and /dev/null differ diff --git a/source-linux/images/smileys/love/loveheart.gif b/source-linux/images/smileys/love/loveheart.gif deleted file mode 100644 index 541220a..0000000 Binary files a/source-linux/images/smileys/love/loveheart.gif and /dev/null differ diff --git a/source-linux/images/smileys/music/dj.gif b/source-linux/images/smileys/music/dj.gif deleted file mode 100644 index 66bc075..0000000 Binary files a/source-linux/images/smileys/music/dj.gif and /dev/null differ diff --git a/source-linux/images/smileys/music/drums.gif b/source-linux/images/smileys/music/drums.gif deleted file mode 100644 index 27215f4..0000000 Binary files a/source-linux/images/smileys/music/drums.gif and /dev/null differ diff --git a/source-linux/images/smileys/music/elvis.gif b/source-linux/images/smileys/music/elvis.gif deleted file mode 100644 index ebcdccc..0000000 Binary files a/source-linux/images/smileys/music/elvis.gif and /dev/null differ diff --git a/source-linux/images/smileys/music/guitar.gif b/source-linux/images/smileys/music/guitar.gif deleted file mode 100644 index 11eccdd..0000000 Binary files a/source-linux/images/smileys/music/guitar.gif and /dev/null differ diff --git a/source-linux/images/smileys/music/trumpet.gif b/source-linux/images/smileys/music/trumpet.gif deleted file mode 100644 index 4595ccc..0000000 Binary files a/source-linux/images/smileys/music/trumpet.gif and /dev/null differ diff --git a/source-linux/images/smileys/music/violin.gif b/source-linux/images/smileys/music/violin.gif deleted file mode 100644 index 53592d6..0000000 Binary files a/source-linux/images/smileys/music/violin.gif and /dev/null differ diff --git a/source-linux/images/smileys/oldcore/beard.png b/source-linux/images/smileys/oldcore/beard.png deleted file mode 100644 index 5d4b284..0000000 Binary files a/source-linux/images/smileys/oldcore/beard.png and /dev/null differ diff --git a/source-linux/images/smileys/oldcore/headbang.gif b/source-linux/images/smileys/oldcore/headbang.gif deleted file mode 100644 index 91ccb8b..0000000 Binary files a/source-linux/images/smileys/oldcore/headbang.gif and /dev/null differ diff --git a/source-linux/images/smileys/oldcore/laughing.gif b/source-linux/images/smileys/oldcore/laughing.gif deleted file mode 100644 index 1bf29de..0000000 Binary files a/source-linux/images/smileys/oldcore/laughing.gif and /dev/null differ diff --git a/source-linux/images/smileys/oldcore/shaka.gif b/source-linux/images/smileys/oldcore/shaka.gif deleted file mode 100644 index e5d7b70..0000000 Binary files a/source-linux/images/smileys/oldcore/shaka.gif and /dev/null differ diff --git a/source-linux/images/smileys/oldcore/surprised.gif b/source-linux/images/smileys/oldcore/surprised.gif deleted file mode 100644 index b074653..0000000 Binary files a/source-linux/images/smileys/oldcore/surprised.gif and /dev/null differ diff --git a/source-linux/images/smileys/oldcore/whitebeard.png b/source-linux/images/smileys/oldcore/whitebeard.png deleted file mode 100644 index 2a1fccb..0000000 Binary files a/source-linux/images/smileys/oldcore/whitebeard.png and /dev/null differ diff --git a/source-linux/images/smileys/respect/bow.gif b/source-linux/images/smileys/respect/bow.gif deleted file mode 100644 index ecc6484..0000000 Binary files a/source-linux/images/smileys/respect/bow.gif and /dev/null differ diff --git a/source-linux/images/smileys/respect/bravo.gif b/source-linux/images/smileys/respect/bravo.gif deleted file mode 100644 index 34f72ab..0000000 Binary files a/source-linux/images/smileys/respect/bravo.gif and /dev/null differ diff --git a/source-linux/images/smileys/respect/hailking.gif b/source-linux/images/smileys/respect/hailking.gif deleted file mode 100644 index 07551e5..0000000 Binary files a/source-linux/images/smileys/respect/hailking.gif and /dev/null differ diff --git a/source-linux/images/smileys/respect/number1.gif b/source-linux/images/smileys/respect/number1.gif deleted file mode 100644 index ab5c410..0000000 Binary files a/source-linux/images/smileys/respect/number1.gif and /dev/null differ diff --git a/source-linux/images/smileys/sad/crying.png b/source-linux/images/smileys/sad/crying.png deleted file mode 100644 index 62b9646..0000000 Binary files a/source-linux/images/smileys/sad/crying.png and /dev/null differ diff --git a/source-linux/images/smileys/sad/prisoner.gif b/source-linux/images/smileys/sad/prisoner.gif deleted file mode 100644 index f2c3181..0000000 Binary files a/source-linux/images/smileys/sad/prisoner.gif and /dev/null differ diff --git a/source-linux/images/smileys/sad/sigh.gif b/source-linux/images/smileys/sad/sigh.gif deleted file mode 100644 index 6860226..0000000 Binary files a/source-linux/images/smileys/sad/sigh.gif and /dev/null differ diff --git a/source-linux/images/smileys/smoking/smoking.gif b/source-linux/images/smileys/smoking/smoking.gif deleted file mode 100644 index 77720b1..0000000 Binary files a/source-linux/images/smileys/smoking/smoking.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/archery.gif b/source-linux/images/smileys/sport/archery.gif deleted file mode 100644 index 8b4b9f6..0000000 Binary files a/source-linux/images/smileys/sport/archery.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/basketball.gif b/source-linux/images/smileys/sport/basketball.gif deleted file mode 100644 index e9ad4b5..0000000 Binary files a/source-linux/images/smileys/sport/basketball.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/bowling.gif b/source-linux/images/smileys/sport/bowling.gif deleted file mode 100644 index 0f8300c..0000000 Binary files a/source-linux/images/smileys/sport/bowling.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/cycling.gif b/source-linux/images/smileys/sport/cycling.gif deleted file mode 100644 index 332081e..0000000 Binary files a/source-linux/images/smileys/sport/cycling.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/darts.gif b/source-linux/images/smileys/sport/darts.gif deleted file mode 100644 index 09fb6ea..0000000 Binary files a/source-linux/images/smileys/sport/darts.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/fencing.gif b/source-linux/images/smileys/sport/fencing.gif deleted file mode 100644 index a4ec5cd..0000000 Binary files a/source-linux/images/smileys/sport/fencing.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/football.gif b/source-linux/images/smileys/sport/football.gif deleted file mode 100644 index c9fa6c5..0000000 Binary files a/source-linux/images/smileys/sport/football.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/golf.gif b/source-linux/images/smileys/sport/golf.gif deleted file mode 100644 index 179fc52..0000000 Binary files a/source-linux/images/smileys/sport/golf.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/horseriding.gif b/source-linux/images/smileys/sport/horseriding.gif deleted file mode 100644 index 13ca450..0000000 Binary files a/source-linux/images/smileys/sport/horseriding.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/juggling.gif b/source-linux/images/smileys/sport/juggling.gif deleted file mode 100644 index 1a2eb60..0000000 Binary files a/source-linux/images/smileys/sport/juggling.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/skipping.gif b/source-linux/images/smileys/sport/skipping.gif deleted file mode 100644 index f63270b..0000000 Binary files a/source-linux/images/smileys/sport/skipping.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/snooker.gif b/source-linux/images/smileys/sport/snooker.gif deleted file mode 100644 index fa2e6a8..0000000 Binary files a/source-linux/images/smileys/sport/snooker.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/surfing.gif b/source-linux/images/smileys/sport/surfing.gif deleted file mode 100644 index b75d74b..0000000 Binary files a/source-linux/images/smileys/sport/surfing.gif and /dev/null differ diff --git a/source-linux/images/smileys/sport/tennis.gif b/source-linux/images/smileys/sport/tennis.gif deleted file mode 100644 index 36e47bf..0000000 Binary files a/source-linux/images/smileys/sport/tennis.gif and /dev/null differ diff --git a/source-linux/images/smileys/tired/countsheep.gif b/source-linux/images/smileys/tired/countsheep.gif deleted file mode 100644 index 815b090..0000000 Binary files a/source-linux/images/smileys/tired/countsheep.gif and /dev/null differ diff --git a/source-linux/images/smileys/tired/hammock.gif b/source-linux/images/smileys/tired/hammock.gif deleted file mode 100644 index 8639dd3..0000000 Binary files a/source-linux/images/smileys/tired/hammock.gif and /dev/null differ diff --git a/source-linux/images/smileys/tired/pillow.gif b/source-linux/images/smileys/tired/pillow.gif deleted file mode 100644 index 367f65e..0000000 Binary files a/source-linux/images/smileys/tired/pillow.gif and /dev/null differ diff --git a/source-linux/images/smileys/tired/yawn.gif b/source-linux/images/smileys/tired/yawn.gif deleted file mode 100644 index d451480..0000000 Binary files a/source-linux/images/smileys/tired/yawn.gif and /dev/null differ diff --git a/source-linux/js/image.js b/source-linux/js/image.js deleted file mode 100644 index b05bf08..0000000 --- a/source-linux/js/image.js +++ /dev/null @@ -1,290 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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 . - -.pragma library -.import QtQuick.LocalStorage 2.0 as Sql -.import "qrc:/js/helper.js" as Helperjs - -function requestList(login,database,onlynew,rootwindow,callback) { - //get list of own images and call download function - Helperjs.friendicaRequest(login,"/api/friendica/photos/list", rootwindow,function (helperobject){ - //print("return"+helperobject); - var obj=JSON.parse(helperobject); - if (onlynew){Helperjs.readField("id",database,"imageData",login.username,function(AllStoredImages){ - if (AllStoredImages.length>0){ - for(var i=0;i< AllStoredImages.length;i++){ - var position=Helperjs.inArray(obj,"id",AllStoredImages[i]); - if (position>-1){obj.splice(position,1)} - } - } - callback(obj) - })} - else{callback(obj)} -})} - -function dataRequest(login,photoID,database,xhr,rootwindow) { - // check if image exist and call download function - Helperjs.friendicaRequest(login,"/api/friendica/photo?photo_id="+photoID, rootwindow, function (image){ - try{ if(image==""){currentimageno=currentimageno+1}else{ - var obj = JSON.parse(image); - var helpfilename=obj.filename.substring(0,obj.filename.lastIndexOf(".")); - var filesuffix=""; - if (obj.type=="image/jpeg"){filesuffix=".jpg"} - else if (obj.type=="image/png"){filesuffix=".png"} - else {filesuffix=""} - if (helpfilename==""){// check if file has any filename - obj.filename=obj["id"]+filesuffix; - } - else{obj.filename=helpfilename+filesuffix} - var link=""; - if(obj["link"][0]){link=obj["link"][0]} else{link=obj["link"]["4"]} - xhr.setUrl(Qt.resolvedUrl(link)); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setFilename(login.imagestore+'albums/'+obj.album+"/"+obj["filename"]); - xhr.setDownloadtype("picture"); - xhr.download(); - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - db.transaction( function(tx) { - var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"'); - if(result.rows.length === 1) {// use update - result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+obj.id+'", created="'+obj.created+'", edited="'+obj.edited+'", profile="'+obj.profile+'", link="'+obj["link"]["4"]+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", location="file://'+login.imagestore+'albums/'+obj.album+'/" where id="'+obj["id"]+'"'); - } else {// use insert print('... does not exists, create it') - result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,obj.id,obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width,obj. profile,obj["link"]["4"],'file://'+login.imagestore+'albums/'+obj.album+"/"]); - } - })}} - catch (e){print("Data retrieval failure! "+ e+obj);} -})} - -function storeImagedata(login,database,imagedata,rootwindow) { - // check if image exist and call download function - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - db.transaction( function(tx) { - var result = tx.executeSql('SELECT * from imageData where id = "'+imagedata["id"]+'"'); - if(result.rows.length === 1) {// use update - result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+imagedata.id+'", created="'+imagedata.created+'", edited="'+imagedata.edited+'", profile="'+imagedata.profile+'", link="'+imagedata.link[0]+'", filename="'+imagedata.filename+'",title="'+imagedata.title+'", desc="'+imagedata.desc+'", type="'+imagedata.type+'", width="'+imagedata.width+'", height="'+imagedata.height+'", album="'+imagedata.album+'", location="file://'+login.imagestore+'albums/'+imagedata.album+'/" where id="'+imagedata["id"]+'"'); - } else {// use insert print('... does not exists, create it') - result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,imagedata.id,imagedata.created,imagedata.edited, imagedata.title, imagedata.desc, imagedata.album, imagedata.filename, imagedata.type, imagedata.height, imagedata.width,imagedata. profile,imagedata.link[0],'file://'+login.imagestore+'albums/'+imagedata.album+"/"]); - } -})} - -function deleteImage(database,login,type,location,filesystem,rootwindow,callback) { // delete image locally and on server - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - var rsfilename=location.substring(location.lastIndexOf("/")+1,location.length); - var rslocation=location.substring(0,location.lastIndexOf("/")+1); - //print(type+" Name "+ rsfilename+" Location: "+rslocation) - db.transaction( function(tx) { - if (type=='image'){ - var rs= tx.executeSql('SELECT * FROM imageData WHERE filename="'+rsfilename+'" AND location="'+rslocation+'"') - var imageId=rs.rows.item(0).id; - Helperjs.friendicaPostRequest(login,"/api/friendica/photo/delete?photo_id="+imageId,"","DELETE",rootwindow, function (obj){ - //var deletereturn = JSON.parse(obj); print(obj); - //if (deletereturn.result=="deleted"){ - db.transaction( function(tx) { - var deleters=tx.executeSql('DELETE FROM imageData WHERE location="'+rslocation+'" AND filename="'+rsfilename+'"'); }); - filesystem.Directory=rslocation.substring(7,rslocation.length-1); - filesystem.rmFile(rsfilename) - //} - }) - } - else{ - Helperjs.friendicaPostRequest(login,"/api/friendica/photoalbum/delete?album="+rsfilename,"","DELETE",rootwindow, function (obj){ - //var deletereturn = JSON.parse(obj); - //if (deletereturn.result=="deleted"){ - db.transaction( function(tx) { - var rs= tx.executeSql('SELECT DISTINCT location FROM imageData WHERE album="'+rsfilename+'" AND username="'+login.username+'"'); - var locationstring=rs.rows.item(0).location; - filesystem.Directory=locationstring.substring(7,locationstring.length-1); - filesystem.rmDir(); - var deleters=tx.executeSql('DELETE FROM imageData WHERE album="'+location+'"'); - }) - //} - }) - } - callback(location) - }) -} - -function updateImage(database,login,type,filesystem,imageId,rootwindow,callback) { // delete image locally and on server - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - Helperjs.readData(database,"imageData",login.username,function(obj){ - db.transaction( function(tx) { - if (type=='image'){ - var deleters=tx.executeSql('DELETE FROM imageData WHERE location="'+obj[0].location+'" AND filename="'+obj[0].filename+'"'); - filesystem.Directory=obj[0].location - filesystem.rmFile(obj[0].filename) - } - }) - },"id",imageId); - callback() -} - - -function deleteContacts(database,user,callback) { // does nothing useful at the moment - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - //print(' delete Image Data() for ' + field +"="+selection) - db.transaction( function(tx) { - result1= tx.executeSql('SELECT * FROM contacts a LEFT OUTER JOIN news b ON a.url==b.uid'); - result2= tx.executeSql('SELECT * FROM contacts a LEFT OUTER JOIN news b ON a.url==b.uid'); - callback(result)}) -} - -//function requestFriendsAlbumPictures(login,friend,rootwindow,callback){ -//// screenscraping of albums page of contact without user and password -// Helperjs.friendicaWebRequest(friend.url.replace("profile","photos"),rootwindow,function(photohtml){ -// //print(photohtml); -// var photoarray=[]; -// var arr = photohtml.split("sidebar-photos-albums-li"); -// for (var i=2;i')-1); -// var album={'link':albumlink,'name':albumname} -// photoarray.push(album); -// } -// callback(photoarray) -// }) -//} - -function newRequestFriendsAlbumPictures(login,friend,rootwindow,callback){//print("newRequestFriendsAlbumPictures"); -// screenscraping of albums page of contact with remoteAuth - //commented out for broken remoteauth - Helperjs.friendicaRemoteAuthRequest(login,friend.url.replace("profile","photos"),friend.url,rootwindow,function(photohtml){ - //Helperjs.friendicaWebRequest(friend.url.replace("profile","photos"),rootwindow,function(photohtml){ - try {var obj=JSON.parse(photohtml);//print ("Photohtml: "+photohtml) - if (obj.hasOwnProperty('status')){ - Helperjs.friendicaWebRequest(friend.url.replace("profile","photos"),rootwindow,function(photohtml){ - getAlbumFromHtml(photohtml,false,rootwindow,callback)}) - }} - catch (e){ - //getAlbumFromHtml(photohtml,true,rootwindow,callback) - getAlbumFromHtml(photohtml,false,rootwindow,callback) - } - }) -} - -function getAlbumFromHtml(photohtml,remoteAuthBool,rootwindow,callback){ - //print(photohtml); - var photoarray=[]; - var arr = photohtml.split("sidebar-photos-albums-li"); - for (var i=2;i')-1); - var album={'link':albumlink,'name':albumname}//print(albumlink+" "+albumname); - photoarray.push(album); - } - callback(photoarray,remoteAuthBool) -} - - -function newRequestFriendsPictures(login,link,friend,remoteAuthBool,remoteauth,rootwindow,callback){ -// screenscraping of pictures page for given album - if (remoteAuthBool){ - remoteauth.setUrl(login.server); - remoteauth.setLogin(login.username+":"+Qt.atob(login.password)); - remoteauth.setContacturl(friend.url); - Helperjs.friendicaRemoteAuthRequest(login,link,friend.url,rootwindow,function(photohtml){ - getPictureFromHtml(photohtml,remoteAuthBool,function(photoarray){ - callback(photoarray) - }) - })} - else{ - Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){ - getPictureFromHtml(photohtml,remoteAuthBool,function(photoarray){ - callback(photoarray) - }) - }) - } -} - -function getPictureFromHtml(photohtml,remoteAuthBool,callback){ - var photoarray=[]; - var basehtml=photohtml.substring(photohtml.indexOf('',photohtml.indexOf('-1){ //theme 1 - var arr = photohtml.split("photo-album-image-wrapper-end");} - -// other themes - if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2 - var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end")) - var arr = photoarea.split("");} - //print("Url: "+login.server+ "Contacturl: "+friend.url) -// remoteauth.setUrl(login.server); -// remoteauth.setLogin(login.username+":"+Qt.atob(login.password)); -// remoteauth.setContacturl(friend.url); - for (var i=0;i-1){ //theme 1 - var arr = photohtml.split("photo-album-image-wrapper-end");} - -// other themes - if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2 - var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end")) - var arr = photoarea.split("");} - - for (var i=0;i -// -// 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 . - -function showFriends(db) { - Service.readActiveConfig(db,function(login){ - Service.requestFriends(login.url,login.user,login.password,displayFriends); - }); -} -function displayFriends(obj){ - for (var i=0; i= c.x) - f.contentX = c.x; - else if (f.contentX+f.width <= c.x+c.width) - f.contentX = c.x+c.width-f.width; - if (f.contentY >= c.y) - f.contentY = c.y; - else if (f.contentY+f.height <= c.y+c.height) - f.contentY = c.y+c.height-f.height; -} - -function createObject(objectQml,qmlParameters,parentitem,callback) { - var component = Qt.createComponent(objectQml); - if (component.status === Component.Ready || component.status === Component.Error) - finishCreation(component,qmlParameters,parentitem,callback); - else - component.statusChanged.connect(finishCreation(qmlParameters)); -} - -function finishCreation(component,qmlParameters,parentitem,callback) { - if (component.status === Component.Ready) { - var createdObject = component.createObject(parentitem, qmlParameters); - if (createdObject === null) - print("Error creating image"); } - else if (component.status === Component.Error) - print("Error loading component:"+component.errorString()); - else {print("created")} - //callback(createdObject); -} - diff --git a/source-linux/js/newsworker.js b/source-linux/js/newsworker.js deleted file mode 100644 index 8a85169..0000000 --- a/source-linux/js/newsworker.js +++ /dev/null @@ -1,178 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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 . - -function findend (text, startpos) { - var indexOf = text.substring(startpos || 0).search(/\s/); - return (indexOf >= 0) ? (indexOf + (startpos || 0)) : text.length; -} - -function beautify(newsitemobject,msg){ - var forumname=""; - try{ - if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_author')&& - ((newsitemobject.friendica_author.url)!=(newsitemobject.user.url))&&((newsitemobject.friendica_author.url)!=null)){ - //print(" Friendica Author "+JSON.stringify(newsitemobject)); - forumname=" via "+newsitemobject.user.name; - newsitemobject.user=newsitemobject.friendica_author; - } - if (typeof(newsitemobject.friendica_activities_self)=="string"){ - newsitemobject.friendica_activities_self=JSON.parse(newsitemobject.friendica_activities_self); - } - }catch(e){print("forum name "+e)} - - var self=({}) - if (newsitemobject.hasOwnProperty("friendica_activities_self")){ - if (newsitemobject.friendica_activities_self.indexOf(3)!=-1){self.attending=qsTr("yes")} - if (newsitemobject.friendica_activities_self.indexOf(4)!=-1){self.attending=qsTr("no")} - if (newsitemobject.friendica_activities_self.indexOf(5)!=-1){self.attending=qsTr("maybe")} - if (newsitemobject.friendica_activities_self.indexOf(1)!=-1){self.liked=1} - if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1} - } - var friendica_activities={self:self} - var imageAttachmentList=[]; - var videoAttachmentList=[]; - var videoformats=["mp4", "avi", "webm","ogg","mp3"] - try{if(newsitemobject.attachments){ - var attachArray=newsitemobject.attachments; - for (var image in attachArray){ - var attachhelper={mimetype:attachArray[image].mimetype} - var attachhelperstring=Qt.btoa(attachArray[image].url) - var helperstringposition=newsitemobject.statusnet_html.indexOf(attachhelperstring); - if (helperstringposition>-1){attachhelper.url=newsitemobject.statusnet_html.substring(newsitemobject.statusnet_html.lastIndexOf("http",helperstringposition),helperstringposition+attachhelperstring.length); - if (attachArray[image].mimetype=="image/jpeg"){attachhelper.url=attachhelper.url+".jpg"} - else if (attachArray[image].mimetype=="image/gif"){attachhelper.url=attachhelper.url+".gif"} - else if (attachArray[image].mimetype=="image/png"){attachhelper.url=attachhelper.url+".png"} - } - else {attachhelper.url=attachArray[image].url} - - //print("Attachhelper "+attachhelper.url) - newsitemobject.statusnet_html=newsitemobject.statusnet_html.replace(attachhelper.url,"") - newsitemobject.statusnet_html=newsitemobject.statusnet_html.replace(attachhelper.url.substring(0,attachhelper.url.length-4)+".jpeg","") - newsitemobject.statusnet_html=newsitemobject.statusnet_html.replace(attachhelper.url.substring(0,attachhelper.url.length-4),"") - - imageAttachmentList.push(attachhelper) - } - } - }catch(e){print("attachment "+e)} - for (var format in videoformats){ - if (newsitemobject.text.indexOf("."+videoformats[format])>-1){ - var videohelper={mimetype:"video/"+videoformats[format]} - var videotext=newsitemobject.text; - while (videotext.indexOf("."+videoformats[format])>-1){ - var videohelperstringposition=videotext.indexOf("."+videoformats[format]); - videohelper.url=videotext.substring(videotext.lastIndexOf("http",videohelperstringposition),videohelperstringposition+4); - videotext=videotext.substring(videohelperstringposition+4,videotext.length) - if ((videoAttachmentList.length==0) || (videoAttachmentList[videoAttachmentList.length-1].url!=videohelper.url)){videoAttachmentList.push(videohelper)} - } - } - } - if (newsitemobject.text.indexOf("/videos/watch/")>-1){ - var ptvideohelper={mimetype:"video/mp4"} - var ptvideotext=newsitemobject.text; - while (ptvideotext.indexOf("/videos/watch/")>-1){ - var ptvideohelperstringposition=ptvideotext.indexOf("/videos/watch/"); - var ptposend=findend(ptvideotext,ptvideohelperstringposition); - if(ptposend==-1){ptposend=ptvideotext.length}; - ptvideohelper.url=ptvideotext.substring(ptvideotext.lastIndexOf("http",ptvideohelperstringposition),ptposend)+"-480.mp4"; - ptvideohelper.url=ptvideohelper.url.replace("/videos/watch","/static/webseed"); - ptvideotext=ptvideotext.substring(ptposend,ptvideotext.length) - if ((videoAttachmentList.length==0) || (videoAttachmentList[videoAttachmentList.length-1].url!=ptvideohelper.url)){videoAttachmentList.push(ptvideohelper)} - } - } - if (newsitemobject.text.indexOf("youtube.com/watch?v")>-1){ - var yttext=newsitemobject.text; - while (yttext.indexOf("youtube.com/watch?v")>-1){ - var ythelperstringposition=yttext.indexOf("watch?v="); - var ytposend=findend(yttext,ythelperstringposition); - var ythelper={mimetype:"video/youtube"} - ythelper.url=yttext.substring(ythelperstringposition+8,ytposend); - yttext=yttext.substring(ytposend,yttext.length); - if ((videoAttachmentList.length==0) || (videoAttachmentList[videoAttachmentList.length-1].url!=ythelper.url)){videoAttachmentList.push(ythelper)} - } - } - newsitemobject.videoAttachmentList=videoAttachmentList; - newsitemobject.imageAttachmentList=imageAttachmentList; - if ((msg.options.hasOwnProperty("hide_nsfw"))&&(msg.options.hide_nsfw==1)&&(newsitemobject.text.indexOf("#nsfw")>-1)){ - newsitemobject.nsfw=true - } else{newsitemobject.nsfw=false} - - newsitemobject.dateDiff=(msg.currentTime-newsitemobject.created_at)/1000; - newsitemobject.friendica_activities_view=friendica_activities; - newsitemobject.forumname=forumname; - return newsitemobject; -} - - - -WorkerScript.onMessage = function(msg) { -if(msg.deleteId!==undefined) - {msg.model.remove(msg.deleteId); - msg.model.sync() -} -else{ - if(msg.method=="refresh" ||(msg.method=="conversation"&&msg.news.length>0)){msg.model.clear()}; - msg.model.sync() - for (var j=0;j1)){ - newsitemobject.lastcomment=beautify(newsitemobject.currentconversation[newsitemobject.currentconversation.length-1],msg); - newsitemobject.lastcomment.indent=1 - //print("Currentconversation" + newsitemobject.currentconversation.length+JSON.stringify(newsitemobject.lastcomment)) - } - - if (msg.method=="conversation"){ - if (j==0){newsitemobject.indent=0}else{ - for (var k=msg.model.count-1;k>-1;k--){ - if (newsitemobject.in_reply_to_status_id==msg.model.get(k).newsitemobject.id){ - newsitemobject.indent=(msg.model.get(k).newsitemobject.indent||0)+1; - if (newsitemobject.indent>6){newsitemobject.indent=6}; - } - } - }} - - var data=({"newsitemobject": newsitemobject}) - } - - if(msg.method=="append") { - msg.model.insert(j, data)} - else{ - msg.model.append(data) - } - } - - if (j==msg.news.length){ - msg.model.sync() - } -} -} diff --git a/source-linux/js/service.js b/source-linux/js/service.js deleted file mode 100644 index b15338b..0000000 --- a/source-linux/js/service.js +++ /dev/null @@ -1,711 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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 . - -//.pragma library -.import QtQuick.LocalStorage 2.0 as Sql -.import "qrc:/js/helper.js" as Helperjs -.import "qrc:/js/news.js" as Newsjs - -// CONFIG FUNCTIONS - -function initDatabase(database) { // initialize the database object - var db =Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - //print('initDatabase()'+database[0]+database[1]+database[2]+database[3]) - db.transaction( function(tx) { - //var version=tx.executeSql('PRAGMA user_version');print(JSON.stringify(version.rows.item(0))) - tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(username TEXT,id INT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, profile INT, link TEXT,location TEXT)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT, imagestore TEXT, maxnews INT, timerInterval INT, newsViewType TEXT,isActive INT, permissions TEXT,maxContactAge INT,APIVersion TEXT,layout TEXT, addons TEXT)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner TEXT)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT, timestamp INT)'); -// tx.executeSql('CREATE INDEX IF NOT EXISTS contact_id ON contacts(id)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS profiles(username TEXT, id INT, profiledata TEXT)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS events(username TEXT, id INT, start INT, end INT, allday INT, title TEXT, j INT, d TEXT, isFirst INT, uid INT, cid INT, uri TEXT, created INT, edited INT, desc TEXT, location TEXT, type TEXT, nofinish TEXT, adjust INT, ignore INT, permissions TEXT, guid INT, itemid INT, plink TEXT, authorName TEXT, authorAvatar TEXT, authorLink TEXT, html TEXT)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS globaloptions(k TEXT, v TEXT)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS friendshiprequests(username TEXT, id INT, usernamef TEXT, acct TEXT, display_name TEXT, locked TEXT, created_at INT, followers_count INT, following_count INT, statuses_count INT, note TEXT, url TEXT, avatar TEXT, avatar_static TEXT, header TEXT, header_static TEXT, emojis TEXT, moved TEXT, fields TEXT, bot TEXT, groupf TEXT, discoverable TEXT, last_status_at INT)'); - tx.executeSql('CREATE TABLE IF NOT EXISTS hashtags(username TEXT, tag TEXT,date INT, statuses TEXT, ownership INT )'); - tx.executeSql('CREATE TABLE IF NOT EXISTS drafts(username TEXT, header TEXT, statushtml TEXT, attachments TEXT, permissions TEXT, sendtime INT)'); - - })} - -function cleanPermissions(oldperms){ - var newperms=oldperms.replace("<","");newperms=newperms.replace(">","");newperms="["+newperms+"]"; - var newpermArray=JSON.parse(newperms); -return (newpermArray) -} - -function getEvents(database,login,rootwindow,callback){ -var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - Helperjs.friendicaWebRequest(login.server+"/cal/"+login.username+"/json",rootwindow,function(obj){ - //Helperjs.friendicaRemoteAuthRequest(login,login.server+"/cal/"+login.username+"/json",login.server+"/profile/"+login.username,rootwindow,function(obj){ - var events = JSON.parse(obj); - db.transaction( function(tx) { - for (var i=0;istartday){ - for (var j=startday+1;j0){ - for(var i = 0; i < rs.rows.length; i++) { - rsArray.push(rs.rows.item(i)) - } - var rsObject={server:rsArray[0].server,username:rsArray[0].username, password:rsArray[0].password,imagestore:rsArray[0].imagestore,isActive:rsArray[0].isActive, newsViewType:rsArray[0].newsViewType,permissions:JSON.parse(rsArray[0].permissions),maxContactAge:rsArray[0].maxContactAge,APIVersion:rsArray[0].APIVersion,addons:rsArray[0].addons}; - if (rsObject.newsViewType!="" && rsObject.newsViewType!=null){updateNewsviewtype(database,rsObject.newsViewType)} - } else {print("config empty");var rsObject=""} - callback(rsObject)}} - ) -} - -function readAllLogins(database,callback) { // reads config - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3],initDatabase(database)); - db.transaction( function(tx) { - var tables = tx.executeSql("SELECT * FROM sqlite_master WHERE type='table'"); - if (tables.rows.length==0){print("no database");callback("")} else { - var rs = tx.executeSql('select * from config'); - var rsArray=[]; - if (rs.rows.length>0){ - for(var i = 0; i < rs.rows.length; i++) { - rsArray.push(rs.rows.item(i)); - rsArray[i].permissions=JSON.parse(rsArray[i].permissions) - } - } - } - callback(rsArray)} - ) -} - -function readActiveConfig(database){ - var obj=""; - readConfig(database,function(config){obj=config},"isActive", 0); - return obj; -} - -function setDefaultOptions(database){ - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - db.transaction( function(tx) { - var rs = tx.executeSql('INSERT INTO globaloptions (k,v) VALUES ("newsViewType","Conversations")'); - }) -} - - -function readGlobaloptions(database,callback){ - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - var go=({}); - db.transaction( function(tx) { - var rs = tx.executeSql('select * from globaloptions'); - for (var r=0; r0){ maxnews=maxnewsrs.rows.item(0).v}; - for (var i=0; i<6;i++){ - if (i!=0){var maxnewsa=maxnews/5}else{maxnewsa=maxnews} - var newscountrs = tx.executeSql('SELECT COUNT(*) from news WHERE messagetype='+i); - var newscount = 0; - if (newscountrs.rows.length>0){newscount=newscountrs.rows.item(0)["COUNT(*)"]};//print(i+"newscount "+newscount) - if (newscount>maxnewsa){ - var lastvalidtimers= tx.executeSql('SELECT DISTINCT created_at FROM news WHERE messagetype='+i+' ORDER BY created_at ASC LIMIT ' +(newscount-maxnewsa)); - var lastvalidtime=lastvalidtimers.rows.item(newscount-maxnewsa-1).created_at; - var deleters = tx.executeSql('DELETE from news WHERE messagetype='+i+' AND created_at<='+lastvalidtime)} - } - callback() - }) - } - -function cleanContacts(login,database,callback){ - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - db.transaction( function(tx) { - var oldestnewsrs= tx.executeSql('SELECT created_at FROM news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY created_at ASC LIMIT 1'); - if (oldestnewsrs.rows.length>0){ var oldestnewsTime=oldestnewsrs.rows.item(0).created_at- 604800000;} else{var oldestnewsTime=0} //contacts can be 7 days old - //print(login.username+" älteste news: "+ oldestnewsTime); - var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge<'+oldestnewsTime); // check for friends - //print ("Contact result length: "+ result.rows.length) - for (var i=0;i0){tagcount=tagcountrs.rows.item(0)["COUNT(*)"]}; - if (tagcount>50){ - var lastvaliddaters= tx.executeSql('SELECT DISTINCT date FROM hashtags ORDER BY date ASC LIMIT ' +(tagcount-50)); - var lastvaliddate=lastvaliddaters.rows.item(tagcount-49).date; - var deleters = tx.executeSql('DELETE from hashtags WHERE date<='+lastvaliddate)} - callback() - }) - } - -function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab - var currentTime=Date.now(); - var image_timestamp=0; - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - db.transaction( function(tx) { - var imagename_helper=[]; - imagename_helper=contact.profile_image_url.split('?');//print("substring: "+JSON.stringify(imagename_helper)+imagename_helper[0].substring(imagename_helper[0].lastIndexOf("/")+1, imagename_helper[0].length)) - try {parseInt(image_timestamp=imagename_helper[1].substring(imagename_helper[1].indexOf("ts=")+3,imagename_helper[1].length))} catch(e){}; - var result; - result = tx.executeSql('SELECT * from contacts where username="'+login.username+'" AND url = "'+contact.url+'"'); // check for news url - if(result.rows.length === 1) {// use update - result = tx.executeSql('UPDATE contacts SET id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",imageAge='+currentTime+', profile_image_url="'+contact.profile_image_url+'", description="'+Qt.btoa(contact.description)+'", protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ contact.created_at+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+', timestamp='+ currentTime+' where username="'+login.username+'" AND url="'+contact.url+'"'); - } else {// use insert - result = tx.executeSql('INSERT INTO contacts VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,contact.id,Qt.btoa(contact.name),contact.screen_name,contact.location,currentTime,contact.profile_image_url, Qt.btoa(contact.description),"",contact.url,contact.protected,contact.followers_count, contact.friends_count,contact.created_at,contact.favorites_count,contact.utc_offset,contact.time_zone,contact.statuses_count,contact.following,contact.verfied,contact.statusnet_blocking,contact.notifications,contact.statusnet_profile_url,contact.cid,contact.network,isFriend,image_timestamp]);} - }); -} - -function processNews(api,data){ - try{var newslist=JSON.parse(data)} catch(e){newsBusy.running=false;}; - if (api=="/api/users/show"){ - var usermessages=[]; - usermessages.push(newslist.status); - newslist=usermessages; - } - if (data==""){} - else if (typeof(newslist)=='undefined'){ - Helperjs.showMessage(qsTr("Undefined Array Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root) - } - else if (newslist.hasOwnProperty('status')){ - Helperjs.showMessage(qsTr("JSON status Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root) - } - else if (!(Array.isArray(newslist))){ - replytimer.restart() - } - else { - var allcontacts=[]; - allcontacts=Newsjs.getAllContacts(db,login.username); - if (api=="/api/direct_messages/all" || api=="/api/direct_messages/conversation"){ - for (var n in newslist){ - newslist[n].created_at=Date.parse(Newsjs.cleanDate(newslist[n].created_at)); - newslist[n].messagetype=1; - newslist[n].source=" Friendica"; - newslist[n].status_id=newslist[n].id; - 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; - newslist[n].in_reply_to_user_id=newslist[n].recipient_id - if(newslist[n].in_reply_to_user_id){newslist[n].reply_user=Newsjs.objFromArray(allcontacts,"id",newslist[n].in_reply_to_user_id)} - }} - else if (api=="/api/friendica/notifications"){ - for (var n in newslist){ - newslist[n].created_at=Date.parse(newslist[n].date); - newslist[n].messagetype=2; - newslist[n].user=Newsjs.objFromArray(allcontacts,"url",newslist[n].url) - if (newslist[n].user==false){ - 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; - } - } - - - else {//if(api!="/api/statuses/user_timeline"){ - var chatlist=[]; - var conversationIds=[]; - var commentCount=[]; - - for (var n in newslist){ - if (newslist[n]!=null){ - newslist[n].created_at=Date.parse(Newsjs.cleanDate(newslist[n].created_at)); - 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].friendica_title!="") {newslist[n].statusnet_html=""+newslist[n].friendica_title +"

"+newslist[n].friendica_html;} - else{newslist[n].statusnet_html=newslist[n].friendica_html} - - if(newslist[n].in_reply_to_user_id){newslist[n].reply_user=Newsjs.objFromArray(allcontacts,"id",newslist[n].in_reply_to_user_id)} - if(newslist[n].hasOwnProperty('friendica_activities')){ - for (var m in newslist[n].friendica_activities.like){ - newslist[n].friendica_activities.like[m]=cleanUser(newslist[n].friendica_activities.like[m]); - } - for (var o in newslist[n].friendica_activities.dislike){ - newslist[n].friendica_activities.dislike[o]=cleanUser(newslist[n].friendica_activities.dislike[o]); - } - for (var p in newslist[n].friendica_activities.attendyes){ - newslist[n].friendica_activities.attendyes[p]=cleanUser(newslist[n].friendica_activities.attendyes[p]); - } - for (var q in newslist[n].friendica_activities.attendno){ - newslist[n].friendica_activities.attendno[q]=cleanUser(newslist[n].friendica_activities.attendno[q]); - } - for (var r in newslist[n].friendica_activities.attendmaybe){ - newslist[n].friendica_activities.attendmaybe[r]=cleanUser(newslist[n].friendica_activities.attendmaybe[r]); - } - } - if(!(newslist[n].hasOwnProperty('friendica_author'))){ - newslist[n].friendica_author=newslist[n].user - } - var conversationindex=conversationIds.indexOf(newslist[n].statusnet_conversation_id); - - //fill chatlist - if (conversationindex==-1){ - chatlist.push(newslist[n]); - conversationIds.push(newslist[n].statusnet_conversation_id); - commentCount.push(1); - } else{ - commentCount[conversationindex]=commentCount[conversationindex]+1; - chatlist[conversationindex]=newslist[n]; - } - } - } - //enrich chatlist with old entries - - for (var count in chatlist){ //print("chat "+JSON.stringify(chatlist[count])+" count: "+commentCount[count]) - //chatlist[count].newscount=commentCount[count] - if (chatlist[count].id_str!==chatlist[count].statusnet_conversation_id){ - try{ - Newsjs.oldchatfromdb(db,login.username,chatlist[count].statusnet_conversation_id,chatlist[count].id,allcontacts,function(oldpost,oldcount){ - chatlist[count]=oldpost; - chatlist[count].newscount=oldcount+commentCount[count]; - //print("JSON "+chatlist[count].statusnet_conversation_id+" "+chatlist[count].id+JSON.stringify(oldpost)) - }) - }catch(e){print(e)} - } - else{chatlist[count].newscount=commentCount[count]} - } - } - - if (api=="/api/conversation/show"|| api=="/api/direct_messages/conversation"){ - newslist.reverse(); - newstab.conversation=newslist - } - else if (api=="/api/statuses/user_timeline" || api=="/api/users/show"){ - root.contactposts=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","Replies"]; - if (newstabarray.indexOf(newstab.newstabstatus)>-1){contacttimer.start()} - } - -} - - -function cleanUser(user){ - user.created_at=Date.parse(Newsjs.cleanDate(user.created_at)); - var imagehelper1=user.profile_image_url.split("?"); - var imagehelper2=imagehelper1[0].substring(imagehelper1[0].lastIndexOf("/")+1,imagehelper1[0].length); - var imagehelper3=login.imagestore+"contacts/"+user.screen_name+"-"+imagehelper2 - if(filesystem.fileexist(imagehelper3)){user.profile_image=imagehelper3}else {user.profile_image=""} - return user -} - -function updateView(viewtype){ - //messageSend.state=""; - //newsBusy.running=true; - //downloadNotice.text="xhr start "+Date.now() - switch(viewtype){ - case "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)}); - break; - case "Timeline": - 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)); - xhr.setUrl(login.server); - xhr.setApi("/api/search"); - break; - case "Notifications": - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/friendica/notifications"); - xhr.clearParams(); - break; - case "Direct Messages": - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/direct_messages/all"); - xhr.clearParams(); - break; - case "Public Timeline": - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/public_timeline"); - xhr.clearParams(); - break; - case "Favorites": - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/favorites"); - xhr.clearParams(); - break; - case "Replies": - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/replies"); - xhr.clearParams(); - break; - default: - 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(); - if (viewtype==="Conversations"){Newsjs.allchatsfromdb(db,login.username,function(temp){ - newsStack.allchats=temp - })} - if ((osSettings.osType=="Android") && root.globaloptions.hasOwnProperty("syncinterval") && root.globaloptions.syncinterval !=null && root.globaloptions.syncinterval !=0){ - //alarm.setAlarm(root.globaloptions.syncinterval); - setBackgroundsync() - } -} - -function showGroups(){ - Helperjs.readData(db,"groups",login.username,function(groups){ - var groupitems=""; - for (var i=0;i0)&&((parseFloat(lastsync[0]["v"])+120)<(Date.now()/1000))){ - alarm.setAlarm(root.globaloptions.syncinterval); - } - },"k","lastsync") -} - -function getGroupnews(list){ - newstab.newstabstatus="Group news"; - newsBusy.running=true; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/lists/statuses"); - xhr.clearParams(); - xhr.setParam("list_id",list) - xhr.get(); -} diff --git a/source-linux/js/smiley.js b/source-linux/js/smiley.js deleted file mode 100644 index 86a66c9..0000000 --- a/source-linux/js/smiley.js +++ /dev/null @@ -1,631 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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 . - - -var html=[//Smileys - '\u263A', - '\u2639', - '\u263B', - //Weather - '\u2600', - '\u2601', - '\u263C', - '\u2614', - '\u2602', - '\u2603', - '\u2604', - '\u26C4', - '\u26C5', - '\u26C8', - //Leisure - '\u2615', - '\u26BD', - '\u26BE', - '\u26F1', - '\u26F2', - '\u26F3', - '\u26F4', - '\u26F5', - '\u26F7', - '\u26F8', - '\u26F9', - '\u26FA', - '\u26FD', - //Hand - '\u261C', - '\u261D', - '\u261E', - '\u261F', - '\u2620', - '\u2622', - '\u2623', - //Religion - '\u2626', - '\u262A', - '\u262C', - '\u262E', - '\u262F', - '\u26EA', - '\u26E9' -] - -var core=[ -{name:'<3',url: -'qrc:///images/smileys/core/smiley-heart.gif'}, - -{name:'</3',url: -'qrc:///images/smileys/core/smiley-brokenheart.gif'}, - -{name:':-)',url: -'qrc:///images/smileys/core/smiley-smile.gif'}, - -{name:';-)',url: -'qrc:///images/smileys/core/smiley-wink.gif'}, - -{name:':-(',url: -'qrc:///images/smileys/core/smiley-frown.gif'}, - -{name:':-P',url: -'qrc:///images/smileys/core/smiley-tongue-out.gif'}, - -{name:':-X',url: -'qrc:///images/smileys/core/smiley-kiss.gif'}, - -{name:':-D',url: -'qrc:///images/smileys/core/smiley-laughing.gif'}, - -{name:':-O',url: -'qrc:///images/smileys/core/smiley-surprised.gif'}, - -{name:'\\o/',url: -'qrc:///images/smileys/core/smiley-thumbsup.gif'}, - -{name:'o.O',url: -'qrc:///images/smileys/core/smiley-Oo.gif'}, - -{name:":'(",url: -'qrc:///images/smileys/core/smiley-cry.gif'}, - -{name:":-!",url: -'qrc:///images/smileys/core/smiley-foot-in-mouth.gif'}, - -{name:":-/",url: -'qrc:///images/smileys/core/smiley-undecided.gif'}, - -{name:":-[",url: -'qrc:///images/smileys/core/smiley-embarassed.gif'}, - -{name:"8-)",url: -'qrc:///images/smileys/core/smiley-cool.gif'}, - -{name:':beer',url: -'qrc:///images/smileys/core/beer_mug.gif'}, - -{name:':coffee',url: -'qrc:///images/smileys/core/coffee.gif'}, - -{name:':facepalm',url: -'qrc:///images/smileys/core/smiley-facepalm.gif'}, - -{name:':like',url: -'qrc:///images/smileys/core/like.gif'}, - -{name:':dislike',url: -'qrc:///images/smileys/core/dislike.gif'}, - -{name:'~friendica',url: -'qrc:///images/smileys/core/friendica-16.png'}, - -{name:'red#',url: -'qrc:///images/smileys/core/rm-16.png'} -] - - -var addon=[ -{name:':bunnyflowers',url: -'qrc:///images/smileys/animals/bunnyflowers.gif'}, - - {name:':chick',url: -'qrc:///images/smileys/animals/chick.gif'}, - - {name:':bumblebee',url: -'qrc:///images/smileys/animals/bee.gif'}, - - {name:':ladybird',url: -'qrc:///images/smileys/animals/ladybird.gif'}, - - {name:':bigspider',url: -'qrc:///images/smileys/animals/bigspider.gif' }, - - {name:':cat',url: -'qrc:///images/smileys/animals/cat.gif'}, - - {name:':bunny',url: -'qrc:///images/smileys/animals/bunny.gif' }, - - {name:':cow',url: -'qrc:///images/smileys/animals/cow.gif' }, - - {name:':crab',url: -'qrc:///images/smileys/animals/crab.gif' }, - - {name:':dolphin',url: -'qrc:///images/smileys/animals/dolphin.gif' }, - - {name:':dragonfly',url: -'qrc:///images/smileys/animals/dragonfly.gif' }, - - {name:':frog',url: -'qrc:///images/smileys/animals/frog.gif'}, - - {name:':hamster',url: -'qrc:///images/smileys/animals/hamster.gif' }, - - {name:':monkey',url: -'qrc:///images/smileys/animals/monkey.gif' }, - - {name:':horse',url: -'qrc:///images/smileys/animals/horse.gif' }, - - {name:':parrot',url: -'qrc:///images/smileys/animals/parrot.gif' }, - - {name:':tux',url: -'qrc:///images/smileys/animals/tux.gif' }, - - {name:':snail',url: -'qrc:///images/smileys/animals/snail.gif' }, - - {name:':sheep',url: -'qrc:///images/smileys/animals/sheep.gif' }, - - {name:':dog',url: -'qrc:///images/smileys/animals/dog.gif'}, - - {name:':elephant',url: -'qrc:///images/smileys/animals/elephant.gif' }, - - {name:':fish',url: -'qrc:///images/smileys/animals/fish.gif' }, - - {name:':giraffe',url: -'qrc:///images/smileys/animals/giraffe.gif' }, - - {name:':pig',url: -'qrc:///images/smileys/animals/pig.gif'}, - -//Baby - - {name:':baby',url: -'qrc:///images/smileys/babies/baby.gif' }, - - {name:':babycot',url: -'qrc:///images/smileys/babies/babycot.gif' }, - - - {name:':pregnant',url: -'qrc:///images/smileys/babies/pregnant.gif' }, - - {name:':stork',url: -'qrc:///images/smileys/babies/stork.gif' }, - - -//Confused - {name:':confused',url: -'qrc:///images/smileys/confused/confused.gif' }, - - {name:':shrug',url: -'qrc:///images/smileys/confused/shrug.gif' }, - - {name:':stupid',url: -'qrc:///images/smileys/confused/stupid.gif' }, - - {name:':dazed',url: -'qrc:///images/smileys/confused/dazed.gif' }, -//Cool 'qrc:///images/smileys - - {name:':affro',url: -'qrc:///images/smileys/cool/affro.gif'}, - -//Devil/Angel - - {name:':angel',url: -'qrc:///images/smileys/devilangel/angel.gif'}, - - {name:':cherub',url: -'qrc:///images/smileys/devilangel/cherub.gif'}, - - {name:':devilangel',url: -'qrc:///images/smileys/devilangel/blondedevil.gif' }, - {name:':catdevil',url: -'qrc:///images/smileys/devilangel/catdevil.gif'}, - - {name:':devillish',url: -'qrc:///images/smileys/devilangel/devil.gif'}, - - {name:':daseesaw',url: -'qrc:///images/smileys/devilangel/daseesaw.gif'}, - - {name:':turnevil',url: -'qrc:///images/smileys/devilangel/turnevil.gif' }, - - {name:':saint',url: -'qrc:///images/smileys/devilangel/saint.gif'}, - - {name:':graveside',url: -'qrc:///images/smileys/devilangel/graveside.gif'}, - -//Unpleasent - - {name:':toilet',url: -'qrc:///images/smileys/disgust/toilet.gif'}, - - {name:':fartinbed',url: -'qrc:///images/smileys/disgust/fartinbed.gif' }, - - {name:':fartblush',url: -'qrc:///images/smileys/disgust/fartblush.gif' }, - -//Drinks - - {name:':tea',url: -'qrc:///images/smileys/drink/tea.gif' }, - - {name:':drool',url: -'qrc:///images/smileys/drool/drool.gif'}, - -//Sad - - {name:':crying',url: -'qrc:///images/smileys/sad/crying.png'}, - - {name:':prisoner',url: -'qrc:///images/smileys/sad/prisoner.gif' }, - - {name:':sigh',url: -'qrc:///images/smileys/sad/sigh.gif'}, - -//Smoking - only one smiley in here, maybe it needs moving elsewhere? - - {name:':smoking',url: -'qrc:///images/smileys/smoking/smoking.gif'}, - -//Sport - - {name:':basketball',url: -'qrc:///images/smileys/sport/basketball.gif'}, - - {name:':bowling',url: -'qrc:///images/smileys/sport/bowling.gif'}, - - {name:':cycling',url: -'qrc:///images/smileys/sport/cycling.gif'}, - - {name:':darts',url: -'qrc:///images/smileys/sport/darts.gif'}, - - {name:':fencing',url: -'qrc:///images/smileys/sport/fencing.gif' }, - - {name:':juggling',url: -'qrc:///images/smileys/sport/juggling.gif'}, - - {name:':skipping',url: -'qrc:///images/smileys/sport/skipping.gif'}, - - {name:':archery',url: -'qrc:///images/smileys/sport/archery.gif'}, - - {name:':surfing',url: -'qrc:///images/smileys/sport/surfing.gif' }, - - {name:':snooker',url: -'qrc:///images/smileys/sport/snooker.gif' }, - - {name:':horseriding',url: -'qrc:///images/smileys/sport/horseriding.gif'}, - -//Love - - {name:':iloveyou',url: -'qrc:///images/smileys/love/iloveyou.gif'}, - - {name:':inlove',url: -'qrc:///images/smileys/love/inlove.gif'}, - - {name:':~love',url: -'qrc:///images/smileys/love/love.gif' }, - - {name:':lovebear',url: -'qrc:///images/smileys/love/lovebear.gif'}, - - {name:':lovebed',url: -'qrc:///images/smileys/love/lovebed.gif' }, - - {name:':loveheart',url: -'qrc:///images/smileys/love/loveheart.gif' }, - -//Tired/Sleep - - {name:':countsheep',url: -'qrc:///images/smileys/tired/countsheep.gif' }, - - {name:':hammock',url: -'qrc:///images/smileys/tired/hammock.gif'}, - - {name:':pillow',url: -'qrc:///images/smileys/tired/pillow.gif' }, - - {name:':yawn',url: -'qrc:///images/smileys/tired/yawn.gif'}, - -//Fight/Flame/Violent - - {name:':2guns',url: -'qrc:///images/smileys/fight/2guns.gif' }, - - {name:':alienfight',url: -'qrc:///images/smileys/fight/alienfight.gif' }, - - {name:':army',url: -'qrc:///images/smileys/fight/army.gif'}, - - {name:':arrowhead',url: -'qrc:///images/smileys/fight/arrowhead.gif'}, - - {name:':bfg',url: -'qrc:///images/smileys/fight/bfg.gif' }, - - {name:':bowman',url: -'qrc:///images/smileys/fight/bowman.gif' }, - - {name:':chainsaw',url: -'qrc:///images/smileys/fight/chainsaw.gif'}, - - {name:':crossbow',url: -'qrc:///images/smileys/fight/crossbow.gif'}, - - {name:':crusader',url: -'qrc:///images/smileys/fight/crusader.gif' }, - - {name:':dead',url: -'qrc:///images/smileys/fight/dead.gif' }, - - {name:':hammersplat',url: -'qrc:///images/smileys/fight/hammersplat.gif' }, - - {name:':lasergun',url: -'qrc:///images/smileys/fight/lasergun.gif' }, - - {name:':machinegun',url: -'qrc:///images/smileys/fight/machinegun.gif' }, - - {name:':acid',url: -'qrc:///images/smileys/fight/acid.gif' }, - -//Fantasy - monsters and dragons fantasy. The other type of fantasy belongs in adult - - {name:':alienmonster',url: -'qrc:///images/smileys/fantasy/alienmonster.gif' }, - - {name:':barbarian',url: -'qrc:///images/smileys/fantasy/barbarian.gif' }, - - {name:':dinosaur',url: -'qrc:///images/smileys/fantasy/dinosaur.gif'}, - - {name:':dragon',url: -'qrc:///images/smileys/fantasy/dragon.gif'}, - - {name:':draco',url: -'qrc:///images/smileys/fantasy/dragonwhelp.gif'}, - - {name:':ghost',url: -'qrc:///images/smileys/fantasy/ghost.gif'}, - - {name:':mummy',url: -'qrc:///images/smileys/fantasy/mummy.gif'}, - -//Food - - {name:':apple',url: -'qrc:///images/smileys/food/apple.gif' }, - - {name:':broccoli',url: -'qrc:///images/smileys/food/broccoli.gif' }, - - {name:':cake',url: -'qrc:///images/smileys/food/cake.gif'}, - - {name:':carrot',url: -'qrc:///images/smileys/food/carrot.gif' }, - - {name:':popcorn',url: -'qrc:///images/smileys/food/popcorn.gif'}, - - {name:':tomato',url: -'qrc:///images/smileys/food/tomato.gif'}, - - {name:':banana',url: -'qrc:///images/smileys/food/banana.gif'}, - - {name:':cooking',url: -'qrc:///images/smileys/food/cooking.gif'}, - - {name:':fryegg',url: -'qrc:///images/smileys/food/fryegg.gif'}, - - {name:':birthdaycake',url: -'qrc:///images/smileys/food/birthdaycake.gif'}, - -//Happy - - {name:':cloud9',url: -'qrc:///images/smileys/happy/cloud9.gif'}, - - {name:':tearsofjoy',url: -'qrc:///images/smileys/happy/tearsofjoy.gif' }, - -//Repsect - - {name:':bow',url: -'qrc:///images/smileys/respect/bow.gif'}, - - {name:':bravo',url: -'qrc:///images/smileys/respect/bravo.gif'}, - - {name:':hailking',url: -'qrc:///images/smileys/respect/hailking.gif'}, - - {name:':number1',url: -'qrc:///images/smileys/respect/number1.gif' }, - -//Laugh - - {name:':hahaha',url: -'qrc:///images/smileys/laugh/hahaha.gif'}, - - {name:':loltv',url: -'qrc:///images/smileys/laugh/loltv.gif' }, - - {name:':rofl',url: -'qrc:///images/smileys/laugh/rofl.gif'}, - -//Music - - {name:':drums',url: -'qrc:///images/smileys/music/drums.gif'}, - - - {name:':guitar',url: -'qrc:///images/smileys/music/guitar.gif'}, - - {name:':trumpet',url: -'qrc:///images/smileys/music/trumpet.gif' }, - -//smileys that used to be in core - - {name:':headbang',url: -'qrc:///images/smileys/oldcore/headbang.gif'}, - - {name:':beard',url: -'qrc:///images/smileys/oldcore/beard.png'}, - - {name:':whitebeard',url: -'qrc:///images/smileys/oldcore/whitebeard.png'}, - - {name:':shaka',url: -'qrc:///images/smileys/oldcore/shaka.gif'}, - - {name:':\\.../',url: -'qrc:///images/smileys/oldcore/shaka.gif'}, - - {name:':\\ooo/',url: -'qrc:///images/smileys/oldcore/shaka.gif' }, - - {name:':headdesk',url: -'qrc:///images/smileys/oldcore/headbang.gif' }, - -//These two are still in core, so oldcore isn't strictly right, but we don't want too many directories - - {name:':-d',url: -'qrc:///images/smileys/oldcore/laughing.gif'}, - - {name:':-o',url: -'qrc:///images/smileys/oldcore/surprised.gif' }, - -// Regex killers - stick these at the bottom so they appear at the end of the English and -// at the start of $OtherLanguage. - - {name:':cool',url: -'qrc:///images/smileys/cool/cool.gif' }, - - {name:':vomit',url: -'qrc:///images/smileys/disgust/vomit.gif' }, - - {name:':golf',url: -'qrc:///images/smileys/sport/golf.gif' }, - - {name:':football',url: -'qrc:///images/smileys/sport/football.gif'}, - - {name:':tennis',url: -'qrc:///images/smileys/sport/tennis.gif' }, - - {name:':alpha',url: -'qrc:///images/smileys/fight/alpha.png' }, - - {name:':marine',url: -'qrc:///images/smileys/fight/marine.gif' }, - - {name:':sabre',url: -'qrc:///images/smileys/fight/sabre.gif' }, - - {name:':tank',url: -'qrc:///images/smileys/fight/tank.gif' }, - - {name:':viking',url: -'qrc:///images/smileys/fight/viking.gif' }, - - {name:':gangs',url: -'qrc:///images/smileys/fight/gangs.gif' }, - - {name:':dj',url: -'qrc:///images/smileys/music/dj.gif'}, - - {name:':elvis',url: -'qrc:///images/smileys/music/elvis.gif'}, - - {name:':violin',url: -'qrc:///images/smileys/music/violin.gif'}, -] - - -var adult=[ -{ -name:'(o)(o) ',url: -'qrc:///images/smileys/adult/tits.gif'}, - -{name:'(.)(.) ',url: -'qrc:///images/smileys/adult/tits.gif'}, - -{name:':bong',url: -'qrc:///images/smileys/adult/bong.gif'}, - -{name:':sperm',url: -'qrc:///images/smileys/adult/sperm.gif'}, - -{name:':drunk',url: -'qrc:///images/smileys/adult/drunk.gif'}, - -{name:':finger',url: -'qrc:///images/smileys/adult/finger.gif'} -] diff --git a/source-linux/js/yplayer.html b/source-linux/js/yplayer.html deleted file mode 100644 index b16816a..0000000 --- a/source-linux/js/yplayer.html +++ /dev/null @@ -1,47 +0,0 @@ - - - -1 - - - -
- - - diff --git a/source-linux/qml/configqml/AccountPage.qml b/source-linux/qml/configqml/AccountPage.qml deleted file mode 100644 index 6363511..0000000 --- a/source-linux/qml/configqml/AccountPage.qml +++ /dev/null @@ -1,364 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.12 -import QtQuick.Layouts 1.12 -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: ({}) - property string imagestoredir: "" - - - 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)} - } - - MButton{ - id:userButton - text:qsTr("User") - font.pointSize: osSettings.bigFontSize - x: root.fontFactor*osSettings.bigFontSize - y: root.fontFactor*osSettings.bigFontSize - width: root.width/2 - 2*mm - height: 2*root.fontFactor*osSettings.bigFontSize - visible: users.length>0 - - onClicked:{ - var useritems=""; - for (var i=0;i-1){ - Helperjs.showMessage(qsTr("Error"),qsTr("Nicknames containing @ symbol currently not supported"),accountPage) - } - imagestoredir=filesystem.homePath+"/"+username.text+"/" - //if (imagestore.text==filesystem.homePath+"/.friendiqa/"){imagestore.text=filesystem.homePath+"/.friendiqa/"+username.text+"/"} - } - } - - - TextField { - id: password - x: root.fontFactor*osSettings.bigFontSize; y: 9*root.fontFactor*osSettings.bigFontSize; width: root.width-9*mm; //height: 5*mm; - //font.pixelSize:3*mm - font.pointSize: osSettings.systemFontSize - selectByMouse: true - echoMode: TextInput.Password - placeholderText: qsTr("Password") - inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhSensitiveData - } - - Text { - id: imagedirlabel - visible: imagestore.text!="" - text: qsTr("Image dir.") - font.pointSize: osSettings.systemFontSize - x: root.fontFactor*osSettings.bigFontSize; y: 12*root.fontFactor*osSettings.bigFontSize - } - - TextField { - id: imagestore - x: root.fontFactor*osSettings.bigFontSize; y: 13*root.fontFactor*osSettings.bigFontSize; width: root.width-17*mm; //height: 5*mm; - visible:imagestore.text!="" - font.pointSize: osSettings.systemFontSize - selectByMouse: true - text: "" //filesystem.homePath+"/.friendiqa/"+username.text+"/" //(osSettings.osType=="Android") && (filesystem.fileexist("/storage/emulated/0/Pictures/"))?"/storage/emulated/0/Pictures/":"" - wrapMode: TextEdit.NoWrap - onTextChanged: imagestoredir=imagestore.text - } - MButton { - x: root.width-3*root.fontFactor*osSettings.bigFontSize; y: 13*root.fontFactor*osSettings.bigFontSize; - height: 2*root.fontFactor*osSettings.bigFontSize; - visible:imagestore.text!="" - text: "..." - font.pointSize: osSettings.bigFontSize - onClicked:{imagestoreDialog.open()} - } - - - 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 - } - } - - - BusyIndicator{ - id: accountBusy - anchors.horizontalCenter: parent.horizontalCenter - y: 16*root.fontFactor*osSettings.bigFontSize - width:10*mm - height: 10*mm - running: false - } - - MButton { - x: root.fontFactor*osSettings.bigFontSize; y: 16*root.fontFactor*osSettings.bigFontSize - text: qsTr("Confirm") - font.pointSize: osSettings.bigFontSize - onClicked:{ - accountBusy.running=true; - var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestoredir, maxnews:"",interval: ""}; - 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 (imagestoredir=="") {errormessage+=qsTr("No image directory 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{ - if (users.length==0){Service.setDefaultOptions(db);} - //print("imagestore" + userconfig.imagestore + " path "+ filesystem.homePath+"/"+username.text) - if(userconfig.imagestore == filesystem.homePath+"/"+username.text+"/") - {//filesystem.Directory=filesystem.homePath; - filesystem.makePath(filesystem.homePath+"/"+username.text); - } - filesystem.Directory=imagestoredir //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 - login=userconfig; - news=[]; - rootstack.currentIndex=0; - newstypeSignal("refresh"); - },"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) - rootstackView.pop() - } - }); - - } - else {Helperjs.showMessage(qsTr("Error"), errormessage,root)} - }} - - - Row{ - spacing:0.5*mm - anchors.top: parent.top - anchors.topMargin: root.fontFactor*osSettings.bigFontSize - anchors.right: parent.right - anchors.rightMargin: 1*mm - MButton { - //x: parent.width/2+4*mm; y: mm; - width: 5*mm; - //height: 3*root.fontFactor*osSettings.bigFontSize - visible: users.length>0 - text: "-" - font.pointSize: osSettings.bigFontSize - 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;}) - }) - }} - - MButton { - //x: parent.width/2+10*mm; y: mm; //width: 5*mm; height: 8*mm; - //height: 3*root.fontFactor*osSettings.bigFontSize - width: 5*mm; - visible: users.length>0 - text: "+" - font.pointSize: osSettings.bigFontSize - onClicked:{ - servername.text="https://" - servericon.visible=false; - servericon.source=""; - username.text="" - password.text="" - imagestore.text="" //filesystem.homePath+"/.friendiqa/"+username.text//"" - userButton.text=qsTr("User") - } - } - - MButton { - //x: parent.width-12*mm; y: mm; //width: 5*mm; height: 8*mm; - //height: 3*root.fontFactor*osSettings.bigFontSize - width: 5*mm; - text: "?" - font.pointSize: osSettings.bigFontSize - onClicked:{ - rootstackView.push("qrc:/qml/configqml/InfoBox.qml"); - } - } - MButton{ - id:closeButton - //height: 3*root.fontFactor*osSettings.bigFontSize - width: 5*mm; - visible: users.length>0 - text: "\uf057" - font.pointSize: osSettings.bigFontSize - onClicked:{rootstackView.pop()} - } - } - - 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; - imagestoredir=obj.imagestore; - if( obj.isActive==0){userButton.font.bold='true'} else {userButton.font.bold='false'} - },"isActive",0) - })} - catch (e){//print("onCompleted" +users.count +e) - } - } -} diff --git a/source-linux/qml/configqml/ConfigPage.qml b/source-linux/qml/configqml/ConfigPage.qml deleted file mode 100644 index 0d9e1ea..0000000 --- a/source-linux/qml/configqml/ConfigPage.qml +++ /dev/null @@ -1,175 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.12 - -import "qrc:/js/service.js" as Service -import "qrc:/qml/configqml" -import "qrc:/qml/genericqml" - -Page{ - //anchors.fill: parent - width:root.width - height:root.height - - Rectangle{ - x: root.fontFactor*osSettings.bigFontSize; y:4*root.fontFactor*osSettings.bigFontSize; - width: parent.width - 6*root.fontFactor*osSettings.bigFontSize; height: 2*root.fontFactor*osSettings.bigFontSize - color:"#F3F3F3" - radius: 0.5*mm - Text{ - anchors.fill: parent - font.pointSize: osSettings.bigFontSize - text:qsTr("Sync") - } - MouseArea{ - anchors.fill:parent - onClicked:rootstackView.push("qrc:qml/configqml/SyncConfig.qml"); - } - } - - Text { - text: qsTr("News as") - font.pointSize:osSettings.systemFontSize - x: root.fontFactor*osSettings.bigFontSize; y: 8*root.fontFactor*osSettings.bigFontSize - } - - Rectangle{ - x: root.fontFactor*osSettings.bigFontSize; y: 10*root.fontFactor*osSettings.bigFontSize; - width: newsTypeField.contentWidth+2*mm; height: 2*root.fontFactor*osSettings.bigFontSize - color:"#F3F3F3" - radius: 0.5*mm - Text{ - id: newsTypeField - anchors.fill: parent - font.pointSize:osSettings.bigFontSize - text:qsTr("Conversations") - } - MouseArea{ - anchors.fill:parent - onClicked:newstypemenu.popup() - } - } - Menu { - id:newstypemenu - width:8*root.fontFactor*osSettings.bigFontSize - MenuItem { - font.pointSize: osSettings.bigFontSize - text: qsTr("Timeline") - onTriggered: {newsTypeField.text=qsTr("Timeline"); - Service.updateglobaloptions(root.db,"newsViewType","Timeline");} - } - MenuItem { - font.pointSize: osSettings.bigFontSize - text: qsTr("Conversations") - onTriggered: {newsTypeField.text=qsTr("Conversations"); - Service.updateglobaloptions(root.db,"newsViewType","Conversations");} - } - } - - - Text { - text: qsTr("Max. News") - font.pointSize: osSettings.systemFontSize - x: root.fontFactor*osSettings.bigFontSize; y:14*root.fontFactor*osSettings.bigFontSize - } - - Slider{ id: maxNews - x:6*root.fontFactor*osSettings.bigFontSize; y: 16*root.fontFactor*osSettings.bigFontSize; - width: root.width/2;height:2*root.fontFactor*osSettings.bigFontSize - from: 0;to:2000; stepSize: 100 - value: root.globaloptions.hasOwnProperty("max_news")?root.globaloptions.max_news:1000 - } - - Rectangle{ - color: "#F3F3F3"; - x: root.fontFactor*osSettings.bigFontSize; y: 16*root.fontFactor*osSettings.bigFontSize; - width: 4*root.fontFactor*osSettings.bigFontSize; height: 2*root.fontFactor*osSettings.bigFontSize; - radius: 0.5*mm - TextEdit{id:maxNewsText; - anchors.fill: parent - font.pointSize: osSettings.bigFontSize - verticalAlignment:TextEdit.AlignRight - text:maxNews.value - selectByMouse: true - onTextChanged: { - Service.updateglobaloptions(root.db,"max_news",text); - } - } - } - - - - CheckBox{ - id: nsfwCheckbox - x: root.fontFactor*osSettings.bigFontSize - y: 20*root.fontFactor*osSettings.bigFontSize - font.pointSize: osSettings.bigFontSize - text: qsTr("Hide #nsfw?") - checked:(globaloptions["hide_nsfw"]==1)?true:false - onClicked: { - toggle(); - if(nsfwCheckbox.checked==true){ - Service.updateglobaloptions(root.db,"hide_nsfw",0);nsfwCheckbox.checked=false; - } - else{ - Service.updateglobaloptions(root.db,"hide_nsfw",1);nsfwCheckbox.checked=true; - } - } - } - - - MButton { - anchors.right: closeButton.left; anchors.rightMargin: mm; - anchors.top: parent.top - anchors.topMargin:root.fontFactor*osSettings.bigFontSize - width: 2*root.fontFactor*osSettings.bigFontSize; - text: "?" - font.pointSize: osSettings.bigFontSize - onClicked:{ - rootstackView.push("qrc:/qml/configqml/InfoBox.qml"); - } - } - MButton{ - id:closeButton - // height: 2*root.fontFactor*osSettings.bigFontSize - width: 2*root.fontFactor*osSettings.bigFontSize; - anchors.top: parent.top - anchors.topMargin:root.fontFactor*osSettings.bigFontSize - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - font.pointSize: osSettings.bigFontSize - onClicked:{rootstackView.pop()} - } -} diff --git a/source-linux/qml/configqml/LeftDrawerScrollview.qml b/source-linux/qml/configqml/LeftDrawerScrollview.qml deleted file mode 100644 index 8a11dce..0000000 --- a/source-linux/qml/configqml/LeftDrawerScrollview.qml +++ /dev/null @@ -1,113 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.0 -import QtQuick.Controls 2.12 -import "qrc:/qml/genericqml" -import "qrc:/js/service.js" as Service - -ScrollView{ - id:leftDrawerScrollviewId - clip: true - width:parent.width-mm - height: parent.height - contentHeight: leftDrawerColumn.height - property string currentnewstabstatus:root.globaloptions.hasOwnProperty("newsViewType")?root.globaloptions.newsViewType:"Conversations"; - - Column{ - id:leftDrawerColumn - x:mm - y:0.5*root.fontFactor*osSettings.bigFontSize - width:parent.width-2*mm - height: 4*root.fontFactor*osSettings.bigFontSize - spacing: 0.7*root.fontFactor*osSettings.bigFontSize - Label{ - width:implicitWidth - font.pointSize: osSettings.systemFontSize - text: "\uf085 "+ qsTr("Settings") - MouseArea{ - anchors.fill:parent - onClicked:{rootstackView.push("qrc:qml/configqml/ConfigPage.qml"); - if(!wideScreen){leftDrawerAndroid.close()} - } - } - } - - Label{y: 2*root.fontFactor*osSettings.bigFontSize - width:implicitWidth - font.pointSize: osSettings.systemFontSize - text: "\uf2bb " + qsTr("Accounts") - MouseArea{ - anchors.fill:parent - onClicked:{rootstackView.push("qrc:qml/configqml/AccountPage.qml"); - if(!wideScreen){leftDrawerAndroid.close()} - } - } - } - - Label{y: 4*root.fontFactor*osSettings.bigFontSize - width:implicitWidth - font.pointSize: osSettings.systemFontSize - text: "\uf08b " +qsTr("Quit") - MouseArea{ - anchors.fill:parent - onClicked:{ - Service.cleanNews(root.db,function(){ - Service.cleanHashtags(root.db,function(){ - Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) - })}) - } - } - } - } - Component.onCompleted:{ - Service.readAllLogins(db,function(accounts){ - if (accounts.length>0 && bar.currentIndex==0){ - leftDrawerColumn.height=4.5*root.fontFactor*osSettings.bigFontSize+accounts.length*17*root.fontFactor*osSettings.bigFontSize - for(var i = 0; i < accounts.length; i++) { - var accountComponent = Qt.createComponent("qrc:/qml/genericqml/DrawerAccountComponent.qml"); - var accountQml = accountComponent.createObject(leftDrawerColumn,{ - "y":4.5*root.fontFactor*osSettings.bigFontSize+i*17*root.fontFactor*osSettings.bigFontSize, - "currentnewstabstatus":currentnewstabstatus, - "account":accounts[i]}); - } - }else if(accounts.length>0 && bar.currentIndex==1){ - leftDrawerColumn.height=4.5*root.fontFactor*osSettings.bigFontSize+accounts.length*8*root.fontFactor*osSettings.bigFontSize - for(var i = 0; i < accounts.length; i++) { - var accountComponent = Qt.createComponent("qrc:/qml/genericqml/DrawerAccountComponentContacts.qml"); - var accountQml = accountComponent.createObject(leftDrawerColumn,{ - "y":4.5*root.fontFactor*osSettings.bigFontSize+i*8*root.fontFactor*osSettings.bigFontSize, - "account":accounts[i]}); - } - } - })} -} diff --git a/source-linux/qml/configqml/SyncConfig.qml b/source-linux/qml/configqml/SyncConfig.qml deleted file mode 100644 index 65686b1..0000000 --- a/source-linux/qml/configqml/SyncConfig.qml +++ /dev/null @@ -1,116 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.12 -import "qrc:/qml/configqml" -import "qrc:/qml/genericqml" -import "qrc:/js/service.js" as Service - -Rectangle{ - color:"white" - width:root.width - height: root.height - - //height:root.height - Text { - text: qsTr("Sync Interval (0=None)") - font.pointSize: osSettings.bigFontSize - //visible: false - x: root.fontFactor*osSettings.bigFontSize; y: root.fontFactor*osSettings.bigFontSize; //width:35*mm;wrapMode: Text.Wrap - } - - Slider{ id: messageIntervalSlider - x:8*root.fontFactor*osSettings.bigFontSize; y: 4*root.fontFactor*osSettings.bigFontSize; - width: root.width-10*root.fontFactor*osSettings.bigFontSize; - height:2*root.fontFactor*osSettings.bigFontSize - value: globaloptions.hasOwnProperty("syncinterval")?globaloptions.syncinterval:0 - from: 0;to:120; stepSize: 15 - } - Rectangle{ - x: root.fontFactor*osSettings.bigFontSize; y:4*root.fontFactor*osSettings.bigFontSize; - width: 4*root.fontFactor*osSettings.bigFontSize; height: 2*root.fontFactor*osSettings.bigFontSize; - TextEdit{ - id: messageIntervalField - anchors.fill: parent - font.pointSize: osSettings.bigFontSize - verticalAlignment:TextEdit.AlignRight - text:messageIntervalSlider.value - focus: true - selectByMouse: true - onTextChanged: { - Service.updateglobaloptions(root.db,"syncinterval",text); - if(osSettings.osType=="Android"){ - //print("setalarm") - alarm.setAlarm(text); - } else if(osSettings.osType=="Linux" && text !=0){ - root.updateSyncinterval(parseInt(text)) - } - } - } - } - Text{x: 6*root.fontFactor*osSettings.bigFontSize; y: 4*root.fontFactor*osSettings.bigFontSize; - width: 2*root.fontFactor*osSettings.bigFontSize; height: 1.5*root.fontFactor*osSettings.bigFontSize; - font.pointSize: osSettings.bigFontSize - text:qsTr("Min.") - } - - ScrollView{ - width: root.width - height: root.height - 10*root.fontFactor*osSettings.bigFontSize; - y:7*root.fontFactor*osSettings.bigFontSize - clip:true - Column{ - //height: implicitHeight - width: parent.width - spacing:mm - //anchors.fill: parent - SyncComponent{adapter:"Timeline"} - SyncComponent{adapter:"Replies"} - SyncComponent{ adapter:"DirectMessages"} - SyncComponent{ adapter:"Notifications"} - SyncComponent{ adapter: "Events"} - SyncComponent{adapter: "FriendRequests"} - } - } - - MButton{ - id:closeButton - anchors.top: parent.top - anchors.topMargin: osSettings.bigFontSize - anchors.right: parent.right - anchors.rightMargin: 1*mm - width: 2*root.fontFactor*osSettings.bigFontSize; - text: "\uf057" - font.pointSize: osSettings.bigFontSize - onClicked:{rootstackView.pop()} - } -} diff --git a/source-linux/qml/contactqml/ContactDetailsComponent.qml b/source-linux/qml/contactqml/ContactDetailsComponent.qml deleted file mode 100644 index 768a653..0000000 --- a/source-linux/qml/contactqml/ContactDetailsComponent.qml +++ /dev/null @@ -1,177 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.0 -import QtQuick.Controls 2.12 -import "qrc:/qml/genericqml" - -Item { -id: contactLargeComponent -x:mm -y:mm -property var contact:({}) -property var createdAtDate: new Date(contact.created_at) -property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend!=0)?"":( ""+qsTr("Connect")+"
") - -Rectangle { - id: wrapper - - width:root.width-2*mm //friendsTabView.width; - height:root.height-20*mm// friendsTabView.height-15*mm - border.color: "grey" - color:"white" - radius: 0.5*mm - Image { - id: photoImage - x:mm - y:mm - width: 15*mm - height:15*mm - source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url - onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} - } - - Label { - id: namelabel - x: mm - width: root.width-6*mm //friendsTabView.width-4*mm - height: 3*mm - text:contact.name+" (@"+contact.screen_name+")" - elide:Text.ElideRight - anchors.topMargin: 0 - anchors.left: photoImage.left - color: "#303030" - font.pixelSize: 4*mm - anchors.top: photoImage.bottom - } - Rectangle{ - id: detailsrectangle - anchors.top: namelabel.bottom - anchors.topMargin: 2*mm - - ScrollView{ - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - //frameVisible: true - id:namelabelflickable - width: root.width-10*mm - height:root.height-50*mm - x: mm - clip:true - Text{ - id:namelabeltext - width: namelabelflickable.width - height: implicitHeight - font.pixelSize: 3*mm - textFormat:Text.RichText - wrapMode: Text.Wrap - text:""+qsTr("Description")+": "+contact.description+"
"+qsTr("Location")+": "+contact.location+"
"+qsTr("Posts")+": "+contact.statuses_count+ - "
"+qsTr("URL")+": "+contact.url+"
"+ - connectUrl+ ""+qsTr("Created at")+": "+createdAtDate.toLocaleString(Qt.locale()) - onLinkActivated: { - Qt.openUrlExternally(link)} - } - } - - Row{ - anchors.top: namelabelflickable.bottom - anchors.topMargin: 2*mm - x: mm - spacing:4 - - MButton{ - id:photobutton - height: 6*mm - width: 8*mm - text: "\uf03e" // "Photos" - visible:(contact.network=="dfrn") - onClicked:{ - fotostab.phototabstatus="Contact"; - root.currentIndex=2; - fotostab.active=true; - root.fotoSignal(contact) ; - contactLargeComponent.destroy(); - } - } - - MButton{ - id:messagebutton - height: 6*mm - width: 8*mm - text: "\uf0e6" //"Messages" - onClicked:{ - root.currentIndex=0; - //newstab.active=true; - root.messageSignal(contact) ; - contactLargeComponent.destroy(); - } - } - - MButton{ - id:dmbutton - visible: (contact.following=="true") - height: 6*mm - width: 8*mm - text: "\uf040" //"DM" - onClicked:{ - root.currentIndex=0; - root.directmessageSignal(contact.screen_name); - contactLargeComponent.destroy(); - } - } - - - MButton{ - id:eventbutton - visible:(contact.network=="dfrn") - height: 6*mm - width: 8*mm - text:"\uf073" //Events - onClicked:{ - root.currentIndex=3; - calendartab.active=true; - calendartab.calendartabstatus="Friend" - root.eventSignal(contact); - contactLargeComponent.destroy(); - } - } - - MButton{ - id: closeButton - height: 6*mm - width: 8*mm - text: "\uf057" //"close" - onClicked:{contactLargeComponent.destroy(); - } - } - } - } -} -} diff --git a/source-linux/qml/contactqml/ContactsListTab.qml b/source-linux/qml/contactqml/ContactsListTab.qml deleted file mode 100644 index b8f0d2a..0000000 --- a/source-linux/qml/contactqml/ContactsListTab.qml +++ /dev/null @@ -1,96 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.12 -import QtQuick.Layouts 1.11 -import QtQuick.LocalStorage 2.0 -import "qrc:/js/helper.js" as Helperjs -//import "qrc:/js/news.js" as Newsjs -import "qrc:/js/service.js" as Service -import "qrc:/qml/contactqml" -import "qrc:/qml/genericqml" - -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){ - for (var j=0;j -// -// 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.12 -import QtQuick.Layouts 1.11 -import QtQuick.LocalStorage 2.0 -import "qrc:/js/helper.js" as Helperjs -import "qrc:/js/news.js" as Newsjs -import "qrc:/qml/contactqml" -import "qrc:/qml/genericqml" - -Item{ - id: friendsGridTab - Layout.fillWidth:true - Layout.fillHeight: true - property int currentContact: 0 - - function showFriends(contact){ - try {friendsModel.clear()} catch(e){print(e)}; - Helperjs.readData(root.db,"friendshiprequests",login.username,function(friendrequestsobject){ - for (var i=0;i1){ - friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid - } - friendsModel.append({"contact":friendsobject[i],"contactType":qsTr("Friends")}); - } - },"isFriend",1,"screen_name ASC"); - } - Connections{ - target:xhr - function onDownloaded(type,url,filename,i){ - if(type=="contactlist"){ - //print(url+" "+filename+" "+i) - friendsGridTab.currentContact=i+1; - if(friendsGridTab.currentContact==root.newContacts.length){ - friendsGridTab.showFriends(root.login.username) - } - } - } - } - MButton { - id: updateFriendsButton - text: "\uf021" - anchors.top: parent.top - anchors.topMargin: mm - anchors.right: parent.right - onClicked: { - try {friendsModel.clear()} catch(e){print(e)}; - Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){}); - updatenews.setDatabase(); - updatenews.login(); - updatenews.friendrequests(); - //root.contactLoadType="friends"; - Newsjs.requestFriends(root.login,db,root,function(nc){ - root.newContacts=nc - root.onNewContactsChanged(nc); - }) - } - } - - ProgressBar{ - id: newContactsProgress - width: 15*mm - height: updateFriendsButton.height - anchors.top: parent.top - anchors.right:updateFriendsButton.left - anchors.rightMargin:mm - visible: (friendsGridTab.currentContact!=(root.newContacts.length))?true:false - value: friendsGridTab.currentContact/root.newContacts.length - } - - Component { - id: sectionHeading - Rectangle { - width: friendsView.width - height: childrenRect.height - //color: "lightsteelblue" - required property string section - Text { - text: parent.section - font.bold: true - font.pointSize: osSettings.bigFontSize - } - } - } - //GridView { - ListView{ - id: friendsView - x:mm - y:updateFriendsButton.height+mm - width:friendsGridTab.width-2*mm - height:friendsGridTab.height-(updateFriendsButton.height+5*mm) - clip: true - spacing: 2 - function processContactSelection(contactobject){showContactdetails(contactobject)} - //add: Transition { - // NumberAnimation { properties: "x,y"; from: 300; duration: 1000 } - // } - model: friendsModel - delegate: ContactComponent { } - section.property: "contactType" - section.criteria: ViewSection.FullString - section.delegate: sectionHeading - } - ListModel{id:friendsModel} - - Component.onCompleted: { - root.friendsSignal.connect(showFriends); - friendsTabView.contactsSignal.connect(showFriends); - showFriends(root.login.username); - root.newContacts=[] - } -} diff --git a/source-linux/qml/contactqml/GroupComponent.qml b/source-linux/qml/contactqml/GroupComponent.qml deleted file mode 100644 index 76a6858..0000000 --- a/source-linux/qml/contactqml/GroupComponent.qml +++ /dev/null @@ -1,272 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.12 -import "qrc:/js/helper.js" as Helperjs -import "qrc:/js/news.js" as Newsjs -import "qrc:/qml/genericqml" - -Item { - id: groupComponent - height: 5*root.fontFactor*osSettings.bigFontSize//8*mm - width: groupComponent.ListView.view.width - property var groupmembers:[] - //property bool newGroup: false - function groupModelAppend(groupcontacts,callback){ - for (var n in groupcontacts){ - groupModel.append({"groupmember":groupcontacts[n]});} - callback() - } - - Rectangle { - id: wrapper - x:0.5*mm - y:0.5*mm - width:parent.width-mm - height: parent.height-mm - radius: 0.5*mm - border.color: "grey" - color:"white" - -// Image { -// id: photoImage -// x:1 -// y:1 -// width: 10*mm -// height:10*mm -// source:"qrc:/images/defaultcontact.jpg" -// } - Rectangle{ - id:namelabelRect - x: 1 - y: 1 - width: wrapper.width-2 - height: 3*root.fontFactor*osSettings.bigFontSize - //border.color: "light grey" - TextInput { - id: namelabel - anchors.fill: parent - readOnly: true - text: group.new?"":group.groupname - color: "#303030" - font.pointSize: osSettings.bigFontSize - } - } - - MButton{ - id: closeButton - visible: false - anchors.right: parent.right - anchors.margins: mm - anchors.top: parent.top - text: "\uf057" - font.pointSize: osSettings.bigFontSize - onClicked:{groupComponent.state=""; - if (group.new){groupsModel.remove(index)} - } - } - - MButton{ - id:infobutton - text:"?" - font.pointSize: osSettings.bigFontSize - anchors.right: parent.right - anchors.rightMargin: mm - anchors.topMargin: mm - anchors.top: parent.top - onClicked:{ - groupComponent.state="large"; - //if(group.new){ - Helperjs.readField("members",root.db,"groups",root.login.username,function(groups){ - try {groupModel.clear()}catch (e){print(e)} - groupmembers=JSON.parse(groups); - for (var user in groupmembers){ - Helperjs.readData(root.db,"contacts",root.login.username,function(userdata){ - if (userdata[0]){ - userdata[0].name=Qt.atob(userdata[0].name); - userdata[0].description=Qt.atob(userdata[0].description) - //groupModel.append({"groupmember":userdata[0] - groupModel.append({"contact":userdata[0] - })} - },"id",groupmembers[user]) - } //catch(e){} - },"groupname",group.groupname); - //} - - } - } - - Rectangle{ - id: detailsrectangle - anchors.top: namelabelRect.bottom - //anchors.topMargin: mm - x:mm - width: parent.width-2*mm - height:parent.height -(3*root.fontFactor*osSettings.bigFontSize+mm) - visible: false - - ListView{ - id: groupListView - anchors.fill: parent - anchors.margins: mm - clip: true - spacing: 2 - model: groupModel - delegate: ContactComponent { }// groupMember - function processContactSelection(contactobject){showContactdetails(contactobject)} - } - - ListModel{id: groupModel} - -// Component { -// id:groupMember -// Rectangle{ -// width:parent.width -// height:6*mm -// Rectangle{id:memberrectangle -// border.color: "#EEEEEE" -// border.width: 1 -// width:parent.width-12*mm -// height:6*mm -// Image { -// id: memberImage -// x:1 -// y:1 -// width: 5*mm -// height:5*mm -// source:(groupmember.isFriend==1)? "file://"+groupmember.profile_image :groupmember.profile_image_url -// onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} -// } -// Text{ -// font.pixelSize: 3*mm -// anchors.left: memberImage.right -// anchors.margins: 1*mm -// width:parent.width-1 -// text:groupmember.name -// } -// MouseArea{ -// anchors.fill: parent -// onClicked:{ -//// root.currentIndex=1; -//// friendstab.active=true; -//// root.contactdetailsSignal(groupmember) -// root.currentIndex=0; -// root.contactdetailsSignal(groupmember) -// } -// } -// // BlueButton{ -// // anchors.left: memberrectangle.right -// // anchors.margins: 1*mm -// // text: "\uf056" -// // onClicked:{ -// // groupModel.remove(index) -// // } -// // } -// } -// } -// } - - - -// Row{ -// anchors.top: groupListView.bottom -// anchors.topMargin: mm -// spacing: mm -// } - -// BlueButton{ -// id: addMembers -// text:"\uf234" -// onClicked: { -// Newsjs.listFriends(root.login,root.db,function(userdata){ -// var newlistcontacts=[]; -// for (var n in userdata){ -// if (groupmembers.indexOf(userdata[n].id)==-1){ -// newlistcontacts.push(userdata[n]) -// } -// } -// var component = Qt.createComponent("qrc:/qml/contactqml/Contactlist.qml"); -// var contactlistobject = component.createObject(groupListView,{"possibleUsers":newlistcontacts}); - -// }) -// } -// } - -// BlueButton{ -// id: updateButton -// text: "\uf0ee" -// onClicked:{ -// var groupobject={}; -// var groupmembers=[]; -// for (var i=0;i -// -// 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.5 -import QtQuick.LocalStorage 2.0 -import QtQuick.Window 2.0 -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" - - -ApplicationWindow{ - id:root - title: "Friendiqa" - property var globaloptions: Service.readGO(db) - property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettingsLinux.qml");return tmp.createObject(root)} - width: globaloptions.hasOwnProperty("appWidth")?globaloptions.appWidth:osSettings.appWidth - height:globaloptions.hasOwnProperty("appHeight")?globaloptions.appHeight:osSettings.appHeight - visible: true - property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000] - property var login: Service.readActiveConfig(db) - property real fontFactor: root.font.pixelSize/root.font.pointSize - property var contactlist: [] - property real mm: osSettings.osType=="Android"?Screen.pixelDensity:Screen.pixelDensity*1.5 - property bool wideScreen : width>height - 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 searchSignal (var searchterm) - signal eventSignal(var contact) - signal uploadSignal(var urls) - signal sendtextSignal(var intenttext) - signal changeimage(var method, var type, var id) - signal updateSyncinterval(int interval) - signal replySignal(var newsobject) - property var news:[] - property var newContacts:[] - property var contactposts:[] - //property string contactLoadType: "" - property bool imagePicking: false - - function onLoginChanged(login){ - if(login==""){rootstackView.push("qrc:/qml/configqml/AccountPage.qml")} - else{//rootstackView.push(rootstack) - if (login.newsViewType!="" || login.newsViewType!=null){ - newstab.newstabstatus=login.newsViewType;} - Newsjs.getCurrentContacts(login,db,function(contacts){ - contactlist=contacts}) - } - } - function onNewContactsChanged(newContacts){ - if(newContacts.length>0){// download contact images and update db - var contacturls=[]; - var contactnames=[]; - for (var link in newContacts){//print("new contact " +newContacts[link].screen_name); - contacturls.push(newContacts[link].profile_image_url); - contactnames.push(newContacts[link].screen_name); - Service.updateContactInDB(login,db,newContacts[link].isFriend,newContacts[link]) - contactlist.push(newContacts[link].url); - } - xhr.setDownloadtype("contactlist"); - xhr.setFilelist(contacturls); - xhr.setContactlist(contactnames); - xhr.setImagedir(login.imagestore); - xhr.getlist(); - } - - } - - Connections { - target: root - function onWidthChanged(appWidth) { - if(osSettings.osType=="Linux" && Math.abs(appWidth-(globaloptions.appWidth||0))>50){ - Service.updateglobaloptions(db,"appWidth",appWidth) - } - } - } - Connections { - target: root - function onHeightChanged(appHeight) { - if(osSettings.osType=="Linux" && Math.abs(appHeight-(globaloptions.appHeight||0))>50){ - Service.updateglobaloptions(db,"appHeight",appHeight) - } - } - } - - - function showContact(contact){ //print(JSON.stringify(contact)); - rootstackView.push("qrc:/qml/newsqml/ContactPage.qml",{"contact": contact}) - } - - - Connections{ - target:xhr - function onDownloaded(type,url,filename,i){ - 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"} - - //Keys.onReleased: {//print(event.key + "Backkey"+newstab.conversation.length+" "+root.depth) - onClosing: { - //if (event.key === osSettings.backKey) { - if (rootstack.currentIndex==0){ - newstab.active=true; - if (newstab.newstabstatus!=globaloptions.newsViewType){ - newstab.newstabstatus=globaloptions.newsViewType; - if(globaloptions.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,0,function(dbnews){ - newsSignal(dbnews) - })} - else{ - Newsjs.chatsfromdb(db,login.username,function(dbnews){ - newsSignal(dbnews) - })} - close.accepted=false; - } - - else if (newstab.conversation.length>0){ - newstab.conversation=[]; - close.accepted=false - } - else if (root.depth>1){ - root.pop(); - close.accepted=false - } - else{ - Service.cleanNews(root.db,function(){ - Service.cleanHashtags(root.db,function(){ - Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) - })}) - close.accepted=true - } - } - else if (rootstack.currentIndex==2){fotoSignal("backButton")} - else {rootstack.currentIndex=0} - //event.accepted = true - //} - } - - - - - header: ToolBar{ - position: wideScreen?ToolBar.Header:ToolBar.Footer - background: Rectangle{ - anchors.fill: parent - color: "#EEEEEE"//"#F8F8F8" - } - RowLayout{ - anchors.fill: parent - ToolButton{ - visible: !wideScreen - text: "\uf0c9" - onClicked:{ - leftDrawer.visible?leftDrawer.close():leftDrawer.open()} - } - TabBar { - id: bar - Layout.fillWidth: true - //width: wideScreen?contentWidth:parent.width-10*mm - //x: 7*mm - onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex - TabButton { - text: "\uf03a" - background:Rectangle{ - anchors.fill: parent - color: "#EEEEEE" - } - } - TabButton { - text: "\uf0c0" - background:Rectangle{ - anchors.fill: parent - color: "#EEEEEE" - } - } - TabButton { - text: "\uf03e" - background:Rectangle{ - anchors.fill: parent - color: "#EEEEEE" - } - } - TabButton { - text: "\uf073" - background:Rectangle{ - anchors.fill: parent - color: "#EEEEEE" - } - } - } - } - } - - LeftDrawerAndroid{ - id: leftDrawer - visible:!wideScreen - } - -// 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 -// } -// } -StackView{id:rootstackView - width:root.width - height: root.height - initialItem: StackLayout{ - id:rootstack - width:rootstackView.width - height: rootstackView.height//-7*mm - //y:wideScreen?7*mm:0 - currentIndex:bar.currentIndex - - Loader{ - id: newstab - Layout.fillWidth:true - Layout.fillHeight: true - property string newstabstatus - property var conversation:[] - - 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: { - onLoginChanged(login); - globaloptions=Service.readGO(db); - if(osSettings.osType=="Android"){ - var component = Qt.createComponent("qrc:/qml/genericqml/IntentReceiver.qml"); - var IntentReceiverQml = component.createObject(root); - } - else if (osSettings.osType=="Linux"){ - newstypeSignal("refresh") - var component = Qt.createComponent("qrc:/qml/genericqml/LinuxSync.qml"); - var LinuxSyncQml = component.createObject(root); - } - } -//} -} diff --git a/source-linux/qml/genericqml/DrawerAccountComponent.qml b/source-linux/qml/genericqml/DrawerAccountComponent.qml deleted file mode 100644 index 2736acd..0000000 --- a/source-linux/qml/genericqml/DrawerAccountComponent.qml +++ /dev/null @@ -1,235 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.0 -import QtQuick.Controls 2.12 -import "qrc:/qml/genericqml" - -Item { - id: drawerAccountComponent - property var account: ({}) - width: parent.width - - Label{ - - y:0.5*root.fontFactor*osSettings.bigFontSize - width:parent.width - height: 1.5*osSettings.bigFontSize*root.fontFactor - verticalAlignment:Text.AlignBottom - font.pointSize: osSettings.bigFontSize - text: account.username - } - // Label{ - // text:login.hasOwnProperty("server")?"@"+login.server:"" - // font.pixelSize: 5*mm - // width: parent.width - // } - - Label{ - y:2*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - text: "\uf021 " + qsTr("Refresh") - MouseArea{ - anchors.fill:parent - onClicked: { - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newstypeSignal("refresh") -// updatenews.setDatabase(); -// updatenews.login(); -// updatenews.startsync(); - } - } - } - - Label{ - y:3.5*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="Timeline" - text: "\uf1da " + qsTr("Timeline") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=0; - currentnewstabstatus="Timeline"; - newstypeSignal("timeline") - } - } - } - - Label{ - y:5*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="Conversations" - text: "\uf086 " + qsTr("Conversations") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=0; - currentnewstabstatus="Conversations"; - newstypeSignal("conversation") - } - } - } - - - - Label{ - y:6.5*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="Replies" - text: "\uf0ec " + qsTr("Replies") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=1 - currentnewstabstatus="Replies"; - newstypeSignal("replies") - } - } - } - - Label{ - y:8*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="DirectMessages" - text: "\uf0e0 " + qsTr("Direct Messages") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=2//newstypeSignal("replies") - currentnewstabstatus="DirectMessages"; - } - } - } - Label{ - y:9.5*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="Favorites" - text: "\uf005 " + qsTr("Favorites") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=0; - currentnewstabstatus="Favorites"; - newstypeSignal("favorites") - } - } - } - - Label{ - y:11*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="Public Timeline" - text: "\uf0ac " + qsTr("Public Timeline") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=0; - currentnewstabstatus="Public Timeline"; - newstypeSignal("publictimeline") - } - } - } - - Label{ - y:12.5*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="Groupnews" - text: "\uf0c0 " + qsTr("Group news") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=0; - currentnewstabstatus="Groupnews"; - newstypeSignal("groupnews") - } - } - } - - Label{ - y:14*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="Search" - text: "\uf002 " + qsTr("Search") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=0; - currentnewstabstatus="Search"; - newstypeSignal("search") - } - } - } - - Label{ - y:15.5*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && currentnewstabstatus=="Notifications" - text: "\uf0f3 " + qsTr("Notifications") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - newsSwipeview.currentIndex=3; - currentnewstabstatus="Notifications"; - newstypeSignal("notifications") - } - } - } -} diff --git a/source-linux/qml/genericqml/ImagePickerLinux.qml b/source-linux/qml/genericqml/ImagePickerLinux.qml deleted file mode 100644 index 2e77f79..0000000 --- a/source-linux/qml/genericqml/ImagePickerLinux.qml +++ /dev/null @@ -1,187 +0,0 @@ -// This file is part of Friendiqa -// https://github.com/lubuwest/Friendiqa -// Copyright (C) 2020 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.0 -import QtQuick.Controls 2.12 -import Qt.labs.folderlistmodel 2.1 -import "qrc:/js/service.js" as Service -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/genericqml" - -Rectangle{ - id:imageDialog - z:2 - border.color: "grey" - width: parent.width-4*mm - height:parent.height-12*mm - x:2*mm - y:10*mm - property string directory: "" - property bool multiple: false - property string imageUrl: "" - property var imageUrls: [] - signal ready(); - function pickImage() {} - - Text{ - id:directoryText - x:0.5*mm - y:0.5*mm - width: imageDialog.width-15*mm - height:contentHeight - wrapMode: Text.Wrap - text: directory - } - Button{ - id:closeButton - height: 3*root.fontFactor*osSettings.bigFontSize - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - onClicked:{ready();imageDialog.destroy()} - } - - ListView { - id: imageView - x:0.5*mm - y: Math.max(directoryText.height, closeButton.height)+mm - width: imageDialog.width-2*mm - height: imageDialog.height-imageView.y-4*mm - clip: true - model: imageModel - delegate: imageItem - } - - FolderListModel{ - id: imageModel - nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG","*.gif"] - sortField: FolderListModel.Time - sortReversed:false - showDotAndDotDot: true - showDirs: true - showDirsFirst: true - folder:directory - } - - BusyIndicator{ - id: imageBusy - anchors.horizontalCenter: imageView.horizontalCenter - anchors.top:imageView.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - running:false - } - - Component{ - id:imageItem - Item{ - width:imageView.width - height:folderImage.height+2*mm - Rectangle{ - id:imagetextRectangle - color:"black" - x:mm - z:3 - opacity: fileIsDir?0:0.5 - width:imagetext.contentWidth - height: imagetext.contentHeight - anchors.bottom: folderImage.bottom - } - Text { - id:imagetext - x:fileIsDir?11*mm:mm - z:4 - text: fileName - width: fileIsDir?parent.width - 12*mm :imageView.width-mm - anchors.bottom: folderImage.bottom - color: fileIsDir?"black":"white" - font.pointSize: osSettings.bigFontSize - wrapMode:Text.Wrap - } - Text { - id:selected - anchors.right:parent.right - visible: attachImageURLs.indexOf(fileURL)>-1 - z:4 - text: "\u2713" - width: 10*mm - anchors.top: folderImage.top - color: "green" - font.pointSize: 3*osSettings.bigFontSize - } - - Image{id:folderImage - width: fileIsDir?10*mm: imageView.width-mm - fillMode:Image.PreserveAspectFit - source:fileIsDir?"qrc:/images/folder-blue.png":fileURL - } - - MouseArea{ - anchors.fill: parent - onClicked:{ - if (fileName==".."){ - imageModel.folder=imageModel.parentFolder; - directory=imageModel.parentFolder - } - else if (fileIsDir){ - imageModel.folder=fileURL; - directory=fileURL - } - else{ - if (multiple!=true){ - //attachImageURLs.push(fileURL); - //attachImage(fileURL); - imageUrls.push(fileURL); - imageUrl=fileURL; - ready(); - imageDialog.destroy() - } - else { - if(selected.visible==true){ - imageUrls.splice(imageUrls.indexOf(fileURL,1)) - selected.visible=false - } - else{ - imageUrls.push(fileURL); - selected.visible=true; - - } - imageUrl=fileURL - } - } - } - } - } - } -} diff --git a/source-linux/qml/genericqml/PermissionDialog.qml b/source-linux/qml/genericqml/PermissionDialog.qml deleted file mode 100644 index f016c67..0000000 --- a/source-linux/qml/genericqml/PermissionDialog.qml +++ /dev/null @@ -1,220 +0,0 @@ -// This file is part of Friendiqa -// https://github.com/lubuwest/Friendiqa -// Copyright (C) 2020 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 "qrc:/js/service.js" as Service -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/genericqml" - -Rectangle{ - id:permissionDialog -// x: mm - width: parent.width-5*mm - height:root.height/3 - function updatePerms(){ - for (var i=0;i-1){contactstatus="positive"} - else if (contact_deny.indexOf(contacts[name].cid)>-1){contactstatus="negative"} - contactModel.append({"contact":contacts[name],"contactstatus":contactstatus}) - }},"isFriend",1); - - Helperjs.readData(db,"groups",login.username,function(owngroups){ - for (var number in owngroups){ - var groupstatus= "neutral"; - if (group_allow.indexOf(owngroups[number].gid)>-1){groupstatus="positive"} - else if (group_deny.indexOf(owngroups[number].gid)>-1){groupstatus="negative"} - groupModel.append({"group":owngroups[number],"groupstatus":groupstatus}) - }}); - } -} diff --git a/source-linux/qml/newsqml/MessageSend.qml b/source-linux/qml/newsqml/MessageSend.qml deleted file mode 100644 index c975e25..0000000 --- a/source-linux/qml/newsqml/MessageSend.qml +++ /dev/null @@ -1,510 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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 . - -// message.qml -// message with buttons -import QtQuick 2.4 -import QtQuick.Controls 2.12 -//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:"#EEEEEE" - width:parent.width - height: conversation || (newsSwipeview.stacktype!="Notifications")?messageColumn.height+mm:0 - id:messageSend - visible:conversation || (newsSwipeview.stacktype!="Notifications")||(newstab.newstabstatus!="Search")?true:false - property string parentId: "" - property bool textfocus: false - //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 var contacts: [] - property var groups: [] - property var contact_allow:login.hasOwnProperty("permissions")?login.permissions[0]:[] - property var contact_deny:login.hasOwnProperty("permissions")?login.permissions[1]:[] - property var group_allow:login.hasOwnProperty("permissions")?login.permissions[2]:[] - property var group_deny:login.hasOwnProperty("permissions")?login.permissions[3]:[] - - function directmessagePrepare(friend){ - messageSend.state="active"; - reply_to_user=friend.screen_name; - receiverLabel.text=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){ - imageAttachment.source=url.toString(); - } - - function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { - //xhr.url= login.server + "/api/statuses/update.json"; - try{newsBusy.running=true;}catch(e){conversationBusy.running=true} - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/update"); - xhr.clearParams(); - xhr.setParam("source", "Friendiqa"); - xhr.setParam("htmlstatus", status); - if (parentId!="") {xhr.setParam("in_reply_to_status_id", parentId)}; - if (title!=="") {xhr.setParam("title", title)}; - if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))}; - if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; - if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; - if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; - if (attachImageURL.length>0) { - for (var image in attachImageURL){ - xhr.setImageFileParam("media", attachImageURL[image]); - xhr.setImageFileParam("angle", rotator.angle.toString()); - } - }; - xhr.post(); - Newsjs.storeHashtags(login,db,status,root) - } - - 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); - xhr.setApi("/api/direct_messages/new"); - xhr.clearParams(); - xhr.setParam("text", text); - xhr.setParam("screen_name", screen_name); - if (parentId!="") {xhr.setParam("replyto", replyto)}; - //if (title!=="") {xhr.setParam("title", title)}; - xhr.post(); - } - - function setParent(newsitemobject){ - //print("Newsobject "+newsitemobject.id+ " "+JSON.stringify(newsitemobject.user)); - if (newsitemobject!=""){ - messageSend.state="conversation" - messageSend.reply_to_user=newsitemobject.user.screen_name; - messageSend.parentId=newsitemobject.id - } else { - //messageSend.state=null; - messageSend.reply_to_user=""; - messageSend.parentId=""; - bodyField.text=""; - attachImageURLs.pop(); - imageAttachment.source="" - } - } - - function contactmenu(letter){//print("letter "+letter) - Newsjs.listFriends(login,db,function(contacts){ - contactModel.clear(); - for (var i=0;i1) - 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+4*mm,10*mm) - - TextArea { - id: bodyField - property string contactprefix:"" - property string placeholder: osSettings.osType=="Linux"? qsTr(" Drop your Content here."):"" - anchors.fill: parent - font.pointSize: osSettings.systemFontSize - font.family: "Noto Sans" - wrapMode: Text.Wrap - selectByMouse: true - placeholderText: conversation?"": (qsTr("What's on your mind?")+placeholder) - textFormat: TextEdit.RichText //TextEdit.PlainText - onLineCountChanged: (conversation==true)?conversationView.contentY=conversationView.contentY+3*mm:newsView.contentY=newsView.contentY+3*mm - onLinkActivated:{Qt.openUrlExternally(link)} - onActiveFocusChanged:{//print(placeholder) - if (activeFocus==true){ - if (conversation==true){ - if(parentId==""){setParent(conversationModel.get(0).newsitemobject);} - messageSend.state="conversation"; - try{conversationView.contentY=conversationView.contentY+20*mm}catch(e){} - } else if (textfocus==false){ - messageSend.state="active"; - newsView.positionViewAtBeginning(); - } - } - } - onTextChanged:{ - if (text!=""){ - var plaintext=getText(0,cursorPosition) - //print(plaintext+plaintext.lastIndexOf("@",cursorPosition)+getText(plaintext.lastIndexOf('@',cursorPosition),cursorPosition) +" preedit: "+ preeditText+cursorPosition); - var regex1 = /@[a-z]+/;var regex2 = /![a-z]+/;var regex3 = /\s/; - //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(plaintext.lastIndexOf('@',cursorPosition),cursorPosition)+preeditText) && !regex3.test(getText(plaintext.lastIndexOf('@',cursorPosition),cursorPosition)+preeditText)){ - var letter=(getText(plaintext.lastIndexOf('@',cursorPosition),cursorPosition)).match(/[a-z]+/); - contactprefix="@"; - contactmenu(letter.toString()) - } else if( regex2.test(getText(plaintext.lastIndexOf('!',cursorPosition),cursorPosition)+preeditText) && !regex3.test(getText(plaintext.lastIndexOf('!',cursorPosition),cursorPosition)+preeditText) ){ - var letter=(getText(plaintext.lastIndexOf('!',cursorPosition),cursorPosition)).match(/[a-z]+/); - contactprefix="!"; - contactmenu(letter.toString()) - }else {contactSelector.visible=false} - }else{contactSelector.visible=false} - } - } - } - - ListView{ - id:contactSelector - visible: false - z:3 - x:8*mm - width: parent.width-9*mm - height: messageSend.height/2 - model:contactModel - function processContactSelection(contact){ - if(Helperjs.getCount(db,login,"contacts","screen_name",contact.screen_name)>1){ - contact.screen_name=contact.screen_name+"+"+contacts.cid - } - if (newsSwipeview.stacktype=='DirectMessages'){ - receiverLabel.text=contact.screen_name; - reply_to_user=contact.screen_name - } else { - bodyField.remove(bodyField.getText(0,bodyField.cursorPosition).lastIndexOf(bodyField.contactprefix,bodyField.cursorPosition),bodyField.cursorPosition); - bodyField.insert(bodyField.cursorPosition, bodyField.contactprefix+contact.screen_name+" "); - bodyField.cursorPosition=bodyField.cursorPosition+contact.screen_name.length+1 - } - //receiverLabel.text=contact.screen_name; - contactSelector.visible=false - } - delegate: ContactComponent { } - } - ListModel{id:contactModel} - - ListView{ - id: tagSelector - visible: false - z:3 - x:8*mm - width: parent.width-9*mm - height: messageSend.height/2 - model:tagModel - clip: true - spacing: 0 - function processTagSelection(hashtag){ - bodyField.insert(bodyField.cursorPosition, hashtag+" "); - bodyField.cursorPosition=bodyField.cursorPosition+hashtag.length+1 - tagSelector.visible=false - } - delegate: MButton {text:tag;onClicked: tagSelector.processTagSelection(tag)} - } - ListModel{id:tagModel} - - Item{ - id:imageAttachment; - property alias source:realimage.source - //property alias angle:rotator.angle - visible: source!="" - width: 45*mm - height: 45*mm; - MouseArea{ - anchors.fill: parent - onClicked: { - attachImageURLs.splice(attachImageURLs.indexOf(source),1); - imageAttachment.source="" - } - } - Image{id:realimage - source:""; - x:2*mm; - width: 45*mm; - height: source==""?0:45*mm; - fillMode: Image.PreserveAspectFit; - transform: Rotation {id:rotator; origin.x: 22.5*mm; origin.y: 22.5*mm; angle: 0} - - } - Rectangle{ - width: 5*mm - height: 5*mm - visible: imageAttachment.source!="" - anchors.bottom: imageAttachment.bottom - anchors.right: imageAttachment.right - color: "black" - opacity: 0.5 - Text{anchors.centerIn:parent;text: "\uf01e";color: "white"} - MouseArea{ - anchors.fill:parent; - onClicked:{ - rotator.angle+=90; - } - } - } - } - - Row{ - id:buttonRow - visible:false //(bodyField.length>1)||(attachImageURLs.length>0) - spacing: mm - height: 12*mm - x: 0.5*mm - MButton{id:permButton - visible: !conversation && (newsSwipeview.stacktype!=="DirectMessages") - height: 2*root.fontFactor*osSettings.bigFontSize - width: 2*root.fontFactor*osSettings.bigFontSize - 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: 2*root.fontFactor*osSettings.bigFontSize - width: 2*root.fontFactor*osSettings.bigFontSize - text: "\uf03e" - visible:!conversation?(newsSwipeview.stacktype!="DirectMessages"):true - 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=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"); - imagePicker.pickImage() - } - } - } - - MButton{ - id:smileyButton - text: "\uf118" - height: 2*root.fontFactor*osSettings.bigFontSize - width: 2*root.fontFactor*osSettings.bigFontSize - onClicked: {if (smileyDialog.visible==false){smileyDialog.visible=true} else{smileyDialog.visible=false}} - } - - MButton{ - id:hastagButton - text: "\uf292" - height: 2*root.fontFactor*osSettings.bigFontSize - width: 2*root.fontFactor*osSettings.bigFontSize - onClicked: {if (tagSelector.visible==false){hashtagmenu()} else{tagSelector.visible=false}} - } - - MButton { - id: cancelButton - height: 2*root.fontFactor*osSettings.bigFontSize - width: 2*root.fontFactor*osSettings.bigFontSize - text: "\uf057" - onClicked: { - if (textfocus==true){messageSend.destroy()} - else{ - bodyField.text=""; - messageSend.state=""; - permissionDialog.visible=false; - receiverLabel.visible=false; - reply_to_user=""; - attachImage(""); - attachImageURLs.pop(); - } - } - } - MButton { - id: sendButton - height: 2*root.fontFactor*osSettings.bigFontSize - width: 2*root.fontFactor*osSettings.bigFontSize - text: "\uf1d9" - onClicked: { - var title=titleField.text.replace("\"","\'"); - var body=bodyField.getFormattedText(0,bodyField.length); - var dmbody=bodyField.getText(0,bodyField.length); - if (conversation || newsSwipeview.stacktype!=="DirectMessages"){ - statusUpdate(title,body,parentId,attachImageURLs)} - 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=root.globaloptions.newsViewType; rootstackView.pop(null) - } - } - } - } - PermissionDialog{id:permissionDialog;x:mm;visible: false} - SmileyDialog{id:smileyDialog;x:mm;visible: false} - } - Component.onCompleted:{ - root.replySignal.connect(setParent); - root.directmessageSignal.connect(directmessagePrepare); - root.uploadSignal.connect(sendUrls); - root.sendtextSignal.connect(sendtext); - if (textfocus==true){bodyField.forceActiveFocus()} - } - - 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:(!conversation&&newsSwipeview.stacktype!="DirectMessages") - } - }, - - State { - name: "reply" - PropertyChanges { - target: messageColumn; height: implicitHeight - } - PropertyChanges { - target: buttonRow; visible:true - } - PropertyChanges { - target: titleField; visible:false - } - PropertyChanges { - target: bodyField; placeholderText:"";focus:true - } - PropertyChanges { - target: stackTypeDescription; visible:false - } - } - ] -} diff --git a/source-linux/qml/newsqml/NewsStack.qml b/source-linux/qml/newsqml/NewsStack.qml deleted file mode 100644 index e77cd69..0000000 --- a/source-linux/qml/newsqml/NewsStack.qml +++ /dev/null @@ -1,444 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.12 -import "qrc:/js/news.js" as Newsjs -import "qrc:/js/helper.js" as Helperjs -import "qrc:/js/service.js" as Service - -Rectangle{ - id: newsStack - //anchors.fill: parent - width: parent.width - height: parent.height - property string updateMethodNews: "refresh" - property var allchats: ({}) - property int lastnewsid:0 - property string newstabstatus: "" - - BusyIndicator{ - id: newsBusy - //visible: false - anchors.horizontalCenter: parent.horizontalCenter - anchors.top:parent.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - z:2 - running: false - } - - 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": - newsStack.updateMethodNews="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"; - newstab.newstabstatus="Groupnews"; - Service.showGroups(); - break; - case "search": - newsView.anchors.topMargin=7*mm; - newstab.newstabstatus="Search"; - newsBusy.running=false; - var leftoffset=osSettings.osType=="Android"?3*osSettings.bigFontSize:0 - var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml"); - var searchItem = component.createObject(newsStack,{y:mm,x:leftoffset,width:root.width-leftoffset,height: 5*mm}); - break; - case "refresh": - if (newstab.newstabstatus=="Timeline" || newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else if (newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ - newsStack.updateMethodNews="conversation"} - else {newsStack.updateMethodNews="refresh"} - - 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" || newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else if (newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ - newsStack.updateMethodNews="conversation"} - 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 (rootstackView.depth>1){rootstackView.pop()}}catch(e){} - newsBusy.running=false; - var currentTime= new Date(); - // downloadNotice.text=downloadNotice.text + "\n shownews start "+ Date.now(); - //print("appendnews "+JSON.stringify(newsToShow)) - if (newsToShow.length==1){var method="refresh"}else{var method = newsStack.updateMethodNews} - var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow,'method':method, 'options':globaloptions}; - newsWorker.sendMessage(msg); - //newsStack.appendNews=false - } - - - - function search(term){ - if (term!=""){ - //newstab.newstabstatus="Search"; - 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 - } - - function getOldNews(){ - var currentTime= new Date(); - try{var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at;} catch(e){var lastnews_id=99999999999999 } - 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" || newstabstatus=="Timeline" ){ - Newsjs.newsfromdb(root.db,root.login, messagetype,function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'method':"", 'options':globaloptions}; - newsWorker.sendMessage(msg); - },false,lastnews_id)} - - else if(newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ - Newsjs.chatsfromdb(root.db,root.login, messagetype,function(news){ - var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'method':"", 'options':globaloptions}; - newsWorker.sendMessage(msg); - },lastnews_id)} - - else if (newstab.newstabstatus=="Notifications" || newstabstatus=="Notifications"){} - else{ - 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; - } - - try{xhr.setParam("max_id",newsModel.get(newsModel.count-1).newsitemobject.id-1);}catch(e){} - xhr.get() - } - } - Connections{ - target:xhr - function onError(data,url,api,code){ - if (data !="contactlist"){Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root);} - newsBusy.running=false; - } - function onSuccess(data,api){ - // downloadNotice.text=downloadNotice.text+ "\n xhr finished "+Date.now(); - Service.processNews(api,data) - replySignal("") - } - } - - 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" || newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else if (newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ - newsStack.updateMethodNews="conversation"} - 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) - } - } - } - - Component { id:footerComponent - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - width:newsView.width - height:6*mm - Text{ - font.pointSize: osSettings.systemFontSize - anchors.centerIn: parent - text:qsTr("More") - } - MouseArea{ - anchors.fill:parent - onClicked:{ - if (newsModel.count==0){ - if (newsSwipeview.stacktype=="Home"){ - 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") - } - } - else {getOldNews();} - } - } - } - } - - ListView { - id: newsView - property real oldContentY:0 - property bool viewdragged: false - property bool viewdraggedpositive: false - property string viewtype: "news" - width: parent.width - height: parent.height-3*mm - //anchors.fill: parent - anchors.margins: 0.5*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 (verticalOvershoot>5*mm){ - viewdraggedpositive=true - } - else{ - if((contentY-oldContentY)>15*mm){ - //swipeIndicator.visible=false; - //newsSwipeview.height=rootstack.height; - //newsSwipeview.y=0; - //rootStackItem.state="fullscreen" - } - else if ((contentY-oldContentY)<-15*mm){ - //swipeIndicator.visible=true; - //newsSwipeview.height=rootstack.height-12*mm; - //newsSwipeview.y=5*mm; - //rootStackItem.state="" - } - } - } - onViewdraggedChanged: { - if (viewdragged){ - var onlynew=true; - newsBusy.running=true; - viewdragged=false - if (newstab.newstabstatus=="Timeline" || newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else if (newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ - newsStack.updateMethodNews="conversation"} - else {newsStack.updateMethodNews="refresh"} - - 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") - } - - } - } - onViewdraggedpositiveChanged: { - if (viewdraggedpositive){ - getOldNews(); - viewdraggedpositive=false - } - } - ScrollBar.vertical: ScrollBar { } - } - - ListModel{id: newsModel} - - WorkerScript { - id: newsWorker - source: "qrc:/js/newsworker.js" - } - - - 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.pointSize: osSettings.systemFontSize - text:"" - } - } - - Component.onCompleted: { - root.newstypeSignal.connect(newstypeHandling); - root.contactdetailsSignal.connect(showContact); - root.newsSignal.connect(showNews); - root.searchSignal.connect(search); - try{newsModel.clear()} catch(e){} - swipeIndicator.visible=true; - //newsSwipeview.height=rootstack.height//-12*mm; - //newsSwipeview.y=5*mm; - //rootStackItem.state="" - root.globaloptions.hasOwnProperty("newsViewType")?newstab.newstabstatus=root.globaloptions.newsViewType:newstab.newstabstatus="Conversations"; - newstabstatus=newstab.newstabstatus; - 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=="Conversations")&&(newsSwipeview.stacktype=="Home")){ - if((newstabstatus=="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 deleted file mode 100644 index 7257bfe..0000000 --- a/source-linux/qml/newsqml/NewsTab.qml +++ /dev/null @@ -1,213 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.12 -import "qrc:/qml/newsqml" -import "qrc:/qml/genericqml" -import "qrc:/js/news.js" as Newsjs -import "qrc:/js/helper.js" as Helperjs -import "qrc:/js/service.js" as Service - -Rectangle{ - id:newstabitem - width:rootstack.width - height: rootstack.height-8*mm - - Timer {id:contacttimer; interval: 50; running: false; repeat: false - onTriggered: { - root.newContacts=Newsjs.findNewContacts(root.news,root.contactlist); - root.onNewContactsChanged(root.newContacts); - Newsjs.storeNews(login,db,root.news,root) - } - } - - function showConversation(conversationIndex,newsitemobject){ - if(newsitemobject.messagetype==0 || newsitemobject.messagetype==3){ - xhr.clearParams(); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/conversation/show"); - xhr.setParam("id",newsitemobject.id) - xhr.setParam("count","200") - xhr.get(); - } - else{ - xhr.clearParams(); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/direct_messages/conversation"); - xhr.setParam("uri",newsitemobject.statusnet_conversation_id) - xhr.get(); - } - } - - function getDateDiffString (seconds){ - var timestring=""; - if (seconds<60) {timestring= Math.round(seconds) + " " +qsTr("seconds");} - else if (seconds<90){timestring= Math.round(seconds/60) + " " +qsTr("minute") ;} - else if (seconds<3600){timestring= Math.round(seconds/60) + " " +qsTr("minutes");} - else if (seconds<5400){timestring= Math.round(seconds/3600) + " " +qsTr("hour");} - else if (seconds<86400){timestring= Math.round(seconds/3600) + " " +qsTr("hours");} - else if (seconds<129600){timestring= Math.round(seconds/86400) + " " +qsTr("day");} - else if (seconds<3888000){timestring= Math.round(seconds/86400) + " " +qsTr("days");} - else if (seconds<5832000){timestring= Math.round(seconds/3888000) + " " +qsTr("month");} - else if (seconds<69984000){timestring= Math.round(seconds/3888000) + " " +qsTr("months");} - else {timestring= Math.round(seconds/46656000) + " " + qsTr("years");} - - return timestring; - } - - function getActivitiesView(newsitemobject){ - var likeText="";var dislikeText="";var attendyesText="";var attendnoText="";var attendmaybeText=""; var self={}; - try{if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_activities')){ - if (newsitemobject.friendica_activities.like.length>0){ - if (newsitemobject.friendica_activities.like.length==1){likeText= newsitemobject.friendica_activities.like[0].name+" "+ qsTr("likes this.")} - else {likeText= newsitemobject.friendica_activities.like.length+" "+ qsTr("like this.")} - } - if (newsitemobject.friendica_activities.dislike.length>0){ - if (newsitemobject.friendica_activities.dislike.length==1){dislikeText= newsitemobject.friendica_activities.dislike[0].name+" "+ qsTr("doesn't like this.")} - else {dislikeText= newsitemobject.friendica_activities.dislike.length+" "+ qsTr("don't like this.")} - } - if (newsitemobject.friendica_activities.attendyes.length>0){ - if (newsitemobject.friendica_activities.attendyes.length==1){attendyesText=newsitemobject.friendica_activities.attendyes[0].name+" "+ qsTr("will attend.")} - else {attendyesText= newsitemobject.friendica_activities.attendyes.length+" "+ qsTr("persons will attend.")} - } - if (newsitemobject.friendica_activities.attendno.length>0){ - if (newsitemobject.friendica_activities.attendno.length==1){attendnoText= newsitemobject.friendica_activities.attendno[0].name+" "+ qsTr("will not attend.")} - else {attendnoText= newsitemobject.friendica_activities.attendno.length+" "+ qsTr("persons will not attend.")} - } - if (newsitemobject.friendica_activities.attendmaybe.length>0){ - if (newsitemobject.friendica_activities.attendmaybe.length==1){attendmaybeText= newsitemobject.friendica_activities.attendmaybe[0].name+" "+ qsTr("may attend.")} - else {attendmaybeText= newsitemobject.friendica_activities.attendmaybe.length+" "+ qsTr("persons may attend.")} - } - //var friendica_activities_self=JSON.parse(newsitemobject.friendica_activities_self); - }} catch(e){print("Activities "+e+ " "+JSON.stringify(newsitemobject.friendica_activities))} - return {likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText} - } - - - -// CalendarTab{ -// visible: wideScreen&&rootstackView.depth<2 -// width: newstabitem.width/3 -// x: newsSwipeview.width -// //anchors.left: newsSwipeview.right -// //anchors.fill: null -// } -// Rectangle{ -// color: "#F8F8F8" -// height: parent.height -// width: 0.5*mm -// anchors.left: newsSwipeview.right -// } - BlueButton{ - x:mm - y:mm - z:2 - visible: !wideScreen - fontColor: "grey" - border.color: "transparent" - text: "\uf0c9" - font.pointSize: osSettings.bigFontSize - onClicked:{ - leftDrawerAndroid.visible?leftDrawerAndroid.close():leftDrawerAndroid.open()} - } - - LeftDrawerLinux{ - id:leftDrawer - property var newstabstatus: newstab.newstabstatus - visible: wideScreen&&rootstackView.depth<2 - width: visible?root.fontFactor*osSettings.systemFontSize*15:0 - height: root.height-bar.height - } - - LeftDrawerAndroid{ - id: leftDrawerAndroid - } - - SwipeView{ - id: newsSwipeview - property string stacktype:"Home" - currentIndex: 0 - width: wideScreen&&rootstackView.depth<2?newstabitem.width-leftDrawer.width:newstabitem.width//newstabitem.width/3*2:newstabitem.width - height: newstabitem.height-4*mm - x: leftDrawer.width - function onDirectMessage(friend){currentIndex=2} - - 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" - } - Loader{ - id: replies - //property string stacktype:"Replies" - source:(newsSwipeview.currentIndex==1)? "qrc:/qml/newsqml/NewsStack.qml":"" - //onLoaded: newsSwipeview.stacktype="Replies" - } - Loader{ - id: directmessages - property var friend:({}) - source:(newsSwipeview.currentIndex==2)? "qrc:/qml/newsqml/NewsStack.qml":"" - //onLoaded: newsSwipeview.stacktype="DirectMessages" - } - Loader{ - id: notifications - //property string stacktype:"Notifications" - source:(newsSwipeview.currentIndex==3)? "qrc:/qml/newsqml/NewsStack.qml":"" - //onLoaded: newsSwipeview.stacktype="Notifications" - } - } - PageIndicator { - id: swipeIndicator - z:5 - height: root.fontFactor*osSettings.bigFontSize - font.pointSize: osSettings.systemFontSize - count: newsSwipeview.count - currentIndex: newsSwipeview.currentIndex - anchors.bottom: newsSwipeview.bottom - anchors.horizontalCenter: parent.horizontalCenter - } - - Component.onCompleted: {root.directmessageSignal.connect(newsSwipeview.onDirectMessage)} -} diff --git a/source-linux/qml/newsqml/SmileyDialog.qml b/source-linux/qml/newsqml/SmileyDialog.qml deleted file mode 100644 index d2ca2a9..0000000 --- a/source-linux/qml/newsqml/SmileyDialog.qml +++ /dev/null @@ -1,217 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.12 -import QtQuick.Layouts 1.11 -import "qrc:/js/smiley.js" as Smileyjs -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/genericqml" - -Rectangle{ - id:smileyDialog - x: mm - width: messageColumn.width-5*mm - height:root.height/2 - - MButton{ - id:closeButton - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - onClicked:{smileyDialog.visible=false} - } - - - TabBar { - id: smileybar - width: parent.width - height: 9*mm - position:TabBar.Header - TabButton { - text:qsTr("Unicode") - font.pointSize: osSettings.systemFontSize - } - TabButton { - text: qsTr("Standard") - font.pointSize: osSettings.systemFontSize - } - TabButton { - text: qsTr("Addon") - font.pointSize: osSettings.systemFontSize - } - - TabButton { - text: qsTr("Adult") - font.pointSize: osSettings.systemFontSize - } - } - - - StackLayout{ - id:smileyTabView - currentIndex: smileybar.currentIndex - anchors.top: closeButton.bottom - anchors.topMargin: 1*mm - width: smileyDialog.width-2*mm - height: smileyDialog.height-4*root.fontFactor*osSettings.bigFontSize - Rectangle{ - id: htmlGridTab - GridView { - id:htmlView - anchors.fill: parent - cellWidth: 5*mm - cellHeight: 5*mm - clip: true - model: htmlModel - delegate: htmlItem - } - - ListModel{ - id:htmlModel - } - Component.onCompleted:{ - for (var icon in Smileyjs.html){ - htmlModel.append({"emoji":Smileyjs.html[icon]}) - } - } - } - - Rectangle{ - id: coreGridTab - GridView { - id: coreSmileyView - anchors.fill: parent - cellWidth: 5*mm - cellHeight: 5*mm - clip: true - model: coreSmileyModel - delegate: smileyItem - } - - ListModel{ - id: coreSmileyModel - } - - Component.onCompleted:{ - var smileyarray=Smileyjs.core - for (var icon in smileyarray){ - coreSmileyModel.append({"emoji":smileyarray[icon]}) - } - } - } - - Rectangle{ - id: addonGridTab - GridView { - id: addonView - anchors.fill: parent - cellWidth: 5*mm - cellHeight: 5*mm - clip: true - model: addonModel - delegate: smileyItem - } - - ListModel{ - id: addonModel - } - Component.onCompleted:{ - for (var icon in Smileyjs.addon){ - addonModel.append({"emoji":Smileyjs.addon[icon]}) - } - } - } - - - Rectangle{ - id: adultGridTab - GridView { - id: adultView - anchors.fill: parent - cellWidth: 5*mm - cellHeight: 5*mm - clip: true - model: adultModel - delegate: smileyItem - } - - ListModel{ - id: adultModel - } - Component.onCompleted:{ - for (var icon in Smileyjs.adult){ - adultModel.append({"emoji":Smileyjs.adult[icon]}) - } - } - } - } - Component{ - id:smileyItem - AnimatedImage{id:smileyImage - width:4.5*mm - height: 4.5*mm - fillMode:Image.PreserveAspectFit - source:emoji.url - - MouseArea{ - anchors.fill: parent - onClicked:{ - //bodyField.append(emoji.name+" ") - bodyField.insert(bodyField.cursorPosition,emoji.name+" "); - smileyDialog.visible=false - } - } - } - } - - Component{ - id:htmlItem - Text{id:smileText - width:4.5*mm - height: 4.5*mm - textFormat:Text.RichText - font.pointSize: 1.2*osSettings.systemFontSize - text: emoji - - MouseArea{ - anchors.fill: parent - onClicked:{ - //bodyField.append(emoji.name+" ") - bodyField.insert(bodyField.cursorPosition,emoji+" "); - smileyDialog.visible=false - } - } - } - } - } diff --git a/source-linux/qml/photoqml/PhotoTab.qml b/source-linux/qml/photoqml/PhotoTab.qml deleted file mode 100644 index ff78708..0000000 --- a/source-linux/qml/photoqml/PhotoTab.qml +++ /dev/null @@ -1,325 +0,0 @@ -// This file is part of Friendiqa -// https://git.friendi.ca/lubuwest/Friendiqa -// Copyright (C) 2020 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.5 -import QtQuick.Controls 2.12 -import QtQml.Models 2.1 -import "qrc:/js/image.js" as Imagejs -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/photoqml" -import "qrc:/qml/genericqml" - - -StackView{ - id: photoStack - //anchors.fill:parent - initialItem:Rectangle { - id:fotorectangle - anchors.fill:parent -// y:1 -// width:root.width-mm -// height:root.height-5*mm - color: '#fff' - property var newimages:[] - property int currentimageno: 0 - property bool remoteContact: false - - - onNewimagesChanged:{ - if(fotorectangle.newimages.length>0){ - //print("newimages "+JSON.stringify(newimages)); - var ownimagelist=[]; - Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){ - for (var i=0;i1){photoStack.pop()} - if(!albumgridview.currentItem){root.currentIndex=0} - if(albumgridview.currentItem.state=='fullscreen'){ - albumgridview.currentItem.state = 'inGrid'} - else if (albumgridview.currentItem.state == 'inGrid'){albumgridview.currentItem.state=''} - else{root.currentIndex=0} - } - else{ - try {photogroupModel.clear()}catch (e){print(e)} - if (friend){ - Imagejs.newRequestFriendsAlbumPictures(login,friend,fotorectangle,function(albums,remoteAuthBool){ - remoteContact=remoteAuthBool; - var msg = {'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture':true,'friend':friend} - photoWorker.sendMessage(msg); - }) - phototabstatusButton.text=friend.screen_name+qsTr("\'s images") - - } - else { - Helperjs.readField("album", db, "imageData",login.username,function(albums){ - if (albums[0]) { - var msg = { 'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture': false}; - photoWorker.sendMessage(msg); - } - }) - } - } - } - - function deletepics(method, type,id){ - if(method=="delete"){Imagejs.deleteImage(db,login,type, id,filesystem,root,function(){//showFotos("") - })} - } - function updatepic(method,type,id){ - if(method=="update"){ - Helperjs.readData(db,"imageData",login.username,function(url){ - 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("qrc:/qml/photoqml/ImageUploadDialog.qml",{"attachImageURLs":urls}) - } - - BlueButton{ - x:mm - y:mm - z:2 - visible: !wideScreen - fontColor: "grey" - border.color: "transparent" - text: "\uf0c9" - font.pointSize: osSettings.bigFontSize - onClicked:{ - leftDrawerAndroid.visible?leftDrawerAndroid.close():leftDrawerAndroid.open()} - } - - LeftDrawerLinux{ - id:leftDrawer - property var newstabstatus: newstab.newstabstatus - visible: wideScreen&&rootstackView.depth<2 - width: visible?osSettings.systemFontSize*15:0 - height: root.height-bar.height - } - - LeftDrawerAndroid{ - id: leftDrawerAndroid - } - - ProgressBar{ - id: newImagesProgress - width: 15*mm - height: updatePhotolist.height - anchors.top: parent.top - anchors.right:uploadPhoto.left - anchors.rightMargin:mm - visible: false - value: fotorectangle.currentimageno/fotorectangle.newimages.length - } - - MButton{ - id: uploadPhoto - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right:updatePhotolist.left - anchors.rightMargin:mm - text:"\uf0ee" - onClicked: { - photoStack.push("qrc:/qml/photoqml/ImageUploadDialog.qml"); -// var component = Qt.createComponent("qrc:/qml/photoqml/ImageUploadDialog.qml"); -// var imageUpload = component.createObject(fotorectangle); - }} - - MButton{ - id: updatePhotolist - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right:phototabstatusButton.left - anchors.rightMargin:mm - text:"\uf0ed" - - Menu { - id:photoupdatemenu - width:8*root.fontFactor*osSettings.bigFontSize - MenuItem { - text: qsTr("All Images") - font.pointSize: osSettings.bigFontSize - onTriggered: { - Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){fotorectangle.newimages=obj})} - } - MenuItem { - text: qsTr("Only new") - font.pointSize: osSettings.bigFontSize - onTriggered: { - Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){fotorectangle.newimages=obj})} - } - } - onClicked: {photoupdatemenu.popup()} - } - - MButton{ - id: phototabstatusButton - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right: parent.right - anchors.rightMargin:2*mm - width: Math.max(8*root.fontFactor*osSettings.bigFontSize,implicitWidth) - text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus - Menu { - id:phototabmenu - width: 20*root.fontFactor*osSettings.bigFontSize - MenuItem { - text: qsTr("Own Images") - font.pointSize: osSettings.bigFontSize - onTriggered: { - fotostab.phototabstatus="Images"; - // phototabstatusButton.text=qsTr("Own images"); - showFotos(root.login,"")} - } - } - onClicked: {phototabmenu.popup()} - } - - - DelegateModel{ - id: visualphotoModel - delegate: PhotogroupComponent{} - model: photogroupModel - } - - ListModel{ - id: photogroupModel - } - - GridView { - id: albumgridview - cellWidth: 17*mm - cellHeight: 17*mm - x: leftDrawer.width//mm; - y:8*mm - width: wideScreen&&rootstackView.depth<2?parent.width-leftDrawer.width-mm:parent.width-mm //parent.width-2*mm; - height: parent.height-9*mm - clip: true - model: visualphotoModel.parts.album - footer:Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - width:12*mm - height:6*mm - Text{ - font.pointSize: 0.75*osSettings.systemFontSize - anchors.centerIn: parent - text:qsTr("More") - } - MouseArea{anchors.fill:parent - onClicked:{//print(photogroupModel.get(0).foreignPicture); - var lastalbum_id=photogroupModel.count-1; - if(photogroupModel.get(photogroupModel.count-1).foreignPicture==true){ - Imagejs.newRequestFriendsAlbumPictures(login,photogroupModel.get(0).friend,fotorectangle,function(albums,remoteAuthBool){ - remoteContact=remoteAuthBool; - var msg = {'model': photogroupModel,'albums':albums,'firstalbum':lastalbum_id+1,'foreignPicture':true,'friend':photogroupModel.get(0).friend} - photoWorker.sendMessage(msg) - }) - } - else{Helperjs.readField("album",root.db, "imageData",root.login.username,function(albums){ - var msg = { 'model': photogroupModel,'albums':albums,'foreignPicture': false,'firstalbum':lastalbum_id+1}; - photoWorker.sendMessage(msg)})} - }}} - } - - Rectangle { id: photoBackground; color: 'black'; width: parent.width; height: parent.height; opacity: 0; visible: opacity != 0.0 } - - ListView { width: parent.width; height:parent.height; model: visualphotoModel.parts.browser; interactive: false } - - MButton { - id: backButton - text: "\uf057" - x: parent.width - backButton.width - root.fontFactor*osSettings.bigFontSize - y: -backButton.height - root.fontFactor*osSettings.bigFontSize - z:2 - onClicked: {photoBackground.opacity=0} - } - - ListView {anchors.fill: parent; model: visualphotoModel.parts.fullscreen; interactive: false } - WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"} - - Component.onCompleted: { - root.fotoSignal.connect(showFotos); - root.uploadSignal.connect(uploadUrls); - root.changeimage.connect(deletepics); - root.changeimage.connect(updatepic); - if (fotostab.phototabstatus=="Images"){showFotos(root.login,"")} - } - } -} diff --git a/source-linux/translations/friendiqa-de.qm b/source-linux/translations/friendiqa-de.qm deleted file mode 100644 index 4128452..0000000 Binary files a/source-linux/translations/friendiqa-de.qm and /dev/null differ diff --git a/source-linux/translations/friendiqa-es.qm b/source-linux/translations/friendiqa-es.qm deleted file mode 100644 index 6918aee..0000000 Binary files a/source-linux/translations/friendiqa-es.qm and /dev/null differ diff --git a/source-linux/translations/friendiqa-es.ts b/source-linux/translations/friendiqa-es.ts deleted file mode 100644 index f21ced5..0000000 --- a/source-linux/translations/friendiqa-es.ts +++ /dev/null @@ -1,1503 +0,0 @@ - - - - - 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 - No se admiten los apodos que contienen el símbolo @ actualmente - - - - 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 - - - - ConfigPage - - - News as - Noticias como - - - - - - Conversations - Conversaciones - - - - - Timeline - Cronología - - - - Max. News - Nº Max. de noticias. - - - - Hide #nsfw? - Ocultar #nsfw? - - - - Sync - Sincronización - - - - 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 - - - Interval (0=None) - Intervalo (0=ningún) - - - Error - Error - - - Confirm - Confirmar - - - No server given! - ¡Servidor no encontrado! - - - No nickname given! - ¡Usuario incorrecto! - - - Nickname not registered at given server! - ¡Usuario incorrecto! - - - No username given! - ¡Usuario incorrecto! - - - No password given! - ¡Contraseña incorrecta! - - - No image directory given! - ¡No se ha encontrado el directorio de imágenes! - - - No maximum news number given! - ¡Nº máximo de noticias incorrecto! - - - Wrong password! - ¡Contraseña incorrecta! - - - Success - éxito! - - - Name - Nombre - - - Timeline - Cronología - - - Conversations - Conversaciones - - - - ContactComponent - - - Connect - Conectar - - - - ContactDetailsComponent - - Connect - Conectar - - - Description - Descripción - - - Location - Localización - - - Posts - Mensajes - - - URL - URL - - - Created at - Creado en - - - - ContactPage - - - seconds - Segundos - - - - minute - Minuto - - - - minutes - Minutos - - - - hour - Hora - - - - hours - Horas - - - - day - Dia - - - - days - Dias - - - - month - Mes - - - - months - Meses - - - - years - Años - - - - 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. - - - - Connect - Conectar - - - - Approve - Aprobar - - - - Reject - Rechazar - - - - Ignore - Ignorar - - - - Description - Descripción - - - - Location - Localización - - - - Posts - Mensajes - - - - URL - URL - - - - Created at - Creado en - - - - Network Error - Fallo de red - - - - Conversation - - - seconds - Segundos - - - - minute - Minuto - - - - minutes - Minutos - - - - hour - Hora - - - - hours - Horas - - - - day - Dia - - - - days - Dias - - - - month - Mes - - - - months - Meses - - - - years - Años - - - - 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. - - - - DrawerAccountComponent - - - Refresh - Actualizar - - - - Timeline - Cronología - - - - Conversations - Conversaciones - - - - Replies - Respuestas - - - - Direct Messages - Mensaje directo - - - - Favorites - Favoritos - - - - Public Timeline - Cronología pública - - - - Group news - Grupos - - - - Search - Busca - - - - Notifications - Notificaciones - - - - DrawerAccountComponentContacts - - - Profile - Perfil - - - - Friends - Amigos - - - - Contacts - Contactos - - - - Groups - Grupos - - - - EventList - - Location - Localización - - - - EventListItem - - - Location - Localización - - - - FriendsListTab - - - Friend Requests - Solicitudes de contacto - - - - Friends - Amigos - - - - FriendsTab - - - Me - Yo - - - - Friends - Amigos - - - - Contacts - Contactos - - - - Groups - Grupos - - - - ImageUploadDialog - - - Upload to album - Subir álbum - - - Album - álbum - - - Image - imagen - - - - Description - Descripción - - - - Upload - Subir - - - - Change - Cambiar - - - - Error - Error - - - - No album name given - ¡Nombre del álbum no encontrado! - - - - LeftDrawerScrollview - - - Settings - Ajustes - - - - Accounts - Cuentas - - - - Quit - Salida - - - - MessageSend - - - to: - a: - - - - Title (optional) - Título (opcional) - - - - Drop your Content here. - Deje caer su contenido aquí. - - - - What's on your mind? - ¿Qué tienes en mente? - - - - - 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! - No se ha suministrado ningún receptor! - - - - MoreComments - - - Show all comments - todos comentarios - - - - NewsStack - - - Network Error - Fallo de red - - - - More - Mas - - - - NewsTab - - Download profile image for - Descargar la imagen del perfil para - - - More - Mas - - - Timeline - Cronología - - - Error - Error - - - Favorites - Favoritos - - - Conversations - Conversaciones - - - Network Error - Fallo de red - - - Public timeline - Cronología pública - - - Direct Messages - Mensaje directo - - - Notifications - Notificaciones - - - Group news - Grupos - - - Quit - Salida - - - - seconds - Segundos - - - - minute - Minuto - - - - minutes - Minutos - - - - hour - Hora - - - - hours - Horas - - - - day - Dia - - - - days - Dias - - - - month - Mes - - - - months - Meses - - - - years - Años - - - - 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. - - - - Newsitem - - attending: - Asistiendo: - - - - Source: - Fuente: - - - - Direct Message - Mensaje directo - - - - In reply to - En respuesta a - - - comments - comentarios - - - - attending - asistencia - - - - ago - hace - - - - 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 - - - - PermissionDialog - - - Friends - Amigos - - - - Groups - Grupos - - - - PhotoTab - - - 's images - s Imágenes - - - - All Images - Todas las imagenes - - - - Only new - Solo nueva - - - - - Own Images - Mis imágenes - - - - More - Mas - - - - ProfileComponent - - - profile name - Nombre de perfil - - - - is default - es por defecto - - - - hide friends - ocultar amigos - - - - profile photo - foto de perfil - - - - profile thumb - foto de perfil pequeña - - - - publish - publicar - - - - publish in network - publicar en la red - - - - description - descripción - - - - date of birth - fecha de nacimiento - - - - address - dirección - - - - city - ciudad - - - - region - región - - - - postal code - código postal - - - - country - país - - - - hometown - ciudad natal - - - - gender - género - - - - marital status - estado civil - - - - married with - casado con - - - - married since - casado desde - - - - sexual - orientación sexual - - - - politics - política - - - - religion - religión - - - - public keywords - palabras clave públicas - - - - private keywords - palabras clave privadas - - - - likes - le gusta - - - - dislikes - no le gusta - - - - about - sobre - - - - music - música - - - - book - libro - - - - tv - tv - - - - film - película - - - - interest - interés - - - - romance - romance - - - - work - trabajo - - - - education - educación - - - - social networks - redes sociales - - - - homepage - página web - - - - Update - Actualización - - - - profile id - profile id - - - - Description - Descripción - - - - Location - Localización - - - - Posts - Mensajes - - - - URL - URL - - - - Created at - Creado en - - - - SmileyDialog - - - Unicode - Unicode - - - - Standard - Standard - - - - Addon - Addon - - - - Adult - XXX - - - - SyncComponent - - - sync - sync - - - - notify - notificar - - - - SyncConfig - - - Sync Interval (0=None) - Intervalo de sincr. (0=Ninguno) - - - - Min. - min. - - - - friendiqa - - Refresh - Actualizar - - - Timeline - Cronología - - - Conversations - Conversaciones - - - Favorites - Favoritos - - - Replies - Respuestas - - - Public Timeline - Cronología pública - - - Group news - Grupos - - - Search - Busca - - - Settings - Ajustes - - - Accounts - Cuentas - - - 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 - - - ago - hace - - - minute - Minuto - - - minutes - Minutos - - - hour - Hora - - - hours - Horas - - - day - Dia - - - days - Dias - - - month - Mes - - - months - Meses - - - years - Años - - - - service - - Error - Error - - - Setting view type of news has moved from account page to config page. - La configuración del tipo de vista de las noticias se ha movido de la página de la cuenta a la página de configuración. - - - - Undefined Array Error - - - - - JSON status Error - - - - diff --git a/source-linux/translations/friendiqa-hu.qm b/source-linux/translations/friendiqa-hu.qm deleted file mode 100644 index a9599bd..0000000 Binary files a/source-linux/translations/friendiqa-hu.qm and /dev/null differ diff --git a/source-linux/translations/friendiqa-hu.ts b/source-linux/translations/friendiqa-hu.ts deleted file mode 100644 index 6afd3d0..0000000 --- a/source-linux/translations/friendiqa-hu.ts +++ /dev/null @@ -1,1534 +0,0 @@ - - - - - AccountPage - - - - - User - Felhasználó - - - - Server - Kiszolgáló - - - - Nickname - Becenév - - - - Password - Jelszó - - - - Image dir. - Képkönyvtár - - - News as - Hírek mint - - - - - - Error - Hiba - - - - Nicknames containing @ symbol currently not supported - A @ szimbólumot tartalmazó becenevek jelenleg nem támogatottak - - - - Confirm - Megerősítés - - - - No server given! - Nincs kiszolgáló megadva! - - - - No nickname given! - Nincs becenév megadva! - - - - No password given! - Nincs jelszó megadva! - - - - No image directory given! - Nincs képkönyvtár megadva! - - - - Wrong password! - Hibás jelszó! - - - - Success - Sikeres - - - - Name - Név - - - Timeline - Idővonal - - - Conversations - Beszélgetések - - - - CalendarTab - - - Events - Események - - - - Own Calendar - Saját naptár - - - - ConfigPage - - - News as - Hírek mint - - - - - - Conversations - Beszélgetések - - - - - Timeline - Idővonal - - - - Max. News - Legtöbb hír - - - - Hide #nsfw? - A #NSFW elrejtése? - - - - Sync - Szinkronizálás - - - - ConfigTab - - User - Felhasználó - - - Server - Kiszolgáló - - - Nickname - Becenév - - - Password - Jelszó - - - Image dir. - Képkönyvtár - - - Max. News - Legtöbb hír - - - News as - Hírek mint - - - Interval (0=None) - Időköz (0 = nincs) - - - Error - Hiba - - - Nickname not registered at given server! - A becenév nincs regisztrálva a megadott kiszolgálón! - - - Confirm - Megerősítés - - - No server given! - Nincs kiszolgáló megadva! - - - No nickname given! - Nincs becenév megadva! - - - Nickname not registered at given server! - A becenév nincs regisztrálva a megadott kiszolgálón! - - - No username given! - Nincs felhasználónév megadva! - - - Sync Interval (0=None) - Szinkronizálási időköz (0 = nincs) - - - Nicknames containing @ symbol currently not supported - A @ szimbólumot tartalmazó becenevek jelenleg nem támogatottak - - - Min. - Legkisebb - - - No password given! - Nincs jelszó megadva! - - - No image directory given! - Nincs képkönyvtár megadva! - - - No maximum news number given! - Nincs legtöbb hír szám megadva! - - - Wrong password! - Hibás jelszó! - - - Success - Sikeres - - - Name - Név - - - Timeline - Idővonal - - - Conversations - Beszélgetések - - - - ContactComponent - - - Connect - Kapcsolódás - - - - ContactDetailsComponent - - Connect - Kapcsolódás - - - Description - Leírás - - - Location - Hely - - - Posts - Bejegyzések - - - URL - URL - - - Created at - Létrehozva - - - - ContactPage - - - seconds - másodperc - - - - minute - perc - - - - minutes - perc - - - - hour - óra - - - - hours - óra - - - - day - nap - - - - days - nap - - - - month - hónap - - - - months - hónap - - - - years - év - - - - likes this. - kedveli ezt. - - - - like this. - kedveli ezt. - - - - doesn't like this. - nem kedveli ezt. - - - - don't like this. - nem kedveli ezt. - - - - will attend. - részt vesz. - - - - persons will attend. - személy részt vesz. - - - - will not attend. - nem vesz részt. - - - - persons will not attend. - személy nem vesz részt. - - - - may attend. - talán részt vesz. - - - - persons may attend. - személy talán részt vesz. - - - - Connect - Kapcsolódás - - - - Approve - Jóváhagyás - - - - Reject - Visszautasítás - - - - Ignore - Mellőzés - - - - Description - Leírás - - - - Location - Hely - - - - Posts - Bejegyzések - - - - URL - URL - - - - Created at - Létrehozva - - - - Network Error - Hálózati hiba - - - - Conversation - - - seconds - másodperc - - - - minute - perc - - - - minutes - perc - - - - hour - óra - - - - hours - óra - - - - day - nap - - - - days - nap - - - - month - hónap - - - - months - hónap - - - - years - év - - - - likes this. - kedveli ezt. - - - - like this. - kedveli ezt. - - - - doesn't like this. - nem kedveli ezt. - - - - don't like this. - nem kedveli ezt. - - - - will attend. - részt vesz. - - - - persons will attend. - személy részt vesz. - - - - will not attend. - nem vesz részt. - - - - persons will not attend. - személy nem vesz részt. - - - - may attend. - talán részt vesz. - - - - persons may attend. - személy talán részt vesz. - - - - DrawerAccountComponent - - - Refresh - Frissítés - - - - Timeline - Idővonal - - - - Conversations - Beszélgetések - - - - Replies - Válaszok - - - - Direct Messages - Közvetlen üzenetek - - - - Favorites - Kedvencek - - - - Public Timeline - Nyilvános idővonal - - - - Group news - Csoporthírek - - - - Search - Keresés - - - - Notifications - Értesítések - - - - DrawerAccountComponentContacts - - - Profile - Profil - - - - Friends - Ismerősök - - - - Contacts - Partnerek - - - - Groups - Csoportok - - - - EventList - - Location - Hely - - - - EventListItem - - - Location - Hely - - - - FriendsListTab - - - Friend Requests - Barátkérések - - - - Friends - Ismerősök - - - - FriendsTab - - - Me - Én - - - - Friends - Ismerősök - - - - Contacts - Partnerek - - - - Groups - Csoportok - - - - GroupComponent - - Error - Hiba - - - No name given - Nincs név megadva - - - - ImageUploadDialog - - - Upload to album - Feltöltés albumba - - - Album - Album - - - Image - Kép - - - - Description - Leírás - - - - Upload - Feltöltés - - - - Change - Változtatás - - - - Error - Hiba - - - - No album name given - Nincs albumnév megadva - - - - LeftDrawerScrollview - - - Settings - Beállítások - - - - Accounts - Fiókok - - - - Quit - Kilépés - - - - MessageSend - - - to: - címzett: - - - - Title (optional) - Cím (elhagyható) - - - - Drop your Content here. - Ejtse ide a tartalmat. - - - - What's on your mind? - Mire gondol? - - - - - Error - Hiba - - - - Only one attachment supported at the moment. - Remove other attachment first! - Csak egyetlen melléklet támogatott jelenleg. - Először távolítsa el a másik mellékletet. - - - - No receiver supplied! - Nincs fogadó megadva! - - - - MoreComments - - - Show all comments - Összes hozzászólás megjelenítése - - - - NewsStack - - - Network Error - Hálózati hiba - - - - More - Több - - - - NewsTab - - Download profile image for - Profilkép letöltése ennél: - - - More - Több - - - Timeline - Idővonal - - - Error - Hiba - - - Favorites - Kedvencek - - - Conversations - Beszélgetések - - - Network Error - Hálózati hiba - - - Replies - Válaszok - - - Public timeline - Nyilvános idővonal - - - Direct Messages - Közvetlen üzenetek - - - Notifications - Értesítések - - - Group news - Csoporthírek - - - Quit - Kilépés - - - - seconds - másodperc - - - - minute - perc - - - - minutes - perc - - - - hour - óra - - - - hours - óra - - - - day - nap - - - - days - nap - - - - month - hónap - - - - months - hónap - - - - years - év - - - - likes this. - kedveli ezt. - - - - like this. - kedveli ezt. - - - - doesn't like this. - nem kedveli ezt. - - - - don't like this. - nem kedveli ezt. - - - - will attend. - részt vesz. - - - - persons will attend. - személy részt vesz. - - - - will not attend. - nem vesz részt. - - - - persons will not attend. - személy nem vesz részt. - - - - may attend. - talán részt vesz. - - - - persons may attend. - személy talán részt vesz. - - - - Newsitem - - attending: - részvétel: - - - - Source: - Forrás: - - - - Direct Message - Közvetlen üzenet - - - - In reply to - Válaszul erre: - - - comments - hozzászólás - - - - attending - részvétel - - - - ago - óta - - - - Attending: - Részvétel: - - - - Reply - Válasz - - - - DM - DM - - - - Repost - Újraküldés - - - - Success! - Sikeres! - - - - Conversation - Beszélgetés - - - - Attending - Részvétel - - - - yes - igen - - - - maybe - talán - - - - no - nem - - - - Delete - Törlés - - - - PermissionDialog - - - Friends - Ismerősök - - - - Groups - Csoportok - - - - PhotoTab - - - 's images - képei - - - - All Images - Összes kép - - - - Only new - Csak újak - - - - - Own Images - Saját képek - - - - More - Több - - - - ProfileComponent - - - profile name - profilnév - - - - is default - alapértelmezett - - - - hide friends - ismerősök elrejtése - - - - profile photo - profilfénykép - - - - profile thumb - profilbélyegkép - - - - publish - közzététel - - - - publish in network - közzététel hálózaton - - - - description - leírás - - - - date of birth - születési dátum - - - - address - cím - - - - city - település - - - - region - régió - - - - postal code - irányítószám - - - - country - ország - - - - hometown - szülőváros - - - - gender - nem - - - - marital status - családi állapot - - - - married with - házas vele - - - - married since - házas ekkortól - - - - sexual - szexuális - - - - politics - politika - - - - religion - vallás - - - - public keywords - nyilvános kulcsszavak - - - - private keywords - személyes kulcsszavak - - - - likes - kedvelések - - - - dislikes - nem kedvelések - - - - about - névjegy - - - - music - zene - - - - book - könyv - - - - tv - TV - - - - film - film - - - - interest - érdeklődés - - - - romance - romantika - - - - work - munka - - - - education - oktatás - - - - social networks - közösségi hálózatok - - - - homepage - honlap - - - - Update - Frissítés - - - - profile id - profilazonosító - - - - Description - Leírás - - - - Location - Hely - - - - Posts - Bejegyzések - - - - URL - URL - - - - Created at - Létrehozva - - - - SmileyDialog - - - Unicode - Unicode - - - - Standard - Szabványos - - - - Addon - Bővítmény - - - - Adult - Felnőtt - - - - SyncComponent - - - sync - szinkronizálás - - - - notify - értesítés - - - - SyncConfig - - - Sync Interval (0=None) - Szinkronizálási időköz (0 = nincs) - - - - Min. - Legkisebb - - - - friendiqa - - Refresh - Frissítés - - - Timeline - Idővonal - - - Conversations - Beszélgetések - - - Favorites - Kedvencek - - - Replies - Válaszok - - - Public Timeline - Nyilvános idővonal - - - Group news - Csoporthírek - - - Search - Keresés - - - Settings - Beállítások - - - Accounts - Fiókok - - - Quit - Kilépés - - - - newsworker - - likes this. - kedveli ezt. - - - like this. - kedveli ezt. - - - doesn't like this. - nem kedveli ezt. - - - don't like this. - nem kedveli ezt. - - - will attend. - részt vesz. - - - persons will attend. - személy részt vesz. - - - will not attend. - nem vesz részt. - - - persons will not attend. - személy nem vesz részt. - - - may attend. - talán részt vesz. - - - persons may attend. - személy talán részt vesz. - - - - yes - igen - - - - no - nem - - - - maybe - talán - - - seconds - másodperc - - - ago - óta - - - minute - perc - - - minutes - perc - - - hour - óra - - - hours - óra - - - day - nap - - - days - nap - - - month - hónap - - - months - hónap - - - - service - - Error - Hiba - - - Changelog - Változásnapló - - - Setting view type of news has moved from account page to config page. - A hírek nézettípusának beállítása át lett helyezve a fiókoldalról a beállítási oldalra. - - - - Undefined Array Error - Meghatározatlan tömbhiba - - - - JSON status Error - JSON-állapothiba - - - diff --git a/source-linux/translations/friendiqa-it.qm b/source-linux/translations/friendiqa-it.qm deleted file mode 100644 index b61cd3c..0000000 Binary files a/source-linux/translations/friendiqa-it.qm and /dev/null differ diff --git a/source-linux/translations/friendiqa-it.ts b/source-linux/translations/friendiqa-it.ts deleted file mode 100644 index 0c14705..0000000 --- a/source-linux/translations/friendiqa-it.ts +++ /dev/null @@ -1,1483 +0,0 @@ - - - - - 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 - I soprannomi contenenti il simbolo @ attualmente non sono supportati - - - - 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! - Password sbagliata! - - - - Success - Ha funzionato! - - - - Name - Nome - - - Timeline - Cronologia - - - Conversations - Conversazioni - - - - CalendarTab - - - Events - Eventi - - - - Own Calendar - Calendario - - - - ConfigPage - - - News as - News come - - - - - - Conversations - Conversazioni - - - - - Timeline - Cronologia - - - - Max. News - Nº Max. di notizie - - - - Hide #nsfw? - Nascondere #nsfw? - - - - Sync - Sync - - - - ConfigTab - - User - Utente - - - Server - Server - - - Nickname - Utente - - - Password - Password - - - Image dir. - Directory immagini - - - Max. News - Nº Max. di notizie - - - News as - News come - - - Interval (0=None) - Intervallo (0=nessuno) - - - Error - Errore - - - Confirm - Conferma - - - No server given! - Nessun server inserito! - - - No nickname given! - Nessun utente inserito! - - - No username given! - Nessun utente inserito! - - - No password given! - Nessuna password inserita! - - - No image directory given! - Nessuna directory immagini inserita! - - - No maximum news number given! - Nessun numero massimo di news inserito! - - - Success - Ha funzionato! - - - Timeline - Cronologia - - - Conversations - Conversazioni - - - - ContactComponent - - - Connect - Connetti - - - - ContactDetailsComponent - - Connect - Connetti - - - Description - Descrizione - - - Location - Località - - - Posts - Messaggi - - - URL - URL - - - Created at - Creato il - - - - ContactPage - - - seconds - secondi - - - - minute - minuti - - - - minutes - minuti - - - - hour - ora - - - - hours - ore - - - - day - giorno - - - - days - giorni - - - - month - mese - - - - months - mesi - - - - years - anni - - - - 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. - - - - Connect - Connetti - - - - Approve - Approvare - - - - Reject - Rifiutare - - - - Ignore - Ignorare - - - - Description - Descrizione - - - - Location - Località - - - - Posts - Messaggi - - - - URL - URL - - - - Created at - Creato il - - - - Network Error - Errore di rete - - - - Conversation - - - seconds - secondi - - - - minute - minuti - - - - minutes - minuti - - - - hour - ora - - - - hours - ore - - - - day - giorno - - - - days - giorni - - - - month - mese - - - - months - mesi - - - - years - anni - - - - 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. - - - - DrawerAccountComponent - - - Refresh - Aggiorna - - - - Timeline - Cronologia - - - - Conversations - Conversazioni - - - - Replies - Risposte - - - - Direct Messages - Messaggio diretto - - - - Favorites - Favoriti - - - - Public Timeline - Cronologia pubblica - - - - Group news - Notizie del gruppo - - - - Search - Cerca - - - - Notifications - Notifiche - - - - DrawerAccountComponentContacts - - - Profile - Profilo - - - - Friends - Amici - - - - Contacts - Contatti - - - - Groups - Gruppi - - - - EventList - - Location - Località - - - - EventListItem - - - Location - Località - - - - FriendsListTab - - - Friend Requests - Richieste di contatto - - - - Friends - Amici - - - - FriendsTab - - - Me - Me - - - - Friends - Amici - - - - Contacts - Contatti - - - - Groups - Gruppi - - - - ImageUploadDialog - - - Upload to album - Carica su album - - - Album - Album - - - Image - Immagine - - - - Description - Descrizione - - - - Upload - Carica - - - - Change - Modifica - - - - Error - Errore - - - - No album name given - Nessun nome album inserito! - - - - LeftDrawerScrollview - - - Settings - Configurazione - - - - Accounts - Conti - - - - Quit - Chiudi - - - - MessageSend - - - to: - a: - - - - Title (optional) - Titolo (opzionale) - - - - Drop your Content here. - Lascia qui il tuo contenuto. - - - - What's on your mind? - A cosa stai pensando? - - - - - 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! - Nessun ricevitore in dotazione! - - - - MoreComments - - - Show all comments - Tutti commenti - - - - NewsStack - - - Network Error - Errore di rete - - - - More - Ancora - - - - NewsTab - - Download profile image for - Download immagine profilo per - - - More - Ancora - - - Timeline - Cronologia - - - Error - Errore - - - Favorites - Favoriti - - - Conversations - Conversazioni - - - Direct Messages - Messaggio diretto - - - Notifications - Notifiche - - - Group news - Gruppi - - - - seconds - secondi - - - - minute - minuti - - - - minutes - minuti - - - - hour - ora - - - - hours - ore - - - - day - giorno - - - - days - giorni - - - - month - mese - - - - months - mesi - - - - years - anni - - - - 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. - - - - Newsitem - - attending: - attendere: - - - - Source: - Codice: - - - - Direct Message - Messaggio diretto - - - - In reply to - In risposta a - - - comments - commenti - - - - attending - partecipare - - - - ago - fa - - - - Attending: - Attendi: - - - - Reply - Risposta - - - - DM - Messaggio diretto - - - - Repost - Condividi - - - - Success! - Ha funzionato! - - - - Conversation - Conversazione - - - - Attending - Attendi - - - - yes - si - - - - maybe - potrebbe - - - - no - no - - - - Delete - Cancella - - - - PermissionDialog - - - Friends - Amici - - - - Groups - Gruppi - - - - PhotoTab - - - 's images - Immagini - - - - All Images - Tutte immagini - - - - Only new - Solo nuovo - - - - - Own Images - Mie immagini - - - - More - Ancora - - - - ProfileComponent - - - profile name - nome del profilo - - - - is default - è predefinito - - - - hide friends - nascondere gli amici - - - - profile photo - foto del profilo - - - - profile thumb - piccola foto di profilo - - - - publish - pubblicare - - - - publish in network - pubblicare in rete - - - - description - descrizione - - - - date of birth - data di nascita - - - - address - indirizzo - - - - city - città - - - - region - regione - - - - postal code - codice postale - - - - country - paese - - - - hometown - città natale - - - - gender - genere - - - - marital status - stato civile - - - - married with - sposato con - - - - married since - sposato da quando - - - - sexual - orientamento sessuale - - - - politics - politica - - - - religion - religione - - - - public keywords - parole chiave pubbliche - - - - private keywords - parole chiave private - - - - likes - ama - - - - dislikes - non piace - - - - about - su - - - - music - musica - - - - book - libro - - - - tv - tv - - - - film - film - - - - interest - interesse - - - - romance - romanticismo - - - - work - lavoro - - - - education - educazione - - - - social networks - reti sociali - - - - homepage - homepage - - - - Update - Aggiornare - - - - profile id - profilo id - - - - Description - Descrizione - - - - Location - Località - - - - Posts - Messaggi - - - - URL - URL - - - - Created at - Creato il - - - - SmileyDialog - - - Unicode - Unicode - - - - Standard - Standard - - - - Addon - Addon - - - - Adult - XXX - - - - SyncComponent - - - sync - sync - - - - notify - notificare - - - - SyncConfig - - - Sync Interval (0=None) - Intervallo (0=nessuno) - - - - Min. - Min. - - - - friendiqa - - Refresh - Aggiorna - - - Timeline - Cronologia - - - Conversations - Conversazioni - - - Favorites - Favoriti - - - Replies - Risposte - - - Public Timeline - Cronologia pubblica - - - Group news - Notizie del gruppo - - - Search - Cerca - - - Settings - Configurazione - - - Accounts - Conti - - - Quit - Chiudi - - - - 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 - - - ago - fa - - - minute - minuti - - - minutes - minuti - - - hour - ora - - - hours - ore - - - day - giorno - - - days - giorni - - - month - mese - - - months - mesi - - - years - anni - - - - service - - Error - Errore - - - Changelog - Changelog - - - Setting view type of news has moved from account page to config page. - L'impostazione del tipo di visualizzazione delle notizie è stata spostata dalla pagina del conto alla pagina di configurazione. - - - - Undefined Array Error - - - - - JSON status Error - - - - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..ea99547 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.16.0) + +project(friendiqa VERSION 0.6 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(CMAKE_VERSION VERSION_LESS "3.7.0") + set(CMAKE_INCLUDE_CURRENT_DIR ON) +endif() + +find_package(Qt6 REQUIRED COMPONENTS Core Quick QuickControls2 Widgets Sql DBus NetworkAuth Multimedia REQUIRED) + +qt_standard_project_setup() + +set(MOC_SOURCES common/uploadableimage.h + common/xhr.h + common/filesystem.h + common/updatenews.h + common/alarm.h + common/oauth.h + common/documenthandler.h) + +set(SOURCES common/friendiqa.cpp + common/uploadableimage.cpp + common/xhr.cpp + common/filesystem.cpp + common/updatenews.cpp + common/alarmlinux.cpp + common/oauth.cpp + common/documenthandler.cpp) + +include_directories(common) + +qt_add_executable(friendiqa ${SOURCES} ${MOC_SOURCES} application.qrc) + +target_link_libraries(friendiqa PRIVATE Qt6::Core) +target_link_libraries(friendiqa PRIVATE Qt6::Widgets) +target_link_libraries(friendiqa PRIVATE Qt6::Quick) +target_link_libraries(friendiqa PRIVATE Qt6::QuickControls2) +target_link_libraries(friendiqa PRIVATE Qt6::Sql) +target_link_libraries(friendiqa PRIVATE Qt6::DBus) +target_link_libraries(friendiqa PRIVATE Qt6::NetworkAuth) +target_link_libraries(friendiqa PRIVATE Qt6::Multimedia) + +install(TARGETS friendiqa DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(FILES assets/de.manic.Friendiqa.desktop DESTINATION share/applications) +install(FILES assets/de.manic.Friendiqa.svg DESTINATION share/icons/hicolor/scalable/apps) diff --git a/src/application.qrc b/src/application.qrc new file mode 100644 index 0000000..a087343 --- /dev/null +++ b/src/application.qrc @@ -0,0 +1,141 @@ + + + qtquickcontrols2.conf + qml/friendiqa.qml + qml/newsqml/NewsStack.qml + qml/newsqml/NewsTab.qml + qml/newsqml/Newsitem.qml + qml/newsqml/MessageSend.qml + qml/newsqml/Conversation.qml + qml/newsqml/FriendicaActivities.qml + qml/newsqml/Hashtag.qml + qml/newsqml/NewsImage.qml + qml/newsqml/NewsVideo.qml + qml/newsqml/ContactPage.qml + qml/newsqml/NewsVideoLarge.qml + qml/newsqml/SmileyDialog.qml + qml/contactqml/FriendsTab.qml + qml/contactqml/GroupComponent.qml + qml/contactqml/ProfileComponent.qml + qml/contactqml/Contactlist.qml + qml/photoqml/PhotoComponent.qml + qml/photoqml/PhotogroupComponent.qml + qml/photoqml/PhotoTab.qml + qml/photoqml/ImageUploadDialog.qml + qml/genericqml/ImagePicker.qml + qml/genericqml/ImagePickerLinux.qml + qml/genericqml/IntentReceiver.qml + qml/genericqml/MButton.qml + qml/genericqml/LinuxSync.qml + qml/genericqml/BlueButton.qml + qml/genericqml/ContactComponent.qml + qml/genericqml/PermissionDialog.qml + qml/calendarqml/CalendarTab.qml + qml/calendarqml/CalendarDay.qml + qml/calendarqml/EventList.qml + qml/configqml/AccountPage.qml + qml/configqml/SyncConfig.qml + qml/configqml/SyncComponent.qml + qml/configqml/InfoBox.qml + qml/configqml/ConfigPage.qml + qml/configqml/OSSettingsAndroid.qml + qml/configqml/OSSettingsLinux.qml + js/image.js + js/photoworker.js + js/service.js + js/news.js + js/newsworker.js + js/helper.js + js/smiley.js + translations/friendiqa-it.ts + translations/friendiqa-it.qm + translations/friendiqa-de.qm + translations/friendiqa-de.ts + translations/friendiqa-es.qm + translations/friendiqa-es.ts + assets/defaultcontact.jpg + assets/folder-blue.png + common/filesystem.cpp + common/filesystem.h + common/friendiqa.cpp + common/uploadableimage.cpp + common/uploadableimage.h + common/xhr.cpp + common/xhr.h + qml/newsqml/MoreComments.qml + qml/newsqml/NewsPhotolist.qml + qml/genericqml/DrawerAccountComponent.qml + qml/configqml/LeftDrawerScrollview.qml + qml/genericqml/LeftDrawerLinux.qml + qml/genericqml/LeftDrawerAndroid.qml + qml/genericqml/DrawerAccountComponentContacts.qml + qml/contactqml/ProfileTab.qml + qml/contactqml/FriendsListTab.qml + qml/contactqml/GroupsListTab.qml + qml/calendarqml/EventListItem.qml + translations/friendiqa-hu.qm + translations/friendiqa-hu.ts + assets/Friendiqa.png + assets/Friendica_monochrome.png + qml/configqml/ConfigAppearancePage.qml + qml/configqml/ConfigStartPage.qml + qml/contactqml/ContactsSearchPage.qml + assets/Friendiqa.ico + qml/calendarqml/EventCreate.qml + qml/newsqml/BlockUser.qml + qml/newsqml/ReportUser.qml + qml/newsqml/MessageImageUploadDialog.qml + qml/configqml/AcceptRules.qml + translations/friendiqa-nl.qm + translations/friendiqa-nl.ts + qml/newsqml/NewsTabbutton.qml + qml/genericqml/RootStack.qml + assets/icons/bars.svg + assets/icons/bell.svg + assets/icons/calendar.svg + assets/icons/caret-down.svg + assets/icons/check.svg + assets/icons/envelope.svg + assets/icons/exchange.svg + assets/icons/globe.svg + assets/icons/home.svg + assets/icons/list.svg + assets/icons/pencil.svg + assets/icons/picture-o.svg + assets/icons/refresh.svg + assets/icons/search.svg + assets/icons/star.svg + assets/icons/times-circle.svg + assets/icons/trash.svg + assets/icons/users.svg + assets/icons/comments.svg + assets/icons/history.svg + assets/icons/sign-out.svg + assets/icons/address-card.svg + assets/icons/star-o.svg + assets/icons/cogs.svg + assets/icons/paper-plane-o.svg + assets/icons/font.svg + assets/icons/hashtag.svg + assets/icons/code.svg + assets/icons/italic.svg + assets/icons/bold.svg + assets/icons/smile-o.svg + assets/icons/frown-o.svg + assets/icons/chevron-down.svg + assets/icons/chevron-up.svg + assets/icons/user-plus.svg + assets/icons/filter.svg + assets/icons/plus.svg + assets/icons/cloud-upload.svg + assets/icons/cloud-download.svg + assets/icons/repeat.svg + assets/icons/times.svg + assets/icons/play.svg + assets/icons/angle-right.svg + assets/icons/angle-left.svg + assets/icons/floppy-o.svg + assets/icons/unlock.svg + assets/icons/lock.svg + + diff --git a/src/assets/Friendica_monochrome.png b/src/assets/Friendica_monochrome.png new file mode 100644 index 0000000..a362235 Binary files /dev/null and b/src/assets/Friendica_monochrome.png differ diff --git a/src/assets/Friendiqa.ico b/src/assets/Friendiqa.ico new file mode 100644 index 0000000..e5b516e Binary files /dev/null and b/src/assets/Friendiqa.ico differ diff --git a/src/assets/Friendiqa.png b/src/assets/Friendiqa.png new file mode 100644 index 0000000..3c358a9 Binary files /dev/null and b/src/assets/Friendiqa.png differ diff --git a/source-linux/images/de.ma-nic.Friendiqa.desktop b/src/assets/de.manic.Friendiqa.desktop similarity index 77% rename from source-linux/images/de.ma-nic.Friendiqa.desktop rename to src/assets/de.manic.Friendiqa.desktop index aa96777..2a7d480 100644 --- a/source-linux/images/de.ma-nic.Friendiqa.desktop +++ b/src/assets/de.manic.Friendiqa.desktop @@ -2,9 +2,9 @@ Version=1.0 Type=Application Exec=friendiqa %u -Icon=Friendiqa.svg +Icon=de.manic.Friendiqa.svg Terminal=false Name=Friendiqa GenericName=Social Media Comment= App for social network Friendica -Categories=Network,Qt,News +Categories=Network diff --git a/source-linux/images/Friendiqa.svg b/src/assets/de.manic.Friendiqa.svg similarity index 100% rename from source-linux/images/Friendiqa.svg rename to src/assets/de.manic.Friendiqa.svg diff --git a/src/assets/de.manic.friendiqa.metainfo.xml b/src/assets/de.manic.friendiqa.metainfo.xml new file mode 100644 index 0000000..9890464 --- /dev/null +++ b/src/assets/de.manic.friendiqa.metainfo.xml @@ -0,0 +1,35 @@ + + + de.manic.friendiqa + + Friendiqa + Qt client for the social network Friendica + + FSFAP + GPL-3.0-or-later + + + pointing + keyboard + touch + + + +

+ Qt based client for the Friendica Social Network. Tabs for news (incl. Direct Messages), friends, photos and events. +

+
+ + de.manic.Friendiqa.desktop + + + https://friendiqa.ma-nic.de/ScreenshotsDesktop/Screenshot_Desktop_Timeline_small.png + + + https://friendiqa.ma-nic.de/Screenshots/PhotoTab.jpg + + + https://friendiqa.ma-nic.de/Screenshots/EventsTab.jpg + + +
diff --git a/source-linux/images/defaultcontact.jpg b/src/assets/defaultcontact.jpg similarity index 100% rename from source-linux/images/defaultcontact.jpg rename to src/assets/defaultcontact.jpg diff --git a/source-linux/images/folder-blue.png b/src/assets/folder-blue.png similarity index 100% rename from source-linux/images/folder-blue.png rename to src/assets/folder-blue.png diff --git a/src/assets/friendica-tray-black.svg b/src/assets/friendica-tray-black.svg new file mode 100644 index 0000000..b9b9428 --- /dev/null +++ b/src/assets/friendica-tray-black.svg @@ -0,0 +1,707 @@ + + + + + + Friendiqa/friendica-tray-black.svg an master - Friendiqa - Friendica + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+ +
+
+
+
+ + +
+ + + + + +
+ + + MorsMortium +
/
+ Friendiqa + + + +
+ + + + + + +
+
+ +
geforkt von lubuwest/Friendiqa
+ +
+ +
+ +
+ +
+ + + 1 + +
+
+ +
+ +
+ + + 0 + +
+
+ + +
+ + Fork + + + + 0 + +
+ +
+ +
+
+ +
+ + + +
+
+
+ +
+ + + + + + + +
+ Du kannst nicht mehr als 25 Themen auswählen + Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein. +
+ + + +
+
+ + + + +
+ +
+ + + + + + + + + Friendiqa/source-linux/images/friendica-tray-black.svg + +
+
+ + + +
+
+ +
+

+
+ +
+ + +
+ 42 Zeilen +
+ + +
+ 1.7 KiB +
+ + + +
+ XML +
+ +
+ + +
+
+ +
+ + +
+ + +
+ Originalformat + + Permalink + + + Blame + + Verlauf + +
+ + + + + + + + + + + +
+

+
+ + + + + + +
+ +
+ + + +
+ +
+
+
+ + +
+
+ + + + +
+ + + + + + + + + + + + + diff --git a/src/assets/friendica-tray-white.svg b/src/assets/friendica-tray-white.svg new file mode 100644 index 0000000..2abd781 --- /dev/null +++ b/src/assets/friendica-tray-white.svg @@ -0,0 +1,707 @@ + + + + + + Friendiqa/friendica-tray-white.svg an master - Friendiqa - Friendica + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+ +
+
+
+
+ + +
+ + + + + +
+ + + MorsMortium +
/
+ Friendiqa + + + +
+ + + + + + +
+
+ +
geforkt von lubuwest/Friendiqa
+ +
+ +
+ +
+ +
+ + + 1 + +
+
+ +
+ +
+ + + 0 + +
+
+ + +
+ + Fork + + + + 0 + +
+ +
+ +
+
+ +
+ + + +
+
+
+ +
+ + + + + + + +
+ Du kannst nicht mehr als 25 Themen auswählen + Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein. +
+ + + +
+
+ + + + +
+ +
+ + + + + + + + + Friendiqa/source-linux/images/friendica-tray-white.svg + +
+
+ + + +
+
+ +
+

+
+ +
+ + +
+ 42 Zeilen +
+ + +
+ 1.7 KiB +
+ + + +
+ XML +
+ +
+ + +
+
+ +
+ + +
+ + +
+ Originalformat + + Permalink + + + Blame + + Verlauf + +
+ + + + + + + + + + + +
+

+
+ + + + + + +
+ +
+ + + +
+ +
+
+
+ + +
+
+ + + + +
+ + + + + + + + + + + + + diff --git a/src/assets/icons/address-card.svg b/src/assets/icons/address-card.svg new file mode 100644 index 0000000..dad3d3f --- /dev/null +++ b/src/assets/icons/address-card.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/angle-left.svg b/src/assets/icons/angle-left.svg new file mode 100644 index 0000000..a52814a --- /dev/null +++ b/src/assets/icons/angle-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/angle-right.svg b/src/assets/icons/angle-right.svg new file mode 100644 index 0000000..c19bd1a --- /dev/null +++ b/src/assets/icons/angle-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/bars.svg b/src/assets/icons/bars.svg new file mode 100644 index 0000000..e3a1572 --- /dev/null +++ b/src/assets/icons/bars.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/bell.svg b/src/assets/icons/bell.svg new file mode 100644 index 0000000..15114e5 --- /dev/null +++ b/src/assets/icons/bell.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/bold.svg b/src/assets/icons/bold.svg new file mode 100644 index 0000000..126b570 --- /dev/null +++ b/src/assets/icons/bold.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/calendar.svg b/src/assets/icons/calendar.svg new file mode 100644 index 0000000..1a57475 --- /dev/null +++ b/src/assets/icons/calendar.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/caret-down.svg b/src/assets/icons/caret-down.svg new file mode 100644 index 0000000..2fe29d6 --- /dev/null +++ b/src/assets/icons/caret-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/check.svg b/src/assets/icons/check.svg new file mode 100644 index 0000000..b9e3741 --- /dev/null +++ b/src/assets/icons/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/chevron-down.svg b/src/assets/icons/chevron-down.svg new file mode 100644 index 0000000..4ec5754 --- /dev/null +++ b/src/assets/icons/chevron-down.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/chevron-up.svg b/src/assets/icons/chevron-up.svg new file mode 100644 index 0000000..55b33d5 --- /dev/null +++ b/src/assets/icons/chevron-up.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/cloud-download.svg b/src/assets/icons/cloud-download.svg new file mode 100644 index 0000000..85f82ed --- /dev/null +++ b/src/assets/icons/cloud-download.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/cloud-upload.svg b/src/assets/icons/cloud-upload.svg new file mode 100644 index 0000000..ad5d266 --- /dev/null +++ b/src/assets/icons/cloud-upload.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/code.svg b/src/assets/icons/code.svg new file mode 100644 index 0000000..fa9d97c --- /dev/null +++ b/src/assets/icons/code.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/cogs.svg b/src/assets/icons/cogs.svg new file mode 100644 index 0000000..6ab59a3 --- /dev/null +++ b/src/assets/icons/cogs.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/comments.svg b/src/assets/icons/comments.svg new file mode 100644 index 0000000..1a001cd --- /dev/null +++ b/src/assets/icons/comments.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/ellipsis-v.svg b/src/assets/icons/ellipsis-v.svg new file mode 100644 index 0000000..0453758 --- /dev/null +++ b/src/assets/icons/ellipsis-v.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/envelope.svg b/src/assets/icons/envelope.svg new file mode 100644 index 0000000..9fc9706 --- /dev/null +++ b/src/assets/icons/envelope.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/exchange.svg b/src/assets/icons/exchange.svg new file mode 100644 index 0000000..26e717d --- /dev/null +++ b/src/assets/icons/exchange.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/filter.svg b/src/assets/icons/filter.svg new file mode 100644 index 0000000..545b4ae --- /dev/null +++ b/src/assets/icons/filter.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/floppy-o.svg b/src/assets/icons/floppy-o.svg new file mode 100644 index 0000000..728301b --- /dev/null +++ b/src/assets/icons/floppy-o.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/font.svg b/src/assets/icons/font.svg new file mode 100644 index 0000000..20ada19 --- /dev/null +++ b/src/assets/icons/font.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/frown-o.svg b/src/assets/icons/frown-o.svg new file mode 100644 index 0000000..4928c07 --- /dev/null +++ b/src/assets/icons/frown-o.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/globe.svg b/src/assets/icons/globe.svg new file mode 100644 index 0000000..5ddc3ab --- /dev/null +++ b/src/assets/icons/globe.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/hashtag.svg b/src/assets/icons/hashtag.svg new file mode 100644 index 0000000..2093029 --- /dev/null +++ b/src/assets/icons/hashtag.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/history.svg b/src/assets/icons/history.svg new file mode 100644 index 0000000..9fd8721 --- /dev/null +++ b/src/assets/icons/history.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/home.svg b/src/assets/icons/home.svg new file mode 100644 index 0000000..f9e993d --- /dev/null +++ b/src/assets/icons/home.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/italic.svg b/src/assets/icons/italic.svg new file mode 100644 index 0000000..bd6cf05 --- /dev/null +++ b/src/assets/icons/italic.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/list.svg b/src/assets/icons/list.svg new file mode 100644 index 0000000..0687a3d --- /dev/null +++ b/src/assets/icons/list.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/lock.svg b/src/assets/icons/lock.svg new file mode 100644 index 0000000..aa9a167 --- /dev/null +++ b/src/assets/icons/lock.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/paper-plane-o.svg b/src/assets/icons/paper-plane-o.svg new file mode 100644 index 0000000..dc8d6ef --- /dev/null +++ b/src/assets/icons/paper-plane-o.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/pencil.svg b/src/assets/icons/pencil.svg new file mode 100644 index 0000000..4138ff2 --- /dev/null +++ b/src/assets/icons/pencil.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/picture-o.svg b/src/assets/icons/picture-o.svg new file mode 100644 index 0000000..d287f37 --- /dev/null +++ b/src/assets/icons/picture-o.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/play.svg b/src/assets/icons/play.svg new file mode 100644 index 0000000..ab80037 --- /dev/null +++ b/src/assets/icons/play.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/plus.svg b/src/assets/icons/plus.svg new file mode 100644 index 0000000..deb2ca6 --- /dev/null +++ b/src/assets/icons/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/refresh.svg b/src/assets/icons/refresh.svg new file mode 100644 index 0000000..e0548d5 --- /dev/null +++ b/src/assets/icons/refresh.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/repeat.svg b/src/assets/icons/repeat.svg new file mode 100644 index 0000000..f3ecc41 --- /dev/null +++ b/src/assets/icons/repeat.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/reply.svg b/src/assets/icons/reply.svg new file mode 100644 index 0000000..ac016c0 --- /dev/null +++ b/src/assets/icons/reply.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/search.svg b/src/assets/icons/search.svg new file mode 100644 index 0000000..35bb21b --- /dev/null +++ b/src/assets/icons/search.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/sign-out.svg b/src/assets/icons/sign-out.svg new file mode 100644 index 0000000..3e7d480 --- /dev/null +++ b/src/assets/icons/sign-out.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/smile-o.svg b/src/assets/icons/smile-o.svg new file mode 100644 index 0000000..6d4f680 --- /dev/null +++ b/src/assets/icons/smile-o.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/star-o.svg b/src/assets/icons/star-o.svg new file mode 100644 index 0000000..4152261 --- /dev/null +++ b/src/assets/icons/star-o.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/star.svg b/src/assets/icons/star.svg new file mode 100644 index 0000000..710cb95 --- /dev/null +++ b/src/assets/icons/star.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/times-circle.svg b/src/assets/icons/times-circle.svg new file mode 100644 index 0000000..d6787c1 --- /dev/null +++ b/src/assets/icons/times-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/times.svg b/src/assets/icons/times.svg new file mode 100644 index 0000000..d02a36e --- /dev/null +++ b/src/assets/icons/times.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/trash.svg b/src/assets/icons/trash.svg new file mode 100644 index 0000000..8cb6ed0 --- /dev/null +++ b/src/assets/icons/trash.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/unlock.svg b/src/assets/icons/unlock.svg new file mode 100644 index 0000000..9cb4435 --- /dev/null +++ b/src/assets/icons/unlock.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/user-plus.svg b/src/assets/icons/user-plus.svg new file mode 100644 index 0000000..2575cf4 --- /dev/null +++ b/src/assets/icons/user-plus.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/users.svg b/src/assets/icons/users.svg new file mode 100644 index 0000000..96ceb0b --- /dev/null +++ b/src/assets/icons/users.svg @@ -0,0 +1,3 @@ + + + diff --git a/source-linux/common/alarm.h b/src/common/alarm.h similarity index 100% rename from source-linux/common/alarm.h rename to src/common/alarm.h diff --git a/source-linux/common/alarmandroid.cpp b/src/common/alarmandroid.cpp similarity index 95% rename from source-linux/common/alarmandroid.cpp rename to src/common/alarmandroid.cpp index 1bbc515..0c7c36d 100644 --- a/source-linux/common/alarmandroid.cpp +++ b/src/common/alarmandroid.cpp @@ -47,6 +47,7 @@ void ALARM::setAlarm(int interval) QVariantMap message; message["value"] = interval; AndroidNative::SystemDispatcher::instance()->loadClass("androidnative.Util"); + AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setPostNotification", message); AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.setSchedule", message); AndroidNative::SystemDispatcher::instance()->dispatch("androidnative.Util.stopService", message); } diff --git a/source-linux/common/alarmlinux.cpp b/src/common/alarmlinux.cpp similarity index 53% rename from source-linux/common/alarmlinux.cpp rename to src/common/alarmlinux.cpp index cdd75c3..5b78567 100644 --- a/source-linux/common/alarmlinux.cpp +++ b/src/common/alarmlinux.cpp @@ -33,7 +33,7 @@ #include #include #include - +#include ALARM *ALARM::instance() { @@ -45,14 +45,57 @@ ALARM::ALARM(QObject *parent) : QObject(parent){} void ALARM::setAlarm(int interval) { - qDebug() << interval; - QVariantMap message; - message["value"] = interval; + //QVariantMap message; + //message["value"] = interval; + if (interval==0){ + QProcess processDisable; + int intDisable = processDisable.execute("systemctl", QStringList() <<"--user"<<"disable"<<"--now"<<"friendiqa-sync.timer"); + qDebug() << " intEnable "< +// +// 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 +#include +#include +#include +#include +#include "documenthandler.h" + +DocumentHandler::DocumentHandler(QObject *parent) + : QObject(parent) + , m_document(nullptr) + , m_cursorPosition(-1) + , m_selectionStart(0) + , m_selectionEnd(0) +{ +} + +QQuickTextDocument *DocumentHandler::document() const +{ + return m_document; +} + +void DocumentHandler::setDocument(QQuickTextDocument *document) +{ + if (document == m_document) + return; + + if (m_document) + disconnect(m_document->textDocument(), &QTextDocument::modificationChanged, this, &DocumentHandler::modifiedChanged); + m_document = document; + if (m_document) + connect(m_document->textDocument(), &QTextDocument::modificationChanged, this, &DocumentHandler::modifiedChanged); + emit documentChanged(); +} + +int DocumentHandler::cursorPosition() const +{ + return m_cursorPosition; +} + +void DocumentHandler::setCursorPosition(int position) +{ + if (position == m_cursorPosition) + return; + + m_cursorPosition = position; + emit cursorPositionChanged(); +} + +int DocumentHandler::selectionStart() const +{ + return m_selectionStart; +} + +void DocumentHandler::setSelectionStart(int position) +{ + if (position == m_selectionStart) + return; + + m_selectionStart = position; + emit selectionStartChanged(); +} + +int DocumentHandler::selectionEnd() const +{ + return m_selectionEnd; +} + +void DocumentHandler::setSelectionEnd(int position) +{ + if (position == m_selectionEnd) + return; + + m_selectionEnd = position; + emit selectionEndChanged(); +} + +QTextCursor DocumentHandler::textCursor() const +{ + QTextDocument *doc = textDocument(); + if (!doc) + return QTextCursor(); + QTextCursor cursor = QTextCursor(doc); + if (m_selectionStart != m_selectionEnd) { + cursor.setPosition(m_selectionStart); + cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(m_cursorPosition); + } + return cursor; +} + +QTextDocument *DocumentHandler::textDocument() const +{ + if (!m_document) + return nullptr; + + return m_document->textDocument(); +} + +void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) +{ + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) + cursor.select(QTextCursor::WordUnderCursor); + cursor.mergeCharFormat(format); +} + +bool DocumentHandler::modified() const +{ + return m_document && m_document->textDocument()->isModified(); +} + +void DocumentHandler::setModified(bool m) +{ + if (m_document) + m_document->textDocument()->setModified(m); +} + +QFont DocumentHandler::font() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont(); + QTextCharFormat format = cursor.charFormat(); + return format.font(); +} + +void DocumentHandler::setFont(const QFont & font){ + + QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font() == font) + return; + + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit fontChanged(); +} + +bool DocumentHandler::bold() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont().bold(); + return cursor.charFormat().font().bold(); +} + +void DocumentHandler::setBold(bool bold) +{ + const QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font().bold() == bold) + return; + + QFont font = cursor.charFormat().font(); + font.setBold(bold); + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit boldChanged(); +} + +bool DocumentHandler::italic() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont().italic(); + return cursor.charFormat().font().italic(); +} + +void DocumentHandler::setItalic(bool italic) +{ + const QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font().italic() == italic) + return; + + QFont font = cursor.charFormat().font(); + font.setItalic(italic); + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit italicChanged(); +} + +bool DocumentHandler::liststyle() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return false; + return bool(cursor.currentList()); +} + +void DocumentHandler::setListstyle(bool liststyle) +{ + QTextCursor cursor = textCursor(); + if (!cursor.isNull() && !liststyle){ + cursor.currentList()->remove(cursor.block()); + emit liststyleChanged(); + }else{ + cursor.createList(QTextListFormat::ListDisc); + emit liststyleChanged(); + } +} + +bool DocumentHandler::codeblock() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return false; + qDebug()<< QTextDocumentFragment(cursor).toPlainText(); + return bool(QTextDocumentFragment(cursor).toMarkdown().contains("```")); +} + +void DocumentHandler::setCodeblock(bool codeblock) +{ + QTextCursor cursor = textCursor(); + if (!cursor.isNull() && !codeblock){ + qDebug()<< "!codeblock ```\n" + QTextDocumentFragment(cursor).toMarkdown() + "\n```"; + cursor.insertMarkdown("```\n" + QTextDocumentFragment(cursor).toMarkdown() + "\n```"); + emit codeblockChanged(); + } + else{ + qDebug()<< "```\n" + QTextDocumentFragment(cursor).toMarkdown() + "\n```"; + cursor.insertMarkdown(QTextDocumentFragment(cursor).toMarkdown().remove("```")); + emit codeblockChanged(); + } +} diff --git a/src/common/documenthandler.h b/src/common/documenthandler.h new file mode 100644 index 0000000..d74c6b9 --- /dev/null +++ b/src/common/documenthandler.h @@ -0,0 +1,114 @@ +// This file is part of Friendiqa +// https://github.com/lubuwest/Friendiqa +// Copyright (C) 2020 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 . + +#ifndef DOCUMENTHANDLER_H +#define DOCUMENTHANDLER_H + +//#include +#include +#include +#include +#include +//QT_BEGIN_NAMESPACE +//class QTextDocument; +//class QQuickTextDocument; +//QT_END_NAMESPACE + +class DocumentHandler : public QObject{ + Q_OBJECT + Q_PROPERTY(QQuickTextDocument *document READ document WRITE setDocument NOTIFY documentChanged) + Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) + Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged) + Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) + Q_PROPERTY(bool bold READ bold WRITE setBold NOTIFY boldChanged) + Q_PROPERTY(bool italic READ italic WRITE setItalic NOTIFY italicChanged) + Q_PROPERTY(bool liststyle READ liststyle WRITE setListstyle NOTIFY liststyleChanged) + Q_PROPERTY(bool codeblock READ codeblock WRITE setCodeblock NOTIFY codeblockChanged) + Q_PROPERTY(bool modified READ modified WRITE setModified NOTIFY modifiedChanged) + +public: + explicit DocumentHandler(QObject *parent = nullptr); + + QQuickTextDocument *document() const; + void setDocument(QQuickTextDocument *document); + + int cursorPosition() const; + void setCursorPosition(int position); + + int selectionStart() const; + void setSelectionStart(int position); + + int selectionEnd() const; + void setSelectionEnd(int position); + + QFont font() const; + void setFont(const QFont & font); + + bool bold() const; + void setBold(bool bold); + + bool italic() const; + void setItalic(bool italic); + + bool liststyle() const; + void setListstyle(bool liststyle); + + bool modified() const; + void setModified(bool m); + + bool codeblock() const; + void setCodeblock(bool codeblock); + +signals: + void documentChanged(); + void cursorPositionChanged(); + void selectionStartChanged(); + void selectionEndChanged(); + void fontChanged(); + void boldChanged(); + void italicChanged(); + void liststyleChanged(); + void codeblockChanged(); + void error(const QString &message); + void modifiedChanged(); + +private: + QTextCursor textCursor() const; + QTextDocument *textDocument() const; + void mergeFormatOnWordOrSelection(const QTextCharFormat &format); + QQuickTextDocument *m_document; + int m_cursorPosition; + int m_selectionStart; + int m_selectionEnd; +}; + +#endif // DOCUMENTHANDLER_H diff --git a/source-linux/common/filesystem.cpp b/src/common/filesystem.cpp similarity index 69% rename from source-linux/common/filesystem.cpp rename to src/common/filesystem.cpp index d8a344d..2ce9919 100644 --- a/source-linux/common/filesystem.cpp +++ b/src/common/filesystem.cpp @@ -53,12 +53,22 @@ QString FILESYSTEM::Directory() const return m_Directory; } +void FILESYSTEM::setVisibility(bool Visibility) +{ + if (Visibility!=m_Visibility) { + m_Visibility = Visibility; + emit visibilityChanged(); + } +} + +bool FILESYSTEM::Visibility() +{ + return m_Visibility; +} + QString FILESYSTEM::homePath() const { - //QDir dir(m_Directory); - // QString homeDir=QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);; - //qDebug(homeDir); return homeDir; } @@ -83,11 +93,9 @@ void FILESYSTEM::makeDir(QString name) { QDir dir(m_Directory); if (dir.mkdir(name)){ - qDebug() << "makedir success" < #include #include - +#include //#include //#include @@ -43,8 +43,12 @@ class FILESYSTEM : public QObject//, public QAndroidActivityResultReceiver { Q_OBJECT Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged) + Q_PROPERTY(bool Visibility READ Visibility WRITE setVisibility NOTIFY visibilityChanged) //Q_PROPERTY(bool direxist READ direxist) Q_PROPERTY(QString homePath READ homePath) + Q_PROPERTY(bool isAutostart READ isAutostart NOTIFY isAutostartChanged) + Q_PROPERTY(QString osType READ osType CONSTANT) + Q_PROPERTY(QString hostname READ hostname CONSTANT) //Q_PROPERTY(QString cameraPath READ cameraPath) @@ -52,16 +56,23 @@ public: static FILESYSTEM *instance(); explicit FILESYSTEM(QObject *parent = 0); void setDirectory(QString Directory); + void setVisibility(bool Visibility); QString Directory() const; QFileInfoList fileList(); //bool direxist(QString Directory); QString homePath() const; + bool Visibility(); + bool isAutostart(); + QString osType() const; + QString hostname() const; //QString cameraPath() const; // virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data); signals: //void imageselected(QString); void directoryChanged(); + void visibilityChanged(); + void isAutostartChanged(); //void fileListContent(QList data); void success(QString data); void error(QString data, int code); @@ -72,12 +83,14 @@ public slots: void makePath(QString name); void rmDir(); void rmFile(QString name); + void setAutostart(bool autostart); //void searchImage(); //void fileList(); private: QString m_Directory; QString homeDir; + bool m_Visibility; //QList m_Filelist; }; diff --git a/source-linux/common/filesystemandroid.cpp b/src/common/filesystemandroid.cpp similarity index 72% rename from source-linux/common/filesystemandroid.cpp rename to src/common/filesystemandroid.cpp index 165aae3..07f6540 100644 --- a/source-linux/common/filesystemandroid.cpp +++ b/src/common/filesystemandroid.cpp @@ -53,6 +53,18 @@ QString FILESYSTEM::Directory() const { return m_Directory; } +void FILESYSTEM::setVisibility(bool Visibility) +{ + if (Visibility!=m_Visibility) { + m_Visibility = Visibility; + emit visibilityChanged(); + } +} + +bool FILESYSTEM::Visibility() +{ + return m_Visibility; +} QString FILESYSTEM::homePath() const { @@ -113,3 +125,46 @@ QFileInfoList FILESYSTEM::fileList() dir.setSorting(QDir::Time | QDir::Reversed); return dir.entryInfoList(); } + +bool FILESYSTEM::isAutostart() { + QFileInfo check_file(QDir::homePath() + "/.config/autostart/friendiqa.desktop"); + + if (check_file.exists() && check_file.isFile()) { + qDebug()<<"autostart "< +// +// 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 +//#include +//#include +//#include +#include +#include "xhr.h" +#include "updatenews.h" +#include "filesystem.h" +//#include "remoteauthasyncimageprovider.h" +#include "alarm.h" +#include "oauth.h" +#include "documenthandler.h" +//#include "AndroidNative/systemdispatcher.h" +//#include "AndroidNative/environment.h" +//#include "AndroidNative/debug.h" +//#include "AndroidNative/mediascannerconnection.h" +//#include +#include +#include +#include + +// Declare a user-defined data type to work with an icon in QML +Q_DECLARE_METATYPE(QSystemTrayIcon::ActivationReason) + + + +#ifdef Q_OS_ANDROID +#include +#include +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { + Q_UNUSED(vm); + qDebug("NativeInterface::JNI_OnLoad()"); // It must call this function within JNI_OnLoad to enable System Dispatcher + + AndroidNative::SystemDispatcher::registerNatives(); + return JNI_VERSION_1_6; +} +#endif + + +int main(int argc, char *argv[]) { + //qDebug()<< "argv Friendiqa"<< (qstrcmp(argv[1],"-service")==0) <<" argv2" <setDatabase(); + updatenews->login(); + updatenews->setSyncAll(true); + updatenews->startsync(); + app.connect (updatenews,SIGNAL(quitapp()),&app,SLOT(quit())); + //QtAndroid::androidService().callMethod("stopSelf"); + return app.exec(); + } + else{ + QQmlApplicationEngine view; + //view.setResizeMode(QQuickView::SizeRootObjectToView); + app.setWindowIcon(QIcon("qrc:/assets/Friendiqa.ico")); + QTranslator qtTranslator; + if(qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations")) + {app.installTranslator(&qtTranslator);} + // RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider; + // view.addImageProvider("remoteauthimage",imageProvider); + // view.rootContext()->setContextProperty("remoteauth", imageProvider); + XHR* xhr = XHR::instance(); + view.rootContext()->setContextProperty("xhr", xhr); + FILESYSTEM* filesystem = FILESYSTEM::instance(); + if (qstrcmp(argv[1],"-background")==0){ + filesystem->setVisibility(false); + } else{filesystem->setVisibility(true);} + + view.rootContext()->setContextProperty("filesystem", filesystem); + ALARM* alarm = ALARM::instance(); + view.rootContext()->setContextProperty("alarm", alarm); + UPDATENEWS* updatenews = UPDATENEWS::instance(); + view.rootContext()->setContextProperty("updatenews", updatenews); + updatenews->setDatabase(); + OAuthWrapper* oauth2 = OAuthWrapper::instance(); + view.rootContext()->setContextProperty("oauth2", oauth2); + qmlRegisterType("io.qt.examples.texteditor", 1, 0, "DocumentHandler"); + qmlRegisterType("QSystemTrayIcon", 1, 0, "QSystemTrayIcon"); + qRegisterMetaType("ActivationReason"); + view.rootContext()->setContextProperty("iconTrayBlack", QIcon(QPixmap(":/assets/friendica-tray-black.svg"))); + view.rootContext()->setContextProperty("iconTrayWhite", QIcon(QPixmap(":/assets/friendica-tray-white.svg"))); + + view.rootContext()->setContextProperty("iconTrayAvailable", QSystemTrayIcon::isSystemTrayAvailable()); + if(updatenews->getStyle() != 0){ + QQuickStyle::setStyle("Material"); + } + view.load(QUrl("qrc:/qml/friendiqa.qml")); + view.connect(view.rootContext()->engine(), SIGNAL(quit()), &app, SLOT(quit())); + return app.exec(); + + } +} diff --git a/src/common/oauth.cpp b/src/common/oauth.cpp new file mode 100644 index 0000000..c2d0d4d --- /dev/null +++ b/src/common/oauth.cpp @@ -0,0 +1,88 @@ +// This file is part of Friendiqa +// https://github.com/lubuwest/Friendiqa +// Copyright (C) 2023 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 "oauth.h" + +#include +#include +#include + + +OAuthWrapper *OAuthWrapper::instance() +{ + static OAuthWrapper oa2; + return &oa2; +} + + +OAuthWrapper::OAuthWrapper(QObject *parent) : QObject(parent) +{ + auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this); + oauth2.setReplyHandler(replyHandler); + oauth2.setScope("read+write+follow+push"); + + connect(&oauth2, &QOAuth2AuthorizationCodeFlow::statusChanged, [=]( + QAbstractOAuth::Status status) { + if (status == QAbstractOAuth::Status::Granted){ + QMapIterator i(oauth2.extraTokens()); + while (i.hasNext()) { + i.next(); + //qDebug() << i.key() << ": " << i.value() << Qt::endl; + } + emit success(oauth2.token()); + } + }); + connect(&oauth2, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, + &QDesktopServices::openUrl); +} + +void OAuthWrapper::setClientId(QString clientid) +{ + m_clientid = clientid; +} +void OAuthWrapper::setServer(QString server) +{ + m_server = server; +} +void OAuthWrapper::setClientSecret(QString clientsecret) +{ + m_clientsecret = clientsecret; +} + +void OAuthWrapper::grant() +{ + oauth2.setClientIdentifier(m_clientid); + oauth2.setAuthorizationUrl(QUrl(m_server + "/oauth/authorize")); + oauth2.setAccessTokenUrl(QUrl(m_server + "/oauth/token")); + + oauth2.setClientIdentifierSharedKey(m_clientsecret); + oauth2.grant(); +} diff --git a/src/common/oauth.h b/src/common/oauth.h new file mode 100644 index 0000000..92b8508 --- /dev/null +++ b/src/common/oauth.h @@ -0,0 +1,71 @@ +// This file is part of Friendiqa +// https://github.com/lubuwest/Friendiqa +// Copyright (C) 2020 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 . + +#ifndef OAUTH_H +#define OAUTH_H + +#include +#include + +#include + + +class OAuthWrapper : public QObject//, public QAndroidActivityResultReceiver +{ + Q_OBJECT + + +public: + OAuthWrapper(QObject *parent = nullptr);; + OAuthWrapper(const QString &clientIdentifier, QObject *parent = nullptr); + static OAuthWrapper *instance(); +// bool isPermanent() const; +// void setPermanent(bool value); + +signals: + void success(QString token); + void error(QString error); + +public slots: + void grant(); + void setServer(QString server); + void setClientId(QString clientid); + void setClientSecret(QString clientsecret); + +private: + QOAuth2AuthorizationCodeFlow oauth2; +// bool permanent = false; + QString m_clientid; + QString m_clientsecret; + QString m_server; +}; + +#endif //OAuthWrapper diff --git a/source-linux/common/remoteauthasyncimageprovider.cpp b/src/common/remoteauthasyncimageprovider.cpp similarity index 100% rename from source-linux/common/remoteauthasyncimageprovider.cpp rename to src/common/remoteauthasyncimageprovider.cpp diff --git a/source-linux/common/remoteauthasyncimageprovider.h b/src/common/remoteauthasyncimageprovider.h similarity index 100% rename from source-linux/common/remoteauthasyncimageprovider.h rename to src/common/remoteauthasyncimageprovider.h diff --git a/source-linux/common/updatenews.cpp b/src/common/updatenews.cpp similarity index 80% rename from source-linux/common/updatenews.cpp rename to src/common/updatenews.cpp index 5da6b54..c894cd2 100644 --- a/source-linux/common/updatenews.cpp +++ b/src/common/updatenews.cpp @@ -32,7 +32,7 @@ #include "updatenews.h" #include -#include +//#include #include #include #include @@ -59,23 +59,29 @@ UPDATENEWS::UPDATENEWS(QObject *parent) : QObject(parent) } -void UPDATENEWS::setUrl(QString url) -{ - if (url!=m_url) { - m_url = url; - xhr.setUrl(url); - emit urlChanged(m_url); - } -} +//void UPDATENEWS::setUrl(QString url) +//{ +// if (url!=m_url) { +// m_url = url; +// xhr.setUrl(url); +// emit urlChanged(m_url); +// } +//} +void UPDATENEWS::setSyncAll(bool syncAll) +{ + m_syncAll=syncAll; +} void UPDATENEWS::setDatabase() { static QQmlEngine qe; QString db_url=qe.offlineStorageDatabaseFilePath("Friendiqa"); - m_db = QSqlDatabase::addDatabase("QSQLITE"); - m_db.setDatabaseName(QUrl("file://"+db_url+".sqlite").toLocalFile()); - //qDebug() << db_url; + if (!m_db.open()) + { + m_db = QSqlDatabase::addDatabase("QSQLITE"); + m_db.setDatabaseName(QUrl("file://"+db_url+".sqlite").toLocalFile()); + } if (!m_db.open()) { @@ -83,29 +89,61 @@ void UPDATENEWS::setDatabase() } } +int UPDATENEWS::getStyle() +{ + if (m_db.open()){ + QSqlQuery syncquery("SELECT * FROM globaloptions",m_db); + while (syncquery.next()){ + if (syncquery.value(0).toString()=="view_darkmode"){ + return syncquery.value(1).toInt(); + } + } + } + return 0; +} + + +QJsonArray UPDATENEWS::getAccounts(QString filtername, QString filtervalue){ + QString filterstring=""; + + if (filtername!=""){ + bool ok; + int filternumber = filtervalue.toInt(&ok, 10); + if(ok){ + filterstring=" WHERE " + filtername + " = " + filtervalue; + } + else{ + filterstring=" WHERE " + filtername + " = '" + filtervalue +"'"; + } + } + QSqlQuery query("SELECT * FROM config" + filterstring + " ORDER BY isActive ASC, username ASC",m_db); + QJsonArray accountlist; + while(query.next()){ + { + QJsonObject accountData; + accountData.insert("server",query.value(0).toString()); + accountData.insert("username",query.value(1).toString()); + accountData.insert("password",query.value(2).toString()); + accountData.insert("imagestore",query.value(3).toString()); + accountData.insert("isActive",query.value(7).toString()); + QJsonArray m_permissions=query.value(7).toJsonArray(); + accountData.insert("permissions",m_permissions); + accountData.insert("token",QString(QByteArray::fromBase64(query.value(10).toByteArray()))); + QJsonDocument m_client; + if(query.value(12).toByteArray()!=""){ + m_client=QJsonDocument::fromJson(QByteArray::fromBase64(query.value(12).toByteArray())); + } + accountData.insert("client",m_client.object()); + accountlist.append(accountData); + } + } + query.clear(); + return accountlist; +} void UPDATENEWS::login() { - QSqlQuery query("SELECT * FROM config WHERE isActive=0",m_db); - while (query.next()) - { - username = query.value(1).toString(); - QByteArray bpassword=query.value(2).toByteArray(); - QString password=QByteArray::fromBase64(bpassword); - m_login=username+":"+password ; - xhr.setLogin(m_login); - m_url=query.value(0).toString(); - xhr.setUrl(m_url); - m_imagedir=query.value(3).toString(); - xhr.setImagedir(m_imagedir); - QString isActive=query.value(7).toString(); - } - //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(); @@ -115,11 +153,9 @@ void UPDATENEWS::login() } 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() << " " <

"+newsitem["friendica_html"].toString(); - query.bindValue(11, friendicaHtml.toUtf8().toBase64());} - else{query.bindValue(11, newsitem["friendica_html"].toString().toUtf8().toBase64());} + //if (newsitem["friendica_title"]!="") { + // QString friendicaHtml="" + newsitem["friendica_title"].toString() +"

"+newsitem["friendica_html"].toString(); + // query.bindValue(11, friendicaHtml.toUtf8().toBase64());} + //else{ + query.bindValue(11, newsitem["friendica_html"].toString().toUtf8().toBase64());//} if (newsitem["statusnet_conversation_id"].isDouble()){ query.bindValue(12, newsitem["statusnet_conversation_id"].toInt()); }else{query.bindValue(12, newsitem["statusnet_conversation_id"].toString());} @@ -351,14 +401,14 @@ void UPDATENEWS::store(QByteArray serverreply,QString apiname) if (apiname == "/api/direct_messages/all"){ query.bindValue(1,"1"); query.bindValue(5,"Friendica"); - query.bindValue(6,newsitem["id"].toString().toInt()); + query.bindValue(6,newsitem["id"].toInt()); if(newsitem["recipient"]["id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["recipient"]["id"].toInt());} query.bindValue(10, newsitem["sender_id"].toInt()); query.bindValue(11, newsitem["text"].toString().toUtf8().toBase64()); if(newsitem["friendica_parent_uri"]!=QJsonValue::Null){ query.bindValue(12,newsitem["friendica_parent_uri"]);} query.bindValue(16, newsitem["sender"]["url"]); } - if (apiname == "/api/friendica/notifications"){ + if (apiname == "/api/friendica/notification"){ query.bindValue(1,"2"); query.bindValue(3,QDateTime::fromString(newsitem["date"].toString(),"yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch()); query.bindValue(5,"Friendica"); @@ -387,7 +437,7 @@ void UPDATENEWS::store(QByteArray serverreply,QString apiname) alarm.notify("DirectMessage: "+newsitem["sender"]["name"].toString(),newsitem["text"].toString(),2); } } - if (apiname=="/api/friendica/notifications"){ + if (apiname=="/api/friendica/notification"){ if(notifylist.contains("notify_Notifications")){ alarm.notify("Notification: "+newsitem["name"].toString(),newsitem["text"].toString(),3); } @@ -398,31 +448,32 @@ void UPDATENEWS::store(QByteArray serverreply,QString apiname) } } QList newcontacts=findNewContacts(news); + emit this->success(m_api); if (newcontacts.size()>0){ updateContacts(newcontacts); startImagedownload("contactlist"); } else { - if(m_updateInterval!=0){ + if((m_updateInterval!=0) && m_syncAll){ syncindex+=1; startsync(); } } } else { - qDebug()<< "Friendiqa updatenews error " << serverreply; - emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply)); - syncindex+=1; - startsync(); + qDebug()<< m_api <error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply)); + emit this->error(m_api,QString(serverreply)); + if(m_syncAll){ + syncindex+=1; + startsync(); + } } } } - - void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index){ - //qDebug()<< "update Imagelocation " << downloadtype << " " << imageurl << " " << filename; if (downloadtype=="contactlist"){ QSqlQuery testquery("SELECT profile_image FROM contacts WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db); testquery.first(); @@ -431,7 +482,7 @@ void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QStr if (index==(newcontactnames.length()-1)){ newcontactnames.clear(); newcontactimagelinks.clear(); - if(m_updateInterval!=0){ + if((m_updateInterval!=0) && m_syncAll){ syncindex+=1; startsync(); } @@ -445,7 +496,7 @@ void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QStr if (index==(newcontactnames.length()-1)){ newcontactnames.clear(); newcontactimagelinks.clear(); - if(m_updateInterval!=0){ + if((m_updateInterval!=0) && m_syncAll){ syncindex+=1; startsync(); } @@ -454,7 +505,6 @@ void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QStr } QJsonObject UPDATENEWS::findNotificationContact(QString contacturl){ - //qDebug()<< "findNotificationContact "< contacts){ 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=?," - "profile_image_url=?, description=?, protected=?, followers_count=?," - "friends_count=?, created_at=?, favourites_count=?, utc_offset=?, time_zone=?, statuses_count=?," - "following=?, verified=?, statusnet_blocking=?, notifications=?, statusnet_profile_url=?, cid=?, network=?, timestamp=? " - " WHERE username='"+ username +"' AND url='" + contact["url"].toString() +"'"); + "profile_image_url=?, description=?, protected=?, followers_count=?," + "friends_count=?, created_at=?, favourites_count=?, utc_offset=?, time_zone=?, statuses_count=?," + "following=?, verified=?, statusnet_blocking=?, notifications=?, statusnet_profile_url=?, cid=?, network=?, timestamp=? " + " WHERE username='"+ username +"' AND url='" + contact["url"].toString() +"'"); query.bindValue(0, contact["id"].toInt()); query.bindValue(1, contact["name"].toString().toUtf8().toBase64()); query.bindValue(2, contact["screen_name"]); @@ -573,10 +623,10 @@ void UPDATENEWS::updateContacts(QList contacts){ else{ query.prepare("INSERT INTO contacts (username, id, name, screen_name, location,imageAge," - "profile_image_url, description, profile_image, url, protected, followers_count," - "friends_count, created_at, favourites_count, utc_offset, time_zone, statuses_count," - "following, verified, statusnet_blocking, notifications, statusnet_profile_url, cid, network, isFriend, timestamp)" - "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + "profile_image_url, description, profile_image, url, protected, followers_count," + "friends_count, created_at, favourites_count, utc_offset, time_zone, statuses_count," + "following, verified, statusnet_blocking, notifications, statusnet_profile_url, cid, network, isFriend, timestamp)" + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); query.bindValue(0,username); query.bindValue(1, contact["id"].toInt()); @@ -628,6 +678,7 @@ void UPDATENEWS::storeFriendrequests(QByteArray serverreply,QString apiname) QSqlQuery imagequery("SELECT avatar FROM friendshiprequests",m_db); QList imageurls; + while (imagequery.next()){ imageurls.append(imagequery.value(0).toString()); } @@ -639,10 +690,10 @@ void UPDATENEWS::storeFriendrequests(QByteArray serverreply,QString apiname) QSqlQuery query(m_db); if (testquery.first()){ query.prepare("UPDATE friendshiprequests SET id=?, usernamef=?, acct=?, display_name=?,locked=?," - "bot=?, discoverable=?, groupf=?, created_at=?," - "note=?, avatar=?, header=?, header_static=?, followers_count=?," - "following_count=?, statuses_count=?, last_status_at=?, emojis=?, fields=? " - " WHERE username='"+ username +"' AND url='" + friendrequestitem["url"].toString() +"'"); + "bot=?, discoverable=?, groupf=?, created_at=?," + "note=?, avatar=?, header=?, header_static=?, followers_count=?," + "following_count=?, statuses_count=?, last_status_at=?, emojis=?, fields=? " + " WHERE username='"+ username +"' AND url='" + friendrequestitem["url"].toString() +"'"); query.bindValue(0, friendrequestitem["id"].toInt()); query.bindValue(1, friendrequestitem["username"]); @@ -667,9 +718,9 @@ void UPDATENEWS::storeFriendrequests(QByteArray serverreply,QString apiname) else{ query.prepare("INSERT INTO friendshiprequests (username, id, usernamef, acct, display_name, locked," - " created_at, followers_count, following_count, statuses_count, note, url, avatar, avatar_static, " - "header, header_static, emojis, moved, fields, bot, groupf, discoverable, last_status_at) " - "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + " created_at, followers_count, following_count, statuses_count, note, url, avatar, avatar_static, " + "header, header_static, emojis, moved, fields, bot, groupf, discoverable, last_status_at) " + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); query.bindValue(0, username); query.bindValue(1, friendrequestitem["id"].toInt()); query.bindValue(2, friendrequestitem["username"].toString()); @@ -710,13 +761,12 @@ void UPDATENEWS::storeFriendrequests(QByteArray serverreply,QString apiname) newcontactimagelinks.append(friendrequestitem["avatar"].toString()); newcontactnames.append(friendrequestitem["username"].toString()); } - } + if (newcontactimagelinks.length()>0){ - //qDebug() << "start Friendrequests imagedownload"; startImagedownload("friendrequests"); }else{ - if(m_updateInterval!=0){ + if((m_updateInterval!=0) && m_syncAll){ syncindex+=1; startsync(); } @@ -740,16 +790,31 @@ void UPDATENEWS::storeEvents(QByteArray serverreply,QString apiname) query.bindValue(0,username); query.bindValue(1,eventitem["id"].toInt()); query.bindValue(2,eventitem["cid"].toInt()); - QString sourcedateStart=eventitem["startTime"].toString(); + QString sourcedateStart=""; + if (eventitem["start_time"].toString()!=""){ + sourcedateStart=eventitem["start_time"].toString();}else{ + sourcedateStart=eventitem["startTime"].toString(); + }; query.bindValue(3,QDateTime::fromString(sourcedateStart,Qt::ISODate).toMSecsSinceEpoch() ); - QString sourcedateEnd=eventitem["endTime"].toString(); + QString sourcedateEnd=""; + if (eventitem["end_time"].toString()!=""){ + sourcedateEnd=eventitem["end_time"].toString();} else{ + sourcedateEnd=eventitem["endTime"].toString(); + } + + if(QDateTime::fromString(sourcedateEnd,Qt::ISODate).toMSecsSinceEpoch()>QDateTime::fromString(sourcedateStart,Qt::ISODate).toMSecsSinceEpoch()){ + //check if end is later than start + query.bindValue(4,QDateTime::fromString(sourcedateEnd,Qt::ISODate).toMSecsSinceEpoch() ); + } else { + query.bindValue(4,0 ); + } query.bindValue(4,QDateTime::fromString(sourcedateEnd,Qt::ISODate).toMSecsSinceEpoch() ); query.bindValue(5,eventitem["name"].toString()); query.bindValue(6,eventitem["uri"].toString()); query.bindValue(7,eventitem["desc"].toString().toUtf8().toBase64()); query.bindValue(8,eventitem["place"].toString()); query.bindValue(9,eventitem["type"].toString()); - query.bindValue(10,eventitem["nofinsh"].toInt()); + query.bindValue(10,eventitem["nofinish"].toInt()); query.bindValue(11,eventitem["adjust"].toInt()); query.bindValue(12,eventitem["ignore"].toInt()); QJsonArray permissions; permissions={eventitem["allow_cid"].toString().replace("<","[").replace(">","]"),eventitem["allow_gid"].toString().replace("<","[").replace(">","]"),eventitem["deny_cid"].toString().replace("<","[").replace(">","]"),eventitem["deny_gid"].toString().replace("<","[").replace(">","]")}; @@ -764,38 +829,31 @@ void UPDATENEWS::storeEvents(QByteArray serverreply,QString apiname) } } if(notifylist.contains("notify_Events")){ - QSqlQuery eventnotifyquery("SELECT start,title FROM events WHERE (start BETWEEN " + QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()) + " AND "+QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()+(m_updateInterval*60*1000))+") AND username='"+ username +"'",m_db); + QSqlQuery eventnotifyquery("SELECT start,title FROM events WHERE (start BETWEEN " + QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()) + " AND "+QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()+(m_updateInterval*119*1000))+") AND username='"+ username +"'",m_db); while (eventnotifyquery.next()) { alarm.notify("Event: "+ QDateTime::fromMSecsSinceEpoch(eventnotifyquery.value(0).toLongLong()).toString("dd.MM.yyyy hh:mm"),eventnotifyquery.value(1).toString(),1); } } - if(m_updateInterval!=0){ + if((m_updateInterval!=0) && m_syncAll){ syncindex+=1; startsync(); } QObject::disconnect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(storeEvents(QByteArray,QString))); } -QString UPDATENEWS::url() const -{ - return m_url; -} - void UPDATENEWS::startImagedownload(QString downloadtype) { xhr.setDownloadtype(downloadtype ); xhr.setFilelist(newcontactimagelinks); xhr.setContactlist(newcontactnames); - xhr.setImagedir(m_imagedir); xhr.getlist(); } 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){ + if((m_updateInterval!=0) && m_syncAll){ syncindex+=1; startsync(); } diff --git a/source-linux/common/updatenews.h b/src/common/updatenews.h similarity index 87% rename from source-linux/common/updatenews.h rename to src/common/updatenews.h index 4fe6741..d046aa1 100644 --- a/source-linux/common/updatenews.h +++ b/src/common/updatenews.h @@ -34,6 +34,7 @@ #include #include +#include #include #include "xhr.h" #include "alarm.h" @@ -42,26 +43,21 @@ class UPDATENEWS : public QObject { Q_OBJECT - Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) -// Q_PROPERTY(QString login READ login NOTIFY loginChanged) + public: static UPDATENEWS *instance(); explicit UPDATENEWS(QObject *parent = 0); - - QString url() const; - //QString login() const; signals: - - void urlChanged(QString url); void success(QString api); void error(QString api, QString content); void quitapp(); public slots: - void setUrl(QString url); + void setSyncAll(bool syncAll); void setDatabase(); + int getStyle(); void login(); void timeline(); void replies(); @@ -70,29 +66,28 @@ public slots: void notifications(); void friendrequests(); void events(); - //void startservice(QString type,QVariantMap map); void startImagedownload(QString downloadtype); void updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index); void store(QByteArray serverreply,QString apiname); void storeFriendrequests(QByteArray serverreply,QString apiname); void storeEvents(QByteArray serverreply,QString apiname); void showError(QString data, QString url,QString api, int code); + QJsonArray getAccounts(QString filtername="",QString filtervalue=""); private: - QString m_url; QString m_api; - QString m_imagedir; - QString m_login; + QString m_url; QString username; + bool m_syncAll; int syncindex; + int usernameindex; + int usernamelength; 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); void updateContacts(QList contacts); XHR xhr; diff --git a/source-linux/common/uploadableimage.cpp b/src/common/uploadableimage.cpp similarity index 92% rename from source-linux/common/uploadableimage.cpp rename to src/common/uploadableimage.cpp index 221f13b..cea2d77 100644 --- a/source-linux/common/uploadableimage.cpp +++ b/src/common/uploadableimage.cpp @@ -42,7 +42,7 @@ void UploadableImage::setAngle(const int &b) { if (b != m_angle) { m_angle = b; - qDebug() << "UploadableImage::setAngle : " << m_angle; + //qDebug() << "UploadableImage::setAngle : " << m_angle; if (m_angle==0) { emit angleChanged(); return; @@ -57,7 +57,7 @@ void UploadableImage::setSource(const QString &a) { m_mimetype = ""; m_filename = ""; - qDebug() << "UploadableImage::setSource : " << m_source; + //qDebug() << "UploadableImage::setSource : " << m_source; if (m_source=="") { emit sourceChanged(); @@ -83,7 +83,7 @@ void UploadableImage::setSource(const QString &a) { } else { m_image = fullimage; } - qDebug() << "UploadableImage::setSource : " << m_image.width() << "x" << m_image.height(); + //qDebug() << "UploadableImage::setSource : " << m_image.width() << "x" << m_image.height(); emit sourceChanged(); QFileInfo fi(m_source); @@ -95,7 +95,7 @@ void UploadableImage::setSource(const QString &a) { if (filetype!="PNG" && filetype!="JPG") { filetype = "JPG"; } - qDebug() << "UploadableImage::setSource : " << "Saving as " << filetype; + //qDebug() << "UploadableImage::setSource : " << "Saving as " << filetype; m_mimetype = "image/"+filetype.toLower(); emit mimetypeChanged(); diff --git a/source-linux/common/uploadableimage.h b/src/common/uploadableimage.h similarity index 100% rename from source-linux/common/uploadableimage.h rename to src/common/uploadableimage.h diff --git a/source-linux/common/xhr.cpp b/src/common/xhr.cpp similarity index 60% rename from source-linux/common/xhr.cpp rename to src/common/xhr.cpp index 27b31d6..dba9c5d 100644 --- a/source-linux/common/xhr.cpp +++ b/src/common/xhr.cpp @@ -32,10 +32,11 @@ #include "xhr.h" #include -#include +//#include #include #include #include +#include #include #include #include "uploadableimage.h" @@ -48,70 +49,95 @@ XHR *XHR::instance() XHR::XHR(QObject *parent) : QObject(parent) { - request.setSslConfiguration(QSslConfiguration::defaultConfiguration()); + //request.setSslConfiguration(QSslConfiguration::defaultConfiguration()); } void XHR::setUrl(QString url) { - if (url!=m_url) { - m_url = url; - emit urlChanged(); - } + if (url!=m_url) { + m_url = url; + emit urlChanged(); + } } void XHR::setApi(QString api) { - if (api!=m_api) { - m_api = api; - emit apiChanged(); - } + if (api!=m_api) { + m_api = api; + emit apiChanged(); + } } void XHR::setLogin(QString login) { - if (login!=m_login) { - m_login = login; - emit loginChanged(); - } + if (login!=m_login) { + m_login = login; + m_token=""; + emit loginChanged(); + } +} + +void XHR::setAccount(QVariantMap account) +{ + clearParams(); + if (account["password"].toString() !=""){ + setLogin(account["username"].toString()+":"+QByteArray::fromBase64(account["password"].toByteArray())); + } + else if (account["token"].toString() !="" && !account["token"].isNull()){ + setToken(account["token"].toString()); + } + setUrl(account["server"].toString()); + setImagedir(account["imagestore"].toString()); + m_account = account; + emit accountChanged(); +} + +void XHR::setToken(QString token) +{ + if (token!=m_token) { + m_token = token; + m_login=""; + emit tokenChanged(); + } } void XHR::setFilename(QString filename) { - if (filename!=m_filename) { - m_filename = filename; - emit filenameChanged(); - } + if (filename!=m_filename) { + m_filename = filename; + emit filenameChanged(); + } } void XHR::setContactlist(QList contactlist) { - if (contactlist!=m_contactlist) { - m_contactlist = contactlist; - emit contactlistChanged(); - } + if (contactlist!=m_contactlist) { + m_contactlist = contactlist; + emit contactlistChanged(); + } } void XHR::setFilelist(QList filelist) { - if (filelist!=m_filelist) { - m_filelist = filelist; - emit filelistChanged(); - } + if (filelist!=m_filelist) { + m_filelist = filelist; + emit filelistChanged(); + } } void XHR::setImagedir(QString imagedir) { - if (imagedir!=m_imagedir) { - m_imagedir = imagedir; - emit imagedirChanged(); - } + if (imagedir!=m_imagedir) { + m_imagedir = imagedir; + emit imagedirChanged(); + } } void XHR::setDownloadtype(QString downloadtype) { - if (downloadtype!=m_downloadtype) { - m_downloadtype = downloadtype; - emit downloadtypeChanged(); - } + if (downloadtype!=m_downloadtype) { + m_downloadtype = downloadtype; + emit downloadtypeChanged(); + } } QString XHR::url() const @@ -129,6 +155,16 @@ QString XHR::login() const return m_login; } +QString XHR::token() const +{ + return m_token; +} + +QVariantMap XHR::account() const +{ + return m_account; +} + QString XHR::filename() const { return m_filename; @@ -173,10 +209,16 @@ void XHR::clearParams() void XHR::download() { QUrl requrl(m_url); + QNetworkRequest request; if(m_downloadtype=="picturelist"){ - QByteArray loginData = m_login.toLocal8Bit().toBase64(); - QString headerData = "Basic " + loginData; - request.setRawHeader("Authorization", headerData.toLocal8Bit()); + if(m_login!=""){ + QByteArray loginData = m_login.toLocal8Bit().toBase64(); + QString headerData = "Basic " + loginData; + request.setRawHeader("Authorization", headerData.toLocal8Bit()); + } else{ + QString headerData = "Bearer " + m_token; + request.setRawHeader("Authorization", headerData.toLocal8Bit()); + } } request.setUrl(requrl); reply = manager.get(request); @@ -185,31 +227,35 @@ void XHR::download() //connect(reply,SIGNAL(downloadProgress(qint64,qint64)), this,SLOT(updateDownloadProgress(qint64,qint64))); connect(reply, &QNetworkReply::finished,this, &XHR::onRequestFinished); connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError); - connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError))); + connect(reply, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError))); } void XHR::get() { QUrlQuery query; - + //qDebug() << "get"; QHashIterator i(params); while(i.hasNext()) { i.next(); + //qDebug() << i.key() << "value" << i.value(); query.addQueryItem(i.key(), i.value()); - //qDebug()< iparams(params); while(iparams.hasNext()) { iparams.next(); - //qDebug() << "\t add param " << iparams.key() << " : " << iparams.value(); QHttpPart textPart; textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + iparams.key() + "\"")); - - textPart.setBody(iparams.value().toUtf8()); multiPart->append(textPart); } @@ -249,7 +293,6 @@ void XHR::post() if (files.contains("media")){ uimg.setAngle(files.value("angle").toInt()); uimg.setSource(files.value("media")); - QHttpPart imagePart; imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(uimg.mimetype())); imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"media\"; filename=\""+uimg.filename()+"\"")); @@ -257,18 +300,47 @@ void XHR::post() multiPart->append(imagePart); } - QByteArray loginData = m_login.toLocal8Bit().toBase64(); - QString headerData = "Basic " + loginData; - request.setRawHeader(QByteArray("Authorization"), headerData.toLocal8Bit()); - + QNetworkRequest request; + if(m_login!=""){ + QByteArray loginData = m_login.toLocal8Bit().toBase64(); + QString headerData = "Basic " + loginData; + request.setRawHeader("Authorization", headerData.toLocal8Bit()); + } else if (m_token!=""){ + QString headerData = "Bearer " + m_token; + request.setRawHeader("Authorization", headerData.toLocal8Bit()); + } request.setUrl(m_url+m_api); reply = manager.post(request, multiPart); qDebug() << "\t request sent"; connect(reply, &QNetworkReply::finished, this, &XHR::onReplySuccess); - connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError))); + connect(reply, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError))); connect(reply, &QNetworkReply::readyRead, this, &XHR::onReadyRead); connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError); - qDebug() << "\t reply signals connected"; +} + +void XHR::postJSON() +{ + if (params.contains("JSON")){ + QByteArray mJSON=params.value("JSON").toUtf8(); + QNetworkRequest request; + if(m_login!=""){ + QByteArray loginData = m_login.toLocal8Bit().toBase64(); + QString headerData = "Basic " + loginData; + request.setRawHeader("Authorization", headerData.toLocal8Bit()); + } else if (m_token!=""){ + QString headerData = "Bearer " + m_token; + request.setRawHeader("Authorization", headerData.toLocal8Bit()); + } + request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json; charset=UTF-8"); + request.setUrl(m_url+m_api); + reply = manager.post(request, mJSON); + qDebug() << "\t request sent"; + connect(reply, &QNetworkReply::finished, this, &XHR::onReplySuccess); + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError))); + connect(reply, &QNetworkReply::readyRead, this, &XHR::onReadyRead); + connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError); + qDebug() << "\t reply signals connected"; + } } void XHR::onReplyError(QNetworkReply::NetworkError code) @@ -283,26 +355,36 @@ void XHR::onReplyError(QNetworkReply::NetworkError code) void XHR::onReplySuccess() { qDebug() << "!"; - emit this->success(buffer, m_api); + //QHashIterator i(params); + // while(i.hasNext()) { + // i.next(); + // //qDebug() << i.key()<< " " << i.value(); + // } + //emit this->success(buffer, m_api); + emit success(buffer, m_api); + //emit this->error(m_downloadtype,m_url,m_api,1); buffer.clear(); -// reply->deleteLater(); + // 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);} + //qDebug() << "buffer " << buffer; + if (buffer.isNull()){qDebug() << "File empty"<error(m_downloadtype,m_url,m_api,1); + } else if (m_downloadtype=="picturelist") { QJsonDocument jsonResponse = QJsonDocument::fromJson(buffer); QJsonObject jsonObject = jsonResponse.object(); - int arraystart=buffer.indexOf('{"data":"')+8; + int arraystart=buffer.indexOf("{\"data\":\"")+8; int arraylength=buffer.indexOf('"',9)-arraystart; QByteArray b64=buffer.mid(arraystart,arraylength); QString helpfilename=jsonObject["filename"].toString(); QString helpfile=helpfilename.left(helpfilename.lastIndexOf(".")); QString filesuffix=""; - if (jsonObject["type"].toString()=="image/jpeg"){filesuffix=".jpg";} + if (jsonObject["type"].toString()=="image/jpeg" || jsonObject["type"].toString()=="image/jpg"){filesuffix=".jpg";} else if (jsonObject["type"].toString()=="image/png"){filesuffix=".png";} else {filesuffix="";} if (helpfilename==""){// check if file has any filename @@ -320,7 +402,6 @@ void XHR::onRequestFinished() jsonObject["data"]=""; jsonObject["filename"]=helpfile+filesuffix; emit this->downloadedjson(m_downloadtype,m_url,m_filename,dlindex,jsonObject); - if(downloadtype()=="picturelist"){dlindex=dlindex+1;XHR::getlist();} } else { QFile file(m_filename); @@ -329,9 +410,10 @@ void XHR::onRequestFinished() buffer.clear(); file.close(); emit this->downloaded(m_downloadtype,m_url,m_filename,dlindex); - if(downloadtype()=="contactlist" || downloadtype()=="friendrequests"){dlindex=dlindex+1;XHR::getlist();} - - //reply->deleteLater(); + //reply->deleteLater(); + } + if(downloadtype()=="contactlist" || downloadtype()=="friendrequests" || downloadtype()=="picturelist"){ + dlindex=dlindex+1;XHR::getlist(); } } @@ -344,7 +426,7 @@ void XHR::onReadyRead() //void XHR::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes) //{ // qDebug() << "Bytes: " << bytesRead<<" / "< &errors) @@ -358,5 +440,6 @@ void XHR::onSSLError(const QList &errors) QString XHR::bufferToString() { - return QTextCodec::codecForName("utf-8")->toUnicode(buffer); + //return QTextCodec::codecForName("utf-8")->toUnicode(buffer); + return QString(buffer); } diff --git a/source-linux/common/xhr.h b/src/common/xhr.h similarity index 90% rename from source-linux/common/xhr.h rename to src/common/xhr.h index 6cec7ee..fd2d024 100644 --- a/source-linux/common/xhr.h +++ b/src/common/xhr.h @@ -37,13 +37,15 @@ #include #include #include -#include +//#include class XHR : public QObject { Q_OBJECT Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged) + Q_PROPERTY(QString token READ token WRITE setToken NOTIFY tokenChanged) + Q_PROPERTY(QVariantMap account READ account WRITE setAccount NOTIFY accountChanged) Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged) Q_PROPERTY(QString imagedir READ imagedir WRITE setImagedir NOTIFY imagedirChanged) Q_PROPERTY(QList contactlist READ contactlist WRITE setContactlist NOTIFY contactlistChanged) @@ -60,6 +62,8 @@ public: QString url() const; QString api() const; QString login() const; + QString token() const; + QVariantMap account() const; QString filename() const; QList contactlist() const; QList filelist() const; @@ -71,6 +75,8 @@ signals: void urlChanged(); void apiChanged(); void loginChanged(); + void tokenChanged(); + void accountChanged(); void filenameChanged(); void contactlistChanged(); void filelistChanged(); @@ -86,6 +92,8 @@ public slots: void setUrl(QString url); void setApi(QString api); void setLogin(QString login); + void setToken(QString token); + void setAccount(QVariantMap account); void setDownloadtype(QString downloadtype); void setFilename(QString filename); void setContactlist(QList filename); @@ -95,6 +103,7 @@ public slots: void setImageFileParam(QString name, QString url); void clearParams(); void post(); + void postJSON(); void get(); void getlist(); void download(); @@ -114,6 +123,8 @@ private: QString m_url; QString m_api; QString m_login; + QString m_token; + QVariantMap m_account; QString m_filename; QString m_downloadtype; // QString m_networktype; @@ -125,7 +136,7 @@ private: int dlindex; QNetworkAccessManager manager; - QNetworkRequest request; + //QNetworkRequest request; QNetworkReply *reply; //QNetworkConfiguration nc; QString bufferToString(); diff --git a/source-linux/js/friendworker.js b/src/js/friendworker.js similarity index 96% rename from source-linux/js/friendworker.js rename to src/js/friendworker.js index ab97351..146b1cf 100644 --- a/source-linux/js/friendworker.js +++ b/src/js/friendworker.js @@ -34,7 +34,6 @@ WorkerScript.onMessage = function(msg) { if (msg.albums[j]) { var albumobject=msg.albums[j]; var data=({"albumobject": albumobject,"foreignPicture": msg.foreignPicture})} -// print("Albums:"+j+msg.albums.length+JSON.stringify(data)); msg.model.append(data);} if (j==msg.albums.length){ msg.model.sync() diff --git a/source-linux/js/helper.js b/src/js/helper.js similarity index 74% rename from source-linux/js/helper.js rename to src/js/helper.js index e22ccbe..7a70eef 100644 --- a/source-linux/js/helper.js +++ b/src/js/helper.js @@ -39,8 +39,8 @@ function friendicaRequest(login,api,rootwindow,callback) { try{ if (xhrequest.status==200){ callback(xhrequest.responseText) - }else{ - showMessage("Error","API:\n" +login.server+api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow); + }else{print("xhrequest.status "+xhrequest.status) + callback(xhrequest.responseText) } } catch (e){ @@ -48,27 +48,39 @@ function friendicaRequest(login,api,rootwindow,callback) { } } } - xhrequest.open("GET", login.server+api,true,login.username,Qt.atob(login.password)); + if (login.password==""){ + xhrequest.open("GET", login.server+api,true); + xhrequest.setRequestHeader("Authorization","Bearer "+login.token); + } + else{ + xhrequest.open("GET", login.server+api,true,login.username,Qt.atob(login.password)); + } xhrequest.send(); } function friendicaPostRequest(login,api,data,method,rootwindow,callback) { var xhrequest= new XMLHttpRequest(); xhrequest.onreadystatechange = function() { - //print(api+JSON.stringify(login)+Qt.atob(login.password)); if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) { } else if(xhrequest.readyState === XMLHttpRequest.DONE) { - try{ if (xhrequest.responseText!=""){ + try{ if (xhrequest.responseText!=""){//print (xhrequest.responseText) callback(xhrequest.responseText) - }else{print("API:\n" +api+" NO RESPONSE"); - showMessage("Error","API:\n" +api+" NO RESPONSE",rootwindow) + }else{ callback(xhrequest.responseText) } } - catch (e){print("API:\n" + api+" "+e+"\n Return:"+xhrequest.responseText);showMessage("Error", "API:\n" + api+" "+e+"\n Return:"+xhrequest.responseText,rootwindow)} + catch (e){ + print("API:\n" + api+" "+e+"\n Return:"+xhrequest.responseText); + } } } - xhrequest.open(method, login.server+api,true,login.username,Qt.atob(login.password)); + if (login.password==""){ + xhrequest.open(method, login.server+api,true); + xhrequest.setRequestHeader("Authorization","Bearer "+login.token); + } + else{ + xhrequest.open(method, login.server+api,true,login.username,Qt.atob(login.password)); + } xhrequest.send(data); } @@ -82,32 +94,6 @@ function getCount(database,login,table,field,countvalue){ return count } -function friendicaWebRequest(url,rootwindow,callback) { - var xhrequest = new XMLHttpRequest(); - xhrequest.onreadystatechange = function() { - if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {} - else if(xhrequest.readyState === XMLHttpRequest.DONE) { - try{callback(xhrequest.responseText)} - catch (e){showMessage("Error","API:\n" +url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)} - } - } - xhrequest.open("GET", url,true); - xhrequest.send(); -} - -function friendicaXmlRequest(url,rootwindow,callback) { - var xhrequest = new XMLHttpRequest(); - xhrequest.onreadystatechange = function() { - if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {} - else if(xhrequest.readyState === XMLHttpRequest.DONE) { - try{callback(xhrequest.responseXML)} - catch (e){showMessage("Error","API:\n" +url+" "+e+"\n Return: "+xhrequest.responseText, rootwindow)} - } - } - xhrequest.open("GET", url); - xhrequest.responseType ="document"; - xhrequest.send(); -} function friendicaRemoteAuthRequest(login,url,c_url,rootwindow,callback) { var xhrequest = new XMLHttpRequest(); @@ -138,7 +124,6 @@ function readData(database,table,username,callback,filter,filtervalue, sort) { / var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); if(!db) { return; } db.transaction( function(tx) { - //print('select * from '+table+user+where+sortparam); var rsArray=[]; var rs = tx.executeSql('select * from '+table+user+where+sortparam); for(var i = 0; i < rs.rows.length; i++) { @@ -157,7 +142,6 @@ var where = " AND "+ filter +" = '" + filtervalue+"'"; db.transaction( function(tx) { //print('... read from database ' + field) var rsArray=[]; - //print('select DISTINCT '+field+' from '+table+' WHERE username="'+username+'"'+where+' ORDER BY '+field+' ASC'); var rs = tx.executeSql('select DISTINCT '+field+' from '+table+' WHERE username="'+username+'"'+where+' ORDER BY '+field+' ASC'); for(var i = 0; i < rs.rows.length; i++) { rsArray.push(rs.rows.item(i)[field]) @@ -180,10 +164,23 @@ var where = " AND "+ filter +" = '" + filtervalue+"'"; }); } +function updateData(database,table, username, key, value, callback,filter,filtervalue) { // reads and applies data from DB + if (filter){ + var where = " AND "+ filter +" = '" + filtervalue+"'"; + } else { var where="";} + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + if(!db) { return; } + db.transaction( function(tx) { + var rsArray=[]; + var rs = tx.executeSql('UPDATE '+table+' SET '+key+' = '+value+' WHERE username="'+username+'"'+where); + callback(); + }); +} + 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+'"}'; + var messageString='import QtQuick 6.3; import QtQuick.Controls 6.3; Dialog{ visible: true; title:"'+header+'";standardButtons: Dialog.Ok;anchors.centerIn: parent;Label{text:" '+cleanmessage+'"}}'; var messageObject=Qt.createQmlObject(messageString,rootwindow,"messageOutput"); } diff --git a/src/js/image.js b/src/js/image.js new file mode 100644 index 0000000..2bacb20 --- /dev/null +++ b/src/js/image.js @@ -0,0 +1,269 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 . + +.pragma library +.import QtQuick.LocalStorage 2.0 as Sql +.import "qrc:/js/helper.js" as Helperjs + +function requestList(login,database,onlynew,rootwindow,callback) { + //get list of own images and call download function + Helperjs.friendicaRequest(login,"/api/friendica/photos/list", rootwindow,function (helperobject){ + //print("return"+helperobject); + var obj=JSON.parse(helperobject); + if (onlynew){Helperjs.readField("id",database,"imageData",login.username,function(AllStoredImages){ + if (AllStoredImages.length>0){ + for(var i=0;i< AllStoredImages.length;i++){ + var position=Helperjs.inArray(obj,"id",AllStoredImages[i]); + if (position>-1){obj.splice(position,1)} + } + } + callback(obj) + })} + else{callback(obj)} + })} + +function dataRequest(login,photo,database,xhr,rootwindow) { + // check if image exist and call download function + Helperjs.friendicaRequest(login,"/api/friendica/photo?photo_id="+photo.id, rootwindow, function (image){ + if(image=="" || typeof(image)=="undefined"){currentimageno=currentimageno+1}else{ + + try{ + var obj = JSON.parse(image); + if (obj.hasOwnProperty('status')){ + var helpfilename=photo.filename.substring(0,photo.filename.lastIndexOf(".")); + var filesuffix=""; + if (photo.type=="image/jpeg" || photo.type=="image/jpg"){filesuffix=".jpg"} + else if (photo.type=="image/png"){filesuffix=".png"} + else {filesuffix=""} + if (helpfilename==""){// check if file has any filename + photo.filename=photo["id"]+filesuffix; + } + else{photo.filename=helpfilename+filesuffix} + var link=""; + xhr.setUrl(Qt.resolvedUrl(photo.thumb)); + if(login.password!=""){xhr.setLogin(login.username+":"+Qt.atob(login.password));} + else{xhr.setToken(login.token)} + xhr.setFilename(login.imagestore+'albums/'+photo.album+"/"+photo["filename"]); + xhr.setDownloadtype("picture"); + xhr.download(); + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"'); + if(result.rows.length === 1) {// use update + result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+photo.id+'", created="'+photo.created+'", edited="'+photo.edited+'", profile="0", link="'+photo["thumb"]+'", filename="'+photo.filename+'",title="", desc="'+photo.desc+'", type="'+photo.type+'", width="0", height="0", album="'+photo.album+'", location="file://'+login.imagestore+'albums/'+photo.album+'/" where id="'+photo["id"]+'"'); + } else {// use insert print('... does not exists, create it') + result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,photo.id,photo.created,photo.edited,'', photo.desc, photo.album, photo.filename, photo.type, '', '',0,photo["thumb"],'file://'+login.imagestore+'albums/'+photo.album+"/"]); + } + }) + }else{ + var helpfilename=obj.filename.substring(0,obj.filename.lastIndexOf(".")); + var filesuffix=""; + if (obj.type=="image/jpeg" || photo.type=="image/jpg"){filesuffix=".jpg"} + else if (obj.type=="image/png"){filesuffix=".png"} + else {filesuffix=""} + if (helpfilename==""){// check if file has any filename + obj.filename=obj["id"]+filesuffix; + } + else{obj.filename=helpfilename+filesuffix} + var link=""; + if(obj["link"][0]){link=obj["link"][0]} else{link=obj["link"]["4"]} + xhr.setUrl(Qt.resolvedUrl(link)); + if(login.password!=""){xhr.setLogin(login.username+":"+Qt.atob(login.password));} + else{xhr.setToken(login.token)} + xhr.setFilename(login.imagestore+'albums/'+obj.album+"/"+obj["filename"]); + xhr.setDownloadtype("picture"); + xhr.download(); + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"'); + if(result.rows.length === 1) {// use update + result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+obj.id+'", created="'+obj.created+'", edited="'+obj.edited+'", profile="'+obj.profile+'", link="'+link+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", location="file://'+login.imagestore+'albums/'+obj.album+'/" where id="'+obj["id"]+'"'); + } else {// use insert print('... does not exists, create it') + result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,obj.id,obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width,obj. profile,link,'file://'+login.imagestore+'albums/'+obj.album+"/"]); + } + }) + }} catch (e){ + var helpfilename=photo.filename.substring(0,photo.filename.lastIndexOf(".")); + var filesuffix=""; + if (photo.type=="image/jpeg" || photo.type=="image/jpg"){filesuffix=".jpg"} + else if (photo.type=="image/png"){filesuffix=".png"} + else {filesuffix=""} + if (helpfilename==""){// check if file has any filename + photo.filename=photo["id"]+filesuffix; + } + else{photo.filename=helpfilename+filesuffix} + var link=""; + xhr.setUrl(Qt.resolvedUrl(photo.thumb)); + if(login.password!=""){xhr.setLogin(login.username+":"+Qt.atob(login.password));} + else{xhr.setToken(login.token)} + xhr.setFilename(login.imagestore+'albums/'+photo.album+"/"+photo["filename"]); + xhr.setDownloadtype("picture"); + xhr.download(); + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('SELECT * from imageData where id = "'+photo["id"]+'"'); + if(result.rows.length === 1) {// use update + result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+photo.id+'", created="'+photo.created+'", edited="'+photo.edited+'", profile="0", link="'+photo["thumb"]+'", filename="'+photo.filename+'",title="", desc="'+photo.desc+'", type="'+photo.type+'", width="0", height="0", album="'+photo.album+'", location="file://'+login.imagestore+'albums/'+photo.album+'/" where id="'+photo["id"]+'"'); + } else {// use insert print('... does not exists, create it') + result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,photo.id,photo.created,photo.edited,'', photo.desc, photo.album, photo.filename, photo.type, '', '',0,photo["thumb"],'file://'+login.imagestore+'albums/'+photo.album+"/"]); + } + }) + print("Data retrieval failure! "+ e+obj); + } + }}) +} + +function storeImagedata(login,database,imagedata,rootwindow) { + // check if image exist and call download function + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('SELECT * from imageData where id = "'+imagedata["id"]+'"'); + if(result.rows.length === 1) {// use update + result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+imagedata.id+'", created="'+imagedata.created+'", edited="'+imagedata.edited+'", profile="'+imagedata.profile+'", link="'+imagedata.link[0]+'", filename="'+imagedata.filename+'",title="'+imagedata.title+'", desc="'+imagedata.desc+'", type="'+imagedata.type+'", width="'+imagedata.width+'", height="'+imagedata.height+'", album="'+imagedata.album+'", location="file://'+login.imagestore+'albums/'+imagedata.album+'/" where id="'+imagedata["id"]+'"'); + } else {// use insert print('... does not exists, create it') + result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,imagedata.id,imagedata.created,imagedata.edited, imagedata.title, imagedata.desc, imagedata.album, imagedata.filename, imagedata.type, imagedata.height, imagedata.width,imagedata. profile,imagedata.link[0],'file://'+login.imagestore+'albums/'+imagedata.album+"/"]); + } + })} + +function deleteImage(database,login,type,location,filesystem,rootwindow,callback) { // delete image locally and on server + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + var rsfilename=location.substring(location.lastIndexOf("/")+1,location.length); + var rslocation=location.substring(0,location.lastIndexOf("/")+1); + db.transaction( function(tx) { + if (type=='image'){ + var rs= tx.executeSql('SELECT * FROM imageData WHERE filename="'+rsfilename+'" AND location="'+rslocation+'"') + var imageId=rs.rows.item(0).id; + Helperjs.friendicaPostRequest(login,"/api/friendica/photo/delete?photo_id="+imageId,"","DELETE",rootwindow, function (obj){ + //var deletereturn = JSON.parse(obj); print(obj); + //if (deletereturn.result=="deleted"){ + db.transaction( function(tx) { + var deleters=tx.executeSql('DELETE FROM imageData WHERE location="'+rslocation+'" AND filename="'+rsfilename+'"'); }); + filesystem.Directory=rslocation.substring(7,rslocation.length-1); + filesystem.rmFile(rsfilename) + //} + }) + } + else{ + Helperjs.friendicaPostRequest(login,"/api/friendica/photoalbum/delete?album="+rsfilename,"","DELETE",rootwindow, function (obj){ + //var deletereturn = JSON.parse(obj); + //if (deletereturn.result=="deleted"){ + db.transaction( function(tx) { + var rs= tx.executeSql('SELECT DISTINCT location FROM imageData WHERE album="'+rsfilename+'" AND username="'+login.username+'"'); + var locationstring=rs.rows.item(0).location; + filesystem.Directory=locationstring.substring(7,locationstring.length-1); + filesystem.rmDir(); + var deleters=tx.executeSql('DELETE FROM imageData WHERE album="'+location+'"'); + }) + //} + }) + } + callback(location) + }) +} + +function updateImage(database,login,type,filesystem,imageId,rootwindow,callback) { // delete image locally and on server + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + Helperjs.readData(database,"imageData",login.username,function(obj){ + db.transaction( function(tx) { + if (type=='image'){ + var deleters=tx.executeSql('DELETE FROM imageData WHERE location="'+obj[0].location+'" AND filename="'+obj[0].filename+'"'); + filesystem.Directory=obj[0].location + filesystem.rmFile(obj[0].filename) + } + }) + },"id",imageId); + callback() +} + + +function deleteContacts(database,user,callback) { // does nothing useful at the moment + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + //print(' delete Image Data() for ' + field +"="+selection) + db.transaction( function(tx) { + result1= tx.executeSql('SELECT * FROM contacts a LEFT OUTER JOIN news b ON a.url==b.uid'); + result2= tx.executeSql('SELECT * FROM contacts a LEFT OUTER JOIN news b ON a.url==b.uid'); + callback(result)}) +} + +function getAlbumFromHtml(photohtml,remoteAuthBool,rootwindow,callback){ + var photoarray=[]; + var arr = photohtml.split("sidebar-photos-albums-li"); + for (var i=2;i')-1); + var album={'link':albumlink,'name':albumname} + photoarray.push(album); + } + callback(photoarray,remoteAuthBool) +} + + +function newRequestFriendsPictures(login,link,friend,remoteAuthBool,remoteauth,rootwindow,callback){ + // screenscraping of pictures page for given album + if (remoteAuthBool){ + remoteauth.setUrl(login.server); + remoteauth.setLogin(login.username+":"+Qt.atob(login.password)); + remoteauth.setContacturl(friend.url); + Helperjs.friendicaRemoteAuthRequest(login,link,friend.url,rootwindow,function(photohtml){ + getPictureFromHtml(photohtml,remoteAuthBool,function(photoarray){ + callback(photoarray) + }) + })} +} + +function getPictureFromHtml(photohtml,remoteAuthBool,callback){ + var photoarray=[]; + var basehtml=photohtml.substring(photohtml.indexOf('',photohtml.indexOf('-1){ //theme 1 + var arr = photohtml.split("photo-album-image-wrapper-end");} + + // other themes + if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2 + var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end")) + var arr = photoarea.split("");} + for (var i=0;iparseInt(x.id)); + db.transaction( function(tx) { + var result2 = tx.executeSql('INSERT INTO groups VALUES (?,?,?,?)', [login.username,lists[list].title,lists[list].id,JSON.stringify(memberarray)]) + groups.push({groupname:lists[list].title,gid:lists[list].id,members:memberarray}) + }); + callback(groups) + }) + } + } + }) +} + +function listFriends(login,database,callback,filter,isFriend=0){ var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var filtertext=''; - //try {filtertext=' AND screen_name like "' + filter+'%"'}catch(e){} - var filtertext=new RegExp(".*"+filter.toLowerCase()+".*") -// if (filter){filtertext=' AND (screen_name like "' + filter+'%" OR name like "' + Qt.btoa(filter)+'%")'} + if (filter!=null){var filtertext=new RegExp(".*"+filter.toLowerCase()+".*")}else{var filtertext=new RegExp(".*")} db.transaction( function(tx) { - //var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'+filtertext); - var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'); + var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>'+isFriend+' ORDER BY screen_name'); // check for friends var contactlist=[]; for (var i=0;i 0) {// use update result = tx.executeSql('UPDATE hashtags SET tag="'+'", date='+curDate+', ownership=0 where username="'+login.username+'" AND tag="'+Qt.btoa(hashtags[tag])+'"'); } else {// use insert result = tx.executeSql('INSERT INTO hashtags (username,tag,date,statuses,ownership) VALUES (?,?,?,?,?)', [login.username,Qt.btoa(hashtags[tag]),curDate,"[]",0]) @@ -122,20 +176,20 @@ function deleteGroup(login,database,rootwindow,group, callback){ Helperjs.friendicaPostRequest(login,"/api/friendica/group_delete?gid="+group.gid+"&name="+group.groupname,"","POST",rootwindow, function (obj){ var deletereturn=JSON.parse(obj); if(deletereturn.success){ - db.transaction( function(tx) { - var result = tx.executeSql('DELETE from groups where username="'+login.username+'" AND groupname="'+group.name+'"'); // delete group - callback() - }); -}})} + db.transaction( function(tx) { + var result = tx.executeSql('DELETE from groups where username="'+login.username+'" AND groupname="'+group.name+'"'); // delete group + callback() + }); + }})} function getLastNews(login,database,callback){ var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var lastnewsid=0; db.transaction( function(tx) { - var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); - try{lastnewsid=result.rows.item(0).status_id;}catch(e){lastnewsid=0}; - callback(lastnewsid) - }) + var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); + try{lastnewsid=result.rows.item(0).status_id;}catch(e){lastnewsid=0}; + callback(lastnewsid) + }) } @@ -163,15 +217,15 @@ function getCurrentContacts(login,database,callback){ db.transaction( function(tx) { var result = tx.executeSql('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=1'); // check for friends for (var i=0;i'+lastDate); - var result2 = tx.executeSql('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge > '+lastDate); - for (var j=0;j'+lastDate); + var result2 = tx.executeSql('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge > '+lastDate); + for (var j=0;j0){ for (var j=0;j0){ + } + if (news[i].hasOwnProperty('friendica_activities') && news[i].friendica_activities.dislike.length>0){ for (var k=0;j

"+news[i].friendica_html;} - else{news[i].statusnet_html=news[i].friendica_html} + //if (news[i].friendica_title!="") {news[i].statusnet_html=""+news[i].friendica_title +"

"+news[i].friendica_html;} + //else{ + news[i].statusnet_html=news[i].friendica_html//} db.transaction( function(tx) { var result = tx.executeSql('SELECT * from news where username="'+login.username+'" AND status_id = "'+news[i].id+'" AND messagetype='+news[i].messagetype); // check for news id if(result.rows.length === 1) {// use update - //print(news[i].id +' news exists, update it'+'UPDATE news SET username="'+login.username+'", messagetype=0, text="'+Qt.btoa(news[i].text)+'", created_at="'+Date.parse(cleanDate(news[i].created_at))+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].status_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'",friendica_activities="'+Qt.btoa(JSON.stringify(friendica_activities))+'",attachments="'+attachments+'",friendica_owner="'+news[i].friendica_owner.url+'" where username="'+login.username+'" AND status_id="'+news[i].status_id+'" AND messagetype=0') result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype='+news[i].messagetype+', text="'+Qt.btoa(news[i].text)+'", created_at="'+news[i].created_at+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].statusnet_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'",friendica_activities="'+Qt.btoa(JSON.stringify(friendica_activities))+'",attachments="'+attachments+'",friendica_owner="'+news[i].friendica_author.url+'" where username="'+login.username+'" AND status_id="'+news[i].status_id+'" AND messagetype=0'); } else {// use insert result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,in_reply_to_status_id,source,status_id,in_reply_to_user_id,geo,favorited,uid,statusnet_html,statusnet_conversation_id,friendica_activities,friendica_activities_self,attachments,friendica_owner) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,news[i].messagetype,Qt.btoa(news[i].text),news[i].created_at, news[i].in_reply_to_status_id, news[i].source, news[i].id,news[i].in_reply_to_user_id,news[i].geo,news[i].favorited, news[i].user.id,Qt.btoa(news[i].statusnet_html),news[i].statusnet_conversation_id, Qt.btoa(JSON.stringify(friendica_activities)),"[]",attachments,news[i].friendica_author.url])}}) - } + } } function getActivitiesUserData(allcontacts,userUrlArray){//print(JSON.stringify(userUrlArray)); var helpArray=[]; for (var i=0;i0){conversationfilter="AND statusnet_conversation_id NOT IN ("+currentconversations.toString()+") "} - for(var j = 0; j< conversations.length; j++) { - var newsrs=tx.executeSql('select * from news WHERE username="'+login.username+'" AND statusnet_conversation_id="'+conversations[j] +'" AND messagetype="'+messagetype+'" ORDER BY created_at ASC'); - //print(JSON.stringify(newsrs.rows.item(0))+JSON.stringify(newsrs.rows.item(1))) - var helpernews=newsrs.rows.item(0); - helpernews=cleanhelpernews(database,login.username,helpernews,allcontacts) - helpernews.currentconversation=[]; - for (var h = 0;h0){ - var helpernews=newsrs.rows.item(0); - var helpernews=cleanhelpernews(database,user,helpernews,allcontacts) + var newsArray=[]; + var countArray=[]; + var allcontacts=getAllContacts(database,user); + for(var j = 0; j< conversationIds.length; j++) { + var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND statusnet_conversation_id="'+conversationIds[j] +'" ORDER BY created_at ASC'); + var helpernews=newsrs.rows.item(0); + if (helpernews){ + var helpernews=cleanhelpernews(database,user,helpernews,allcontacts) helpernews.currentconversation=[]; for (var h = 0;h0){ + for (var h = 0;h +// +// 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 . + +function findend (text, startpos) { + var indexOf = text.substring(startpos || 0).search(/\s/); + return (indexOf >= 0) ? (indexOf + (startpos || 0)) : text.length; +} + +function beautify(newsitemobject,msg){ + var forumname=""; + try{ + if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_author')&& + ((newsitemobject.friendica_author.url)!=(newsitemobject.user.url))&&((newsitemobject.friendica_author.url)!=null)){ + //print(" Friendica Author "+JSON.stringify(newsitemobject)); + forumname=" via "+newsitemobject.user.name; + newsitemobject.user=newsitemobject.friendica_author; + } + if (typeof(newsitemobject.friendica_activities_self)=="string"){ + newsitemobject.friendica_activities_self=JSON.parse(newsitemobject.friendica_activities_self); + } + }catch(e){print("forum name "+e)} + + var self=({}) + if (newsitemobject.hasOwnProperty("friendica_activities_self")){ + if (newsitemobject.friendica_activities_self.indexOf(3)!=-1){self.attending=qsTr("yes")} + if (newsitemobject.friendica_activities_self.indexOf(4)!=-1){self.attending=qsTr("no")} + if (newsitemobject.friendica_activities_self.indexOf(5)!=-1){self.attending=qsTr("maybe")} + if (newsitemobject.friendica_activities_self.indexOf(1)!=-1){self.liked=1} + if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1} + } + var friendica_activities={self:self} + var imageAttachmentList=[]; + var videoAttachmentList=[]; + var videoformats=["mp4", "avi", "webm","ogg","mp3"] + try{if(newsitemobject.attachments){ + var attachArray=newsitemobject.attachments; + for (var image in attachArray){ + var attachhelper={mimetype:attachArray[image].mimetype} + var attachhelperstring="-1){var removeme=newsitemobject.statusnet_html.substring(helperstringposition,newsitemobject.statusnet_html.indexOf('">',helperstringposition)+2);} + newsitemobject.statusnet_html=newsitemobject.statusnet_html.replace(removeme,"") + imageAttachmentList.push(attachhelper) + } + } + }catch(e){print("attachment "+e)} + newsitemobject.statusnet_html=newsitemobject.statusnet_html.replace(/class=\"attachment-image\"/g,"width=\"600\" "); + try{ + for (var format in videoformats){ + if (newsitemobject.text.indexOf("."+videoformats[format])>-1){ + var videohelper={mimetype:"video/"+videoformats[format]} + var videotext=newsitemobject.text; + while (videotext.indexOf("."+videoformats[format])>-1){ + var videohelperstringposition=videotext.indexOf("."+videoformats[format]); + videohelper.url=videotext.substring(videotext.lastIndexOf("http",videohelperstringposition),videohelperstringposition+4); + videotext=videotext.substring(videohelperstringposition+4,videotext.length) + if ((videoAttachmentList.length==0) || (videoAttachmentList[videoAttachmentList.length-1].url!=videohelper.url)){videoAttachmentList.push(videohelper)} + } + } + } + if (newsitemobject.text.indexOf("/videos/watch/")>-1){ + var ptvideohelper={mimetype:"video/mp4"} + var ptvideotext=newsitemobject.text; + while (ptvideotext.indexOf("/videos/watch/")>-1){ + var ptvideohelperstringposition=ptvideotext.indexOf("/videos/watch/"); + var ptposend=findend(ptvideotext,ptvideohelperstringposition); + if(ptposend==-1){ptposend=ptvideotext.length}; + ptvideohelper.url=ptvideotext.substring(ptvideotext.lastIndexOf("http",ptvideohelperstringposition),ptposend)+"-480.mp4"; + ptvideohelper.url=ptvideohelper.url.replace("/videos/watch","/static/webseed"); + ptvideotext=ptvideotext.substring(ptposend,ptvideotext.length) + if ((videoAttachmentList.length==0) || (videoAttachmentList[videoAttachmentList.length-1].url!=ptvideohelper.url)){videoAttachmentList.push(ptvideohelper)} + } + } + }catch(e){print(e)} + newsitemobject.videoAttachmentList=videoAttachmentList; + newsitemobject.imageAttachmentList=imageAttachmentList; + if ((msg.options.hasOwnProperty("hide_nsfw"))&&(msg.options.hide_nsfw==1)&&(newsitemobject.text.indexOf("#nsfw")>-1)){ + newsitemobject.nsfw=true + } else{newsitemobject.nsfw=false} + + newsitemobject.dateDiff=(msg.currentTime-newsitemobject.created_at)/1000; + newsitemobject.friendica_activities_view=friendica_activities; + newsitemobject.forumname=forumname; + return newsitemobject; +} + +WorkerScript.onMessage = function(msg) { + if(msg.deleteId!==undefined) + {msg.model.remove(msg.deleteId); + msg.model.sync() + } + else{ + if(msg.method=="refresh" || msg.method=="contact" ||(msg.method=="conversation"&&msg.news.length>0)){msg.model.clear()}; + msg.model.sync() + for (var j in msg.news){ + let data=({}); + if (typeof(msg.news[j])=='object') { + var newsitemobject=msg.news[j]; + newsitemobject=beautify(newsitemobject,msg); + if (!(typeof(newsitemobject.currentconversation)=='undefined') && (newsitemobject.currentconversation.length>0)){ + let n=1; + while ((n-1;k--){ + if (newsitemobject.in_reply_to_status_id==msg.model.get(k).newsitemobject.id){ + newsitemobject.indent=(msg.model.get(k).newsitemobject.indent||0)+1; + if (newsitemobject.indent>6){newsitemobject.indent=6}; + firstReply=k; + } + if (newsitemobject.in_reply_to_status_id==msg.model.get(k).newsitemobject.in_reply_to_status_id){ + count+=1 + } + } + }} + data=({"newsitemobject": newsitemobject}) + } + if(data.newsitemobject.user.statusnet_blocking==true){break} + if(msg.method=="append") { + msg.model.insert(j, data) + } else if (msg.method=="conversation" && firstReply>0){ + msg.model.insert(firstReply+count+1, data) + } + else{ + msg.model.append(data) + } + } + msg.model.sync() + } +} diff --git a/source-linux/js/photoworker.js b/src/js/photoworker.js similarity index 90% rename from source-linux/js/photoworker.js rename to src/js/photoworker.js index eff840f..4dfdc21 100644 --- a/source-linux/js/photoworker.js +++ b/src/js/photoworker.js @@ -32,14 +32,14 @@ WorkerScript.onMessage = function(msg) { if (msg.firstalbum==0){msg.model.clear();} var contact={}; try{contact=msg.friend}catch(e){print(e)} - var limit=0; if (msg.albums.length-msg.firstalbum<20){limit=msg.albums.length} else{limit=msg.firstalbum+20} + var limit=0; if (msg.albums.length-msg.firstalbum<20){limit=msg.albums.length} else{limit=msg.firstalbum+20} for (var j=msg.firstalbum;j +// +// 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 . + +//.pragma library +.import QtQuick.LocalStorage 2.0 as Sql +.import "qrc:/js/helper.js" as Helperjs +.import "qrc:/js/news.js" as Newsjs + + +const newsViewType = 'Conversations' +const defaultNewsTypes = encodeURI(JSON.stringify(["Home","Replies","DirectMessages","Notifications"])) //'[\"Home\",\"Replies\",\"DirectMessages\",\"Notifications\"]' + +// CONFIG FUNCTIONS + +function initDatabase(database) { // initialize the database object + var db =Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + //print('initDatabase()'+database[0]+database[1]+database[2]+database[3]) + db.transaction( function(tx) { + //var version=tx.executeSql('PRAGMA user_version');print(JSON.stringify(version.rows.item(0))) + tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(username TEXT,id INT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, profile INT, link TEXT,location TEXT)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT, imagestore TEXT, maxnews INT, timerInterval INT, newsViewType TEXT,isActive INT, permissions TEXT,maxContactAge INT,APIVersion TEXT,layout TEXT, addons TEXT)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner TEXT)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT, timestamp INT)'); + // tx.executeSql('CREATE INDEX IF NOT EXISTS contact_id ON contacts(id)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS profiles(username TEXT, id INT, profiledata TEXT)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS events(username TEXT, id INT, start INT, end INT, allday INT, title TEXT, j INT, d TEXT, isFirst INT, uid INT, cid INT, uri TEXT, created INT, edited INT, desc TEXT, location TEXT, type TEXT, nofinish TEXT, adjust INT, ignore INT, permissions TEXT, guid INT, itemid INT, plink TEXT, authorName TEXT, authorAvatar TEXT, authorLink TEXT, html TEXT)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS globaloptions(k TEXT, v TEXT)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS friendshiprequests(username TEXT, id INT, usernamef TEXT, acct TEXT, display_name TEXT, locked TEXT, created_at INT, followers_count INT, following_count INT, statuses_count INT, note TEXT, url TEXT, avatar TEXT, avatar_static TEXT, header TEXT, header_static TEXT, emojis TEXT, moved TEXT, fields TEXT, bot TEXT, groupf TEXT, discoverable TEXT, last_status_at INT)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS hashtags(username TEXT, tag TEXT,date INT, statuses TEXT, ownership INT )'); + tx.executeSql('CREATE TABLE IF NOT EXISTS drafts(username TEXT, header TEXT, statushtml TEXT, attachments TEXT, permissions TEXT, sendtime INT)'); + + })} + +function cleanPermissions(oldperms){ + var newperms=oldperms.replace("<","");newperms=newperms.replace(">","");newperms="["+newperms+"]"; + var newpermArray=JSON.parse(newperms); + return (newpermArray) +} + +function newscount(database, callback){ + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var newscountrs = tx.executeSql('SELECT COUNT(*) from news'); + var newscount = newscountrs.rows.item(0)["COUNT(*)"]; + callback(newscount) + }) +} + +function eventsfromdb(database, username,callback){ + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + var allcontacts=[]; + allcontacts=Newsjs.getAllContacts(root.db,login.username); + db.transaction( function(tx) { + var eventrs=tx.executeSql('select * from events WHERE username="'+username+'" ORDER BY start ASC'); + var eventArray=[]; + var dayArray=[]; + for(var i = 0; i < eventrs.rows.length; i++) { + eventArray.push(eventrs.rows.item(i)); + if (eventArray[i].cid!=0){eventArray[i]["eventOwner"]=Newsjs.objFromArray(allcontacts,"cid",eventArray[i].cid);} + else{eventArray[i]["eventOwner"]=Newsjs.objFromArray(allcontacts,"isFriend",2);} + var startday=Math.floor((eventArray[i].start-new Date(eventArray[i].start).getTimezoneOffset() * 60 * 1000)/86400000); + var endday=Math.floor((eventArray[i].end-1-new Date(eventArray[i].end).getTimezoneOffset() * 60 * 1000)/86400000);if (enddaystartday){ + for (var j=startday+1;j 0) {// use update + result = tx.executeSql('UPDATE globaloptions SET v="'+dbValue+'" WHERE k="'+key+'"') + } else {// use insert + result = tx.executeSql('INSERT INTO globaloptions (k,v) VALUES (?,?)', [key,dbValue]) + } + }) + root.globaloptions[key]=value; +} + +function deleteConfig(database,userobj,callback) { // delete user data from DB + if (userobj){var where = " WHERE username='"+ userobj.username+"' and server='"+userobj.server+"'";} else { return "no user selected!";} + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + if(!db) { return; } + db.transaction( function(tx) { + var rs1 = tx.executeSql('delete from config'+where); + var rs2 = tx.executeSql("delete from news WHERE username='"+ userobj.username+"'"); + var rs3 = tx.executeSql("delete from contacts WHERE username='"+ userobj.username+"'"); + var rs4 = tx.executeSql("delete from imageData WHERE username='"+ userobj.username+"'"); + var rs5 = tx.executeSql("delete from groups WHERE username='"+ userobj.username+"'"); + var rs6 = tx.executeSql("delete from events WHERE username='"+ userobj.username+"'"); + callback(); + }) +} + +//function updateNewsviewtype(database, newsViewtype){ +// var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); +// if(!db) { return; } +// db.transaction( function(tx) { +// var rs1 = tx.executeSql('INSERT INTO globaloptions (k,v) VALUES (?,?)', ["newsViewType",newsViewtype]) +// var rs2 = tx.executeSql('UPDATE config SET newsViewType=""'); +// }) +//} + +function cleanNews(database,callback){ + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var maxnewsrs = tx.executeSql("SELECT v FROM globaloptions WHERE k='max_news'"); + var maxnews=1000; if(maxnewsrs.rows.length>0){ maxnews=maxnewsrs.rows.item(0).v}; + for (var i=0; i<6;i++){ + if (i!=0){var maxnewsa=maxnews/5}else{maxnewsa=maxnews} + var newscountrs = tx.executeSql('SELECT COUNT(*) from news WHERE messagetype='+i); + var newscount = 0; + if (newscountrs.rows.length>0){newscount=newscountrs.rows.item(0)["COUNT(*)"]}; + if (newscount>maxnewsa){ + var lastvalidtimers= tx.executeSql('SELECT DISTINCT created_at FROM news WHERE messagetype='+i+' ORDER BY created_at ASC LIMIT ' +(newscount-maxnewsa)); + var lastvalidtime=lastvalidtimers.rows.item(newscount-maxnewsa-1).created_at; + var deleters = tx.executeSql('DELETE from news WHERE messagetype='+i+' AND created_at<='+lastvalidtime)} + } + callback() + }) +} + +function cleanContacts(login,database,callback){ + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var oldestnewsrs= tx.executeSql('SELECT created_at FROM news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY created_at ASC LIMIT 1'); + if (oldestnewsrs.rows.length>0){ var oldestnewsTime=oldestnewsrs.rows.item(0).created_at- 604800000;} else{var oldestnewsTime=0} //contacts can be 7 days old + var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend=0 AND statusnet_blocking<>1 AND imageAge<'+oldestnewsTime); // check for friends + for (var i=0;i0){tagcount=tagcountrs.rows.item(0)["COUNT(*)"]}; + if (tagcount>50){ + var lastvaliddaters= tx.executeSql('SELECT DISTINCT date FROM hashtags ORDER BY date ASC LIMIT ' +(tagcount-50)); + var lastvaliddate=lastvaliddaters.rows.item(tagcount-49).date; + var deleters = tx.executeSql('DELETE from hashtags WHERE date<='+lastvaliddate)} + callback() + }) +} + +function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab + var currentTime=Date.now(); + var image_timestamp=0; + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var imagename_helper=[]; + imagename_helper=contact.profile_image_url.split('?'); + try {parseInt(image_timestamp=imagename_helper[1].substring(imagename_helper[1].indexOf("ts=")+3,imagename_helper[1].length))} catch(e){}; + var result; + result = tx.executeSql('SELECT * from contacts where username="'+login.username+'" AND url = "'+contact.url+'"'); // check for news url + if(result.rows.length === 1) {// use update + result = tx.executeSql('UPDATE contacts SET id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",imageAge='+currentTime+', profile_image_url="'+contact.profile_image_url+'", description="'+Qt.btoa(contact.description)+'", protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ contact.created_at+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+', timestamp='+ currentTime+' where username="'+login.username+'" AND url="'+contact.url+'"'); + } else {// use insert + result = tx.executeSql('INSERT INTO contacts VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,contact.id,Qt.btoa(contact.name),contact.screen_name,contact.location,currentTime,contact.profile_image_url, Qt.btoa(contact.description),"",contact.url,contact.protected,contact.followers_count, contact.friends_count,contact.created_at,contact.favorites_count,contact.utc_offset,contact.time_zone,contact.statuses_count,contact.following,contact.verfied,contact.statusnet_blocking,contact.notifications,contact.statusnet_profile_url,contact.cid,contact.network,isFriend,image_timestamp]);} + }); +} + +function processNews(api,data){ + try{var newslist=JSON.parse(data)} catch(e){print("processnews "+e+ " api "+ api + " data "+data)}; + if (api=="/api/users/show"){ + var usermessages=[]; + usermessages.push(newslist.status); + newslist=usermessages; + } + if (data=="" || api=="/api/v1/statuses"){showNews("")}//newsBusy.running=false} + else if (typeof(newslist)=='undefined'){ + Helperjs.showMessage(qsTr("Undefined Array Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root) + } + else if (newslist.hasOwnProperty('status')){ + Helperjs.showMessage(qsTr("JSON status Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root) + } + + else { + var allcontacts=[]; + allcontacts=Newsjs.getAllContacts(db,login.username); + + if (!(Array.isArray(newslist)) && (typeof(newslist)==='object')){//answers return object, not array + newslist=[];newslist.push(JSON.parse(data)); + } + + if (api=="/api/direct_messages/all" || api=="/api/direct_messages/conversation" ||api=="/api/direct_messages/new"){ + for (var n in newslist){ + try{newslist[n].created_at=Date.parse(Newsjs.cleanDate(newslist[n].created_at));}catch(e){ + newslist[n].created_at=Date.parse(newslist[n].created_at) + } + newslist[n].messagetype=1; + newslist[n].source=" Friendica"; + newslist[n].status_id=newslist[n].id; + 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; + newslist[n].in_reply_to_user_id=newslist[n].recipient_id + if(newslist[n].in_reply_to_user_id){newslist[n].reply_user=Newsjs.objFromArray(allcontacts,"id",newslist[n].in_reply_to_user_id)} + }} + else if (api=="/api/friendica/notification"){ + for (var n in newslist){ + newslist[n].created_at=Date.parse(newslist[n].date); + newslist[n].messagetype=2; + newslist[n].user=Newsjs.objFromArray(allcontacts,"url",newslist[n].url) + if (newslist[n].user==false){ + 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; + } + } + + else {//if(api!="/api/statuses/user_timeline"){ + var chatlist=[]; + var chatlistclean=[]; + var conversationIds=[]; + var commentCount=[]; + + for (var n in newslist){ + if (newslist[n]!=null){ + newslist[n].created_at=Date.parse(Newsjs.cleanDate(newslist[n].created_at)); + newslist[n].messagetype=5; + newslist[n].status_id=newslist[n].id; + 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); + try{ + let localContact=Newsjs.objFromArray(allcontacts,"id",newslist[n].user.id); + newslist[n].user.statusnet_blocking=localContact.statusnet_blocking + }catch(e){} + //if (newslist[n].friendica_title!="") {newslist[n].statusnet_html=""+newslist[n].friendica_title +"

"+newslist[n].friendica_html;} + //else{ //friendica_title also included in html + newslist[n].statusnet_html=newslist[n].friendica_html + //} + + if(newslist[n].in_reply_to_user_id){newslist[n].reply_user=Newsjs.objFromArray(allcontacts,"id",newslist[n].in_reply_to_user_id)} + if(newslist[n].hasOwnProperty('friendica_activities')){ + for (var m in newslist[n].friendica_activities.like){ + newslist[n].friendica_activities.like[m]=cleanUser(newslist[n].friendica_activities.like[m]); + } + for (var o in newslist[n].friendica_activities.dislike){ + newslist[n].friendica_activities.dislike[o]=cleanUser(newslist[n].friendica_activities.dislike[o]); + } + for (var p in newslist[n].friendica_activities.attendyes){ + newslist[n].friendica_activities.attendyes[p]=cleanUser(newslist[n].friendica_activities.attendyes[p]); + } + for (var q in newslist[n].friendica_activities.attendno){ + newslist[n].friendica_activities.attendno[q]=cleanUser(newslist[n].friendica_activities.attendno[q]); + } + for (var r in newslist[n].friendica_activities.attendmaybe){ + newslist[n].friendica_activities.attendmaybe[r]=cleanUser(newslist[n].friendica_activities.attendmaybe[r]); + } + } + if(!(newslist[n].hasOwnProperty('friendica_author'))){ + newslist[n].friendica_author=newslist[n].user + } + var conversationindex=conversationIds.indexOf(newslist[n].statusnet_conversation_id); + + //fill chatlist + if (conversationindex==-1){ + let conversation=[];conversation.push(newslist[n]); + let firstmessage={currentconversation:conversation}; + chatlist.push(firstmessage); + conversationIds.push(newslist[n].statusnet_conversation_id); + commentCount.push(1); + } else{ + commentCount[conversationindex]=commentCount[conversationindex]+1; + chatlist[conversationindex].currentconversation.push(newslist[n]); + } + } + } + + if ((root.globaloptions.hasOwnProperty("newsViewType") && (root.globaloptions.newsViewType=="Conversations"))&&!(api=="/api/conversation/show"|| api=="/api/direct_messages/conversation")){ + //enrich chatlist with old entries + for (var count in chatlist){ + chatlist[count].currentconversation.reverse(); + if (chatlist[count].currentconversation[0].id_str!==chatlist[count].currentconversation[0].statusnet_conversation_id){ + try{ + Newsjs.oldchatfromdb(db,login.username,chatlist[count].currentconversation[0].statusnet_conversation_id,chatlist[count].currentconversation[0].id,allcontacts,function(oldpost,oldcount){ + let completeChat=oldpost.currentconversation.concat(chatlist[count].currentconversation); + let newChat=completeChat[0]; + newChat.currentconversation=[]; + for (let c in completeChat){ + if (completeChat[c].status_id!=newChat.status_id){ + newChat["currentconversation"].push(completeChat[c]) + } + } + newChat.newscount=oldcount+commentCount[count]; + chatlistclean.push(newChat); + }) + }catch(e){print(e)} + } + else{ + let newChat=chatlist[count].currentconversation[0]; + newChat["currentconversation"]=[]; + for (let c in chatlist[count].currentconversation){ + if (chatlist[count].currentconversation[c].status_id!=newChat.status_id){ + newChat["currentconversation"].push(chatlist[count].currentconversation[c]) + } + } + newChat.newscount=commentCount[count]; + chatlistclean.push(newChat); + } + } + } + } + + if (api=="/api/conversation/show"|| api=="/api/direct_messages/conversation"){ + newslist.reverse(); + root.conversation=newslist + } + else if (api=="/api/statuses/user_timeline" || api=="/api/users/show"){ + root.contactposts=newslist + } + else if ((api!="/api/direct_messages/all")&&(api!="/api/friendica/notification")&&(api!="/api/direct_messages/new")&&(newstab.newstabstatus==="Conversations")){ + showNews(chatlistclean);root.news=newslist + } + else { + showNews(newslist);root.news=newslist + }; + + //var newstabarray=["Conversations","Favorites","Timeline","DirectMessage","Replies"]; + //if (newstabarray.indexOf(newstab.newstabstatus)>-1){ + contacttimer.start() + //} + } +} + +function cleanUser(user){ + user.created_at=Date.parse(Newsjs.cleanDate(user.created_at)); + var imagehelper1=user.profile_image_url.split("?"); + var imagehelper2=imagehelper1[0].substring(imagehelper1[0].lastIndexOf("/")+1,imagehelper1[0].length); + var imagehelper3=login.imagestore+"contacts/"+user.screen_name+"-"+imagehelper2 + if(filesystem.fileexist(imagehelper3)){user.profile_image=imagehelper3}else {user.profile_image=""} + return user +} + +function updateView(viewtype,lastnews=0){ + //messageSend.state=""; + //newsBusy.running=true; + //downloadNotice.text="xhr start "+Date.now() + + if (viewtype==="Conversations"){Newsjs.allchatsfromdb(db,login.username,function(temp){ + newsStack.allchats=temp + })} + if ((osSettings.osType=="Android") && root.globaloptions.hasOwnProperty("syncinterval") && root.globaloptions.syncinterval !=null && root.globaloptions.syncinterval !=0){ + //alarm.setAlarm(root.globaloptions.syncinterval); + setBackgroundsync() + } + + xhr.setAccount(login); + switch(viewtype){ + case "Conversations": + xhr.setApi("/api/statuses/friends_timeline"); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50); + break; + case "Timeline": + xhr.setApi("/api/statuses/friends_timeline"); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50) + break; + case "Search": + xhr.setApi("/api/search"); + break; + case "Notifications": + xhr.setApi("/api/friendica/notification"); + break; + case "Direct Messages": + xhr.setApi("/api/direct_messages/all"); + break; + case "Public Timeline": + xhr.setApi("/api/statuses/public_timeline"); + break; + case "Favorites": + xhr.setApi("/api/favorites"); + break; + case "Replies": + xhr.setApi("/api/statuses/replies"); + break; + default: + xhr.setApi("/api/statuses/friends_timeline"); + xhr.setParam("since_id",lastnews); + xhr.setParam("count",50) + newstab.newstabstatus="Conversations"; + } + xhr.get(); +} + +function showGroups(){ + Helperjs.readData(db,"groups",login.username,function(groups){ + var groupitems=""; + for (var i=0;i0)&&((parseFloat(lastsync[0]["v"])+120)<(Date.now()/1000))){ + alarm.setAlarm(root.globaloptions.syncinterval); + } + },"k","lastsync") +} + +function getGroupnews(list){ + newstab.newstabstatus="Group news"; + newsBusy.running=true; + xhr.setAccount(login); + xhr.setApi("/api/lists/statuses"); + xhr.setParam("list_id",list) + xhr.get(); +} diff --git a/src/js/smiley.js b/src/js/smiley.js new file mode 100644 index 0000000..7a7f7bc --- /dev/null +++ b/src/js/smiley.js @@ -0,0 +1,698 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 . + + +var html=[//Smileys + '\u263A', + '\ud83d\ude00', + '\ud83d\ude02', + '\ud83d\ude06', + '\ud83d\ude07', + '\ud83d\ude08', + '\ud83d\ude09', + '\ud83d\ude0B', + '\ud83d\ude0D', + '\ud83d\ude0E', + '\ud83d\ude0F', + '\ud83d\ude10', + '\ud83d\ude15', + '\ud83d\ude18', + '\ud83d\ude1B', + '\ud83d\ude1C', + '\ud83d\ude1D', + '\ud83d\ude1E', + '\ud83d\ude1F', + '\ud83d\ude20', + '\ud83d\ude21', + '\ud83d\ude22', + '\ud83d\ude23', + '\ud83d\ude24', + '\ud83d\ude26', + '\ud83d\ude27', + '\ud83d\ude2C', + '\ud83d\ude2D', + '\ud83d\ude2E', + '\ud83d\ude2F', + '\ud83d\ude31', + '\ud83d\ude32', + '\ud83d\ude33', + '\ud83d\ude31', + '\ud83d\ude32', + '\ud83d\ude33', + '\ud83d\ude34', + '\ud83d\ude37', + '\ud83d\ude41', + '\ud83d\ude42', + '\ud83d\ude43', + '\ud83d\ude44', + '\ud83d\ude45', + '\ud83d\ude46', + '\ud83d\ude47', + '\ud83d\ude4B', + '\ud83d\ude4C', + '\ud83d\ude4D', + '\ud83d\ude4E', + '\ud83d\ude4F', + '\ud83e\udd2F', + '\uD83E\uDD17', + '\uD83E\uDD14', + '\uD83E\uDD73', + '\uD83E\uDD21', + '\uD83D\uDC4D', + '\uD83D\uDC94', + '\u2764\uFE0F', + '\uD83D\uDCA9', + '\uD83D\uDC2D', + '\uD83D\uDC2E', + '\uD83D\uDC31', + '\uD83D\uDCAF', + '\uD83C\uDF82', + '\uD83C\uDF89', + '\uD83C\uDF81', + '\uD83C\uDF08', + '\uD83D\uDC80', + '\u2639', + '\u263B', + //Weather + '\u2600', + '\u2601', + '\u263C', + '\u2614', + '\u2602', + '\u2603', + '\u2604', + '\u26C4', + '\u26C5', + '\u26C8', + //Leisure + '\u2615', + '\u26BD', + '\u26BE', + '\u26F1', + '\u26F2', + '\u26F3', + '\u26F4', + '\u26F5', + '\u26F7', + '\u26F8', + '\u26F9', + '\u26FA', + '\u26FD', + //Hand + '\u261C', + '\u261D', + '\u261E', + '\u261F', + '\u2620', + '\u2622', + '\u2623', + //Religion + '\u2626', + '\u262A', + '\u262C', + '\u262E', + '\u262F', + '\u26EA', + '\u26E9' + ] + +var core=[ + {name:'<3',url: + 'qrc:///assets/smileys/core/smiley-heart.gif'}, + + {name:'</3',url: + 'qrc:///assets/smileys/core/smiley-brokenheart.gif'}, + + {name:':-)',url: + 'qrc:///assets/smileys/core/smiley-smile.gif'}, + + {name:';-)',url: + 'qrc:///assets/smileys/core/smiley-wink.gif'}, + + {name:':-(',url: + 'qrc:///assets/smileys/core/smiley-frown.gif'}, + + {name:':-P',url: + 'qrc:///assets/smileys/core/smiley-tongue-out.gif'}, + + {name:':-X',url: + 'qrc:///assets/smileys/core/smiley-kiss.gif'}, + + {name:':-D',url: + 'qrc:///assets/smileys/core/smiley-laughing.gif'}, + + {name:':-O',url: + 'qrc:///assets/smileys/core/smiley-surprised.gif'}, + + {name:'\\o/',url: + 'qrc:///assets/smileys/core/smiley-thumbsup.gif'}, + + {name:'o.O',url: + 'qrc:///assets/smileys/core/smiley-Oo.gif'}, + + {name:":'(",url: + 'qrc:///assets/smileys/core/smiley-cry.gif'}, + + {name:":-!",url: + 'qrc:///assets/smileys/core/smiley-foot-in-mouth.gif'}, + + {name:":-/",url: + 'qrc:///assets/smileys/core/smiley-undecided.gif'}, + + {name:":-[",url: + 'qrc:///assets/smileys/core/smiley-embarassed.gif'}, + + {name:"8-)",url: + 'qrc:///assets/smileys/core/smiley-cool.gif'}, + + {name:':beer',url: + 'qrc:///assets/smileys/core/beer_mug.gif'}, + + {name:':coffee',url: + 'qrc:///assets/smileys/core/coffee.gif'}, + + {name:':facepalm',url: + 'qrc:///assets/smileys/core/smiley-facepalm.gif'}, + + {name:':like',url: + 'qrc:///assets/smileys/core/like.gif'}, + + {name:':dislike',url: + 'qrc:///assets/smileys/core/dislike.gif'}, + + {name:'~friendica',url: + 'qrc:///assets/smileys/core/friendica-16.png'}, + + {name:'red#',url: + 'qrc:///assets/smileys/core/rm-16.png'} + ] + + +var addon=[ + {name:':bunnyflowers',url: + 'qrc:///assets/smileys/animals/bunnyflowers.gif'}, + + {name:':chick',url: + 'qrc:///assets/smileys/animals/chick.gif'}, + + {name:':bumblebee',url: + 'qrc:///assets/smileys/animals/bee.gif'}, + + {name:':ladybird',url: + 'qrc:///assets/smileys/animals/ladybird.gif'}, + + {name:':bigspider',url: + 'qrc:///assets/smileys/animals/bigspider.gif' }, + + {name:':cat',url: + 'qrc:///assets/smileys/animals/cat.gif'}, + + {name:':bunny',url: + 'qrc:///assets/smileys/animals/bunny.gif' }, + + {name:':cow',url: + 'qrc:///assets/smileys/animals/cow.gif' }, + + {name:':crab',url: + 'qrc:///assets/smileys/animals/crab.gif' }, + + {name:':dolphin',url: + 'qrc:///assets/smileys/animals/dolphin.gif' }, + + {name:':dragonfly',url: + 'qrc:///assets/smileys/animals/dragonfly.gif' }, + + {name:':frog',url: + 'qrc:///assets/smileys/animals/frog.gif'}, + + {name:':hamster',url: + 'qrc:///assets/smileys/animals/hamster.gif' }, + + {name:':monkey',url: + 'qrc:///assets/smileys/animals/monkey.gif' }, + + {name:':horse',url: + 'qrc:///assets/smileys/animals/horse.gif' }, + + {name:':parrot',url: + 'qrc:///assets/smileys/animals/parrot.gif' }, + + {name:':tux',url: + 'qrc:///assets/smileys/animals/tux.gif' }, + + {name:':snail',url: + 'qrc:///assets/smileys/animals/snail.gif' }, + + {name:':sheep',url: + 'qrc:///assets/smileys/animals/sheep.gif' }, + + {name:':dog',url: + 'qrc:///assets/smileys/animals/dog.gif'}, + + {name:':elephant',url: + 'qrc:///assets/smileys/animals/elephant.gif' }, + + {name:':fish',url: + 'qrc:///assets/smileys/animals/fish.gif' }, + + {name:':giraffe',url: + 'qrc:///assets/smileys/animals/giraffe.gif' }, + + {name:':pig',url: + 'qrc:///assets/smileys/animals/pig.gif'}, + + //Baby + + {name:':baby',url: + 'qrc:///assets/smileys/babies/baby.gif' }, + + {name:':babycot',url: + 'qrc:///assets/smileys/babies/babycot.gif' }, + + + {name:':pregnant',url: + 'qrc:///assets/smileys/babies/pregnant.gif' }, + + {name:':stork',url: + 'qrc:///assets/smileys/babies/stork.gif' }, + + + //Confused + {name:':confused',url: + 'qrc:///assets/smileys/confused/confused.gif' }, + + {name:':shrug',url: + 'qrc:///assets/smileys/confused/shrug.gif' }, + + {name:':stupid',url: + 'qrc:///assets/smileys/confused/stupid.gif' }, + + {name:':dazed',url: + 'qrc:///assets/smileys/confused/dazed.gif' }, + //Cool 'qrc:///assets/smileys + + {name:':affro',url: + 'qrc:///assets/smileys/cool/affro.gif'}, + + //Devil/Angel + + {name:':angel',url: + 'qrc:///assets/smileys/devilangel/angel.gif'}, + + {name:':cherub',url: + 'qrc:///assets/smileys/devilangel/cherub.gif'}, + + {name:':devilangel',url: + 'qrc:///assets/smileys/devilangel/blondedevil.gif' }, + {name:':catdevil',url: + 'qrc:///assets/smileys/devilangel/catdevil.gif'}, + + {name:':devillish',url: + 'qrc:///assets/smileys/devilangel/devil.gif'}, + + {name:':daseesaw',url: + 'qrc:///assets/smileys/devilangel/daseesaw.gif'}, + + {name:':turnevil',url: + 'qrc:///assets/smileys/devilangel/turnevil.gif' }, + + {name:':saint',url: + 'qrc:///assets/smileys/devilangel/saint.gif'}, + + {name:':graveside',url: + 'qrc:///assets/smileys/devilangel/graveside.gif'}, + + //Unpleasent + + {name:':toilet',url: + 'qrc:///assets/smileys/disgust/toilet.gif'}, + + {name:':fartinbed',url: + 'qrc:///assets/smileys/disgust/fartinbed.gif' }, + + {name:':fartblush',url: + 'qrc:///assets/smileys/disgust/fartblush.gif' }, + + //Drinks + + {name:':tea',url: + 'qrc:///assets/smileys/drink/tea.gif' }, + + {name:':drool',url: + 'qrc:///assets/smileys/drool/drool.gif'}, + + //Sad + + {name:':crying',url: + 'qrc:///assets/smileys/sad/crying.png'}, + + {name:':prisoner',url: + 'qrc:///assets/smileys/sad/prisoner.gif' }, + + {name:':sigh',url: + 'qrc:///assets/smileys/sad/sigh.gif'}, + + //Smoking - only one smiley in here, maybe it needs moving elsewhere? + + {name:':smoking',url: + 'qrc:///assets/smileys/smoking/smoking.gif'}, + + //Sport + + {name:':basketball',url: + 'qrc:///assets/smileys/sport/basketball.gif'}, + + {name:':bowling',url: + 'qrc:///assets/smileys/sport/bowling.gif'}, + + {name:':cycling',url: + 'qrc:///assets/smileys/sport/cycling.gif'}, + + {name:':darts',url: + 'qrc:///assets/smileys/sport/darts.gif'}, + + {name:':fencing',url: + 'qrc:///assets/smileys/sport/fencing.gif' }, + + {name:':juggling',url: + 'qrc:///assets/smileys/sport/juggling.gif'}, + + {name:':skipping',url: + 'qrc:///assets/smileys/sport/skipping.gif'}, + + {name:':archery',url: + 'qrc:///assets/smileys/sport/archery.gif'}, + + {name:':surfing',url: + 'qrc:///assets/smileys/sport/surfing.gif' }, + + {name:':snooker',url: + 'qrc:///assets/smileys/sport/snooker.gif' }, + + {name:':horseriding',url: + 'qrc:///assets/smileys/sport/horseriding.gif'}, + + //Love + + {name:':iloveyou',url: + 'qrc:///assets/smileys/love/iloveyou.gif'}, + + {name:':inlove',url: + 'qrc:///assets/smileys/love/inlove.gif'}, + + {name:':~love',url: + 'qrc:///assets/smileys/love/love.gif' }, + + {name:':lovebear',url: + 'qrc:///assets/smileys/love/lovebear.gif'}, + + {name:':lovebed',url: + 'qrc:///assets/smileys/love/lovebed.gif' }, + + {name:':loveheart',url: + 'qrc:///assets/smileys/love/loveheart.gif' }, + + //Tired/Sleep + + {name:':countsheep',url: + 'qrc:///assets/smileys/tired/countsheep.gif' }, + + {name:':hammock',url: + 'qrc:///assets/smileys/tired/hammock.gif'}, + + {name:':pillow',url: + 'qrc:///assets/smileys/tired/pillow.gif' }, + + {name:':yawn',url: + 'qrc:///assets/smileys/tired/yawn.gif'}, + + //Fight/Flame/Violent + + {name:':2guns',url: + 'qrc:///assets/smileys/fight/2guns.gif' }, + + {name:':alienfight',url: + 'qrc:///assets/smileys/fight/alienfight.gif' }, + + {name:':army',url: + 'qrc:///assets/smileys/fight/army.gif'}, + + {name:':arrowhead',url: + 'qrc:///assets/smileys/fight/arrowhead.gif'}, + + {name:':bfg',url: + 'qrc:///assets/smileys/fight/bfg.gif' }, + + {name:':bowman',url: + 'qrc:///assets/smileys/fight/bowman.gif' }, + + {name:':chainsaw',url: + 'qrc:///assets/smileys/fight/chainsaw.gif'}, + + {name:':crossbow',url: + 'qrc:///assets/smileys/fight/crossbow.gif'}, + + {name:':crusader',url: + 'qrc:///assets/smileys/fight/crusader.gif' }, + + {name:':dead',url: + 'qrc:///assets/smileys/fight/dead.gif' }, + + {name:':hammersplat',url: + 'qrc:///assets/smileys/fight/hammersplat.gif' }, + + {name:':lasergun',url: + 'qrc:///assets/smileys/fight/lasergun.gif' }, + + {name:':machinegun',url: + 'qrc:///assets/smileys/fight/machinegun.gif' }, + + {name:':acid',url: + 'qrc:///assets/smileys/fight/acid.gif' }, + + //Fantasy - monsters and dragons fantasy. The other type of fantasy belongs in adult + + {name:':alienmonster',url: + 'qrc:///assets/smileys/fantasy/alienmonster.gif' }, + + {name:':barbarian',url: + 'qrc:///assets/smileys/fantasy/barbarian.gif' }, + + {name:':dinosaur',url: + 'qrc:///assets/smileys/fantasy/dinosaur.gif'}, + + {name:':dragon',url: + 'qrc:///assets/smileys/fantasy/dragon.gif'}, + + {name:':draco',url: + 'qrc:///assets/smileys/fantasy/dragonwhelp.gif'}, + + {name:':ghost',url: + 'qrc:///assets/smileys/fantasy/ghost.gif'}, + + {name:':mummy',url: + 'qrc:///assets/smileys/fantasy/mummy.gif'}, + + //Food + + {name:':apple',url: + 'qrc:///assets/smileys/food/apple.gif' }, + + {name:':broccoli',url: + 'qrc:///assets/smileys/food/broccoli.gif' }, + + {name:':cake',url: + 'qrc:///assets/smileys/food/cake.gif'}, + + {name:':carrot',url: + 'qrc:///assets/smileys/food/carrot.gif' }, + + {name:':popcorn',url: + 'qrc:///assets/smileys/food/popcorn.gif'}, + + {name:':tomato',url: + 'qrc:///assets/smileys/food/tomato.gif'}, + + {name:':banana',url: + 'qrc:///assets/smileys/food/banana.gif'}, + + {name:':cooking',url: + 'qrc:///assets/smileys/food/cooking.gif'}, + + {name:':fryegg',url: + 'qrc:///assets/smileys/food/fryegg.gif'}, + + {name:':birthdaycake',url: + 'qrc:///assets/smileys/food/birthdaycake.gif'}, + + //Happy + + {name:':cloud9',url: + 'qrc:///assets/smileys/happy/cloud9.gif'}, + + {name:':tearsofjoy',url: + 'qrc:///assets/smileys/happy/tearsofjoy.gif' }, + + //Repsect + + {name:':bow',url: + 'qrc:///assets/smileys/respect/bow.gif'}, + + {name:':bravo',url: + 'qrc:///assets/smileys/respect/bravo.gif'}, + + {name:':hailking',url: + 'qrc:///assets/smileys/respect/hailking.gif'}, + + {name:':number1',url: + 'qrc:///assets/smileys/respect/number1.gif' }, + + //Laugh + + {name:':hahaha',url: + 'qrc:///assets/smileys/laugh/hahaha.gif'}, + + {name:':loltv',url: + 'qrc:///assets/smileys/laugh/loltv.gif' }, + + {name:':rofl',url: + 'qrc:///assets/smileys/laugh/rofl.gif'}, + + //Music + + {name:':drums',url: + 'qrc:///assets/smileys/music/drums.gif'}, + + + {name:':guitar',url: + 'qrc:///assets/smileys/music/guitar.gif'}, + + {name:':trumpet',url: + 'qrc:///assets/smileys/music/trumpet.gif' }, + + //smileys that used to be in core + + {name:':headbang',url: + 'qrc:///assets/smileys/oldcore/headbang.gif'}, + + {name:':beard',url: + 'qrc:///assets/smileys/oldcore/beard.png'}, + + {name:':whitebeard',url: + 'qrc:///assets/smileys/oldcore/whitebeard.png'}, + + {name:':shaka',url: + 'qrc:///assets/smileys/oldcore/shaka.gif'}, + + {name:':\\.../',url: + 'qrc:///assets/smileys/oldcore/shaka.gif'}, + + {name:':\\ooo/',url: + 'qrc:///assets/smileys/oldcore/shaka.gif' }, + + {name:':headdesk',url: + 'qrc:///assets/smileys/oldcore/headbang.gif' }, + + //These two are still in core, so oldcore isn't strictly right, but we don't want too many directories + + {name:':-d',url: + 'qrc:///assets/smileys/oldcore/laughing.gif'}, + + {name:':-o',url: + 'qrc:///assets/smileys/oldcore/surprised.gif' }, + + // Regex killers - stick these at the bottom so they appear at the end of the English and + // at the start of $OtherLanguage. + + {name:':cool',url: + 'qrc:///assets/smileys/cool/cool.gif' }, + + {name:':vomit',url: + 'qrc:///assets/smileys/disgust/vomit.gif' }, + + {name:':golf',url: + 'qrc:///assets/smileys/sport/golf.gif' }, + + {name:':football',url: + 'qrc:///assets/smileys/sport/football.gif'}, + + {name:':tennis',url: + 'qrc:///assets/smileys/sport/tennis.gif' }, + + {name:':alpha',url: + 'qrc:///assets/smileys/fight/alpha.png' }, + + {name:':marine',url: + 'qrc:///assets/smileys/fight/marine.gif' }, + + {name:':sabre',url: + 'qrc:///assets/smileys/fight/sabre.gif' }, + + {name:':tank',url: + 'qrc:///assets/smileys/fight/tank.gif' }, + + {name:':viking',url: + 'qrc:///assets/smileys/fight/viking.gif' }, + + {name:':gangs',url: + 'qrc:///assets/smileys/fight/gangs.gif' }, + + {name:':dj',url: + 'qrc:///assets/smileys/music/dj.gif'}, + + {name:':elvis',url: + 'qrc:///assets/smileys/music/elvis.gif'}, + + {name:':violin',url: + 'qrc:///assets/smileys/music/violin.gif'}, + ] + + +var adult=[ + { + name:'(o)(o) ',url: + 'qrc:///assets/smileys/adult/tits.gif'}, + + {name:'(.)(.) ',url: + 'qrc:///assets/smileys/adult/tits.gif'}, + + {name:':bong',url: + 'qrc:///assets/smileys/adult/bong.gif'}, + + {name:':sperm',url: + 'qrc:///assets/smileys/adult/sperm.gif'}, + + {name:':drunk',url: + 'qrc:///assets/smileys/adult/drunk.gif'}, + + {name:':finger',url: + 'qrc:///assets/smileys/adult/finger.gif'} + ] diff --git a/source-linux/qml/calendarqml/CalendarDay.qml b/src/qml/calendarqml/CalendarDay.qml similarity index 76% rename from source-linux/qml/calendarqml/CalendarDay.qml rename to src/qml/calendarqml/CalendarDay.qml index 6033099..bbb8de7 100644 --- a/source-linux/qml/calendarqml/CalendarDay.qml +++ b/src/qml/calendarqml/CalendarDay.qml @@ -29,14 +29,13 @@ // 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 QtQuick 6.3 Item { id: calendarDay - width: root.fontFactor*osSettings.bigFontSize*2//5*mm - height: root.fontFactor*osSettings.bigFontSize*2//5*mm - property int dateInt: Math.floor(Date.parse(model.date)/86400000) //Math.floor((Date.parse(model.date)-(new Date().getTimezoneOffset() * 60 * 1000))/86400000) + width: root.fontFactor*osSettings.bigFontSize*2 + height: root.fontFactor*osSettings.bigFontSize*2 + property int dateInt: Math.floor(model.date.valueOf()/86400000) Rectangle { id: placeHolder color: model.today?'lightblue':'transparent'; @@ -50,7 +49,7 @@ Item { id:daytext anchors.right: parent.right anchors.margins: 0.5*mm - color:(model.month==monthgrid.month)?"black":"grey" + color:(model.month==monthgrid.month)?osSettings.primaryTextColor:osSettings.secondaryTextColor wrapMode: Text.WrapAnywhere text: model.day font.bold: model.today @@ -67,10 +66,8 @@ Item { } MouseArea { anchors.fill: calendarDay - onClicked: {rootstackView.push("qrc:/qml/calendarqml/EventList.qml",{"dayint": dateInt,"events":events}); -// var component = Qt.createComponent("qrc:/qml/calendarqml/EventList.qml"); -// if (component.status== Component.Ready){ -// var eventlist = component.createObject(calendartab,{"dayint": dateInt})} + onClicked: { + rootstackView.push("qrc:/qml/calendarqml/EventList.qml",{"dayint": dateInt,"events":events}); } } } diff --git a/source-linux/qml/calendarqml/CalendarTab.qml b/src/qml/calendarqml/CalendarTab.qml similarity index 52% rename from source-linux/qml/calendarqml/CalendarTab.qml rename to src/qml/calendarqml/CalendarTab.qml index 57dffc8..9fa14c7 100644 --- a/source-linux/qml/calendarqml/CalendarTab.qml +++ b/src/qml/calendarqml/CalendarTab.qml @@ -29,10 +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 2.12 -import QtQml 2.2 -import Qt.labs.calendar 1.0 +import QtQuick 6.3 +import QtQuick.Controls 6.3 + +//import Qt.labs.calendar 1.0 //import QtQuick.Layouts 1.3 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs @@ -41,35 +41,33 @@ import "qrc:/qml/genericqml" Rectangle { id:calendarrectangle -// y:1 - width:parent.width//-mm - height:parent.height//-5*mm -// anchors.fill: parent - color: '#fff' + // y:1 + width:parent.width + height:parent.height + color: osSettings.backgroundColor property date currentTime: new Date() property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000 property var events:[] property var eventdays:[] - function showEvents(friend){ if(friend=="backButton"){Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ - events=eventArray; + events=cleanEvents(eventArray); eventdays=dayArray}) } else if (friend!=""){ - calendartab.calendartabstatus=friend.url.substring(friend.url.lastIndexOf("/")+1,friend.url.length) + calendartab.calendartabstatus=friend.url.substring(friend.url.lastIndexOf("/")+1,friend.url.length) Service.newRequestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){ - events=eventArray; - eventdays=dayArray}) + events=cleanEvents(eventArray); + eventdays=dayArray}) } else {calendartab.calendartabstatus="Events"; Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ - events=eventArray; + events=cleanEvents(eventArray); eventdays=dayArray; calBusy.running=false - - var currentevents=events.filter(event=>(currentTime<=event.end)); + var currentevents=events; + currentevents=events.filter(event=>(currentTime<=event.end)); for (var i=0; i0){events[item].end=events[item].end-offsetTime}; + } + return events + } - BlueButton{ - x:mm - y:mm + function createEvent(event){ + rootstackView.push("qrc:/qml/calendarqml/EventCreate.qml",{"eventInformation": event}) + } + + BusyIndicator{ + id: calBusy + anchors.horizontalCenter: calendarView.horizontalCenter + anchors.top:calendarView.top + anchors.topMargin: 2*mm + width:10*mm + height: 10*mm + running: false + } + + ToolButton{ z:2 + id:menuButton + anchors.right: parent.right + anchors.top: parent.top + //anchors.topMargin: friendsbar.height visible: !wideScreen - fontColor: "grey" - border.color: "transparent" - text: "\uf0c9" - font.pointSize: osSettings.bigFontSize + icon.name: "application-menu" + icon.source: "qrc:/assets/icons/bars.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize onClicked:{ leftDrawerAndroid.visible?leftDrawerAndroid.close():leftDrawerAndroid.open()} } @@ -105,7 +117,7 @@ Rectangle { id:leftDrawer property var newstabstatus: newstab.newstabstatus visible: wideScreen&&rootstackView.depth<2 - width: visible?osSettings.systemFontSize*15:0 + width: visible?root.fontFactor*osSettings.systemFontSize*15:0 height: root.height-bar.height } @@ -119,34 +131,82 @@ Rectangle { anchors.topMargin: 0.5*mm anchors.right:calendartabstatusButton.left anchors.rightMargin:mm - width: 2*root.fontFactor*osSettings.bigFontSize; - text:"\uf021" + display: AbstractButton.IconOnly + text: qsTr("refresh")//"\uf021" + icon.name: "view-refresh-symbolic" + icon.source: "qrc:/assets/icons/refresh.svg" + // background: Rectangle{color: osSettings.dialogColor; + // radius: 0.5*mm} onClicked: { calBusy.running=true; updatenews.setDatabase(); updatenews.login(); + updatenews.setSyncAll(false); updatenews.events(); -// Service.getEvents(db,login, calendartab,function(){ -// showEvents("") -// }) }} Connections{ - target: updatenews + target: updatenews - function onSuccess(api){ - calBusy.running=false; - showEvents("") - } - } + function onSuccess(api){ + calBusy.running=false; + showEvents("") + } + } + Dialog { + id: deleteDialog + anchors.centerIn: parent + property int eventid:0 + title: qsTr("Delete Event?") + standardButtons: Dialog.Ok | Dialog.Cancel + modal: true + onAccepted: { + xhr.setAccount(login); + xhr.setApi("/api/friendica/event_delete"); + xhr.setParam("id",eventid); + xhr.post(); + } + onRejected: {close()} + } + + MButton{ + id: createNewEvent + anchors.top: parent.top + anchors.topMargin: 0.5*mm + anchors.right:updateEvents.left + anchors.rightMargin:mm + width: 2*root.fontFactor*osSettings.bigFontSize; + display: AbstractButton.IconOnly + text: qsTr("add") + icon.name: "list-add-symbolic" + icon.source: "qrc:/assets/icons/plus.svg" + // background: Rectangle{color: osSettings.dialogColor; + // radius: 0.5*mm} + onClicked: { + rootstackView.push("qrc:/qml/calendarqml/EventCreate.qml") + } + } + + Connections{ + target: xhr + function onSuccess(text,api){ + if(api=="/api/friendica/event_create"){ + calBusy.running=true; + updatenews.setDatabase(); + updatenews.login(); + updatenews.setSyncAll(false); + updatenews.events(); + } + } + } MButton{ id: calendartabstatusButton anchors.top: parent.top anchors.topMargin: 0.5*mm anchors.right: parent.right - anchors.rightMargin:2*mm + anchors.rightMargin:menuButton.width + mm width: Math.max(6*root.fontFactor*osSettings.bigFontSize,implicitWidth) text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus Menu { @@ -154,18 +214,16 @@ Rectangle { width: 20*root.fontFactor*osSettings.systemFontSize MenuItem { text: qsTr("Own Calendar") - //font.pixelSize: 3*mm font.pointSize: osSettings.systemFontSize onTriggered: { calendartab.calendartabstatus="Events"; - // calendartabstatusButton.text=qsTr("own Calendar"); + // calendartabstatusButton.text=qsTr("own Calendar"); showEvents("")} } } onClicked: {calendartabmenu.popup()} } - ListView{ id: calendarView y:2*root.fontFactor*osSettings.bigFontSize//8*mm @@ -176,47 +234,45 @@ Rectangle { snapMode: ListView.SnapOneItem orientation: ListView.Horizontal highlightRangeMode: ListView.StrictlyEnforceRange -// currentIndex: count -// onCurrentIndexChanged:{print("Index "+currentIndex)} - model: CalendarModel {id:calendarModel + + model: CalendarModel {id:calendarModel from: new Date() to: new Date(new Date().valueOf()+93312000000) } delegate: Item{ - width:Math.min(23*root.fontFactor*osSettings.bigFontSize,calendarView.width) - height: parent.height - Text{ - font.bold: true - //Layout.fillWidth: true - width: parent.width-root.fontFactor*osSettings.bigFontSize - horizontalAlignment:Text.AlignHCenter - text: model.year - font.pointSize: osSettings.systemFontSize - } - Text{y:1.5*root.fontFactor*osSettings.bigFontSize - width: parent.width-osSettings.bigFontSize - text: Qt.locale().standaloneMonthName(model.month) - //Layout.fillWidth: true - horizontalAlignment:Text.AlignHCenter - font.pointSize: osSettings.systemFontSize - } - DayOfWeekRow{y:3*root.fontFactor*osSettings.bigFontSize - width: parent.width-root.fontFactor*osSettings.bigFontSize - locale: monthgrid.locale - //Layout.fillWidth: true - font.pointSize: osSettings.systemFontSize - } + width:Math.min(23*root.fontFactor*osSettings.bigFontSize,calendarView.width) + height: calendarView.height + Text{ + font.bold: true + width: parent.width-root.fontFactor*osSettings.bigFontSize + horizontalAlignment:Text.AlignHCenter + color: osSettings.primaryTextColor + text: model.year + font.pointSize: osSettings.systemFontSize + } + Text{y:1.5*root.fontFactor*osSettings.bigFontSize + width: parent.width-osSettings.bigFontSize + text: Qt.locale().standaloneMonthName(model.month) + color: osSettings.primaryTextColor + horizontalAlignment:Text.AlignHCenter + font.pointSize: osSettings.systemFontSize + } + DayOfWeekRow{y:3*root.fontFactor*osSettings.bigFontSize + width: parent.width-root.fontFactor*osSettings.bigFontSize + locale: monthgrid.locale + font.pointSize: osSettings.systemFontSize + } - MonthGrid {y:5*root.fontFactor*osSettings.bigFontSize - id: monthgrid - height: parent.height-5*root.fontFactor*osSettings.bigFontSize - width: parent.width-root.fontFactor*osSettings.bigFontSize - month: model.month - year: model.year - locale: Qt.locale() - delegate: CalendarDay{} - } + MonthGrid {y:5*root.fontFactor*osSettings.bigFontSize + id: monthgrid + height: parent.height-5*root.fontFactor*osSettings.bigFontSize + width: parent.width-root.fontFactor*osSettings.bigFontSize + month: model.month + year: model.year + locale: Qt.locale() + delegate: CalendarDay{} + } } ScrollIndicator.horizontal: ScrollIndicator { } Component.onCompleted: positionViewAtBeginning() @@ -238,7 +294,8 @@ Rectangle { } Component.onCompleted: { + root.eventcreateSignal.connect(createEvent); root.eventSignal.connect(showEvents); if (calendartab.calendartabstatus=="Events"){showEvents("")} } - } +} diff --git a/src/qml/calendarqml/EventCreate.qml b/src/qml/calendarqml/EventCreate.qml new file mode 100644 index 0000000..8cb2b5e --- /dev/null +++ b/src/qml/calendarqml/EventCreate.qml @@ -0,0 +1,471 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +//import QtQuick.Controls 1.4 as Oldcontrols +import "qrc:/js/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" +import "qrc:/qml/calendarqml" + +Flickable{ + id:eventCreateBox + property date startDate: new Date() + property var eventInformation: ({}) + //anchors.fill: parent + + contentWidth: eventRect.width; contentHeight: eventRect.height + function formatText(count, modelData) { + var data = count === 12 ? modelData + 1 : modelData; + return data.toString().length < 2 ? "0" + data : data; + } + + boundsBehavior:Flickable.StopAtBounds + ScrollBar.vertical: ScrollBar { } + + Rectangle{ + id: eventRect + width: root.width + height: textColumn.height + 6*root.fontFactor*osSettings.bigFontSize + color: osSettings.backgroundColor + + MButton{ + id:closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + onClicked:{rootstackView.pop()} + } + + Label{ + x: 0.5*root.fontFactor*osSettings.bigFontSize + y: 2*root.fontFactor*osSettings.bigFontSize + width: 3*root.fontFactor*osSettings.bigFontSize + height: root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + //verticalAlignment: TextInput.AlignBottom + color: osSettings.primaryTextColor + text:qsTr("Start") + } + + TextField { + id: textStartDate + property string dateDay:(startDate.getDate()).toString().length<2?"0"+(startDate.getDate()):(startDate.getDate()) + property string dateMonth: (startDate.getMonth()+1).toString().length<2?"0"+(startDate.getMonth()+1):(startDate.getMonth()+1) + x: 4*root.fontFactor*osSettings.bigFontSize + y: root.fontFactor*osSettings.bigFontSize + width: 5*root.fontFactor*osSettings.bigFontSize + height: 2.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + horizontalAlignment: TextInput.AlignRight + text: dateDay+"-"+dateMonth+"-"+startDate.getFullYear() + inputMask: "99-99-9999" + validator: RegularExpressionValidator{regularExpression: /^([0-2\s]?[0-9\s]|3[0-1\s])-(0[0-9\s]|1[0-2\s])-([0-9\s][0-9\s][0-9\s][0-9\s])$ / } + font.bold: true + } + + MButton { + id: textStartDateDropdown + x: 9.5*root.fontFactor*osSettings.bigFontSize + y: root.fontFactor*osSettings.bigFontSize + width: 2*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + text: qsTr("Start date") + display: AbstractButton.IconOnly + icon.name: "expand" + icon.source: "qrc:/assets/icons/caret-down.svg" + onClicked:{ + cal.visible=true; + cal.curSelection="start" + } + } + + TextField { + id: textStartTime + x: 13*root.fontFactor*osSettings.bigFontSize + y: root.fontFactor*osSettings.bigFontSize + width: 3*root.fontFactor*osSettings.bigFontSize + height: 2.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + inputMask: "99:99" + text: "00:00" + horizontalAlignment: TextInput.AlignRight + validator: RegularExpressionValidator{regularExpression: /^([0-1\s]?[0-9\s]|2[0-3\s]):([0-5\s][0-9\s])$ / } + font.bold: true + } + + MButton { + id: textStartTimeDropdown + x: 16.5*root.fontFactor*osSettings.bigFontSize + y: root.fontFactor*osSettings.bigFontSize + width: 2*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + text: qsTr("Start time") + display: AbstractButton.IconOnly + icon.name: "expand" + icon.source: "qrc:/assets/icons/caret-down.svg" + onClicked:{ + onClicked: {timeTumbler.visible=true;timeTumbler.curSelection="start"} + } + } + + Label{ + x: 0.5*root.fontFactor*osSettings.bigFontSize + y: 4*root.fontFactor*osSettings.bigFontSize + width: 3*root.fontFactor*osSettings.bigFontSize + height: root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + color: osSettings.primaryTextColor + text:qsTr("End") + } + TextField { + id: textEndDate + x: 4*root.fontFactor*osSettings.bigFontSize + y: 3*root.fontFactor*osSettings.bigFontSize + width: 5*root.fontFactor*osSettings.bigFontSize + height: 2.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + horizontalAlignment: TextInput.AlignRight + inputMask: "99-99-9999" + validator: RegularExpressionValidator{regularExpression: /^([0-2\s]?[0-9\s]|3[0-1\s])-(0[0-9\s]|1[0-2\s])-([0-9\s][0-9\s][0-9\s][0-9\s])$ / } + enabled: false + font.bold: true + } + + MButton { + id: textEndDateDropdown + x: 9.5*root.fontFactor*osSettings.bigFontSize + y: 3*root.fontFactor*osSettings.bigFontSize + width: 2*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + enabled: false + text: qsTr("End date") + display: AbstractButton.IconOnly + icon.name: "expand" + icon.source: "qrc:/assets/icons/caret-down.svg" + onClicked:{ + cal.visible=true; + cal.curSelection="end" + } + } + + TextField { + id: textEndTime + x: 13*root.fontFactor*osSettings.bigFontSize + y: 3*root.fontFactor*osSettings.bigFontSize + width: 3*root.fontFactor*osSettings.bigFontSize + height: 2.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + enabled: false + horizontalAlignment: TextInput.AlignRight + inputMask: "99:99" + validator: RegularExpressionValidator{regularExpression: /^([0-1\s]?[0-9\s]|2[0-3\s]):([0-5\s][0-9\s])$ / } + font.bold: true + } + + MButton { + id: textEndTimeDropdown + x: 16.5*root.fontFactor*osSettings.bigFontSize + y: 3*root.fontFactor*osSettings.bigFontSize + width: 2*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + enabled: false + text: qsTr("End time") + display: AbstractButton.IconOnly + icon.name: "expand" + icon.source: "qrc:/assets/icons/caret-down.svg" + onClicked:{ + onClicked: {timeTumbler.visible=true;timeTumbler.curSelection="end"} + } + } + + Column{ + id: textColumn + x: 4*root.fontFactor*osSettings.bigFontSize + y: 6*root.fontFactor*osSettings.bigFontSize + width: parent.width-7*root.fontFactor*osSettings.bigFontSize + + ListView{ + id: cal + visible: false + width: textColumn.width //12*root.fontFactor*osSettings.bigFontSize + height: 15*root.fontFactor*osSettings.bigFontSize + clip: true + snapMode: ListView.SnapOneItem + orientation: ListView.Horizontal + highlightRangeMode: ListView.StrictlyEnforceRange + property string curSelection: "start" + + model: CalendarModel {id:calendarModel + from: new Date() + to: new Date(new Date().valueOf()+93312000000) + } + delegate: + Item{ + width:Math.min(23*root.fontFactor*osSettings.bigFontSize,cal.width) + height: parent.height + Text{ + font.bold: true + width: parent.width-root.fontFactor*osSettings.bigFontSize + horizontalAlignment:Text.AlignHCenter + color: osSettings.primaryTextColor + text: model.year + font.pointSize: osSettings.systemFontSize + } + Text{y:1.5*root.fontFactor*osSettings.bigFontSize + width: parent.width-osSettings.bigFontSize + text: Qt.locale().standaloneMonthName(model.month) + color: osSettings.primaryTextColor + horizontalAlignment:Text.AlignHCenter + font.pointSize: osSettings.systemFontSize + } + DayOfWeekRow{y:3*root.fontFactor*osSettings.bigFontSize + width: parent.width-root.fontFactor*osSettings.bigFontSize + locale: monthgrid.locale + font.pointSize: osSettings.systemFontSize + } + + MonthGrid {y:5*root.fontFactor*osSettings.bigFontSize + id: monthgrid + height: parent.height-5*root.fontFactor*osSettings.bigFontSize + width: parent.width-root.fontFactor*osSettings.bigFontSize + month: model.month + year: model.year + locale: Qt.locale() + delegate: Button{ + width: root.fontFactor*osSettings.bigFontSize*3 + height: root.fontFactor*osSettings.bigFontSize*2 + enabled: model.month==monthgrid.month + text: model.day + font.underline: model.today + font.pointSize: 1.2*osSettings.systemFontSize + highlighted: model.today + onClicked:{if (cal.curSelection=="start"){ + textStartDate.text=Qt.formatDate(model.date, "dd-MM-yyyy"); + }else{ + textEndDate.text=Qt.formatDate(model.date, "dd-MM-yyyy"); + } + cal.visible=false}} + } + } + ScrollIndicator.horizontal: ScrollIndicator { } + Component.onCompleted: positionViewAtBeginning() + } + + Frame { + id: timeTumbler + width: 12*root.fontFactor*osSettings.bigFontSize + height: 10*root.fontFactor*osSettings.bigFontSize + visible: false + property string curSelection: "start" + + Row { + Tumbler { + id: hoursTumbler + model: 24 + delegate: tumblerDelegateComponent + currentIndex: 12 + } + Tumbler { + id: minutesTumbler + model: 60 + delegate: tumblerDelegateComponent + } + } + MButton { + id: timeInputfinished + width: 2*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Accept time") + display: AbstractButton.IconOnly + icon.name: "checkbox" + icon.source: "qrc:/assets/icons/check.svg" + onClicked:{ + if (timeTumbler.curSelection=="start"){ + textStartTime.text=formatText(24,hoursTumbler.currentIndex)+":"+formatText(60,minutesTumbler.currentIndex); + }else{ + textEndTime.text=formatText(24,hoursTumbler.currentIndex)+":"+formatText(60,minutesTumbler.currentIndex); + } + timeTumbler.visible=false + } + } + } + + CheckBox{ + id: checkNoEndTime + width: 12*root.fontFactor*osSettings.bigFontSize + height: 2.5*root.fontFactor*osSettings.bigFontSize + checked: true + font.pointSize: osSettings.systemFontSize + text: qsTr("no end") + onCheckedChanged: { + if(checked==true){ + textEndDate.enabled=false; + textEndDateDropdown.enabled=false; + textEndTime.enabled=false; + textEndTimeDropdown.enabled=false; + textEndDate.text=""; + textEndTime.text="" + }else{ + textEndDate.enabled=true; + textEndDateDropdown.enabled=true; + textEndTime.enabled=true; + textEndTimeDropdown.enabled=true; + textEndDate.text=textStartDate.text; + textEndTime.text=textStartTime.text + } + } + } + + TextField { + id: titleField + width: parent.width-root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: true + placeholderText: qsTr("Title (required)") + } + + Rectangle{ + color: osSettings.backgroundColor + radius: 0.5*mm + width: parent.width-root.fontFactor*osSettings.bigFontSize + height:Math.max(bodyField.contentHeight+root.fontFactor*osSettings.bigFontSize,2.5*root.fontFactor*osSettings.bigFontSize) + TextArea { + id: bodyField + anchors.fill: parent + font.pointSize: osSettings.systemFontSize + font.family: "Noto Sans" + wrapMode: Text.Wrap + selectByMouse: true + placeholderText: qsTr("Event description (optional)") + textFormat: TextEdit.PlainText + text: eventInformation.hasOwnProperty("text")?eventInformation.text:"" + onLinkActivated:{Qt.openUrlExternally(link)} + } + } + + TextField { + id: locationField + width: parent.width-root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + placeholderText: qsTr("Location (optional)") + } + + CheckBox{ + id: chkbxPublish + width: 10*root.fontFactor*osSettings.bigFontSize + height: 2.5*root.fontFactor*osSettings.bigFontSize + checked: true + font.pointSize: osSettings.systemFontSize + text: qsTr("Publish event?") + } + + BusyIndicator{ + id: eventCreateBusy + anchors.horizontalCenter: eventRect.horizontalCenter + anchors.top: eventRect.top + anchors.topMargin: 2*root.fontFactor*osSettings.bigFontSize + width:3*root.fontFactor*osSettings.bigFontSize + height: 3*root.fontFactor*osSettings.bigFontSize + running: false + } + + MButton{ + id:createEventButton + text: qsTr("Create event") + width:textColumn.width + onClicked:{ + let startdatetext=textStartDate.getText(0,textStartDate.length); + let startdate=new Date(startdatetext.substring(6,10)+"-"+startdatetext.substring(3,5)+"-"+startdatetext.substring(0,2)+"T"+textStartTime.text) + + if (titleField.text==""){ + Helperjs.showMessage(qsTr("Error"),qsTr("No event name supplied"),eventCreateBox) + }else{ + let startdatetext=textStartDate.getText(0,textStartDate.length); + let startdate=new Date(startdatetext.substring(6,10)+"-"+startdatetext.substring(3,5)+"-"+startdatetext.substring(0,2)+"T"+textStartTime.text) + eventCreateBusy.running=true; + xhr.setAccount(login); + xhr.setApi("/api/friendica/event_create"); + xhr.setParam("name", titleField.text); + xhr.setParam("start_time",startdate.toISOString()) + if(!checkNoEndTime.checked){ + let enddatetext=textEndDate.getText(0,textEndDate.length); + let enddate=new Date(enddatetext.substring(6,10)+"-"+enddatetext.substring(3,5)+"-"+enddatetext.substring(0,2)+"T"+textEndTime.text) + xhr.setParam("end_time",enddate.toISOString()) + } + xhr.setParam("name",titleField.text) + if (bodyField.text!=""){xhr.setParam("desc",bodyField.text)} + if (locationField.text!=""){xhr.setParam("place",locationField.text)} + xhr.setParam("publish",chkbxPublish.checked) + xhr.post(); + } + } + } + Connections{ + target: xhr + function onSuccess(text,api){ + if (api=="/api/friendica/event_create"){ + updatenews.setDatabase(); + updatenews.login(); + updatenews.setSyncAll(false); + updatenews.events(); + try{while(rootstackView.depth>1){rootstackView.pop()}}catch(e){} + } + } + function onError(text,api){ + if (api=="/api/friendica/event_create"){ + Helperjs.showMessage(qsTr("Error"),text,root) + } + } + } + } + + Component { + id: tumblerDelegateComponent + Label { + text: formatText(Tumbler.tumbler.count, modelData) + opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2) + color: osSettings.primaryTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pointSize: osSettings.systemFontSize + } + } + } +} diff --git a/source-linux/qml/calendarqml/EventList.qml b/src/qml/calendarqml/EventList.qml similarity index 68% rename from source-linux/qml/calendarqml/EventList.qml rename to src/qml/calendarqml/EventList.qml index 7edc97d..8fb4e58 100644 --- a/source-linux/qml/calendarqml/EventList.qml +++ b/src/qml/calendarqml/EventList.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 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -38,10 +38,7 @@ import "qrc:/qml/calendarqml" Rectangle{ id:eventList -// height: parent.height -// width:parent.width - - //radius: 0.5*mm + color: osSettings.backgroundColor property var daylist:[] property int dayint: 0 property var events:[] @@ -52,9 +49,44 @@ Rectangle{ anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm - text: "\uf057" + width: 2*root.fontFactor*osSettings.bigFontSize; + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" onClicked:{rootstackView.pop()} } + + MButton{ + id: createNewEvent + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right:closeButton.left + anchors.rightMargin:mm + width: 2*root.fontFactor*osSettings.bigFontSize; + display: AbstractButton.IconOnly + icon.name: "list-add-symbolic" + icon.source: "qrc:/assets/icons/plus.svg" + onClicked: { + rootstackView.push("qrc:/qml/calendarqml/EventCreate.qml",{"startDate": new Date(dayint*86400000)}) + } + } + Dialog { + id: deleteDialog + anchors.centerIn: parent + property int eventid:0 + title: qsTr("Delete Event?") + standardButtons: Dialog.Ok | Dialog.Cancel + modal: true + onAccepted: { + xhr.setAccount(login); + xhr.setApi("/api/friendica/event_delete"); + xhr.setParam("id",eventid); + xhr.post(); + } + onRejected: {close()} + } + ListView { id: eventlistView y:closeButton.height+2*mm @@ -64,16 +96,13 @@ Rectangle{ model: eventModel delegate: EventListItem{} } - ListModel{ id: eventModel } - - Component.onCompleted:{//print("daylist"+JSON.stringify(events) + dayint) + Component.onCompleted:{ var currentevents=events.filter(event=>(dayint>=event.startday)&&(dayint<=event.endday)); for (var i=0; i. -import QtQuick 2.0 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import QtQml 6.3 import "qrc:/js/service.js" as Service import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -41,8 +42,9 @@ Rectangle{ property string status: eventstatus property var currEvent: event width:parent.width - height:eventNameText.height+eventDetailsText.height+mm - border.color: "light grey" + height:Math.max(eventNameText.height+eventDetailsText.height,profileImage.height)+mm + //border.color: osSettings.backgroundDimColor + color: osSettings.backgroundColor border.width: 1 radius: 0.5*mm Image { @@ -52,17 +54,17 @@ Rectangle{ y:1 width: 7*mm height: 7*mm - //radius:mm - - onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/assets/defaultcontact.jpg"} } Text { id:eventNameText x: 8*mm width:parent.width-8*mm height:contentHeight + color: osSettings.primaryTextColor + textFormat: Text.RichText font.pointSize: osSettings.systemFontSize - text: new Date(event.start).toLocaleString(Qt.locale(),Locale.NarrowFormat)+ " - " +((event.end>0)&&(event.end!=null)?new Date(event.end).toLocaleString(Qt.locale(),Locale.NarrowFormat):"\u221E")+":\n"+event.title //+calendarrectangle.offsetTime + text: new Date(event.start).toLocaleString(Qt.locale(),Locale.NarrowFormat)+ " - " +((event.end>0)&&(event.end!=null)?new Date(event.end).toLocaleString(Qt.locale(),Locale.NarrowFormat):"\u221E")+":
"+(status=="large"?""+event.title+"":event.title) wrapMode:Text.Wrap } @@ -72,19 +74,52 @@ Rectangle{ z:4 width: parent.width-8*mm height: contentHeight + color: osSettings.primaryTextColor textFormat: Text.RichText - text: status!="large"?"":Qt.atob(event.desc) + (event.location==""?"":"

"+qsTr("Location")+": "+event.location)//Qt.atob(event.html) + text: status!="large"?"":Qt.atob(event.desc) + (event.location==""?"":"

"+qsTr("Location")+": "+event.location) anchors.top: eventNameText.bottom font.pointSize: osSettings.systemFontSize wrapMode:Text.Wrap onLinkActivated:{Qt.openUrlExternally(link)} } + MouseArea{ anchors.fill: parent + MButton{ + id: deleteEvent + anchors.top: parent.top + anchors.topMargin: 0.5*mm + anchors.right:parent.right + anchors.rightMargin:mm + width: 2*root.fontFactor*osSettings.bigFontSize; + icon.name: "user-trash-symbolic" + icon.source: "qrc:/assets/icons/trash.svg" + // background: Rectangle{color: osSettings.dialogColor; + // radius: 0.5*mm} + onClicked: { + deleteDialog.eventid=event.id + deleteDialog.open() + } + } + onClicked:{ if (status==""){ rootstackView.push("qrc:/qml/calendarqml/EventList.qml",{"dayint": event.startday, "events":[event]}); } else {rootstackView.pop()} } } + + Connections{ + target: xhr + function onSuccess(text,api){ + if (api=="/api/friendica/event_delete"){ + let obj=JSON.parse(text); + if(obj.status=="deleted"&&obj.id==event.id){ + Helperjs.deleteData(db,"events",login.username, function(){ + eventModel.remove(index); + },"id",obj.id) + } + } + } + } } diff --git a/source-linux/qml/newsqml/NewsYplayer.qml b/src/qml/configqml/AcceptRules.qml similarity index 59% rename from source-linux/qml/newsqml/NewsYplayer.qml rename to src/qml/configqml/AcceptRules.qml index fff2b1f..68e4107 100644 --- a/source-linux/qml/newsqml/NewsYplayer.qml +++ b/src/qml/configqml/AcceptRules.qml @@ -1,5 +1,3 @@ - - // This file is part of Friendiqa // https://git.friendi.ca/lubuwest/Friendiqa // Copyright (C) 2020 Marco R. @@ -31,47 +29,40 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.8 -import QtQuick.Controls 2.12 -import "qrc:/js/helper.js" as Helperjs -import QtWebView 1.1 +import QtQuick 6.3 +import QtQuick.Controls 6.3 - -Page { - id:newsYplayer - //color:"black" - width:root.width; - height:root.height-7*mm - property string url:"" - property string ytcode:"" - - WebView { - id: webView - anchors.fill: parent - z:1 - opacity: 0 - - url: root.osSettings.osType=="Android"?"https://youtube.com/watch?v="+ytcode:"qrc:/js/yplayer.html?" + ytcode - - Behavior on opacity { NumberAnimation { duration: 200 } } - - onLoadingChanged: { - switch (loadRequest.status) - { - case WebView.LoadSucceededStatus: - opacity = 1 - return - case WebView.LoadStartedStatus: - case WebView.LoadStoppedStatus: - break - case WebView.LoadFailedStatus: - print("Failed to load the requested video" + url) - break - } - opacity = 0 - } - onTitleChanged: { - if (title==2){root.pop()} - } +Dialog { + id: rulesDialog + height: parent.height/2 + width: parent.width + anchors.centerIn: parent + title: qsTr("Accept instance rules") + property string rules: "" + standardButtons: Dialog.Yes | Dialog.No + modal: true + onAccepted: { + username.visible=true; + ruleButton.visible=false; + confirmationOAuth.visible=true } + onRejected: {close()} + ScrollView{ + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + width: root.width-2*root.fontFactor*osSettings.bigFontSize + height:parent.height + clip:true + Text { + x:1; y:1 + width: root.width-4*root.fontFactor*osSettings.bigFontSize + wrapMode: TextEdit.Wrap + color: osSettings.primaryTextColor + linkColor: osSettings.secondaryTextColor + textFormat: Text.PlainText + font.family: "Noto Sans" + font.pointSize: osSettings.systemFontSize + text: rules + + } + } } diff --git a/src/qml/configqml/AccountPage.qml b/src/qml/configqml/AccountPage.qml new file mode 100644 index 0000000..fc11c0e --- /dev/null +++ b/src/qml/configqml/AccountPage.qml @@ -0,0 +1,617 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtCore 6.3 +import QtQuick.Dialogs 6.3 +import QtQuick.Controls 6.3 +import QtQuick.Layouts +import QtQml.Models 6.3 +import "qrc:/js/service.js" as Service +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: ({}) + property string imagestoredir: "" + property var appdata: ({}) + + function setServericon(server){ + if ((server!=null) && (server!="")){ + xhr.setUrl(server); + xhr.setApi("/api/statusnet/config"); + xhr.clearParams(); + xhr.get(); + } + } + + function verify(userconfig){ + Helperjs.friendicaRequest(userconfig,"/api/v1/accounts/verify_credentials",root,function(obj){ + accountBusy.running=false; + try{var credentials=JSON.parse(obj); + if (credentials.hasOwnProperty('error')){ + Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password or 2FA enabled!"),root) + } + else{ + if (users.length==0){Service.setDefaultOptions(db);} + if (userconfig.hasOwnProperty("APIVersion")){userconfig.password=""} + if (imagestoredir==""){ + imagestoredir=filesystem.homePath+"/"+credentials.username+"/"; + userconfig.imagestore=imagestoredir + } + if(userconfig.imagestore == filesystem.homePath+"/"+credentials.username+"/") + {filesystem.makePath(filesystem.homePath+"/"+credentials.username);} + filesystem.Directory=imagestoredir; + filesystem.makeDir("contacts"); + filesystem.makeDir("albums"); + userconfig.accountId=credentials.id; + userconfig.username=credentials.username; + 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 + login=userconfig; + news=[]; + contactlist=[]; + if(rootstackView.depth>1){rootstackSignal(0);newstypeSignal("refresh");} + else {rootstackView.replace("qrc:/qml/genericqml/RootStack.qml",StackView.PopTransition)}; + },"isActive",0); + Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.display_name+"\nScreen Name: "+credentials.username,root) + rootstackView.pop() + } + }catch(e){Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password or 2FA enabled!"+e),root)}; + }) + } + + BusyIndicator{ + id: accountBusy + anchors.centerIn: parent + width: 5*root.fontFactor*osSettings.bigFontSize + height: 5*root.fontFactor*osSettings.bigFontSize + running: false + } + + ColumnLayout{ + x: root.fontFactor*osSettings.bigFontSize + width: root.width - 2*mm + y: root.fontFactor*osSettings.bigFontSize + spacing: root.fontFactor*osSettings.bigFontSize + + Row{ + spacing:0.5*mm + height: userButton.height + width: parent.width + + MButton{ + id:userButton + text:qsTr("User") + font.pointSize: osSettings.bigFontSize + visible: users.length>0 + onClicked:{ + var useritems=""; + for (var i=0;i0 + text: "-" + font.pointSize: osSettings.bigFontSize + onClicked:{ + var userconfig={server: servername.text, username: username.text, password: Qt.btoa(password.text)}; + + Service.readConfig(db,function(user){ + if(userdata.token!=""){xhr.setUrl(servername.text); + xhr.setApi("/oauth/revoke"); + xhr.clearParams(); + xhr.setParam("client_id",user.client.client_id); + xhr.setParam("client_secret",user.client.client_secret); + xhr.setParam("token",user.token); + xhr.post(); + } + },"username",username.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=""; + userButton.text=qsTr("User"); + Helperjs.readData(db,"config","",function(storedUsers){ + storedUsers.sort(function(obj1, obj2) { + return obj1.isActive - obj2.isActive; + }) + accountPage.users=storedUsers;}) + accountPage.state="new_oauth" + }) + }} + + MButton { + visible: users.length>0 + text: "+" + font.pointSize: osSettings.bigFontSize + onClicked:{ + servername.text="https://" + servericon.visible=false; + servericon.source=""; + username.text="" + password.text="" + imagestore.text="" + userButton.text=qsTr("User") + accountPage.state="new_oauth" + } + } + + MButton { + text: "?" + font.pointSize: osSettings.bigFontSize + onClicked:{ + rootstackView.push("qrc:/qml/configqml/InfoBox.qml"); + } + } + MButton { + text: qsTr("Method") + display: AbstractButton.IconOnly + icon.name: "expand" + icon.source: "qrc:/assets/icons/caret-down.svg" + font.pointSize: osSettings.bigFontSize + Menu { + id:authMethodMenu + width: 10*root.fontFactor*osSettings.systemFontSize + MenuItem { + text: qsTr("OAuth") + font.pointSize: osSettings.systemFontSize + font.bold:accountPage.state=="oauth" + onTriggered: {accountPage.state="oauth"} + } + MenuItem { + text: qsTr("Password") + font.pointSize: osSettings.systemFontSize + font.bold:accountPage.state=="password" + onTriggered: {accountPage.state="password"} + } + } + onClicked: {authMethodMenu.popup()} + } + MButton{ + id:closeButton + visible: users.length>0 + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + font.pointSize: osSettings.bigFontSize + onClicked:{rootstackView.pop()} + } + } + Row{ + spacing:0.5*mm + height: 3*root.fontFactor*osSettings.bigFontSize + width: parent.width + Image{ + id:servericon + width:2.5*root.fontFactor*osSettings.bigFontSize; height: 2.5*root.fontFactor*osSettings.bigFontSize + visible: false + source:"" + property var serverconfig:({}) + MouseArea{ + anchors.fill:parent + onClicked:{ + let serverConfigString="import QtQuick 6.3; import QtQuick.Dialogs 6.3; MessageDialog{ visible: true; title:'Server';buttons: MessageDialog.Ok;text: 'Name: "+ + servericon.serverconfig.site.name+"\nLanguage: "+servericon.serverconfig.site.language+ + "\nEmail: "+servericon.serverconfig.site.email+"\nTimezone: "+servericon.serverconfig.site.timezone+"\nClosed: "+servericon.serverconfig.site.closed+ + "\nText limit: "+servericon.serverconfig.site.textlimit+"\nShort Url length: "+servericon.serverconfig.site.shorturllength+ + "\nFriendica version: "+servericon.serverconfig.site.friendica.FRIENDICA_VERSION+ + "\nDB Update version: "+servericon.serverconfig.site.friendica.DB_UPDATE_VERSION+"'}"; + + var serverconfigObject=Qt.createQmlObject(serverConfigString,accountPage,"serverconfigOutput"); + } + } + } + //FontLoader{id: fontAwesome; source: "qrc:/assets/fontawesome-webfont.ttf"} + MButton{ + id:serverSearchButton + width: 3*root.fontFactor*osSettings.bigFontSize; height: 2.5*root.fontFactor*osSettings.bigFontSize + //text:"\uf002" + icon.name: "system-search" + font.pointSize: osSettings.bigFontSize + visible: servericon.visible?false:true + onClicked:{Qt.openUrlExternally(Qt.resolvedUrl("https://dir.friendica.social/servers"))} + } + + // ComboBox{ + // id: servername + // x: 4*root.fontFactor*osSettings.bigFontSize + // y: 3.5*root.fontFactor*osSettings.bigFontSize + // width: root.width-5*root.fontFactor*osSettings.bigFontSize + // height: 2.5*root.fontFactor*osSettings.bigFontSize//5*mm; + // font.pointSize: osSettings.systemFontSize + // editable:true + // model: serverModel + // onAccepted: { + // let cleanText =currentText;if(currentText==""){cleanText=editText} + // if((cleanText).substring(0,8) !=="https://"){ + // cleanText="https://"+cleanText + // } + // if (find(cleanText) === -1) { + // serverModel.append({text: cleanText}) + // currentIndex = find(cleanText) + // displayText=cleanText + // } + // if (cleanText!=""){accountPage.setServericon(cleanText)} + // } + // onFocusChanged: { + // if(focus==false){ + // onAccepted() + // } + // } + // } + TextField { + id: servername + width: root.width-5*root.fontFactor*osSettings.bigFontSize + height: 2.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + text:"https://" + onFocusChanged:{ + if (focus){servermenu.open()} + else{ + if((servername.text).substring(0,11) =="https://http"){ + servername.text= (servername.text).substring(8) + } + if (servername.text!="https://"){ + accountPage.setServericon(servername.text)} + } + } + } + Menu { + id:servermenu + width: 13*root.fontFactor*osSettings.bigFontSize + Instantiator{ + model:serverModel + MenuItem{ + text: modelData + onTriggered: {servername.text=modelData} + } + onObjectAdded:{servermenu.insertItem(index,object)} + onObjectRemoved:{servermenu.removeItem(object)} + } + } + + ListModel{id:serverModel + ListElement{text:"https://anonsys.net"} + ListElement{text:"https://asaps-sm.lafayettegroup.com"} + ListElement{text:"https://f.freinetz.ch"} + ListElement{text:"https://friendica.chilemasto.casa"} + ListElement{text:"https://friendica.eskimo.com"} + ListElement{text:"https://friendica.me"} + ListElement{text:"https://friendica.opensocial.space"} + ListElement{text:"https://friendica.utzer.de"} + ListElement{text:"https://friendica.vrije-mens.org"} + ListElement{text:"https://libranet.de"} + ListElement{text:"https://loma.ml"} + ListElement{text:"https://nerdica.net"} + ListElement{text:"https://nsfw.wnymathguy.com"} + ListElement{text:"https://opensocial.at"} + ListElement{text:"https://poliverso.org"} + ListElement{text:"https://social.isurf.ca"} + ListElement{text:"https://social.trom.tf"} + ListElement{text:"https://squeet.me"} + ListElement{text:"https://venera.social"} + } + } + MButton { + id: ruleButton + width: parent.width + visible: (osSettings.osType=="Android") && (userButton.text== qsTr("User")) + height: 2*root.fontFactor*osSettings.bigFontSize; + text: qsTr("Instance rules") + font.pointSize: osSettings.bigFontSize + onClicked:{ + xhr.setUrl(servername.text); + xhr.setApi("/api/v1/instance/rules"); + xhr.clearParams(); + xhr.get(); + } + } + + TextField { + id: username + width: root.width-5*root.fontFactor*osSettings.bigFontSize + height: 2.5*root.fontFactor*osSettings.bigFontSize; + Layout.leftMargin: 3*root.fontFactor*osSettings.bigFontSize; + font.pointSize: osSettings.systemFontSize + visible: (osSettings.osType=="Android")?(text!= ""):true + placeholderText: qsTr("Nickname") + selectByMouse: true + onEditingFinished: { + if (username.text.indexOf('@')>-1){ + Helperjs.showMessage(qsTr("Error"),qsTr("Nicknames containing @ symbol currently not supported"),accountPage) + } + imagestoredir=filesystem.homePath+"/"+username.text+"/" + } + } + + TextField { + id: password + width: root.width-9*mm; height: 2.5*root.fontFactor*osSettings.bigFontSize; + Layout.leftMargin: 3*root.fontFactor*osSettings.bigFontSize; + font.pointSize: osSettings.systemFontSize + visible: (osSettings.osType=="Android")?(userButton.text!= qsTr("User")):true + selectByMouse: true + echoMode: TextInput.Password + placeholderText: qsTr("Password") + inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhSensitiveData + } + + Row{ + spacing:0.5*mm + height: 3*root.fontFactor*osSettings.bigFontSize + width: parent.width + Label { + id: imagedirlabel + visible: imagestore.text!="" + text: qsTr("Image dir.") + font.pointSize: osSettings.systemFontSize + } + + TextField { + id: imagestore + width: root.width-17*mm; + height: 2.5*root.fontFactor*osSettings.bigFontSize; + visible:imagestore.text!="" + font.pointSize: osSettings.systemFontSize + selectByMouse: true + text: "" + wrapMode: TextEdit.NoWrap + onTextChanged: imagestoredir=imagestore.text + } + + MButton { + visible:imagestore.text!="" + text: "..." + font.pointSize: osSettings.bigFontSize + onClicked:{imagestoreDialog.open()} + } + + FolderDialog { + id: imagestoreDialog + title: "Please choose a directory" + currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] + //selectFolder: true + onAccepted: { + var imagestoreString=imagestoreDialog.selectedFolder.toString(); + imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/" + imagestore.text=imagestoreString + } + } + } + + + MButton { + id:confirmationOAuth + width: parent.width + text: qsTr("Connect") + font.pointSize: osSettings.bigFontSize + visible: (osSettings.osType=="Android")?userButton.text!= qsTr("User"):true + onClicked:{ + if (servername.text==""){Helperjs.showMessage(qsTr("Error"), qsTr("No server given!"),root)} + else{ + xhr.setUrl(servername.text); + xhr.setApi("/api/v1/apps"); + xhr.clearParams(); + if (osSettings.osType=="Android"){ + xhr.setParam("client_name","Friendiqa-Android"); + } else { + xhr.setParam("client_name","Friendiqa-"+filesystem.hostname); + } + xhr.setParam("redirect_uris","http://127.0.0.1:1337/"); + xhr.setParam("scopes","read write follow push"); + xhr.setParam("website","https://friendiqa.ma-nic.de"); + xhr.post(); + } + } + } + + Connections{ + target: xhr + function onSuccess(text,api){ + if(api=="/api/v1/instance/rules"){ + let rulestext=""; + try{let rulesarray=JSON.parse(text) + for (let rule in rulesarray){ + rulestext=rulestext+rulesarray[rule].text+"\n" + } + var component = Qt.createComponent("qrc:/qml/configqml/AcceptRules.qml"); + var rulesdialog = component.createObject(accountPage,{"rules": rulestext}); + rulesdialog.open();}catch(e){print("/api/v1/instance/rules" +e)} + } + else if(api=="/api/statusnet/config"){ + try{let serverdata = JSON.parse(text); + servericon.visible=true; + servericon.source=serverdata.site.logo; + servericon.serverconfig=serverdata; + } + catch(e){print(e)} + } + + else if (api=="/api/v1/apps"){ + let app=JSON.parse(text); + accountPage.appdata=app; + oauth2.setClientId(app.client_id); + oauth2.setClientSecret(app.client_secret); + oauth2.setServer(servername.text); + oauth2.grant(); + } + } + } + + Connections{ + target: oauth2 + function onSuccess(text){ + var userconfig={server: servername.displayText, username:"", password:"", imagestore: imagestoredir,interval:"",token: text,client:Qt.btoa(JSON.stringify(appdata))} + verify(userconfig) + } + function onError(text){ + Helperjs.showMessage(qsTr("Error"), qsTr("Couldn't connect to server"),root) + print ("oauth2 onerror "+text) + } + } + + MButton { + id:confirmation + width: 10*root.fontFactor*osSettings.bigFontSize; + text: qsTr("Confirm") + font.pointSize: osSettings.bigFontSize + visible: false// (osSettings.osType=="Android")?userButton.text!= qsTr("User"):true + onClicked:{ + accountBusy.running=true; + var userconfig={server: servername.displayText, username: username.text, password:Qt.btoa(password.text), imagestore:imagestoredir,interval:""}; + 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 (imagestoredir=="") {errormessage+=qsTr("No image directory given!")} + else {errormessage=""} + if (errormessage=="") {verify(userconfig)} + else {Helperjs.showMessage(qsTr("Error"), errormessage,root)} + }} + + MButton { + id: setDefault + width: 10*root.fontFactor*osSettings.bigFontSize; + text: qsTr("Set as default") + font.pointSize: osSettings.bigFontSize + visible: false + onClicked:{ + accountBusy.running=true; + let users=updatenews.getAccounts("username",username.text) + Service.storeConfig(db,users[0]); + Service.readConfig(db,function(userconfig){ + //reset values + login=userconfig; + news=[]; + contactlist=[]; + rootstackSignal(0); + newstypeSignal("refresh"); + },"isActive",0); + Helperjs.showMessage(qsTr("Success"),"Screen Name: "+users[0].username,root) + rootstackView.pop() + } + } + } + states: [ + State { + name: "new_oauth" + PropertyChanges {target: username; visible: false } + PropertyChanges {target: password; visible: false} + PropertyChanges {target: ruleButton; visible: true} + }, + State { + name:"oauth" + PropertyChanges {target: username; visible: false} + PropertyChanges {target: password; visible: false} + PropertyChanges {target: confirmationOAuth; visible: true} + PropertyChanges {target: setDefault; visible: true} + PropertyChanges {target: confirmation; visible: false} + }, + State{ + name:"password" + PropertyChanges {target: username; visible: true } + PropertyChanges {target: password; visible: true} + PropertyChanges {target: confirmation; visible: true} + PropertyChanges {target: confirmationOAuth; visible: false} + } + ] + + 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){ + if (obj==null){ + accountPage.state="new_oauth" + } + else{ + userButton.text=obj.username; + servername.text=obj.server; + serverModel.insert(0,{text:obj.server}) + accountPage.setServericon(obj.server); + username.text= obj.username; + password.text=Qt.atob(obj.password); + imagestore.text=obj.imagestore; + imagestoredir=obj.imagestore; + if( obj.isActive==0){userButton.font.bold='true'} else {userButton.font.bold='false'} + if(obj.password!=""){accountPage.state="password"} + else if (obj.token!=""){accountPage.state="oauth"} + else {accountPage.state="new_oauth"} + } + + },"isActive",0) + })} + catch (e){print(e)} + } +} diff --git a/src/qml/configqml/ConfigAppearancePage.qml b/src/qml/configqml/ConfigAppearancePage.qml new file mode 100644 index 0000000..b77f691 --- /dev/null +++ b/src/qml/configqml/ConfigAppearancePage.qml @@ -0,0 +1,256 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +//import QtQuick.Dialogs 1.2 +import QtQuick.Controls 6.3 +import "qrc:/js/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/configqml" +import "qrc:/qml/genericqml" + +Page{ + width: parent.width + height: parent.height + ScrollView{ + anchors.fill: parent + contentHeight: 40*root.fontFactor*osSettings.bigFontSize + contentWidth: root.width + clip:true + + Label { + text: qsTr("News as") + font.pointSize:osSettings.systemFontSize + x: root.fontFactor*osSettings.bigFontSize; y: 2*root.fontFactor*osSettings.bigFontSize + } + + Rectangle{ + x: root.fontFactor*osSettings.bigFontSize; y: 4*root.fontFactor*osSettings.bigFontSize; + width: newsTypeField.contentWidth+2*mm; height: 2*root.fontFactor*osSettings.bigFontSize + color: osSettings.backgroundDimColor//"#F3F3F3" + radius: 0.5*mm + Label{ + id: newsTypeField + anchors.fill: parent + font.pointSize:osSettings.bigFontSize + text:qsTr("Conversations") + } + MouseArea{ + anchors.fill:parent + onClicked:newstypemenu.popup() + } + } + Menu { + id:newstypemenu + width:12*root.fontFactor*osSettings.bigFontSize + MenuItem { + font.pointSize: osSettings.bigFontSize + text: qsTr("Timeline") + onTriggered: {newsTypeField.text=qsTr("Timeline"); + Service.updateglobaloptions(root.db,"newsViewType","Timeline");} + } + MenuItem { + font.pointSize: osSettings.bigFontSize + text: qsTr("Conversations") + onTriggered: {newsTypeField.text=qsTr("Conversations"); + Service.updateglobaloptions(root.db,"newsViewType","Conversations");} + } + } + + + Label { + text: qsTr("Max. News") + font.pointSize: osSettings.systemFontSize + x: root.fontFactor*osSettings.bigFontSize; y:8*root.fontFactor*osSettings.bigFontSize + } + + Slider{ id: maxNews + x:6*root.fontFactor*osSettings.bigFontSize; y: 10*root.fontFactor*osSettings.bigFontSize; + width: root.width/2;height:2*root.fontFactor*osSettings.bigFontSize + from: 0;to:2000; stepSize: 100 + value: root.globaloptions.hasOwnProperty("max_news")?root.globaloptions.max_news:1000 + } + + Rectangle{ + color: osSettings.backgroundDimColor + x: root.fontFactor*osSettings.bigFontSize; y: 10*root.fontFactor*osSettings.bigFontSize; + width: 4*root.fontFactor*osSettings.bigFontSize; height: 2*root.fontFactor*osSettings.bigFontSize; + radius: 0.5*mm + TextEdit{id:maxNewsText; + anchors.fill: parent + font.pointSize: osSettings.bigFontSize + verticalAlignment:TextEdit.AlignRight + color: osSettings.primaryTextColor + text:maxNews.value + selectByMouse: true + onTextChanged: { + Service.updateglobaloptions(root.db,"max_news",text); + } + } + } + + CheckBox{ + id: nsfwCheckbox + x: root.fontFactor*osSettings.bigFontSize + y: 14*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.bigFontSize + text: qsTr("Hide #nsfw?") + checked:(globaloptions["hide_nsfw"]==1)?true:false + onClicked: { + toggle(); + if(nsfwCheckbox.checked==true){ + Service.updateglobaloptions(root.db,"hide_nsfw",0);nsfwCheckbox.checked=false; + } + else{ + Service.updateglobaloptions(root.db,"hide_nsfw",1);nsfwCheckbox.checked=true; + } + } + } + + + // CheckBox{ + // id: darkmodeCheckbox + // tristate:true + // x: root.fontFactor*osSettings.bigFontSize + // y: 24*root.fontFactor*osSettings.bigFontSize + // font.pointSize: osSettings.bigFontSize + // text: qsTr("Dark Mode") + // checked:(globaloptions["view_darkmode"]==1)?true:false + // onClicked: { + // toggle(); + // if(darkmodeCheckbox.checked==true){ + // Service.updateglobaloptions(root.db,"view_darkmode",0);darkmodeCheckbox.checked=false; + // root.Material.theme=Material.Light + // } + // else{ + // Service.updateglobaloptions(root.db,"view_darkmode",1);darkmodeCheckbox.checked=true; + // root.Material.theme=Material.Dark + // } + // } + // } + + + Column{ + x: root.fontFactor*osSettings.bigFontSize + y: 18*root.fontFactor*osSettings.bigFontSize + Label{ + text: qsTr("Default News Tabs") + font.pointSize: osSettings.systemFontSize + } + + Repeater{id:newstypeRepeater + model: 4 + delegate:ComboBox{ + required property int index + model: ["Home", "Replies", "DirectMessages","Favorites","Public Timeline","Notifications"] + currentIndex: model.indexOf(globaloptions.defaultNewsTypes[index]) + onCurrentTextChanged: { + if (currentText !== globaloptions.defaultNewsTypes[index]){ + globaloptions.defaultNewsTypes.splice(index,1,currentText); + Service.updateglobaloptions(root.db,"defaultNewsTypes",globaloptions.defaultNewsTypes) + root.globaloptionsChanged() + } + } + } + } + } + + Column{ + visible: osSettings.osType=="Android" + x: root.fontFactor*osSettings.bigFontSize + y: 26*root.fontFactor*osSettings.bigFontSize + Label{ + text: qsTr("Dark Mode") + font.pointSize: osSettings.systemFontSize} + + RadioButton{ + text: qsTr("System") + checked: (globaloptions["view_darkmode"]==0 || globaloptions["view_darkmode"]==undefined)?true:false + font.pointSize: osSettings.bigFontSize + onClicked: { + if(checked==true){ + Service.updateglobaloptions(root.db,"view_darkmode",0); + root.Material.theme=Material.System + } + } + } + RadioButton{ + text: qsTr("Dark") + checked: (globaloptions["view_darkmode"]==1)?true:false + font.pointSize: osSettings.bigFontSize + onClicked: { + if(checked==true){ + Service.updateglobaloptions(root.db,"view_darkmode",1); + root.Material.theme=Material.Dark + } + } + } + RadioButton{ + text: qsTr("Light") + checked: (globaloptions["view_darkmode"]==2)?true:false + font.pointSize: osSettings.bigFontSize + onClicked: { + if(checked==true){ + Service.updateglobaloptions(root.db,"view_darkmode",2); + root.Material.theme=Material.Light + } + } + } + } + + + + + MButton { + anchors.right: parent.right; anchors.rightMargin: root.fontFactor*osSettings.bigFontSize; + anchors.top: parent.top + anchors.topMargin: 3*root.fontFactor*osSettings.bigFontSize + //width: 2*root.fontFactor*osSettings.bigFontSize; + text: "?" + font.pointSize: osSettings.bigFontSize + onClicked:{ + rootstackView.push("qrc:/qml/configqml/InfoBox.qml"); + } + } + } +// MButton{ +// id:closeButton +// // height: 2*root.fontFactor*osSettings.bigFontSize +// width: 2*root.fontFactor*osSettings.bigFontSize; +// anchors.top: parent.top +// anchors.topMargin:root.fontFactor*osSettings.bigFontSize +// anchors.right: parent.right +// anchors.rightMargin: 1*mm +// text: "\uf057" +// font.pointSize: osSettings.bigFontSize +// onClicked:{rootstackView.pop()} +// } +} diff --git a/src/qml/configqml/ConfigPage.qml b/src/qml/configqml/ConfigPage.qml new file mode 100644 index 0000000..5e4b27b --- /dev/null +++ b/src/qml/configqml/ConfigPage.qml @@ -0,0 +1,129 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Layouts +import QtQuick.Controls 6.3 +import "qrc:/js/service.js" as Service +import "qrc:/qml/configqml" +import "qrc:/qml/genericqml" + +Page{ + //anchors.fill: parent + width:root.width + height:root.height + + TabBar { + id: configbar + width: parent.width-3*root.fontFactor*osSettings.bigFontSize//osSettings.osType=="Android"?parent.width-3*root.fontFactor*osSettings.bigFontSize:parent.width + height: 2*root.fontFactor*osSettings.bigFontSize + x: osSettings.osType=="Android"?2*osSettings.bigFontSize:0 + //visible: !wideScreen + position:TabBar.Header + currentIndex: 0 + TabButton { + text: qsTr("Appearance") + font.pointSize: osSettings.systemFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + width:6*root.fontFactor*osSettings.bigFontSize + } + TabButton { + text: qsTr("Sync") + font.pointSize: osSettings.systemFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + width:10*root.fontFactor*osSettings.bigFontSize + } +// TabButton { +// text: qsTr("Start") +// visible:osSettings.osType=="Linux" +// font.pointSize: osSettings.systemFontSize +// height: 2*root.fontFactor*osSettings.bigFontSize +// width:10*root.fontFactor*osSettings.bigFontSize +// } + } + + LeftDrawerLinux{ + id:leftDrawer + visible: wideScreen&&rootstackView.depth<2 + width: visible?osSettings.systemFontSize*15:0 + height: root.height-bar.height + } + + LeftDrawerAndroid{ + id: leftDrawerAndroid + } + + StackLayout{ + id:configTabView + width: wideScreen&&rootstackView.depth<2?parent.width-leftDrawer.width-mm:parent.width-mm//newstabitem.width/3*2:newstabitem.width + x: leftDrawer.width + y: configbar.height + height: parent.height-configbar.height-mm + currentIndex: configbar.currentIndex +// onCurrentIndexChanged:{ +// if (currentIndex==1){ +// contactsSignal("") +// } +// else if (currentIndex==2){ +// contactsSignal("") +// } +// else if (currentIndex==3){groupsSignal(root.login.username)} +// } + + Loader{ + id: appearanceLoader + source:(configTabView.currentIndex==0)? "qrc:/qml/configqml/ConfigAppearancePage.qml":"" + } + + Loader{ + id: syncLoader + source:(configTabView.currentIndex==1)? "qrc:/qml/configqml/SyncConfig.qml":"" + } + +// Loader{ +// id: startLoader +// source:(configTabView.currentIndex==2)? "qrc:/qml/configqml/ConfigStartPage.qml":"" +// } + } + MButton{ + id:closeButton + anchors.top: parent.top + anchors.topMargin:2*root.fontFactor*osSettings.bigFontSize + anchors.right: parent.right + anchors.rightMargin: root.fontFactor*osSettings.bigFontSize + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + font.pointSize: osSettings.bigFontSize + onClicked:{rootstackView.pop()} + } +} diff --git a/src/qml/configqml/ConfigStartPage.qml b/src/qml/configqml/ConfigStartPage.qml new file mode 100644 index 0000000..123b786 --- /dev/null +++ b/src/qml/configqml/ConfigStartPage.qml @@ -0,0 +1,80 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 + +Page{ + //anchors.fill: parent + width:root.width + height:root.height-6*root.fontFactor*osSettings.bigFontSize + + CheckBox{ + id: autostartCheckbox + x: mm + y: root.fontFactor*osSettings.bigFontSize + width: 10*root.fontFactor*osSettings.bigFontSize + checked:filesystem.isAutostart + //style: CheckBoxStyle { + text: qsTr("Autostart") + font.pointSize: osSettings.bigFontSize + onClicked: { + toggle(); + if(autostartCheckbox.checked==true){ + filesystem.setAutostart(false); + autostartCheckbox.checked=false; + } + else{ + filesystem.setAutostart(true); + autostartCheckbox.checked=true; + } + } + } +// CheckBox{ +// id: minimizeCheckbox +// x: mm +// y: 3*root.fontFactor*osSettings.bigFontSize +// width: 10*root.fontFactor*osSettings.bigFontSize +// enabled: autostartCheckbox.checked==true +// checked:(globaloptions["notify_"+adapter]==1)?true:false +// text: qsTr("Start Minimized") +// font.pointSize: osSettings.bigFontSize +// 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/InfoBox.qml b/src/qml/configqml/InfoBox.qml similarity index 87% rename from source-linux/qml/configqml/InfoBox.qml rename to src/qml/configqml/InfoBox.qml index aa65121..354b74b 100644 --- a/source-linux/qml/configqml/InfoBox.qml +++ b/src/qml/configqml/InfoBox.qml @@ -29,29 +29,26 @@ // 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 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/genericqml" Page{ - //color:"white" - // width:infoBoxText.contentWidth - // height:infoBoxText.contentHeight Text{id:infoBoxText anchors.top:closeButton.bottom anchors.topMargin: mm textFormat: Text.RichText width: root.width-mm font.pointSize: osSettings.systemFontSize + color: osSettings.primaryTextColor wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: "Friendiqa v0.6.1
Licensed under GPL 3 with the exception of OpenSSL
"+ + text: "Friendiqa v0.6.9
Licensed under GPL 3 with the exception of OpenSSL
"+ "Website https://friendiqa.ma-nic.de
"+ "Sourcecode: https://git.friendi.ca/LubuWest/Friendiqa
"+ "Privacy Policy: http://git.friendi.ca/lubuwest/Friendiqa/src/branch/master/PrivacyPolicy.md
"+ "Code by Marco
"+ "Qt Framework www.qt.io
"+ - "Icons by FontAwesome
"+ - "Folder Icon by KDE Breeze Icons
"+ + "Icons by Fork Awesome
"+ "AndroidNative by Ben Lau
"+ "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/)" onLinkActivated:{ @@ -63,8 +60,10 @@ Page{ anchors.topMargin: root.fontFactor*osSettings.bigFontSize anchors.right: parent.right anchors.rightMargin: 1*mm - text: "\uf057" - font.pointSize: osSettings.bigFontSize + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" onClicked:{rootstackView.pop()} } } diff --git a/src/qml/configqml/LeftDrawerScrollview.qml b/src/qml/configqml/LeftDrawerScrollview.qml new file mode 100644 index 0000000..dd69727 --- /dev/null +++ b/src/qml/configqml/LeftDrawerScrollview.qml @@ -0,0 +1,141 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import "qrc:/qml/genericqml" +import "qrc:/js/service.js" as Service + +ScrollView{ + id:leftDrawerScrollviewId + clip: true + width:parent.width-mm + height: parent.height + contentHeight: leftDrawerColumn.height + property string currentnewstabstatus:root.globaloptions.hasOwnProperty("newsViewType")?root.globaloptions.newsViewType:"Conversations"; + + function initialize(){ + accountModel.clear(); + Service.readAllLogins(db,function(accounts){ + if (accounts.length>0 && bar.currentIndex==0){ + leftDrawerColumn.height=6.5*root.fontFactor*osSettings.bigFontSize+accounts.length*17*root.fontFactor*osSettings.bigFontSize + for(var account in accounts) { + accountModel.append({"account":accounts[account]}) + } + }else if(accounts.length>0 && bar.currentIndex==1){ + leftDrawerColumn.height=6.5*root.fontFactor*osSettings.bigFontSize+accounts.length*8*root.fontFactor*osSettings.bigFontSize + for(var account in accounts) { + accountModel.append({"account":accounts[account]}) + } + } + }) + } + + Column{ + id:leftDrawerColumn + x:mm + y:0.5*root.fontFactor*osSettings.bigFontSize + width:leftDrawerScrollviewId.width-2*mm + height: 4*root.fontFactor*osSettings.bigFontSize + spacing: 0.7*root.fontFactor*osSettings.bigFontSize + + ToolButton{ + font.pointSize: osSettings.systemFontSize + text: qsTr("Settings") + icon.name: "settings-configure" + icon.source: "qrc:/assets/icons/cogs.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize +// background: Rectangle{color: osSettings.dialogColor; +// radius: 0.5*mm} + onClicked:{ + rootstackView.push("qrc:qml/configqml/ConfigPage.qml"); + if(!wideScreen){leftDrawerAndroid.close()} + } + } + ToolButton{ + y:2*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + text: qsTr("Accounts") + icon.name: "addressbook-details" + icon.source: "qrc:/assets/icons/address-card.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize +// background: Rectangle{color: osSettings.dialogColor; +// radius: 0.5*mm} + onClicked:{ + rootstackView.push("qrc:qml/configqml/AccountPage.qml"); + if(!wideScreen){leftDrawerAndroid.close()} + } + } + ToolButton{ + y:4*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + text: qsTr("Quit") + icon.name: "system-log-out-symbolic" + icon.source: "qrc:/assets/icons/sign-out.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize +// background: Rectangle{color: osSettings.dialogColor; +// radius: 0.5*mm} + onClicked:{ + Service.cleanNews(root.db,function(){ + Service.cleanHashtags(root.db,function(){ + Service.cleanContacts(root.login,root.db,function(){ + Qt.quit()}) + })}) + } + } + ListModel{id:accountModel} + Component{id:accountLoader + Loader{ + source: bar.currentIndex==0?"qrc:/qml/genericqml/DrawerAccountComponent.qml":"qrc:/qml/genericqml/DrawerAccountComponentContacts.qml" + } + } + ListView{ + id:accountList + y: 6.5*root.fontFactor*osSettings.bigFontSize + width:leftDrawerColumn.width + height: contentHeight + model: accountModel + delegate: accountLoader + } + } + + Connections{ + target: root + function onLoginChanged(){ + initialize() + } + } + + Component.onCompleted:{initialize()} +} diff --git a/source-linux/qml/configqml/OSSettingsAndroid.qml b/src/qml/configqml/OSSettingsAndroid.qml similarity index 71% rename from source-linux/qml/configqml/OSSettingsAndroid.qml rename to src/qml/configqml/OSSettingsAndroid.qml index 4c5b9de..19515ac 100644 --- a/source-linux/qml/configqml/OSSettingsAndroid.qml +++ b/src/qml/configqml/OSSettingsAndroid.qml @@ -30,17 +30,41 @@ // along with this program. If not, see . import QtQuick.Window 2.0 -import QtQuick 2.0 +import QtQuick 6.3 +import QtQuick.Controls.Material 6.3 + QtObject{ property int appWidth: Screen.desktopAvailableWidth property int appHeight: Screen.desktopAvailableHeight property int backKey: Qt.Key_Back //property string attachImageDir:filesystem.cameraPath+"/" property string osType: "Android" + property int systemFontSize: root.font.pointSize*1.1 property int bigFontSize: systemFontSize*1.3 property string imagePickQml: "ImagePicker" - property string imagePicker:'import QtQuick 2.0; import "qrc:/qml/genericqml";'+ + property string imagePicker:'import QtQuick 6.3; import "qrc:/qml/genericqml";'+ imagePickQml+'{multiple : true;onReady: {attachImageURLs.push(imageUrl);'+ 'attachImage(imageUrl)}}' + + Material.theme: Material.System + property color backgroundColor: Material.backgroundColor + property color backgroundDimColor:Material.backgroundDimColor + property color primaryTextColor: Material.primaryTextColor + property color secondaryTextColor: Material.secondaryTextColor + property color dialogColor: Material.dialogColor + property color accentColor: Material.accentColor + property color buttonColor: Material.buttonColor + + function setTheme(theme){ + if (theme=="system"){ + Material.theme=Material.System + } + else if (theme=="dark"){ + Material.theme=Material.Dark + } + else if (theme=="light"){ + Material.theme=Material.Light + } + } } diff --git a/src/qml/configqml/OSSettingsLinux.qml b/src/qml/configqml/OSSettingsLinux.qml new file mode 100644 index 0000000..4b4a624 --- /dev/null +++ b/src/qml/configqml/OSSettingsLinux.qml @@ -0,0 +1,67 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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.Window 2.0 +import QtQuick 6.3 +import QtQuick.Controls 6.3 + +//QtObject{ +Item{ + property real appWidth: Screen.desktopAvailableWidth/4*3 + property real appHeight: Screen.desktopAvailableHeight/4*3 + property int backKey: Qt.Key_Escape + property string osType: "Linux" + property int systemFontSize: root.font.pointSize*1.1 + property int bigFontSize: systemFontSize*1.5 + //property string attachImageDir:filesystem.homePath+"/Pictures/" + property string imagePickQml: "ImagePickerLinux" + SystemPalette { id: myPalette; colorGroup: SystemPalette.Active } + property color backgroundColor: myPalette.window + property color backgroundDimColor: myPalette.button + property color primaryTextColor: myPalette.windowText + property color secondaryTextColor: myPalette.buttonText + property color dialogColor: myPalette.base + property color accentColor: myPalette.highlight + property color buttonColor: myPalette.button + property color buttonText: myPalette.buttonText + + function setTheme(theme){ + if (theme=="system"){ + //Material.theme=Material.System + } + else if (theme=="dark"){ + //Material.theme=Material.Dark + } + else if (theme=="light"){ + //Material.theme=Material.Light + } + } +} diff --git a/source-linux/qml/configqml/SyncComponent.qml b/src/qml/configqml/SyncComponent.qml similarity index 97% rename from source-linux/qml/configqml/SyncComponent.qml rename to src/qml/configqml/SyncComponent.qml index c20055f..f58fa14 100644 --- a/source-linux/qml/configqml/SyncComponent.qml +++ b/src/qml/configqml/SyncComponent.qml @@ -30,13 +30,13 @@ // along with this program. If not, see . -import QtQuick 2.11 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/configqml" import "qrc:/js/service.js" as Service Rectangle{ - color: "#EEEEEE" //Material.Grey + color: osSettings.dialogColor property string adapter: "" width: parent.width height: 4*root.fontFactor*osSettings.bigFontSize diff --git a/src/qml/configqml/SyncConfig.qml b/src/qml/configqml/SyncConfig.qml new file mode 100644 index 0000000..d23542f --- /dev/null +++ b/src/qml/configqml/SyncConfig.qml @@ -0,0 +1,75 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import "qrc:/qml/configqml" +import "qrc:/qml/genericqml" +import "qrc:/js/service.js" as Service + +Page{ + width:root.width + height: root.height + + Switch{ + x:root.fontFactor*osSettings.bigFontSize; + y: root.fontFactor*osSettings.bigFontSize; + font.pointSize: osSettings.bigFontSize + checked: globaloptions.hasOwnProperty("syncinterval")?(globaloptions.syncinterval>0):0 + text: qsTr("Backgound Sync") + onToggled: { + if(checked){ + alarm.setAlarm(15); + Service.updateglobaloptions(root.db,"syncinterval",15); + } else { + alarm.setAlarm(0); + Service.updateglobaloptions(root.db,"syncinterval",0); + } + } + } + + ScrollView{ + width: root.width + height: root.height - 10*root.fontFactor*osSettings.bigFontSize; + y:4*root.fontFactor*osSettings.bigFontSize + clip:true + Column{ + width: parent.width + spacing:mm + SyncComponent{adapter:"Timeline"} + SyncComponent{adapter:"Replies"} + SyncComponent{ adapter:"DirectMessages"} + SyncComponent{ adapter:"Notifications"} + SyncComponent{ adapter: "Events"} + SyncComponent{adapter: "FriendRequests"} + } + } +} diff --git a/source-linux/qml/contactqml/Contactlist.qml b/src/qml/contactqml/Contactlist.qml similarity index 94% rename from source-linux/qml/contactqml/Contactlist.qml rename to src/qml/contactqml/Contactlist.qml index 576d990..8c0b2cb 100644 --- a/source-linux/qml/contactqml/Contactlist.qml +++ b/src/qml/contactqml/Contactlist.qml @@ -30,8 +30,8 @@ // along with this program. If not, see . // List of people -import QtQuick 2.0 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" @@ -74,7 +74,7 @@ Rectangle { width: 5*mm height:5*mm source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url - onStatusChanged: if (contactImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + onStatusChanged: if (contactImage.status == Image.Error) {source="qrc:/assets/defaultcontact.jpg"} } Text{ font.pointSize: osSettings.bigFontSize @@ -116,8 +116,10 @@ Rectangle { anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm - //color:"white" - text: "\uf057" + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" onClicked: { groupModelAppend(contacts,function(){ contactlistRectangle.destroy() diff --git a/src/qml/contactqml/ContactsSearchPage.qml b/src/qml/contactqml/ContactsSearchPage.qml new file mode 100644 index 0000000..d2a3689 --- /dev/null +++ b/src/qml/contactqml/ContactsSearchPage.qml @@ -0,0 +1,183 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import QtQuick.Layouts +import QtQuick.LocalStorage 2.0 +import "qrc:/js/helper.js" as Helperjs +import "qrc:/js/service.js" as Service +import "qrc:/js/news.js" as Newsjs +import "qrc:/qml/contactqml" +import "qrc:/qml/genericqml" + +Item{ + id: contactsSearchPage + //background: Rectangle{color: osSettings.dialogColor; radius: 0.5*mm} + + function search(term){ + contactSearchBusy.running=true; + try {contactsSearchModel.clear()} catch(e){}; + xhr.setAccount(login); + xhr.setApi("/api/v1/accounts/search"); + xhr.setParam("q",term); + xhr.setParam("limit",99) + xhr.get(); + } + + Connections{ + target:xhr + function onError(data,url,api,code){ + if (data !="contactlist"){Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root);} + contactSearchBusy.running=false; + } + function onSuccess(data,api){ + if (api=="/api/v1/accounts/search" && data!=""){ + try{var searchlist = JSON.parse(data);}catch(e){print("Error "+e)} + contactSearchBusy.running=false; + if (Array.isArray(searchlist)){ + searchlist.sort(function(a,b){ + if (a.group > b.group) { + return -1; + } + if (a.group < b.group) { + return 1; + } + return 0 + }) + for (let i=0;i +// +// 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 6.3 +import QtQuick.Controls 6.3 +import QtQuick.Layouts +import QtQuick.LocalStorage 2.0 +import "qrc:/js/helper.js" as Helperjs +import "qrc:/js/news.js" as Newsjs +import "qrc:/qml/contactqml" +import "qrc:/qml/genericqml" + +Item{ + id: friendsGridTab + Layout.fillWidth:true + Layout.fillHeight: true + property int currentContact: 0 + signal contactRefreshSignal() + + function showFriends(username){ + try {friendsModel.clear()} catch(e){}; + Helperjs.readData(db,"friendshiprequests",username,function(friendrequestsobject){ + for (var i=0;i1){ + friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid + } + friendsModel.append({"contact":friendsobject[i],"contactType":qsTr("Friends")}); + } + },(searchText.text==""?searchText.preeditText:searchText.text)); + } + + function showContacts(contact){ + try {friendsModel.clear()} catch(e){}; + Newsjs.listFriends(login,db,function(contactsobject){ + for (var j=0;j1){ + contactsobject[j].screen_name=contactsobject[j].screen_name+"+"+contactsobject[j].cid + } + friendsModel.append({"contact":contactsobject[j]}); + } + },searchText.text,-1); + } + + function showBlocked(contact){ + try {friendsModel.clear()} catch(e){}; + Newsjs.listBlocked(login,db,function(contactsobject){ + for (var j=0;j1){ + contactsobject[j].screen_name=contactsobject[j].screen_name+"+"+contactsobject[j].cid + } + friendsModel.append({"contact":contactsobject[j]}); + } + }); + } + + Connections{ + target:xhr + function onDownloaded(type,url,filename,i){ + if(type=="contactlist"){ + friendsGridTab.currentContact=i+1; + if(friendsGridTab.currentContact==root.newContacts.length){ + friendsGridTab.showFriends(root.login.username) + } + } + } + } + + MButton { + id: updateFriendsButton + height: friendsCombo.height + text: qsTr("refresh") + display: AbstractButton.IconOnly + icon.name: "view-refresh-symbolic" + icon.source: "qrc:/assets/icons/refresh.svg" + anchors.top: parent.top + anchors.topMargin: mm + anchors.left: friendsCombo.right + anchors.leftMargin: root.fontFactor*osSettings.systemFontSize + onClicked: { + try {friendsModel.clear()} catch(e){print(e)}; + Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){}); + updatenews.setDatabase(); + updatenews.login(); + updatenews.setSyncAll(false); + updatenews.friendrequests(); + //root.contactLoadType="friends"; + Newsjs.requestFriends(root.login,db,root,function(nc){ + root.newContacts=nc + root.onNewContactsChanged(nc); + }) + } + } + + ProgressBar{ + id: newContactsProgress + width: friendsView.width + height: 2*mm + x: mm + y: 3.5*root.fontFactor*osSettings.bigFontSize + visible: (friendsGridTab.currentContact!=(root.newContacts.length))?true:false + value: friendsGridTab.currentContact/root.newContacts.length + } + + ComboBox{ + id: friendsCombo + x: mm + y: mm + width: 6*root.fontFactor*osSettings.bigFontSize + height: 1.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + model: [qsTr("Friends"), qsTr("All"), qsTr("Blocked")] + onCurrentIndexChanged:{ + if (currentIndex === 0) { + showFriends(root.login.username); + } else + if (currentIndex===1){ + showContacts() + } else if (currentIndex===2){ + showBlocked() + } + } + Component.onCompleted: {root.contactRefreshSignal.connect(onCurrentIndexChanged)} + } + + Rectangle { + id:searchComponent + anchors.top: friendsCombo.bottom + anchors.topMargin: mm + x: mm + //color: osSettings.backgroundColor + radius:0.5*mm + width: 10*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + TextField { + id: searchText + //color: osSettings.primaryTextColor + focus: true + font.pointSize: osSettings.systemFontSize + wrapMode: Text.Wrap + anchors.fill:parent + selectByMouse: true + cursorVisible: false + onTextChanged: {showFriends(root.login.username)}//if (text.length>0) + onPreeditTextChanged: {{showFriends(root.login.username)}}//if (preeditText.length>0) + Image{ + source: "qrc:/assets/icons/filter.svg" + width: root.fontFactor*osSettings.bigFontSize + height: root.fontFactor*osSettings.bigFontSize + visible: searchText.text=="" + } + } + } + + Component { + id: sectionHeading + Rectangle { + width: friendsView.width + height: childrenRect.height + color: osSettings.backgroundColor + required property string section + Text { + color: osSettings.secondaryTextColor + text: parent.section + font.bold: true + font.pointSize: osSettings.bigFontSize + } + } + } + + Component { id:headerComponent + ToolButton{ + height: 2*root.fontFactor*osSettings.bigFontSize + width:friendsView.width + icon.name:"list-add-user-symbolic" + icon.source: "qrc:/assets/icons/user-plus.svg" + icon.width: 2*root.fontFactor*osSettings.bigFontSize + icon.height: 2*root.fontFactor*osSettings.bigFontSize + onClicked:{ + rootstackView.push("qrc:/qml/contactqml/ContactsSearchPage.qml") + } + } + } + + ListView{ + id: friendsView + x:mm + y: 3.5*root.fontFactor*osSettings.bigFontSize+3*mm + width:friendsGridTab.width-2*mm + height:friendsGridTab.height-(updateFriendsButton.height+10*mm) + clip: true + spacing: 2 + function processContactSelection(contactobject){showContactdetails(contactobject)} + model: friendsModel + delegate: ContactComponent { } + header:headerComponent + section.property: "contactType" + section.criteria: ViewSection.FullString + section.delegate: sectionHeading + } + ListModel{id:friendsModel} + + Component.onCompleted: { + root.friendsSignal.connect(showFriends); + friendsTabView.contactsSignal.connect(showFriends); + showFriends(root.login.username); + root.newContacts=[] + } +} diff --git a/source-linux/qml/contactqml/FriendsTab.qml b/src/qml/contactqml/FriendsTab.qml similarity index 67% rename from source-linux/qml/contactqml/FriendsTab.qml rename to src/qml/contactqml/FriendsTab.qml index dbf794c..f964c4f 100644 --- a/source-linux/qml/contactqml/FriendsTab.qml +++ b/src/qml/contactqml/FriendsTab.qml @@ -29,9 +29,9 @@ // 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.12 -import QtQuick.Layouts 1.11 +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import QtQuick.Layouts import QtQuick.LocalStorage 2.0 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs @@ -41,61 +41,55 @@ import "qrc:/qml/genericqml" Rectangle { y:1 - color: "white" - + color: osSettings.backgroundColor function showContactdetails(contact){ -// rootstack.currentIndex=0; -// bar.currentIndex=0; root.contactdetailsSignal(contact) } - BlueButton{ - x:mm - y:mm + ToolButton{ + id:menuButton z:2 + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: friendsbar.height visible: !wideScreen - fontColor: "grey" - border.color: "transparent" - text: "\uf0c9" - font.pointSize: osSettings.bigFontSize + icon.name: "application-menu" + icon.source: "qrc:/assets/icons/bars.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize onClicked:{ leftDrawerAndroid.visible?leftDrawerAndroid.close():leftDrawerAndroid.open()} } TabBar { - id: friendsbar - width: osSettings.osType=="Android"?parent.width-2*osSettings.bigFontSize:parent.width - height: 9*mm - x: osSettings.osType=="Android"?2*osSettings.bigFontSize:0 - visible: !wideScreen - position:TabBar.Header - currentIndex: 1 - TabButton { - text: qsTr("Me") - font.pointSize: osSettings.systemFontSize - height: 7*mm - } - TabButton { - text: qsTr("Friends") - font.pointSize: osSettings.systemFontSize - height: 7*mm - } - TabButton { - text: qsTr("Contacts") - font.pointSize: osSettings.systemFontSize - height: 7*mm - } - TabButton { - text: qsTr("Groups") - font.pointSize: osSettings.systemFontSize - height: 7*mm - } + id: friendsbar + width: osSettings.osType=="Android"?parent.width-2*root.fontFactor*osSettings.bigFontSize:parent.width + height: 2*root.fontFactor*osSettings.bigFontSize + x: osSettings.osType=="Android"?2*root.fontFactor*osSettings.bigFontSize:0 + visible: !wideScreen + position:TabBar.Header + currentIndex: 1 + TabButton { + text: qsTr("Me") + font.pointSize: osSettings.systemFontSize + height: 1.7*root.fontFactor*osSettings.bigFontSize + } + TabButton { + text: qsTr("Friends") + font.pointSize: osSettings.systemFontSize + height: 1.7*root.fontFactor*osSettings.bigFontSize + } + TabButton { + text: qsTr("Circles") + font.pointSize: osSettings.systemFontSize + height: 1.7*root.fontFactor*osSettings.bigFontSize + } } LeftDrawerLinux{ id:leftDrawer visible: wideScreen&&rootstackView.depth<2 - width: visible?osSettings.systemFontSize*15:0 + width: visible?root.fontFactor*osSettings.systemFontSize*15:0 height: root.height-bar.height } @@ -105,7 +99,6 @@ Rectangle { StackLayout{ id:friendsTabView - //anchors.fill: parent width: wideScreen&&rootstackView.depth<2?parent.width-leftDrawer.width-mm:parent.width-mm//newstabitem.width/3*2:newstabitem.width x: leftDrawer.width y: friendsbar.visible?friendsbar.height:0 @@ -118,10 +111,7 @@ Rectangle { if (currentIndex==1){ contactsSignal("") } - else if (currentIndex==2){ - contactsSignal("") - } - else if (currentIndex==3){groupsSignal(root.login.username)} + else if (currentIndex==2){groupsSignal(root.login.username)} } Loader{ @@ -134,17 +124,9 @@ Rectangle { source:(friendsTabView.currentIndex==1)? "qrc:/qml/contactqml/FriendsListTab.qml":"" } - Loader{ - id: contactsListLoader - source:(friendsTabView.currentIndex==2)? "qrc:/qml/contactqml/ContactsListTab.qml":"" - } - Loader{ id: groupsListLoader - source:(friendsTabView.currentIndex==3)? "qrc:/qml/contactqml/GroupsListTab.qml":"" + source:(friendsTabView.currentIndex==2)? "qrc:/qml/contactqml/GroupsListTab.qml":"" } } - Component.onCompleted: { - //root.contactdetailsSignal.connect(showContactdetails); - } } diff --git a/src/qml/contactqml/GroupComponent.qml b/src/qml/contactqml/GroupComponent.qml new file mode 100644 index 0000000..5988610 --- /dev/null +++ b/src/qml/contactqml/GroupComponent.qml @@ -0,0 +1,162 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import "qrc:/js/helper.js" as Helperjs +import "qrc:/js/news.js" as Newsjs +import "qrc:/qml/genericqml" + +Item { + id: groupComponent + height: 5*root.fontFactor*osSettings.bigFontSize//8*mm + width: groupComponent.ListView.view.width + property var groupmembers:[] + //property bool newGroup: false + function groupModelAppend(groupcontacts,callback){ + for (var n in groupcontacts){ + groupModel.append({"groupmember":groupcontacts[n]});} + callback() + } + + Rectangle { + id: wrapper + x:0.5*mm + y:0.5*mm + width:parent.width-mm + height: parent.height-mm + radius: 0.5*mm + border.color: "grey" + color:osSettings.backgroundColor + + Rectangle{ + id:namelabelRect + x: 1 + y: 1 + width: wrapper.width-2 + height: 3*root.fontFactor*osSettings.bigFontSize + //border.color: "light grey" + color: osSettings.backgroundColor + TextInput { + id: namelabel + anchors.fill: parent + readOnly: true + text: group.new?"":group.groupname + color: osSettings.secondaryTextColor//"#303030" + font.pointSize: osSettings.bigFontSize + } + } + + MButton{ + id: closeButton + visible: false + anchors.right: parent.right + anchors.margins: mm + anchors.top: parent.top + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + font.pointSize: osSettings.bigFontSize + onClicked:{groupComponent.state=""; + if (group.new){groupsModel.remove(index)} + } + } + + MButton{ + id:infobutton + text: qsTr("Members") + display: AbstractButton.IconOnly + icon.name: "usermenu-down" + icon.source: "qrc:/assets/icons/times-circle.svg" + font.pointSize: osSettings.bigFontSize + anchors.right: parent.right + anchors.rightMargin: mm + anchors.topMargin: mm + anchors.top: parent.top + onClicked:{ + groupComponent.state="large"; + //if(group.new){ + Helperjs.readField("members",root.db,"groups",root.login.username,function(groups){ + try {groupModel.clear()}catch (e){print(e)} + groupmembers=JSON.parse(groups); + for (var user in groupmembers){ + Helperjs.readData(root.db,"contacts",root.login.username,function(userdata){ + if (userdata[0]){ + userdata[0].name=Qt.atob(userdata[0].name); + userdata[0].description=Qt.atob(userdata[0].description) + //groupModel.append({"groupmember":userdata[0] + groupModel.append({"contact":userdata[0] + })} + },"id",groupmembers[user]) + } //catch(e){} + },"groupname",group.groupname); + //} + + } + } + + Rectangle{ + id: detailsrectangle + anchors.top: namelabelRect.bottom + color: osSettings.backgroundColor + //anchors.topMargin: mm + x:mm + width: parent.width-2*mm + height:parent.height -(3*root.fontFactor*osSettings.bigFontSize+mm) + visible: false + + ListView{ + id: groupListView + anchors.fill: parent + anchors.margins: mm + clip: true + spacing: 2 + model: groupModel + delegate: ContactComponent { }// groupMember + function processContactSelection(contactobject){showContactdetails(contactobject)} + } + ListModel{id: groupModel} + } + Component.onCompleted:{if(group.new){groupComponent.state="large"}} + } + + states: [ + State { + name: "large" + PropertyChanges { target: groupComponent; height: groupsView.height - 6*root.fontFactor*osSettings.bigFontSize } + PropertyChanges { target: namelabel; font.pointSize: 1.2*osSettings.bigFontSize; readOnly:false} + PropertyChanges { target: closeButton; visible: true} + PropertyChanges { target: detailsrectangle; visible:true } + PropertyChanges { target: infobutton; visible: false} + } + ] +} diff --git a/source-linux/qml/contactqml/GroupsListTab.qml b/src/qml/contactqml/GroupsListTab.qml similarity index 56% rename from source-linux/qml/contactqml/GroupsListTab.qml rename to src/qml/contactqml/GroupsListTab.qml index e19cbe1..eaf754c 100644 --- a/source-linux/qml/contactqml/GroupsListTab.qml +++ b/src/qml/contactqml/GroupsListTab.qml @@ -29,9 +29,8 @@ // 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.12 -//import QtQuick.Layouts 1.11 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import QtQuick.LocalStorage 2.0 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs @@ -45,20 +44,16 @@ Item{ function showGroups(username){ try {groupsModel.clear()} catch(e){print(e)}; Helperjs.readData(db, "groups",root.login.username,function(groupsobject){ - for (var j=0;j. -import QtQuick 2.0 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/genericqml" import "qrc:/js/service.js" as Service @@ -38,15 +38,14 @@ Rectangle { // width:parent.width-2*mm // height:parent.height-14*mm anchors.fill:parent - color:"white" + color: osSettings.backgroundColor property var profile:({}) property var attachImageURLs:[] property var createdAtDate: new Date(profile.friendica_owner.created_at) function updateProfileImage(){ - xhr.url= login.server + "/api/account/update_profile_image.json"; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.clearParams(); + xhr.setAccount(login); + xhr.setApi("/api/account/update_profile_image.json"); xhr.setImageFileParam("image", photoImage.source ); xhr.post(); } @@ -54,7 +53,7 @@ Rectangle { function buildProfiletext(pobject,callback){ var profileobject={}; var profiletext=""; - for (var key in pobject){//print(key+obj[key]) + for (var key in pobject){ if(pobject[key]!=""&&pobject[key]!=null&&key!="users"&&key!="profile_id"){ var keytext=""; switch(key){ @@ -95,9 +94,19 @@ Rectangle { case "education":keytext=qsTr("education");break; case "social_networks":keytext=qsTr("social networks");break; case "homepage":keytext=qsTr("homepage");break; + case "custom_fields":keytext=qsTr("other");break; default:keytext=key; } - profiletext=profiletext+(""+keytext+": "+(pobject[key])+"
"); + if (key=="custom_fields"){ + var customObject=pobject[key]; + for (var customkey in customObject){ + profiletext=profiletext+(""+customObject[customkey].label+": "+(customObject[customkey].value)+"
");} + }else if(key=="homepage" || key=="profile_photo" || key=="profile_thumb"){ + profiletext=profiletext+(""+keytext+": "+(pobject[key])+"
"); + } + else{ + profiletext=profiletext+(""+keytext+": "+(pobject[key])+"
"); + } } } callback(profiletext) @@ -108,7 +117,11 @@ Rectangle { anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right - text: "\uf021" + anchors.rightMargin: menuButton.width + text: qsTr("refresh") + display: AbstractButton.IconOnly + icon.name: "view-refresh-symbolic" + icon.source: "qrc:/assets/icons/refresh.svg" font.pointSize: osSettings.bigFontSize onClicked: { Service.requestProfile(root.login,root.db,root,function(nc){ @@ -141,39 +154,48 @@ Rectangle { width: 15*mm height:15*mm source: "file://"+profile.friendica_owner.profile_image - onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/assets/defaultcontact.jpg"} MouseArea{ anchors.fill: parent onClicked:{ imagePicking=true; - var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ + var imagePicker = Qt.createQmlObject('import QtQuick 6.3; import "qrc:/qml/genericqml";'+ osSettings.imagePickQml+'{multiple: false;onReady: {photoImage.source=imageUrl;'+ '}}',profileTab,"imagePicker"); imagePicker.pickImage() } } } - Rectangle{ - id:phototextRectangle - color:"black" - z:3 - opacity: 0.5 - width:6*mm - height: phototext.contentHeight - anchors.top: photoImage.top - anchors.right: photoImage.right - } - Text { - id:phototext +// Rectangle{ +// id:phototextRectangle +// color:"black" +// z:3 +// opacity: 0.5 +// width:6*mm +// height: phototext.contentHeight +// anchors.top: photoImage.top +// anchors.right: photoImage.right +// } +// Text { +// id:phototext +// z:4 +// font.family: fontAwesome.name +// text: "\uf040" +// width:5*mm +// anchors.top: photoImage.top +// anchors.right:photoImage.right +// color: "white" +// font.pointSize: 1.2*osSettings.bigFontSize +// } + Image{ z:4 - text: "\uf040" - width:5*mm + source: "qrc:/assets/icons/pencil.svg" + width: root.fontFactor*osSettings.systemFontSize + height: root.fontFactor*osSettings.systemFontSize anchors.top: photoImage.top anchors.right:photoImage.right - color: "white" - font.pointSize: 1.2*osSettings.bigFontSize - } + } MButton{ id:updatebutton width: 8*root.fontFactor*osSettings.bigFontSize @@ -196,7 +218,7 @@ Rectangle { anchors.topMargin: 0 anchors.left: photoImage.left wrapMode: Text.Wrap - color: "#303030" + color: osSettings.secondaryTextColor font.pointSize: osSettings.bigFontSize anchors.top: photoImage.bottom } @@ -207,12 +229,13 @@ Rectangle { Rectangle{ id:profileRect width:profileView.width + color: osSettings.backgroundColor height: 5*mm+profiletextfield.height Text{ y:mm font.pointSize: osSettings.systemFontSize text:""+qsTr("profile id")+": "+profileid+"
" - color:"black" + color:osSettings.primaryTextColor } Text{ id:profiletextfield @@ -222,7 +245,8 @@ Rectangle { wrapMode: Text.Wrap font.pointSize: osSettings.systemFontSize text:profiletext - color:"black" + color: osSettings.primaryTextColor + onLinkActivated: Qt.openUrlExternally(link) } } } @@ -230,6 +254,7 @@ Rectangle { id:textcomponent Text{ id:namelabeltext + color: osSettings.primaryTextColor width: namelabelflickable.width height: implicitHeight font.pointSize: osSettings.bigFontSize diff --git a/source-linux/qml/contactqml/ProfileTab.qml b/src/qml/contactqml/ProfileTab.qml similarity index 94% rename from source-linux/qml/contactqml/ProfileTab.qml rename to src/qml/contactqml/ProfileTab.qml index e13cbf9..b16d7b5 100644 --- a/source-linux/qml/contactqml/ProfileTab.qml +++ b/src/qml/contactqml/ProfileTab.qml @@ -29,11 +29,8 @@ // 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.12 -//import QtQuick.Controls.Styles 1.4 -//import QtQuick.Layouts 1.11 -//import QtQuick.LocalStorage 2.0 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs import "qrc:/js/service.js" as Service diff --git a/src/qml/friendiqa.qml b/src/qml/friendiqa.qml new file mode 100644 index 0000000..59aef93 --- /dev/null +++ b/src/qml/friendiqa.qml @@ -0,0 +1,324 @@ +// 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 6.3 +import QtQuick.LocalStorage 2.0 +import QtQuick.Window 2.0 +import QtQuick.Controls 6.3 +import QtQuick.Layouts +import QSystemTrayIcon 1.0 +import "qrc:/js/news.js" as Newsjs +import "qrc:/js/service.js" as Service +import "qrc:/qml/genericqml" +import "qrc:/qml/configqml" + +ApplicationWindow{ + id:root + title: "Friendiqa" + property var globaloptions: Service.readGO(db) + property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettings"+filesystem.osType+".qml");return tmp.createObject(root)} + width: globaloptions.hasOwnProperty("appWidth")?globaloptions.appWidth:osSettings.appWidth + height:globaloptions.hasOwnProperty("appHeight")?globaloptions.appHeight:osSettings.appHeight + visible: filesystem.Visibility// true + property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000] + property var login: Service.readActiveConfig(db) + property real fontFactor: root.font.pixelSize/root.font.pointSize + property var contactlist: [] + property var conversation: [] + property real mm: osSettings.osType=="Android"?Screen.pixelDensity:Screen.pixelDensity*1.5 + property bool wideScreen : width>height + signal rootstackSignal(int pageindex) + signal fotoSignal(var username, var friend) + signal sendmessageSignal(string type, var newsitemobject) + signal newsSignal(var news) + signal newstypeSignal(var type) + signal friendsSignal(var username) + signal contactdetailsSignal(var contact) + signal contactRefreshSignal() + signal searchSignal (var searchterm) + signal eventSignal(var contact) + signal eventcreateSignal(var event) + signal uploadSignal(var urls) + signal sendtextSignal(var intenttext) + signal changeimage(var method, var type, var id) + signal updateSyncinterval(int interval) + signal replySignal(var newsobject) + property var news:[] + property var newContacts:[] + property var contactposts:[] + property bool imagePicking: false + + SystemPalette { id: myPalette; colorGroup: SystemPalette.Active } + property color backgroundColor: myPalette.window + + function onLoginChanged(login){ + if(login=="" || login==null){rootstackView.push("qrc:/qml/configqml/AccountPage.qml")} + else{if(rootstackView.depth<1){rootstackView.push("qrc:/qml/genericqml/RootStack.qml")} + // if (login.newsViewType!="" || login.newsViewType!=null){ + // newstab.newstabstatus=login.newsViewType;} + Newsjs.getCurrentContacts(login,db,function(contacts){ + contactlist=contacts}) + } + } + function onNewContactsChanged(newContacts){ + if(newContacts.length>0){// download contact images and update db + var contacturls=[]; + var contactnames=[]; + for (var link in newContacts){ + contacturls.push(newContacts[link].profile_image_url); + contactnames.push(newContacts[link].screen_name); + Service.updateContactInDB(login,db,newContacts[link].isFriend,newContacts[link]) + contactlist.push(newContacts[link].url); + } + xhr.setDownloadtype("contactlist"); + xhr.setFilelist(contacturls); + xhr.setContactlist(contactnames); + xhr.setImagedir(login.imagestore); + xhr.getlist(); + } + } + + function showContact(contact){ + rootstackView.push("qrc:/qml/newsqml/ContactPage.qml",{"contact": contact}) + } + + Connections { + target: root + function onWidthChanged(appWidth) { + if(osSettings.osType=="Linux" && Math.abs(appWidth-(globaloptions.appWidth||0))>50){ + Service.updateglobaloptions(db,"appWidth",appWidth) + } + } + function onHeightChanged(appHeight) { + if(osSettings.osType=="Linux" && Math.abs(appHeight-(globaloptions.appHeight||0))>50){ + Service.updateglobaloptions(db,"appHeight",appHeight) + } + } + } + + Connections{ + target:xhr + function onDownloaded(type,url,filename,i){ + 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+'"'); + }) + } + } + } + + onClosing: { + if (rootstackView.depth>1){ + rootstackView.pop(); + close.accepted=false + } + else if (bar.currentIndex==0){ + //newstab.active=true; + // if (newstab.newstabstatus!=globaloptions.newsViewType){ + // newstab.newstabstatus=globaloptions.newsViewType; + // if(globaloptions.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,0,function(dbnews){ + // newsSignal(dbnews) + // })} + // else{ + // Newsjs.chatsfromdb(db,login.username,0,[],function(dbnews){ + // newsSignal(dbnews) + // })} + // close.accepted=false; + // } + + // if (newstab.conversation.length>0){ + // newstab.conversation=[]; + // close.accepted=false + // } + + Service.cleanNews(root.db,function(){ + Service.cleanHashtags(root.db,function(){ + Service.cleanContacts(root.login,root.db,function(){ + //if (osSettings.osType=="Android" || !iconTrayAvailable){ + Qt.quit() + //} +// else{ +// systemTray.show(); +// systemTray.showMessage("",qsTr("Background Sync\n Rightclick or Middleclick to Quit"),"",5000) +// root.hide() +// } + }) + })}) + close.accepted=true + } + //else if (bar.currentIndex==2){fotoSignal(login.username,"backButton");close.accepted=false} + else {rootstackSignal(0);bar.currentIndex=0;close.accepted=false} + } + + Rectangle{ + anchors.fill: parent + color: osSettings.backgroundColor + } + + footer: ToolBar{ + id: roottoolbar + width:root.width + background: Rectangle{ + anchors.fill: parent + color: osSettings.backgroundDimColor + } + + TabBar { + id: bar + width: parent.width + //Layout.fillWidth: true + onCurrentIndexChanged: { + rootstackSignal(bar.currentIndex); + try{while(rootstackView.depth>1){rootstackView.pop()}}catch(e){} + } + TabButton { + width: bar.width/4 + height: bar.height + icon.name: "format-list-unordered" + text: qsTr("Posts") + display: AbstractButton.IconOnly + icon.source: "qrc:/assets/icons/list.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + // background:Rectangle{ + // anchors.fill: parent + // color: osSettings.backgroundDimColor + // } + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Posts") + onDoubleClicked: {newstypeSignal("refresh")} + } + TabButton { + width: bar.width/4 + height: bar.height + icon.name: "group" + text: qsTr("Contacts") + display: AbstractButton.IconOnly + icon.source: "qrc:/assets/icons/users.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + // background:Rectangle{ + // anchors.fill: parent + // color: osSettings.backgroundDimColor + // } + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Contacts") + } + TabButton { + width: bar.width/4 + height: bar.height + icon.name: "viewimage" + text: qsTr("Images") + display: AbstractButton.IconOnly + icon.source: "qrc:/assets/icons/picture-o.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + // background:Rectangle{ + // anchors.fill: parent + // color: osSettings.backgroundDimColor + // } + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Photos") + } + TabButton { + width: bar.width/4 + height: bar.height + icon.name: "view-calendar" + text: qsTr("Calendar") + display: AbstractButton.IconOnly + icon.source: "qrc:/assets/icons/calendar.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + // background:Rectangle{ + // anchors.fill: parent + // color: osSettings.backgroundDimColor + // } + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Calendar") + } + } + } + + StackView{id:rootstackView + width:root.width + height: root.height-roottoolbar.contentHeight + } + +// QSystemTrayIcon { +// id: systemTray +// visible: false +// onActivated: { +// if(reason === 3){ +// root.show(); +// bar.currentIndex=0; +// root.globaloptions.hasOwnProperty("newsViewType")?newstab.newstabstatus=root.globaloptions.newsViewType:newstab.newstabstatus="Conversations"; +// newstypeSignal(newstab.newstabstatus) +// systemTray.hide() +// } else { +// Qt.quit() +// } +// } +// Component.onCompleted: { +// icon = root.color. -import QtQuick 2.0 +import QtQuick 6.3 Rectangle{ id: blueButton width: Math.max(mainText.width+2*mm,5*mm) height: 5*mm - border.color: "light blue" + //border.color: "light blue" color:"transparent"//"#EFEAEA" "sky blue" property alias fontColor: mainText.color border.width:1 radius: mm property alias text: mainText.text property alias font: mainText.font + property alias fontSize: mainText.font.pointSize signal clicked state:"" Text{ id:mainText - color: "black" + color: osSettings.primaryTextColor anchors.centerIn: parent width: contentWidth height: contentHeight - font.family:fontAwesome.name + //font.family:fontAwesome.name font.pointSize: osSettings.bigFontSize text: "" elide: Text.ElideNone @@ -65,7 +66,7 @@ Rectangle{ states: [ State { name: "Pressed" - PropertyChanges { target: blueButton; color: "white"} } + PropertyChanges { target: blueButton; color: osSettings.buttonColor} } ] transitions: [ Transition { to:"*" diff --git a/source-linux/qml/genericqml/ContactComponent.qml b/src/qml/genericqml/ContactComponent.qml similarity index 73% rename from source-linux/qml/genericqml/ContactComponent.qml rename to src/qml/genericqml/ContactComponent.qml index 9688b1a..52a983c 100644 --- a/source-linux/qml/genericqml/ContactComponent.qml +++ b/src/qml/genericqml/ContactComponent.qml @@ -29,66 +29,66 @@ // 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 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/genericqml" Item { id: contactComponent - height: 4.5*root.fontFactor*osSettings.systemFontSize//8*mm - width: contactComponent.ListView.view.width//parent.width + height: 5*root.fontFactor*osSettings.systemFontSize + width: contactComponent.ListView.view.width property var createdAtDate: new Date(contact.created_at) property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend==1)?"":( ""+qsTr("Connect")+"
") Rectangle { id: wrapper width:parent.width - height: parent.height//8*mm + height: parent.height radius: 0.5*mm - border.color: "grey" - color:"white" + border.color: osSettings.backgroundDimColor + color: osSettings.backgroundColor Image { id: photoImage x:0.5*mm y:0.5*mm - width: 4*root.fontFactor*osSettings.systemFontSize//7*mm - height:4*root.fontFactor*osSettings.systemFontSize//7*mm + width: 4*root.fontFactor*osSettings.systemFontSize + height:4*root.fontFactor*osSettings.systemFontSize source:((contact.profile_image!="") && (typeof(contact.profile_image)=="string"))? "file://"+contact.profile_image : contact.profile_image_url - onStatusChanged: {if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}} + onStatusChanged: {if (photoImage.status == Image.Error) {source="qrc:/assets/defaultcontact.jpg"}} } Flow{ - width: wrapper.width-4*root.fontFactor*osSettings.systemFontSize//8*mm + width: wrapper.width-4*root.fontFactor*osSettings.systemFontSize height: wrapper.height-mm anchors.left: photoImage.right - anchors.margins: 1*mm - //spacing: mm + anchors.margins: 0.5*mm clip: true Label { id: namelabel - width: Math.min(wrapper.width-(photoImage.width+mm),contentWidth)//wrapper.width-4 - height: 1.1*root.fontFactor*osSettings.bigFontSize//3*mm + width: Math.min(wrapper.width-(photoImage.width+mm),contentWidth) + height: 1.1*root.fontFactor*osSettings.bigFontSize text: contact.name elide: contentWidth>wrapper.width-4*osSettings.systemFontSize?Text.ElideRight:Text.ElideNone - color: "#303030" + color: osSettings.secondaryTextColor font.pointSize: osSettings.bigFontSize } Label { id: screennamelabel - width: Math.min(wrapper.width-4*root.fontFactor*osSettings.systemFontSize,contentWidth)//contentWidth+2*mm//wrapper.width-8*mm - height: 1.1*root.fontFactor*osSettings.bigFontSize//3*mm + width: Math.min(wrapper.width-4*root.fontFactor*osSettings.systemFontSize,contentWidth) + height: 1.1*root.fontFactor*osSettings.bigFontSize text: "(@"+contact.screen_name+")" elide: contentWidth>wrapper.width-4*root.fontFactor*osSettings.systemFontSize?Text.ElideRight:Text.ElideNone - color: "#303030" + color: osSettings.secondaryTextColor font.pointSize: osSettings.bigFontSize } Label { id: descriptionlabel - width: Math.min(wrapper.width-4*root.fontFactor*osSettings.systemFontSize,contentWidth)//contentWidth+2*mm//wrapper.width-8*mm - height: 2*root.fontFactor*osSettings.systemFontSize//2.5*mm - text: contact.description - elide:contentWidth>wrapper.width-4*root.fontFactor*osSettings.systemFontSize?Text.ElideRight:Text.ElideNone - color: "#303030" + width: wrapper.width-5*root.fontFactor*osSettings.systemFontSize + height: wrapper.height-mm-1.1*root.fontFactor*osSettings.bigFontSize + maximumLineCount:2 + text: Qt.atob(contact.description)!=""?contact.description:"" + elide:Text.ElideRight + color: osSettings.secondaryTextColor font.pointSize: osSettings.systemFontSize } } @@ -96,9 +96,6 @@ Item { anchors.fill: parent onClicked:{ contactComponent.ListView.view.processContactSelection(contact) -// rootstack.currentIndex=0; -// bar.currentIndex=0; -// root.contactdetailsSignal(contact) } } } diff --git a/src/qml/genericqml/DrawerAccountComponent.qml b/src/qml/genericqml/DrawerAccountComponent.qml new file mode 100644 index 0000000..b3b4631 --- /dev/null +++ b/src/qml/genericqml/DrawerAccountComponent.qml @@ -0,0 +1,242 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import "qrc:/qml/genericqml" +import "qrc:/qml/newsqml" + +Item { + id: drawerAccountComponent + width: accountList.width + height: 17*root.fontFactor*osSettings.bigFontSize + function changeNews(typeRequest){ + newsSwipeview.stacktype=typeRequest; + if (newstabitem.newstypes.indexOf(typeRequest)<0){ + newsSwipeview.currentIndex=0; + newstabbar.currentIndex=0; +// let component =Qt.createQmlObject('import QtQuick 6.3; Loader{source:(newsSwipeview.currentIndex=='+(newsSwipeview.count)+')? "qrc:/qml/newsqml/NewsStack.qml":"qrc:/qml/newsqml/NewsStack.qml"}',newsSwipeview,"NewsstackLoader") +// newsSwipeview.addItem(component); +// newstabitem.newstypes.push(typeRequest); +// addToolbutton(typeRequest); +// newstabbar.currentIndex=newsSwipeview.count-1; + }else{ + newsSwipeview.currentIndex=newstabitem.newstypes.indexOf(typeRequest); + newstabbar.currentIndex=newstabitem.newstypes.indexOf(typeRequest); + } + } + + + Label{ + y:0.5*root.fontFactor*osSettings.bigFontSize + width:parent.width + height: 1.5*osSettings.bigFontSize*root.fontFactor + color: osSettings.primaryTextColor + verticalAlignment:Text.AlignBottom + font.pointSize: osSettings.bigFontSize + text: account.username + } + + ToolButton{ + y:2*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + text: qsTr("Refresh") + icon.name: "view-refresh-symbolic" + icon.source: "qrc:/assets/icons/refresh.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + newstypeSignal("") + } + } + + ToolButton{ + y:3.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="Home" && newstab.newstabstatus=="Timeline" + text: qsTr("Timeline") + icon.name: "chronometer" + icon.source: "qrc:/assets/icons/history.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + changeNews("Home"); + currentnewstabstatus="Timeline"; + newstypeSignal("timeline") + } + } + + ToolButton{ + y: 5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="Home" && newstab.newstabstatus=="Conversations" + text: qsTr("Conversations") + icon.name: "view-conversation-balloon" + icon.source: "qrc:/assets/icons/comments.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + changeNews("Home"); + currentnewstabstatus="Conversations"; + newstypeSignal("conversation") + } + } + + ToolButton{ + y:6.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="Replies" + text: qsTr("Replies") + icon.name: "mail-reply-all-symbolic" + icon.source: "qrc:/assets/icons/exchange.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + changeNews("Replies"); + //currentnewstabstatus="Replies"; + newstypeSignal("replies") + } + } + + ToolButton{ + y: 8*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="DirectMessages" + text: qsTr("Direct Messages") + icon.name: "mail-message" + icon.source: "qrc:/assets/icons/envelope.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + changeNews("DirectMessages") + } + } + + ToolButton{ + y: 9.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="Favorites" + text: qsTr("Favorites") + icon.name: "starred-symbolic" + icon.source: "qrc:/assets/icons/star.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + changeNews("Favorites") + newstypeSignal("favorites") + } + } + + ToolButton{ + y: 11*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="Public Timeline" + text: qsTr("Public Timeline") + icon.name: "globe" + icon.source: "qrc:/assets/icons/globe.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + changeNews("Public Timeline") + currentnewstabstatus="Public Timeline"; + newstypeSignal("publictimeline") + } + } + + ToolButton{ + y: 12.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="Groupnews" + text: qsTr("Group news") + icon.name: "group" + icon.source: "qrc:/assets/icons/users.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + newsSwipeview.currentIndex=0; + currentnewstabstatus="Groupnews"; + changeNews("Group News") + newstypeSignal("groupnews") + } + } + + ToolButton{ + y: 14*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="Search" + text: qsTr("Search") + icon.name: "system-search" + icon.source: "qrc:/assets/icons/search.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + newsSwipeview.currentIndex=0; + currentnewstabstatus="Search"; + newstypeSignal("search") + changeNews("Search"); + } + } + + ToolButton{ + y: 15.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + font.bold: account.username==root.login.username && newsSwipeview.stacktype=="Notifications" + text: qsTr("Notifications") + icon.name: "notifications" + icon.source: "qrc:/assets/icons/bell.svg" + icon.height: root.fontFactor*osSettings.systemFontSize + icon.width: root.fontFactor*osSettings.systemFontSize + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + changeNews("Notifications") + newstypeSignal("notifications") + } + } +} diff --git a/source-linux/qml/genericqml/DrawerAccountComponentContacts.qml b/src/qml/genericqml/DrawerAccountComponentContacts.qml similarity index 82% rename from source-linux/qml/genericqml/DrawerAccountComponentContacts.qml rename to src/qml/genericqml/DrawerAccountComponentContacts.qml index da545e0..544ade1 100644 --- a/source-linux/qml/genericqml/DrawerAccountComponentContacts.qml +++ b/src/qml/genericqml/DrawerAccountComponentContacts.qml @@ -29,17 +29,16 @@ // 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 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/genericqml" Item { id: drawerAccountComponent - property var account: ({}) - width: parent.width + width: accountList.width + height: 8*root.fontFactor*osSettings.bigFontSize Label{ - y:0.5*osSettings.bigFontSize width:parent.width height: 1.5*root.fontFactor*osSettings.bigFontSize @@ -57,7 +56,7 @@ Item { y:2*root.fontFactor*osSettings.bigFontSize width:parent.width font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && friendsTabView.currentIndex==0 + font.bold: account.username==login.username && friendsTabView.currentIndex==0 text: " "+qsTr("Profile") MouseArea{ anchors.fill:parent @@ -65,6 +64,7 @@ Item { login=account; if(!wideScreen){leftDrawerAndroid.close()} friendsTabView.currentIndex=0; + friendsbar.currentIndex=0; profileLoader.source=""; profileLoader.source="qrc:/qml/contactqml/ProfileTab.qml" } @@ -82,7 +82,8 @@ Item { onClicked:{ login=account; if(!wideScreen){leftDrawerAndroid.close()} - friendsTabView.currentIndex=1 + friendsTabView.currentIndex=1; + friendsbar.currentIndex=1; friendsListLoader.source=""; friendsListLoader.source="qrc:/qml/contactqml/FriendsListTab.qml" } @@ -94,31 +95,14 @@ Item { width:parent.width font.pointSize: osSettings.systemFontSize font.bold: account.username==login.username && friendsTabView.currentIndex==2 - text: " "+qsTr("Contacts") + text: " "+qsTr("Circles") MouseArea{ anchors.fill:parent onClicked:{ login=account; if(!wideScreen){leftDrawerAndroid.close()} - friendsTabView.currentIndex=2 - } - } - } - - - - Label{ - y:6.5*root.fontFactor*osSettings.bigFontSize - width:parent.width - font.pointSize: osSettings.systemFontSize - font.bold: account.username==login.username && friendsTabView.currentIndex==3 - text: " "+qsTr("Groups") - MouseArea{ - anchors.fill:parent - onClicked:{ - login=account; - if(!wideScreen){leftDrawerAndroid.close()} - friendsTabView.currentIndex=3 + friendsTabView.currentIndex=2; + friendsbar.currentIndex=2; } } } diff --git a/source-linux/qml/genericqml/ImagePicker.qml b/src/qml/genericqml/ImagePicker.qml similarity index 94% rename from source-linux/qml/genericqml/ImagePicker.qml rename to src/qml/genericqml/ImagePicker.qml index d414c1f..2ac69a2 100644 --- a/source-linux/qml/genericqml/ImagePicker.qml +++ b/src/qml/genericqml/ImagePicker.qml @@ -1,4 +1,4 @@ -import QtQuick 2.0 +import QtQuick 6.3 import AndroidNative 1.0 Item { @@ -37,7 +37,8 @@ Item { Connections { target: SystemDispatcher - onDispatched: { + //onDispatched: { + function onDispatched(type, message){ if ((type === m_CHOSEN_MESSAGE) && (root.imagePicking==true)) { var h=[]; for (var n in message.imageUrls){ diff --git a/src/qml/genericqml/ImagePickerLinux.qml b/src/qml/genericqml/ImagePickerLinux.qml new file mode 100644 index 0000000..e15dbde --- /dev/null +++ b/src/qml/genericqml/ImagePickerLinux.qml @@ -0,0 +1,208 @@ +// This file is part of Friendiqa +// https://github.com/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtCore 6.3 +import QtQuick.Controls 6.3 +import QtQuick.Dialogs 6.3 +import "qrc:/js/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Item{ + id:imageDialog + z:2 +// border.color: "grey" +// color: Material.backgroundColor +// width: parent.width-root.fontFactor*osSettings.bigFontSize +// height: parent.height-3*root.fontFactor*osSettings.bigFontSize +// x: 0.5*root.fontFactor*osSettings.bigFontSize +// y: 2*root.fontFactor*osSettings.bigFontSize + property string directory: "" + property bool multiple: false + property string imageUrl: "" + //property var imageUrls: [] + signal ready(); + function pickImage() {imageFileDialog.open()} + +// Text{ +// id:directoryText +// anchors.bottom: parent.bottom +//// x:0.5*mm +//// y:0.5*mm +// width: imageDialog.width-3.5*root.fontFactor*osSettings.bigFontSize +// height:contentHeight +// font.pointSize: osSettings.bigFontSize +// wrapMode: Text.Wrap +// text: directory +// color: Material.primaryTextColor +// } +// Button{ +// id:closeButton +// height: 2*root.fontFactor*osSettings.bigFontSize +// anchors.top: parent.top +// anchors.topMargin: 0.5*mm +// anchors.right: parent.right +// anchors.rightMargin: 1*mm +// text: "\uf057" +// onClicked:{ +// ready();imageDialog.destroy() +// } +// } + FileDialog { + id: imageFileDialog + title: "Please choose a file" + currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] + fileMode: FileDialog.OpenFiles + //selectMultiple: true + onAccepted: { + //imageUrl=imageFileDialog.fileUrls.toString(); + imageUrl=imageFileDialog.selectedFiles.toString(); + ready(); + } + } +// ListView { +// id: imageView +// x:0.5*mm +// y: 2.5*root.fontFactor*osSettings.bigFontSize//Math.max(directoryText.height, closeButton.height)+mm +// width: parent.width-2*mm +// height: parent.height-3*root.fontFactor*osSettings.bigFontSize +// boundsBehavior:Flickable.StopAtBounds +// clip: true +// model: imageModel +// delegate: imageItem +// ScrollBar.vertical: ScrollBar { } +// } + +// FolderListModel{ +// id: imageModel +// nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG","*.gif"] +// sortField: FolderListModel.Time +// sortReversed:false +// showDotAndDotDot: true +// showDirs: true +// showDirsFirst: true +// folder:directory +// } + +// BusyIndicator{ +// id: imageBusy +// anchors.horizontalCenter: imageView.horizontalCenter +// anchors.top:imageView.top +// anchors.topMargin: 2*mm +// width: 2*root.fontFactor*osSettings.bigFontSize +// height: 2*root.fontFactor*osSettings.bigFontSize +// running:false +// } + +// Component{ +// id:imageItem +// Item{ +// width:imageView.width +// height: Math.max(fileImage.height,1.5*root.fontFactor*osSettings.bigFontSize)+2*mm +// Rectangle{ +// id:imagetextRectangle +// color:"black" +// x:mm +// z:3 +// opacity: fileIsDir?0:0.5 +// width:imagetext.contentWidth +// height: imagetext.contentHeight +// anchors.bottom: fileImage.bottom +// } +// Text { +// id:imagetext +// x: mm//fileIsDir?11*mm:mm +// z:4 +// text: fileIsDir?"\uf07b "+fileName:fileName +// width: fileIsDir?parent.width - 2.5*root.fontFactor*osSettings.bigFontSize :imageView.width-mm +// anchors.bottom: fileImage.bottom +// color: fileIsDir?Material.primaryTextColor:"white" +// font.pointSize: osSettings.bigFontSize +// wrapMode:Text.Wrap +// } +// Text { +// id:selected +// anchors.right:parent.right +// visible: attachImageURLs.indexOf(fileURL)>-1 +// z:4 +// text: "\u2713" +// width: 2*root.fontFactor*osSettings.bigFontSize +// anchors.top: fileImage.top +// color: "green" +// font.pointSize: 3*osSettings.bigFontSize +// } + +// Image{id:fileImage +// width: imageView.width-mm +// fillMode:Image.PreserveAspectFit +// source:fileIsDir?"":fileURL +// } + +// MouseArea{ +// anchors.fill: parent +// onClicked:{ +// if (fileName==".."){ +// imageModel.folder=imageModel.parentFolder; +// directory=imageModel.parentFolder +// } +// else if (fileIsDir){ +// imageModel.folder=fileURL; +// directory=fileURL +// } +// else{ +// if (multiple!=true){ +// //attachImageURLs.push(fileURL); +// //attachImage(fileURL); +// imageUrls.push(fileURL); +// imageUrl=fileURL; +// ready(); +// imageDialog.destroy() +// } +// else { +// if(selected.visible==true){ +// imageUrls.splice(imageUrls.indexOf(fileURL,1)) +// selected.visible=false +// } +// else{ +// imageUrls.push(fileURL); +// selected.visible=true; + +// } +// imageUrl=fileURL +// } +// } +// } +// } +// } +// } +// Component.onCompleted: imageFileDialog.open() +} diff --git a/source-linux/qml/genericqml/IntentReceiver.qml b/src/qml/genericqml/IntentReceiver.qml similarity index 73% rename from source-linux/qml/genericqml/IntentReceiver.qml rename to src/qml/genericqml/IntentReceiver.qml index 062ab36..7cad83a 100644 --- a/source-linux/qml/genericqml/IntentReceiver.qml +++ b/src/qml/genericqml/IntentReceiver.qml @@ -1,4 +1,4 @@ -import QtQuick 2.0 +import QtQuick 6.3 import AndroidNative 1.0 Item { @@ -22,13 +22,15 @@ Item { h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5)) } imageUrls=h; - if(imageUrls.length==1){ - rootstack.currentIndex=0;newstab.active=true; - root.uploadSignal(imageUrls) - } else{ - rootstack.currentIndex=2;fotostab.active=true; - root.uploadSignal(imageUrls) - } + rootstack.currentIndex=0;newstab.active=true; + root.uploadSignal(imageUrls.join(",")) +// if(imageUrls.length==1){ +// rootstack.currentIndex=0;newstab.active=true; +// root.uploadSignal(imageUrls) +// } else{ +// rootstack.currentIndex=2;fotostab.active=true; +// root.uploadSignal(imageUrls) +// } } else if (type==m_TEXT_MESSAGE){ rootstack.currentIndex=0;newstab.active=true; root.sendtextSignal(message) diff --git a/source-linux/qml/genericqml/LeftDrawerAndroid.qml b/src/qml/genericqml/LeftDrawerAndroid.qml similarity index 94% rename from source-linux/qml/genericqml/LeftDrawerAndroid.qml rename to src/qml/genericqml/LeftDrawerAndroid.qml index 5545836..8387fc1 100644 --- a/source-linux/qml/genericqml/LeftDrawerAndroid.qml +++ b/src/qml/genericqml/LeftDrawerAndroid.qml @@ -29,13 +29,14 @@ // 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 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/configqml" Drawer{ id: leftDrawer width: root.fontFactor*osSettings.systemFontSize*13 height: root.height + background: Rectangle{color: osSettings.backgroundColor} LeftDrawerScrollview{} } diff --git a/source-linux/qml/genericqml/LeftDrawerLinux.qml b/src/qml/genericqml/LeftDrawerLinux.qml similarity index 88% rename from source-linux/qml/genericqml/LeftDrawerLinux.qml rename to src/qml/genericqml/LeftDrawerLinux.qml index 68166b3..73f9267 100644 --- a/source-linux/qml/genericqml/LeftDrawerLinux.qml +++ b/src/qml/genericqml/LeftDrawerLinux.qml @@ -29,16 +29,13 @@ // 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 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/configqml" Rectangle{ -// id: leftDrawer -// width: osSettings.systemFontSize*30 -// height: root.height-bar.height - //y: bar.height signal opened() + color: osSettings.backgroundColor LeftDrawerScrollview{ width:parent.width-mm @@ -49,7 +46,6 @@ Rectangle{ width: 1 height: leftDrawer.height anchors.right: leftDrawer.right - color: "#EEEEEE" + color: osSettings.dialogColor } - Component.onCompleted: {opened();} } diff --git a/source-linux/qml/genericqml/LinuxSync.qml b/src/qml/genericqml/LinuxSync.qml similarity index 88% rename from source-linux/qml/genericqml/LinuxSync.qml rename to src/qml/genericqml/LinuxSync.qml index 9abc6e9..dde0210 100644 --- a/source-linux/qml/genericqml/LinuxSync.qml +++ b/src/qml/genericqml/LinuxSync.qml @@ -1,5 +1,4 @@ -import QtQuick 2.4 - +import QtQuick 6.3 Item { Timer{ @@ -8,13 +7,13 @@ Item { onTriggered: { updatenews.setDatabase(); updatenews.login(); + updatenews.setSyncAll(true) updatenews.startsync(); } } function startSyncTimer(interval){ syncTimer.interval=interval*60000; - //print("synctimer interval "+syncTimer.interval) syncTimer.start() } diff --git a/source-linux/qml/genericqml/MButton.qml b/src/qml/genericqml/MButton.qml similarity index 78% rename from source-linux/qml/genericqml/MButton.qml rename to src/qml/genericqml/MButton.qml index 74c1803..b2c8cea 100644 --- a/source-linux/qml/genericqml/MButton.qml +++ b/src/qml/genericqml/MButton.qml @@ -28,15 +28,21 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.6 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 Button{ id: mButton - property alias color: bg.color - width: Math.max(text.width+2*mm,2*root.fontFactor*osSettings.bigFontSize) + //property alias color: bg.color + width: Math.max(implicitContentWidth+2*mm,3*root.fontFactor*osSettings.bigFontSize) //radius: mm height: 2*root.fontFactor*osSettings.bigFontSize - //color: Material.grey + //color: Material.foreground + //font.family: fontAwesome.name font.pointSize: osSettings.bigFontSize - background: Rectangle{id:bg;color:"#F3F3F3";radius: 0.5*mm} + //highlighted:true + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + + // background: Rectangle{id:bg;color: osSettings.dialogColor; + // radius: 0.5*mm} } diff --git a/src/qml/genericqml/PermissionDialog.qml b/src/qml/genericqml/PermissionDialog.qml new file mode 100644 index 0000000..fecef74 --- /dev/null +++ b/src/qml/genericqml/PermissionDialog.qml @@ -0,0 +1,232 @@ +// This file is part of Friendiqa +// https://github.com/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import "qrc:/js/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Rectangle{ + id:permissionDialog + color: osSettings.backgroundColor + // x: mm + width: parent.width-5*mm + height:root.height/3 + function updatePerms(){ + for (var i=0;i-1){contactstatus="positive"} +// else if (contact_deny.indexOf(contacts[name].cid)>-1){contactstatus="negative"} +// contactModel.append({"contact":contacts[name],"contactstatus":contactstatus}) +// }},"isFriend",1,"name"); + +// Helperjs.readData(db,"groups",login.username,function(owngroups){ +// for (var number in owngroups){ +// var groupstatus= "neutral"; +// if (group_allow.indexOf(owngroups[number].gid)>-1){groupstatus="positive"} +// else if (group_deny.indexOf(owngroups[number].gid)>-1){groupstatus="negative"} +// groupModel.append({"group":owngroups[number],"groupstatus":groupstatus}) +// }}); +// } +} diff --git a/source-linux/qml/genericqml/Search.qml b/src/qml/genericqml/RootStack.qml similarity index 60% rename from source-linux/qml/genericqml/Search.qml rename to src/qml/genericqml/RootStack.qml index eafa617..3898095 100644 --- a/source-linux/qml/genericqml/Search.qml +++ b/src/qml/genericqml/RootStack.qml @@ -28,42 +28,38 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import QtQuick.Layouts -import QtQuick 2.7 -import QtQuick.Controls 2.12 -import "qrc:/qml/genericqml" -//import "qrc:/js/news.js" as Newsjs -//import "qrc:/js/helper.js" as Helperjs -//import "qrc:/js/service.js" as Service +StackLayout{ + id:rootstack + width:rootstackView.width + height: rootstackView.height + currentIndex:bar.currentIndex + function indexchange(pageindex){currentIndex=pageindex;bar.currentIndex=pageindex} -Rectangle { - id:searchComponent - - Rectangle{ - color: "#EEEEEE" - radius:0.5*mm - anchors.left: parent.left - anchors.leftMargin:mm - anchors.top:parent.top - anchors.topMargin: 0.5*mm - width:parent.width-2*mm - height: 4*mm //Math.max( searchText.contentHeight,5*mm) - - TextInput { - id: searchText - focus: true - font.pointSize: osSettings.bigFontSize - wrapMode: Text.Wrap - anchors.fill: parent - selectByMouse: true - cursorVisible: false - onEditingFinished:{ if (displayText!=""){search(displayText)};searchComponent.destroy()} - //onHeightChanged: newsView.contentY+=4.5*mm - - } - Component.onCompleted: searchText.forceActiveFocus() - + Loader{ + id: newstab + property string newstabstatus + source:(rootstack.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" + } + Loader{ + id: friendstab + source: (rootstack.currentIndex==1)?"qrc:/qml/contactqml/FriendsTab.qml":"" + } + Loader{ + id: fotostab + property string phototabstatus:"Images" + source: (rootstack.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":"" + } + Loader{ + id: calendartab + property string calendartabstatus:"Events" + source: (rootstack.currentIndex==3)?"qrc:/qml/calendarqml/CalendarTab.qml":"" + } + Component.onCompleted: { + root.rootstackSignal.connect(indexchange); } - } diff --git a/source-linux/qml/configqml/RegisterPage.qml b/src/qml/newsqml/BlockUser.qml similarity index 66% rename from source-linux/qml/configqml/RegisterPage.qml rename to src/qml/newsqml/BlockUser.qml index 90eb809..e559207 100644 --- a/source-linux/qml/configqml/RegisterPage.qml +++ b/src/qml/newsqml/BlockUser.qml @@ -29,36 +29,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.9 -import QtQuick.Controls 2.12 -import QtWebView 1.1 -import "qrc:/qml/genericqml" +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import "qrc:/js/helper.js" as Helperjs -Rectangle{ - color:"white" - property alias url:htmlview.url +Dialog { + id: userReportDialog + anchors.centerIn: parent + property var newsitem:({}) + title: qsTr("Block contact?") - WebView {id:htmlview; - height:parent.height-7*mm - width:parent.width - y:7*mm -// MouseArea { -// anchors.fill:parent; -// onClicked:{ -// //print(url) -// } -// } - //onLoadingChanged: print(loadProgress) + standardButtons: Dialog.Ok | Dialog.Cancel + modal: true + onAccepted: { + Helperjs.updateData(root.db,"contacts",login.username,"statusnet_blocking", true,function(){},"id",newsitem.user.id) + xhr.setAccount(login); + xhr.setApi("/api/v1/accounts/" + newsitem.user.id + "/block"); + xhr.post(); } - Button{ - id:closeButton - height: 3*root.fontFactor*osSettings.bigFontSize - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - font.pointSize: osSettings.bigFontSize - onClicked:{root.pop()} - } + onRejected: {close()} + Label {text: newsitem.user.name} } diff --git a/source-linux/qml/newsqml/ContactPage.qml b/src/qml/newsqml/ContactPage.qml similarity index 59% rename from source-linux/qml/newsqml/ContactPage.qml rename to src/qml/newsqml/ContactPage.qml index e0b3bcb..4ac2b3a 100644 --- a/source-linux/qml/newsqml/ContactPage.qml +++ b/src/qml/newsqml/ContactPage.qml @@ -30,8 +30,8 @@ // along with this program. If not, see . -import QtQuick 2.0 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/news.js" as Newsjs import "qrc:/js/service.js" as Service @@ -43,8 +43,6 @@ Page { property var contact:({}) property string profileimagesource:contact.profile_image - //function backRequested(){pageStack.pop()} - function getDateDiffString (seconds){ var timestring=""; if (seconds<60) {timestring= Math.round(seconds) + " " +qsTr("seconds");} @@ -90,18 +88,13 @@ Page { } function showConversation(conversationIndex,newsitemobject){ + xhr.setAccount(login); if(newsitemobject.messagetype==0 || newsitemobject.messagetype==3){ - xhr.clearParams(); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); xhr.setApi("/api/conversation/show"); xhr.setParam("id",newsitemobject.id) xhr.get(); } else{ - xhr.clearParams(); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); xhr.setApi("/api/direct_messages/conversation"); xhr.setParam("uri",newsitemobject.statusnet_conversation_id) xhr.get(); @@ -133,21 +126,19 @@ Page { BusyIndicator{ id: contactBusy anchors.centerIn:parent - width:10*mm - height: 10*mm + width: 1.5*root.fontFactor*osSettings.bigFontSize + height: 1.5*root.fontFactor*osSettings.bigFontSize running: true } Component { id: contactHeader Rectangle{ - border.color: "#EEEEEE" + border.color: osSettings.backgroundDimColor border.width: 1 - color:"white" + color: osSettings.backgroundColor width:contactView.width height: contactView.width<35*root.fontFactor*osSettings.systemFontSize?(profileImage.height+namelabel.height+detailtext.height+7*mm):Math.max(profileImage.height,(buttonflow.height+namelabel.height+detailtext.height))+7*mm - //height: wrapper.height property var createdAtDate: new Date(contact.created_at) - property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend!=0)?"":( ""+qsTr("Connect")+"
") Image { id: profileImage @@ -156,116 +147,178 @@ Page { width: Math.min(15*root.fontFactor*osSettings.bigFontSize,contactView.width/2) //contactView.width/2 height:width source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url - onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/assets/defaultcontact.jpg"} Connections{ target:contactList - onProfileimagesourceChanged:profileImage.source=profileimagesource + function onProfileimagesourceChanged(){profileImage.source=profileimagesource} } } + Flow{id:buttonflow anchors.right: parent.right anchors.rightMargin: mm width: contactView.width - (profileImage.width+3*mm) - height: (contact.hasOwnProperty("acct"))?21*mm:15*mm//profileImage.height + height: (contact.hasOwnProperty("acct"))?21*mm:15*mm y: mm spacing:4 - BlueButton{ - id:photobutton - height: 6*mm - width: 8*mm - text: "\uf03e" // "Photos" - visible:(contact.network=="dfrn") - onClicked:{ - rootstack.currentIndex=2; - bar.currentIndex=2; - fotostab.phototabstatus="Contact"; + // MButton{ + // id:photobutton + // height: 6*mm + // width: 8*mm + // text: qsTr("Photos") + // visible:(contact.network=="dfrn") + // onClicked:{ + // rootstackSignal(2); + // bar.currentIndex=2; + // fotostab.phototabstatus="Contact"; - //fotostab.active=true; - fotoSignal(root.login,contact) ; - rootstackView.pop(); - } - } + // //fotostab.active=true; + // fotoSignal(root.login,contact) ; + // rootstackView.pop(); + // } + // } - BlueButton{ + MButton{ id:dmbutton - height: 6*mm - width: 8*mm visible: (contact.following=="true") - text: "\uf040" //"DM" + text: qsTr("Direct Message") + display: AbstractButton.IconOnly + icon.name: "mail-message" + icon.source: "qrc:/assets/icons/envelope.svg" onClicked:{ - rootstack.currentIndex=0; - newsSwipeview.currentIndex=2; - directmessageSignal(contact) + rootstackSignal(0); + sendmessageSignal("directmessage",{id:"",user:{screen_name:contact.screen_name}}) } } - BlueButton{ - id:eventbutton - visible:(contact.network=="dfrn") - height: 6*mm - width: 8*mm - text:"\uf073" - onClicked:{ - rootstack.currentIndex=3; - bar.currentIndex=3; - calendartab.calendartabstatus="Friend" - eventSignal(contact); - rootstackView.pop() - } - } - BlueButton{ + // MButton{ + // id:eventbutton + // visible:(contact.network=="dfrn") + // height: 6*mm + // width: 8*mm + // text:qsTr("Events") + // onClicked:{ + // rootstackSignal(3); + // bar.currentIndex=3; + // calendartab.calendartabstatus="Friend" + // eventSignal(contact); + // rootstackView.pop() + // } + // } + MButton{ id:approvebutton - visible:(contact.hasOwnProperty("acct")) - height: 6*mm - //width: implicitContentWidth+2*mm//8*mm + visible:(contact.hasOwnProperty("acct")&&!contact.searchContact) + width: implicitWidth text:qsTr("Approve") onClicked:{ - - Helperjs.friendicaPostRequest(login,"/api/v1/follow_requests/" + contact.id + "/authorize",'',"POST",root,function(returnvalue){ - Helperjs.deleteData(db,"friendshiprequests",login.username,function(){},"id", contact.id) - }) - root.friendsSignal(); + xhr.setAccount(login); + xhr.setApi("/api/v1/follow_requests/" + contact.id + "/authorize"); + xhr.post(); + Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){},"id", contact.id) + try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)} rootstackView.pop() } } - BlueButton{ + MButton{ id:rejectbutton - visible:(contact.hasOwnProperty("acct")) - height: 6*mm - //width: implicitContentWidth+2*mm//8*mm + visible:(contact.hasOwnProperty("acct")&&!contact.searchContact) + width: implicitWidth text:qsTr("Reject") onClicked:{ - Helperjs.friendicaPostRequest(login,"/api/v1/follow_requests/" + contact.id + "/reject",'',"POST",root,function(returnvalue){ - Helperjs.deleteData(db,"friendshiprequests",login.username,function(){},"id", contact.id) - }) - root.friendsSignal(); + xhr.setAccount(login); + xhr.setApi("/api/v1/follow_requests/" + contact.id + "/authorize"); + xhr.post(); + Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){},"id", contact.id) + try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)} rootstackView.pop() } } - BlueButton{ + MButton{ id:ignorebutton - visible:(contact.hasOwnProperty("acct")) - height: 6*mm - //width: implicitContentWidth+2*mm//8*mm + visible:(contact.hasOwnProperty("acct")&&!contact.searchContact) + width: implicitWidth text:qsTr("Ignore") onClicked:{ - Helperjs.friendicaPostRequest(login,"/api/v1/follow_requests/" + contact.id + "/ignore",'',"POST",root,function(returnvalue){ - Helperjs.deleteData(db,"friendshiprequests",login.username,function(){},"id", contact.id) - }); - root.friendsSignal(); + xhr.setAccount(login); + xhr.setApi("/api/v1/follow_requests/" + contact.id + "/ignore"); + xhr.post(); + Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){},"id", contact.id) + try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)} rootstackView.pop() } } + MButton{ + id:followbutton + visible:(contact.isFriend==0 || !contact.hasOwnProperty("isFriend")) + width: implicitWidth + text:qsTr("Follow") + onClicked:{ + contactBusy.running=true; + xhr.setAccount(login); + xhr.setApi("/api/v1/accounts/" + contact.id + "/follow"); + xhr.post(); + Helperjs.updateData(root.db,"contacts",root.login.username,"isFriend",1,function(){},"id",contact.id) + try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)} + rootstackView.pop() + } + } + + MButton{ + id:unfollowbutton + visible:(contact.isFriend==1) + width: implicitWidth + text:qsTr("Unfollow") + onClicked:{ + contactBusy.running=true; + xhr.setApi("/api/v1/accounts/" + contact.id + "/unfollow"); + xhr.post(); + Helperjs.updateData(root.db,"contacts",root.login.username,"isFriend",0,function(){},"id",contact.id) + try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)} + rootstackView.pop() + } + } + + MButton{ + id: blockbutton + visible:(contact.statusnet_blocking!=1) + width: implicitWidth + text:qsTr("Block") + onClicked:{ + contactBusy.running=true; + Helperjs.updateData(root.db,"contacts",root.login.username,"statusnet_blocking",true,function(){},"id",contact.id) + xhr.setAccount(login); + xhr.setApi("/api/v1/accounts/" + contact.id + "/block"); + xhr.post(); + try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)} + rootstackView.pop() + } + } + + MButton{ + id: unblockbutton + visible:(contact.statusnet_blocking==1) + width: implicitWidth + text:qsTr("Unblock") + onClicked:{ + contactBusy.running=true; + Helperjs.updateData(root.db,"contacts",root.login.username,"statusnet_blocking",false,function(){},"id",contact.id) + xhr.setAccount(login); + xhr.setApi("/api/v1/accounts/" + contact.id + "/unblock"); + xhr.post(); + try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)} + rootstackView.pop() + } + } + }//Flow end Label { id: namelabel - //x:mm width: contactView.width<35*root.fontFactor*osSettings.systemFontSize?contactView.width-2*mm:contactView.width-17*root.fontFactor*osSettings.bigFontSize height: implicitHeight text:contact.name+" (@"+contact.screen_name+")" - wrapMode: Text.Wrap//elide:Text.ElideRight - color: "#303030" + wrapMode: Text.Wrap + color: osSettings.primaryTextColor font.pointSize: 1.2*osSettings.bigFontSize font.family: "Noto Sans" anchors.top: contactView.width<35*root.fontFactor*osSettings.systemFontSize?profileImage.bottom:buttonflow.bottom @@ -277,24 +330,22 @@ Page { anchors.top: namelabel.bottom anchors.left: contactView.width<35*root.fontFactor*osSettings.systemFontSize?contactView.left:profileImage.right anchors.margins: 2*mm - //x:mm width: contactView.width<35*root.fontFactor*osSettings.systemFontSize?contactView.width-2*mm:contactView.width-17*root.fontFactor*osSettings.bigFontSize height: implicitHeight font.pointSize: osSettings.systemFontSize font.family: "Noto Sans" textFormat:Text.RichText wrapMode: Text.Wrap - text:""+qsTr("Description")+": "+contact.description+"
"+qsTr("Location")+": "+contact.location+"
"+qsTr("Posts")+": "+contact.statuses_count+ + color: osSettings.primaryTextColor + text:""+qsTr("Description")+": "+(Qt.atob(contact.description)!=""?contact.description:"")+"
"+qsTr("Location")+": "+contact.location+"
"+qsTr("Posts")+": "+contact.statuses_count+ "
"+qsTr("URL")+": "+contact.url+"
"+ - connectUrl+ ""+qsTr("Created at")+": "+createdAtDate.toLocaleString(Qt.locale()) + ""+qsTr("Created at")+": "+createdAtDate.toLocaleString(Qt.locale())+"
"+ + ""+qsTr("Followers")+": "+contact.followers_count+"
"+ + ""+qsTr("Following")+": "+contact.friends_count+"
" onLinkActivated: { Qt.openUrlExternally(link)} } - - - //} } - }//Component end Connections{ @@ -304,19 +355,21 @@ Page { contactBusy.running=false; } function onSuccess(data,api){ - Service.processNews(api,data) - replySignal("") + if (api=="/api/statuses/user_timeline" || api=="/api/conversation/show"|| api=="/api/direct_messages/conversation"){ + if (data!=""){ + Service.processNews(api,data) + }else{contactBusy.running=false} + } } } Connections{ target:root function onContactpostsChanged(){ - if (root.contactposts.length>0&&root.contactposts[0]!=null){profileimagesource=root.contactposts[0].user.profile_image_url_large} + if (root.contactposts.length>0&&root.contactposts[0]!=null){profileimagesource=root.contactposts[0].friendica_author.profile_image_url_large} contactBusy.running=false; - contactModel.clear(); var currentTime= new Date(); - var msg = {'currentTime': currentTime, 'model': contactModel,'news':root.contactposts, 'options':globaloptions}; + var msg = {'currentTime': currentTime, 'model': contactModel,'news':root.contactposts, 'options':globaloptions, 'method':'contact'}; contactWorker.sendMessage(msg) } } @@ -335,19 +388,17 @@ Page { anchors.right: parent.right anchors.rightMargin: 1*mm width: 2*root.fontFactor*osSettings.bigFontSize; - text: "\uf057" - //font.pixelSize: 3*mm + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" onClicked: { rootstackView.pop() } } Component.onCompleted: { - xhr.clearParams(); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - if(contact.isFriend==1 || contact.hasOwnProperty("acct")){ - xhr.setApi("/api/statuses/user_timeline");} - else{xhr.setApi("/api/users/show");} + xhr.setAccount(login); + xhr.setApi("/api/statuses/user_timeline") xhr.setParam("user_id",contact.id) xhr.get(); } diff --git a/source-linux/qml/newsqml/Conversation.qml b/src/qml/newsqml/Conversation.qml similarity index 81% rename from source-linux/qml/newsqml/Conversation.qml rename to src/qml/newsqml/Conversation.qml index a511617..65fc382 100644 --- a/source-linux/qml/newsqml/Conversation.qml +++ b/src/qml/newsqml/Conversation.qml @@ -30,19 +30,14 @@ // along with this program. If not, see . // ConversationView with button -import QtQuick 2.0 -import QtQuick.Controls 2.12 -import "qrc:/js/helper.js" as Helperjs +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/genericqml" import "qrc:/qml/newsqml" Page { id:conversationList property var news:[] -// color: "white" - //function backRequested(){pageStack.pop()} -// width:root.width -// height: root.height-7*mm function getDateDiffString (seconds){ var timestring=""; @@ -88,17 +83,26 @@ Page { return {likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText} } + function openMessageSend(messageState,newsitemobject){ + var parentId="" + var replyUser="" + if(newsitemobject!=""){ + parentId=newsitemobject.id + replyUser=newsitemobject.user.screen_name; + } + var messageObject = Qt.createComponent("qrc:/qml/newsqml/MessageSend.qml"); + var messageWindow=messageObject.createObject(root, { parentId: parentId, reply_to_user: replyUser, windowstate: messageState }); + messageWindow.show(); + } ListView { id: conversationView property string viewtype: "conversation" - //x:3*mm - //y:8*mm - width: conversationList.width//-4*mm - height:conversationList.height//-20*mm + width: conversationList.width + height:conversationList.height-2*root.fontFactor*osSettings.bigFontSize clip: true spacing: 0 - footer: MessageSend{conversation:true} + ScrollBar.vertical: ScrollBar { } model: conversationModel delegate: Newsitem{} } @@ -106,23 +110,24 @@ Page { id: conversationBusy anchors.horizontalCenter: conversationView.horizontalCenter anchors.top:conversationView.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm + anchors.topMargin: mm + width: 2*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize running: true } Connections{ - target:newstab - onConversationChanged:{ - if(newstab.conversation.length==0){ - rootstackView.pop() - } else { conversationBusy.running=false; + target: root + function onConversationChanged(){print(conversation+" conversation "+JSON.stringify(root.conversation)) + // if(root.conversation.length==0){ + // rootstackView.pop() + // } else { + conversationBusy.running=false; conversationModel.clear(); var currentTime= new Date(); - var msg = {'currentTime': currentTime, 'model': conversationModel,'news':newstab.conversation, 'method':'conversation', 'options':globaloptions}; + var msg = {'currentTime': currentTime, 'model': conversationModel,'news':root.conversation, 'method':'conversation', 'options':globaloptions}; conversationWorker.sendMessage(msg) - } + //} } } @@ -140,10 +145,12 @@ Page { anchors.right: parent.right anchors.rightMargin: 1*mm width: 2*root.fontFactor*osSettings.bigFontSize; - text: "\uf057" + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" onClicked: { - //newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning); - newstab.conversation=[]; + root.conversation=[]; if (rootstackView.depth>1){ rootstackView.pop()} } } diff --git a/source-linux/qml/newsqml/FriendicaActivities.qml b/src/qml/newsqml/FriendicaActivities.qml similarity index 62% rename from source-linux/qml/newsqml/FriendicaActivities.qml rename to src/qml/newsqml/FriendicaActivities.qml index 0fdc91e..9555d8c 100644 --- a/source-linux/qml/newsqml/FriendicaActivities.qml +++ b/src/qml/newsqml/FriendicaActivities.qml @@ -30,15 +30,15 @@ // along with this program. If not, see . // List of people from Friendica Activities -import QtQuick 2.0 +import QtQuick 6.3 import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" Rectangle { id:activitiesRectangle property var activitymembers - color: "white" - border.color: "light grey" + color: osSettings.dialogColor + //border.color: osSettings.frameColor radius:0.5*mm width:root.width/2 height:Math.min(root.height/2,(10*mm+6*activitymembers.length*mm)) @@ -53,50 +53,56 @@ Rectangle { spacing: 0 model: activitiesModel delegate: activitiesContact - } + } - ListModel{id: activitiesModel} + ListModel{id: activitiesModel} - Component { id:activitiesContact - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - radius:0.5*mm - width:parent.width - height:6*mm - Image { - id: contactImage - x:1 - y:1 - width: 5*mm - height:5*mm - source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url - onStatusChanged: if (contactImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} - } - Text{ - font.pointSize: osSettings.bigFontSize - anchors.left: contactImage.right - anchors.margins: 1*mm - text:contact.name - } + Component { + id:activitiesContact + Rectangle{ + //border.color: Material.frameColor + color: osSettings.backgroundColor + border.width: 1 + radius:0.5*mm + width:parent.width + height:6*mm + Image { + id: contactImage + x:1 + y:1 + width: 5*mm + height:5*mm + source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url + onStatusChanged: if (contactImage.status == Image.Error) {source="qrc:/assets/defaultcontact.jpg"} + } + Text{ + color: osSettings.primaryTextColor + font.pointSize: osSettings.bigFontSize + anchors.left: contactImage.right + anchors.margins: 1*mm + text:contact.name + } MouseArea{ anchors.fill: parent onClicked:{showContact(contact)} } - }} + } + } MButton { - id: closeButton - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - color:"white" - text: "\uf057"// qsTr("Close") - onClicked: { - activitiesRectangle.destroy() - } + id: closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + onClicked: { + activitiesRectangle.destroy() + } } Component.onCompleted: { diff --git a/source-linux/qml/newsqml/Hashtag.qml b/src/qml/newsqml/Hashtag.qml similarity index 89% rename from source-linux/qml/newsqml/Hashtag.qml rename to src/qml/newsqml/Hashtag.qml index 47602c5..28aa64c 100644 --- a/source-linux/qml/newsqml/Hashtag.qml +++ b/src/qml/newsqml/Hashtag.qml @@ -29,18 +29,19 @@ // 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 6.3 Rectangle { - id:hasgtagRectangle - color: "light grey" + id:hashtagRectangle + color: osSettings.dialogColor property alias text: hashtagText.text radius:0.3*mm width:hashtagText.contentWidth+mm - height:2.5* mm + height:root.fontFactor*osSettings.bigFontSize Text{ id:hashtagText - font.pixelSize: 1.5*mm + font.pointSize: osSettings.systemFontSize + color: osSettings.secondaryTextColor anchors.centerIn: parent anchors.margins: 0.5*mm } diff --git a/src/qml/newsqml/MessageImageUploadDialog.qml b/src/qml/newsqml/MessageImageUploadDialog.qml new file mode 100644 index 0000000..492c535 --- /dev/null +++ b/src/qml/newsqml/MessageImageUploadDialog.qml @@ -0,0 +1,310 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Page{ + id:imageDialog + property var attachImageURLs: [] + // property var contacts: [] + // property var groups: [] + // property var contact_allow:login.permissions[0] + // property var contact_deny:login.permissions[1] + // property var group_allow:login.permissions[2] + // property var group_deny:login.permissions[3] + property int imageNo: 0 + + function uploadImage(imageid){ + if(imageUploadModel.get(imageid).uploaded==true){ + imageNo=imageNo+1; + if(imageNo0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))}; + //if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; + //if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; + //if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; + xhr.setImageFileParam("media", imageUploadModel.get(imageid).imageUrl); + xhr.setImageFileParam("angle", imageUploadModel.get(imageid).imageRotation); + xhr.post(); + } + } + + function updateAltText(imageid, media){ + xhr.setAccount(login); + xhr.setApi("/api/media/metadata/create"); + xhr.setParam("JSON",JSON.stringify({media_id:media,alt_text:{text:imageUploadModel.get(imageid).description}})); + xhr.postJSON(); + } + + function attach(){ + imagePicking=true; + var imagePicker = Qt.createQmlObject('import QtQuick 6.3; import "qrc:/qml/genericqml";'+ + osSettings.imagePickQml+'{multiple : false;onReady: {'+ + 'attachImage(imageUrl)}}',imageDialog,"imagePicker"); + imagePicker.pickImage() + } + + function attachImage(url){ + if (url.indexOf(",")>0){ + let urlArray=url.split(","); + for (let file in urlArray){attachImage(urlArray[file])} + } else{ + if(url!=""){ + imageUploadModel.append({"imageUrl":url,"description":"","imageUploaded":false,"imageRotation":0}) + } + } + } + + y:1 + width: messageColumn.width-1.5*root.fontFactor*osSettings.bigFontSize + height: 15*root.fontFactor*osSettings.bigFontSize//root.height/2-1.5*root.fontFactor*osSettings.bigFontSize + + onVisibleChanged: {if (visible==false){ + imageUploadModel.clear(); + imageNo=0; + }} + + Connections{ + target:xhr + function onError(data,url,api,code){ + print("error "+data); + } + function onSuccess(data,api){ + if (api=="/api/media/upload" ){ + let obj=JSON.parse(data); + messageSend.media_ids.push(obj.media_id); + if(imageUploadModel.get(imageNo).description!==""){ + try{ + updateAltText(imageNo,obj.media_id_string) + }catch(e){} + } + else{ + imageUploadModel.set(imageNo,{"imageUploaded":true}); + imageNo=imageNo+1; + if(imageNo0){ + uploadImage(imageNo) + }} + } + } + ProgressBar{ + id: newimageProgress + width: 5*root.fontFactor*osSettings.bigFontSize + height: root.fontFactor*osSettings.systemFontSize//buttonRow.height + anchors.top: parent.top + visible: false + value: imageNo/imageUploadModel.count + } +} diff --git a/src/qml/newsqml/MessageSend.qml b/src/qml/newsqml/MessageSend.qml new file mode 100644 index 0000000..6dce620 --- /dev/null +++ b/src/qml/newsqml/MessageSend.qml @@ -0,0 +1,615 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 . + +// message.qml +// message with buttons +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import QtQuick.Window 2.0; +import QtQuick.Dialogs 6.3; +//import Qt.labs.platform 6.3 as Platform +import io.qt.examples.texteditor 1.0; +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" +import "qrc:/qml/newsqml" + +Window{ + color: osSettings.backgroundColor + width: parent.width + height: 2/3*parent.height + id: messageSend + title: (reply_to_user!="")?qsTr("Answer to")+" @"+reply_to_user:qsTr("New message") + property bool wideScreen : width>height + property string parentId: "" + property string reply_to_user:"" + property string windowstate:"" + property alias bodyMessage: bodyField.text + property var media_ids:[] + property var contacts: [] + property var groups: [] + property var contact_allow:login.hasOwnProperty("permissions")?login.permissions[0]:[] + property var contact_deny:login.hasOwnProperty("permissions")?login.permissions[1]:[] + property var group_allow:login.hasOwnProperty("permissions")?login.permissions[2]:[] + property var group_deny:login.hasOwnProperty("permissions")?login.permissions[3]:[] + + function sendUrls(urls){ + attachImage(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){ + if(url!=""){ + imageUploadDialog.visible=true; + imageUploadDialog.attachImage(url) + } + } + + function statusUpdate(title,status,in_reply_to_status_id) { + try{newsBusy.running=true;conversationBusy.running=true}catch(e){} + xhr.setAccount(login); + xhr.setApi("/api/statuses/update"); + xhr.setParam("source", "Friendiqa"); + xhr.setParam("status", status); + if (parentId!="") {xhr.setParam("in_reply_to_status_id", in_reply_to_status_id)}; + if (title!=="") {xhr.setParam("title", title)}; + // if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))}; + // if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; + // if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; + // if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; + if (media_ids.length>0) { + xhr.setParam("media_ids", media_ids.join()); + } + xhr.post(); + Newsjs.storeHashtags(login,db,status,root); + media_ids=[] + messageSend.close() + } + + function dmUpdate(title,text,replyto,screen_name) { + newsBusy.running=true; + xhr.setAccount(login); + xhr.setApi("/api/direct_messages/new"); + xhr.setParam("text", text); + xhr.setParam("screen_name", screen_name); + if (parentId!="") {xhr.setParam("replyto", replyto)}; + xhr.post(); + messageSend.close() + } + + function contactmenu(letter){ + Newsjs.listFriends(login,db,function(contacts){ + contactModel.clear(); + for (var i=0;i1){ + contact.screen_name=contact.screen_name+"+"+contacts.cid + } + if (windowstate=='directmessage'){ + receiverLabel.text=contact.screen_name; + reply_to_user=contact.screen_name + } else { + bodyField.remove(bodyField.getText(0,bodyField.cursorPosition).lastIndexOf(bodyField.contactprefix,bodyField.cursorPosition),bodyField.cursorPosition); + bodyField.insert(bodyField.cursorPosition, bodyField.contactprefix+contact.screen_name+" "); + bodyField.cursorPosition=bodyField.cursorPosition+contact.screen_name.length+1 + } + + contactSelector.visible=false + } + delegate: ContactComponent { } + } + ListModel{id:contactModel} + + ListView{ + id: tagSelector + visible: false + z:3 + x:2*root.fontFactor*osSettings.bigFontSize + width: parent.width-2.2*root.fontFactor*osSettings.bigFontSize + height: messageSend.height/2 + model:tagModel + clip: true + spacing: 0 + function processTagSelection(hashtag){ + bodyField.insert(bodyField.cursorPosition, hashtag+" "); + bodyField.cursorPosition=bodyField.cursorPosition+hashtag.length+1 + tagSelector.visible=false + } + delegate: MButton {text:tag;onClicked: tagSelector.processTagSelection(tag)} + } + ListModel{id:tagModel} + Row{ + id:formatRow + visible: wideScreen + spacing: mm + height: 3.5*root.fontFactor*osSettings.bigFontSize + x: 0.5*mm + MButton { + id: boldButton + //text: "\uf032" // icon-bold + text: qsTr("Bold") + display: AbstractButton.IconOnly + icon.name: "format-text-bold" + icon.source: "qrc:/assets/icons/bold.svg" + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Bold") + focusPolicy: Qt.NoFocus + onClicked: { + document.bold = !document.bold; + bodyField.forceActiveFocus() + } + } + MButton { + id: italicButton + //text: "\uf033" // icon-italic + text: qsTr("Format") + display: AbstractButton.IconOnly + icon.name: "format-text-italic" + icon.source: "qrc:/assets/icons/italic.svg" + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Italic") + focusPolicy: Qt.NoFocus + onClicked: {document.italic = !document.italic;bodyField.forceActiveFocus()} + } + + MButton { + id: liststyleButton + //text: "\uf03a" // icon-align-justify + text: qsTr("Format") + display: AbstractButton.IconOnly + icon.name: "format-list-unordered" + icon.source: "qrc:/assets/icons/list.svg" + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Create list") + onClicked: {document.liststyle = !document.liststyle;bodyField.forceActiveFocus()} + } + MButton { + id: codeblockButton + //text: "\uf121" // icon-code + text: qsTr("Format") + display: AbstractButton.IconOnly + icon.name: "format-text-code" + icon.source: "qrc:/assets/icons/code.svg" + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Format as code") + onClicked: {document.codeblock = !document.codeblock;bodyField.forceActiveFocus()} + } + MButton { + id: plainButton + text: bodyField.textFormat==TextEdit.PlainText?qsTr("Rendered"):qsTr("MD") // icon-code + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Show Markdown code") + onClicked: { + if(bodyField.textFormat==TextEdit.PlainText){ + bodyField.textFormat=TextEdit.MarkdownText;} + else {bodyField.textFormat=TextEdit.PlainText} + bodyField.forceActiveFocus() + } + } + MButton { + id: menuButton + //text: "\uf044" + text: qsTr("Format") + display: AbstractButton.IconOnly + icon.name: "view-more-symbolic"//"overflow-menu" + icon.source: "qrc:/assets/icons/ellipsis-v.svg" + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Edit") + onClicked: { contextMenu.open()} + } + } + //PermissionDialog{id:permissionDialog;x:mm;visible: false} + SmileyDialog{id:smileyDialog;x:mm;visible: false} + MessageImageUploadDialog{id:imageUploadDialog;visible: false} + Row{ + id:buttonRow + visible: true + spacing: mm + height: 3.5*root.fontFactor*osSettings.bigFontSize + x: 0.5*mm + + // MButton{id:permButton //Permissions not working in Friendica 02/2022 + // visible: !conversation && (newsSwipeview.stacktype!=="DirectMessages") + // height: 2*root.fontFactor*osSettings.bigFontSize + // width: 2*root.fontFactor*osSettings.bigFontSize + // 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:smileyButton + text: qsTr("emojies") + display: AbstractButton.IconOnly + icon.name: "smiley" + icon.source: "qrc:/assets/icons/smile-o.svg" + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Insert smiley") + onClicked: {if (smileyDialog.visible==false){smileyDialog.visible=true} else{smileyDialog.visible=false}} + } + + MButton{ + id:hastagButton + text: "#" + // display: AbstractButton.IconOnly + // icon.name: "tag-symbolic" + // icon.source: "qrc:/assets/icons/hashtag.svg" + // icon.width: root.fontFactor*osSettings.bigFontSize + // icon.height: root.fontFactor*osSettings.bigFontSize + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Insert previous hashtag") + onClicked: {if (tagSelector.visible==false){hashtagmenu()} else{tagSelector.visible=false}} + } + MButton{ + id:imagesButton + visible:(newsSwipeview.stacktype!="DirectMessages") + //text: "\uf03e" + text: qsTr("Image") + display: AbstractButton.IconOnly + icon.name: "viewimage" + icon.source: "qrc:/assets/icons/picture-o.svg" + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Insert images") + onClicked: { + if (imageUploadDialog.visible==false){ + imageUploadDialog.visible=true; + imageUploadDialog.attach() + } + else{imageUploadDialog.visible=false}} + } + + MButton { + id: cancelButton + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Cancel message") + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + onClicked: {messageSend.close()} + } + MButton { + id: formatButton + visible: !wideScreen + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Format message") + text: qsTr("Format") + display: AbstractButton.IconOnly + icon.name: "format-text-italic" + icon.source: "qrc:/assets/icons/font.svg" + onClicked: {formatRow.visible?formatRow.visible=false:formatRow.visible=true} + } + MButton { + id: sendButton + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Send message") + text: qsTr("Send") + display: AbstractButton.IconOnly + icon.name: "document-send" + icon.source: "qrc:/assets/icons/paper-plane-o.svg" + onClicked: { + var title=titleField.text.replace("\"","\'"); + var body=bodyField.getFormattedText(0,bodyField.length); + var dmbody=bodyField.getText(0,bodyField.length); + if (windowstate=="directmessage"){ + if (reply_to_user!=""){dmUpdate(title,dmbody,parentId,reply_to_user)} + else{Helperjs.showMessage(qsTr("Error"),qsTr("No receiver supplied!"),root)} + + }else { + body=body.replace(/\*\*/g,"__") + statusUpdate(title,body,parentId) + } + } + } + } + + } + } + Component.onCompleted:{ + if(parentId!="" &&reply_to_user!=""){ + receiverLabel.text=reply_to_user; + } + // root.replySignal.connect(setParent); + // root.directmessageSignal.connect(directmessagePrepare); + root.uploadSignal.connect(sendUrls); + root.sendtextSignal.connect(sendtext); + bodyField.forceActiveFocus() + } + + StateGroup{ + state: windowstate + states: [ + State { + name: "active" + PropertyChanges { + target: messageColumn; height: implicitHeight + } + PropertyChanges { + target: titleField; visible: true + } + + }, + State { + name: "directmessage" + PropertyChanges { + target: messageColumn; height: implicitHeight + } + PropertyChanges { + target: formatRow; visible: false + } + PropertyChanges { + target: titleField; visible: false + } + PropertyChanges { + target: receiverLabel; visible: true; + } + PropertyChanges { + target: imagesButton; visible: false + } + PropertyChanges { + target: formatButton; visible: false + } }, + + State { + name: "reply" + PropertyChanges { + target: messageColumn; height: implicitHeight + } + PropertyChanges { + target: titleField; visible: false + } + PropertyChanges { + target: bodyField; placeholderText:"";focus:true + } + } + ] + } +} diff --git a/source-linux/qml/newsqml/MoreComments.qml b/src/qml/newsqml/MoreComments.qml similarity index 90% rename from source-linux/qml/newsqml/MoreComments.qml rename to src/qml/newsqml/MoreComments.qml index 9a7f03c..ccb3510 100644 --- a/source-linux/qml/newsqml/MoreComments.qml +++ b/src/qml/newsqml/MoreComments.qml @@ -29,15 +29,14 @@ // 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 6.3 + Rectangle{ id: moreComments width: parent.width - height: 5*mm - color:"white" + height: root.fontFactor*osSettings.bigFontSize*2 + color:osSettings.backgroundColor property int comments:0 -// border.color:"grey" -// border.width:1 signal clicked state:"" @@ -48,8 +47,8 @@ Rectangle{ anchors.margins: mm width: contentWidth height: contentHeight - font.family:fontAwesome.name - text: qsTr("Show all comments")+" (" +comments + ")" //"\uf0dc" + //font.family:fontAwesome.name + text: qsTr("Show all comments")+" (" +comments + ")" } MouseArea{ id:buttonArea diff --git a/source-linux/qml/newsqml/NewsImage.qml b/src/qml/newsqml/NewsImage.qml similarity index 95% rename from source-linux/qml/newsqml/NewsImage.qml rename to src/qml/newsqml/NewsImage.qml index 9527959..c3a76c6 100644 --- a/source-linux/qml/newsqml/NewsImage.qml +++ b/src/qml/newsqml/NewsImage.qml @@ -29,9 +29,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.9 +import QtQuick 6.3 AnimatedImage {id:gif; width:toprow.width; + cache:false + smooth: false //property string mimetype:"" fillMode: Image.PreserveAspectFit; onStatusChanged: {playing = (status == AnimatedImage.Ready)} @@ -52,6 +54,8 @@ AnimatedImage {id:gif; } MouseArea {anchors.fill:parent; onClicked:{ - rootstackView.push("qrc:/qml/newsqml/NewsPhotolist.qml",{"photolistarray": model.newsitemobject.imageAttachmentList})} + rootstackView.push("qrc:/qml/newsqml/NewsPhotolist.qml",{"photolistarray": model.newsitemobject.imageAttachmentList}) + //roottoolbar.visible=false + } } } diff --git a/source-linux/qml/newsqml/NewsPhotolist.qml b/src/qml/newsqml/NewsPhotolist.qml similarity index 72% rename from source-linux/qml/newsqml/NewsPhotolist.qml rename to src/qml/newsqml/NewsPhotolist.qml index 62ca124..831ecd4 100644 --- a/source-linux/qml/newsqml/NewsPhotolist.qml +++ b/src/qml/newsqml/NewsPhotolist.qml @@ -30,14 +30,14 @@ // along with this program. If not, see . -import QtQuick 2.9 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/genericqml" Page{ id:photolistview width:root.width; - height:root.height//-7*mm + height:root.height property var photolistarray: [] Rectangle{ @@ -49,6 +49,7 @@ Page{ anchors.fill: parent orientation: Qt.Horizontal highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem + spacing: root.fontFactor*osSettings.systemFontSize model:photolistModel delegate: photoWrapper } @@ -64,8 +65,15 @@ Page{ anchors.topMargin: 1*mm anchors.right: parent.right anchors.rightMargin: 1*mm - text: "\uf057" - onClicked: {if (rootstackView.depth>1){ rootstackView.pop()} + color: osSettings.dialogColor + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + onClicked: { + if (rootstackView.depth>1){ + //roottoolbar.visible=true; + rootstackView.pop()} } } Component { @@ -85,42 +93,49 @@ Page{ running: realImage.status==Image.Loading anchors.centerIn: parent } + PinchArea { + id:imagePinch + pinch.target: realImage + anchors.fill: realImage + pinch.minimumScale: 0.1 + pinch.maximumScale: 10 + enabled: true + } } -// PinchArea { -// id:imagePinch -// pinch.target: realImage -// anchors.fill: realImage -// pinch.minimumScale: 0.1 -// pinch.maximumScale: 10 -// enabled: false -// } + } - BlueButton{ + MButton{ width: 5*mm height:photolistview.height anchors.left: newsphotolistView.left visible: newsphotolistView.currentIndex!=0 - text:"\uf053" - fontColor:"grey" - border.color: "transparent" - color:"transparent" - radius:0 + // text:"\uf053" + // fontColor:"grey" + // border.color: "transparent" + // color:"transparent" + // radius:0 + display: AbstractButton.IconOnly + icon.name: "arrow-left" + icon.source: "qrc:/assets/icons/angle-left.svg" onClicked: {newsphotolistView.currentIndex=newsphotolistView.currentIndex-1} } - BlueButton{ + MButton{ width: 5*mm height:photolistview.height anchors.right: newsphotolistView.right visible: newsphotolistView.currentIndex!=photolistarray.length-1 - text:"\uf054" - fontColor:"grey" - border.color: "transparent" - color:"transparent" - radius:0 + // text:"\uf054" + // fontColor:"grey" + // border.color: "transparent" + // color:"transparent" + // radius:0 + display: AbstractButton.IconOnly + icon.name: "arrow-right" + icon.source: "qrc:/assets/icons/angle-right.svg" onClicked: {newsphotolistView.currentIndex=newsphotolistView.currentIndex+1} } @@ -131,4 +146,5 @@ Page{ }) } } + //onDestroyed: root.roottoolbar.visible=true } diff --git a/src/qml/newsqml/NewsStack.qml b/src/qml/newsqml/NewsStack.qml new file mode 100644 index 0000000..44b8608 --- /dev/null +++ b/src/qml/newsqml/NewsStack.qml @@ -0,0 +1,568 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import "qrc:/js/news.js" as Newsjs +import "qrc:/js/helper.js" as Helperjs +import "qrc:/js/service.js" as Service +import "qrc:/qml/genericqml" + +Rectangle{ + id: newsStack + color: osSettings.backgroundColor + property string updateMethodNews: "refresh" + property var allchats: ({}) + property int lastnewsid:0 + property string newstabstatus: "" + + function newstypeHandling(newstype){ + newsModel.clear(); + //if (!newsBusy.running) { + try{newsBusy.running=true}catch(e){print("newsBusy.running=true " + e)}; + //root.replySignal(""); + 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": + updateMethodNews="conversation"; + newstab.newstabstatus="Conversations"; + Newsjs.chatsfromdb(root.db,root.login,0,[],function(news,lastid){ + lastnewsid=lastid; + showNews(news)}); + break; + case "favorites": + updateMethodNews="refresh"; + newstab.newstabstatus="Favorites"; + Service.updateView("Favorites"); + expectScreenUpdate=true; + break; + case "replies": + updateMethodNews="refresh"; + newstab.newstabstatus="Replies"; + Service.updateView("Replies"); + expectScreenUpdate=true; + break; + case "publictimeline": + updateMethodNews="refresh"; + newstab.newstabstatus="Public Timeline"; + Service.updateView("Public Timeline"); + expectScreenUpdate=true; + break; + case "groupnews": + updateMethodNews="refresh"; + newstab.newstabstatus="Groupnews"; + Service.showGroups(); + expectScreenUpdate=true; + break; + case "search": + newsView.anchors.topMargin=root.fontFactor*osSettings.bigFontSize*3; + newstab.newstabstatus="Search"; + newsBusy.running=false; + searchBox.visible=true; + break; + case "refresh": + if (newstab.newstabstatus=="Timeline" || newstabstatus=="Timeline"){ + updateMethodNews="append" + } else if (newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ + updateMethodNews="conversation"} + else {updateMethodNews="refresh"} + //root.contactLoadType="news"; + if (newsSwipeview.stacktype=="Home"){ + Service.updateView(newstab.newstabstatus,lastnewsid) + } + else if (newsSwipeview.stacktype=="Directmessage"){ + Service.updateView("Direct Messages",lastnewsid) + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications") + } + expectScreenUpdate=true; + break; + default: + if (newstab.newstabstatus=="Timeline" || newstabstatus=="Timeline"){ + updateMethodNews="append" + } else if (newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ + updateMethodNews="conversation"} + else {updateMethodNews="refresh"} + //root.contactLoadType="news"; + if (newsSwipeview.stacktype=="Home"){ + Service.updateView(newstab.newstabstatus,lastnewsid) + } + else if (newsSwipeview.stacktype=="DirectMessages"){ + Service.updateView("Direct Messages",lastnewsid) + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications",lastnewsid) + } + else if (newsSwipeview.stacktype=="Favorites"){ + Service.updateView("Favorites",lastnewsid) + } + else if (newsSwipeview.stacktype=="Replies"){ + Service.updateView("Replies",lastnewsid) + } + else if (newsSwipeview.stacktype=="Public Timeline"){ + Service.updateView("Public Timeline",lastnewsid) + } + else if (newsSwipeview.stacktype=="Search"){ + Service.updateView("Search",lastnewsid) + } + else{ + Service.updateView(newstab.newstabstatus,lastnewsid) + } + expectScreenUpdate=true; + //} + } + } + + function showNews(newsToShow){ + try{if (rootstackView.depth>1){rootstackView.pop()}}catch(e){} + newsBusy.running=false; + if(newsToShow.length>0){ + var currentTime= new Date() + // downloadNotice.text=downloadNotice.text + "\n shownews start "+ Date.now(); + if (newsToShow.length==1){var method="refresh"}else{var method = updateMethodNews} + var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow,'method':method, 'options':globaloptions}; + newsWorker.sendMessage(msg); + } + } + + function search(term){ + if (term!=""){ + newsBusy.running=true; + newsSwipeview.stacktype="Search"; + updateMethodNews="refresh"; + xhr.setAccount(login); + xhr.setApi("/api/search/tweets"); + xhr.setParam("q",term) + xhr.get(); + expectScreenUpdate=true; + } + newsView.anchors.topMargin=mm + } + + function getOldNews(){ + var currentTime= new Date(); + + try{var oldnewsitemobject=newsModel.get(newsModel.count-1).newsitemobject; + if(oldnewsitemobject.hasOwnProperty("lastcomment")){ + var lastnews_id=oldnewsitemobject.lastcomment.created_at; + }else{ + var lastnews_id=oldnewsitemobject.created_at; + } + } catch(e){print(e);var lastnews_id=99999999999999} + 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(newsSwipeview.stacktype!="Home"|| newstab.newstabstatus=="Timeline" || newstabstatus=="Timeline" ){ + Newsjs.newsfromdb(root.db,root.login, messagetype,function(news){ + var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'method':"", 'options':globaloptions}; + newsWorker.sendMessage(msg); + },false,lastnews_id)} + + else if(newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ + var currentconversations=[]; + for (let c=0;c5*mm){ + viewdraggedpositive=true + } + else{ + if((contentY-oldContentY)>15*mm){ + //swipeIndicator.visible=false; + //newsSwipeview.height=rootstack.height; + //newsSwipeview.y=0; + //rootStackItem.state="fullscreen" + } + else if ((contentY-oldContentY)<-15*mm){ + //swipeIndicator.visible=true; + //newsSwipeview.height=rootstack.height-12*mm; + //newsSwipeview.y=5*mm; + //rootStackItem.state="" + } + } + } + onViewdraggedChanged: { + if (viewdragged){ + var onlynew=true; + newsBusy.running=true; + viewdragged=false + if (newstab.newstabstatus=="Timeline" || newstabstatus=="Timeline"){ + updateMethodNews="append" + } else if (newstab.newstabstatus=="Conversations" || newstabstatus=="Conversations"){ + updateMethodNews="conversation"} + else {updateMethodNews="refresh"} + let currentnewstabstatus="Conversations"; + if (newstab.newstabstatus!=""){ + currentnewstabstatus=newstab.newstabstatus + }else if (newstabstatus!=""){ + currentnewstabstatus=newstabstatus + } + + if (newsSwipeview.stacktype=="Home"){ + Newsjs.getLastNews(root.login,root.db,function(currentlastnews){ + if (currentlastnews>lastnewsid){ + if(currentnewstabstatus=="Timeline"){ + try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){ + lastnewsid=lastid; + showNews(dbnews) + })}catch(e){Helperjs.showMessage("Error",e,root)}; + } + if(currentnewstabstatus=="Conversations"){ + Newsjs.chatsfromdb(db,root.login,0,[],function(news,lastid){ + lastnewsid=lastid; + showNews(news)}); + } + } else { + expectScreenUpdate=true; + Service.updateView(currentnewstabstatus,currentlastnews) + } + }); + } + else if (newsSwipeview.stacktype=="DirectMessages"){ + Service.updateView("Direct Messages") + expectScreenUpdate=true; + } + else if (newsSwipeview.stacktype=="Notifications"){ + Service.updateView("Notifications") + expectScreenUpdate=true; + } + else if (newsSwipeview.stacktype=="Replies"){ + Service.updateView("Replies") + expectScreenUpdate=true; + } + + } + } + onViewdraggedpositiveChanged: { + if (viewdraggedpositive){ + getOldNews(); + viewdraggedpositive=false + } + } + ScrollBar.vertical: ScrollBar { } + } + + ListModel{id: newsModel} + + WorkerScript { + id: newsWorker + source: "qrc:/js/newsworker.js" + } + + 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.pointSize: osSettings.systemFontSize + text:"" + } + } + + Component.onCompleted: { + root.newsSignal.connect(showNews); + root.searchSignal.connect(search); + try{newsModel.clear()} catch(e){} + swipeIndicator.visible=true; + root.globaloptions.hasOwnProperty("newsViewType")?newstab.newstabstatus=root.globaloptions.newsViewType:newstab.newstabstatus="Conversations"; + newstabstatus=newstab.newstabstatus; + if(newsSwipeview.stacktype=="Search"){searchBox.visible=true} //else if (newsSwipeview.stacktype=="Group News"){newstypeHandling("groupnews")} + if(["Home","DirectMessages","Notifications","Replies"].indexOf(newsSwipeview.stacktype)>-1){loadDBNews()} + } +} diff --git a/src/qml/newsqml/NewsTab.qml b/src/qml/newsqml/NewsTab.qml new file mode 100644 index 0000000..61dfa98 --- /dev/null +++ b/src/qml/newsqml/NewsTab.qml @@ -0,0 +1,293 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import "qrc:/qml/newsqml" +import "qrc:/qml/genericqml" +import "qrc:/js/news.js" as Newsjs +import "qrc:/js/helper.js" as Helperjs +import "qrc:/js/service.js" as Service + +Page{ + id:newstabitem + width:rootstack.width + height: rootstack.height + property var newstypes: globaloptions.hasOwnProperty("defaultNewsTypes")?globaloptions.defaultNewsTypes:["Home","Replies","DirectMessages","Notifications"] + property bool expectScreenUpdate: false + + Timer {id:contacttimer; interval: 50; running: false; repeat: false + onTriggered: { + root.newContacts=Newsjs.findNewContacts(root.news,root.contactlist); + root.onNewContactsChanged(root.newContacts); + Newsjs.storeNews(login,db,root.news,root) + } + } + + function showConversation(conversationIndex,newsitemobject){ + expectScreenUpdate=true; + if(newsitemobject.messagetype==0 || newsitemobject.messagetype==3){ + xhr.setAccount(login); + xhr.setApi("/api/conversation/show"); + xhr.setParam("id",newsitemobject.id) + xhr.setParam("count","200") + xhr.get(); + } + else{ + xhr.setAccount(login); + xhr.setApi("/api/direct_messages/conversation"); + xhr.setParam("uri",newsitemobject.statusnet_conversation_id) + xhr.get(); + } + } + + function getDateDiffString (seconds){ + var timestring=""; + if (seconds<60) {timestring= Math.round(seconds) + " " +qsTr("seconds");} + else if (seconds<90){timestring= Math.round(seconds/60) + " " +qsTr("minute") ;} + else if (seconds<3600){timestring= Math.round(seconds/60) + " " +qsTr("minutes");} + else if (seconds<5400){timestring= Math.round(seconds/3600) + " " +qsTr("hour");} + else if (seconds<86400){timestring= Math.round(seconds/3600) + " " +qsTr("hours");} + else if (seconds<129600){timestring= Math.round(seconds/86400) + " " +qsTr("day");} + else if (seconds<3888000){timestring= Math.round(seconds/86400) + " " +qsTr("days");} + else if (seconds<5832000){timestring= Math.round(seconds/3888000) + " " +qsTr("month");} + else if (seconds<69984000){timestring= Math.round(seconds/3888000) + " " +qsTr("months");} + else {timestring= Math.round(seconds/46656000) + " " + qsTr("years");} + + return timestring; + } + + function getActivitiesView(newsitemobject){ + var likeText="";var dislikeText="";var attendyesText="";var attendnoText="";var attendmaybeText=""; var self={}; + try{if (newsitemobject.messagetype==0&&newsitemobject.hasOwnProperty('friendica_activities')){ + if (newsitemobject.friendica_activities.like.length>0){ + if (newsitemobject.friendica_activities.like.length==1){likeText= newsitemobject.friendica_activities.like[0].name+" "+ qsTr("likes this.")} + else {likeText= newsitemobject.friendica_activities.like.length+" "+ qsTr("like this.")} + } + if (newsitemobject.friendica_activities.dislike.length>0){ + if (newsitemobject.friendica_activities.dislike.length==1){dislikeText= newsitemobject.friendica_activities.dislike[0].name+" "+ qsTr("doesn't like this.")} + else {dislikeText= newsitemobject.friendica_activities.dislike.length+" "+ qsTr("don't like this.")} + } + if (newsitemobject.friendica_activities.attendyes.length>0){ + if (newsitemobject.friendica_activities.attendyes.length==1){attendyesText=newsitemobject.friendica_activities.attendyes[0].name+" "+ qsTr("will attend.")} + else {attendyesText= newsitemobject.friendica_activities.attendyes.length+" "+ qsTr("persons will attend.")} + } + if (newsitemobject.friendica_activities.attendno.length>0){ + if (newsitemobject.friendica_activities.attendno.length==1){attendnoText= newsitemobject.friendica_activities.attendno[0].name+" "+ qsTr("will not attend.")} + else {attendnoText= newsitemobject.friendica_activities.attendno.length+" "+ qsTr("persons will not attend.")} + } + if (newsitemobject.friendica_activities.attendmaybe.length>0){ + if (newsitemobject.friendica_activities.attendmaybe.length==1){attendmaybeText= newsitemobject.friendica_activities.attendmaybe[0].name+" "+ qsTr("may attend.")} + else {attendmaybeText= newsitemobject.friendica_activities.attendmaybe.length+" "+ qsTr("persons may attend.")} + } + //var friendica_activities_self=JSON.parse(newsitemobject.friendica_activities_self); + }} catch(e){print("Activities "+e+ " "+JSON.stringify(newsitemobject.friendica_activities))} + return {likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText} + } + + function openMessageSend(messageState,newsitemobject){ + var parentId="" + var replyUser="" + if(newsitemobject!=""){ + parentId=newsitemobject.id + replyUser=newsitemobject.user.screen_name; + } + // var messageString='import qtquick 6.3; import QtQuick.Window 2.0; import "qrc:/qml/newsqml";'+ + // ' Window{id:messageWindow; title:"Message"; width:root.width; height:root.height; '+ + // 'MessageSend{state:"'+messageState+'"} Component.onCompleted: {x=Screen.width/2-width/2; y=Screen.height/2-height/2}}'; + // var messageObject=Qt.createQmlObject(messageString,root,"messageOutput"); + var messageObject = Qt.createComponent("qrc:/qml/newsqml/MessageSend.qml"); + var messageWindow=messageObject.createObject(root, { parentId: parentId, reply_to_user: replyUser, windowstate: messageState }); + messageWindow.show(); + } + +// function getIcon(typerequest){ +// switch (typerequest){ +// case "Home": return "\uf015" +// case "Favorites": return "\uf005"; +// case "Replies": return "\uf0ec"; +// case "DirectMessages": return "\uf0e0"; +// case "Public Timeline": return "\uf0ac"; +// case "Group News": return "\uf0c0"; +// case "Search": return "\uf002"; +// case "Notifications": return "\uf0f3"; +// } +// } + + function getIcon(typerequest){ + switch (typerequest){ + case "Home": return {iconName:"user-home-symbolic",iconUrl:"qrc:/assets/icons/home.svg"}; + case "Favorites": return {iconName:"starred-symbolic",iconUrl:"qrc:/assets/icons/star.svg"}; + case "Replies": return {iconName:"mail-reply-all-symbolic",iconUrl:"qrc:/assets/icons/exchange.svg"}; + case "DirectMessages": return {iconName:"mail-message",iconUrl:"qrc:/assets/icons/envelope.svg"}; + case "Public Timeline": return {iconName:"globe",iconUrl:"qrc:/assets/icons/globe.svg"}; + case "Group News": return {iconName:"group",iconUrl:"qrc:/assets/icons/users.svg"}; + case "Search": return {iconName:"system-search",iconUrl:"qrc:/assets/icons/search.svg"}; + case "Notifications": return {iconName:"notifications",iconUrl:"qrc:/assets/icons/bell.svg"}; + } + } + + function addToolbutton(buttontype){ + var component = Qt.createComponent("qrc:/qml/newsqml/NewsTabbutton.qml"); + var tabcomp = component.createObject(newstabbar,{buttontype:buttontype,"buttonIcon":getIcon(buttontype)}); + newstabbar.addItem(tabcomp); + } + // CalendarTab{ + // visible: wideScreen&&rootstackView.depth<2 + // width: newstabitem.width/3 + // x: newsSwipeview.width + // //anchors.left: newsSwipeview.right + // //anchors.fill: null + // } + // Rectangle{ + // color: "#F8F8F8" + // height: parent.height + // width: 0.5*mm + // anchors.left: newsSwipeview.right + // } + + //MessageSend{} + + //BlueButton{ + + + MButton{ + z:2 + anchors.right: parent.right + anchors.bottom: newsSwipeview.bottom + // fontColor: "grey" + // border.color: "transparent" + icon.name: "document-edit-symbolic" //"open-for-editing" + //text: "o \uf040" + //implicitHeight: root.fontFactor*osSettings.bigFontSize + onClicked:{ + if (newsSwipeview.stacktype=="DirectMessages"){openMessageSend("directmessage","")} + else {openMessageSend("active","")} + } + } + + LeftDrawerLinux{ + id:leftDrawer + property var newstabstatus: newstab.newstabstatus + visible: wideScreen&&rootstackView.depth<2 + width: visible?root.fontFactor*osSettings.systemFontSize*15:0 + height: root.height-bar.height + } + + LeftDrawerAndroid{ + id: leftDrawerAndroid + } + + TabBar { + id: newstabbar + x: leftDrawer.width + width: newsSwipeview.width + height: contentHeight+2 + spacing: 1 + position: TabBar.Header + onCurrentIndexChanged: { + newsSwipeview.currentIndex=newstabbar.currentIndex; + } + clip: true + } + + SwipeView{ + id: newsSwipeview + property string stacktype:"Home" + width: wideScreen&&rootstackView.depth<2?newstabitem.width-leftDrawer.width:newstabitem.width//newstabitem.width/3*2:newstabitem.width + height: newstabitem.height-(newstabbar.height+root.fontFactor*osSettings.systemFontSize) + x: leftDrawer.width + y: newstabbar.height + //function onDirectMessage(friend){currentIndex=2} + + onCurrentIndexChanged: { + if(newstypes[currentIndex]){stacktype=newstypes[currentIndex]} + else{stacktype="Home"} + newstabbar.currentIndex=newsSwipeview.currentIndex; + } + + Loader{ + source:(newsSwipeview.currentIndex==0)? "qrc:/qml/newsqml/NewsStack.qml":"" + } + Loader{ + source:(newsSwipeview.currentIndex==1)? "qrc:/qml/newsqml/NewsStack.qml":"" + } + Loader{ + source:(newsSwipeview.currentIndex==2)? "qrc:/qml/newsqml/NewsStack.qml":"" + } + Loader{ + source:(newsSwipeview.currentIndex==3)? "qrc:/qml/newsqml/NewsStack.qml":"" + } + } + + ToolButton{ + z:2 + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: newstabbar.height + visible: !wideScreen + icon.name: "application-menu" + icon.source: "qrc:/assets/icons/bars.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + onClicked:{ + leftDrawerAndroid.visible?leftDrawerAndroid.close():leftDrawerAndroid.open()} + } + + PageIndicator { + id: swipeIndicator + z:5 + height: root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + count: newsSwipeview.count + currentIndex: newsSwipeview.currentIndex + anchors.bottom: newsSwipeview.bottom + anchors.horizontalCenter: parent.horizontalCenter + } + + Connections{ + target: root + function onGlobaloptionsChanged(){ + newstypes=globaloptions.defaultNewsTypes; + while (newstabbar.count>0){ + newstabbar.removeItem(newstabbar.contentData[0]); + } + for (let view in newstypes){ + addToolbutton(newstypes[view]) + } + } + } + + Component.onCompleted: { + root.sendmessageSignal.connect(openMessageSend); + root.globaloptionsChanged(); + } +} diff --git a/source-linux/qml/newsqml/NewsVideo.qml b/src/qml/newsqml/NewsTabbutton.qml similarity index 63% rename from source-linux/qml/newsqml/NewsVideo.qml rename to src/qml/newsqml/NewsTabbutton.qml index 2e7d899..d8c6e14 100644 --- a/source-linux/qml/newsqml/NewsVideo.qml +++ b/src/qml/newsqml/NewsTabbutton.qml @@ -29,31 +29,28 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.9 +import QtQuick 6.3 +import QtQuick.Controls 6.3 -Rectangle{ - color:"black" - //border.color: "light grey" - width:toprow.width/2; - height:toprow.width/3//video.hasVideo?newscolumn.width/4*3:10*mm - property var attachment:({}) - Text{ - id:noticeText - text:"\uf144"; - color:"light grey" - width:parent.width - font.pixelSize: parent.height/2 - x: (parent.width-contentWidth)/2 - y:parent.height/5 - } - - MouseArea {anchors.fill:parent; - onClicked:{ - if(attachment.mimetype=="video/youtube"){ - rootstackView.push("qrc:/qml/newsqml/NewsYplayer.qml",{"ytcode":attachment.url,"mimetype":attachment.mimetype}); - } else { - rootstackView.push("qrc:/qml/newsqml/NewsVideoLarge.qml",{"source": attachment.url,"mimetype": attachment.mimetype}); - } - } - } +TabButton { + id: tabbutton + //font.family: fontAwesome.name + font.pointSize : osSettings.bigFontSize + width: newstabbar.width/4 + property string buttontype: "" + property var buttonIcon: ({}) + icon.name: buttonIcon.iconName + icon.source: buttonIcon.iconUrl + //icon.color: newstypes[newsSwipeview.currentIndex]==buttontype?osSettings.accentColor:color + icon.height: root.fontFactor*osSettings.bigFontSize + icon.width: root.fontFactor*osSettings.bigFontSize + // background:Rectangle{ + // anchors.fill: parent + // color: osSettings.backgroundDimColor + // border.color: newstypes[newsSwipeview.currentIndex]==buttontype?osSettings.accentColor:color + // } + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr(buttontype) + onDoubleClicked: {newstypeSignal(buttontype)} } diff --git a/source-linux/qml/configqml/OSSettingsLinux.qml b/src/qml/newsqml/NewsVideo.qml similarity index 75% rename from source-linux/qml/configqml/OSSettingsLinux.qml rename to src/qml/newsqml/NewsVideo.qml index a758b26..7a72ccc 100644 --- a/source-linux/qml/configqml/OSSettingsLinux.qml +++ b/src/qml/newsqml/NewsVideo.qml @@ -29,15 +29,20 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick.Window 2.0 -import QtQuick 2.0 -QtObject{ - property real appWidth: Screen.desktopAvailableWidth/4*3 - property real appHeight: Screen.desktopAvailableHeight/4*3 - property int backKey: Qt.Key_Escape - property string osType: "Linux" - property int systemFontSize: root.font.pointSize*1.1 - property int bigFontSize: systemFontSize*1.5 - //property string attachImageDir:filesystem.homePath+"/Pictures/" - property string imagePickQml: "ImagePickerLinux" +import QtQuick 6.3 + +Rectangle{ + color:"light grey" + width: 7*root.fontFactor*osSettings.bigFontSize + height: 7*root.fontFactor*osSettings.bigFontSize + property var attachment:({}) + Image{ + anchors.fill: parent + source: "qrc:/assets/icons/play.svg" + } + MouseArea {anchors.fill:parent; + onClicked:{ + rootstackView.push("qrc:/qml/newsqml/NewsVideoLarge.qml",{"source": Qt.resolvedUrl(attachment.url),"mimetype": attachment.mimetype}); + } + } } diff --git a/source-linux/qml/newsqml/NewsVideoLarge.qml b/src/qml/newsqml/NewsVideoLarge.qml similarity index 52% rename from source-linux/qml/newsqml/NewsVideoLarge.qml rename to src/qml/newsqml/NewsVideoLarge.qml index e6cdda6..8f84683 100644 --- a/source-linux/qml/newsqml/NewsVideoLarge.qml +++ b/src/qml/newsqml/NewsVideoLarge.qml @@ -29,18 +29,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtMultimedia 5.8 -import QtQuick 2.9 -import QtQuick.Controls 2.12 - +import QtMultimedia 6.3 +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import "qrc:/qml/genericqml" Page{ id:newsvideofullscreen - //color:"black" - //border.color: "light grey" width:root.width; height:root.height-3*root.fontFactor*osSettings.bigFontSize - property alias source:video.source + property alias source: video.source + property string mimetype:"" + + Rectangle{ + anchors.fill: newsvideofullscreen + color: "black" + } + Text{ id:noticeText text:"" @@ -53,55 +58,83 @@ Page{ visible: video.playbackState!=MediaPlayer.PlayingState } - Video {id:video; - anchors.fill:parent - property string mimetype:"" - onErrorChanged:{noticeText.font.pointSize=osSettings.bigFontSize;noticeText.text=errorString;} - fillMode: Image.PreserveAspectFit; - autoLoad: true - autoPlay: true - audioRole: MediaPlayer.VideoRole - MouseArea { - anchors.fill:parent; - onClicked:{ - rootstackView.pop() - } - } + MediaPlayer { + id: video + audioOutput: AudioOutput {} + videoOutput: videoOutput + Component.onCompleted: {play()} + onErrorChanged: {noticeText.text=errorString;Qt.openUrlExternally(source)} } - ProgressBar{ - id: videoProgress - width: parent.width - height: 2*mm - anchors.bottom: video.bottom - z:2 - visible:video.playbackState!=MediaPlayer.StoppedState - value: video.position/video.duration - + VideoOutput { + id: videoOutput + anchors.fill: parent MouseArea { anchors.fill:parent; onClicked:{ if(video.playbackState!=MediaPlayer.PlayingState){ video.play()} else{video.pause() } + if(Math.round(video.position/video.duration*1000) == 1000){ + video.position=0;video.play() + } + } + } + + Rectangle{ + color:"light grey" + visible: video.playbackState!=MediaPlayer.PlayingState || (Math.round(video.position/video.duration*1000) == 1000) + opacity: 0.5 + anchors.centerIn: videoOutput + width: 5*root.fontFactor*osSettings.bigFontSize + height: 5*root.fontFactor*osSettings.bigFontSize + Image{ + anchors.fill: parent + source: "qrc:/assets/icons/play.svg" } } } - ProgressBar{ id: videoBuffer - width: parent.width - height: 2*mm - anchors.bottom: video.bottom - visible:video.playbackState!=MediaPlayer.StoppedState + width: parent.width-4*mm + x: 2*mm + height: mm + contentItem: Item { + Rectangle { + width: videoBuffer.visualPosition * parent.width + height: parent.height + color: "light blue" + } + } + anchors.bottom: parent.bottom value: video.bufferProgress } -// Slider{ id: videoSlider -// width: parent.width -// height: 3*mm -// anchors.top: video.bottom -// visible:video.playbackState!=MediaPlayer.StoppedState && video.seekable -// value: video.position/video.duration -// onPressed:video.seek(value*video.duration) -// } + + Slider{ + id: videoSlider + x: 2*mm + width: parent.width-4*mm + height: 2*mm + z: 2 + anchors.bottom: parent.bottom + visible:video.playbackState!=MediaPlayer.StoppedState && video.seekable + value: video.position/video.duration + onMoved: video.position=value*video.duration + } + + MButton { + id: closeButton + z:2 + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + opacity: 0.6 + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + onClicked: {if (rootstackView.depth>1){ rootstackView.pop()} + } + } } diff --git a/source-linux/qml/newsqml/Newsitem.qml b/src/qml/newsqml/Newsitem.qml similarity index 64% rename from source-linux/qml/newsqml/Newsitem.qml rename to src/qml/newsqml/Newsitem.qml index a7c4c9f..91f2044 100644 --- a/source-linux/qml/newsqml/Newsitem.qml +++ b/src/qml/newsqml/Newsitem.qml @@ -29,16 +29,16 @@ // 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 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/js/news.js" as Newsjs import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" Item { id: newsitem - width: newsitemobject.hasOwnProperty("indent")&&newsitemobject.indent>0?parent.width:newsitem.ListView.view.width//parent.width//newsView.width // - height:toprow.height+friendicaActivities.height+controlrow.height+conversationColumn.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm) + width: newsitemobject.hasOwnProperty("indent")&&newsitemobject.indent>0?parent.width:newsitem.ListView.view.width + height:toprow.height+friendicaActivities.height+controlrow.height+conversationColumn.height+1 property int itemindex: index property var newsitemobject:model.newsitemobject property string attending: "" @@ -55,25 +55,26 @@ Item { } function pushConversation(){ + //expectScreenUpdate=true; + showConversation(index,newsitemobject) if (model.newsitemobject.hasOwnProperty("currentconversation")){ rootstackView.push("qrc:/qml/newsqml/Conversation.qml",{"news": model.newsitemobject.currentconversation})} - //newsStack.push("qrc:/qml/newsqml/Conversation.qml",{"news": model.newsitemobject.currentconversation})} - //else{newsStack.push("qrc:/qml/newsqml/Conversation.qml")}; else{rootstackView.push("qrc:/qml/newsqml/Conversation.qml")}; - showConversation(index,newsitemobject) } - Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; color:"light grey"} + Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; + color: osSettings.backgroundDimColor + } Rectangle{ width:newsitem.width height:newsitem.height-1 - color: "white" + color: osSettings.backgroundColor Column { - id:toprow //newscolumn - width: newsitemobject.hasOwnProperty("indent")?newsitem.width-(newsitem.width/20 *(newsitemobject.indent+1)):newsitem.width//-8*mm - x:newsitemobject.hasOwnProperty("indent")?newsitem.width/20*(newsitemobject.indent):0 + id:toprow + width: newsitemobject.hasOwnProperty("indent")?newsitem.width-(newsitem.width/20 *(newsitemobject.indent+1))-mm:newsitem.width-mm + x:newsitemobject.hasOwnProperty("indent")?newsitem.width/20*(newsitemobject.indent)+0.5*mm:0.5*mm height: newsitemobject.nsfw?5*mm:Math.min(implicitHeight,3/4*root.height) clip: true Item{id:itemHeader @@ -92,7 +93,7 @@ Item { width: 2*root.fontFactor*osSettings.bigFontSize height: 2*root.fontFactor*osSettings.bigFontSize //radius:mm - onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} + onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/assets/defaultcontact.jpg"} } Flow{ id:topFlow @@ -102,7 +103,7 @@ Item { anchors.margins: mm Label { id:user_name - //color: "grey" + color: osSettings.primaryTextColor width:parent.width font.bold: true font.pointSize: osSettings.systemFontSize @@ -112,58 +113,53 @@ Item { Label { id:messageTypeLabel - color: "grey" + color: osSettings.secondaryTextColor text: if (newsitemobject.messagetype==1){ qsTr("Direct Message")} else if(newsitemobject.messagetype==2) {" Notification"} else {qsTr("Source: ")+newsitemobject.source} font.pointSize: 0.6*osSettings.systemFontSize } Label { id:createdAtLabel - color: "grey" + color: osSettings.secondaryTextColor font.pointSize: 0.6*osSettings.systemFontSize horizontalAlignment: Label.AlignRight text: " \u00B7 "+getDateDiffString(newsitemobject.dateDiff) + " " +qsTr("ago") } Label { id:replytoLabel - color: "grey" + color: osSettings.secondaryTextColor font.pointSize: 0.6*osSettings.systemFontSize font.family: "Noto Sans" horizontalAlignment: Label.AlignRight - text: try {" \u00B7 "+qsTr("In reply to ")+newsitemobject.reply_user.screen_name - }catch(e){" "} + text: (newsitemobject.reply_user!=false&&typeof(newsitemobject.reply_user)!="undefined")?" \u00B7 "+qsTr("In reply to ")+newsitemobject.reply_user.screen_name:" " } } - //Component.onCompleted:print("Newsitemwidth "+newsitem.width+ " Indent "+newsitemobject.indent) } MouseArea{id: itemBody width: toprow.width-2 height: itemMessage.height - onPressAndHold: {pushConversation()} + onClicked: {pushConversation()} Text { - color: "#404040" - linkColor: "light green" + color: osSettings.primaryTextColor + linkColor: osSettings.accentColor id: itemMessage textFormat: Text.RichText font.family: "Noto Sans" font.pointSize: osSettings.systemFontSize text: newsitemobject.statusnet_html width: toprow.width-2 - //height:newsitemobject.nsfw?5*mm:Math.min(implicitHeight,3/4*root.height) height: implicitHeight wrapMode: Text.Wrap clip:true - onLinkActivated:{Qt.openUrlExternally(link)} - Component.onCompleted:{ - if (newsitemobject.messagetype==0){ - var hashtags=[]; - hashtags=Newsjs.findTags(newsitemobject.text); - var component = Qt.createComponent("qrc:/qml/newsqml/Hashtag.qml"); - for (var tags in hashtags){ - var hashtagQml = component.createObject(friendicaActivities,{"text":hashtags[tags].trim()}); - } + onLinkActivated:{ + if(link.startsWith(root.login.server+"\/search\?tag=")){ + newstab.newstabstatus="Search"; + //root.searchSignal(link.substring(root.login.server.length+12,link.length)) + search((link.substring(root.login.server.length+12,link.length))) } - + else{Qt.openUrlExternally(link)} + } + Component.onCompleted:{ if (newsitemobject.imageAttachmentList.length>0){ if(newsitemobject.imageAttachmentList[0].mimetype.substring(0,5)=="image"){ var component = Qt.createComponent("qrc:/qml/newsqml/NewsImage.qml"); @@ -189,27 +185,30 @@ Item { } - BlueButton{ + Button{ width: newsitem.width-2 height:5*mm - anchors.bottom: toprow.bottom//itemMessage.bottom - visible: toprow.implicitHeight>3/4*root.height || newsitemobject.nsfw//messageColumn.implicitHeight>3/4*root.height || newsitemobject.nsfw//itemMessage.implicitHeight>3/4*root.height - text:"\uf078" - fontColor:"grey" - border.color: "transparent" - color:"white" - // gradient: Gradient { - // GradientStop { position: 0.0; color: "transparent" } - // GradientStop { position: 0.5; color: "white" } - // } - radius:0 + anchors.bottom: toprow.bottom + visible: toprow.implicitHeight>3/4*root.height || newsitemobject.nsfw + icon.name:"arrow-down" + icon.source: "qrc:/assets/icons/chevron-down.svg" + icon.width: 2*root.fontFactor*osSettings.bigFontSize + icon.height: 2*root.fontFactor*osSettings.bigFontSize + icon.color:"transparent" + background: Rectangle{ + gradient: Gradient { + GradientStop { position: 0.0; color: "transparent" } + GradientStop { position: 0.7; color: osSettings.backgroundColor} + } + } onClicked: { - if (text=="\uf078"){ - toprow.height=toprow.implicitHeight+6*mm;text="\uf077" + if (icon.name=="arrow-down"){ + toprow.height=toprow.implicitHeight+5*mm; + icon.name="arrow-up";icon.source="qrc:/assets/icons/chevron-up.svg"; } else { toprow.height=Math.min(toprow.implicitHeight,3/4*root.height); - text="\uf078"; - newsView.positionViewAtIndex(index,ListView.Beginning); + icon.name="arrow-down";icon.source="qrc:/assets/icons/chevron-down.svg"; + newsitem.ListView.view.positionViewAtIndex(index,ListView.Beginning); } } } @@ -221,45 +220,45 @@ Item { width:parent.width spacing:mm - Label{color: "grey" + Label{color: osSettings.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize - text: friendica_activities_view.likeText + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.likeText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.like)} } } - Label{color: "grey" + Label{color: osSettings.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize - text: friendica_activities_view.dislikeText + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.dislikeText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.dislike)} } } - Label{color: "grey" + Label{color: osSettings.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize - text: friendica_activities_view.attendyesText + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendyesText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendyes)} }} - Label{color: "grey" + Label{color: osSettings.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize - text: friendica_activities_view.attendnoText + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendnoText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendno)} } } - Label{color: "grey" + Label{color: osSettings.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize - text: friendica_activities_view.attendmaybeText + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendmaybeText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendmaybe)} @@ -267,7 +266,7 @@ Item { } Label{ id:attendLabel - color: "grey" + color: osSettings.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize horizontalAlignment: Label.AlignRight @@ -278,24 +277,21 @@ Item { //Bottom row for buttons Row{id:controlrow anchors.top:friendicaActivities.bottom - height: root.fontFactor*osSettings.bigFontSize - CheckBox{ + height: 1.5*root.fontFactor*osSettings.bigFontSize + ToolButton{ id:likeCheckbox - width:newsitem.width/5 //10*mm + width:newsitem.width/5 height: parent.height visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false checked:(model.newsitemobject.friendica_activities_view.self.liked==1)?true:false - indicator: Rectangle{ - implicitWidth: newsitem.width/5 //10*mm - implicitHeight:root.fontFactor*osSettings.bigFontSize - Text{ - anchors.centerIn: parent - font.pointSize: osSettings.systemFontSize - font.family:fontAwesome.name - color:likeCheckbox.checked?"black": "grey" - text:likeCheckbox.checked?"\uf118"+"!":"\uf118" - } - } + icon.name:"smiley" + icon.source: "qrc:/assets/icons/smile-o.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Like") + onClicked: { if(likeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"like",newsitemobject.id,root);dislikeCheckbox.checked=false; newsitemobject.friendica_activities_view.self.liked=1; @@ -306,23 +302,20 @@ Item { newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); }} } - CheckBox{ + ToolButton{ id: dislikeCheckbox - width:newsitem.width/5 //10*mm + width:newsitem.width/5 height: parent.height visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false checked: (newsitemobject.friendica_activities_view.self.disliked==1)?true:false - indicator: Rectangle{ - implicitWidth: newsitem.width/5 //10*mm - implicitHeight:root.fontFactor*osSettings.bigFontSize - Text{ - anchors.centerIn: parent - font.pointSize: osSettings.systemFontSize - font.family:fontAwesome.name - color:dislikeCheckbox.checked?"black": "grey" - text: dislikeCheckbox.checked?"\uf119"+"!":"\uf119" - } - } + //icon.name:"frown" + icon.source: favoritedCheckbox.checked?"qrc:/assets/icons/star.svg":"qrc:/assets/icons/frown-o.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Dislike") + onClicked: { if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.id,root);likeCheckbox.checked=false; newsitemobject.friendica_activities_view.self.disliked=1; @@ -334,75 +327,82 @@ Item { }} } - CheckBox { + ToolButton{ + //CheckBox { id:favoritedCheckbox visible:((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3)) - width: newsitem.width/5 // 10*mm + width: newsitem.width/5 height: parent.height - indicator:Rectangle{ - implicitWidth: newsitem.width/5 //10*mm - implicitHeight:root.fontFactor*osSettings.bigFontSize - Text{ - anchors.centerIn: parent - font.pointSize: osSettings.systemFontSize - font.family:fontAwesome.name - color: favoritedCheckbox.checked?"black":"grey" - text:"\uf005" - } - } + icon.name: favoritedCheckbox.checked?"starred-symbolic":"non-starred-symbolic" + icon.source: favoritedCheckbox.checked?"qrc:/assets/icons/star.svg":"qrc:/assets/icons/star-o.svg" + icon.width: root.fontFactor*osSettings.systemFontSize + icon.height: root.fontFactor*osSettings.systemFontSize + icon.color: favoritedCheckbox.checked?osSettings.primaryTextColor: osSettings.secondaryTextColor + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Favorite") + checked:(newsitemobject.favorited>0) onClicked:{ - if(favoritedCheckbox.checkState==Qt.Checked){ - Newsjs.favorite(login,true,newsitemobject.id,root); model.newsitemobject.favorited=1} - else if(favoritedCheckbox.checkState==Qt.Unchecked){ - Newsjs.favorite(login,false,newsitemobject.id,root);model.newsitemobject.favorited=0} + if(!checked){ + Newsjs.favorite(login,true,newsitemobject.id,root); model.newsitemobject.favorited=1; + checked=true + } + else if(checked){ + Newsjs.favorite(login,false,newsitemobject.id,root);model.newsitemobject.favorited=0; + checked=false + } } } - Rectangle{ - width: newsitem.width/5 //10*mm + + ToolButton{ + id: reply + visible: (newsitemobject.messagetype!==2) + width: newsitem.width/5 height: parent.height - visible:(newsitemobject.messagetype!==2) - color:"transparent" - Text{ - id:newsmenusymbol - color: "grey" - anchors.centerIn: parent - font.pointSize: osSettings.systemFontSize - font.family:fontAwesome.name - text: "\uf142" + icon.name: "mail-reply-sender-symbolic" + icon.source: "qrc:/assets/icons/reply.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Reply") + + onClicked:{ + openMessageSend("reply",newsitemobject) + } + } + + ToolButton{ + id: menubutton + visible: (newsitemobject.messagetype!==2) + width: newsitem.width/5 + height: parent.height + icon.name: "view-more-symbolic"//"overflow-menu" + icon.source: "qrc:/assets/icons/ellipsis-v.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + ToolTip.delay: 800 + ToolTip.visible: pressed || hovered + ToolTip.text: qsTr("Menu") + + onClicked:{ + newsmenu.popup()} } - MouseArea{ - anchors.fill:parent - onClicked: {newsmenu.popup()}} } - } Menu { id:newsmenu - width: 18*osSettings.FontSize + width: 10*root.fontFactor*osSettings.systemFontSize delegate: MenuItem{ contentItem: Text{ font.pointSize: osSettings.systemFontSize + color: osSettings.secondaryTextColor text: parent.text } } - Action{ - text: qsTr("Reply") - onTriggered: { - var directmessage=0; - if (newsitemobject.messagetype==1){ directmessage=1} - var replycomp=Qt.createComponent("qrc:/qml/newsqml/MessageSend.qml"); - var conversation; - if (newsitem.ListView.view.viewtype=="conversation"){conversation=true} - else{conversation=false}; - var reply=replycomp.createObject(friendicaActivities,{parentId:newsitemobject.id,reply_to_user:newsitemobject.user.screen_name, state:"reply",conversation:conversation,textfocus:true}) - } - } - Action { - text: qsTr("DM") - onTriggered: { - root.directmessageSignal(newsitemobject.user.screen_name); - } + onAboutToShow:{if(newsitemobject.hasOwnProperty("external_url")){ + insertAction(4,externalAction)} } Action { text: qsTr("Repost") @@ -412,19 +412,59 @@ Item { }) } } + Action { + text: qsTr("Block contact") + onTriggered: { + var component = Qt.createComponent("qrc:/qml/newsqml/BlockUser.qml"); + var userblockdialog = component.createObject(root,{"newsitem": newsitemobject}); + userblockdialog.open() + } + } + Action { + text: qsTr("Report contact") + onTriggered: { + var component = Qt.createComponent("qrc:/qml/newsqml/ReportUser.qml"); + var userreportdialog = component.createObject(root,{"newsitem": newsitemobject}); + userreportdialog.open() + } + } Action { text: qsTr("Conversation") onTriggered: { pushConversation(); } } + Action { + text: qsTr("DM") + onTriggered: { + root.sendmessageSignal("directmessage",newsitemobject); + } + } + Action { + text: qsTr("Bookmark") + onTriggered: { + if(model.newsitemobject.favorited==0){ + Newsjs.favorite(login,true,newsitemobject.id,root); model.newsitemobject.favorited=1} + else if(model.newsitemobject.favorited==1){ + Newsjs.favorite(login,false,newsitemobject.id,root);model.newsitemobject.favorited=0} + } + } + Action{ + text:qsTr("Calendar Entry") + onTriggered:{ + rootstackSignal(3); + bar.currentIndex=3; + eventcreateSignal(newsitemobject); + } + } Menu{ title: qsTr("Attending") - width: 10*osSettings.systemFontSize + width: 10*root.fontFactor*osSettings.systemFontSize delegate: MenuItem{ contentItem: Text{ font.pointSize: osSettings.systemFontSize + color: osSettings.secondaryTextColor text: parent.text } } @@ -449,16 +489,11 @@ Item { text: qsTr("Delete") onTriggered: { Newsjs.deleteNews(root.login,root.db,newsitemobject.id,newsitemobject.messagetype,root,function(reply){ - var msg = {'deleteId': index, 'model': newsModel}; + var msg = {'deleteId': index, 'model': newsitem.ListView.view.model}; newsWorker.sendMessage(msg); }) } } - - //MenuItem{ - // text:qsTr("Show on website") - // onTriggered:Qt.openUrlExternally(login.server+"/display/"+newsitemobject - //} } Column{ id:conversationColumn @@ -466,4 +501,9 @@ Item { width: newsitem.width } } + Action{id:externalAction + text: qsTr("External") + onTriggered: {Qt.openUrlExternally(newsitemobject.external_url)} + } + } diff --git a/source-linux/qml/newsqml/PermissionDialog.qml b/src/qml/newsqml/PermissionDialog.qml similarity index 100% rename from source-linux/qml/newsqml/PermissionDialog.qml rename to src/qml/newsqml/PermissionDialog.qml diff --git a/source-linux/qml/newsqml/NewsLink.qml b/src/qml/newsqml/ReportUser.qml similarity index 55% rename from source-linux/qml/newsqml/NewsLink.qml rename to src/qml/newsqml/ReportUser.qml index 78f1555..2583785 100644 --- a/source-linux/qml/newsqml/NewsLink.qml +++ b/src/qml/newsqml/ReportUser.qml @@ -29,39 +29,46 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.9 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/js/helper.js" as Helperjs -//import QtWebView 1.1 -Rectangle{ - color:"transparent" - width:newscolumn.width; - height:newscolumn.width/4*3 - property string url:""//htmlview.text +Dialog { + id: userReportkDialog + anchors.centerIn: parent + property var newsitem:({}) + title: qsTr("Report contact?") - Text{id:htmlview - textFormat:Text.RichText + standardButtons: Dialog.Ok | Dialog.Cancel + modal: true + onAccepted: { + let statusArray=[];statusArray.push(newsitem.id.toString()); + xhr.setAccount(login); + xhr.setApi("/api/v1/reports"); + xhr.setParam("account_id",newsitem.user.id); + //xhr.setParam("status_ids",JSON.stringify(statusArray)); + xhr.setParam("comment",comment.text); + xhr.setParam("category",categoryCombo.currentText); + xhr.post(); } -// WebView {id:htmlview; -// anchors.fill: parent -// } - Component.onCompleted:{ + onRejected: {close()} + Column{ + height: nameLabel.height+comment.height+categoryCombo.height + Label {id:nameLabel;text: newsitem.user.name} + TextField { + id: comment + font.pointSize: osSettings.systemFontSize + selectByMouse: true + placeholderText: qsTr("comment") + } + ComboBox{ + id: categoryCombo + width: 6*root.fontFactor*osSettings.bigFontSize + height: 1.5*root.fontFactor*osSettings.bigFontSize + font.pointSize: osSettings.systemFontSize + model: [qsTr("illegal"),qsTr("spam"), qsTr("violation")] + } -// Helperjs.friendicaWebRequest(url,parent,function(document){ -// print(document); - -//// var metas = document.getElementsByTagName('meta'); //get all the meta tag elements -//// //iterate through them -//// for (i=0; i +// +// 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 6.3 +import QtQuick.Controls 6.3 +import QtQuick.Layouts +import "qrc:/js/smiley.js" as Smileyjs +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" + +Rectangle{ + id:smileyDialog + x: mm + width: messageColumn.width-5*mm + height:root.height/2 + color: osSettings.backgroundColor + + MButton{ + id:closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + onClicked:{smileyDialog.visible=false} + } + + Rectangle{ + id: htmlGridTab + color: osSettings.backgroundColor + width: smileyDialog.width-4*root.fontFactor*osSettings.bigFontSize//2*mm + height: smileyDialog.height//-4*root.fontFactor*osSettings.bigFontSize + + GridView { + id:htmlView + anchors.fill: parent + cellWidth: 5*mm + cellHeight: 5*mm + clip: true + model: htmlModel + delegate: htmlItem + } + + ListModel{ + id:htmlModel + } + Component.onCompleted:{ + for (var icon in Smileyjs.html){ + htmlModel.append({"emoji":Smileyjs.html[icon]}) + } + } + } + + Component{ + id:htmlItem + Label{id:smileText + width:4.5*mm + height: 4.5*mm + textFormat:Text.RichText + font.pointSize: osSettings.osType=="Linux"?1.7*osSettings.systemFontSize:1.4*osSettings.systemFontSize + text: emoji + + MouseArea{ + anchors.fill: parent + onClicked:{ + bodyField.insert(bodyField.cursorPosition,emoji+" "); + smileyDialog.visible=false + } + } + } + } +} diff --git a/source-linux/qml/photoqml/ImageUploadDialog.qml b/src/qml/photoqml/ImageUploadDialog.qml similarity index 83% rename from source-linux/qml/photoqml/ImageUploadDialog.qml rename to src/qml/photoqml/ImageUploadDialog.qml index 5ab0c48..012a646 100644 --- a/source-linux/qml/photoqml/ImageUploadDialog.qml +++ b/src/qml/photoqml/ImageUploadDialog.qml @@ -29,13 +29,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import QtQuick 2.5 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/js/helper.js" as Helperjs import "qrc:/js/image.js" as Imagejs import "qrc:/qml/genericqml" -Rectangle{ +Page{ id:imageDialog property var attachImageURLs: [] property string imageId: "" @@ -49,11 +49,10 @@ Rectangle{ property int imageNo: 0 function uploadSelectedImage(inumber){ - xhr.url= login.server + "/api/friendica/photo/create.json"; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.clearParams(); + xhr.setAccount(login); + xhr.setApi("/api/friendica/photo/create.json"); xhr.setParam("desc",imageUploadModel.get(inumber).description); - xhr.setParam("album", album.currentText); + if(album.editText!=""){xhr.setParam("album", album.editText)}else{xhr.setParam("album", album.currentText)}; //if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))}; //if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; //if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; @@ -64,9 +63,8 @@ Rectangle{ function updateImage(){ - xhr.url= login.server + "/api/friendica/photo/update.json"; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.clearParams(); + xhr.setAccount(login); + xhr.setApi("/api/friendica/photo/update.json"); xhr.setParam("desc",imageUploadModel.get(0).description); xhr.setParam("album", currentAlbum); xhr.setParam("album_new", album.currentText); @@ -76,9 +74,15 @@ Rectangle{ function attachImage(url){ - imageUploadModel.append({"imageUrl":url,"description":""}) + if (url.indexOf(",")>0){ + let urlArray=url.split(","); + for (let file in urlArray){attachImage(urlArray[file])} + } else{ + if(url!=""){ + imageUploadModel.append({"imageUrl":url,"description":"","imageUploaded":false,"imageRotation":0}) + } } - + } //border.color: "grey" y:1 width:root.width-mm @@ -87,7 +91,7 @@ Rectangle{ Connections{ target:xhr - onError:{print(data)}//if (data=="image"){Helperjs.showMessage()}} + //onError:{print(data)}//if (data=="image"){Helperjs.showMessage()}} onSuccess:{ if (imageId==""){ imageNo=imageNo+1; @@ -96,7 +100,7 @@ Rectangle{ }else{ Imagejs.requestList(login,db, true,root,function(obj){ fotorectangle.newimages=obj; - imageDialog.destroy() + photoStack.pop() }) }} else{ @@ -118,7 +122,7 @@ Rectangle{ anchors.right: parent.right anchors.rightMargin: 1*mm spacing:5*mm - Text{ + Label{ font.pointSize: osSettings.bigFontSize font.bold: true text:qsTr("Upload to album") @@ -134,7 +138,10 @@ Rectangle{ MButton{ id:closeButton - text: "\uf057" + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" width: 2.5*root.fontFactor*osSettings.bigFontSize font.pointSize: osSettings.bigFontSize onClicked:{photoStack.pop()} @@ -192,7 +199,7 @@ Rectangle{ x:3*mm //23*mm y: 11*mm + album.height width: imageDialog.width-5*mm //25*mm - height: parent.height -(9*root.fontFactor*osSettings.bigFontSize)//root.width/2 //25*mm + height: parent.height -(12*root.fontFactor*osSettings.bigFontSize)//root.width/2 //25*mm model: imageUploadModel delegate: imageDelegate footer: imageId==""?imageFooter:null @@ -231,7 +238,8 @@ Rectangle{ id: imageDelegate Rectangle{ width:root.width/2 //Math.max(20*mm,descriptionInput.contentWidth) - height:imageUploadView.height-5*mm // 20*mm + height:imageUploadView.height-3*root.fontFactor*osSettings.bigFontSize// 20*mm + color: osSettings.backgroundColor Image{ id: uploadImage width: root.width/2-mm //20*mm @@ -250,7 +258,7 @@ Rectangle{ } Rectangle{ - //color: "light grey" + color: osSettings.backgroundColor border.color: "grey" anchors.top: uploadImage.bottom anchors.topMargin: mm @@ -273,23 +281,18 @@ Rectangle{ } Component{ id: imageFooter - Image{ - id: footerImage - height: root.width/4 - width: root.width/4 //15*mm - //15*mm - fillMode: Image.PreserveAspectFit - source:"qrc:/images/addImage.png" - MouseArea{ - anchors.fill: parent - onClicked:{ - imagePicking=true; - var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+ - osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+ - 'attachImage(imageUrl)}}',imageDialog,"imagePicker"); - imagePicker.pickImage() - } - } + BlueButton{ + width: 5*root.fontFactor*osSettings.bigFontSize + height:imageUploadView.height-3*root.fontFactor*osSettings.bigFontSize + color: osSettings.backgroundColor + text:"\u002b" + fontSize: 3*osSettings.bigFontSize + onClicked:{ + imagePicking=true; + var imagePicker = Qt.createQmlObject('import QtQuick 6.3; import "qrc:/qml/genericqml";'+ + osSettings.imagePickQml+'{multiple : false;onReady: {'+ + 'attachImage(imageUrl)}}',imageDialog,"imagePicker"); + imagePicker.pickImage()} } } @@ -304,7 +307,7 @@ Rectangle{ text: imageId==""?qsTr("Upload"):qsTr("Change") font.pointSize: osSettings.bigFontSize onClicked:{ - if(album.currentText==""){Helperjs.showMessage(qsTr("Error"),qsTr(" No album name given"), imageDialog)} + if(album.currentText==""&&album.editText==""){Helperjs.showMessage(qsTr("Error"),qsTr(" No album name given"), imageDialog)} else if (imageId!=""){uploadBusy.running=true; updateImage()} else{newimageProgress.visible=true; if (imageUploadModel.count>0){ diff --git a/source-linux/qml/photoqml/PhotoComponent.qml b/src/qml/photoqml/PhotoComponent.qml similarity index 96% rename from source-linux/qml/photoqml/PhotoComponent.qml rename to src/qml/photoqml/PhotoComponent.qml index 5e67fe4..347f9c3 100644 --- a/source-linux/qml/photoqml/PhotoComponent.qml +++ b/src/qml/photoqml/PhotoComponent.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.5 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/photoqml" Package { @@ -84,7 +84,7 @@ Package { MouseArea { width: realImage.paintedWidth; height: realImage.paintedHeight; anchors.centerIn: realImage onPressAndHold:{ - var menuString="import QtQuick 2.5;import QtQuick.Controls 2.12; "+ + var menuString="import QtQuick 6.3;import QtQuick.Controls 6.3; "+ "Menu {MenuItem {text:qsTr('Delete on client and server'); onTriggered: {"+ "changeimage('delete','image','"+imageLocation+"');photoModel.remove(index)}}"+ "MenuItem {text:qsTr('Move to album'); onTriggered: {"+ @@ -113,7 +113,6 @@ Package { enabled: false } - // onStateChanged: print("State"+photoWrapper.state+index) states: [ State { name: 'stacked'; when: albumWrapper.state == '' diff --git a/src/qml/photoqml/PhotoTab.qml b/src/qml/photoqml/PhotoTab.qml new file mode 100644 index 0000000..6168800 --- /dev/null +++ b/src/qml/photoqml/PhotoTab.qml @@ -0,0 +1,352 @@ +// This file is part of Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa +// Copyright (C) 2020 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 6.3 +import QtQuick.Controls 6.3 +import QtQml.Models 2.1 +import "qrc:/js/image.js" as Imagejs +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/photoqml" +import "qrc:/qml/genericqml" + + +StackView{ + id: photoStack + initialItem:Rectangle { + id:fotorectangle + //anchors.fill:parent + color: osSettings.backgroundColor + property var newimages:[] + property int currentimageno: 0 + property bool remoteContact: false + + + onNewimagesChanged:{ + if(fotorectangle.newimages.length>0){ + var ownimagelist=[]; + Helperjs.readField("album",root.db,"imageData",root.login.username,function(albums){ + for (var i=0;i 1){photoStack.pop()} + else if(albumgridview.currentItem==null){rootstackSignal(0)} + else if(albumgridview.currentItem.state=='fullscreen'){ + albumgridview.currentItem.state = 'inGrid'} + else if (albumgridview.currentItem.state == 'inGrid'){albumgridview.currentItem.state=''} + else{rootstackSignal(0)} + } + else{ + try {photogroupModel.clear()}catch (e){print(e)} + if (friend){ +// Imagejs.newRequestFriendsAlbumPictures(login,friend,fotorectangle,function(albums,remoteAuthBool){ +// remoteContact=remoteAuthBool; +// var msg = {'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture':true,'friend':friend} +// photoWorker.sendMessage(msg); +// }) +// phototabstatusButton.text=friend.screen_name+qsTr("\'s images") + + } + else { + xhr.setAccount(login); + xhr.setApi("/api/friendica/photoalbums"); + xhr.get(); +// Helperjs.readField("album", db, "imageData",login.username,function(albums){ +// if (albums[0]) { +// var msg = { 'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture': false}; +// photoWorker.sendMessage(msg); +// } +// }) + } + } + } + + function deletepics(method, type,id){ + if(method=="delete"){Imagejs.deleteImage(db,login,type, id,filesystem,root,function(){//showFotos("") + })} + } + function updatepic(method,type,id){ + if(method=="update"){ + Helperjs.readData(db,"imageData",login.username,function(url){ + 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("qrc:/qml/photoqml/ImageUploadDialog.qml",{"attachImageURLs":urls}) + } + + ToolButton{ + id:menuButton + z:2 + anchors.right: parent.right + anchors.top: parent.top + visible: !wideScreen + icon.name: "application-menu" + icon.source: "qrc:/assets/icons/bars.svg" + icon.width: root.fontFactor*osSettings.bigFontSize + icon.height: root.fontFactor*osSettings.bigFontSize + onClicked:{ + leftDrawerAndroid.visible?leftDrawerAndroid.close():leftDrawerAndroid.open()} + } + + LeftDrawerLinux{ + id:leftDrawer + property var newstabstatus: newstab.newstabstatus + visible: wideScreen&&rootstackView.depth<2 + width: visible?root.fontFactor*osSettings.systemFontSize*15:0 + height: root.height-bar.height + } + + LeftDrawerAndroid{ + id: leftDrawerAndroid + } + + ProgressBar{ + id: newImagesProgress + width: 15*mm + height: updatePhotolist.height + anchors.top: parent.top + anchors.right:uploadPhoto.left + anchors.rightMargin:mm + visible: false + value: fotorectangle.currentimageno/fotorectangle.newimages.length + } + + MButton{ + id: uploadPhoto + anchors.top: parent.top + anchors.topMargin: 0.5*mm + anchors.right:updatePhotolist.left + anchors.rightMargin:mm + text: qsTr("upload") + display: AbstractButton.IconOnly + icon.name: "cloud-upload" + icon.source: "qrc:/assets/icons/cloud-upload.svg" + onClicked: {photoStack.push("qrc:/qml/photoqml/ImageUploadDialog.qml")} + } + + MButton{ + id: updatePhotolist + anchors.top: parent.top + anchors.topMargin: 0.5*mm + anchors.right:phototabstatusButton.left + anchors.rightMargin:mm + text: qsTr("download") + display: AbstractButton.IconOnly + icon.name: "cloud-download" + icon.source: "qrc:/assets/icons/cloud-download.svg" + + Menu { + id:photoupdatemenu + width:8*root.fontFactor*osSettings.bigFontSize + MenuItem { + text: qsTr("All Images") + font.pointSize: osSettings.bigFontSize + onTriggered: { + Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){fotorectangle.newimages=obj})} + } + MenuItem { + text: qsTr("Only new") + font.pointSize: osSettings.bigFontSize + onTriggered: { + Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){fotorectangle.newimages=obj})} + } + } + onClicked: {photoupdatemenu.popup()} + } + + MButton{ + id: phototabstatusButton + anchors.top: parent.top + anchors.topMargin: 0.5*mm + anchors.right: menuButton.left + anchors.rightMargin:2*mm + width: Math.max(8*root.fontFactor*osSettings.bigFontSize,implicitWidth) + text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus + Menu { + id:phototabmenu + width: 20*root.fontFactor*osSettings.bigFontSize + MenuItem { + text: qsTr("Own Images") + font.pointSize: osSettings.bigFontSize + onTriggered: { + fotostab.phototabstatus="Images"; + // phototabstatusButton.text=qsTr("Own images"); + showFotos(root.login,"")} + } + } + onClicked: {phototabmenu.popup()} + } + + + DelegateModel{ + id: visualphotoModel + delegate: PhotogroupComponent{} + model: photogroupModel + } + + ListModel{ + id: photogroupModel + } + + GridView { + id: albumgridview + cellWidth: 17*mm + cellHeight: 17*mm + x: leftDrawer.width + y:8*mm + width: wideScreen&&rootstackView.depth<2?parent.width-leftDrawer.width-mm:parent.width-mm + height: parent.height-9*mm + clip: true + model: visualphotoModel.parts.album + footer:Rectangle{ + border.color: osSettings.backgroundDimColor + border.width: 1 + color: osSettings.dialogColor + width:12*mm + height:6*mm + Text{ + color: osSettings.primaryTextColor + font.pointSize: 0.75*osSettings.systemFontSize + anchors.centerIn: parent + text:qsTr("More") + } + MouseArea{anchors.fill:parent + onClicked:{ + var lastalbum_id=photogroupModel.count-1; + if(photogroupModel.get(photogroupModel.count-1).foreignPicture==true){ +// Imagejs.newRequestFriendsAlbumPictures(login,photogroupModel.get(0).friend,fotorectangle,function(albums,remoteAuthBool){ +// remoteContact=remoteAuthBool; +// var msg = {'model': photogroupModel,'albums':albums,'firstalbum':lastalbum_id+1,'foreignPicture':true,'friend':photogroupModel.get(0).friend} +// photoWorker.sendMessage(msg) +// }) + } + else{Helperjs.readField("album",root.db, "imageData",root.login.username,function(albums){ + var msg = { 'model': photogroupModel,'albums':albums,'foreignPicture': false,'firstalbum':lastalbum_id+1}; + photoWorker.sendMessage(msg)})} + }}} + } + + Rectangle { id: photoBackground; color: 'black'; width: parent.width; height: parent.height; opacity: 0; visible: opacity != 0.0 } + + ListView { width: parent.width; height:parent.height; model: visualphotoModel.parts.browser; interactive: false } + + MButton { + id: backButton + text: qsTr("Close") + display: AbstractButton.IconOnly + icon.name: "dialog-close" + icon.source: "qrc:/assets/icons/times-circle.svg" + x: parent.width - backButton.width - root.fontFactor*osSettings.bigFontSize + y: -backButton.height - root.fontFactor*osSettings.bigFontSize + z:2 + onClicked: {photoBackground.opacity=0} + } + + ListView {anchors.fill: parent; model: visualphotoModel.parts.fullscreen; interactive: false } + WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"} + + Component.onCompleted: { + root.fotoSignal.connect(showFotos); + root.uploadSignal.connect(uploadUrls); + root.changeimage.connect(deletepics); + root.changeimage.connect(updatepic); + if (fotostab.phototabstatus=="Images"){showFotos(root.login,"")} + } + } +} diff --git a/source-linux/qml/photoqml/PhotogroupComponent.qml b/src/qml/photoqml/PhotogroupComponent.qml similarity index 79% rename from source-linux/qml/photoqml/PhotogroupComponent.qml rename to src/qml/photoqml/PhotogroupComponent.qml index 8796627..96f6feb 100644 --- a/source-linux/qml/photoqml/PhotogroupComponent.qml +++ b/src/qml/photoqml/PhotogroupComponent.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.5 -import QtQuick.Controls 2.12 +import QtQuick 6.3 +import QtQuick.Controls 6.3 import QtQml.Models 2.1 //import "qrc:/js/service.js" as Service import "qrc:/js/image.js" as Imagejs @@ -112,20 +112,30 @@ Package { } })} else{ - Helperjs.readData(db,"imageData",root.login.username,function(obj){ - if (obj) { - for (var k=0;k - + + + AcceptRules + + Accept instance rules + Bitte Instanzregeln akzeptieren + + AccountPage - - - User Name - Server Server - Nickname Kurzname - Password Passwort - Image dir. Bildverz. News as - Anzeige + 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 + Chronologisch Conversations - Unterhaltungen + Unterhaltungen + + + Instance rules + Server-Verhaltensregeln + + + Wrong password or 2FA enabled! + Falsches Passwort bzw. 2FA eingeschaltet! + + + Connect + Anmelden + + + No server given! + Kein Server angegeben! + + + Couldn't connect to server + Keine Verbindung zum Server + + + Set as default + Als Standard setzen + + + Method + Verfahren + + + OAuth + OAuth + + + Close + Schließen + + + + BlockUser + + Block contact? + Kontakt blockieren? CalendarTab - Events Termine - Own Calendar Eigener Kalender + + Delete Event? + Termin löschen? + + + refresh + Aktualisieren + + + add + Neu + + + + ConfigAppearancePage + + News as + Anzeige + + + Conversations + Unterhaltungen + + + Timeline + Chronologisch + + + Max. News + Max. Nachr. + + + Hide #nsfw? + #nsfw minimieren? + + + Dark Mode + Design + + + System + Standard-Design + + + Dark + Dunkles Design + + + Light + Helles Design + + + Default News Tabs + Standard-Tabs für Posts + ConfigPage - News as Anzeige - - - Conversations Unterhaltungen - - Timeline Chronologisch - Max. News Max. Nachr. - Hide #nsfw? #nsfw minimieren? - Sync Autom. Aktualisierung + + Appearance + Anzeige + + + Start + Start + + + Close + Schließen + + + + ConfigStartPage + + Autostart + Autostart + ConfigTab User - Name + Name Server - Server + Server Nickname - Kurzname + Kurzname Password - Passwort + Passwort Image dir. - Bildverz. + Bildverz. Max. News - Max. Nachr. + Max. Nachr. News as - Anzeige + Anzeige Interval (0=None) - Intervall (0=keins) + Intervall (0=keins) Error - Fehler + Fehler Nickname not registered at given server! - Name auf der Seite nicht registriert! + 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! + 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 ContactComponent - Connect Kontaktanfrage @@ -263,334 +356,336 @@ ContactDetailsComponent Connect - Kontaktanfrage + Kontaktanfrage Description - Beschreibung + Beschreibung Location - Ort + Ort Posts - Beiträge + Beiträge URL - Profilseite + Profilseite Created at - Erstellt + Erstellt ContactPage - seconds Sekunden - minute Minute - minutes Minuten - hour Stunde - hours Stunden - day Tag - days Tage - month Monat - months Monate - years Jahre - 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. - Connect Kontaktanfrage - Approve Erlauben - Reject Ablehnen - Ignore Ignorieren - + Follow + Folgen + + + Unfollow + Entfolgen + + Description Beschreibung - Location Ort - Posts Beiträge - URL Profilseite - Created at Erstellt - Network Error Netzwerk-Fehler + + Followers + Folgende + + + Following + Folgt + + + Block + Blockieren + + + Unblock + Entblocken + + + Direct Message + Direktnachricht + + + Close + Schließen + + + + Contactlist + + Close + Schließen + + + + ContactsSearchPage + + Network Error + Netzwerk-Fehler + + + Forum + Forum + + + Person + Person + + + Close + Schließen + Conversation - seconds Sekunden - minute Minute - minutes Minuten - hour Stunde - hours Stunden - day Tag - days Tage - month Monat - months Monate - years Jahre - 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. + + Close + Schließen + DrawerAccountComponent - Refresh Aktualisieren - Timeline Chronologisch - Conversations Unterhaltungen - Replies Interaktionen - Direct Messages Direktnachrichten - Favorites Markierte News - Public Timeline öff. Timeline - Group news News Gruppe - Search Suche - Notifications Meldungen @@ -598,73 +693,156 @@ DrawerAccountComponentContacts - Profile Profil - Friends Freunde - Contacts Kontakte - Groups Gruppen + + EventCreate + + Start + Start + + + End + Ende + + + no end + Ende nicht bekannt + + + Title (required) + Titel (notwendig) + + + Event description (optional) + Terminbeschreibung (optional) + + + Location (optional) + Ort (optional) + + + Publish event? + Termin teilen? + + + Create event + Termin erstellen + + + Error + Fehler + + + No event name supplied + Kein Termintitel angegeben + + + Close + Schließen + + + Start date + Veranstaltungsbeginn + + + Start time + Startzeit + + + End date + Veranstaltungsende + + + End time + Endzeitpunkt + + + Accept time + Zeitpunkt akzeptieren + + EventList Location - Ort + Ort + + + Delete Event? + Termin löschen? + + + Close + Schließen EventListItem - Location Ort + + FriendicaActivities + + Close + Schließen + + FriendsListTab - Friend Requests Kontaktanfragen - Friends Kontakte + + All + Alle + + + Blocked + Geblockte + + + refresh + Aktualisieren + FriendsTab - Me Ich - Friends Freunde - Contacts Kontakte - Groups Gruppen @@ -673,682 +851,813 @@ GroupComponent Error - Fehler + Fehler No name given - Kein Name angegeben + Kein Name angegeben + + + Close + Schließen + + + Members + Mitglieder + + + + GroupsListTab + + refresh + Aktualisieren ImageUploadDialog - Upload to album In Album hochladen Album - Album + Album Image - Bild + Bild - Description Beschreibung - Upload Hochladen - Change Ändern - Error Fehler - No album name given Kein Albumname angegeben + + Close + Schließen + + + + InfoBox + + Close + Schließen + LeftDrawerScrollview - Settings Einstellungen - Accounts Konten - Quit Schliessen + + MessageImageUploadDialog + + Description + Beschreibung + + + Upload + Hochladen + + + Add + Neu + + MessageSend - to: an: - Title (optional) Überschrift (optional) - Drop your Content here. Legen Sie Ihren Inhalt per Drag & Drop hier ab. - 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! + + Answer to + Antwort an + + + New message + Neue Nachricht + + + Copy + Kopieren + + + Cut + Ausschneiden + + + Paste + Einfügen + + + Text + Text + + + Bold + Fett + + + Format + Formatieren + + + Italic + Kursiv + + + Create list + Liste erstellen + + + Format as code + Als Code formatieren + + + Rendered + gerendert + + + MD + MD + + + Show Markdown code + Zeige Markdown Text + + + Edit + Bearbeiten + + + emojies + Emojis + + + Insert smiley + Smiley einfügen + + + Insert previous hashtag + Bestehenden Hashtag einfügen + + + Image + Bild + + + Insert images + Bild einfügen + + + Cancel message + Nachricht abbrechen + + + Close + Schließen + + + Format message + Nachricht Formatieren + + + Send message + Nachricht senden + + + Send + Senden + MoreComments - Show all comments Alle Kommentare + + NewsPhotolist + + Close + Schließen + + NewsStack - Network Error Netzwerk-Fehler - More Mehr + + Close + Schließen + NewsTab Download profile image for - Lade Profilbild für + Lade Profilbild für More - Mehr + Mehr Timeline - Chronologisch + Chronologisch Error - Fehler + 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 - seconds Sekunden - minute Minute - minutes Minuten - hour Stunde - hours Stunden - day Tag - days Tage - month Monat - months Monate - years Jahre - 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. + + NewsVideoLarge + + Close + Schließen + + Newsitem attending: - Teilnahme + Teilnahme - Source: Quelle: - Direct Message Direktnachricht - In reply to Antwort an comments - Kommentare + Kommentare - attending partecipare - ago her - Attending: Teilnahme: - Reply Antworten - DM Direktnachricht - Repost Teilen - Success! Erledigt! - Conversation Unterhaltung - Attending Teilnahme - yes ja - maybe vielleicht - no nein - Delete Löschen - - Show height - + Bookmark + Markieren + + + External + Webseite + + + Block contact + Kontakt blockieren + + + Report contact + Kontakt melden + + + Calendar Entry + Kalendereintrag + + + Like + Ich mag das + + + Dislike + Ich mag das nicht + + + Favorite + Markieren + + + Menu + Menü PermissionDialog - Friends Freunde - Groups Gruppen + + save + Speichern + + + apply + Anwenden + PhotoTab - 's images s Bilder - All Images Alle Bilder - Only new Nur neue - - Own Images Eigene Bilder - More Mehr + + upload + Hochladen + + + download + Herunterladen + + + Close + Schließen + 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 + + other + Sonstige + + + refresh + Aktualisieren + + + + ReportUser + + Report contact? + Kontakt melden? + + + comment + Kommentar + + + illegal + illegal + + + spam + Spam + + + violation + Regelverletzung + SmileyDialog - Unicode Unicode - Standard Standard - Addon Addon - Adult XXX + + Close + Schließen + SyncComponent - sync akt. - notify benachr. @@ -1356,182 +1665,213 @@ SyncConfig - Sync Interval (0=None) Akt.-intervall (0=keine) - Min. Min. + + Backgound Sync + Hintergrund-Aktualisierung + friendiqa Refresh - Aktualisieren + Aktualisieren Timeline - Chronologisch + Chronologisch Conversations - Unterhaltungen + Unterhaltungen Favorites - Markierte News + Markierte News Replies - Interaktionen + Interaktionen Public Timeline - öff. Timeline + öff. Timeline Group news - News Gruppe + News Gruppe Search - Suche + Suche Settings - Einstellungen + Einstellungen Accounts - Konten + Konten Quit - Schliessen + Schliessen + + + Background Sync + Rightclick or Middleclick to Quit + Hintergrund-Aktualisierung +Rechtsklick oder Mittelklick zum Schliessen + + + Click to open Friendiqa + Klicken, um Friendiqa zu öffnen + + + Posts + Beiträge + + + Contacts + Kontakte + + + Photos + Fotos + + + Calendar + Kalender + + + Images + Bilder newsworker likes this. - mag das. + mag das. like this. - mögen das. + mögen das. doesn't like this. - mag das nicht. + mag das nicht. don't like this. - mögen das nicht. + mögen das nicht. will attend. - nehmen teil. + nehmen teil. persons will attend. - Personen nehmen teil. + Personen nehmen teil. will not attend. - nimmt nicht teil. + nimmt nicht teil. persons will not attend. - Personen nehmen nicht teil. + Personen nehmen nicht teil. may attend. - nimmt vielleicht teil. + nimmt vielleicht teil. persons may attend. - Personen nehmen vielleicht teil. + Personen nehmen vielleicht teil. - yes ja - no nein - maybe vielleicht seconds - Sekunden + Sekunden ago - her + her minute - Minute + Minute minutes - Minuten + Minuten hour - Stunde + Stunde hours - Stunden + Stunden day - Tag + Tag days - Tage + Tage month - Monat + Monat months - Monate + Monate + + + years + Jahre service Error - Fehler + Fehler Changelog - Änderungen + Änderungen Setting view type of news has moved from account page to config page. - Die Einstellung der Ansichtsart von Nachrichten wurde von der Kontoseite auf die Konfigurationsseite verschoben. + Die Einstellung der Ansichtsart von Nachrichten wurde von der Kontoseite auf die Konfigurationsseite verschoben. - Undefined Array Error Antwort-Array ungültig - JSON status Error Server-Antwort: Fehler diff --git a/src/translations/friendiqa-es.qm b/src/translations/friendiqa-es.qm new file mode 100644 index 0000000..f034d60 Binary files /dev/null and b/src/translations/friendiqa-es.qm differ diff --git a/src/translations/friendiqa-es.ts b/src/translations/friendiqa-es.ts new file mode 100644 index 0000000..d34bbea --- /dev/null +++ b/src/translations/friendiqa-es.ts @@ -0,0 +1,2949 @@ + + + + + AcceptRules + + + + + Accept instance rules + + + + + AccountPage + + + + + + + + + + + User + Usuario + + + Server + Servidor + + + + + + + Nickname + Usuario + + + + + + + + Password + Contraseña + + + + + + + Image dir. + Dir. de imágenes + + + News as + Noticias como + + + + + + + Instance rules + + + + + + + + + + + + + Error + Error + + + + + Method + + + + + + OAuth + + + + + + Close + + + + + + + + Nicknames containing @ symbol currently not supported + No se admiten los apodos que contienen el símbolo @ actualmente + + + + + + Connect + Conectar + + + + + + No server given! + + + + + + + Couldn't connect to server + + + + + + + + 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! + + + + + + Set as default + + + + + + + + Wrong password or 2FA enabled! + + + + Wrong password! + ¡Contraseña incorrecta! + + + + + + + + Success + éxito! + + + + + + + Name + Nombre + + + Timeline + Cronología + + + Conversations + Conversaciones + + + + BlockUser + + + + + Block contact? + + + + + CalendarTab + + + + refresh + + + + + + + Delete Event? + ¿Borrar la cita? + + + + + add + + + + + + + + Events + Eventos + + + + + + + Own Calendar + Calendario propio + + + + ConfigAppearancePage + + + + + News as + Noticias como + + + + + + + + Conversations + Conversaciones + + + + + + + Timeline + Cronología + + + + + + Max. News + Nº Max. de noticias. + + + + + + Hide #nsfw? + Ocultar #nsfw? + + + + + Default News Tabs + + + + + + + Dark Mode + Diseño + + + + + + System + diseño estándar + + + + + + Dark + diseño oscuro + + + + + + Light + diseño brillante + + + + ConfigPage + + News as + Noticias como + + + Conversations + Conversaciones + + + Timeline + Cronología + + + Max. News + Nº Max. de noticias. + + + Hide #nsfw? + Ocultar #nsfw? + + + + + + Appearance + Apariencia + + + + + + Sync + Sincronización + + + + + Close + + + + + + Start + Iniciar + + + + ConfigStartPage + + + + + Autostart + Autoarranque + + + + 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 + + + Interval (0=None) + Intervalo (0=ningún) + + + Error + Error + + + Confirm + Confirmar + + + No server given! + ¡Servidor no encontrado! + + + No nickname given! + ¡Usuario incorrecto! + + + Nickname not registered at given server! + ¡Usuario incorrecto! + + + No username given! + ¡Usuario incorrecto! + + + No password given! + ¡Contraseña incorrecta! + + + No image directory given! + ¡No se ha encontrado el directorio de imágenes! + + + No maximum news number given! + ¡Nº máximo de noticias incorrecto! + + + Wrong password! + ¡Contraseña incorrecta! + + + Success + éxito! + + + Name + Nombre + + + Timeline + Cronología + + + Conversations + Conversaciones + + + Nickname not registered at given server! + + + + Sync Interval (0=None) + Intervalo de sincr. (0=Ninguno) + + + Nicknames containing @ symbol currently not supported + No se admiten los apodos que contienen el símbolo @ actualmente + + + Min. + min. + + + + ContactComponent + + + + + Connect + Conectar + + + + ContactDetailsComponent + + Connect + Conectar + + + Description + Descripción + + + Location + Localización + + + Posts + Mensajes + + + URL + URL + + + Created at + Creado en + + + + ContactPage + + + + + seconds + Segundos + + + + + + minute + Minuto + + + + + + minutes + Minutos + + + + + + hour + Hora + + + + + + hours + Horas + + + + + + day + Dia + + + + + + days + Dias + + + + + + month + Mes + + + + + + months + Meses + + + + + + years + Años + + + + + + 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. + + + + + Direct Message + Mensaje directo + + + + + Close + + + + Connect + Conectar + + + + + + + Approve + Aprobar + + + + + + + Reject + Rechazar + + + + + + + Ignore + Ignorar + + + + + + + Follow + Seguir + + + + + + + Unfollow + Dejar de seguir + + + + + + + Block + + + + + + + + Unblock + + + + + + + + Description + Descripción + + + + + + + Location + Localización + + + + + + + Posts + Mensajes + + + + + + + URL + URL + + + + + + + Created at + Creado en + + + + + + + Followers + Seguidores + + + + + + + Following + Siguiente + + + + + + + Network Error + Fallo de red + + + + Contactlist + + + + Close + + + + + ContactsSearchPage + + + + + + Network Error + Fallo de red + + + + + + + Forum + Foro + + + + + + + Person + Persona + + + + + + Close + + + + + Conversation + + + + + seconds + Segundos + + + + + + minute + Minuto + + + + + + minutes + Minutos + + + + + + hour + Hora + + + + + + hours + Horas + + + + + + day + Dia + + + + + + days + Dias + + + + + + month + Mes + + + + + + months + Meses + + + + + + years + Años + + + + + + 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. + + + + + Close + + + + + DrawerAccountComponent + + + + + Refresh + Actualizar + + + + + + Timeline + Cronología + + + + + + Conversations + Conversaciones + + + + + + Replies + Respuestas + + + + + + Direct Messages + Mensaje directo + + + + + + Favorites + Favoritos + + + + + + Public Timeline + Cronología pública + + + + + + Group news + Grupos + + + + + + Search + Busca + + + + + + Notifications + Notificaciones + + + + DrawerAccountComponentContacts + + + + + Profile + Perfil + + + + + + Friends + Amigos + + + Contacts + Contactos + + + + + + Groups + Grupos + + + + EventCreate + + + + Close + + + + + + + Start + Iniciar + + + + + Start date + + + + + + Start time + + + + + + + End + Finalizar + + + + + End date + + + + + + End time + + + + + + Accept time + + + + + + + no end + sin fin + + + + + + Title (required) + título (obligatorio) + + + + + + Event description (optional) + Descripción del evento (opcional) + + + + + + Location (optional) + Ubicación (opcional) + + + + + + Publish event? + ¿Publicar el fecha? + + + + + + Create event + crear fecha + + + + + + + Error + Error + + + + + + No event name supplied + No se ha nombre de la fecha + + + + EventList + + Location + Localización + + + + + Close + + + + + + + Delete Event? + ¿Borrar la cita? + + + + EventListItem + + + + + Location + Localización + + + + FriendicaActivities + + + + Close + + + + + FriendsListTab + + + + + Friend Requests + Solicitudes de contacto + + + + + + + Friends + Amigos + + + + + refresh + + + + + + + All + Todos + + + + + + Blocked + + + + + FriendsTab + + + + + Me + Yo + + + + + + Friends + Amigos + + + Contacts + Contactos + + + + + + Groups + Grupos + + + + GroupComponent + + + + Close + + + + + + Members + + + + Error + Error + + + No name given + + + + + GroupsListTab + + + + refresh + + + + + ImageUploadDialog + + + + + + Upload to album + Subir álbum + + + Album + álbum + + + Image + imagen + + + + + Close + + + + + + + + Description + Descripción + + + + + + + Upload + Subir + + + + + + + Change + Cambiar + + + + + + + Error + Error + + + + + + + No album name given + ¡Nombre del álbum no encontrado! + + + + InfoBox + + + + Close + + + + + LeftDrawerScrollview + + + + + Settings + Ajustes + + + + + + Accounts + Cuentas + + + + + + Quit + Salida + + + + MessageImageUploadDialog + + + + + + Description + Descripción + + + + + Add + + + + + + + + Upload + Subir + + + + MessageSend + + + + Answer to + + + + + + New message + + + + + + + to: + a: + + + + + + Title (optional) + Título (opcional) + + + + + + Drop your Content here. + Deje caer su contenido aquí. + + + + + + What's on your mind? + ¿Qué tienes en mente? + + + + + Copy + + + + + + Cut + + + + + + Paste + + + + + + Text + + + + + + + Bold + + + + + + + + + + Format + + + + + + Italic + + + + + + Create list + + + + + + Format as code + + + + + + Rendered + + + + + + MD + + + + + + Show Markdown code + + + + + + Edit + + + + + + emojies + + + + + + Insert smiley + + + + + + Insert previous hashtag + + + + + + Image + imagen + + + + + Insert images + + + + + + Cancel message + + + + + + Close + + + + + + Format message + + + + + + Send message + + + + + + Send + + + + + + + + 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! + No se ha suministrado ningún receptor! + + + + MoreComments + + + + + Show all comments + todos comentarios + + + + NewsPhotolist + + + + Close + + + + + NewsStack + + Network Error + Fallo de red + + + + + + + More + Mas + + + + + + Close + + + + + NewsTab + + Download profile image for + Descargar la imagen del perfil para + + + More + Mas + + + Timeline + Cronología + + + Error + Error + + + Favorites + Favoritos + + + Conversations + Conversaciones + + + Network Error + Fallo de red + + + Public timeline + Cronología pública + + + Direct Messages + Mensaje directo + + + Notifications + Notificaciones + + + Group news + Grupos + + + Quit + Salida + + + + + + + seconds + Segundos + + + + + + + minute + Minuto + + + + + + + minutes + Minutos + + + + + + + hour + Hora + + + + + + + hours + Horas + + + + + + + day + Dia + + + + + + + days + Dias + + + + + + + month + Mes + + + + + + + months + Meses + + + + + + + years + Años + + + + + + + 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. + + + Replies + Respuestas + + + + NewsVideoLarge + + + + Close + + + + + Newsitem + + attending: + Asistiendo: + + + + + + Source: + Fuente: + + + + + + Direct Message + Mensaje directo + + + + + + In reply to + En respuesta a + + + comments + comentarios + + + + + + attending + asistencia + + + + + + ago + hace + + + + + + Attending: + Asistiendo: + + + + + Reply + Respuesta + + + + + + DM + Mensaje directo + + + + + + Repost + Volver a publicar + + + + + Like + + + + + + Dislike + + + + + + Favorite + + + + + + Menu + + + + + + + Success! + éxito! + + + + + + Block contact + + + + + + + Report contact + + + + + + + Conversation + Conversación + + + + + + Bookmark + marca + + + + + + Calendar Entry + + + + + + + Attending + Asistiendo + + + + + + yes + si + + + + + + maybe + quizás + + + + + + no + no + + + + + + Delete + Borrar + + + + + + External + sitio web + + + + PermissionDialog + + + + + + Friends + Amigos + + + + + + + Groups + Grupos + + + + + save + + + + + + apply + + + + + PhotoTab + + + + 's images + s Imágenes + + + + + upload + + + + + + download + + + + + + + + All Images + Todas las imagenes + + + + + + + Only new + Solo nueva + + + + + + + + Own Images + Mis imágenes + + + + + + + More + Mas + + + + + Close + + + + + ProfileComponent + + + + + + profile name + Nombre de perfil + + + + + + + is default + es por defecto + + + + + + + hide friends + ocultar amigos + + + + + + + profile photo + foto de perfil + + + + + + + profile thumb + foto de perfil pequeña + + + + + + + publish + publicar + + + + + + + publish in network + publicar en la red + + + + + + + description + descripción + + + + + + + date of birth + fecha de nacimiento + + + + + + + address + dirección + + + + + + + city + ciudad + + + + + + + region + región + + + + + + + postal code + código postal + + + + + + + country + país + + + + + + + hometown + ciudad natal + + + + + + + gender + género + + + + + + + marital status + estado civil + + + + + + + married with + casado con + + + + + + + married since + casado desde + + + + + + + sexual + orientación sexual + + + + + + + politics + política + + + + + + + religion + religión + + + + + + + public keywords + palabras clave públicas + + + + + + + private keywords + palabras clave privadas + + + + + + + likes + le gusta + + + + + + + dislikes + no le gusta + + + + + + + about + sobre + + + + + + + music + música + + + + + + + book + libro + + + + + + + tv + tv + + + + + + + film + película + + + + + + + interest + interés + + + + + + + romance + romance + + + + + + + work + trabajo + + + + + + + education + educación + + + + + + + social networks + redes sociales + + + + + + + homepage + página web + + + + + + + other + otros + + + + + refresh + + + + + + + + Update + Actualización + + + + + + + profile id + profile id + + + + + + + Description + Descripción + + + + + + + Location + Localización + + + + + + + Posts + Mensajes + + + + + + + URL + URL + + + + + + + Created at + Creado en + + + + ReportUser + + + + + Report contact? + + + + + + + + comment + + + + + + + + illegal + + + + + + + + spam + + + + + + + + violation + + + + + SmileyDialog + + + + Unicode + Unicode + + + + + Standard + Standard + + + + + Addon + Addon + + + + + Adult + XXX + + + + + Close + + + + + SyncComponent + + + + + sync + sync + + + + + + notify + notificar + + + + SyncConfig + + + + Sync Interval (0=None) + Intervalo de sincr. (0=Ninguno) + + + + + Min. + min. + + + + + Backgound Sync + + + + + friendiqa + + Refresh + Actualizar + + + Timeline + Cronología + + + Conversations + Conversaciones + + + Favorites + Favoritos + + + Replies + Respuestas + + + Public Timeline + Cronología pública + + + Group news + Grupos + + + Search + Busca + + + Settings + Ajustes + + + Accounts + Cuentas + + + Quit + Salida + + + + + + Background Sync + Rightclick or Middleclick to Quit + Sincronización de fondo +Haga clic con el botón derecho del ratón o con el botón central para salir. + + + + + + + Posts + Mensajes + + + + + + + Contacts + Contactos + + + + + Images + + + + + + + Photos + + + + + + + + Calendar + + + + + + + Click to open Friendiqa + Haga clic para abrir Friendiqa + + + + 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 + + + ago + hace + + + minute + Minuto + + + minutes + Minutos + + + hour + Hora + + + hours + Horas + + + day + Dia + + + days + Dias + + + month + Mes + + + months + Meses + + + years + Años + + + + service + + Error + Error + + + Setting view type of news has moved from account page to config page. + La configuración del tipo de vista de las noticias se ha movido de la página de la cuenta a la página de configuración. + + + + + + + Undefined Array Error + + + + + + + + JSON status Error + + + + Changelog + + + + diff --git a/src/translations/friendiqa-hu.qm b/src/translations/friendiqa-hu.qm new file mode 100644 index 0000000..8fe3bc1 Binary files /dev/null and b/src/translations/friendiqa-hu.qm differ diff --git a/src/translations/friendiqa-hu.ts b/src/translations/friendiqa-hu.ts new file mode 100644 index 0000000..7c2f3c9 --- /dev/null +++ b/src/translations/friendiqa-hu.ts @@ -0,0 +1,3140 @@ + + + + + AcceptRules + + + + + + Accept instance rules + + + + + AccountPage + + + + + + + + + + + User + Felhasználó + + + Server + Kiszolgáló + + + + + + + Nickname + Becenév + + + + + + + + Password + Jelszó + + + + + + + Image dir. + Képkönyvtár + + + News as + Hírek mint + + + + + + + Instance rules + + + + + + + + + + + + + Error + Hiba + + + + + + Method + + + + + + + OAuth + + + + + + + Close + + + + + + + + Nicknames containing @ symbol currently not supported + A @ szimbólumot tartalmazó becenevek jelenleg nem támogatottak + + + + + + + Connect + Kapcsolódás + + + + + + + No server given! + + + + + + + + Couldn't connect to server + + + + + + + + Confirm + Megerősítés + + + + + + + No server given! + Nincs kiszolgáló megadva! + + + + + + + No nickname given! + Nincs becenév megadva! + + + + + + + No password given! + Nincs jelszó megadva! + + + + + + + No image directory given! + Nincs képkönyvtár megadva! + + + + + + + Set as default + + + + + + + + Wrong password or 2FA enabled! + + + + Wrong password! + Hibás jelszó! + + + + + + + + Success + Sikeres + + + + + + + Name + Név + + + Timeline + Idővonal + + + Conversations + Beszélgetések + + + + BlockUser + + + + + + Block contact? + + + + + CalendarTab + + + + + refresh + + + + + + + + Delete Event? + + + + + + + add + + + + + + + + Events + Események + + + + + + + Own Calendar + Saját naptár + + + + ConfigAppearancePage + + + + + + News as + Hírek mint + + + + + + + + + Conversations + Beszélgetések + + + + + + + + Timeline + Idővonal + + + + + + + Max. News + Legtöbb hír + + + + + + + Hide #nsfw? + A #NSFW elrejtése? + + + + + + Default News Tabs + + + + + + + + Dark Mode + Sötét mód + + + + + + + System + Rendszer + + + + + + + Dark + Sötét + + + + + + + Light + Világos + + + + ConfigPage + + News as + Hírek mint + + + Conversations + Beszélgetések + + + Timeline + Idővonal + + + Max. News + Legtöbb hír + + + Hide #nsfw? + A #NSFW elrejtése? + + + + + + + Appearance + Megjelenés + + + + + + + Sync + Szinkronizálás + + + + + + Close + + + + + + Start + Indítás + + + + ConfigStartPage + + + + + + Autostart + Automatikus indítás + + + + ConfigTab + + User + Felhasználó + + + Server + Kiszolgáló + + + Nickname + Becenév + + + Password + Jelszó + + + Image dir. + Képkönyvtár + + + Max. News + Legtöbb hír + + + News as + Hírek mint + + + Interval (0=None) + Időköz (0 = nincs) + + + Error + Hiba + + + Nickname not registered at given server! + A becenév nincs regisztrálva a megadott kiszolgálón! + + + Confirm + Megerősítés + + + No server given! + Nincs kiszolgáló megadva! + + + No nickname given! + Nincs becenév megadva! + + + Nickname not registered at given server! + A becenév nincs regisztrálva a megadott kiszolgálón! + + + No username given! + Nincs felhasználónév megadva! + + + Sync Interval (0=None) + Szinkronizálási időköz (0 = nincs) + + + Nicknames containing @ symbol currently not supported + A @ szimbólumot tartalmazó becenevek jelenleg nem támogatottak + + + Min. + Legkisebb + + + No password given! + Nincs jelszó megadva! + + + No image directory given! + Nincs képkönyvtár megadva! + + + No maximum news number given! + Nincs legtöbb hír szám megadva! + + + Wrong password! + Hibás jelszó! + + + Success + Sikeres + + + Name + Név + + + Timeline + Idővonal + + + Conversations + Beszélgetések + + + + ContactComponent + + + + + + Connect + Kapcsolódás + + + + ContactDetailsComponent + + Connect + Kapcsolódás + + + Description + Leírás + + + Location + Hely + + + Posts + Bejegyzések + + + URL + URL + + + Created at + Létrehozva + + + + ContactPage + + + + + + seconds + másodperc + + + + + + + minute + perc + + + + + + + minutes + perc + + + + + + + hour + óra + + + + + + + hours + óra + + + + + + + day + nap + + + + + + + days + nap + + + + + + + month + hónap + + + + + + + months + hónap + + + + + + + years + év + + + + + + + likes this. + kedveli ezt. + + + + + + + like this. + kedveli ezt. + + + + + + + doesn't like this. + nem kedveli ezt. + + + + + + + don't like this. + nem kedveli ezt. + + + + + + + will attend. + részt vesz. + + + + + + + persons will attend. + személy részt vesz. + + + + + + + will not attend. + nem vesz részt. + + + + + + + persons will not attend. + személy nem vesz részt. + + + + + + + may attend. + talán részt vesz. + + + + + + + persons may attend. + személy talán részt vesz. + + + + + + Direct Message + Közvetlen üzenet + + + + + + Close + + + + Connect + Kapcsolódás + + + + + + + Approve + Jóváhagyás + + + + + + + Reject + Visszautasítás + + + + + + + Ignore + Mellőzés + + + + + + + Follow + Követés + + + + + + + Unfollow + Követés megszüntetése + + + + + + + Block + + + + + + + + Unblock + + + + + + + + Description + Leírás + + + + + + + Location + Hely + + + + + + + Posts + Bejegyzések + + + + + + + URL + URL + + + + + + + Created at + Létrehozva + + + + + + + Followers + + + + + + + + Following + + + + + + + + Network Error + Hálózati hiba + + + + Contactlist + + + + + Close + + + + + ContactsSearchPage + + + + + + Network Error + Hálózati hiba + + + + + + + Forum + fórum + + + + + + + Person + személy + + + + + + + Close + + + + + Conversation + + + + + + seconds + másodperc + + + + + + + minute + perc + + + + + + + minutes + perc + + + + + + + hour + óra + + + + + + + hours + óra + + + + + + + day + nap + + + + + + + days + nap + + + + + + + month + hónap + + + + + + + months + hónap + + + + + + + years + év + + + + + + + likes this. + kedveli ezt. + + + + + + + like this. + kedveli ezt. + + + + + + + doesn't like this. + nem kedveli ezt. + + + + + + + don't like this. + nem kedveli ezt. + + + + + + + will attend. + részt vesz. + + + + + + + persons will attend. + személy részt vesz. + + + + + + + will not attend. + nem vesz részt. + + + + + + + persons will not attend. + személy nem vesz részt. + + + + + + + may attend. + talán részt vesz. + + + + + + + persons may attend. + személy talán részt vesz. + + + + + + Close + + + + + DrawerAccountComponent + + + + + + Refresh + Frissítés + + + + + + + Timeline + Idővonal + + + + + + + Conversations + Beszélgetések + + + + + + + Replies + Válaszok + + + + + + + Direct Messages + Közvetlen üzenetek + + + + + + + Favorites + Kedvencek + + + + + + + Public Timeline + Nyilvános idővonal + + + + + + + Group news + Csoporthírek + + + + + + + Search + Keresés + + + + + + + Notifications + Értesítések + + + + DrawerAccountComponentContacts + + + + + + Profile + Profil + + + + + + Friends + Ismerősök + + + Contacts + Partnerek + + + + + + + Groups + Csoportok + + + + EventCreate + + + + + Close + + + + + + + + Start + Indítás + + + + + + Start date + + + + + + + Start time + + + + + + + + End + + + + + + + End date + + + + + + + End time + + + + + + + Accept time + + + + + + + + no end + + + + + + + + Title (required) + + + + + + + + Event description (optional) + + + + + + + + Location (optional) + + + + + + + + Publish event? + + + + + + + + Create event + + + + + + + + + Error + Hiba + + + + + + + No event name supplied + + + + + EventList + + Location + Hely + + + + + + Close + + + + + + + + Delete Event? + + + + + EventListItem + + + + + Location + Hely + + + + FriendicaActivities + + + + + Close + + + + + FriendsListTab + + + + + + Friend Requests + Barátkérések + + + + + + + + Friends + Ismerősök + + + + + + refresh + + + + + + + + All + + + + + + + + Blocked + + + + + FriendsTab + + + + + + Me + Én + + + + + + + Friends + Ismerősök + + + Contacts + Partnerek + + + + + + + Groups + Csoportok + + + + GroupComponent + + Error + Hiba + + + No name given + Nincs név megadva + + + + + + Close + + + + + + + Members + + + + + GroupsListTab + + + + + refresh + + + + + ImageUploadDialog + + + + + + Upload to album + Feltöltés albumba + + + Album + Album + + + Image + Kép + + + + + + Close + + + + + + + + Description + Leírás + + + + + + + Upload + Feltöltés + + + + + + + Change + Változtatás + + + + + + + Error + Hiba + + + + + + + No album name given + Nincs albumnév megadva + + + + InfoBox + + + + + Close + + + + + LeftDrawerScrollview + + + + + + Settings + Beállítások + + + + + + + Accounts + Fiókok + + + + + + + Quit + Kilépés + + + + MessageImageUploadDialog + + + + + + Description + Leírás + + + + + + Add + + + + + + + + Upload + Feltöltés + + + + MessageSend + + + + + Answer to + + + + + + + New message + + + + + + + + to: + címzett: + + + + + + + Title (optional) + Cím (elhagyható) + + + + + + + Drop your Content here. + Ejtse ide a tartalmat. + + + + + + + What's on your mind? + Mire gondol? + + + + + + Copy + + + + + + + Cut + + + + + + + Paste + + + + + + + Text + + + + + + + + Bold + + + + + + + + + + + Format + + + + + + + Italic + + + + + + + Create list + + + + + + + Format as code + + + + + + + Rendered + + + + + + + MD + + + + + + + Show Markdown code + + + + + + + Edit + + + + + + + emojies + + + + + + + Insert smiley + + + + + + + Insert previous hashtag + + + + + + + Image + Kép + + + + + + Insert images + + + + + + + Cancel message + + + + + + + Close + + + + + + + Format message + + + + + + + Send message + + + + + + + Send + + + + + + + + Error + Hiba + + + Only one attachment supported at the moment. + Remove other attachment first! + Csak egyetlen melléklet támogatott jelenleg. + Először távolítsa el a másik mellékletet. + + + + + + + No receiver supplied! + Nincs fogadó megadva! + + + + MoreComments + + + + + + Show all comments + Összes hozzászólás megjelenítése + + + + NewsPhotolist + + + + + Close + + + + + NewsStack + + Network Error + Hálózati hiba + + + + + + + More + Több + + + + + + + Close + + + + + NewsTab + + Download profile image for + Profilkép letöltése ennél: + + + More + Több + + + Timeline + Idővonal + + + Error + Hiba + + + Favorites + Kedvencek + + + Conversations + Beszélgetések + + + Network Error + Hálózati hiba + + + Replies + Válaszok + + + Public timeline + Nyilvános idővonal + + + Direct Messages + Közvetlen üzenetek + + + Notifications + Értesítések + + + Group news + Csoporthírek + + + Quit + Kilépés + + + + + + + seconds + másodperc + + + + + + + minute + perc + + + + + + + minutes + perc + + + + + + + hour + óra + + + + + + + hours + óra + + + + + + + day + nap + + + + + + + days + nap + + + + + + + month + hónap + + + + + + + months + hónap + + + + + + + years + év + + + + + + + likes this. + kedveli ezt. + + + + + + + like this. + kedveli ezt. + + + + + + + doesn't like this. + nem kedveli ezt. + + + + + + + don't like this. + nem kedveli ezt. + + + + + + + will attend. + részt vesz. + + + + + + + persons will attend. + személy részt vesz. + + + + + + + will not attend. + nem vesz részt. + + + + + + + persons will not attend. + személy nem vesz részt. + + + + + + + may attend. + talán részt vesz. + + + + + + + persons may attend. + személy talán részt vesz. + + + + NewsVideoLarge + + + + + Close + + + + + Newsitem + + attending: + részvétel: + + + + + + + Source: + Forrás: + + + + + + + Direct Message + Közvetlen üzenet + + + + + + In reply to + Válaszul erre: + + + comments + hozzászólás + + + + + + + attending + részvétel + + + + + + + ago + óta + + + + + + + Attending: + Részvétel: + + + + + + Reply + Válasz + + + + + + + DM + DM + + + + + + + Repost + Újraküldés + + + + + + Like + + + + + + + Dislike + + + + + + + Favorite + + + + + + + Menu + + + + + + + + Success! + Sikeres! + + + + + + + Block contact + + + + + + + + Report contact + + + + + + + + Conversation + Beszélgetés + + + + + + + Bookmark + könyvjelző + + + + + + + Calendar Entry + + + + + + + + Attending + Részvétel + + + + + + + yes + igen + + + + + + + maybe + talán + + + + + + + no + nem + + + + + + + Delete + Törlés + + + + + + + External + weboldal + + + + PermissionDialog + + + + + + Friends + Ismerősök + + + + + + + Groups + Csoportok + + + + + + save + + + + + + + apply + + + + + PhotoTab + + + + 's images + képei + + + + + + upload + + + + + + + download + + + + + + + + All Images + Összes kép + + + + + + + Only new + Csak újak + + + + + + + + Own Images + Saját képek + + + + + + + More + Több + + + + + + Close + + + + + ProfileComponent + + + + + + profile name + profilnév + + + + + + + is default + alapértelmezett + + + + + + + hide friends + ismerősök elrejtése + + + + + + + profile photo + profilfénykép + + + + + + + profile thumb + profilbélyegkép + + + + + + + publish + közzététel + + + + + + + publish in network + közzététel hálózaton + + + + + + + description + leírás + + + + + + + date of birth + születési dátum + + + + + + + address + cím + + + + + + + city + település + + + + + + + region + régió + + + + + + + postal code + irányítószám + + + + + + + country + ország + + + + + + + hometown + szülőváros + + + + + + + gender + nem + + + + + + + marital status + családi állapot + + + + + + + married with + házas vele + + + + + + + married since + házas ekkortól + + + + + + + sexual + szexuális + + + + + + + politics + politika + + + + + + + religion + vallás + + + + + + + public keywords + nyilvános kulcsszavak + + + + + + + private keywords + személyes kulcsszavak + + + + + + + likes + kedvelések + + + + + + + dislikes + nem kedvelések + + + + + + + about + névjegy + + + + + + + music + zene + + + + + + + book + könyv + + + + + + + tv + TV + + + + + + + film + film + + + + + + + interest + érdeklődés + + + + + + + romance + romantika + + + + + + + work + munka + + + + + + + education + oktatás + + + + + + + social networks + közösségi hálózatok + + + + + + + homepage + honlap + + + + + + + other + + + + + + + refresh + + + + + + + + Update + Frissítés + + + + + + + profile id + profilazonosító + + + + + + + Description + Leírás + + + + + + + Location + Hely + + + + + + + Posts + Bejegyzések + + + + + + + URL + URL + + + + + + + Created at + Létrehozva + + + + ReportUser + + + + + + Report contact? + + + + + + + + comment + + + + + + + + illegal + + + + + + + + spam + + + + + + + + violation + + + + + SmileyDialog + + + + Unicode + Unicode + + + + + Standard + Szabványos + + + + + Addon + Bővítmény + + + + + Adult + Felnőtt + + + + + + Close + + + + + SyncComponent + + + + + + sync + szinkronizálás + + + + + + + notify + értesítés + + + + SyncConfig + + + + Sync Interval (0=None) + Szinkronizálási időköz (0 = nincs) + + + + + Min. + Legkisebb + + + + + + Backgound Sync + + + + + friendiqa + + Refresh + Frissítés + + + Timeline + Idővonal + + + Conversations + Beszélgetések + + + Favorites + Kedvencek + + + Replies + Válaszok + + + Public Timeline + Nyilvános idővonal + + + Group news + Csoporthírek + + + Search + Keresés + + + Settings + Beállítások + + + Accounts + Fiókok + + + Quit + Kilépés + + + + + Background Sync + Rightclick or Middleclick to Quit + Háttérszinkronizálás +Kilépéshez kattintson a jobb gombbal vagy középső gombbal + + + + + + + + Posts + Bejegyzések + + + + + + + + Contacts + Partnerek + + + + + + Images + + + + + + + + Photos + + + + + + + + + Calendar + + + + + + Click to open Friendiqa + Kattintson a Friendiqa megnyitásához + + + + newsworker + + likes this. + kedveli ezt. + + + like this. + kedveli ezt. + + + doesn't like this. + nem kedveli ezt. + + + don't like this. + nem kedveli ezt. + + + will attend. + részt vesz. + + + persons will attend. + személy részt vesz. + + + will not attend. + nem vesz részt. + + + persons will not attend. + személy nem vesz részt. + + + may attend. + talán részt vesz. + + + persons may attend. + személy talán részt vesz. + + + + + + yes + igen + + + + + + no + nem + + + + + + maybe + talán + + + seconds + másodperc + + + ago + óta + + + minute + perc + + + minutes + perc + + + hour + óra + + + hours + óra + + + day + nap + + + days + nap + + + month + hónap + + + months + hónap + + + years + év + + + + service + + Error + Hiba + + + Changelog + Változásnapló + + + Setting view type of news has moved from account page to config page. + A hírek nézettípusának beállítása át lett helyezve a fiókoldalról a beállítási oldalra. + + + + + + + Undefined Array Error + Meghatározatlan tömbhiba + + + + + + + JSON status Error + JSON-állapothiba + + + diff --git a/src/translations/friendiqa-it.qm b/src/translations/friendiqa-it.qm new file mode 100644 index 0000000..f6f68d8 Binary files /dev/null and b/src/translations/friendiqa-it.qm differ diff --git a/src/translations/friendiqa-it.ts b/src/translations/friendiqa-it.ts new file mode 100644 index 0000000..d087998 --- /dev/null +++ b/src/translations/friendiqa-it.ts @@ -0,0 +1,3263 @@ + + + + + AcceptRules + + + + + + Accept instance rules + + + + + AccountPage + + + + + + + + + + + + User + Utente + + + Server + Server + + + + + + + + Nickname + Utente + + + + + + + + + Password + Password + + + + + + + + Image dir. + Directory immagini + + + News as + News come + + + + + + + + Instance rules + + + + + + + + + + + + + + Error + Errore + + + + + + Method + + + + + + + OAuth + + + + + + + Close + + + + + + + + + Nicknames containing @ symbol currently not supported + I soprannomi contenenti il simbolo @ attualmente non sono supportati + + + + + + + Connect + Connetti + + + + + + + No server given! + + + + + + + + Couldn't connect to server + + + + + + + + + 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! + + + + + + + Set as default + + + + + + + + + Wrong password or 2FA enabled! + + + + Wrong password! + Password sbagliata! + + + + + + + + + Success + Ha funzionato! + + + + + + + + Name + Nome + + + Timeline + Cronologia + + + Conversations + Conversazioni + + + + BlockUser + + + + + + Block contact? + + + + + CalendarTab + + + + + refresh + + + + + + + + Delete Event? + Cancellare la data? + + + + + + add + + + + + + + + + Events + Eventi + + + + + + + + Own Calendar + Calendario + + + + ConfigAppearancePage + + + + + + News as + News come + + + + + + + + + Conversations + Conversazioni + + + + + + + + Timeline + Cronologia + + + + + + + Max. News + Nº Max. di notizie + + + + + + + Hide #nsfw? + Nascondere #nsfw? + + + + + + Default News Tabs + + + + + + + + Dark Mode + design + + + + + + + System + design standard + + + + + + + Dark + design scuro + + + + + + + Light + design luminoso + + + + ConfigPage + + News as + News come + + + Conversations + Conversazioni + + + Timeline + Cronologia + + + Max. News + Nº Max. di notizie + + + Hide #nsfw? + Nascondere #nsfw? + + + + + + + Appearance + Visualizzare + + + + + + + Sync + Sync + + + + + + Close + + + + + + Start + Avviare + + + + ConfigStartPage + + + + + + Autostart + Avvio automatico + + + + ConfigTab + + User + Utente + + + Server + Server + + + Nickname + Utente + + + Password + Password + + + Image dir. + Directory immagini + + + Max. News + Nº Max. di notizie + + + News as + News come + + + Interval (0=None) + Intervallo (0=nessuno) + + + Error + Errore + + + Confirm + Conferma + + + No server given! + Nessun server inserito! + + + No nickname given! + Nessun utente inserito! + + + No username given! + Nessun utente inserito! + + + No password given! + Nessuna password inserita! + + + No image directory given! + Nessuna directory immagini inserita! + + + No maximum news number given! + Nessun numero massimo di news inserito! + + + Success + Ha funzionato! + + + Timeline + Cronologia + + + Conversations + Conversazioni + + + Nickname not registered at given server! + + + + Nickname not registered at given server! + + + + Sync Interval (0=None) + Intervallo (0=nessuno) + + + Nicknames containing @ symbol currently not supported + I soprannomi contenenti il simbolo @ attualmente non sono supportati + + + Min. + Min. + + + Wrong password! + Password sbagliata! + + + Name + Nome + + + + ContactComponent + + + + + + Connect + Connetti + + + + ContactDetailsComponent + + Connect + Connetti + + + Description + Descrizione + + + Location + Località + + + Posts + Messaggi + + + URL + URL + + + Created at + Creato il + + + + ContactPage + + + + + + seconds + secondi + + + + + + + minute + minuti + + + + + + + minutes + minuti + + + + + + + hour + ora + + + + + + + hours + ore + + + + + + + day + giorno + + + + + + + days + giorni + + + + + + + month + mese + + + + + + + months + mesi + + + + + + + years + anni + + + + + + + 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. + + + + + + Direct Message + Messaggio diretto + + + + + + Close + + + + Connect + Connetti + + + + + + + + Approve + Approvare + + + + + + + + Reject + Rifiutare + + + + + + + + Ignore + Ignorare + + + + + + + + Follow + Seguire + + + + + + + + Unfollow + Non seguire + + + + + + + + Block + + + + + + + + + Unblock + + + + + + + + + Description + Descrizione + + + + + + + + Location + Località + + + + + + + + Posts + Messaggi + + + + + + + + URL + URL + + + + + + + + Created at + Creato il + + + + + + + + Followers + Seguaci + + + + + + + + Following + Seguente + + + + + + + + Network Error + Errore di rete + + + + Contactlist + + + + + Close + + + + + ContactsSearchPage + + + + + + + Network Error + Errore di rete + + + + + + + + Forum + Forum + + + + + + + + Person + Persona + + + + + + + Close + + + + + Conversation + + + + + + seconds + secondi + + + + + + + minute + minuti + + + + + + + minutes + minuti + + + + + + + hour + ora + + + + + + + hours + ore + + + + + + + day + giorno + + + + + + + days + giorni + + + + + + + month + mese + + + + + + + months + mesi + + + + + + + years + anni + + + + + + + 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. + + + + + + Close + + + + + DrawerAccountComponent + + + + + + Refresh + Aggiorna + + + + + + + Timeline + Cronologia + + + + + + + Conversations + Conversazioni + + + + + + + Replies + Risposte + + + + + + + Direct Messages + Messaggio diretto + + + + + + + Favorites + Favoriti + + + + + + + Public Timeline + Cronologia pubblica + + + + + + + Group news + Notizie del gruppo + + + + + + + Search + Cerca + + + + + + + Notifications + Notifiche + + + + DrawerAccountComponentContacts + + + + + + Profile + Profilo + + + + + + Friends + Amici + + + Contacts + Contatti + + + + + + + Groups + Gruppi + + + + EventCreate + + + + + Close + + + + + + + + Start + Avviare + + + + + + Start date + + + + + + + Start time + + + + + + + + End + Fine + + + + + + End date + + + + + + + End time + + + + + + + Accept time + + + + + + + + no end + senza fine + + + + + + + Title (required) + Titolo (obbligatorio) + + + + + + + Event description (optional) + descrizione della data (opzionale) + + + + + + + Location (optional) + Posizione (opzionale) + + + + + + + Publish event? + Pubblicare l'evento? + + + + + + + Create event + Creare l'evento + + + + + + + + Error + Errore + + + + + + + No event name supplied + Nessun nome di evento + + + + EventList + + Location + Località + + + + + + Close + + + + + + + + Delete Event? + Cancellare la data? + + + + EventListItem + + + + + Location + Località + + + + FriendicaActivities + + + + + Close + + + + + FriendsListTab + + + + + + Friend Requests + Richieste di contatto + + + + + + + + Friends + Amici + + + + + + refresh + + + + + + + + All + Tutti + + + + + + + Blocked + + + + + FriendsTab + + + + + + Me + Me + + + + + + + Friends + Amici + + + Contacts + Contatti + + + + + + + Groups + Gruppi + + + + GroupComponent + + + + + Close + + + + + + + Members + + + + Error + Errore + + + No name given + + + + + GroupsListTab + + + + + refresh + + + + + ImageUploadDialog + + + + + + + Upload to album + Carica su album + + + Album + Album + + + Image + Immagine + + + + + + Close + + + + + + + + + Description + Descrizione + + + + + + + + Upload + Carica + + + + + + + + Change + Modifica + + + + + + + + Error + Errore + + + + + + + + No album name given + Nessun nome album inserito! + + + + InfoBox + + + + + Close + + + + + LeftDrawerScrollview + + + + + + Settings + Configurazione + + + + + + + Accounts + Conti + + + + + + + Quit + Chiudi + + + + MessageImageUploadDialog + + + + + + + Description + Descrizione + + + + + + Add + + + + + + + + + Upload + Carica + + + + MessageSend + + + + + Answer to + + + + + + + New message + + + + + + + + to: + a: + + + + + + + Title (optional) + Titolo (opzionale) + + + + + + + Drop your Content here. + Lascia qui il tuo contenuto. + + + + + + + What's on your mind? + A cosa stai pensando? + + + + + + Copy + + + + + + + Cut + + + + + + + Paste + + + + + + + Text + + + + + + + + Bold + + + + + + + + + + + Format + + + + + + + Italic + + + + + + + Create list + + + + + + + Format as code + + + + + + + Rendered + + + + + + + MD + + + + + + + Show Markdown code + + + + + + + Edit + + + + + + + emojies + + + + + + + Insert smiley + + + + + + + Insert previous hashtag + + + + + + + Image + Immagine + + + + + + Insert images + + + + + + + Cancel message + + + + + + + Close + + + + + + + Format message + + + + + + + Send message + + + + + + + Send + + + + + + + + + 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! + Nessun ricevitore in dotazione! + + + + MoreComments + + + + + + Show all comments + Tutti commenti + + + + NewsPhotolist + + + + + Close + + + + + NewsStack + + Network Error + Errore di rete + + + + + + + + More + Ancora + + + + + + + Close + + + + + NewsTab + + Download profile image for + Download immagine profilo per + + + More + Ancora + + + Timeline + Cronologia + + + Error + Errore + + + Favorites + Favoriti + + + Conversations + Conversazioni + + + Direct Messages + Messaggio diretto + + + Notifications + Notifiche + + + Group news + Gruppi + + + + + + + + seconds + secondi + + + + + + + + minute + minuti + + + + + + + + minutes + minuti + + + + + + + + hour + ora + + + + + + + + hours + ore + + + + + + + + day + giorno + + + + + + + + days + giorni + + + + + + + + month + mese + + + + + + + + months + mesi + + + + + + + + years + anni + + + + + + + + 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. + + + Network Error + Errore di rete + + + Replies + Risposte + + + Public timeline + + + + Quit + Chiudi + + + + NewsVideoLarge + + + + + Close + + + + + Newsitem + + attending: + attendere: + + + + + + + Source: + Codice: + + + + + + + Direct Message + Messaggio diretto + + + + + + In reply to + In risposta a + + + comments + commenti + + + + + + + attending + partecipare + + + + + + + ago + fa + + + + + + + Attending: + Attendi: + + + + + + Reply + Risposta + + + + + + + DM + Messaggio diretto + + + + + + + Repost + Condividi + + + + + + Like + + + + + + + Dislike + + + + + + + Favorite + + + + + + + Menu + + + + + + + + Success! + Ha funzionato! + + + + + + + Block contact + + + + + + + + Report contact + + + + + + + + Conversation + Conversazione + + + + + + + Bookmark + Segnalibro + + + + + + + Calendar Entry + + + + + + + + Attending + Attendi + + + + + + + yes + si + + + + + + + maybe + potrebbe + + + + + + + no + no + + + + + + + Delete + Cancella + + + + + + + External + Sito web + + + + PermissionDialog + + + + + + Friends + Amici + + + + + + + Groups + Gruppi + + + + + + save + + + + + + + apply + + + + + PhotoTab + + + + 's images + Immagini + + + + + + upload + + + + + + + download + + + + + + + + + All Images + Tutte immagini + + + + + + + + Only new + Solo nuovo + + + + + + + + + Own Images + Mie immagini + + + + + + + + More + Ancora + + + + + + Close + + + + + ProfileComponent + + + + + + + profile name + nome del profilo + + + + + + + + is default + è predefinito + + + + + + + + hide friends + nascondere gli amici + + + + + + + + profile photo + foto del profilo + + + + + + + + profile thumb + piccola foto di profilo + + + + + + + + publish + pubblicare + + + + + + + + publish in network + pubblicare in rete + + + + + + + + description + descrizione + + + + + + + + date of birth + data di nascita + + + + + + + + address + indirizzo + + + + + + + + city + città + + + + + + + + region + regione + + + + + + + + postal code + codice postale + + + + + + + + country + paese + + + + + + + + hometown + città natale + + + + + + + + gender + genere + + + + + + + + marital status + stato civile + + + + + + + + married with + sposato con + + + + + + + + married since + sposato da quando + + + + + + + + sexual + orientamento sessuale + + + + + + + + politics + politica + + + + + + + + religion + religione + + + + + + + + public keywords + parole chiave pubbliche + + + + + + + + private keywords + parole chiave private + + + + + + + + likes + ama + + + + + + + + dislikes + non piace + + + + + + + + about + su + + + + + + + + music + musica + + + + + + + + book + libro + + + + + + + + tv + tv + + + + + + + + film + film + + + + + + + + interest + interesse + + + + + + + + romance + romanticismo + + + + + + + + work + lavoro + + + + + + + + education + educazione + + + + + + + + social networks + reti sociali + + + + + + + + homepage + homepage + + + + + + + + other + altri + + + + + + refresh + + + + + + + + + Update + Aggiornare + + + + + + + + profile id + profilo id + + + + + + + + Description + Descrizione + + + + + + + + Location + Località + + + + + + + + Posts + Messaggi + + + + + + + + URL + URL + + + + + + + + Created at + Creato il + + + + ReportUser + + + + + + Report contact? + + + + + + + + + comment + + + + + + + + + illegal + + + + + + + + + spam + + + + + + + + + violation + + + + + SmileyDialog + + + + Unicode + Unicode + + + + + Standard + Standard + + + + + Addon + Addon + + + + + Adult + XXX + + + + + + Close + + + + + SyncComponent + + + + + + sync + sync + + + + + + + notify + notificare + + + + SyncConfig + + + + Sync Interval (0=None) + Intervallo (0=nessuno) + + + + + Min. + Min. + + + + + + Backgound Sync + + + + + friendiqa + + Refresh + Aggiorna + + + Timeline + Cronologia + + + Conversations + Conversazioni + + + Favorites + Favoriti + + + Replies + Risposte + + + Public Timeline + Cronologia pubblica + + + Group news + Notizie del gruppo + + + Search + Cerca + + + Settings + Configurazione + + + Accounts + Conti + + + Quit + Chiudi + + + + + + Background Sync + Rightclick or Middleclick to Quit + Sincronizzazione dello sfondo +Fare clic con il tasto destro del mouse o con il tasto centrale per uscire + + + + + + Click to open Friendiqa + Clicca per aprire Friendiqa + + + + + + + + Posts + Messaggi + + + + + + + + Contacts + Contatti + + + + + + Images + + + + + + + + Photos + + + + + + + + + Calendar + + + + + 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 + + + ago + fa + + + minute + minuti + + + minutes + minuti + + + hour + ora + + + hours + ore + + + day + giorno + + + days + giorni + + + month + mese + + + months + mesi + + + years + anni + + + + service + + Error + Errore + + + Changelog + Changelog + + + Setting view type of news has moved from account page to config page. + L'impostazione del tipo di visualizzazione delle notizie è stata spostata dalla pagina del conto alla pagina di configurazione. + + + + + + + + Undefined Array Error + + + + + + + + + JSON status Error + + + + diff --git a/src/translations/friendiqa-nl.qm b/src/translations/friendiqa-nl.qm new file mode 100644 index 0000000..7bbc963 Binary files /dev/null and b/src/translations/friendiqa-nl.qm differ diff --git a/src/translations/friendiqa-nl.ts b/src/translations/friendiqa-nl.ts new file mode 100644 index 0000000..4465ca6 --- /dev/null +++ b/src/translations/friendiqa-nl.ts @@ -0,0 +1,3139 @@ + + + + + AcceptRules + + + + + + Accept instance rules + Instantieregels aanvaarden + + + + AccountPage + + + + + + + + + + + User + Gebruiker + + + + + + + Instance rules + Instantieregels + + + + + + + Nickname + Bijnaam + + + + + + + + + + + + Error + Foutmelding + + + + + + + Nicknames containing @ symbol currently not supported + Bijnamen met het @-symbool worden momenteel niet ondersteund + + + + + + + + Password + Wachtwoord + + + + + + Method + + + + + + + OAuth + + + + + + + Close + + + + + + + + Image dir. + Afbeeldingsmap + + + + + + + Connect + Verbinden + + + + + + + No server given! + + + + + + + + Couldn't connect to server + + + + + + + + Confirm + Oké + + + + + + + No server given! + Geen server opgegeven! + + + + + + + No nickname given! + Geen bijnaam opgegeven! + + + + + + + No password given! + Geen wachtwoord opgegeven! + + + + + + + No image directory given! + Geen afbeeldingsmap opgegeven! + + + + + + + Set as default + + + + + + + + Wrong password or 2FA enabled! + Onjuist wachtwoord of 2FA ingeschakeld! + + + + + + + + Success + Voltooid + + + + + + + Name + Naam + + + Server + + + + News as + Nieuws als + + + Wrong password! + + + + Timeline + Tijdlijn + + + Conversations + Gesprekken + + + + BlockUser + + + + + + Block contact? + Contactpersoon blokkeren? + + + + CalendarTab + + + + + refresh + + + + + + + + Delete Event? + Gebeurtenis verwijderen? + + + + + + add + + + + + + + + Events + Gebeurtenissen + + + + + + + Own Calendar + Eigen agenda + + + + ConfigAppearancePage + + + + + + News as + Nieuws als + + + + + + + + + Conversations + Gesprekken + + + + + + + + Timeline + Tijdlijn + + + + + + + Max. News + Max. aantal items + + + + + + + Hide #nsfw? + #nsfw verbergen? + + + + + + Default News Tabs + + + + + + + + Dark Mode + Donker thema + + + + + + + System + Systeemthema + + + + + + + Dark + Donker + + + + + + + Light + Licht + + + + ConfigPage + + + + + + Appearance + Vormgeving + + + + + + + Sync + Synchronisatie + + + + + + Close + + + + + + Start + Starten + + + News as + Nieuws als + + + Conversations + Gesprekken + + + Timeline + Tijdlijn + + + Max. News + Max. aantal items + + + Hide #nsfw? + #nsfw verbergen? + + + + ConfigStartPage + + + + + + Autostart + Automatisch opstarten + + + + ConfigTab + + User + Gebruiker + + + Server + + + + Nickname + Bijnaam + + + Password + Wachtwoord + + + Image dir. + Afbeeldingsmap + + + Max. News + Max. aantal items + + + News as + Nieuws als + + + Interval (0=None) + + + + Error + Foutmelding + + + Nickname not registered at given server! + + + + Confirm + Oké + + + No server given! + Geen server opgegeven! + + + No nickname given! + Geen bijnaam opgegeven! + + + Nickname not registered at given server! + + + + No username given! + + + + Sync Interval (0=None) + Synchroniseren, elke (0=niet) + + + Nicknames containing @ symbol currently not supported + Bijnamen met het @-symbool worden momenteel niet ondersteund + + + Min. + min. + + + No password given! + Geen wachtwoord opgegeven! + + + No image directory given! + Geen afbeeldingsmap opgegeven! + + + No maximum news number given! + + + + Wrong password! + + + + Success + Voltooid + + + Name + Naam + + + Timeline + Tijdlijn + + + Conversations + Gesprekken + + + + ContactComponent + + + + + + Connect + Verbinden + + + + ContactDetailsComponent + + Connect + Verbinden + + + Description + Beschrijving + + + Location + Locatie + + + Posts + Berichten + + + URL + Url + + + Created at + Gemaakt op + + + + ContactPage + + + + + + seconds + seconden + + + + + + + minute + minuut + + + + + + + minutes + minuten + + + + + + + hour + uur + + + + + + + hours + uur + + + + + + + day + dag + + + + + + + days + dagen + + + + + + + month + maand + + + + + + + months + maanden + + + + + + + years + jaar + + + + + + + likes this. + vindt dit leuk. + + + + + + + like this. + vinden dit leuk. + + + + + + + doesn't like this. + vindt dit niet leuk. + + + + + + + don't like this. + vinden dit niet leuk. + + + + + + + will attend. + neemt deel. + + + + + + + persons will attend. + personen nemen deel. + + + + + + + will not attend. + neemt niet deel. + + + + + + + persons will not attend. + personen nemen niet deel. + + + + + + + may attend. + neemt mogelijk deel. + + + + + + + persons may attend. + personen nemen mogelijk deel. + + + + + + Direct Message + Privébericht + + + + + + + Approve + Goedkeuren + + + + + + + Reject + Weigeren + + + + + + + Ignore + Negeren + + + + + + + Follow + Volgen + + + + + + + Unfollow + Ontvolgen + + + + + + + Block + Blokkeren + + + + + + + Unblock + Deblokkeren + + + + + + + Description + Beschrijving + + + + + + + Location + Locatie + + + + + + + Posts + Berichten + + + + + + + URL + Url + + + + + + + Created at + Gemaakt op + + + + + + + Followers + Volgers + + + + + + + Following + Volgend + + + + + + + Network Error + Netwerkfout + + + + + + Close + + + + Connect + Verbinden + + + + Contactlist + + + + + Close + + + + + ContactsSearchPage + + + + + + Network Error + Netwerkfout + + + + + + + Forum + Forum + + + + + + + Person + Persoon + + + + + + + Close + + + + + Conversation + + + + + + seconds + seconden + + + + + + + minute + minuut + + + + + + + minutes + minuten + + + + + + + hour + uur + + + + + + + hours + uur + + + + + + + day + dag + + + + + + + days + dagen + + + + + + + month + maand + + + + + + + months + maanden + + + + + + + years + jaar + + + + + + + likes this. + vindt dit leuk. + + + + + + + like this. + vinden dit leuk. + + + + + + + doesn't like this. + vindt dit niet leuk. + + + + + + + don't like this. + vinden dit niet leuk. + + + + + + + will attend. + neemt deel. + + + + + + + persons will attend. + personen nemen deel. + + + + + + + will not attend. + neemt niet deel. + + + + + + + persons will not attend. + personen nemen niet deel. + + + + + + + may attend. + neemt mogelijk deel. + + + + + + + persons may attend. + personen nemen mogelijk deel. + + + + + + Close + + + + + DrawerAccountComponent + + + + + + Refresh + Herladen + + + + + + + Timeline + Tijdlijn + + + + + + + Conversations + Gesprekken + + + + + + + Replies + Antwoorden + + + + + + + Direct Messages + Privéberichten + + + + + + + Favorites + Favorieten + + + + + + + Public Timeline + Openbare tijdlijn + + + + + + + Group news + Groepsnieuws + + + + + + + Search + Zoeken + + + + + + + Notifications + Meldingen + + + + DrawerAccountComponentContacts + + + + + + Profile + Profiel + + + + + + Friends + Vrienden + + + + + + + Groups + Groepen + + + Contacts + + + + + EventCreate + + + + + Close + + + + + + + + Start + Begint om + + + + + + Start date + + + + + + + Start time + + + + + + + + End + Eindigt om + + + + + + End date + + + + + + + End time + + + + + + + Accept time + + + + + + + + no end + oneindig + + + + + + + Title (required) + Titel (vereist) + + + + + + + Event description (optional) + Gebeurtenisbeschrijving (optioneel) + + + + + + + Location (optional) + Locatie (optioneel) + + + + + + + Publish event? + Gebeurtenis publiceren? + + + + + + + Create event + Gebeurtenis aanmaken + + + + + + + + Error + Foutmelding + + + + + + + No event name supplied + Geen gebeurtenisnaam ingevoerd + + + + EventList + + + + + Close + + + + + + + + Delete Event? + Gebeurtenis verwijderen? + + + Location + Locatie + + + + EventListItem + + + + + Location + Locatie + + + + FriendicaActivities + + + + + Close + + + + + FriendsListTab + + + + + + Friend Requests + Vriendschapsverzoeken + + + + + + + + Friends + Vrienden + + + + + + refresh + + + + + + + + All + Alle + + + + + + + Blocked + Geblokkeerd + + + + FriendsTab + + + + + + Me + Ik + + + + + + + Friends + Vrienden + + + + + + + Groups + Groepen + + + Contacts + + + + + GroupComponent + + + + + Close + + + + + + + Members + + + + Error + Foutmelding + + + No name given + + + + + GroupsListTab + + + + + refresh + + + + + ImageUploadDialog + + + + + + Upload to album + Uploaden naar album + + + + + + Close + + + + + + + + Description + Beschrijving + + + + + + + Upload + Uploaden + + + + + + + Change + Wijzigen + + + + + + + Error + Foutmelding + + + + + + + No album name given + Geen albumnaam ingevoerd + + + Album + + + + Image + + + + + InfoBox + + + + + Close + + + + + LeftDrawerScrollview + + + + + + Settings + Instellingen + + + + + + + Accounts + Accounts + + + + + + + Quit + Afsluiten + + + + MessageImageUploadDialog + + + + + + Description + Beschrijving + + + + + + Add + + + + + + + + Upload + Uploaden + + + + MessageSend + + + + + Answer to + + + + + + + New message + + + + + + + + to: + aan: + + + + + + + Title (optional) + Titel (optioneel) + + + + + + + Drop your Content here. + Sleep inhoud hierheen. + + + + + + + What's on your mind? + Waar denk je aan? + + + + + + Copy + + + + + + + Cut + + + + + + + Paste + + + + + + + Text + + + + + + + + Bold + + + + + + + + + + + Format + + + + + + + Italic + + + + + + + Create list + + + + + + + Format as code + + + + + + + Rendered + + + + + + + MD + + + + + + + Show Markdown code + + + + + + + Edit + + + + + + + emojies + + + + + + + Insert smiley + + + + + + + Insert previous hashtag + + + + + + + Image + + + + + + + Insert images + + + + + + + Cancel message + + + + + + + Close + + + + + + + Format message + + + + + + + Send message + + + + + + + Send + + + + + + + + Error + Foutmelding + + + + + + + No receiver supplied! + Geen ontvanger gekozen! + + + Only one attachment supported at the moment. + Remove other attachment first! + + + + + MoreComments + + + + + + Show all comments + Alle reacties tonen + + + + NewsPhotolist + + + + + Close + + + + + NewsStack + + + + + + More + Meer + + + + + + + Close + + + + Network Error + Netwerkfout + + + + NewsTab + + + + + + seconds + seconden + + + + + + + minute + minuut + + + + + + + minutes + minuten + + + + + + + hour + uur + + + + + + + hours + uur + + + + + + + day + dag + + + + + + + days + dagen + + + + + + + month + maand + + + + + + + months + maanden + + + + + + + years + jaar + + + + + + + likes this. + vindt dit leuk. + + + + + + + like this. + vinden dit leuk. + + + + + + + doesn't like this. + vindt dit niet leuk. + + + + + + + don't like this. + vinden dit niet leuk. + + + + + + + will attend. + neemt deel. + + + + + + + persons will attend. + personen nemen deel. + + + + + + + will not attend. + neemt niet deel. + + + + + + + persons will not attend. + personen nemen niet deel. + + + + + + + may attend. + neemt mogelijk deel. + + + + + + + persons may attend. + personen nemen mogelijk deel. + + + Download profile image for + + + + More + Meer + + + Timeline + Tijdlijn + + + Error + Foutmelding + + + Favorites + Favorieten + + + Conversations + Gesprekken + + + Network Error + Netwerkfout + + + Replies + Antwoorden + + + Public timeline + + + + Direct Messages + Privéberichten + + + Notifications + Meldingen + + + Group news + Groepsnieuws + + + Quit + Afsluiten + + + + NewsVideoLarge + + + + + Close + + + + + Newsitem + + + + + + attending + neemt deel + + + + + + + Direct Message + Privébericht + + + + + + + Source: + Bron: + + + + + + + ago + geleden + + + + + + In reply to + Als antwoord op + + + + + + + Attending: + Deelnemers: + + + + + + Like + + + + + + + Dislike + + + + + + + Favorite + + + + + + + Reply + + + + + + + Menu + + + + + + + + Repost + Opnieuw plaatsen + + + + + + + Success! + Voltooid! + + + + + + + Block contact + Contactpersoon blokkeren + + + + + + + Report contact + Contactpersoon melden + + + + + + + Conversation + Gesprek + + + + + + + DM + PB + + + + + + + Bookmark + Bladwijzer + + + + + + + Calendar Entry + Agenda-item + + + + + + + Attending + Deelnemen + + + + + + + yes + ja + + + + + + + maybe + misschien + + + + + + + no + nee + + + + + + + Delete + Verwijderen + + + + + + + External + Extern + + + attending: + + + + comments + + + + + PermissionDialog + + + + + + Friends + Vrienden + + + + + + + Groups + Groepen + + + + + + save + + + + + + + apply + + + + + PhotoTab + + + + 's images + 's afbeeldingen + + + + + + upload + + + + + + + download + + + + + + + + All Images + Alle afbeeldingen + + + + + + + Only new + Alleen nieuwe + + + + + + + + Own Images + Eigen afbeeldingen + + + + + + + More + Meer + + + + + + Close + + + + + ProfileComponent + + + + + + profile name + profielnaam + + + + + + + is default + is standaard + + + + + + + hide friends + vrienden verbergen + + + + + + + profile photo + profielfoto + + + + + + + profile thumb + profielminiatuur + + + + + + + publish + publiceren + + + + + + + publish in network + publiceren op netwerk + + + + + + + description + beschrijving + + + + + + + date of birth + geboortedatum + + + + + + + address + adres + + + + + + + city + plaatsnaam + + + + + + + region + regio/provincie + + + + + + + postal code + postcode + + + + + + + country + land + + + + + + + hometown + geboorteplaats + + + + + + + gender + geslacht + + + + + + + marital status + huwelijksstatus + + + + + + + married with + gehuwd met + + + + + + + married since + gehuwd sinds + + + + + + + sexual + sekse + + + + + + + politics + politiek + + + + + + + religion + religie + + + + + + + public keywords + openbare trefwoorden + + + + + + + private keywords + privétrefwoorden + + + + + + + likes + ik houd van + + + + + + + dislikes + ik houd niet van + + + + + + + about + over + + + + + + + music + muziek + + + + + + + book + boek + + + + + + + tv + tv + + + + + + + film + film + + + + + + + interest + hobby + + + + + + + romance + romantiek + + + + + + + work + werk + + + + + + + education + educatie + + + + + + + social networks + sociale netwerken + + + + + + + homepage + website + + + + + + + other + overig + + + + + + refresh + + + + + + + + Update + Bijwerken + + + + + + + profile id + profiel-id + + + + + + + Description + Beschrijving + + + + + + + Location + Locatie + + + + + + + Posts + Berichten + + + + + + + URL + Url + + + + + + + Created at + Gemaakt op + + + + ReportUser + + + + + + Report contact? + Contactpersoon melden? + + + + + + + comment + reactie + + + + + + + illegal + illegaal + + + + + + + spam + spam + + + + + + + violation + overtreding + + + + SmileyDialog + + + + Unicode + Unicode + + + + + Standard + Standaard + + + + + Addon + Uitbreiding + + + + + Adult + 18+ + + + + + + Close + + + + + SyncComponent + + + + + + sync + synchronisatie + + + + + + + notify + melden + + + + SyncConfig + + + + Sync Interval (0=None) + Synchroniseren, elke (0=niet) + + + + + Min. + min. + + + + + + Backgound Sync + + + + + friendiqa + + + + Background Sync + Rightclick or Middleclick to Quit + Achtergrondsynchronisatie + Rechts- of middelklik om te stoppen + + + + + + + + Posts + Berichten + + + + + + + + Contacts + + + + + + + Images + + + + + + + + Photos + + + + + + + + + Calendar + + + + + + Click to open Friendiqa + Klik om Friendiqa te openen + + + Refresh + Herladen + + + Timeline + Tijdlijn + + + Conversations + Gesprekken + + + Favorites + Favorieten + + + Replies + Antwoorden + + + Public Timeline + Openbare tijdlijn + + + Group news + Groepsnieuws + + + Search + Zoeken + + + Settings + Instellingen + + + Accounts + Accounts + + + Quit + Afsluiten + + + + newsworker + + + + + yes + ja + + + + + + no + nee + + + + + + maybe + misschien + + + likes this. + vindt dit leuk. + + + like this. + vinden dit leuk. + + + doesn't like this. + vindt dit niet leuk. + + + don't like this. + vinden dit niet leuk. + + + will attend. + neemt deel. + + + persons will attend. + personen nemen deel. + + + will not attend. + neemt niet deel. + + + persons will not attend. + personen nemen niet deel. + + + may attend. + neemt mogelijk deel. + + + persons may attend. + personen nemen mogelijk deel. + + + seconds + seconden + + + ago + geleden + + + minute + minuut + + + minutes + minuten + + + hour + uur + + + hours + uur + + + day + dag + + + days + dagen + + + month + maand + + + months + maanden + + + years + jaar + + + + service + + + + + + Undefined Array Error + Onbepaalde reeksfout + + + + + + + JSON status Error + Json-statusfout + + + Error + Foutmelding + + + Changelog + + + + Setting view type of news has moved from account page to config page. + + + +