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 5119886..81cab7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,137 +1,219 @@ -## v0.5.3 ## -* Implementation of new events API (incl. sync and notification) for Friendica version >= 20.03 -* Indentation to see replied to newsitem for conversation view -* News view type config moved from account page to config page -* Simplification of account page on first start -* Bugfixes +## 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.5.2 ## -* Redesign of news item -* Background sync for Android >8.0 -* Bugfixes +## v0.6.8 +* OAuth2 as signup method +* New translation: Dutch -## v0.5.1 ## -* Videos open in full screen -* Youtube videos open in app -* Option to minimize #nsfw post -* Rotate image in messageSend component +## v0.6.7 -## v0.5 ## -* Redesign due to QML Components 1 being deprecated in Qt 5.12: Slideview for News, left Drawer for Settings, message creation in listview header -* Android Notifications for News, DMs, Replies -* Global app config separated from account config +* Upload multiple images for post and add image descriptions +* Block user +* Report user +* Create Calendar entry from post text +## v0.6.6 -## v0.4 ## -* Background sync for friends timeline (interval on config page must be > 0) for Android > 5 -* Replies timeline -* Bugfix: App asks for storage permission on first start +* Create event +* Delete event +* New sorting of conversations +## v0.6.5 -## v0.3.4 ## -* Direct message creation from profile page works again -* Profile image upload works again -* Viewing private album pictures of contacts works again -* On first start servername from https://dir.friendica.social/servers/surprise selected -* Register button opens webview of registration page on server +* Fix reply in Friendica 3/2022 version due to API bug +* Image downloads work again +* Some additional emojis +## v0.6.4 -## v0.3.3 ## -* Update for OpenSSL and At -* Experimental support for Peertube (links are expanded to video widget) -* Some Unicode emojis -* Redesign of contact details (click on contact opens in new stack and shows last news) +* 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 -## v0.3.2 ## -* For news containing url ending with mp3, mp4, avi, webm, ogg: media can be played in app -* Pictures can be renamed or moved to another album -* Bugfix: random crashes for conversations -* Bugfix: attach image to message works again -* Bugfix: check for nickname on Server has been removed due to API change +* 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 -## v0.3.1 ## -* By popular demand: Conversations open in a new stack, like in Twidere -* Conversations open after (long) press on news, like in Twidere -* Image attachments are shown below text and can be enlarged, like in Twidere (solves issue #8) -* New messages are html, line breaks work (solves issue #7) +* 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 -## v0.3 ## -* Fix for [issue 6](https://github.com/LubuWest/Friendiqa/issues/6) -* Refactoring of news part -* Search button for news -* Click on hashtag in newsitem starts search for news with that word -* Public timeline -* Timeline for selected group -* Small redesign of SendMessage page +* Add requestLegacyExternalStorage in AndroidManifest for attachment permissions +* Refresh timeline on start for Linux +* DropArea bugfix for Flatpak +## v0.6 -## v0.2.2 ## -* Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5) -* Link to list of public server on Config Tab -* Small redesign of SendMessage page -* Intents for texts/urls (Send text or url from everywhere to create message) +* New language: Hungarian thank to urbalazs (https://www.urbalazs.hu) +* Multiple photos in post open in separate slideshow +* Layout redesign +* Adaptive sidebar +* Sync Friendship Requests, approve/deny/ignore requests +* Events: show upcoming events below calendar +* Linux: Drag&Drop for new messages and photo upload +* Linux: Remember app size +## v0.5.3 -## v0.2.1 ## -* Fix for [issue 4](https://github.com/LubuWest/Friendiqa/issues/4) -* Fix for Friendica [issue 4689](https://github.com/friendica/friendica/issues/4689) -* Long posts are automatically truncated -* Intents for pictures (Send one image from gallery: attach to message, send multiple images: upload to album) +* Implementation of new events API (incl. sync and notification) for Friendica version >= 20.03 +* Indentation to see replied to newsitem for conversation view +* News view type config moved from account page to config page +* Simplification of account page on first start +* Bugfixes +## v0.5.2 -## v0.2 ## -# News # -* Profile image download completely reworked, resulting in speed improvement +* Redesign of news item +* Background sync for Android >8.0 +* Bugfixes -# Contacts # -* New profile tab, data of public and private profiles shown -* Change profile picture -* For friends image button shows private images thanks to new remoteAuth API (Friendica 3.6 server required) --> private holiday pictures have finally arrived! -* For friends calendar button shows private events thanks to new remoteAuth API (Friendica 3.6 server required) -* News button for forum accounts shows news published via that forum +## v0.5.1 -# Images # -* Complete rework of image download, fixes bug with private images -* Download all or only new images +* Videos open in full screen +* Youtube videos open in app +* Option to minimize #nsfw post +* Rotate image in messageSend component -# Config # -* Check if nickname exist on server -* Check if password is correct -* Account deletion now also removes news, image data and events from local db +## v0.5 -# Translations # -* Italian thanks to Davide de Prisco +* Redesign due to QML Components 1 being deprecated in Qt 5.12: Slideview for News, left Drawer for Settings, message creation in listview header +* Android Notifications for News, DMs, Replies +* Global app config separated from account config +## v0.4 + +* Background sync for friends timeline (interval on config page must be > 0) for Android > 5 +* Replies timeline +* Bugfix: App asks for storage permission on first start + +## v0.3.4 + +* Direct message creation from profile page works again +* Profile image upload works again +* Viewing private album pictures of contacts works again +* On first start servername from https://dir.friendica.social/servers/surprise selected +* Register button opens webview of registration page on server + +## v0.3.3 + +* Update for OpenSSL and At +* Experimental support for Peertube (links are expanded to video widget) +* Some Unicode emojis +* Redesign of contact details (click on contact opens in new stack and shows last news) + +## v0.3.2 + +* For news containing url ending with mp3, mp4, avi, webm, ogg: media can be played in app +* Pictures can be renamed or moved to another album +* Bugfix: random crashes for conversations +* Bugfix: attach image to message works again +* Bugfix: check for nickname on Server has been removed due to API change + +## v0.3.1 + +* By popular demand: Conversations open in a new stack, like in Twidere +* Conversations open after (long) press on news, like in Twidere +* Image attachments are shown below text and can be enlarged, like in Twidere (solves issue #8) +* New messages are html, line breaks work (solves issue #7) + +## v0.3 + +* Fix for [issue 6](https://github.com/LubuWest/Friendiqa/issues/6) +* Refactoring of news part +* Search button for news +* Click on hashtag in newsitem starts search for news with that word +* Public timeline +* Timeline for selected group +* Small redesign of SendMessage page + +## v0.2.2 + +* Fix for [issue 5](https://github.com/LubuWest/Friendiqa/issues/5) +* Link to list of public server on Config Tab +* Small redesign of SendMessage page +* Intents for texts/urls (Send text or url from everywhere to create message) + +## v0.2.1 + +* Fix for [issue 4](https://github.com/LubuWest/Friendiqa/issues/4) +* Fix for Friendica [issue 4689](https://github.com/friendica/friendica/issues/4689) +* Long posts are automatically truncated +* Intents for pictures (Send one image from gallery: attach to message, send multiple images: upload to album) + +## v0.2 + +# News + +* Profile image download completely reworked, resulting in speed improvement + +# Contacts + +* New profile tab, data of public and private profiles shown +* Change profile picture +* For friends image button shows private images thanks to new remoteAuth API (Friendica 3.6 server required) --> private holiday pictures have finally arrived! +* For friends calendar button shows private events thanks to new remoteAuth API (Friendica 3.6 server required) +* News button for forum accounts shows news published via that forum + +# Images + +* Complete rework of image download, fixes bug with private images +* Download all or only new images + +# Config + +* Check if nickname exist on server +* Check if password is correct +* Account deletion now also removes news, image data and events from local db + +# Translations + +* Italian thanks to Davide de Prisco ## v0.1.2## -* FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above +* FIX: Include openssl v1.0.2m for SSL connections in Android v7 and above ## v0.1.1## -* FIX: Spanish translation -* FIX: Empty Newsview after deletion of first newsitem +* FIX: Spanish translation +* FIX: Empty Newsview after deletion of first newsitem ## v0.1## -# News # +# News -* Native Android image selector for new message -* Click on contacts shows contact details on news page -* Fix problem with news list after deletion of item +* Native Android image selector for new message +* Click on contacts shows contact details on news page +* Fix problem with news list after deletion of item -# Contacts # -* Clean contacts with no news +# Contacts -# Images # -* Upload pictures with description to album (permissions cannot be set due to API problems) -* Delete pictures or albums from client and server (long press on picture in overview) -* Fix problem when enlarging photo +* Clean contacts with no news -# Translations # -* German, Spanish +# Images + +* Upload pictures with description to album (permissions cannot be set due to API problems) +* Delete pictures or albums from client and server (long press on picture in overview) +* Fix problem when enlarging photo + +# Translations + +* German, Spanish diff --git a/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/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 0fef74b..e80c04c 100644 --- a/README.md +++ b/README.md @@ -1,123 +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 -* Click on image shows image fullscreen -* 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 -* 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, Notify yes/no -* Hide #nsfw - -ToDo -* OAuth? - - -# Other # -ToDo -* Video tab -* Translation -* Blingbling - - -# Translations # -* German, Spanish, Italian -* 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/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) - - -## 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-android/CMakeLists.txt b/source-android/CMakeLists.txt new file mode 100644 index 0000000..c47a156 --- /dev/null +++ b/source-android/CMakeLists.txt @@ -0,0 +1,96 @@ +# 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) + +set(CMAKE_CXX_STANDARD 11) +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(Qt5 COMPONENTS Widgets Quick Sql DBus WebView REQUIRED) + +#Webview Webengine + +set(MOC_SOURCES common/uploadableimage.h + common/xhr.h + common/filesystem.h + common/remoteauthasyncimageprovider.h + common/updatenews.h + common/alarm.h) + +set(SOURCES common/friendiqa.cpp + common/uploadableimage.cpp + common/xhr.cpp + common/filesystem.cpp + common/remoteauthasyncimageprovider.cpp + common/updatenews.cpp + common/alarmandroid.cpp) + +include_directories(common) + +add_executable(friendiqa ${SOURCES} ${MOC_SOURCES} application.qrc) + +target_link_libraries(friendiqa Qt::Core) +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) + +# 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 22426df..277b677 100644 --- a/source-android/android/AndroidManifest.xml +++ b/source-android/android/AndroidManifest.xml @@ -1,19 +1,20 @@ - - - - - - - - + + - - + + @@ -87,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 --> - + @@ -129,4 +130,11 @@ + + + + + + + diff --git a/source-android/android/arm/libcrypto_1_1.so b/source-android/android/arm/libcrypto_1_1.so old mode 100755 new mode 100644 diff --git a/source-android/android/arm/libssl_1_1.so b/source-android/android/arm/libssl_1_1.so old mode 100755 new mode 100644 diff --git a/source-android/android/arm64/libcrypto_1_1.so b/source-android/android/arm64/libcrypto_1_1.so old mode 100755 new mode 100644 diff --git a/source-android/android/arm64/libssl_1_1.so b/source-android/android/arm64/libssl_1_1.so old mode 100755 new mode 100644 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/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/gradlew b/source-android/android/gradlew old mode 100755 new mode 100644 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 423f4aa..01833c2 100644 --- a/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java +++ b/source-android/androidnative.pri/java/src/androidnative/AndroidNativeActivity.java @@ -4,13 +4,13 @@ import android.util.Log; import android.app.Activity; import android.os.*; import java.util.Map; +import java.util.HashMap; import android.content.pm.PackageManager; import android.content.Context; import android.Manifest.permission; -//import android.support.v4.app.ActivityCompat; -//import android.support.v4.content.ContextCompat; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; +import androidnative.AndroidNativeService; /** An alternative Activity class for Qt applicaiton. @@ -18,8 +18,9 @@ import androidx.core.content.ContextCompat; */ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.QtActivity { - public static final int MY_PERMISSIONS_REQUEST_WRITE_STORAGE = 0x245285a8; - + 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) { @@ -30,18 +31,24 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt protected void onResume() { super.onResume(); - if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) { + + + + AndroidNativeService fs = new AndroidNativeService(); + fs.startQtService(this); + //if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) { // Permission is not granted - ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},MY_PERMISSIONS_REQUEST_WRITE_STORAGE); + // ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},MY_PERMISSIONS_REQUEST_WRITE_STORAGE); // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an // app-defined int constant. The callback method gets the // result of the request. - } else { + //} else { System.loadLibrary("friendiqa_arm64-v8a"); + //System.loadLibrary("friendiqa_armeabi-v7a"); if((getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_NEW_TASK) || (getIntent().getFlags() == Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) || (getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))) { SystemDispatcher.onActivityResume(); } else { @@ -68,29 +75,42 @@ public class AndroidNativeActivity extends org.qtproject.qt5.android.bindings.Qt } else { SystemDispatcher.onActivityResume(); }} - } + //} } @Override public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) { + Log.d(TAG,"onRequestPermissionsResult"); switch (requestCode) { - case MY_PERMISSIONS_REQUEST_WRITE_STORAGE: { + case MY_PERMISSIONS_REQUEST_READ_STORAGE: { // If request is cancelled, the result arrays are empty. - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - SystemDispatcher.onActivityResume(); - } 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; } } -} protected void onNewIntent(Intent data) { System.loadLibrary("friendiqa_arm64-v8a"); + //System.loadLibrary("friendiqa_armeabi-v7a"); super.onNewIntent(data); if ((data!=null) && (data.getType() != null) && !(data.getBooleanExtra("used",false))){ String type = data.getType(); 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/ImagePicker.java b/source-android/androidnative.pri/java/src/androidnative/ImagePicker.java index 5fd8c04..9b9b0e5 100644 --- a/source-android/androidnative.pri/java/src/androidnative/ImagePicker.java +++ b/source-android/androidnative.pri/java/src/androidnative/ImagePicker.java @@ -1,6 +1,7 @@ package androidnative; import org.qtproject.qt5.android.QtNative; import android.content.Intent; +import android.content.Context; import android.util.Log; import android.app.Activity; import java.util.Map; @@ -17,12 +18,20 @@ import android.content.ClipData; import java.util.List; import java.util.ArrayList; +import android.content.pm.PackageManager; +import android.content.Context; +import android.Manifest.permission; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + + + public class ImagePicker { // Random public static final int PICK_IMAGE_ACTION = 0x245285a3; public static final int TAKE_PHOTO_ACTION = 0x29fe8748; - + public static final int MY_PERMISSIONS_REQUEST_READ_STORAGE = 0x245285a8; public static final String PICK_IMAGE_MESSAGE = "androidnative.ImagePicker.pickImage"; public static final String TAKE_PHOTO_MESSAGE = "androidnative.ImagePicker.takePhoto"; public static final String CHOSEN_MESSAGE = "androidnative.ImagePicker.chosen"; @@ -47,8 +56,15 @@ public class ImagePicker { } static void pickImage(Map message) { + Context context; + context = QtNative.activity().getApplicationContext(); + Activity activity = org.qtproject.qt5.android.QtNative.activity(); + if (ContextCompat.checkSelfPermission(context,android.Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) { + // Permission is not granted + ActivityCompat.requestPermissions(activity,new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},MY_PERMISSIONS_REQUEST_READ_STORAGE); + } else { Boolean multiple = false; - Activity activity = org.qtproject.qt5.android.QtNative.activity(); + //Activity activity = org.qtproject.qt5.android.QtNative.activity(); Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); @@ -63,7 +79,7 @@ public class ImagePicker { // >= API 18 activity.startActivityForResult(intent, PICK_IMAGE_ACTION); - } + }} static void takePhoto(Map message) { if (message.containsKey("broadcast")) { @@ -96,7 +112,6 @@ public class ImagePicker { return; int requestCode = (Integer) message.get("requestCode"); Intent data = (Intent) message.get("data"); - if (requestCode == PICK_IMAGE_ACTION) { importImage(data); } else if (requestCode == TAKE_PHOTO_ACTION) { @@ -111,8 +126,8 @@ public class ImagePicker { static private void importImage(Intent data) { Uri uri = data.getData(); - Log.d(TAG,"importImage: uri:" + uri); - Log.d(TAG,"importImage: type: " + data.getType()); + //Log.d(TAG,"importImage: uri:" + uri); + //Log.d(TAG,"importImage: type: " + data.getType()); if (data.getClipData() != null) { importImageFromClipData(data); diff --git a/source-android/androidnative.pri/java/src/androidnative/SystemDispatcher.java b/source-android/androidnative.pri/java/src/androidnative/SystemDispatcher.java index a8f0015..616fce5 100644 --- a/source-android/androidnative.pri/java/src/androidnative/SystemDispatcher.java +++ b/source-android/androidnative.pri/java/src/androidnative/SystemDispatcher.java @@ -140,6 +140,7 @@ public class SystemDispatcher { waitingIntent=null; isIntentPending=false; } else { //onIntent start + Log.e(TAG,"notInitialized: onIntentStart "+data); message.put("text",data.getStringExtra(Intent.EXTRA_TEXT)); message.put("subject",data.getStringExtra(Intent.EXTRA_SUBJECT)); waitingIntent = message; 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/friendiqa.cpp b/source-android/common/friendiqa.cpp index 259a880..7dc02b5 100644 --- a/source-android/common/friendiqa.cpp +++ b/source-android/common/friendiqa.cpp @@ -36,11 +36,9 @@ #include "xhr.h" #include "updatenews.h" #include "filesystem.h" +#include "oauth.h" #include "remoteauthasyncimageprovider.h" #include "AndroidNative/systemdispatcher.h" -//#include "AndroidNative/environment.h" -//#include "AndroidNative/debug.h" -//#include "AndroidNative/mediascannerconnection.h" #ifdef Q_OS_ANDROID @@ -57,26 +55,24 @@ 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(); } else{ QApplication app(argc, argv); - QQuickView view; - //qDebug()<<"FriendiqaMain started"; + QQmlApplicationEngine view; QTranslator qtTranslator; qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations"); app.installTranslator(&qtTranslator); RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider; - view.engine()->addImageProvider("remoteauthimage",imageProvider); + view.addImageProvider("remoteauthimage",imageProvider); view.rootContext()->setContextProperty("remoteauth", imageProvider); XHR* xhr = XHR::instance(); view.rootContext()->setContextProperty("xhr", xhr); @@ -86,9 +82,9 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) { view.rootContext()->setContextProperty("alarm", alarm); UPDATENEWS* updatenews = UPDATENEWS::instance(); view.rootContext()->setContextProperty("updatenews", updatenews); - view.setSource(QUrl("qrc:/qml/friendiqa.qml")); - //QtWebEngine::initialize(); - view.show(); + 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())); return app.exec(); 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 fdc129c..20ff216 100644 --- a/source-android/friendiqa.pro +++ b/source-android/friendiqa.pro @@ -13,17 +13,18 @@ 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) SOURCES += common/friendiqa.cpp \ - common/uploadableimage.cpp \ + common/uploadableimage.cpp \ common/xhr.cpp \ - common/filesystem.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 \ @@ -52,7 +52,9 @@ OTHER_FILES += qml/friendiqa.qml \ TRANSLATIONS += translations/friendiqa-de.ts \ translations/friendiqa-es.ts \ - translations/friendiqa-it.ts + translations/friendiqa-it.ts \ + translations/friendiqa-hu.ts \ + translations/friendiqa-nl.ts HEADERS += \ common/uploadableimage.h \ @@ -60,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 \ @@ -71,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 \ @@ -83,4 +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 9f4955e..e9c5227 100644 --- a/source-android/qml/friendiqa.qml +++ b/source-android/qml/friendiqa.qml @@ -33,46 +33,55 @@ 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 +import "qrc:/qml/genericqml" -StackView{ +ApplicationWindow{ id:root + title: "Friendiqa" property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettingsAndroid.qml");return tmp.createObject(root)} - width: osSettings.appWidth - height:osSettings.appHeight + 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 - signal messageSignal(var friend) + 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 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 string contactLoadType: "" property bool imagePicking: false - onLoginChanged:{ - if(login==""){root.push("qrc:/qml/configqml/AccountPage.qml")} - else{root.push(rootStackItem) - if (login.newsViewType!="" || login.newsViewType!=null){newstab.newstabstatus=login.newsViewType;} + Material.theme: Material.System + + function onLoginChanged(login){ + if(login=="" || login==null){rootstackView.push("qrc:/qml/configqml/AccountPage.qml")} + else{ Newsjs.getCurrentContacts(login,db,function(contacts){ contactlist=contacts})} } - onNewContactsChanged:{ + function onNewContactsChanged(newContacts){ if(newContacts.length>0){// download contact images and update db var contacturls=[]; var contactnames=[]; @@ -91,9 +100,32 @@ StackView{ } + 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){ + rootstackView.push("qrc:/qml/newsqml/ContactPage.qml",{"contact": contact}) + } + + Connections{ target:xhr - onDownloaded:{ + 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; @@ -104,293 +136,135 @@ StackView{ } } + FontLoader{id: fontAwesome; source: "qrc:/images/fontawesome-webfont.ttf"} - Keys.onReleased: {//print(event.key + "Backkey"+newstab.conversation.length+" "+root.depth) - if (event.key === osSettings.backKey) { + onClosing: { 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; } - else if (newstab.conversation.length>0){newstab.conversation=[]} - else if (root.depth>1){root.pop()} - else{Service.cleanNews(root.db,function(){ - Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) - })} + else if (newstab.conversation.length>0){ + newstab.conversation=[]; + close.accepted=false + } + 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() + }) + })}) + 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} + } - Drawer{ - id: leftDrawer - width: 0.66* root.width - height: root.height - edge: Qt.LeftEdge - position: 1.0 - Column{ - x:mm - width:parent.width-mm - Label{ - text: login.hasOwnProperty("username")?login.username:"" - font.pixelSize: 4*mm - width: parent.width - height: 6*mm - } -// Label{ -// text:login.hasOwnProperty("server")?"@"+login.server:"" -// font.pixelSize: 5*mm -// width: parent.width -// } - - Label{ - text: "\uf021 " + qsTr("Refresh") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ + + + + footer:ToolBar{id:roottoolbar + background: Rectangle{ + anchors.fill: parent + color: Material.backgroundDimColor + } + + TabBar { + id: bar + width:parent.width + onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex + TabButton { + text: "\uf03a" + font.pointSize: osSettings.bigFontSize + background:Rectangle{ anchors.fill: parent - onClicked:{ - leftDrawer.close(); -// newstypeSignal("refresh") - updatenews.setDatabase(); - updatenews.login(); - updatenews.startsync(); - } + color: Material.backgroundDimColor } } - - - Label{ - text: "\uf1da " + qsTr("Timeline") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ + TabButton { + text: "\uf0c0" + font.pointSize: osSettings.bigFontSize + background:Rectangle{ anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("timeline") - } + color: Material.backgroundDimColor } } - - Label{ - text: "\uf086 " + qsTr("Conversations") - width: parent.width - font.pixelSize: 4*mm - MouseArea{ + TabButton { + text: "\uf03e" + font.pointSize: osSettings.bigFontSize + background:Rectangle{ anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("conversation") - } + color: Material.backgroundDimColor } } - - Label{ - text: "\uf005 " + qsTr("Favorites") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ + TabButton { + text: "\uf073" + font.pointSize: osSettings.bigFontSize + background:Rectangle{ anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("favorites") - } + color: Material.backgroundDimColor } } - Label{ - text: "\uf0ec " + qsTr("Replies") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("replies") - } - } - } - - - Label{ - text: "\uf0ac " + qsTr("Public Timeline") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("publictimeline") - } - } - } - - Label{ - text: "\uf0c0 " + qsTr("Group news") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("groupnews") - } - } - } - - Label{ - text: "\uf002 " + qsTr("Search") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("search") - } - } - } - - Label{ - text: "\uf085 "+ qsTr("Settings") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked: {root.push("qrc:qml/configqml/ConfigPage.qml"); - leftDrawer.close() - } - } - } - Label{ - text: "\uf2bb " + qsTr("Accounts") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked: {root.push("qrc:qml/configqml/AccountPage.qml"); - leftDrawer.close() - } - } - } - - Label{ - text: "\uf08b " +qsTr("Quit") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - Service.cleanNews(root.db,function(){ - Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) - }) - } - } - } - } } - Item{ - id:rootStackItem - width:parent.width - height: parent.height - //anchors.fill:parent - states: State { - name: "fullscreen"; - PropertyChanges { target: bar; height:0 } - PropertyChanges { target: rootstack; height:parent.height } - } - - transitions: Transition { - PropertyAnimation { properties: "height"; - easing.type: Easing.InOutQuad - duration: 1000 - } - } - TabBar { - id: bar - width: parent.width - height: 7*mm - position:TabBar.Footer - anchors.top: rootstack.bottom - onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex - TabButton { - text: "\uf03a" - font.pixelSize: 3*mm - height: 6*mm - } - TabButton { - text: "\uf0c0" - font.pixelSize: 3*mm - height: 6*mm - } - TabButton { - text: "\uf03e" - font.pixelSize: 3*mm - height: 6*mm - } - - TabButton { - text: "\uf073" - font.pixelSize: 3*mm - height: 6*mm - } - } - - StackLayout{ + StackView{id:rootstackView + width:root.width + height: root.height + initialItem: StackLayout{ id:rootstack - width:parent.width - height: parent.height-7*mm + width:rootstackView.width + height: rootstackView.height currentIndex:bar.currentIndex - Loader{ id: newstab - Layout.fillWidth:true - Layout.fillHeight: true property string newstabstatus property var conversation:[] - property var contactposts:[] source:(rootstack.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" + //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: { - forceActiveFocus(); - //print(xhr.networktype()); + 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"); var IntentReceiverQml = component.createObject(root); @@ -401,4 +275,3 @@ StackView{ } } } -} 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 1b454d1..0000000 --- a/source-linux/application.qrc +++ /dev/null @@ -1,241 +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/ContactDetailsComponent.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 - - diff --git a/source-linux/common/friendiqa.cpp b/source-linux/common/friendiqa.cpp deleted file mode 100644 index 52ef822..0000000 --- a/source-linux/common/friendiqa.cpp +++ /dev/null @@ -1,101 +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); - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - QTranslator qtTranslator; - qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations"); - app.installTranslator(&qtTranslator); - RemoteAuthAsyncImageProvider *imageProvider = new RemoteAuthAsyncImageProvider; - view.engine()->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.setSource(QUrl("qrc:/qml/friendiqa.qml")); - view.show(); - view.connect(view.rootContext()->engine(), SIGNAL(quit()), &app, SLOT(quit())); - return app.exec(); - } -} - diff --git a/source-linux/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 c7c5908..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/news.js b/source-linux/js/news.js deleted file mode 100644 index cd1fecf..0000000 --- a/source-linux/js/news.js +++ /dev/null @@ -1,600 +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 requestFriends(login,database,rootwindow,callback){ -// return array of friends - var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); - db.transaction( function(tx) { - var result = tx.executeSql('UPDATE contacts SET isFriend=0 where username="'+login.username+'"')}); // clean old friends - Helperjs.friendicaRequest(login,"/api/statuses/friends?count=9999", rootwindow,function (obj){ - var friends=JSON.parse(obj); - for (var i=0;i0'+filtertext); - var result = tx.executeSql('SELECT * from contacts WHERE username="'+login.username+'" AND isFriend>0'); - // check for friends - var contactlist=[]; - 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;j0){ - for (var j=0;j0){ - for (var k=0;j0){var helpernews=newsrs.rows.item(0); - var newscount=newsrs.rows.length; - helpernews=fetchUsersForNews(database,user,helpernews,allcontacts); - helpernews.statusnet_html=Qt.atob(helpernews.statusnet_html); - helpernews.text=Qt.atob(helpernews.text); - helpernews.id=helpernews.status_id;helpernews.friendica_author=objFromArray(allcontacts,"url",helpernews.friendica_owner); - if (helpernews.attachments!="" && helpernews.attachments!==null){helpernews.attachments=JSON.parse(Qt.atob(helpernews.attachments))}; - callback(helpernews,newscount);} -// var conversationobject={news:helpernews,newscount:newscount}; -// return conversationobject; -})} - - - - -function getAllContacts(database,user){ - var allcontacts=[]; - Helperjs.readData(database,"contacts",user,function(obj){ - allcontacts=obj; - for (var n in allcontacts){ - allcontacts[n].name=Qt.atob(allcontacts[n].name); - allcontacts[n].description=Qt.atob(allcontacts[n].description) - } - }); - return allcontacts; -} - -function inArray(list, prop, val) { - if (list.length > 0 ) { - for (var i in list) {if (list[i][prop] == val) { - return true; - } - } - } return false; -} - -function objFromArray(list, prop, val) { - if (list.length > 0 ) { - for (var i in list) {if (list[i][prop] == val) { - return list[i]; - } - } - } return false; -} - -function cleanDate(date){ - var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25); - return cleanedDate -} diff --git a/source-linux/js/newsworker.js b/source-linux/js/newsworker.js deleted file mode 100644 index 6c83d17..0000000 --- a/source-linux/js/newsworker.js +++ /dev/null @@ -1,174 +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 attachmentList=[]; - 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} - attachmentList.push(attachhelper) - //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),"") - } - } - }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 ((attachmentList.length==0) || (attachmentList[attachmentList.length-1].url!=videohelper.url)){attachmentList.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 ((attachmentList.length==0) || (attachmentList[attachmentList.length-1].url!=ptvideohelper.url)){attachmentList.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 ((attachmentList.length==0) || (attachmentList[attachmentList.length-1].url!=ythelper.url)){attachmentList.push(ythelper)} - } - } - newsitemobject.attachmentList=attachmentList; - - 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.model.clear()}; - msg.model.sync() - for (var j=0;j1)){ - newsitemobject.lastcomment=beautify(newsitemobject.currentconversation[newsitemobject.currentconversation.length-1],msg); - //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+1; - if (newsitemobject.indent>6){newsitemobject.indent=6}; - break} - } - }} - - 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 8f79b08..0000000 --- a/source-linux/js/service.js +++ /dev/null @@ -1,674 +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)') -})} - -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 {var rsObject=""} - callback(rsObject)}} - ) -} - -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)); -// print('SELECT DISTINCT created_at FROM news WHERE messagetype='+i+' ORDER BY created_at ASC LIMIT ' +(newscount-maxnewsa)) -// print(JSON.stringify(lastvalidtimers.rows.item(newscount-maxnewsa-1))) - 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;i-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/calendarqml/CalendarTab.qml b/source-linux/qml/calendarqml/CalendarTab.qml deleted file mode 100644 index 9e6884a..0000000 --- a/source-linux/qml/calendarqml/CalendarTab.qml +++ /dev/null @@ -1,189 +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 QtQml 2.2 -import Qt.labs.calendar 1.0 -//import QtQuick.Controls 1.2 as Oldcontrol -import QtQuick.Layouts 1.3 -import "qrc:/js/service.js" as Service -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/calendarqml" -import "qrc:/qml/genericqml" - -Rectangle { - id:calendarrectangle -// y:1 -// width:root.width-mm -// height:root.height-5*mm - anchors.fill: parent - color: '#fff' - property date currentTime: new Date() - property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000 - property var events:[] - property var eventdays:[] - - - function showEvents(friend){ - if(friend=="backButton"){Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ - events=eventArray; - eventdays=dayArray}) - } - else if (friend!=""){ - calendartab.calendartabstatus=friend.url.substring(friend.url.lastIndexOf("/")+1,friend.url.length) - Service.newRequestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){ - events=eventArray; - eventdays=dayArray}) - } - else {calendartab.calendartabstatus="Events"; - Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ - events=eventArray; - eventdays=dayArray; - calBusy.running=false - }) - } - } - - BusyIndicator{ - id: calBusy - anchors.horizontalCenter: calendarView.horizontalCenter - anchors.top:calendarView.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - running: false - } - - - MButton{ - id: updateEvents - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right:calendartabstatusButton.left - anchors.rightMargin:mm - height: 6*mm - width: 8*mm - text:"\uf021" - onClicked: { - calBusy.running=true; - updatenews.setDatabase(); - updatenews.login(); - updatenews.events(); -// Service.getEvents(db,login, calendartab,function(){ -// showEvents("") -// }) - }} - -Connections{ - target: updatenews - - onSuccess:{ - calBusy.running=false; - showEvents("") - } - } - - - MButton{ - id: calendartabstatusButton - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right: parent.right - anchors.rightMargin:2*mm - height: 6*mm - width: Math.max(10*mm,implicitWidth) - text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus - Menu { - id:calendartabmenu - width: 40*mm - MenuItem { - text: qsTr("Own Calendar") - font.pixelSize: 3*mm - onTriggered: { - calendartab.calendartabstatus="Events"; - // calendartabstatusButton.text=qsTr("own Calendar"); - showEvents("")} - } - } - onClicked: {calendartabmenu.popup()} - } - - - ListView{ - id: calendarView - x: mm;y:8*mm - width: parent.width-2*mm; height: parent.height-9*mm - clip: true - snapMode: ListView.SnapOneItem - orientation: ListView.Horizontal - highlightRangeMode: ListView.StrictlyEnforceRange - model: CalendarModel {id:calendarModel - from: new Date() - to: new Date(new Date().valueOf()+93312000000) - } - delegate: - ColumnLayout{ - width:calendarView.width - Text{ - font.bold: true - Layout.fillWidth: true - horizontalAlignment:Text.AlignHCenter - text: model.year - } - Text{ - text: Qt.locale().standaloneMonthName(model.month) - Layout.fillWidth: true - horizontalAlignment:Text.AlignHCenter - } - DayOfWeekRow{ - locale: monthgrid.locale - Layout.fillWidth: true - font.pixelSize: 3*mm - } - - MonthGrid { - id: monthgrid - Layout.fillWidth: true - month: model.month - year: model.year - locale: Qt.locale() - delegate: CalendarDay{} - } - } - ScrollIndicator.horizontal: ScrollIndicator { } - } - - Component.onCompleted: { - root.eventSignal.connect(showEvents); - if (calendartab.calendartabstatus=="Events"){showEvents("")} - } - } diff --git a/source-linux/qml/calendarqml/EventList.qml b/source-linux/qml/calendarqml/EventList.qml deleted file mode 100644 index e5629b4..0000000 --- a/source-linux/qml/calendarqml/EventList.qml +++ /dev/null @@ -1,132 +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:/js/service.js" as Service -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/genericqml" - -Rectangle{ - id:eventList - z:2 - border.color: "grey" - width: parent.width-4*mm - height:parent.height-12*mm - x:mm - y:mm - property var daylist:[] - property int dayint: 0 - MButton{ - id:closeButton - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - height: 6*mm - width: 8*mm - text: "\uf057" - onClicked:{eventList.destroy()} - } - ListView { - id: eventlistView - x: mm - y:closeButton.height+2*mm - width: eventList.width-2*mm - height: eventList.height-closeButton.height-4*mm - clip: true - model: eventModel - delegate: eventItem - } - - ListModel{ - id: eventModel - } - - Component.onCompleted:{//print("daylist"+JSON.stringify(daylist) + dayint) - var currentevents=events.filter(event=>(dayint>=event.startday)&&(dayint<=event.endday)); - for (var i=0; i0?new Date(event.end).toLocaleString(Qt.locale(),Locale.NarrowFormat):" ")+": "+event.title //+calendarrectangle.offsetTime - font.pixelSize: 3*mm - wrapMode:Text.Wrap - } - - Text { - id:eventDetailsText - x:8*mm - z:4 - width: parent.width-8*mm - height: contentHeight - textFormat: Text.RichText - text: status==""?"":Qt.atob(event.desc) + (event.location==""?"":"

"+qsTr("Location")+": "+event.location)//Qt.atob(event.html) - anchors.top: eventNameText.bottom - font.pixelSize: 3*mm - wrapMode:Text.Wrap - onLinkActivated:{Qt.openUrlExternally(link)} - } - MouseArea{ - anchors.fill: parent - onClicked:{if (status==""){status="large"} else {status=""} - } - } - } - } -} diff --git a/source-linux/qml/configqml/AccountPage.qml b/source-linux/qml/configqml/AccountPage.qml deleted file mode 100644 index f9d88c7..0000000 --- a/source-linux/qml/configqml/AccountPage.qml +++ /dev/null @@ -1,467 +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 "qrc:/js/service.js" as Service -import "qrc:/js/layout.js" as Layoutjs -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/configqml" -import "qrc:/qml/genericqml" - -Page{ - id:accountPage - width: root.width - height: root.height - property var users:[] - property var userdata: ({}) - - function setServericon(server){ - try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",accountPage, function (obj){ - var serverdata = JSON.parse(obj); - servericon.visible=true; - servericon.source=serverdata.site.logo})} catch(e){print(e)} - } - - Button{ - id:userButton - height: 8*mm - text:qsTr("User") - font.pixelSize: 3*mm - x: mm - y: mm - width: root.width/2 - 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) - } - } - } - } -// Button { -// x: root.width-9*mm; y: 23.5*mm; width:5*mm; height:5*mm -// text: "\uf234" -// font.pixelSize: 3*mm -// onClicked: { -// root.push("qrc:/qml/configqml/RegisterPage.qml",{url:servername.text+"/register?nickname="+username.getText(0,username.length)}) -// } -// } - - Rectangle{ - color: "light grey" - x: 4*mm; y: 33.5*mm; width: root.width-6*mm; height: 5*mm; - TextInput { - id: password - anchors.fill: parent - font.pixelSize:3*mm - selectByMouse: true - echoMode: TextInput.PasswordEchoOnEdit - } - } - - Rectangle{color: "light grey"; x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm;} - Flickable { - id: imagestoreFlickable - x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm; - clip: true - TextInput { - id: imagestore - width: imagestoreFlickable.width - height: imagestoreFlickable.height - font.pixelSize:3*mm - text: (osSettings.osType=="Android") && (filesystem.fileexist("/storage/emulated/0/Pictures/"))?"/storage/emulated/0/Pictures/":"" - wrapMode: TextEdit.NoWrap - onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,imagestoreFlickable) - } - } - - FileDialog { - id: imagestoreDialog - title: "Please choose a directory" - folder: shortcuts.pictures - selectFolder: true - onAccepted: { - var imagestoreString=imagestoreDialog.folder.toString(); - imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/" - imagestore.text=imagestoreString - } - } - - Button { - x: root.width-9*mm; y: 43.5*mm; width: 5*mm; height: 5*mm; - text: "..." - font.pixelSize: 3*mm - onClicked: - {imagestoreDialog.open()} - } - - -// Slider{ id: maxNews -// x:19*mm; y: 53.5*mm;width: root.width/2;height:5*mm -// from: 0;to:2000; stepSize: 100 -// } - - -// Rectangle{color: "light grey"; x: 4*mm; y: 53.5*mm; width: 9*mm; height: 5*mm; -// TextEdit{id:maxNewsText; -// anchors.fill: parent -// font.pixelSize:3*mm -// verticalAlignment:TextEdit.AlignRight -// text:maxNews.value -// focus: true -// selectByMouse: true -// } -// } - -// Rectangle{ -// x: 4*mm; y: 53.5*mm; width: newsTypeField.contentWidth+2*mm; height: 5*mm; -// color:"light grey" -// Text{ -// id: newsTypeField -// anchors.fill: parent -// font.pixelSize:3*mm -// text:"Conversations" -// } -// MouseArea{ -// anchors.fill:parent -// onClicked:newstypemenu.popup() -// } -// } - - BusyIndicator{ - id: accountBusy - anchors.horizontalCenter: parent.horizontalCenter - y: 63.5*mm - width:10*mm - height: 10*mm - running: false - } -// CheckBox{ -// id:showwebsiteCheckbox -// x:35*mm;y:80*mm -// onClicked:{ -// if (checked==true){ -// Service.updateglobaloptions(root.db,"showWebsiteForLinks","true") -// root.globaloptions.showWebsiteForLinks="true" -// } -// else { -// Service.updateglobaloptions(root.db,"showWebsiteForLinks","false") -// root.globaloptions.showWebsiteForLinks="false" -// } -// } -// } - - Button { - x: 4*mm; y: 63.5*mm - height: 8*mm - text: qsTr("Confirm") - font.pixelSize: 3*mm - onClicked:{ - accountBusy.running=true; - var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text, maxnews:"",interval: ""}; - var errormessage=""; - if (servername.text==""){errormessage=qsTr("No server given! ")} - else if (username.text==""){errormessage+=qsTr("No nickname given! ")} - else if (password.text=="") {errormessage+=qsTr("No password given! ")} - else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")} - //else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")} - else {errormessage=""} - if (errormessage=="") { - Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){ - accountBusy.running=false; - var credentials=JSON.parse(obj); - if (credentials.hasOwnProperty('status')){ - Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root) - } - else{ - if (users.length==0){Service.setDefaultOptions(db);} - filesystem.Directory=userconfig.imagestore; - filesystem.makeDir("contacts"); - filesystem.makeDir("albums"); - Service.storeConfig(db,userconfig); - Service.readConfig(db,function(userconfig){ - Helperjs.readData(db,"config","",function(storedUsers){ - storedUsers.sort(function(obj1, obj2) { - return obj1.isActive - obj2.isActive; - }); - accountPage.users=storedUsers}); - //reset values - root.login=userconfig; - root.news=[]; - rootstack.currentIndex=0; - root.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) - } - }); - - } - else {Helperjs.showMessage(qsTr("Error"), errormessage,root)} - }} - - - - Button { - x: parent.width/2+2*mm; y: mm; width: 5*mm; height: 8*mm; - visible: users.length>0 - text: "-" - font.pixelSize: 3*mm - onClicked:{ - var userconfig={server: servername.text, username: username.text, password: Qt.btoa(password.text)}; - Service.deleteConfig(db,userconfig,function(){ - filesystem.Directory=imagestore.text+"contacts"; - filesystem.rmDir(); - filesystem.Directory=imagestore.text+"albums"; - filesystem.rmDir(); - servername.text="https://"; - servericon.visible=false; - servericon.source=""; - username.text=""; - password.text=""; - imagestore.text=""; - //maxNews.value=0; - //newsTypeField.text="Conversations"; - //messageIntervalSlider.value=30; - userButton.text=qsTr("User"); - Helperjs.readData(db,"config","",function(storedUsers){ - storedUsers.sort(function(obj1, obj2) { - return obj1.isActive - obj2.isActive; - }) - accountPage.users=storedUsers;}) - }) - }} - - Button { - x: parent.width/2+8*mm; y: mm; width: 5*mm; height: 8*mm; - visible: users.length>0 - text: "+" - font.pixelSize: 3*mm - onClicked:{ - servername.text="https://" - servericon.visible=false; - servericon.source=""; - username.text="" - password.text="" - imagestore.text="" - //maxNews.value=0 - //newsTypeField.text="Conversations" - //messageIntervalSlider.value=30 - userButton.text=qsTr("User") - } - } - - Button { - x: parent.width/2+14*mm; y: mm; width: 5*mm; height: 8*mm; - text: "?" - font.pixelSize: 3*mm - onClicked:{ - root.push("qrc:/qml/configqml/InfoBox.qml"); - } - } - Button{ - id:closeButton - height: 8*mm - width: 5*mm - visible: users.length>0 - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - font.pixelSize: 3*mm - onClicked:{root.pop()} - } -// Menu { -// id:newstypemenu -// MenuItem { -// font.pixelSize: 3*mm -// text: qsTr("Timeline") -// onTriggered: {newsTypeField.text="Timeline"} -// } -// MenuItem { -// font.pixelSize: 3*mm -// text: qsTr("Conversations") -// onTriggered: {newsTypeField.text="Conversations"} -// } -// } - - Component.onCompleted: { - try{Helperjs.readData(db,"config","",function(storedUsers){ - storedUsers.sort(function(obj1, obj2) { - return obj1.isActive - obj2.isActive; - }) - accountPage.users=storedUsers; - Service.readConfig(db,function(obj){ - userButton.text=obj.username; - servername.text=obj.server; - accountPage.setServericon(obj.server); - username.text= obj.username; - password.text=Qt.atob(obj.password); - imagestore.text=obj.imagestore; - //maxNews.value=obj.maxnews; - //newsTypeField.text=obj.newsViewType; - //messageIntervalSlider.value=obj.timerInterval; - if( obj.isActive==0){userButton.font.bold='true'} else {userButton.font.bold='false'} - },"isActive",0) - })} - catch (e){//print("onCompleted" +users.count +e) -// Helperjs.friendicaWebRequest("https://dir.friendica.social/servers/surprise",accountPage,function(html){ -// print(html); -// var bpos=html.indexOf("base "); -// var baseurl=html.substring(html.indexOf("http",bpos),html.indexOf('"',html.indexOf("http",bpos))); -// servername.text=baseurl -// }) - } - } -} diff --git a/source-linux/qml/configqml/ConfigPage.qml b/source-linux/qml/configqml/ConfigPage.qml deleted file mode 100644 index f95662b..0000000 --- a/source-linux/qml/configqml/ConfigPage.qml +++ /dev/null @@ -1,169 +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: 4*mm; y:13.5*mm; width: parent.width - 14*mm; height: 5*mm; - color:"light grey" - radius: 0.5*mm - Text{ - anchors.fill: parent - font.pixelSize:3*mm - text:qsTr("Sync") - } - MouseArea{ - anchors.fill:parent - onClicked:root.push("qrc:qml/configqml/SyncConfig.qml"); - } - } - - Text { - text: qsTr("News as") - font.pixelSize:3*mm - x: 4*mm; y: 20*mm - } - - Rectangle{ - x: 4*mm; y: 23.5*mm; width: newsTypeField.contentWidth+2*mm; height: 5*mm; - color:"light grey" - radius: 0.5*mm - Text{ - id: newsTypeField - anchors.fill: parent - font.pixelSize:3*mm - text:qsTr("Conversations") - } - MouseArea{ - anchors.fill:parent - onClicked:newstypemenu.popup() - } - } - Menu { - id:newstypemenu - MenuItem { - font.pixelSize: 3*mm - text: qsTr("Timeline") - onTriggered: {newsTypeField.text=qsTr("Timeline"); - Service.updateglobaloptions(root.db,"newsViewType","Timeline");} - } - MenuItem { - font.pixelSize: 3*mm - text: qsTr("Conversations") - onTriggered: {newsTypeField.text=qsTr("Conversations"); - Service.updateglobaloptions(root.db,"newsViewType","Conversations");} - } - } - - - Text { - text: qsTr("Max. News") - font.pixelSize:3*mm - x: 4*mm; y:30*mm - } - - Slider{ id: maxNews - x:19*mm; y: 33.5*mm;width: root.width/2;height:5*mm - from: 0;to:2000; stepSize: 100 - value: root.globaloptions.hasOwnProperty("max_news")?root.globaloptions.max_news:1000 - } - - Rectangle{color: "light grey"; x: 4*mm; y: 33.5*mm; width: 9*mm; height: 5*mm; - radius: 0.5*mm - TextEdit{id:maxNewsText; - anchors.fill: parent - font.pixelSize:3*mm - verticalAlignment:TextEdit.AlignRight - text:maxNews.value - selectByMouse: true - onTextChanged: { - Service.updateglobaloptions(root.db,"max_news",text); - } - } - } - - - - CheckBox{ - id: nsfwCheckbox - x: 4*mm - y: 43.5*mm - font.pixelSize: 3*mm - //width:5*mm - 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: 1*mm - width: 8*mm; height: 6*mm; - text: "?" - font.pixelSize: 3*mm - onClicked:{ - root.push("qrc:/qml/configqml/InfoBox.qml"); - } - } - MButton{ - id:closeButton - height: 6*mm - width :8*mm - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - font.pixelSize: 3*mm - onClicked:{root.pop()} - } -} diff --git a/source-linux/qml/contactqml/ContactDetailsComponent.qml b/source-linux/qml/contactqml/ContactDetailsComponent.qml deleted file mode 100644 index 2b21682..0000000 --- a/source-linux/qml/contactqml/ContactDetailsComponent.qml +++ /dev/null @@ -1,176 +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" - 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{ - horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff - //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(); - } - } - - - Button{ - 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(); - } - } - - Button{ - id: closeButton - height: 6*mm - width: 8*mm - text: "\uf057" //"close" - onClicked:{contactLargeComponent.destroy(); - } - } - } - } -} -} diff --git a/source-linux/qml/contactqml/FriendsTab.qml b/source-linux/qml/contactqml/FriendsTab.qml deleted file mode 100644 index 87eb392..0000000 --- a/source-linux/qml/contactqml/FriendsTab.qml +++ /dev/null @@ -1,402 +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.Controls.Styles 1.4 -import QtQuick.Layouts 1.11 -import QtQuick.LocalStorage 2.0 -import "qrc:/js/helper.js" as Helperjs -import "qrc:/js/news.js" as Newsjs -import "qrc:/js/service.js" as Service -import "qrc:/qml/contactqml" -import "qrc:/qml/genericqml" - -Rectangle { - y:1 - color: "white" - -// function showContactdetails(contact){ -// var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml"); -// if(contact.isFriend){ -// friendsTabView.currentIndex=1; -// var contactDetails = component.createObject(friendstab,{"contact": contact}) -// } -// else{friendsTabView.currentIndex=2; -// var contactDetails = component.createObject(friendstab,{"contact": contact}) -// } -// } - - function showContactdetails(contact){ - rootstack.currentIndex=0; - bar.currentIndex=0; - root.contactdetailsSignal(contact) - } - - function showProfile(callback){ - var profile=({}); - Helperjs.readData(db,"profiles",login.username,function(profileobject){ - var profilearray=[]; - for (var i in profileobject){ - profilearray.push(JSON.parse(Qt.atob(profileobject[i].profiledata))); - } - profile.profiles=profilearray; - }); - Helperjs.readData(db,"contacts",login.username,function(owner){ - profile.friendica_owner=owner[0]; - },"isFriend",2); - callback(profile) - } - - TabBar { - id: friendsbar - width: parent.width - height: 9*mm - position:TabBar.Header - currentIndex: 1 - TabButton { - text: qsTr("Me") - font.pixelSize: 2*mm - } - TabButton { - text: qsTr("Friends") - font.pixelSize: 2*mm - } - TabButton { - text: qsTr("Contacts") - font.pixelSize: 2*mm - } - TabButton { - text: qsTr("Groups") - font.pixelSize: 2*mm - } - } - StackLayout{ - id:friendsTabView - //anchors.fill: parent - x:mm - y:10*mm - width: parent.width-2*mm - height: parent.height-10*mm - currentIndex: friendsbar.currentIndex - signal contactsSignal(var contact) - signal groupsSignal(var username) - - onCurrentIndexChanged:{ - if (currentIndex==1){ - contactsSignal("") - } - else if (currentIndex==2){ - contactsSignal("") - } - else if (currentIndex==3){groupsSignal(root.login.username)} - } -// style: TabViewStyle { -// frameOverlap: 1 -// tab: Rectangle { -// color: "white" -// implicitWidth: root.width/4-2*mm -// implicitHeight: 4*mm -// Text { id: text -// anchors.centerIn: parent -// text: styleData.title -// color: "dark grey" -// font.pixelSize:2.5*mm -// font.bold: styleData.selected -// } -// } -// frame: Rectangle { color: "light grey" } -// tabsAlignment:Qt.AlignHCenter -// } - - Item{ - id:profileGridTab - Layout.fillWidth:true - Layout.fillHeight: true - Component.onCompleted:{ - showProfile(function(profile){ - var component = Qt.createComponent("qrc:/qml/contactqml/ProfileComponent.qml"); - var profilecomp = component.createObject(profileGridTab,{"profile": profile}); - }); - } - } - - 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,"contacts",login.username,function(friendsobject){ - for (var i=0;i1){ - friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid - } - friendsModel.append({"contact":friendsobject[i]}); - } - },"isFriend",1,"screen_name ASC"); - } - Connections{ - target:xhr - onDownloaded:{ - 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 - height: 6*mm - width: 8*mm - onClicked: { - try {friendsModel.clear()} catch(e){print(e)}; - //root.contactLoadType="friends"; - Newsjs.requestFriends(root.login,db,root,function(nc){ - root.newContacts=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 - } - - //GridView { - ListView{ - id: friendsView - x:mm - y:updateFriendsButton.height+2*mm - width:friendsGridTab.width-2*mm - height:friendsGridTab.height-updateFriendsButton.height-2*mm - clip: true - spacing: 2 - function processContactSelection(contactobject){showContactdetails(contactobject)} - //add: Transition { - // NumberAnimation { properties: "x,y"; from: 300; duration: 1000 } - // } - model: friendsModel - delegate: ContactComponent { } - } - - ListModel{id:friendsModel} - - Component.onCompleted: { - root.friendsSignal.connect(showFriends); - friendsTabView.contactsSignal.connect(showFriends); - showFriends(root.login.username); - root.newContacts=[] - } - } - - 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 "qrc:/js/helper.js" as Helperjs -import "qrc:/js/news.js" as Newsjs -import "qrc:/qml/genericqml" - -Item { - id: groupComponent - 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 - width: 16*mm - height: 15*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 - width: wrapper.width-2 - height: 3.5*mm - anchors.top: photoImage.bottom - border.color: "light grey" - TextInput { - id: namelabel - anchors.fill: parent - readOnly: true - text: group.new?"":group.groupname - color: "#303030" - font.pixelSize: 3*mm - - } - } - - MButton{ - id: closeButton - visible: false - width: 8*mm - height: 6*mm - anchors.left: infobutton.right - anchors.margins: mm - anchors.top: parent.top - - text: "\uf057" - font.pixelSize: 3*mm - onClicked:{groupComponent.state=""; - if (group.new){groupsModel.remove(index)} - } - } - - MButton{ - id:infobutton - width: 4*mm - height: 6*mm - - //color:"transparent" - text:"?" - font.pixelSize: 3*mm - anchors.left: photoImage.right - anchors.leftMargin: mm - anchors.topMargin: mm - anchors.top: parent.top - onClicked:{ - //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); - //} - groupComponent.state="large" - } - } - - Rectangle{ - id: detailsrectangle - anchors.top: namelabelRect.bottom - anchors.topMargin: mm - opacity: 0 - -// 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) -// // } -// // } -// } -// } -// } - - ListView{ - id: groupListView - x:1 - //anchors.top: parent.top - width: root.width-10*mm - height:groupsView.height - 24*mm - clip: true - spacing: 2 - model: groupModel - delegate: ContactComponent { }// groupMember - function processContactSelection(contactobject){showContactdetails(contactobject)} - } - - ListModel{id: groupModel} - - 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 - - -StackView{ - id:root - property QtObject osSettings: {var tmp=Qt.createComponent("qrc:/qml/configqml/OSSettingsLinux.qml");return tmp.createObject(root)} - width: osSettings.appWidth - height:osSettings.appHeight - property var db: ["Friendiqa", "1.0", "Stores Friendica data", 100000000] - property var login: Service.readActiveConfig(db) - property var globaloptions: Service.readGO(db) - property var contactlist: [] - property real mm: osSettings.osType=="Android"?Screen.pixelDensity:Screen.pixelDensity*1.5 - signal messageSignal(var friend) - signal fotoSignal(var username, var friend) - signal directmessageSignal(var friend) - signal newsSignal(var news) - signal newstypeSignal(var type) - signal friendsSignal(var username) - signal contactdetailsSignal(var contact) - signal eventSignal(var contact) - signal uploadSignal(var urls) - signal sendtextSignal(var intenttext) - signal changeimage(var method, var type, var id) - signal updateSyncinterval(int interval) - property var news:[] - property var newContacts:[] - //property string contactLoadType: "" - property bool imagePicking: false - - onLoginChanged:{ - if(login==""){root.push("qrc:/qml/configqml/AccountPage.qml")} - else{root.push(rootStackItem) - if (login.newsViewType!="" || login.newsViewType!=null){newstab.newstabstatus=login.newsViewType;} - Newsjs.getCurrentContacts(login,db,function(contacts){ - contactlist=contacts})} - } - onNewContactsChanged:{ - 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(); - } - - } - - Connections{ - target:xhr - onDownloaded:{ - if(type=="contactlist"){ - var database=LocalStorage.openDatabaseSync(root.db[0],root.db[1],root.db[2],root.db[3]); - var result; - database.transaction( function(tx) { - result = tx.executeSql('UPDATE contacts SET profile_image="'+filename+'" where profile_image_url="'+url+'"'); - }) - } - } - } - - FontLoader{id: fontAwesome; source: "qrc:/images/fontawesome-webfont.ttf"} - - Keys.onReleased: {//print(event.key + "Backkey"+newstab.conversation.length+" "+root.depth) - 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) - })} - } - - else if (newstab.conversation.length>0){newstab.conversation=[]} - else if (root.depth>1){root.pop()} - else{Service.cleanNews(root.db,function(){ - Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) - })} - } - else if (rootstack.currentIndex==2){fotoSignal("backButton")} - else {rootstack.currentIndex=0} - event.accepted = true - }} - - Drawer{ - id: leftDrawer - width: 0.66* root.width - height: root.height - edge: Qt.LeftEdge - position: 1.0 - Column{ - x:mm - width:parent.width-mm - Label{ - text: login.hasOwnProperty("username")?login.username:"" - font.pixelSize: 4*mm - width: parent.width - height: 6*mm - } -// Label{ -// text:login.hasOwnProperty("server")?"@"+login.server:"" -// font.pixelSize: 5*mm -// width: parent.width -// } - - Label{ - text: "\uf021 " + qsTr("Refresh") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); -// newstypeSignal("refresh") - updatenews.setDatabase(); - updatenews.login(); - updatenews.startsync(); - } - } - } - - - Label{ - text: "\uf1da " + qsTr("Timeline") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("timeline") - } - } - } - - Label{ - text: "\uf086 " + qsTr("Conversations") - width: parent.width - font.pixelSize: 4*mm - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("conversation") - } - } - } - - Label{ - text: "\uf005 " + qsTr("Favorites") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("favorites") - } - } - } - Label{ - text: "\uf0ec " + qsTr("Replies") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("replies") - } - } - } - - - Label{ - text: "\uf0ac " + qsTr("Public Timeline") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("publictimeline") - } - } - } - - Label{ - text: "\uf0c0 " + qsTr("Group news") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("groupnews") - } - } - } - - Label{ - text: "\uf002 " + qsTr("Search") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.close(); - newstypeSignal("search") - } - } - } - - Label{ - text: "\uf085 "+ qsTr("Settings") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked: {root.push("qrc:qml/configqml/ConfigPage.qml"); - leftDrawer.close() - } - } - } - Label{ - text: "\uf2bb " + qsTr("Accounts") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked: {root.push("qrc:qml/configqml/AccountPage.qml"); - leftDrawer.close() - } - } - } - - Label{ - text: "\uf08b " +qsTr("Quit") - font.pixelSize: 4*mm - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - Service.cleanNews(root.db,function(){ - Service.cleanContacts(root.login,root.db,function(){ - Qt.quit()}) - }) - } - } - } - - } - } - - Item{ - id:rootStackItem - width:parent.width - height: parent.height - //anchors.fill:parent - states: State { - name: "fullscreen"; - PropertyChanges { target: bar; height:0 } - PropertyChanges { target: rootstack; height:parent.height } - } - - transitions: Transition { - PropertyAnimation { properties: "height"; - easing.type: Easing.InOutQuad - duration: 1000 - } - } - TabBar { - id: bar - width: parent.width - height: 7*mm - position:TabBar.Footer - anchors.top: rootstack.bottom - onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex - TabButton { - text: "\uf03a" - font.pixelSize: 3*mm - height: 6*mm - } - TabButton { - text: "\uf0c0" - font.pixelSize: 3*mm - height: 6*mm - } - TabButton { - text: "\uf03e" - font.pixelSize: 3*mm - height: 6*mm - } - - TabButton { - text: "\uf073" - font.pixelSize: 3*mm - height: 6*mm - } - } - - StackLayout{ - id:rootstack - width:parent.width - height: parent.height-7*mm - currentIndex:bar.currentIndex - - - Loader{ - id: newstab - Layout.fillWidth:true - Layout.fillHeight: true - property string newstabstatus - property var conversation:[] - property var contactposts:[] - source:(rootstack.currentIndex==0)? "qrc:/qml/newsqml/NewsTab.qml":"" - } - Loader{ - id: friendstab - Layout.fillWidth:true - Layout.fillHeight: true - source: (rootstack.currentIndex==1)?"qrc:/qml/contactqml/FriendsTab.qml":"" - } - Loader{ - id: fotostab - property string phototabstatus:"Images" - Layout.fillWidth:true - Layout.fillHeight: true - source: (rootstack.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":"" - } - Loader{ - id: calendartab - property string calendartabstatus:"Events" - Layout.fillWidth:true - Layout.fillHeight: true - source: (rootstack.currentIndex==3)?"qrc:/qml/calendarqml/CalendarTab.qml":"" - } - - } - Component.onCompleted: { - forceActiveFocus(); - //print(xhr.networktype()); - if(osSettings.osType=="Android"){ - var component = Qt.createComponent("qrc:/qml/genericqml/IntentReceiver.qml"); - var IntentReceiverQml = component.createObject(root); - } - else if (osSettings.osType=="Linux"){ - var component = Qt.createComponent("qrc:/qml/genericqml/LinuxSync.qml"); - var LinuxSyncQml = component.createObject(root); - } - } -} -} diff --git a/source-linux/qml/genericqml/ImagePickerLinux.qml b/source-linux/qml/genericqml/ImagePickerLinux.qml deleted file mode 100644 index ddb0045..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: 8*mm - 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.pixelSize: 3*mm - 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.pixelSize: 10*mm - } - - 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/genericqml/Search.qml b/source-linux/qml/genericqml/Search.qml deleted file mode 100644 index 8a05021..0000000 --- a/source-linux/qml/genericqml/Search.qml +++ /dev/null @@ -1,87 +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.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 - - -Rectangle { - id:searchComponent - //onActiveFocusChanged: searchText.forceActiveFocus() - //onVisibleChanged: if (visible) searchText.forceActiveFocus() -// border.color: "#EEEEEE" -// border.width: 1 - color:"lightgrey" -// width:conversationView.width -// height:Math.max(replyText.contentHeight+2*mm,6*mm) - Rectangle{ - color: "white" - radius:0.5*mm - anchors.left: parent.left - anchors.leftMargin:mm - anchors.top:parent.top - anchors.topMargin: 0.5*mm - width:parent.width-2*mm - height: 4*mm //Math.max( searchText.contentHeight,5*mm) - - TextInput { - id: searchText - focus: true - font.pixelSize: 3*mm - 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() -// BlueButton { -// id: sendButton -// text: "\uf002" -// anchors.left: parent.right -// anchors.leftMargin:mm -// anchors.top:parent.top -// //anchors.topMargin: 0.5*mm -// color:"white" -// onClicked: { -// var body=searchText.getText(0,searchText.length); -// search(body) -// } -// } - } - -} diff --git a/source-linux/qml/newsqml/ContactPage.qml b/source-linux/qml/newsqml/ContactPage.qml deleted file mode 100644 index b77abd2..0000000 --- a/source-linux/qml/newsqml/ContactPage.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.0 -import QtQuick.Controls 2.12 -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/genericqml" - -Rectangle { - id:contactList - color: "white" - property var contact:({}) - property string profileimagesource:contact.profile_image - ListView { - id: contactView - x:mm - y:9*mm - width: contactList.width-4*mm - height:contactList.height-10*mm - clip: true - spacing: 0 - header: contactHeader - model: contactModel - delegate: Newsitem{} - } - BusyIndicator{ - id: contactBusy - anchors.centerIn:parent - width:10*mm - height: 10*mm - running: true - } - - Component { id: contactHeader - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - color:"white" - width:contactView.width - height: profileImage.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 - x:mm - y:mm - width: 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"} - Connections{ - target:contactList - onProfileimagesourceChanged:profileImage.source=profileimagesource - } - } - Column{id:buttoncolumn - anchors.right: parent.right - anchors.rightMargin: mm - y: mm - spacing:4 - - MButton{ - id:photobutton - height: 6*mm - width: 8*mm - text: "\uf03e" // "Photos" - //font.pixelSize: 3*mm - visible:(contact.network=="dfrn") - onClicked:{ - rootstack.currentIndex=2; - bar.currentIndex=2; - fotostab.phototabstatus="Contact"; - - //fotostab.active=true; - fotoSignal(root.login,contact) ; - newsStack.pop(); - } - } - - MButton{ - id:dmbutton - height: 6*mm - width: 8*mm - visible: (contact.following=="true") - text: "\uf040" //"DM" - //font.pixelSize: 3*mm - onClicked:{ - rootstack.currentIndex=0; - newsSwipeview.currentIndex=2; - directmessageSignal(contact) - } - } - - MButton{ - id:eventbutton - visible:(contact.network=="dfrn") - height: 6*mm - width: 8*mm - text:"\uf073" - //font.pixelSize: 3*mm - onClicked:{ - rootstack.currentIndex=3; - bar.currentIndex=3; - calendartab.calendartabstatus="Friend" - eventSignal(contact); - newsStack.pop() - } - } - - }//Column end - Label { - id: namelabel - x:mm - width: contactView.width-2*mm - height: implicitHeight - text:contact.name+" (@"+contact.screen_name+")" - wrapMode: Text.Wrap//elide:Text.ElideRight - color: "#303030" - font.pixelSize: 4*mm - anchors.top: profileImage.bottom - anchors.topMargin: mm - } - Text{ - id:detailtext - anchors.top: namelabel.bottom - anchors.topMargin: 2*mm - x:mm - width: contactView.width-2*mm - height: implicitHeight - font.pixelSize: 2.5*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)} - } - - - //} - } - - }//Component end - Connections{ - target:newstab - onContactpostsChanged:{ - if (newstab.contactposts.length>0){profileimagesource=newstab.contactposts[0].user.profile_image_url_large} - contactBusy.running=false; - contactModel.clear(); - var currentTime= new Date(); - var msg = {'currentTime': currentTime, 'model': contactModel,'news':newstab.contactposts, 'options':globaloptions}; - contactWorker.sendMessage(msg) - } - } - - ListModel{id: contactModel} - - WorkerScript { - id: contactWorker - source: "qrc:/js/newsworker.js" - } - - MButton { - id: closeButton - height: 6*mm - width: 8*mm - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - //font.pixelSize: 3*mm - onClicked: { - newsStack.pop() - } - } - Component.onCompleted: { - xhr.clearParams(); - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/user_timeline"); - xhr.setParam("user_id",contact.id) - xhr.get(); - } -} diff --git a/source-linux/qml/newsqml/Conversation.qml b/source-linux/qml/newsqml/Conversation.qml deleted file mode 100644 index c0dbfc7..0000000 --- a/source-linux/qml/newsqml/Conversation.qml +++ /dev/null @@ -1,192 +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 . - -// ConversationView with button -import QtQuick 2.0 -import QtQuick.Controls 2.12 -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/genericqml" -import "qrc:/qml/newsqml" - -Rectangle { - id:conversationList -// width:root.width-5*mm -// height:root.height-12*mm - property var news:[] -// y:1 -// z:2 - color: "white" -// border.color: "grey" -// width:root.width-5*mm -// height: conversationView.height+10*mm - - ListView { - id: conversationView - property string viewtype: "conversation" - x:3*mm - y:8*mm - width: conversationList.width-4*mm - //height: contentHeight - height:conversationList.height-10*mm - clip: true - spacing: 0 - footer: MessageSend{conversation:true}//footerReply - model: conversationModel - delegate: Newsitem{} - } - BusyIndicator{ - id: conversationBusy - anchors.horizontalCenter: conversationView.horizontalCenter - anchors.top:conversationList.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - running: true - } - - Connections{ - target:newstab - onConversationChanged:{ - //if(newsitem.itemindex==newsStack.conversationIndex){ - if(newstab.conversation.length==0){ - newsStack.pop() - //newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning); - //conversationList.destroy(); conversationsymbol.color="grey" - } else { conversationBusy.running=false; - conversationModel.clear(); - var currentTime= new Date(); - var msg = {'currentTime': currentTime, 'model': conversationModel,'news':newstab.conversation, 'method':'conversation', 'options':globaloptions}; - conversationWorker.sendMessage(msg) - //conversationsymbol.color="grey" - } - //} - } - } - -// Component { id:footerReply -// Rectangle{ -// border.color: "#EEEEEE" -// border.width: 1 -// color:"lightgrey" -// width:conversationView.width -// height:Math.max(replyText.contentHeight+2*mm,6*mm) -// Rectangle{ -// color: "white" -// radius:0.5*mm -// anchors.left: parent.left -// anchors.leftMargin:mm -// anchors.top:parent.top -// anchors.topMargin: 0.5*mm -// width:parent.width-12*mm -// height:Math.max( replyText.contentHeight,5*mm) - -// TextInput { -// id: replyText -// font.pixelSize: 3*mm -// wrapMode: Text.Wrap -// anchors.fill: parent -// selectByMouse: true -// onHeightChanged: conversationView.contentY+=4.5*mm -// } -// } - -// Button { -// id: sendButton -// height: 8*mm -// width:8*mm -// text: "\uf1d9" -// anchors.right: parent.right -// anchors.rightMargin:mm -// anchors.top:parent.top -// anchors.topMargin: 0.5*mm -// //color:"white" -// onClicked: { try{ -// var body=replyText.getText(0,replyText.length); -// newsBusy.running=true; -// replyText.text="" -// xhr.clearParams(); -// xhr.setLogin(login.username+":"+Qt.atob(login.password)); -// if (conversationModel.get(0).newsitemobject.messagetype==0){ - -// //xhr.url= login.server + "/api/statuses/update.json"; -// xhr.setUrl(login.server); -// xhr.setApi("/api/statuses/update"); -// xhr.setParam("source", "Friendiqa"); -// xhr.setParam("status", body); -// xhr.setParam("in_reply_to_status_id", conversationModel.get(conversationModel.count-1).newsitemobject.id)} -// else {//xhr.url= login.server + "/api/direct_messages/new.json"; -// xhr.setUrl(login.server); -// xhr.setApi("/api/direct_messages/new"); -// xhr.setParam("text", body); -// xhr.setParam("screen_name",conversationModel.get(conversationModel.count-1).newsitemobject.screen_name); -// xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.id) -// } -// xhr.post(); -// } catch(e){Helperjs.showMessage("Error",e.toString(),root)} -// } -// } -// } -// } - - - - ListModel{id: conversationModel} - - WorkerScript { - id: conversationWorker - source: "qrc:/js/newsworker.js" - } - - MButton { - id: closeButton - height: 6*mm - width: 8*mm - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - onClicked: { - //newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning); - - newstab.conversation=[]; - //newsStack.pop() - //conversationList.destroy(); - //conversationsymbol.color="grey" - } - } - - Component.onCompleted: { - if (news.length>0){var currentTime= new Date(); - var msg = {'currentTime': currentTime, 'model': conversationModel,'news':news,'method':'conversation', 'options':globaloptions}; - conversationWorker.sendMessage(msg)} - } -} diff --git a/source-linux/qml/newsqml/MessageSend.qml b/source-linux/qml/newsqml/MessageSend.qml deleted file mode 100644 index 962796c..0000000 --- a/source-linux/qml/newsqml/MessageSend.qml +++ /dev/null @@ -1,555 +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: (newsSwipeview.stacktype!="Notifications")?messageColumn.height+mm:0 - id:messageSend - visible:(newsSwipeview.stacktype!="Notifications")?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]:[] - -// onReply_to_userChanged: { -// if (reply_to_user!=""){ -// print("reply "+reply_to_user) -// //receiverLabel.visible=true -// receiverLabel.text=reply_to_user -// } -// } - - 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(); -// var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment'+attachImageURLs.length+'; source:"'+ -// url.toString()+'"; x:2*mm; width: 45*mm; height: 45*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+ -// url+'"),1); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage"); - } - - function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { - //xhr.url= login.server + "/api/statuses/update.json"; - newsBusy.running=true; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/statuses/update"); - 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(); - } - - 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" - reply_to_user=newsitemobject.user.screen_name; - parentId=newsitemobject.id - } else { - messageSend.state=""; - reply_to_user=""; - 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:"" - anchors.fill: parent - font.pixelSize: 3*mm - font.family: "Noto Sans" - wrapMode: Text.Wrap - selectByMouse: true - placeholderText: conversation?"": qsTr("What's on your mind?") - textFormat: TextEdit.RichText //TextEdit.PlainText - onLineCountChanged: (conversation==true)?conversationView.contentY=conversationView.contentY+3*mm:newsView.contentY=newsView.contentY+3*mm - onLinkActivated:{Qt.openUrlExternally(link)} - onActiveFocusChanged:{ - if (activeFocus==true){ - if (conversation==true){ - setParent(conversationModel.get(0).newsitemobject); - messageSend.state="conversation"; - conversationView.contentY=conversationView.contentY+20*mm - } 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} - - - 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{ -// spacing: 2 -// width: parent.width -// CheckBox{ -// id:dmCheckbox -// text:"DM" -// enabled: false -// checked: (directmessage==1)?true:false -// onClicked:{ -// if(dmCheckbox.checkedState==Qt.Checked){directmessage=1} -// else if(dmCheckbox.checkedState==Qt.Unchecked){directmessage=0} -// } -// } - -// Button{ -// text:"\uf0c1" -// height:8*mm -// onClicked: { -// if(bodyField.selectedText==""){Helperjs.showMessage("Error","No text selected",messageSend)} -// else{urlTextEdit.text=""; -// urlRectangle.visible=true}} -// } -// } -// Rectangle{ -// id:urlRectangle -// height: 7*mm //parent.height -// width:parent.width-2*mm -// visible:false -// TextField{ -// id:urlTextEdit -// width:parent.width-7*mm -// height:parent.height -// } -// Button{ -// anchors.left:urlTextEdit.right -// anchors.leftMargin:mm -// height:8*mm -// text:"\u2713" -// onClicked: {if(urlTextEdit.text!=""){ -// var start = bodyField.selectionStart; -// var text=bodyField.selectedText -// if(text.lastIndexOf(".jpg")>-1 || text.lastIndexOf(".jpeg")>-1 || text.lastIndexOf(".png")>-1){text=""} -// text = "[url="+urlTextEdit.text+"]" + text + "[/url]"; -// bodyField.remove(start,bodyField.selectionEnd); -// bodyField.insert(start,text);} -// urlRectangle.visible=false} -// } -// } - Row{ - id:buttonRow - visible:false //(bodyField.length>1)||(attachImageURLs.length>0) - spacing: mm - height: 12*mm - x: 0.5*mm - MButton{id:permButton - visible: (newsSwipeview.stacktype!=="DirectMessages") - height: 6*mm - width: 7*mm - text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023" - onClicked: { if (permissionDialog.visible==false){permissionDialog.visible=true} else{permissionDialog.visible=false}} - } - MButton { - id: attachButton - height: 6*mm - width: 7*mm - text: "\uf03e" - visible:(newsSwipeview.stacktype!="DirectMessages") - onClicked: { - if (attachImageURLs.length>0){//Server currently accepts only one attachment - Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn) - } - else{ - root.imagePicking=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: 6*mm - width: 7*mm - onClicked: {if (smileyDialog.visible==false){smileyDialog.visible=true} else{smileyDialog.visible=false}} - } - - MButton { - id: cancelButton - height: 6*mm - width: 7*mm - 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: 6*mm - width: 7*mm - text: "\uf1d9" - onClicked: { - var title=titleField.text.replace("\"","\'"); - var body=bodyField.getFormattedText(0,bodyField.length); - var dmbody=bodyField.getText(0,bodyField.length); - if (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; newsStack.pop(null) - } - } - } - } - PermissionDialog{id:permissionDialog;x:mm;visible: false} - SmileyDialog{id:smileyDialog;x:mm;visible: false} - } - Component.onCompleted:{ - //parentId=conversationModel.get(conversationModel.count-1).newsitemobject.id - //if(attachImageURLs.length>0){attachImage(attachImageURLs[0])} - newsStack.replySignal.connect(setParent); - root.directmessageSignal.connect(directmessagePrepare); - root.uploadSignal.connect(sendUrls); - root.sendtextSignal.connect(sendtext); - 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"); - } -// PropertyChanges { -// target: toLabel; visible:(newsSwipeview.stacktype=="DirectMessages"); -// } - }, - State { - name: "conversation" - PropertyChanges { - target: messageColumn; height: implicitHeight - } - PropertyChanges { - target: buttonRow; visible:true - } - PropertyChanges { - target: titleField; visible:(newsSwipeview.stacktype!="DirectMessages") - } - -// PropertyChanges { -// target: receiverLabel; visible:true; text:qsTr("to")+": "+ conversationModel.get(0).newsitemobject.user.name -// } - -// PropertyChanges { -// target: messageSend; reply_to_user: conversationModel.get(0).newsitemobject.user.screen_name -// } - -// PropertyChanges { -// target: messageSend; parentId: conversationModel.get(0).newsitemobject.status_id -// } - }, - - State { - name: "reply" - PropertyChanges { - target: messageColumn; height: implicitHeight - } - PropertyChanges { - target: buttonRow; visible:true - } - PropertyChanges { - target: titleField; visible:false - } - PropertyChanges { - target: bodyField; placeholderText:"";focus:true - } - } - ] -} -//} diff --git a/source-linux/qml/newsqml/NewsStack.qml b/source-linux/qml/newsqml/NewsStack.qml deleted file mode 100644 index a3dfe39..0000000 --- a/source-linux/qml/newsqml/NewsStack.qml +++ /dev/null @@ -1,421 +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 - -StackView{ - id: newsStack - anchors.fill: parent - property string updateMethodNews: "refresh" - property var allchats: ({}) - signal replySignal(var newsobject) - property int lastnewsid:0 - - function newstypeHandling(newstype){ - newsBusy.running=true; - replySignal(""); - //messagesend.state=""; - newsModel.clear(); - switch(newstype){ - case "timeline": - newstab.newstabstatus="Timeline"; - try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){ - lastnewsid=lastid; - showNews(dbnews) - })}catch(e){Helperjs.showMessage("Error",e,root)}; - break; - case "conversation": - newstab.newstabstatus="Conversations"; - Newsjs.chatsfromdb(root.db,root.login,0,function(news,lastid){ - lastnewsid=lastid; - showNews(news)}); - break; - case "favorites": - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Favorites"; - Service.updateView("Favorites"); - break; - case "replies": - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Replies"; - Service.updateView("Replies"); - break; - case "publictimeline": - newsStack.updateMethodNews="refresh"; - newstab.newstabstatus="Public Timeline"; - Service.updateView("Public Timeline"); - break; - case "groupnews": - newsStack.updateMethodNews="refresh"; - Service.showGroups(); - break; - case "search": - newsView.anchors.topMargin=7*mm; - newsBusy.running=false; - var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml"); - var searchItem = component.createObject(newsStack,{y:mm,width:root.width,height: 5*mm}); - break; - case "refresh": - if (newstab.newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else {newsStack.updateMethodNews="refresh"} - //root.contactLoadType="news"; - if (newsSwipeview.stacktype=="Home"){ - Service.updateView(newstab.newstabstatus) - } - else if (newsSwipeview.stacktype=="DirectMessage"){ - Service.updateView("Direct Messages") - } - else if (newsSwipeview.stacktype=="Notifications"){ - Service.updateView("Notifications") - } - break; - default: - if (newstab.newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else {newsStack.updateMethodNews="refresh"} - //root.contactLoadType="news"; - if (newsSwipeview.stacktype=="Home"){ - Service.updateView(newstab.newstabstatus) - } - else if (newsSwipeview.stacktype=="Directmessage"){ - Service.updateView("Direct Messages") - } - else if (newsSwipeview.stacktype=="Notifications"){ - Service.updateView("Notifications") - } - } - } - - - function showNews(newsToShow){ - try{if (newsStack.depth>1){newsStack.pop()}}catch(e){} - newsBusy.running=false; - var currentTime= new Date(); - // downloadNotice.text=downloadNotice.text + "\n shownews start "+ Date.now(); - //print("appendnews "+JSON.stringify(newsToShow)) - 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 showContact(contact){ //print(JSON.stringify(contact)); - //newstab.newstabstatus="Contact"; - newsStack.push("qrc:/qml/newsqml/ContactPage.qml",{"contact": contact}); - } - - function search(term){//print("Search "+term) - if (term!=""){ - newstab.newstabstatus="Search"; - newsBusy.running=true; - newsStack.updateMethodNews="refresh"; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.setUrl(login.server); - xhr.setApi("/api/search"); - xhr.clearParams(); - xhr.setParam("q",term) - xhr.get();} - newsView.anchors.topMargin=mm - } - - 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"){//print("lastnewsid "+lastnews_id); - 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"){ - 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=="Contact"){ -// Newsjs.newsfromdb(root.db,root.login, function(news){ -// var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; -// newsWorker.sendMessage(msg); -// },newsModel.get(newsModel.count-1).newsitemobject.uid,lastnews_id)} - else if (newstab.newstabstatus=="Notifications"){} - else{ - //newsStack.appendNews=true; - try{xhr.setParam("max_id",newsModel.get(newsModel.count-1).newsitemobject.id-1);}catch(e){} - xhr.get() - } - } - Connections{ - target:xhr - onError:{ - if (data !="contactlist"){Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root);} - newsBusy.running=false; - } - onSuccess:{ - // 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"){ - newsStack.updateMethodNews="append" - } else {newsStack.updateMethodNews="refresh"} - if (newsSwipeview.stacktype=="Home"){ - Service.updateView(newstab.newstabstatus) - } - else if (newsSwipeview.stacktype=="DirectMessages"){ - Service.updateView("Direct Messages") - } - else if (newsSwipeview.stacktype=="Replies"){ - Service.updateView("Replies") - } - replySignal("") - //Service.updateView(newstab.newstabstatus) - } - } - } - - initialItem: Rectangle { - id:newslistRectangle - y:1 - color: "white" - //anchors.fill:parent - - Component { id:footerComponent - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - width:newsView.width - height:6*mm - Text{ - font.pixelSize: 1.5*mm - anchors.centerIn: parent - text:qsTr("More") - } - MouseArea{ - anchors.fill:parent - onClicked:{ - 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" - anchors.fill: parent - anchors.margins: 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=rootStackItem.height; - newsSwipeview.y=0; - rootStackItem.state="fullscreen" - } - else if ((contentY-oldContentY)<-15*mm){ - swipeIndicator.visible=true; - newsSwipeview.height=rootStackItem.height-12*mm; - newsSwipeview.y=5*mm; - rootStackItem.state="" - } - } - } - onViewdraggedChanged: { - if (viewdragged){ - var onlynew=true; - newsBusy.running=true; - viewdragged=false - if (newstab.newstabstatus=="Timeline"){ - newsStack.updateMethodNews="append" - } else {newsStack.updateMethodNews="refresh"} - //root.contactLoadType="news"; - if (newsSwipeview.stacktype=="Home"){ - Newsjs.getLastNews(root.login,root.db,function(currentlastnews){ - if (currentlastnews>lastnewsid){ - if(newstab.newstabstatus=="Timeline"){ - try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){ - lastnewsid=lastid; - showNews(dbnews) - })}catch(e){Helperjs.showMessage("Error",e,root)}; - } - if(newstab.newstabstatus=="Conversations"){ - Newsjs.chatsfromdb(db,root.login,0,function(news,lastid){ - lastnewsid=lastid; - showNews(news)}); - } - } else { - Service.updateView(newstab.newstabstatus) - } - }); - } - else if (newsSwipeview.stacktype=="DirectMessages"){ - Service.updateView("Direct Messages") - } - else if (newsSwipeview.stacktype=="Notifications"){ - Service.updateView("Notifications") - } - else if (newsSwipeview.stacktype=="Replies"){ - Service.updateView("Replies") - } - - } - } - onViewdraggedpositiveChanged: { - if (viewdraggedpositive){ - getOldNews(); - viewdraggedpositive=false - } - } - } - - ListModel{id: newsModel} - - WorkerScript { - id: newsWorker - source: "qrc:/js/newsworker.js" - } - - BusyIndicator{ - id: newsBusy - anchors.horizontalCenter: parent.horizontalCenter - anchors.top:parent.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - } - Rectangle{ - id:downloadNotice - property alias text: noticeText.text - color:"white" - border.color:"grey" - z:1 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom:parent.bottom - anchors.bottomMargin: 2*mm - width: noticeText.width+2*mm - height: noticeText.height+2*mm - visible: (downloadNotice.text!="") - - Text{ - id:noticeText - color: "grey" - anchors.centerIn: parent - width: contentWidth - height: contentHeight - font.pixelSize: 2*mm - text:"" - } - } - - Component.onCompleted: { - root.newstypeSignal.connect(newstypeHandling); - root.messageSignal.connect(onFriendsMessages); - root.contactdetailsSignal.connect(showContact); - root.newsSignal.connect(showNews); - - try{newsModel.clear()} catch(e){} - swipeIndicator.visible=true; - newsSwipeview.height=rootStackItem.height-12*mm; - newsSwipeview.y=5*mm; - rootStackItem.state="" - root.globaloptions.hasOwnProperty("newsViewType")?newstab.newstabstatus=root.globaloptions.newsViewType:newstab.newstabstatus="Conversations"; - 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")){ - 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/NewsVideo.qml b/source-linux/qml/newsqml/NewsVideo.qml deleted file mode 100644 index 9b17cbc..0000000 --- a/source-linux/qml/newsqml/NewsVideo.qml +++ /dev/null @@ -1,75 +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 QtMultimedia 5.8 -import QtQuick 2.9 -//import QtQuick.Controls 2.4 -//import QtQuick.Controls.Styles 1.4 - -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 - //visible: video.playbackState!=MediaPlayer.PlayingState - } - - MouseArea {anchors.fill:parent; - onClicked:{ - if(attachment.mimetype=="video/youtube"){ - root.push("qrc:/qml/newsqml/NewsYplayer.qml",{"ytcode":attachment.url,"mimetype":attachment.mimetype}); -// var component = Qt.createComponent("qrc:/qml/newsqml/NewsYplayer.qml"); -// var videoQml = component.createObject(root,{"ytcode":attachment.url,"mimetype":attachment.mimetype}); - } else { - root.push("qrc:/qml/newsqml/NewsVideoLarge.qml",{"source": attachment.url,"mimetype": attachment.mimetype}); -// var component = Qt.createComponent("qrc:/qml/newsqml/NewsVideoLarge.qml"); -// var videoQml = component.createObject(root,{"source": attachment.url,"mimetype": attachment.mimetype}); - } - } - } -// 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) -// } -} diff --git a/source-linux/qml/newsqml/NewsVideoLarge.qml b/source-linux/qml/newsqml/NewsVideoLarge.qml deleted file mode 100644 index 82a006b..0000000 --- a/source-linux/qml/newsqml/NewsVideoLarge.qml +++ /dev/null @@ -1,112 +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 QtMultimedia 5.8 -import QtQuick 2.9 -import QtQuick.Controls 2.12 -//import QtQuick.Controls.Styles 1.4 - -Rectangle{ - id:newsvideofullscreen - color:"black" - //border.color: "light grey" - width:root.width; - height:root.height - property alias source:video.source - Text{ - id:noticeText - text:"" - color:"light grey" - width:parent.width/2 - wrapMode: Text.Wrap - font.pixelSize: 3*mm - x:parent.width/2-parent.height/4 - y:parent.height/5 - visible: video.playbackState!=MediaPlayer.PlayingState - } - - Video {id:video; - anchors.fill:parent - property string mimetype:"" - onErrorChanged:{noticeText.font.pixelSize=3*mm;noticeText.text=errorString;} - fillMode: Image.PreserveAspectFit; - autoLoad: true - autoPlay: true - audioRole: MediaPlayer.VideoRole - MouseArea { - anchors.fill:parent; - onClicked:{ - root.pop() - //newsvideofullscreen.destroy(); - } - } - } - - 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 - MouseArea { - anchors.fill:parent; - onClicked:{ - if(video.playbackState!=MediaPlayer.PlayingState){ - video.play()} else{video.pause() - } - } - } - } - - ProgressBar{ - id: videoBuffer - width: parent.width - height: 2*mm - anchors.bottom: video.bottom - visible:video.playbackState!=MediaPlayer.StoppedState - value: video.bufferProgress -// style:ProgressBarStyle{ -// progress: Rectangle{ -// color:"light grey" -// } -// } - } -// 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) -// } -} diff --git a/source-linux/qml/newsqml/Newsitem.qml b/source-linux/qml/newsqml/Newsitem.qml deleted file mode 100644 index 19ecee8..0000000 --- a/source-linux/qml/newsqml/Newsitem.qml +++ /dev/null @@ -1,526 +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:/js/news.js" as Newsjs -import "qrc:/js/helper.js" as Helperjs -import "qrc:/qml/genericqml" - -Item { - id: newsitem - width: parent.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) - property int itemindex: index - property var newsitemobject:model.newsitemobject - property string attending: "" - property var friendica_activities_view: getActivitiesView(model.newsitemobject) - - onAttendingChanged: {attendLabel.visible=true; - attendLabel.text= qsTr("attending")+": "+ qsTr(attending)} - - signal replyto(string parent_id) - - function showActivityContacts(contacts){ - var component = Qt.createComponent("qrc:/qml/newsqml/FriendicaActivities.qml"); - var imagedialog = component.createObject(friendicaActivities,{"activitymembers": contacts}); - } - - function findTags(fulltext){ - return fulltext.match(/\s+[#]+[A-Za-z0-9-_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]+/g) - } - - function pushConversation(){ - if (model.newsitemobject.hasOwnProperty("currentconversation")){ - newsStack.push("qrc:/qml/newsqml/Conversation.qml",{"news": model.newsitemobject.currentconversation})} - else{newsStack.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:newsitem.height-1 - color: "white"//(newsitemobject.messagetype==1)?"#ffe6e6" : "white" - -// Row{id:toprow -// Column { -// id: authorcolumn -// width: 8*mm - - -// } - Column { - id:toprow //newscolumn - width: newsitemobject.hasOwnProperty("indent")?newsitem.width-(newsitem.width/20 *newsitemobject.indent):newsitem.width//-8*mm - x:newsitemobject.hasOwnProperty("indent")?newsitem.width/20*newsitemobject.indent:0 - Item{ - height: Math.max(profileImage.height+mm,topFlow.implicitHeight+mm) - width: parent.width - MouseArea{ - anchors.fill: parent - onClicked:{ - showContact(newsitemobject.user)} - } - Image { - id:profileImage - source: ((newsitemobject.user.profile_image!="") && (typeof(newsitemobject.user.profile_image)=="string"))? "file://"+newsitemobject.user.profile_image : newsitemobject.user.profile_image_url - x:1 - y:1 - width: 7*mm - height: 7*mm - //radius:mm - - onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} - } - Flow{ - id:topFlow - spacing: mm - width:parent.width-8*mm - anchors.left: profileImage.right - anchors.margins: mm - Label { - id:user_name - //color: "grey" - width:parent.width - font.bold: true - font.pixelSize: 2.5*mm - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: newsitemobject.user.name+" (@"+newsitemobject.user.screen_name+")"+newsitemobject.forumname - } - - Label { - id:messageTypeLabel - color: "grey" - text: if (newsitemobject.messagetype==1){ qsTr("Direct Message")} else if(newsitemobject.messagetype==2) {" Notification"} else {qsTr("Source: ")+newsitemobject.source} - font.pixelSize: 1.5*mm - } - Label { - id:createdAtLabel - color: "grey" - font.pixelSize: 1.5*mm - horizontalAlignment: Label.AlignRight - text: getDateDiffString(newsitemobject.dateDiff) + " " +qsTr("ago") - } - Label { - id:replytoLabel - color: "grey" - font.pixelSize: 1.5*mm - font.family: "Noto Sans" - horizontalAlignment: Label.AlignRight - text: try {qsTr("In reply to ")+newsitemobject.reply_user.screen_name - }catch(e){" "} - } - - // Label { - // id:newscountLabel - // visible:((newstabstatus=="Conversations")&&(newsitemobject.newscount>1))?true:false - // color: "grey" - // height:3.5*mm - // font.pixelSize: 1.5*mm - // font.bold: true - // horizontalAlignment: Label.AlignRight - // text: try {(newsitemobject.newscount-1)+qsTr(" comments") }catch(e){" "} - // MouseArea{ - // anchors.fill:parent - // onClicked: { - // pushConversation(); - // } - // } - // } - } - } - -// Column{ id: messageColumn -// //anchors.top:topFlow.bottom -// width:parent.width -// spacing:mm -// clip:true -// height: newsitemobject.nsfw?5*mm:Math.min(implicitHeight,3/4*root.height) - MouseArea{ - width: toprow.width-2 - height: itemMessage.height - onPressAndHold: { - pushConversation(); - } - Text { - color: "#404040" - linkColor: "light green" - id: itemMessage - textFormat: Text.RichText - font.family: "Noto Sans" - text: newsitemobject.statusnet_html//newsitemobject.attachmentList.length>0?newsitemobject.text : newsitemobject.statusnet_html - width: 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=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()}); - }} - - if (newsitemobject.attachmentList.length>0){ - for(var attachments in newsitemobject.attachmentList){// (newsitemobject.attachmentList[attachments].url); - if(newsitemobject.attachmentList[attachments].mimetype.substring(0,5)=="image"){ - var component = Qt.createComponent("qrc:/qml/newsqml/NewsImage.qml"); - var imageQml = component.createObject(toprow,{"source":newsitemobject.attachmentList[attachments].url,"mimetype":newsitemobject.attachmentList[attachments].mimetype}); - } - else if(newsitemobject.attachmentList[attachments].mimetype=="text/html"){ - var component = Qt.createComponent("qrc:/qml/newsqml/NewsLink.qml"); - var linkQml = component.createObject(toprow,{"url":newsitemobject.attachmentList[attachments].url}); - } - else { - var component = Qt.createComponent("qrc:/qml/newsqml/NewsVideo.qml"); - //var videoQml = component.createObject(messageColumn,{"source":newsitemobject.attachmentList[attachments].url,"mimetype":newsitemobject.attachmentList[attachments].mimetype}); - var videoQml = component.createObject(toprow,{"attachment":newsitemobject.attachmentList[attachments]}); - } - } - } - - if (newsitemobject.hasOwnProperty("lastcomment")){ - var moreComponent = Qt.createComponent("qrc:/qml/newsqml/MoreComments.qml"); - var conversationQml = moreComponent.createObject(conversationColumn,{"comments":newsitemobject.newscount-1}); - - var commentComponent = Qt.createComponent("qrc:/qml/newsqml/Newsitem.qml"); - var conversationQml = commentComponent.createObject(conversationColumn,{"newsitemobject":newsitemobject.lastcomment}); - } - } - }} - //} - BlueButton{ - width: newsitem.width-8*mm-2 - height:5*mm - //anchors.bottom: messageColumn.bottom//itemMessage.bottom - visible: itemMessage.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 - onClicked: { - if (text=="\uf078"){ - itemMessage.height=itemMessage.implicitHeight+10*mm;text="\uf077" - } else { - itemMessage.height=Math.min(itemMessage.implicitHeight,3/4*root.height); - text="\uf078"; - newsView.positionViewAtIndex(index,ListView.Beginning); - } - } - } - //} - } - Flow{ - id:friendicaActivities - anchors.top:toprow.bottom - width:parent.width - spacing:mm - - Label{color: "grey" - height:3.5*mm - font.pixelSize: 1.5*mm - text: friendica_activities_view.likeText - MouseArea{ - anchors.fill: parent - onClicked: { showActivityContacts(newsitemobject.friendica_activities.like)} - } - } - Label{color: "grey" - height:3.5*mm - font.pixelSize: 1.5*mm - text: friendica_activities_view.dislikeText - MouseArea{ - anchors.fill: parent - onClicked: { showActivityContacts(newsitemobject.friendica_activities.dislike)} - } - } - Label{color: "grey" - height:3.5*mm - font.pixelSize: 1.5*mm - text: friendica_activities_view.attendyesText - MouseArea{ - anchors.fill: parent - onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendyes)} - }} - Label{color: "grey" - height:3.5*mm - font.pixelSize: 1.5*mm - text: friendica_activities_view.attendnoText - MouseArea{ - anchors.fill: parent - onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendno)} - } - } - Label{color: "grey" - height:3.5*mm - font.pixelSize: 1.5*mm - text: friendica_activities_view.attendmaybeText - MouseArea{ - anchors.fill: parent - onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendmaybe)} - } - } - Label{ - id:attendLabel - color: "grey" - height:3.5*mm - font.pixelSize: 1.5*mm - horizontalAlignment: Label.AlignRight - text: (newsitemobject.friendica_activities_view.self.attending)?(qsTr("Attending: ")+ qsTr(newsitemobject.friendica_activities_view.self.attending)):"" - } - } - Row{id:controlrow - anchors.top:friendicaActivities.bottom - height: 4*mm - CheckBox{ - id:likeCheckbox - width:newsitem.width/5 //10*mm - 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:4*mm - Text{ - anchors.centerIn: parent - font.pixelSize: 3*mm - font.family:fontAwesome.name - color:likeCheckbox.checked?"black": "grey" - text:likeCheckbox.checked?"\uf118"+"!":"\uf118" - } - } - onClicked: { - if(likeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"like",newsitemobject.id,root);dislikeCheckbox.checked=false; - newsitemobject.friendica_activities_view.self.liked=1; - newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); - } - else{Newsjs.like(root.login,root.db,0,"like",newsitemobject.id,root); - newsitemobject.friendica_activities_view.self.liked=0; - newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); - }} - } - CheckBox{ - id: dislikeCheckbox - width:newsitem.width/5 //10*mm - 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:4*mm - Text{ - anchors.centerIn: parent - font.pixelSize: 3*mm - font.family:fontAwesome.name - color:dislikeCheckbox.checked?"black": "grey" - text: dislikeCheckbox.checked?"\uf119"+"!":"\uf119" - } - } - onClicked: { - if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.id,root);likeCheckbox.checked=false; - newsitemobject.friendica_activities_view.self.disliked=1; - newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); - } - else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.id,root); - newsitemobject.friendica_activities_view.self.disliked=0; - newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); - }} - } - - CheckBox { - id:favoritedCheckbox - visible:((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3)) - width: newsitem.width/5 // 10*mm - height: parent.height - indicator:Rectangle{ - implicitWidth: newsitem.width/5 //10*mm - implicitHeight:4*mm - Text{ - anchors.centerIn: parent - font.pixelSize: 3*mm - font.family:fontAwesome.name - color: favoritedCheckbox.checked?"black":"grey" - text:"\uf005" - } - } - checked:(newsitemobject.favorited>0) - onClicked:{ - if(favoritedCheckbox.checkedState==Qt.Checked){ - Newsjs.favorite(login,true,newsitemobject.id,root); model.newsitemobject.favorited=1} - else if(favoritedCheckbox.checkedState==Qt.Unchecked){ - Newsjs.favorite(login,false,newsitemobject.id,root);model.newsitemobject.favorited=0} - } - } - Rectangle{ - width: newsitem.width/5 //10*mm - height: parent.height - visible:(newsitemobject.messagetype!==2) - color:"transparent" - Text{ - id:newsmenusymbol - color: "grey" - anchors.centerIn: parent - font.pixelSize: 3*mm - font.family:fontAwesome.name - text: "\uf142" - } - MouseArea{ - anchors.fill:parent - onClicked: {newsmenu.popup()}} - } -// Rectangle{ -// width: 10*mm -// height: 4*mm -// visible:(newsitemobject.messagetype!==2)&&(newstab.newstabstatus!="Conversation") -// color:"transparent" -// Text{ -// id:conversationsymbol -// color: "grey" -// anchors.centerIn: parent -// font.pixelSize: 2.5*mm -// font.family: fontAwesome.name -// text: "\uf086" -// } -// MouseArea{ -// anchors.fill:parent -// onClicked:{ -// if (newsitemobject.hasOwnProperty("currentconversation")){newsStack.push("qrc:/qml/newsqml/Conversation.qml",{"news": newsitemobject.currentconversation})} -// else{newsStack.push("qrc:/qml/newsqml/Conversation.qml")}; -// showConversation(index,newsitemobject) -// } -// } -// } - - } - - Menu { - id:newsmenu - width: 30*mm - delegate: MenuItem{ - contentItem: Text{ - font.pixelSize: 3*mm - text: parent.text - } - } - Action{ - text: qsTr("Reply") - onTriggered: { - var directmessage=0; - if (newsitemobject.messagetype==1){ directmessage=1} - var replycomp=Qt.createComponent("qrc:/qml/newsqml/MessageSend.qml"); - var conversation;newsitem.ListView.view.viewtype=="conversation"?true:false; - var reply=replycomp.createObject(friendicaActivities,{parentId:newsitemobject.id,reply_to_user:newsitemobject.user.screen_name, state:"reply",conversation:conversation,textfocus:true}) - //replySignal(newsitemobject) - //newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"reply_to_user": newsitemobject.user.screen_name,"parentId":newsitemobject.id,"login":root.login,"directmessage":directmessage}); - } - } - Action { - text: qsTr("DM") - onTriggered: { - root.directmessageSignal(newsitemobject.user.screen_name); - } - } - Action { - text: qsTr("Repost") - onTriggered: { - Newsjs.retweetNews(root.login,db,newsitemobject.id,root,function(reply){ - Helperjs.showMessage("Repost",qsTr("Success!"),root) - }) - } - } - Action { - text: qsTr("Conversation") - onTriggered: { - pushConversation(); - } - } - - Menu{ - title: qsTr("Attending") - width: 20*mm - delegate: MenuItem{ - contentItem: Text{ - font.pixelSize: 3*mm - text: parent.text - } - } - Action{ - text:qsTr("yes") - onTriggered: {Newsjs.attend(root.login,db,"yes",newsitemobject.id,root,function(){ - model.newsitemobject.friendica_activities_view.self.attending="yes";attending="yes"}) - } - } - Action{text:qsTr("maybe") - onTriggered: {Newsjs.attend(root.login,db,"maybe",newsitemobject.id,root,function(){ - model.newsitemobject.friendica_activities_view.self.attending="maybe";attending="maybe"}) - } - } - Action{text:qsTr("no") - onTriggered: {Newsjs.attend(root.login,db,"no",newsitemobject.id,root,function(){ - model.newsitemobject.friendica_activities_view.self.attending="no";attending="no"})} - } - } - - Action { - text: qsTr("Delete") - onTriggered: { - Newsjs.deleteNews(root.login,root.db,newsitemobject.id,newsitemobject.messagetype,root,function(reply){ - var msg = {'deleteId': index, 'model': newsModel}; - newsWorker.sendMessage(msg); - }) - } - } - - //MenuItem{ - // text:qsTr("Show on website") - // onTriggered:Qt.openUrlExternally(login.server+"/display/"+newsitemobject - //} - } - Column{ - id:conversationColumn - anchors.top:controlrow.bottom - anchors.right: parent.right - width: newsitem.width-5*mm - } -} -} diff --git a/source-linux/qml/newsqml/SmileyDialog.qml b/source-linux/qml/newsqml/SmileyDialog.qml deleted file mode 100644 index cead53c..0000000 --- a/source-linux/qml/newsqml/SmileyDialog.qml +++ /dev/null @@ -1,242 +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.Controls.Styles 1.4 -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 - - Button{ - id:closeButton - height: 6*mm - width: 8*mm - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - onClicked:{smileyDialog.visible=false} - } - - - TabBar { - id: smileybar - width: parent.width - height: 9*mm - position:TabBar.Header - TabButton { - text:qsTr("Unicode") - font.pixelSize: 2*mm - } - TabButton { - text: qsTr("Standard") - font.pixelSize: 2*mm - } - TabButton { - text: qsTr("Addon") - font.pixelSize: 2*mm - } - - TabButton { - text: qsTr("Adult") - font.pixelSize: 2*mm - } - } - - - StackLayout{ - id:smileyTabView - currentIndex: smileybar.currentIndex - anchors.top: closeButton.bottom - anchors.topMargin: 1*mm - width: smileyDialog.width-2*mm - height: smileyDialog.height-7*mm -// style: TabViewStyle { -// frameOverlap: 1 -// tab: Rectangle { -// color: "white" -// implicitWidth: smileyTabView.width/4-2*mm -// implicitHeight: 4*mm -// Text { id: text -// anchors.centerIn: parent -// text: styleData.title -// color: "dark grey" -// font.pixelSize:2.5*mm -// font.bold: styleData.selected -// } -// } -// frame: Rectangle { color: "light grey" } -// tabsAlignment:Qt.AlignHCenter -// } - - 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.pixelSize: 4*mm - 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 023a7d1..0000000 --- a/source-linux/qml/photoqml/PhotoTab.qml +++ /dev/null @@ -1,305 +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}) - } - - 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 - height: 6*mm - width: 8*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 - height: 6*mm - width: 8*mm - text:"\uf0ed" - - Menu { - id:photoupdatemenu - width:40*mm - MenuItem { - text: qsTr("All Images") - font.pixelSize: 3*mm - onTriggered: { - Imagejs.requestList(root.login,root.db, false, fotostab,function(obj){fotorectangle.newimages=obj})} - } - MenuItem { - text: qsTr("Only new") - font.pixelSize: 3*mm - onTriggered: { - Imagejs.requestList(root.login,root.db, true,fotostab,function(obj){fotorectangle.newimages=obj})} - } - } - onClicked: {photoupdatemenu.popup()} - } - - MButton{ - id: phototabstatusButton - anchors.top: parent.top - anchors.topMargin: 0.5*mm - anchors.right: parent.right - anchors.rightMargin:2*mm - height: 6*mm - width: Math.max(10*mm,implicitWidth) - text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus - Menu { - id:phototabmenu - width: 40*mm - MenuItem { - text: qsTr("Own Images") - font.pixelSize: 3*mm - onTriggered: { - fotostab.phototabstatus="Images"; - // phototabstatusButton.text=qsTr("Own images"); - 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: mm;y:8*mm - width: 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.pixelSize: 1.5*mm - 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 - height: 6*mm - width: 8*mm - text: "\uf057" - x: parent.width - backButton.width - 3*mm - y: -backButton.height - 4*mm - 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 173db70..0000000 Binary files a/source-linux/translations/friendiqa-de.qm and /dev/null differ diff --git a/source-linux/translations/friendiqa-de.ts b/source-linux/translations/friendiqa-de.ts deleted file mode 100644 index ecd9fd8..0000000 --- a/source-linux/translations/friendiqa-de.ts +++ /dev/null @@ -1,1211 +0,0 @@ - - - - - AccountPage - - - - - User - Name - - - - Server - Server - - - - Nickname - Kurzname - - - - Password - Passwort - - - - Image dir. - Bildverz. - - - News as - Anzeige - - - - - - Error - Fehler - - - - Nicknames containing @ symbol currently not supported - Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. - - - - Confirm - Bestätigen - - - - No server given! - Kein Server angegeben! - - - - No nickname given! - Kein Kurzname angegeben! - - - - No password given! - Kein Passwort angegeben! - - - - No image directory given! - Kein Verzeichnis für Bilder angegeben! - - - - Wrong password! - Falsches Passwort! - - - - Success - Bestätigt - - - - Name - Name - - - Timeline - Chronologisch - - - Conversations - Unterhaltungen - - - - CalendarTab - - - Events - Termine - - - - Own Calendar - Eigener Kalender - - - - ConfigPage - - - News as - Anzeige - - - - - - Conversations - Unterhaltungen - - - - - Timeline - Chronologisch - - - - Max. News - Max. Nachr. - - - - Hide #nsfw? - #nsfw minimieren? - - - - Sync - Autom. Aktualisierung - - - - ConfigTab - - User - Name - - - Server - Server - - - Nickname - Kurzname - - - Password - Passwort - - - Image dir. - Bildverz. - - - Max. News - Max. Nachr. - - - News as - Anzeige - - - Interval (0=None) - Intervall (0=keins) - - - Error - Fehler - - - Nickname not registered at given server! - Name auf der Seite nicht registriert! - - - Confirm - Bestätigen - - - No server given! - Kein Server angegeben! - - - No nickname given! - Kein Kurzname angegeben! - - - Nickname not registered at given server! - Name auf der Seite nicht registriert! - - - No username given! - Kein Nutzername angegeben! - - - Sync Interval (0=None) - Akt.-intervall (0=keine) - - - Nicknames containing @ symbol currently not supported - Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. - - - Min. - Min. - - - No password given! - Kein Passwort angegeben! - - - No image directory given! - Kein Verzeichnis für Bilder angegeben! - - - No maximum news number given! - Maximale News-Anzahl nicht angegeben! - - - Wrong password! - Falsches Passwort! - - - Success - Bestätigt - - - Name - Name - - - Timeline - Chronologisch - - - Conversations - Unterhaltungen - - - - ContactComponent - - - Connect - Kontaktanfrage - - - - ContactDetailsComponent - - - Connect - Kontaktanfrage - - - - Description - Beschreibung - - - - Location - Ort - - - - Posts - Beiträge - - - - URL - Profilseite - - - - Created at - Erstellt - - - - ContactPage - - - Connect - Kontaktanfrage - - - - Description - Beschreibung - - - - Location - Ort - - - - Posts - Beiträge - - - - URL - Profilseite - - - - Created at - Erstellt - - - - EventList - - - Location - Ort - - - - FriendsTab - - - Me - Ich - - - - Friends - Freunde - - - - Contacts - Kontakte - - - - Groups - Gruppen - - - - GroupComponent - - Error - Fehler - - - No name given - Kein Name angegeben - - - - ImageUploadDialog - - - Upload to album - In Album hochladen - - - Album - Album - - - Image - Bild - - - - Description - Beschreibung - - - - Upload - Hochladen - - - - Change - Ändern - - - - Error - Fehler - - - - No album name given - Kein Albumname angegeben - - - - MessageSend - - - to: - an: - - - - Title (optional) - Überschrift (optional) - - - - What's on your mind? - Woran denkst du gerade? - - - - - Error - Fehler - - - - Only one attachment supported at the moment. - Remove other attachment first! - Nur ein Anhang derzeit unterstützt. - Lösche zuerst den anderen Anhang! - - - - No receiver supplied! - Kein Empfänger angegeben! - - - - MoreComments - - - Show all comments - Alle Kommentare - - - - NewsStack - - - Network Error - Netzwerk-Fehler - - - - More - Mehr - - - - NewsTab - - Download profile image for - Lade Profilbild für - - - More - Mehr - - - Timeline - Chronologisch - - - Error - Fehler - - - Favorites - Markierte News - - - Conversations - Unterhaltungen - - - Network Error - Netzwerk-Fehler - - - Replies - Interaktionen - - - Public timeline - Gemeinschaft - - - Direct Messages - Direktnachrichten - - - Notifications - Meldungen - - - Group news - News Gruppe - - - Quit - 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. - - - - Newsitem - - attending: - Teilnahme - - - - Source: - Quelle: - - - - Direct Message - Direktnachricht - - - - In reply to - Antwort an - - - comments - 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 - - - - PermissionDialog - - - Friends - Freunde - - - - Groups - Gruppen - - - - PhotoTab - - - 's images - s Bilder - - - - All Images - Alle Bilder - - - - Only new - Nur neue - - - - - Own Images - Eigene Bilder - - - - More - Mehr - - - - 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 - - - - SmileyDialog - - - Unicode - Unicode - - - - Standard - Standard - - - - Addon - Addon - - - - Adult - XXX - - - - SyncComponent - - - sync - akt. - - - - notify - benachr. - - - - SyncConfig - - - Sync Interval (0=None) - Akt.-intervall (0=keine) - - - - Min. - Min. - - - - friendiqa - - - Refresh - Aktualisieren - - - - Timeline - Chronologisch - - - - Conversations - Unterhaltungen - - - - Favorites - Markierte News - - - - Replies - Interaktionen - - - - Public Timeline - öff. Timeline - - - - Group news - News Gruppe - - - - Search - Suche - - - - Settings - Einstellungen - - - - Accounts - Konten - - - - Quit - Schliessen - - - - newsworker - - likes this. - mag das. - - - like this. - mögen das. - - - doesn't like this. - mag das nicht. - - - don't like this. - mögen das nicht. - - - will attend. - nehmen teil. - - - persons will attend. - Personen nehmen teil. - - - will not attend. - nimmt nicht teil. - - - persons will not attend. - Personen nehmen nicht teil. - - - may attend. - nimmt vielleicht teil. - - - persons may attend. - Personen nehmen vielleicht teil. - - - - yes - ja - - - - no - nein - - - - maybe - vielleicht - - - seconds - Sekunden - - - ago - her - - - minute - Minute - - - minutes - Minuten - - - hour - Stunde - - - hours - Stunden - - - day - Tag - - - days - Tage - - - month - Monat - - - months - Monate - - - - service - - Error - Fehler - - - - Changelog - Ä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. - - - - Undefined Array Error - Antwort-Array ungültig - - - - JSON status Error - Server-Antwort: Fehler - - - diff --git a/source-linux/translations/friendiqa-es.qm b/source-linux/translations/friendiqa-es.qm deleted file mode 100644 index eed8306..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 cfd6cd4..0000000 --- a/source-linux/translations/friendiqa-es.ts +++ /dev/null @@ -1,1184 +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 - - - Connect - Conectar - - - - Description - Descripción - - - - Location - Localización - - - - Posts - Mensajes - - - - URL - URL - - - - Created at - Creado en - - - - EventList - - - Location - Localización - - - - 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! - - - - MessageSend - - - to: - a: - - - - Title (optional) - Título (opcional) - - - - 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 - - - - - hide friends - - - - - profile photo - - - - - profile thumb - - - - - publish - - - - - publish in network - - - - - description - - - - - date of birth - - - - - address - - - - - city - - - - - region - - - - - postal code - - - - - country - - - - - hometown - - - - - gender - - - - - marital status - - - - - married with - - - - - married since - - - - - sexual - - - - - politics - - - - - religion - - - - - public keywords - - - - - private keywords - - - - - likes - - - - - dislikes - - - - - about - - - - - music - - - - - book - - - - - tv - - - - - film - - - - - interest - - - - - romance - - - - - work - - - - - education - - - - - social networks - - - - - homepage - - - - - Update - - - - - profile id - 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 - - - - Changelog - - - - - 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-it.qm b/source-linux/translations/friendiqa-it.qm deleted file mode 100644 index eca6573..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 4cd39a1..0000000 --- a/source-linux/translations/friendiqa-it.ts +++ /dev/null @@ -1,1160 +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 - - - Connect - Connetti - - - - Description - Descrizione - - - - Location - Località - - - - Posts - Messaggi - - - - URL - URL - - - - Created at - Creato il - - - - EventList - - - Location - Località - - - - 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! - - - - MessageSend - - - to: - a: - - - - Title (optional) - Titolo (opzionale) - - - - 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 - - - - - is default - - - - - hide friends - - - - - profile photo - - - - - profile thumb - - - - - publish - - - - - publish in network - - - - - description - - - - - date of birth - - - - - address - - - - - city - - - - - region - - - - - postal code - - - - - country - - - - - hometown - - - - - gender - - - - - marital status - - - - - married with - - - - - married since - - - - - sexual - - - - - politics - - - - - religion - - - - - public keywords - - - - - private keywords - - - - - likes - - - - - dislikes - - - - - about - - - - - music - - - - - book - - - - - tv - - - - - film - - - - - interest - - - - - romance - - - - - work - - - - - education - - - - - social networks - - - - - homepage - - - - - Update - - - - - profile id - - - - - Description - Descrizione - - - - 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 99% rename from source-linux/common/alarm.h rename to src/common/alarm.h index 9d35fd0..9edea0b 100644 --- a/source-linux/common/alarm.h +++ b/src/common/alarm.h @@ -40,7 +40,6 @@ class ALARM : public QObject //Q_PROPERTY(int alarmtime READ alarmtime WRITE setAlarm NOTIFY alarmChanged) public: static ALARM *instance(); - explicit ALARM(QObject *parent = 0); //int alarmtime() const; 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 63% rename from source-linux/common/filesystem.cpp rename to src/common/filesystem.cpp index fefdd3c..2ce9919 100644 --- a/source-linux/common/filesystem.cpp +++ b/src/common/filesystem.cpp @@ -30,6 +30,7 @@ // along with this program. If not, see . #include "filesystem.h" +#include FILESYSTEM *FILESYSTEM::instance() { @@ -52,11 +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=dir.homePath(); - //qDebug(homeDir); + QString homeDir=QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);; return homeDir; } @@ -83,13 +95,25 @@ void FILESYSTEM::makeDir(QString name) if (dir.mkdir(name)){ emit success(name); } - else {emit error(name,1);} + else { + emit error(name,1); + } +} + +void FILESYSTEM::makePath(QString name) +{ + QDir dir(m_Directory); + if (dir.mkpath(name)){ + emit success(name); + } + else { + qDebug() << "makepath error" < #include +#include +#include //#include //#include @@ -41,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) @@ -50,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); @@ -67,14 +80,17 @@ signals: public slots: bool fileexist(QString name); void makeDir(QString name); + 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/src/common/filesystemandroid.cpp b/src/common/filesystemandroid.cpp new file mode 100644 index 0000000..07f6540 --- /dev/null +++ b/src/common/filesystemandroid.cpp @@ -0,0 +1,170 @@ +// 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 . + +#include "filesystem.h" +#include + + +FILESYSTEM *FILESYSTEM::instance() +{ + static FILESYSTEM filesystem; + return &filesystem; +} + +FILESYSTEM::FILESYSTEM(QObject *parent) : QObject(parent){} + +void FILESYSTEM::setDirectory(QString Directory) +{ + if (Directory!=m_Directory) { + m_Directory = Directory; + emit directoryChanged(); + } +} + +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 +{ + QAndroidJniObject activity =QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative","activity", "()Landroid/app/Activity;"); + QAndroidJniObject dir = activity.callObjectMethod("getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;", NULL); + QString homeDir=dir.toString(); + return homeDir; +} + +bool FILESYSTEM::fileexist(QString name) +{ return QFile::exists(name); +} + +void FILESYSTEM::makeDir(QString name) +{ + QDir dir(m_Directory); + if (dir.mkdir(name)){ + emit success(name); + } + else { + emit error(name,1); + } +} + +void FILESYSTEM::makePath(QString name) +{ + QDir dir(m_Directory); + if (dir.mkpath(name)){ + emit success(name); + } + else { + emit error(name,1);} +} + +void FILESYSTEM::rmDir() +{ + QDir dir(m_Directory); + if (dir.removeRecursively()){ + emit success(m_Directory); + } + else {emit error(m_Directory,1);} +} + +void FILESYSTEM::rmFile(QString name) +{ + QDir dir(m_Directory); + if(dir.remove(name)){ + emit success(name); + } + else {emit error(name,1);} +} +QFileInfoList FILESYSTEM::fileList() +{ + QDir dir(m_Directory); + QStringList filters; + filters << "*.png" <<"*.PNG" << "*.jpg" << "*.JPG" << "*.JPEG"; + dir.setNameFilters(filters); + 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 63% rename from source-linux/common/updatenews.cpp rename to src/common/updatenews.cpp index d64ba34..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 @@ -45,7 +45,6 @@ #include #include #include -//#include "AndroidNative/systemdispatcher.h" @@ -60,68 +59,103 @@ 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()) - { - qDebug() << "Error: connection with database fail " << m_db.lastError(); - } + if (!m_db.open()) + { + qDebug() << "Error: connection with database fail " << m_db.lastError(); + } +} + +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(); - //QSqlQuery syncquery("SELECT * FROM globaloptions WHERE k like 'sync_%' AND v=1",m_db); while (syncquery.next()){ if (syncquery.value(0).toString()=="syncinterval"){ m_updateInterval=syncquery.value(1).toInt(); } if (syncquery.value(0).toString().left(5)=="sync_" && syncquery.value(1).toInt()==1){ synclist.append(syncquery.value(0).toString()); - //qDebug() << " sync " << syncquery.value(0).toString() << " " <

"+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());} QJsonArray likeArray;QJsonArray dislikeArray;QJsonArray attendyesArray;QJsonArray attendnoArray;QJsonArray attendmaybeArray; if (newsitem.toObject().contains("friendica_activities")){ for (int a=0; a < newsitem["friendica_activities"]["like"].toArray().count();a++){ @@ -312,7 +377,7 @@ void UPDATENEWS::store(QByteArray serverreply,QString apiname) for (int e = 0; e < newsitem["friendica_activities"]["attendmaybe"].toArray().count();e++){ attendmaybeArray.append(newsitem["friendica_activities"]["attendmaybe"][e]["url"].toString()); } - } + } QJsonArray friendica_activities; friendica_activities={likeArray,dislikeArray,attendyesArray,attendnoArray,attendmaybeArray}; QJsonDocument activities; activities.setArray(friendica_activities); query.bindValue(13,activities.toJson(QJsonDocument::Compact).toBase64()); @@ -328,7 +393,7 @@ void UPDATENEWS::store(QByteArray serverreply,QString apiname) query.bindValue(16, newsitem["friendica_author"]["url"]); }else { query.bindValue(16, newsitem["user"]["url"]); - } + } if (apiname=="/api/statuses/replies"){ query.bindValue(1,"3"); @@ -336,13 +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"].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"); @@ -371,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); } @@ -382,41 +448,55 @@ void UPDATENEWS::store(QByteArray serverreply,QString apiname) } } QList newcontacts=findNewContacts(news); - //qDebug()<< "new contacts count " << newcontacts.size(); + emit this->success(m_api); if (newcontacts.size()>0){ updateContacts(newcontacts); - startImagedownload(); + 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){ if (downloadtype=="contactlist"){ QSqlQuery testquery("SELECT profile_image FROM contacts WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db); testquery.first(); - //qDebug()<< "update imageurl for " < UPDATENEWS::findNewContacts(QJsonDocument news){ imageurls.append(query.value(0).toString()); } QList newcontacts; - //qDebug()<<"updatenews findcontacts news count "< UPDATENEWS::findNewContacts(QJsonDocument news){ if (news[i].toObject().contains("friendica_activities") ){ for (int a=0; a < news[i]["friendica_activities"]["like"].toArray().count();a++){ if(imageurls.contains(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0))){ - } + } else{ newcontacts.append(news[i]["friendica_activities"]["like"][a]); newcontactimagelinks.append(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0)); @@ -476,7 +555,7 @@ QList UPDATENEWS::findNewContacts(QJsonDocument news){ } for (int b=0; b < news[i]["friendica_activities"]["dislike"].toArray().count();b++){ if(imageurls.contains(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0))){ - } + } else{ newcontacts.append(news[i]["friendica_activities"]["dislike"][b]); newcontactimagelinks.append(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0)); @@ -487,13 +566,13 @@ QList UPDATENEWS::findNewContacts(QJsonDocument news){ //owner contacts if (news[i].toObject().contains("friendica_author") ){ if(imageurls.contains(news[i]["friendica_author"]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_owner"]["profile_image_url"].toString().section('?',0,0))){ - } + } else{ newcontacts.append(news[i]["friendica_author"]); newcontactimagelinks.append(news[i]["friendica_author"]["profile_image_url"].toString().section('?',0,0)); newcontactnames.append(news[i]["friendica_author"]["screen_name"].toString()); } - } + } } return newcontacts; } @@ -505,14 +584,13 @@ void UPDATENEWS::updateContacts(QList contacts){ QJsonValue contact=contacts[i]; QSqlQuery query(m_db); try{ - //qDebug() << "updatecontact " << contact["screen_name"]; QSqlQuery testquery("SELECT url FROM contacts WHERE username='"+ username +"' AND url='" + contact["url"].toString() +"'",m_db); if (testquery.first()){ query.prepare("UPDATE contacts SET id=?, name=?, screen_name=?, location=?,imageAge=?," - "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"]); @@ -545,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()); @@ -591,11 +669,116 @@ void UPDATENEWS::updateContacts(QList contacts){ } } +void UPDATENEWS::storeFriendrequests(QByteArray serverreply,QString apiname) +{ if (apiname!=m_api || xhr.downloadtype()!=""){} else { + QJsonDocument friendrequests; + QJsonParseError jsonerror; + friendrequests=QJsonDocument::fromJson(serverreply,&jsonerror); + if (friendrequests.isArray()){ + + QSqlQuery imagequery("SELECT avatar FROM friendshiprequests",m_db); + QList imageurls; + + while (imagequery.next()){ + imageurls.append(imagequery.value(0).toString()); + } + + for (int i=0; i < friendrequests.array().count();i++){ + QJsonValue friendrequestitem=friendrequests[i]; + try{ + QSqlQuery testquery("SELECT url FROM friendshiprequests WHERE username='"+ username +"' AND url='" + friendrequestitem["url"].toString() +"'",m_db); + 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() +"'"); + + query.bindValue(0, friendrequestitem["id"].toInt()); + query.bindValue(1, friendrequestitem["username"]); + query.bindValue(2, friendrequestitem["acct"]); + query.bindValue(3, friendrequestitem["display_name"].toString().toUtf8().toBase64()); + query.bindValue(4, friendrequestitem["locked"].toBool()); + query.bindValue(5, friendrequestitem["bot"].toBool()); + query.bindValue(6, friendrequestitem["discoverable"].toBool()); + query.bindValue(7, friendrequestitem["group"].toBool()); + query.bindValue(8, QDateTime::fromString(friendrequestitem["created_at"].toString(),Qt::ISODate).toMSecsSinceEpoch() ); + query.bindValue(9, friendrequestitem["note"].toString().toUtf8().toBase64()); + query.bindValue(10, friendrequestitem["avatar"]); + query.bindValue(11, friendrequestitem["header"]); + query.bindValue(12, friendrequestitem["header_static"]); + query.bindValue(13, friendrequestitem["followers_count"].toInt()); + query.bindValue(14, friendrequestitem["following_count"].toInt()); + query.bindValue(15, friendrequestitem["statuses_count"].toInt()); + query.bindValue(16, QDateTime::fromString(friendrequestitem["last_status_at"].toString(),Qt::ISODate).toMSecsSinceEpoch() ); + query.bindValue(17, friendrequestitem["emojis"].toString().toUtf8().toBase64()); + query.bindValue(18, friendrequestitem["fields"].toString().toUtf8().toBase64()); + } + 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 (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + query.bindValue(0, username); + query.bindValue(1, friendrequestitem["id"].toInt()); + query.bindValue(2, friendrequestitem["username"].toString()); + query.bindValue(3, friendrequestitem["acct"].toString()); + query.bindValue(4, friendrequestitem["display_name"].toString().toUtf8().toBase64()); + query.bindValue(5, friendrequestitem["locked"].toBool()); + query.bindValue(6, QDateTime::fromString(friendrequestitem["created_at"].toString(),Qt::ISODate).toMSecsSinceEpoch()); + query.bindValue(7, friendrequestitem["followers_count"].toInt()); + query.bindValue(8, friendrequestitem["following_count"].toInt()); + query.bindValue(9, friendrequestitem["statuses_count"].toInt()); + query.bindValue(10, friendrequestitem["note"].toString().toUtf8().toBase64()); + query.bindValue(11, friendrequestitem["url"].toString()); + query.bindValue(12, friendrequestitem["avatar"].toString()); + query.bindValue(13, ""); + query.bindValue(14, friendrequestitem["header"].toString()); + query.bindValue(15, friendrequestitem["header_static"].toString()); + query.bindValue(16, friendrequestitem["emojis"].toString().toUtf8().toBase64()); + query.bindValue(17, "false"); + query.bindValue(18, friendrequestitem["fields"].toString().toUtf8().toBase64()); + query.bindValue(19, friendrequestitem["bot"].toBool()); + query.bindValue(20, friendrequestitem["group"].toBool()); + query.bindValue(21, friendrequestitem["discoverable"].toBool()); + query.bindValue(22, QDateTime::fromString(friendrequestitem["last_status_at"].toString(),Qt::ISODate).toMSecsSinceEpoch()); + + if(notifylist.contains("notify_FriendRequests")){ + alarm.notify("Friend Request: "+ friendrequestitem["acct"].toString(),friendrequestitem["note"].toString(),0); + } + + } + if(!(query.exec())) {qDebug()<< "friendrequestitem error " << query.lastError() << " " << query.lastQuery();} + } catch(...){ + qDebug() << "Friendiqasync Error inserting friendrequestitem" << friendrequestitem["acct"] << " " ; + } + + if(imageurls.contains(friendrequestitem["avatar"].toString() )){ + } + else{ + newcontactimagelinks.append(friendrequestitem["avatar"].toString()); + newcontactnames.append(friendrequestitem["username"].toString()); + } + } + + if (newcontactimagelinks.length()>0){ + startImagedownload("friendrequests"); + }else{ + if((m_updateInterval!=0) && m_syncAll){ + syncindex+=1; + startsync(); + } + } + } + } + QObject::disconnect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(storeFriendrequests(QByteArray,QString))); +} void UPDATENEWS::storeEvents(QByteArray serverreply,QString apiname) -{ if (apiname!=m_api || xhr.downloadtype()!=""){} else { +{ if (apiname!=m_api || xhr.downloadtype()!=""){} else { QJsonDocument events; - //qDebug()<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(">","]")}; QJsonDocument permissionDocument; permissionDocument.setArray(permissions); query.bindValue(13,permissionDocument.toJson(QJsonDocument::Compact)); if(!(query.exec())) {qDebug()<< "store events " << query.lastError();} - } catch(...){ - qDebug() << "Friendiqasync Error event" << eventitem["name"]; - } + } catch(...){ + qDebug() << "Friendiqasync Error event" << eventitem["name"]; + } } - emit this->success(m_api); + emit this->success(m_api); } } 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); - while (eventnotifyquery.next()) { - alarm.notify("Event: "+ QDateTime::fromMSecsSinceEpoch(eventnotifyquery.value(0).toLongLong()).toString("dd.MM.yyyy hh:mm"),eventnotifyquery.value(1).toString(),1); - } + 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 +void UPDATENEWS::startImagedownload(QString downloadtype) { - return m_url; -} - -void UPDATENEWS::startImagedownload() -{ - //qDebug() << "start image download"; - xhr.setDownloadtype("contactlist"); + 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 86% rename from source-linux/common/updatenews.h rename to src/common/updatenews.h index b44b558..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,55 +43,51 @@ 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(); void startsync(); void directmessages(); void notifications(); + void friendrequests(); void events(); - //void startservice(QString type,QVariantMap map); - void startImagedownload(); + 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 59% rename from source-linux/common/xhr.cpp rename to src/common/xhr.cpp index f50a13d..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; @@ -154,11 +190,6 @@ QString XHR::downloadtype() const return m_downloadtype; } -QString XHR::networktype() -{ - return nc.bearerTypeFamily() + nc.bearerTypeName(); -} - void XHR::setParam(QString name, QString value) { params.insert(name, value); @@ -178,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); @@ -190,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); } @@ -254,39 +293,54 @@ 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()+"\"")); imagePart.setBody(uimg.bytes()); multiPart->append(imagePart); } -// QHashIterator ifiles(files); -// while(ifiles.hasNext()) { -// ifiles.next(); - -// uimg.setSource(ifiles.value()); -// //qDebug() << "\t image: " << uimg.mimetype() << ", " << ifiles.key(); - -// QHttpPart imagePart; -// imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(uimg.mimetype())); -// imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + ifiles.key() + "\"; filename=\""+uimg.filename()+"\"")); -// imagePart.setBody(uimg.bytes()); -// 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) @@ -301,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 @@ -338,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); @@ -347,9 +410,10 @@ void XHR::onRequestFinished() buffer.clear(); file.close(); emit this->downloaded(m_downloadtype,m_url,m_filename,dlindex); - if(downloadtype()=="contactlist"){dlindex=dlindex+1;XHR::getlist();} - - //reply->deleteLater(); + //reply->deleteLater(); + } + if(downloadtype()=="contactlist" || downloadtype()=="friendrequests" || downloadtype()=="picturelist"){ + dlindex=dlindex+1;XHR::getlist(); } } @@ -362,7 +426,7 @@ void XHR::onReadyRead() //void XHR::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes) //{ // qDebug() << "Bytes: " << bytesRead<<" / "< &errors) @@ -376,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 87% rename from source-linux/common/xhr.h rename to src/common/xhr.h index d283b95..fd2d024 100644 --- a/source-linux/common/xhr.h +++ b/src/common/xhr.h @@ -37,19 +37,21 @@ #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) Q_PROPERTY(QList filelist READ filelist WRITE setFilelist NOTIFY filelistChanged) Q_PROPERTY(QString downloadtype READ downloadtype WRITE setDownloadtype NOTIFY downloadtypeChanged) - Q_PROPERTY(QString networktype READ networktype() NOTIFY networktypeChanged) + //Q_PROPERTY(QString networktype READ networktype() NOTIFY networktypeChanged) public: @@ -60,17 +62,21 @@ 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; QString imagedir() const; QString downloadtype() const; - QString networktype(); +// QString networktype(); 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,9 +123,11 @@ 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; +// QString m_networktype; QHash params; QHash files; QList m_filelist; @@ -125,9 +136,9 @@ private: int dlindex; QNetworkAccessManager manager; - QNetworkRequest request; + //QNetworkRequest request; QNetworkReply *reply; - QNetworkConfiguration nc; + //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 c69d524..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{ - showMessage("Error","API:\n" +api+" NO RESPONSE",rootwindow) callback(xhrequest.responseText) } } - catch (e){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]) @@ -166,10 +150,37 @@ var where = " AND "+ filter +" = '" + filtervalue+"'"; }); } + +function deleteData(database,table, username, 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('DELETE from '+table+' WHERE username="'+username+'"'+where); + callback(); + }); +} + +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;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 . + +.pragma library +.import QtQuick.LocalStorage 2.0 as Sql +.import "qrc:/js/helper.js" as Helperjs + +function requestFriends(login,database,rootwindow,callback){ + // return array of friends + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + db.transaction( function(tx) { + var result = tx.executeSql('UPDATE contacts SET isFriend=0 where username="'+login.username+'"'); // clean old friends + var result2 = tx.executeSql('DELETE from groups where username="'+login.username+'"'); // clean old groups + }) + // /api/statuses/friends not working in Friendica 2/2022 , switching to api/v1/lists and download of all list members + Helperjs.friendicaRequest(login,"/api/statuses/friends?count=9999", rootwindow,function (obj){ + //var allfriends=[]; + //Helperjs.friendicaRequest(login,"/api/v1/lists",rootwindow,function(listsobj){ + // var lists=JSON.parse(listsobj) + // for (var list in lists){ + // Helperjs.friendicaRequest(login,"/api/v1/lists/"+lists[list].id+"/accounts?limit=0", rootwindow,function (obj){ + let friendsobj=JSON.parse(obj); + let friends=friendsobj.users; + //var memberarray=[]; + 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=''; + 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>'+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]) + } + }) + } +} + +function deleteGroup(login,database,rootwindow,group, callback){ + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + 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() + }); + }})} + +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) + }) +} + + + +//function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback){ +// // retrieve and return timeline since last news, return contacts which are not friends and older than 2 days for update (friends can be updated in Contactstab) +// var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); +// var parameter = "?count=50"; +// if(onlynew){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'); // check for last news id +// try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})} +// var newContacts=[]; +// Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){ +// var news=JSON.parse(obj); +// if (news.hasOwnProperty('status')){ +// Helperjs.showMessage(qsTr("Error"),"API:\n" +login.server+"/api/statuses/friends_timeline"+parameter+"\n Return: \n"+obj,rootwindow) +// } +// var newContacts=findNewContacts(news,contacts); +// callback(news,newContacts) +//})} + +function getCurrentContacts(login,database,callback){ + var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); + var contactlist=[]; + 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;j0){ + for (var j=0;j0){ + for (var k=0;j

"+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 + 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()+") "} + + var conversationsrs=tx.executeSql('select DISTINCT statusnet_conversation_id from news WHERE username="'+login.username+'" AND status_id'+stop+' AND messagetype IN ( "'+messagetype+'" ) '+ conversationfilter +'ORDER BY created_at DESC LIMIT 20'); //+' ORDER BY created_at DESC LIMIT 20'); + var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); + try{var lastid=result.rows.item(0).status_id;}catch(e){var lastid=0}; + var conversations=[]; + for(var i = 0; i < conversationsrs.rows.length; i++) { + conversations.push(conversationsrs.rows.item(i).statusnet_conversation_id); + } + var newsArray=[]; + var allcontacts=getAllContacts(database,login.username); + + 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'); + var helpernews=newsrs.rows.item(0); + helpernews=cleanhelpernews(database,login.username,helpernews,allcontacts) + helpernews.currentconversation=[]; + for (var h = 0;h0){ + for (var h = 0;h 0 ) { + for (var i in list) {if (list[i][prop] == val) { + return true; + } + } + } return false; +} + +function objFromArray(list, prop, val) { + if (list.length > 0 ) { + for (var i in list) {if (list[i][prop] == val) { + return list[i]; + } + } + } return false; +} + +function cleanDate(date){ + var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25); + return cleanedDate +} + +function findTags(fulltext){ + return fulltext.match(/\s+[#]+[A-Za-z0-9-_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]+/g) +} diff --git a/src/js/newsworker.js b/src/js/newsworker.js new file mode 100644 index 0000000..8eab544 --- /dev/null +++ b/src/js/newsworker.js @@ -0,0 +1,170 @@ +// 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="-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 c9dbc96..bbb8de7 100644 --- a/source-linux/qml/calendarqml/CalendarDay.qml +++ b/src/qml/calendarqml/CalendarDay.qml @@ -29,28 +29,31 @@ // 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:7*mm - height: 7*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: 'lightblue'; antialiasing: true + color: model.today?'lightblue':'transparent'; + border.color: 'lightblue' + border.width: 2 + antialiasing: true anchors.fill:parent + radius: 0.5*mm } Text { 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 - font.pixelSize: 4*mm + font.pointSize: 1.2*osSettings.systemFontSize } Rectangle { id:eventRect @@ -58,15 +61,13 @@ Item { anchors.margins: 0.5*mm anchors.bottom: calendarDay.bottom width: parent.width-mm - height: mm + height: 0.5*osSettings.systemFontSize//mm visible: eventdays.indexOf(dateInt)>-1 } MouseArea { anchors.fill: calendarDay onClicked: { - var component = Qt.createComponent("qrc:/qml/calendarqml/EventList.qml"); - if (component.status== Component.Ready){ - var eventlist = component.createObject(calendartab,{"dayint": dateInt})} + rootstackView.push("qrc:/qml/calendarqml/EventList.qml",{"dayint": dateInt,"events":events}); } } } diff --git a/src/qml/calendarqml/CalendarTab.qml b/src/qml/calendarqml/CalendarTab.qml new file mode 100644 index 0000000..9fa14c7 --- /dev/null +++ b/src/qml/calendarqml/CalendarTab.qml @@ -0,0 +1,301 @@ +// 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 Qt.labs.calendar 1.0 +//import QtQuick.Layouts 1.3 +import "qrc:/js/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/calendarqml" +import "qrc:/qml/genericqml" + +Rectangle { + id:calendarrectangle + // 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=cleanEvents(eventArray); + eventdays=dayArray}) + } + else if (friend!=""){ + calendartab.calendartabstatus=friend.url.substring(friend.url.lastIndexOf("/")+1,friend.url.length) + Service.newRequestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){ + events=cleanEvents(eventArray); + eventdays=dayArray}) + } + else {calendartab.calendartabstatus="Events"; + Service.eventsfromdb(db,login.username,function(eventArray,dayArray){ + events=cleanEvents(eventArray); + eventdays=dayArray; + calBusy.running=false + var currentevents=events; + currentevents=events.filter(event=>(currentTime<=event.end)); + for (var i=0; i0){events[item].end=events[item].end-offsetTime}; + } + return events + } + + 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 + 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 + } + + MButton{ + id: updateEvents + anchors.top: parent.top + anchors.topMargin: 0.5*mm + anchors.right:calendartabstatusButton.left + anchors.rightMargin:mm + 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(); + }} + + Connections{ + target: updatenews + + 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:menuButton.width + mm + width: Math.max(6*root.fontFactor*osSettings.bigFontSize,implicitWidth) + text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus + Menu { + id:calendartabmenu + width: 20*root.fontFactor*osSettings.systemFontSize + MenuItem { + text: qsTr("Own Calendar") + font.pointSize: osSettings.systemFontSize + onTriggered: { + calendartab.calendartabstatus="Events"; + // calendartabstatusButton.text=qsTr("own Calendar"); + showEvents("")} + } + } + onClicked: {calendartabmenu.popup()} + } + + ListView{ + id: calendarView + y:2*root.fontFactor*osSettings.bigFontSize//8*mm + width: wideScreen&&rootstackView.depth<2?parent.width-leftDrawer.width-mm:parent.width-mm//newstabitem.width/3*2:newstabitem.width + x: leftDrawer.width + height: 18*root.fontFactor*osSettings.bigFontSize //parent.height-9*mm + clip: true + snapMode: ListView.SnapOneItem + orientation: ListView.Horizontal + highlightRangeMode: ListView.StrictlyEnforceRange + + 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: 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{} + } + } + ScrollIndicator.horizontal: ScrollIndicator { } + Component.onCompleted: positionViewAtBeginning() + } + + ListView { + id: eventlistView + y:20*root.fontFactor*osSettings.bigFontSize + x: leftDrawer.width + height: parent.height-20*root.fontFactor*osSettings.bigFontSize + width: wideScreen&&rootstackView.depth<2?parent.width-leftDrawer.width-mm:parent.width-mm + clip: true + model: eventModel + delegate: EventListItem{} + } + + ListModel{ + id: eventModel + } + + 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/src/qml/calendarqml/EventList.qml b/src/qml/calendarqml/EventList.qml new file mode 100644 index 0000000..8fb4e58 --- /dev/null +++ b/src/qml/calendarqml/EventList.qml @@ -0,0 +1,109 @@ +// 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/service.js" as Service +import "qrc:/js/helper.js" as Helperjs +import "qrc:/qml/genericqml" +import "qrc:/qml/calendarqml" + +Rectangle{ + id:eventList + color: osSettings.backgroundColor + property var daylist:[] + property int dayint: 0 + property var events:[] + + MButton{ + id:closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + 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 + width: eventList.width-4*root.fontFactor*osSettings.bigFontSize + height: eventList.height-closeButton.height-root.fontFactor*osSettings.bigFontSize + clip: true + model: eventModel + delegate: EventListItem{} + } + ListModel{ + id: eventModel + } + Component.onCompleted:{ + var currentevents=events.filter(event=>(dayint>=event.startday)&&(dayint<=event.endday)); + 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 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" +import "qrc:/qml/calendarqml" + +Rectangle{ + id:eventItem + property string status: eventstatus + property var currEvent: event + width:parent.width + 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 { + id:profileImage + source: ((event.eventOwner.profile_image!="") && (typeof(event.eventOwner.profile_image)=="string"))? "file://"+event.eventOwner.profile_image : event.eventOwner.profile_image_url + x:1 + y:1 + width: 7*mm + height: 7*mm + 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")+":
"+(status=="large"?""+event.title+"":event.title) + wrapMode:Text.Wrap + } + + Text { + id:eventDetailsText + x:8*mm + 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) + 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/src/qml/configqml/AcceptRules.qml b/src/qml/configqml/AcceptRules.qml new file mode 100644 index 0000000..68e4107 --- /dev/null +++ b/src/qml/configqml/AcceptRules.qml @@ -0,0 +1,68 @@ +// 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 + +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 65% rename from source-linux/qml/configqml/InfoBox.qml rename to src/qml/configqml/InfoBox.qml index 0402662..354b74b 100644 --- a/source-linux/qml/configqml/InfoBox.qml +++ b/src/qml/configqml/InfoBox.qml @@ -29,43 +29,41 @@ // 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" -Rectangle{ - color:"white" - width:infoBoxText.contentWidth - height:infoBoxText.contentHeight +Page{ 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.5.3
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
"+ - "AndroidNative by Ben Lau
"+ - "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/)" - onLinkActivated:{ + "Code by Marco
"+ + "Qt Framework www.qt.io
"+ + "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:{ Qt.openUrlExternally(link)} - } - Button{ - id:closeButton - height: 6*mm - width: 8*mm - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - font.pixelSize: 3*mm - onClicked:{root.pop()} - } + } + MButton{ + id:closeButton + anchors.top: parent.top + anchors.topMargin: root.fontFactor*osSettings.bigFontSize + 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()} + } } 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/src/qml/configqml/OSSettingsAndroid.qml b/src/qml/configqml/OSSettingsAndroid.qml new file mode 100644 index 0000000..19515ac --- /dev/null +++ b/src/qml/configqml/OSSettingsAndroid.qml @@ -0,0 +1,70 @@ +// 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.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 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 83% rename from source-linux/qml/configqml/SyncComponent.qml rename to src/qml/configqml/SyncComponent.qml index b8cd30c..f58fa14 100644 --- a/source-linux/qml/configqml/SyncComponent.qml +++ b/src/qml/configqml/SyncComponent.qml @@ -30,31 +30,31 @@ // 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: 12*mm + height: 4*root.fontFactor*osSettings.bigFontSize Label{ x: mm y: 0.5*mm - font.pixelSize:3*mm + font.pointSize: osSettings.systemFontSize text: qsTr(adapter) } CheckBox{ id: syncCheckbox x: mm - y: 5*mm - width:20*mm + y: root.fontFactor*osSettings.bigFontSize + width: 10*root.fontFactor*osSettings.bigFontSize checked:(globaloptions["sync_"+adapter]==1)?true:false //style: CheckBoxStyle { text: qsTr("sync") - font.pixelSize:3*mm + font.pointSize: osSettings.bigFontSize onClicked: { toggle(); if(syncCheckbox.checked==true){ @@ -67,13 +67,13 @@ Rectangle{ } CheckBox{ id: notifyCheckbox - x:25*mm - y: 5*mm - width:25*mm + x: 10*root.fontFactor*osSettings.bigFontSize + y: root.fontFactor*osSettings.bigFontSize + width: 10*root.fontFactor*osSettings.bigFontSize enabled: adapter!="Notifications" checked:(globaloptions["notify_"+adapter]==1)?true:false text: qsTr("notify") - font.pixelSize:3*mm + font.pointSize: osSettings.bigFontSize onClicked: { toggle(); if(notifyCheckbox.checked==true){ diff --git a/source-linux/qml/configqml/SyncConfig.qml b/src/qml/configqml/SyncConfig.qml similarity index 54% rename from source-linux/qml/configqml/SyncConfig.qml rename to src/qml/configqml/SyncConfig.qml index ef7ebf6..d23542f 100644 --- a/source-linux/qml/configqml/SyncConfig.qml +++ b/src/qml/configqml/SyncConfig.qml @@ -29,82 +29,47 @@ // 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 6.3 +import QtQuick.Controls 6.3 import "qrc:/qml/configqml" import "qrc:/qml/genericqml" import "qrc:/js/service.js" as Service -Rectangle{ - color:"white" +Page{ width:root.width height: root.height - //height:root.height - Text { - text: qsTr("Sync Interval (0=None)") - font.pixelSize:3*mm - //visible: false - x: 4*mm; y: 10*mm; //width:35*mm;wrapMode: Text.Wrap - } - - Slider{ id: messageIntervalSlider - x:22*mm; y: 13.5*mm;width: root.width/2;height:5*mm - value: globaloptions.hasOwnProperty("syncinterval")?globaloptions.syncinterval:0 - from: 0;to:120; stepSize: 15 - } - Rectangle{ - x: 4*mm; y: 13.5*mm; width: 9*mm; height: 5*mm; - TextEdit{ - id: messageIntervalField - anchors.fill: parent - font.pixelSize:3*mm - verticalAlignment:TextEdit.AlignRight - text:messageIntervalSlider.value - focus: true - selectByMouse: true - onTextChanged: { - Service.updateglobaloptions(root.db,"syncinterval",text); - if(osSettings.osType=="Android"){ - alarm.setAlarm(text); - } else if(osSettings.osType=="Linux" && text !=0){ - root.updateSyncinterval(parseInt(text)) - } - } + 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); + } } } - Text{x: 14*mm; y: 13.5*mm; width: 5*mm; height: 5*mm; - font.pixelSize:3*mm - text:qsTr("Min.") - } ScrollView{ width: root.width - height: root.height - 25*mm;y:22*mm + height: root.height - 10*root.fontFactor*osSettings.bigFontSize; + y:4*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: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - height: 6*mm - width: 8*mm - text: "\uf057" - font.pixelSize: 3*mm - onClicked:{root.pop()} - } } diff --git a/source-linux/qml/contactqml/Contactlist.qml b/src/qml/contactqml/Contactlist.qml similarity index 53% rename from source-linux/qml/contactqml/Contactlist.qml rename to src/qml/contactqml/Contactlist.qml index 045930b..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" @@ -47,41 +47,41 @@ Rectangle { height:groupListView.height ListView { - id: contactView - x:mm - y:6*mm - width: contactlistRectangle.width-2*mm - height: contactlistRectangle.height-10*mm - clip: true - spacing: 0 - model: contactModel - delegate: listContact - } + id: contactView + x:mm + y:6*mm + width: contactlistRectangle.width-2*mm + height: contactlistRectangle.height-10*mm + clip: true + spacing: 0 + model: contactModel + delegate: listContact + } - ListModel{id: contactModel} + ListModel{id: contactModel} - Component { id:listContact - Rectangle{ - border.color: "#EEEEEE" - border.width: 1 - radius:0.5*mm - width:contactView.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.pixelSize: 3*mm - anchors.left: contactImage.right - anchors.margins: 1*mm - text:Qt.atob(contact.name) - } + Component { id:listContact + Rectangle{ + border.color: "#EEEEEE" + border.width: 1 + radius:0.5*mm + width:contactView.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{ + font.pointSize: osSettings.bigFontSize + anchors.left: contactImage.right + anchors.margins: 1*mm + text:Qt.atob(contact.name) + } Text { id:selected anchors.right:parent.right @@ -91,40 +91,40 @@ Rectangle { width: 5*mm anchors.top: parent.top color: "green" - font.pixelSize: 3*mm + font.pointSize: osSettings.bigFontSize } - MouseArea{ + MouseArea{ anchors.fill: parent onClicked:{ if(selected.visible==true){ - contacts.splice(Helperjs.inArray(contacts,"id",contact.id),1); - selected.visible=false - } - else{ - contacts.push(contact); - selected.visible=true; - } - } - } + contacts.splice(Helperjs.inArray(contacts,"id",contact.id),1); + selected.visible=false + } + else{ + contacts.push(contact); + selected.visible=true; + } + } } - } + } + } - MButton { - id: closeButton - height:6* mm - width: 8*mm - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - //color:"white" - text: "\uf057" - onClicked: { - groupModelAppend(contacts,function(){ - contactlistRectangle.destroy() - }); - } + 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: { + groupModelAppend(contacts,function(){ + contactlistRectangle.destroy() + }); + } } Component.onCompleted: { 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/src/qml/contactqml/FriendsTab.qml b/src/qml/contactqml/FriendsTab.qml new file mode 100644 index 0000000..f964c4f --- /dev/null +++ b/src/qml/contactqml/FriendsTab.qml @@ -0,0 +1,132 @@ +// 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/news.js" as Newsjs +import "qrc:/js/service.js" as Service +import "qrc:/qml/contactqml" +import "qrc:/qml/genericqml" + +Rectangle { + y:1 + color: osSettings.backgroundColor + function showContactdetails(contact){ + root.contactdetailsSignal(contact) + } + + ToolButton{ + id:menuButton + z:2 + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: friendsbar.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()} + } + + TabBar { + 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?root.fontFactor*osSettings.systemFontSize*15:0 + height: root.height-bar.height + } + + LeftDrawerAndroid{ + id: leftDrawerAndroid + } + + StackLayout{ + id:friendsTabView + 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 + height: friendsbar.visible?parent.height-friendsbar.height-mm:parent.height-mm + currentIndex: friendsbar.currentIndex + signal contactsSignal(var contact) + signal groupsSignal(var username) + + onCurrentIndexChanged:{ + if (currentIndex==1){ + contactsSignal("") + } + else if (currentIndex==2){groupsSignal(root.login.username)} + } + + Loader{ + id: profileLoader + source:(friendsTabView.currentIndex==0)? "qrc:/qml/contactqml/ProfileTab.qml":"" + } + + Loader{ + id: friendsListLoader + source:(friendsTabView.currentIndex==1)? "qrc:/qml/contactqml/FriendsListTab.qml":"" + } + + Loader{ + id: groupsListLoader + source:(friendsTabView.currentIndex==2)? "qrc:/qml/contactqml/GroupsListTab.qml":"" + } + } +} 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/src/qml/contactqml/GroupsListTab.qml b/src/qml/contactqml/GroupsListTab.qml new file mode 100644 index 0000000..eaf754c --- /dev/null +++ b/src/qml/contactqml/GroupsListTab.qml @@ -0,0 +1,146 @@ +// 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.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: groupsGridTab + + 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,8 +53,8 @@ Rectangle { function buildProfiletext(pobject,callback){ var profileobject={}; var profiletext=""; - for (var key in pobject){//print(key+obj[key]) - if(pobject[key]!=""&&key!="users"&&key!="profile_id"){ + for (var key in pobject){ + if(pobject[key]!=""&&pobject[key]!=null&&key!="users"&&key!="profile_id"){ var keytext=""; switch(key){ case "profile_name":keytext=qsTr("profile name");break; @@ -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) @@ -105,16 +114,19 @@ Rectangle { MButton { id: update - height: 6*mm - width: 8*mm anchors.top: parent.top anchors.topMargin: mm anchors.right: parent.right - text: "\uf021" - font.pixelSize: 3*mm + 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){ root.newContacts=nc; + root.onNewContactsChanged(nc); photoImage.source=""; showProfile(function(newprofile){ profile=newprofile; @@ -142,46 +154,54 @@ 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;'+ - '}}',profileGridTab,"imagePicker"); + '}}',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.pixelSize: 4*mm - } + } MButton{ id:updatebutton - height: 6*mm - width:8*mm + width: 8*root.fontFactor*osSettings.bigFontSize visible: "file://"+profile.friendica_owner.profile_image!= photoImage.source text:qsTr("Update") - font.pixelSize: 3*mm + font.pointSize: osSettings.bigFontSize anchors.left: photoImage.right anchors.leftMargin: 0.5*mm anchors.topMargin: mm @@ -198,8 +218,8 @@ Rectangle { anchors.topMargin: 0 anchors.left: photoImage.left wrapMode: Text.Wrap - color: "#303030" - font.pixelSize: 4*mm + color: osSettings.secondaryTextColor + font.pointSize: osSettings.bigFontSize anchors.top: photoImage.bottom } @@ -209,12 +229,13 @@ Rectangle { Rectangle{ id:profileRect width:profileView.width + color: osSettings.backgroundColor height: 5*mm+profiletextfield.height Text{ y:mm - font.pixelSize: 3*mm + font.pointSize: osSettings.systemFontSize text:""+qsTr("profile id")+": "+profileid+"
" - color:"black" + color:osSettings.primaryTextColor } Text{ id:profiletextfield @@ -222,9 +243,10 @@ Rectangle { y:4.5*mm width:parent.width-2.5*mm wrapMode: Text.Wrap - font.pixelSize: 3*mm + font.pointSize: osSettings.systemFontSize text:profiletext - color:"black" + color: osSettings.primaryTextColor + onLinkActivated: Qt.openUrlExternally(link) } } } @@ -232,9 +254,10 @@ Rectangle { id:textcomponent Text{ id:namelabeltext + color: osSettings.primaryTextColor width: namelabelflickable.width height: implicitHeight - font.pixelSize: 3*mm + font.pointSize: osSettings.bigFontSize textFormat:Text.RichText wrapMode: Text.Wrap text:""+qsTr("Description")+": "+(Qt.atob(profile.friendica_owner.description))+"
"+qsTr("Location")+": "+profile.friendica_owner.location+"
"+qsTr("Posts")+": "+profile.friendica_owner.statuses_count+ @@ -245,10 +268,6 @@ Rectangle { } } -// Rectangle{ -// id: detailsrectangle - - ScrollView{ ScrollBar.horizontal.policy: ScrollBar.AlwaysOff id:namelabelflickable @@ -262,15 +281,12 @@ Rectangle { ListView { id: profileView header:textcomponent -// width:parent.width -// height: root.height -// clip: true spacing: 0 model: profileModel delegate: profileItem } } -// } + Component.onCompleted: { profile.profiles.sort(function(obj1, obj2) { diff --git a/source-linux/qml/newsqml/NewsLink.qml b/src/qml/contactqml/ProfileTab.qml similarity index 62% rename from source-linux/qml/newsqml/NewsLink.qml rename to src/qml/contactqml/ProfileTab.qml index 78f1555..b16d7b5 100644 --- a/source-linux/qml/newsqml/NewsLink.qml +++ b/src/qml/contactqml/ProfileTab.qml @@ -29,39 +29,34 @@ // 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 +import "qrc:/js/news.js" as Newsjs +import "qrc:/js/service.js" as Service +import "qrc:/qml/contactqml" +import "qrc:/qml/genericqml" -Rectangle{ - color:"transparent" - width:newscolumn.width; - height:newscolumn.width/4*3 - property string url:""//htmlview.text - - Text{id:htmlview - textFormat:Text.RichText +Item{ + id:profileTab + function showProfile(callback){ + var profile=({}); + Helperjs.readData(db,"profiles",login.username,function(profileobject){ + var profilearray=[]; + for (var i in profileobject){ + profilearray.push(JSON.parse(Qt.atob(profileobject[i].profiledata))); + } + profile.profiles=profilearray; + }); + Helperjs.readData(db,"contacts",login.username,function(owner){ + profile.friendica_owner=owner[0]; + },"isFriend",2); + callback(profile) } -// WebView {id:htmlview; -// anchors.fill: parent -// } Component.onCompleted:{ - -// 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.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,8*mm) + width: Math.max(mainText.width+2*mm,5*mm) height: 5*mm - color:"light blue"//"#EFEAEA" "sky blue" + //border.color: "light blue" + color:"transparent"//"#EFEAEA" "sky blue" property alias fontColor: mainText.color -// border.color:"grey" -// border.width:1 + 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.pixelSize: 3*mm + //font.family:fontAwesome.name + font.pointSize: osSettings.bigFontSize text: "" + elide: Text.ElideNone } MouseArea{ id:buttonArea @@ -64,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 58% rename from source-linux/qml/genericqml/ContactComponent.qml rename to src/qml/genericqml/ContactComponent.qml index 63f6656..52a983c 100644 --- a/source-linux/qml/genericqml/ContactComponent.qml +++ b/src/qml/genericqml/ContactComponent.qml @@ -29,64 +29,73 @@ // 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: 8*mm - 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: 8*mm - border.color: "grey" - color:"white" + height: parent.height + radius: 0.5*mm + border.color: osSettings.backgroundDimColor + color: osSettings.backgroundColor Image { id: photoImage x:0.5*mm y:0.5*mm - width: 7*mm - height: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"}} } - Column{ - width: wrapper.width-8*mm + Flow{ + 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: wrapper.width-4 - height: 3*mm + width: Math.min(wrapper.width-(photoImage.width+mm),contentWidth) + height: 1.1*root.fontFactor*osSettings.bigFontSize text: contact.name - elide:Text.ElideRight - color: "#303030" - font.pixelSize: 3*mm + elide: contentWidth>wrapper.width-4*osSettings.systemFontSize?Text.ElideRight:Text.ElideNone + color: osSettings.secondaryTextColor + font.pointSize: osSettings.bigFontSize } Label { id: screennamelabel - width: wrapper.width-8*mm - height: 2.5*mm - text: "@"+contact.screen_name + 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: osSettings.secondaryTextColor + font.pointSize: osSettings.bigFontSize + } + Label { + id: descriptionlabel + 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: "#303030" - font.pixelSize: 2.5*mm + color: osSettings.secondaryTextColor + font.pointSize: osSettings.systemFontSize } } MouseArea{ 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/src/qml/genericqml/DrawerAccountComponentContacts.qml b/src/qml/genericqml/DrawerAccountComponentContacts.qml new file mode 100644 index 0000000..544ade1 --- /dev/null +++ b/src/qml/genericqml/DrawerAccountComponentContacts.qml @@ -0,0 +1,110 @@ +// 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" + +Item { + id: drawerAccountComponent + 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 + 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 + font.bold: account.username==login.username && friendsTabView.currentIndex==0 + text: " "+qsTr("Profile") + MouseArea{ + anchors.fill:parent + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + friendsTabView.currentIndex=0; + friendsbar.currentIndex=0; + profileLoader.source=""; + profileLoader.source="qrc:/qml/contactqml/ProfileTab.qml" + } + } + } + + Label{ + y:3.5*root.fontFactor*osSettings.bigFontSize + width:parent.width + font.pointSize: osSettings.systemFontSize + font.bold: account.username==login.username && friendsTabView.currentIndex==1 + text: " "+qsTr("Friends") + MouseArea{ + anchors.fill:parent + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + friendsTabView.currentIndex=1; + friendsbar.currentIndex=1; + friendsListLoader.source=""; + friendsListLoader.source="qrc:/qml/contactqml/FriendsListTab.qml" + } + } + } + + Label{ + y:5*root.fontFactor*osSettings.bigFontSize + width:parent.width + font.pointSize: osSettings.systemFontSize + font.bold: account.username==login.username && friendsTabView.currentIndex==2 + text: " "+qsTr("Circles") + MouseArea{ + anchors.fill:parent + onClicked:{ + login=account; + if(!wideScreen){leftDrawerAndroid.close()} + 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 70% rename from source-linux/qml/genericqml/IntentReceiver.qml rename to src/qml/genericqml/IntentReceiver.qml index 8c3a007..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 { @@ -15,20 +15,22 @@ Item { Connections { target: SystemDispatcher - onDispatched: { + function onDispatched (type, message) { if ((type === m_IMAGE_MESSAGE)&& (root.imagePicking==false)) { var h=[]; for (var n in message.imageUrls){ 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/MButton.qml b/src/qml/genericqml/LeftDrawerAndroid.qml similarity index 82% rename from source-linux/qml/genericqml/MButton.qml rename to src/qml/genericqml/LeftDrawerAndroid.qml index b6cb841..8387fc1 100644 --- a/source-linux/qml/genericqml/MButton.qml +++ b/src/qml/genericqml/LeftDrawerAndroid.qml @@ -1,5 +1,5 @@ // This file is part of Friendiqa -// https://github.com/lubuwest/Friendiqa +// https://git.friendi.ca/lubuwest/Friendiqa // Copyright (C) 2020 Marco R. // // This program is free software: you can redistribute it and/or modify @@ -28,14 +28,15 @@ // // 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 -Button{ - id: mButton - width: Math.max(text.width+2*mm,8*mm) - //radius: mm - height: 6*mm - //color: Material.grey - font.pixelSize: 3*mm - background: Rectangle{color:"#F8F8F8";radius: 0.5*mm} + +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/configqml/OSSettingsLinux.qml b/src/qml/genericqml/LeftDrawerLinux.qml similarity index 79% rename from source-linux/qml/configqml/OSSettingsLinux.qml rename to src/qml/genericqml/LeftDrawerLinux.qml index 20440a7..73f9267 100644 --- a/source-linux/qml/configqml/OSSettingsLinux.qml +++ b/src/qml/genericqml/LeftDrawerLinux.qml @@ -29,13 +29,23 @@ // 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/3 - property real appHeight: Screen.desktopAvailableHeight/3*2 - property int backKey: Qt.Key_Escape - property string osType: "Linux" - //property string attachImageDir:filesystem.homePath+"/Pictures/" - property string imagePickQml: "ImagePickerLinux" +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import "qrc:/qml/configqml" + +Rectangle{ + signal opened() + color: osSettings.backgroundColor + + LeftDrawerScrollview{ + width:parent.width-mm + height:parent.height + x:mm + } + Rectangle{ + width: 1 + height: leftDrawer.height + anchors.right: leftDrawer.right + color: osSettings.dialogColor + } } 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/src/qml/genericqml/MButton.qml b/src/qml/genericqml/MButton.qml new file mode 100644 index 0000000..b2c8cea --- /dev/null +++ b/src/qml/genericqml/MButton.qml @@ -0,0 +1,48 @@ +// 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 +Button{ + id: mButton + //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.foreground + //font.family: fontAwesome.name + font.pointSize: osSettings.bigFontSize + //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/src/qml/genericqml/RootStack.qml b/src/qml/genericqml/RootStack.qml new file mode 100644 index 0000000..3898095 --- /dev/null +++ b/src/qml/genericqml/RootStack.qml @@ -0,0 +1,65 @@ +// 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 QtQuick.Layouts + +StackLayout{ + id:rootstack + width:rootstackView.width + height: rootstackView.height + currentIndex:bar.currentIndex + + function indexchange(pageindex){currentIndex=pageindex;bar.currentIndex=pageindex} + + 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/src/qml/newsqml/BlockUser.qml b/src/qml/newsqml/BlockUser.qml new file mode 100644 index 0000000..e559207 --- /dev/null +++ b/src/qml/newsqml/BlockUser.qml @@ -0,0 +1,52 @@ +// 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 + +Dialog { + id: userReportDialog + anchors.centerIn: parent + property var newsitem:({}) + title: qsTr("Block contact?") + + 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(); + } + onRejected: {close()} + Label {text: newsitem.user.name} +} diff --git a/src/qml/newsqml/ContactPage.qml b/src/qml/newsqml/ContactPage.qml new file mode 100644 index 0000000..4ac2b3a --- /dev/null +++ b/src/qml/newsqml/ContactPage.qml @@ -0,0 +1,405 @@ +// 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:/js/service.js" as Service +import "qrc:/qml/genericqml" + + +Page { + id:contactList + property var contact:({}) + property string profileimagesource:contact.profile_image + + 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 showConversation(conversationIndex,newsitemobject){ + xhr.setAccount(login); + if(newsitemobject.messagetype==0 || newsitemobject.messagetype==3){ + xhr.setApi("/api/conversation/show"); + xhr.setParam("id",newsitemobject.id) + xhr.get(); + } + else{ + xhr.setApi("/api/direct_messages/conversation"); + xhr.setParam("uri",newsitemobject.statusnet_conversation_id) + xhr.get(); + } + } + + 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) + } + } + + ListView { + id: contactView + x:mm + y:4*root.fontFactor*osSettings.bigFontSize + width: contactList.width-2*mm + height:contactList.height-7*root.fontFactor*osSettings.bigFontSize + clip: true + spacing: 0 + property string viewtype: "conversation" + header: contactHeader + model: contactModel + delegate: Newsitem{} + } + + BusyIndicator{ + id: contactBusy + anchors.centerIn:parent + width: 1.5*root.fontFactor*osSettings.bigFontSize + height: 1.5*root.fontFactor*osSettings.bigFontSize + running: true + } + + Component { id: contactHeader + Rectangle{ + border.color: osSettings.backgroundDimColor + border.width: 1 + 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 + property var createdAtDate: new Date(contact.created_at) + + Image { + id: profileImage + x:mm + y:mm + 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:/assets/defaultcontact.jpg"} + Connections{ + target:contactList + 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 + y: mm + spacing:4 + + // 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(); + // } + // } + + MButton{ + id:dmbutton + visible: (contact.following=="true") + text: qsTr("Direct Message") + display: AbstractButton.IconOnly + icon.name: "mail-message" + icon.source: "qrc:/assets/icons/envelope.svg" + onClicked:{ + rootstackSignal(0); + sendmessageSignal("directmessage",{id:"",user:{screen_name:contact.screen_name}}) + } + } + + // 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")&&!contact.searchContact) + width: implicitWidth + text:qsTr("Approve") + onClicked:{ + 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() + } + } + MButton{ + id:rejectbutton + visible:(contact.hasOwnProperty("acct")&&!contact.searchContact) + width: implicitWidth + text:qsTr("Reject") + onClicked:{ + 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() + } + } + MButton{ + id:ignorebutton + visible:(contact.hasOwnProperty("acct")&&!contact.searchContact) + width: implicitWidth + text:qsTr("Ignore") + onClicked:{ + 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 + 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 + 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 + anchors.margins: mm + anchors.left: contactView.width<35*root.fontFactor*osSettings.systemFontSize?contactView.left:profileImage.right + } + Text{ + id:detailtext + anchors.top: namelabel.bottom + anchors.left: contactView.width<35*root.fontFactor*osSettings.systemFontSize?contactView.left:profileImage.right + anchors.margins: 2*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 + 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+"
"+ + ""+qsTr("Created at")+": "+createdAtDate.toLocaleString(Qt.locale())+"
"+ + ""+qsTr("Followers")+": "+contact.followers_count+"
"+ + ""+qsTr("Following")+": "+contact.friends_count+"
" + onLinkActivated: { + Qt.openUrlExternally(link)} + } + } + }//Component end + + 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);} + contactBusy.running=false; + } + function onSuccess(data,api){ + 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].friendica_author.profile_image_url_large} + contactBusy.running=false; + var currentTime= new Date(); + var msg = {'currentTime': currentTime, 'model': contactModel,'news':root.contactposts, 'options':globaloptions, 'method':'contact'}; + contactWorker.sendMessage(msg) + } + } + + ListModel{id: contactModel} + + WorkerScript { + id: contactWorker + source: "qrc:/js/newsworker.js" + } + + MButton { + id: closeButton + anchors.top: parent.top + anchors.topMargin: 0.5*root.fontFactor*osSettings.bigFontSize + anchors.right: parent.right + anchors.rightMargin: 1*mm + 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() + } + } + Component.onCompleted: { + xhr.setAccount(login); + xhr.setApi("/api/statuses/user_timeline") + xhr.setParam("user_id",contact.id) + xhr.get(); + } +} diff --git a/source-linux/qml/newsqml/NewsTab.qml b/src/qml/newsqml/Conversation.qml similarity index 54% rename from source-linux/qml/newsqml/NewsTab.qml rename to src/qml/newsqml/Conversation.qml index ec7c8fa..65fc382 100644 --- a/source-linux/qml/newsqml/NewsTab.qml +++ b/src/qml/newsqml/Conversation.qml @@ -29,44 +29,15 @@ // 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 2.3 -//import QtQuick.Dialogs 1.3 +// ConversationView with button +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import "qrc:/qml/genericqml" import "qrc:/qml/newsqml" -import "qrc:/js/news.js" as Newsjs -import "qrc:/js/helper.js" as Helperjs -import "qrc:/js/service.js" as Service -Item { - - onHeightChanged: {newsSwipeview.height=height-6*mm} - Timer {id:contacttimer; interval: 50; running: false; repeat: false - onTriggered: { - // downloadNotice.text=downloadNotice.text + "\n contactTimer start "+ Date.now() - root.newContacts=Newsjs.findNewContacts(root.news,root.contactlist); - Newsjs.storeNews(login,db,root.news,root) - } - } - - function 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.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(); - } - } +Page { + id:conversationList + property var news:[] function getDateDiffString (seconds){ var timestring=""; @@ -112,96 +83,81 @@ Item { 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(); + } - function onFriendsMessages(friend){ - newstab.newstabstatus="Contact" - Newsjs.newsfromdb(db,root.login.username, 0,function(dbnews){ - if (dbnews.length==0){ - Newsjs.newsfromdb(db,login.username,0,function(forumnews){ - showNews(forumnews) - },friend.url) + ListView { + id: conversationView + property string viewtype: "conversation" + width: conversationList.width + height:conversationList.height-2*root.fontFactor*osSettings.bigFontSize + clip: true + spacing: 0 + ScrollBar.vertical: ScrollBar { } + model: conversationModel + delegate: Newsitem{} + } + BusyIndicator{ + id: conversationBusy + anchors.horizontalCenter: conversationView.horizontalCenter + anchors.top:conversationView.top + anchors.topMargin: mm + width: 2*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + running: true + } + + Connections{ + 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':root.conversation, 'method':'conversation', 'options':globaloptions}; + conversationWorker.sendMessage(msg) + //} + } + } + + ListModel{id: conversationModel} + + WorkerScript { + id: conversationWorker + source: "qrc:/js/newsworker.js" + } + + MButton { + id: closeButton + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + 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: { + root.conversation=[]; + if (rootstackView.depth>1){ rootstackView.pop()} } - else showNews(dbnews) - },friend.id) } - Label{ - text:"\uf0c9 " - font.pixelSize: 5* mm - anchors.left: parent.left - anchors.margins: mm - color: "#B0BEC5" - MouseArea{ - anchors.fill: parent - onClicked:{ - leftDrawer.open() - } - } + Component.onCompleted: { + if (news.length>0){var currentTime= new Date(); + var msg = {'currentTime': currentTime, 'model': conversationModel,'news':news,'method':'conversation', 'options':globaloptions}; + conversationWorker.sendMessage(msg)} } - Label{ - text:qsTr(newsSwipeview.stacktype) - font.pixelSize: 3* mm - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: 2*mm - } - SwipeView{ - id: newsSwipeview - property string stacktype:"Home" - currentIndex: 0 - width: parent.width - height: parent.height-6*mm - y: 5*mm - function onDirectMessage(friend){currentIndex=2} - transitions: Transition { - PropertyAnimation { properties: "height"; - easing.type: Easing.InOutQuad - duration: 1000 - } - } - - 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" - } - Component.onCompleted: {root.directmessageSignal.connect(onDirectMessage)} - } - - PageIndicator { - id: swipeIndicator - count: newsSwipeview.count - currentIndex: newsSwipeview.currentIndex - - anchors.bottom: newsSwipeview.bottom - anchors.horizontalCenter: parent.horizontalCenter - } - } diff --git a/source-linux/qml/newsqml/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 f39063e..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,51 +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.pixelSize: 3*mm - 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)} } - }} + } + } - BlueButton { - id: closeButton - //width:10*mm - 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() - } + 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: { + activitiesRectangle.destroy() + } } Component.onCompleted: { diff --git a/source-linux/qml/newsqml/Hashtag.qml b/src/qml/newsqml/Hashtag.qml similarity index 86% rename from source-linux/qml/newsqml/Hashtag.qml rename to src/qml/newsqml/Hashtag.qml index 711a10c..28aa64c 100644 --- a/source-linux/qml/newsqml/Hashtag.qml +++ b/src/qml/newsqml/Hashtag.qml @@ -29,23 +29,24 @@ // 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 } MouseArea{ anchors.fill: parent - onClicked:{search(hashtagText.text.replace("#",""))} + onClicked:{root.searchSignal(hashtagText.text.replace("#",""))} } } 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 89% rename from source-linux/qml/newsqml/MoreComments.qml rename to src/qml/newsqml/MoreComments.qml index d7b8d86..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,9 +47,8 @@ Rectangle{ anchors.margins: mm width: contentWidth height: contentHeight - font.family:fontAwesome.name - //font.pixelSize: 3*mm - 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 65% rename from source-linux/qml/newsqml/NewsImage.qml rename to src/qml/newsqml/NewsImage.qml index ebfe6f9..c3a76c6 100644 --- a/source-linux/qml/newsqml/NewsImage.qml +++ b/src/qml/newsqml/NewsImage.qml @@ -29,22 +29,33 @@ // 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; - property string mimetype:"" + cache:false + smooth: false + //property string mimetype:"" fillMode: Image.PreserveAspectFit; - onStatusChanged: playing = (status == AnimatedImage.Ready); + onStatusChanged: {playing = (status == AnimatedImage.Ready)} + Rectangle{ + visible: (model.newsitemobject.imageAttachmentList.length>1)&&(gif.status==Image.Ready) + opacity: 0.5 + color: "black" + width:imageCountText.contentWidth+mm + height: imageCountText.contentHeight+mm + x: (gif.width-gif.paintedWidth)/2+gif.paintedWidth-width + anchors.bottom: parent.bottom + Text { + anchors.centerIn: parent + id: imageCountText + text: "+ " + (model.newsitemobject.imageAttachmentList.length-1).toString() + color: "white" + } + } MouseArea {anchors.fill:parent; onClicked:{ - if (mimetype!="image/gif"){ - var attachcomponent = Qt.createQmlObject('import QtQuick 2.0; '+ - 'Rectangle{id:recfullscreen;color:"white";width:root.width;height:root.height;'+ - 'MouseArea {anchors.fill:parent;onClicked:{recfullscreen.destroy()}}'+ - 'AnimatedImage {id:giffullscreen;source: "'+gif.source+ - '";anchors.centerIn:parent; width:root.width;height:root.height;fillMode: Image.PreserveAspectFit; onStatusChanged: playing = (status == AnimatedImage.Ready);'+ - '}}',root,"Attachmentlarge") - } + rootstackView.push("qrc:/qml/newsqml/NewsPhotolist.qml",{"photolistarray": model.newsitemobject.imageAttachmentList}) + //roottoolbar.visible=false } } } diff --git a/src/qml/newsqml/NewsPhotolist.qml b/src/qml/newsqml/NewsPhotolist.qml new file mode 100644 index 0000000..831ecd4 --- /dev/null +++ b/src/qml/newsqml/NewsPhotolist.qml @@ -0,0 +1,150 @@ +// 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" + +Page{ + id:photolistview + width:root.width; + height:root.height + property var photolistarray: [] + + Rectangle{ + anchors.fill: newsphotolistView + color: "black" + } + ListView{ + id: newsphotolistView + anchors.fill: parent + orientation: Qt.Horizontal + highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem + spacing: root.fontFactor*osSettings.systemFontSize + model:photolistModel + delegate: photoWrapper + } + + ListModel{ + id: photolistModel + } + + MButton { + id: closeButton + z:2 + anchors.top: parent.top + anchors.topMargin: 1*mm + anchors.right: parent.right + anchors.rightMargin: 1*mm + 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 { + id: photoWrapper + + AnimatedImage { + id: realImage; + width: photolistview.width; height: photolistview.height + antialiasing: true; + asynchronous: true + autoTransform:true + cache: false + fillMode: Image.PreserveAspectFit; + onStatusChanged: playing = (status == AnimatedImage.Ready); + source: url + BusyIndicator{ + 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 + } + } + + + } + + + 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 + display: AbstractButton.IconOnly + icon.name: "arrow-left" + icon.source: "qrc:/assets/icons/angle-left.svg" + onClicked: {newsphotolistView.currentIndex=newsphotolistView.currentIndex-1} + } + + 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 + display: AbstractButton.IconOnly + icon.name: "arrow-right" + icon.source: "qrc:/assets/icons/angle-right.svg" + onClicked: {newsphotolistView.currentIndex=newsphotolistView.currentIndex+1} + } + + Component.onCompleted: { + if (photolistarray.length>0){ + photolistarray.forEach(function(photo){ + photolistModel.append(photo) + }) + } + } + //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/configqml/RegisterPage.qml b/src/qml/newsqml/NewsTabbutton.qml similarity index 63% rename from source-linux/qml/configqml/RegisterPage.qml rename to src/qml/newsqml/NewsTabbutton.qml index 3dcbc8d..d8c6e14 100644 --- a/source-linux/qml/configqml/RegisterPage.qml +++ b/src/qml/newsqml/NewsTabbutton.qml @@ -29,39 +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.Controls 2.12 -import QtWebView 1.1 -import "qrc:/qml/genericqml" +import QtQuick 6.3 +import QtQuick.Controls 6.3 -Rectangle{ - color:"white" - //border.color: "light grey" - property alias url:htmlview.url -// width:root.width-5*mm -// height:root.height-12*mm - - WebView {id:htmlview; - height:parent.height-7*mm - width:parent.width - y:7*mm -// MouseArea { -// anchors.fill:parent; -// onClicked:{ -// //print(url) -// } -// } - //onLoadingChanged: print(loadProgress) - } - Button{ - id:closeButton - height:6*mm - anchors.top: parent.top - anchors.topMargin: 1*mm - anchors.right: parent.right - anchors.rightMargin: 1*mm - text: "\uf057" - font.pixelSize: 3*mm - onClicked:{root.pop()} - } +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/OSSettingsAndroid.qml b/src/qml/newsqml/NewsVideo.qml similarity index 72% rename from source-linux/qml/configqml/OSSettingsAndroid.qml rename to src/qml/newsqml/NewsVideo.qml index 4ef254d..7a72ccc 100644 --- a/source-linux/qml/configqml/OSSettingsAndroid.qml +++ b/src/qml/newsqml/NewsVideo.qml @@ -29,16 +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 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 string imagePickQml: "ImagePicker" - property string imagePicker:'import QtQuick 2.0; import "qrc:/qml/genericqml";'+ - imagePickQml+'{multiple : true;onReady: {attachImageURLs.push(imageUrl);'+ - 'attachImage(imageUrl)}}' +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/src/qml/newsqml/NewsVideoLarge.qml b/src/qml/newsqml/NewsVideoLarge.qml new file mode 100644 index 0000000..8f84683 --- /dev/null +++ b/src/qml/newsqml/NewsVideoLarge.qml @@ -0,0 +1,140 @@ +// 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 QtMultimedia 6.3 +import QtQuick 6.3 +import QtQuick.Controls 6.3 +import "qrc:/qml/genericqml" + +Page{ + id:newsvideofullscreen + width:root.width; + height:root.height-3*root.fontFactor*osSettings.bigFontSize + property alias source: video.source + property string mimetype:"" + + Rectangle{ + anchors.fill: newsvideofullscreen + color: "black" + } + + Text{ + id:noticeText + text:"" + color:"light grey" + width:parent.width/2 + wrapMode: Text.Wrap + font.pointSize: osSettings.bigFontSize + x:parent.width/2-parent.height/4 + y:parent.height/5 + visible: video.playbackState!=MediaPlayer.PlayingState + } + + MediaPlayer { + id: video + audioOutput: AudioOutput {} + videoOutput: videoOutput + Component.onCompleted: {play()} + onErrorChanged: {noticeText.text=errorString;Qt.openUrlExternally(source)} + } + + 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-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 + 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/src/qml/newsqml/Newsitem.qml b/src/qml/newsqml/Newsitem.qml new file mode 100644 index 0000000..91f2044 --- /dev/null +++ b/src/qml/newsqml/Newsitem.qml @@ -0,0 +1,509 @@ +// 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:/qml/genericqml" + +Item { + id: newsitem + 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: "" + property var friendica_activities_view: getActivitiesView(model.newsitemobject) + + onAttendingChanged: {attendLabel.visible=true; + attendLabel.text= qsTr("attending")+": "+ qsTr(attending)} + + signal replyto(string parent_id) + + function showActivityContacts(contacts){ + var component = Qt.createComponent("qrc:/qml/newsqml/FriendicaActivities.qml"); + var imagedialog = component.createObject(friendicaActivities,{"activitymembers": contacts}); + } + + function pushConversation(){ + //expectScreenUpdate=true; + showConversation(index,newsitemobject) + if (model.newsitemobject.hasOwnProperty("currentconversation")){ + rootstackView.push("qrc:/qml/newsqml/Conversation.qml",{"news": model.newsitemobject.currentconversation})} + else{rootstackView.push("qrc:/qml/newsqml/Conversation.qml")}; + } + + Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; + color: osSettings.backgroundDimColor + } + + Rectangle{ + width:newsitem.width + height:newsitem.height-1 + color: osSettings.backgroundColor + + Column { + 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 + height: Math.max(profileImage.height+mm,topFlow.implicitHeight+mm) + width: parent.width + MouseArea{ + anchors.fill: parent + onClicked:{ + showContact(newsitemobject.user)} + } + Image { + id:profileImage + source: ((newsitemobject.user.profile_image!="") && (typeof(newsitemobject.user.profile_image)=="string"))? "file://"+newsitemobject.user.profile_image : newsitemobject.user.profile_image_url + x:1 + y:1 + width: 2*root.fontFactor*osSettings.bigFontSize + height: 2*root.fontFactor*osSettings.bigFontSize + //radius:mm + onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/assets/defaultcontact.jpg"} + } + Flow{ + id:topFlow + spacing: 0.5*mm + width:parent.width-8*mm + anchors.left: profileImage.right + anchors.margins: mm + Label { + id:user_name + color: osSettings.primaryTextColor + width:parent.width + font.bold: true + font.pointSize: osSettings.systemFontSize + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + text: newsitemobject.user.name+" (@"+newsitemobject.user.screen_name+")"+newsitemobject.forumname + } + + Label { + id:messageTypeLabel + 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: osSettings.secondaryTextColor + font.pointSize: 0.6*osSettings.systemFontSize + horizontalAlignment: Label.AlignRight + text: " \u00B7 "+getDateDiffString(newsitemobject.dateDiff) + " " +qsTr("ago") + } + Label { + id:replytoLabel + color: osSettings.secondaryTextColor + font.pointSize: 0.6*osSettings.systemFontSize + font.family: "Noto Sans" + horizontalAlignment: Label.AlignRight + text: (newsitemobject.reply_user!=false&&typeof(newsitemobject.reply_user)!="undefined")?" \u00B7 "+qsTr("In reply to ")+newsitemobject.reply_user.screen_name:" " + } + } + } + + MouseArea{id: itemBody + width: toprow.width-2 + height: itemMessage.height + onClicked: {pushConversation()} + Text { + 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: implicitHeight + wrapMode: Text.Wrap + clip:true + 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"); + var imageQml = component.createObject(toprow,{"source":newsitemobject.imageAttachmentList[0].url}); + } + } + + if (newsitemobject.videoAttachmentList.length>0){ + var component = Qt.createComponent("qrc:/qml/newsqml/NewsVideo.qml"); + //var videoQml = component.createObject(messageColumn,{"source":newsitemobject.attachmentList[attachments].url,"mimetype":newsitemobject.attachmentList[attachments].mimetype}); + var videoQml = component.createObject(toprow,{"attachment":newsitemobject.videoAttachmentList[0]}); + } + + if (newsitemobject.hasOwnProperty("lastcomment")){ + var moreComponent = Qt.createComponent("qrc:/qml/newsqml/MoreComments.qml"); + var conversationQml = moreComponent.createObject(conversationColumn,{"comments":newsitemobject.newscount-1}); + + var commentComponent = Qt.createComponent("qrc:/qml/newsqml/Newsitem.qml"); + var conversationQml = commentComponent.createObject(conversationColumn,{"newsitemobject":newsitemobject.lastcomment}); + } + } + }} + + } + + Button{ + width: newsitem.width-2 + height:5*mm + 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 (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); + icon.name="arrow-down";icon.source="qrc:/assets/icons/chevron-down.svg"; + newsitem.ListView.view.positionViewAtIndex(index,ListView.Beginning); + } + } + } + + // Bottom row for activities + Flow{ + id:friendicaActivities + anchors.top:toprow.bottom + width:parent.width + spacing:mm + + Label{color: osSettings.secondaryTextColor + height:3.5*mm + font.pointSize: 0.75*osSettings.systemFontSize + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.likeText + MouseArea{ + anchors.fill: parent + onClicked: { showActivityContacts(newsitemobject.friendica_activities.like)} + } + } + Label{color: osSettings.secondaryTextColor + height:3.5*mm + font.pointSize: 0.75*osSettings.systemFontSize + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.dislikeText + MouseArea{ + anchors.fill: parent + onClicked: { showActivityContacts(newsitemobject.friendica_activities.dislike)} + } + } + Label{color: osSettings.secondaryTextColor + height:3.5*mm + font.pointSize: 0.75*osSettings.systemFontSize + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendyesText + MouseArea{ + anchors.fill: parent + onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendyes)} + }} + Label{color: osSettings.secondaryTextColor + height:3.5*mm + font.pointSize: 0.75*osSettings.systemFontSize + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendnoText + MouseArea{ + anchors.fill: parent + onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendno)} + } + } + Label{color: osSettings.secondaryTextColor + height:3.5*mm + font.pointSize: 0.75*osSettings.systemFontSize + text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendmaybeText + MouseArea{ + anchors.fill: parent + onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendmaybe)} + } + } + Label{ + id:attendLabel + color: osSettings.secondaryTextColor + height:3.5*mm + font.pointSize: 0.75*osSettings.systemFontSize + horizontalAlignment: Label.AlignRight + text: (newsitemobject.friendica_activities_view.self.attending)?(qsTr("Attending: ")+ qsTr(newsitemobject.friendica_activities_view.self.attending)):"" + } + } + + //Bottom row for buttons + Row{id:controlrow + anchors.top:friendicaActivities.bottom + height: 1.5*root.fontFactor*osSettings.bigFontSize + ToolButton{ + id:likeCheckbox + 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 + 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; + newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); + } + else{Newsjs.like(root.login,root.db,0,"like",newsitemobject.id,root); + newsitemobject.friendica_activities_view.self.liked=0; + newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); + }} + } + ToolButton{ + id: dislikeCheckbox + 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 + //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; + newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); + } + else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.id,root); + newsitemobject.friendica_activities_view.self.disliked=0; + newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); + }} + } + + ToolButton{ + //CheckBox { + id:favoritedCheckbox + visible:((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3)) + width: newsitem.width/5 + height: parent.height + 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(!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 + } + } + } + + ToolButton{ + id: reply + visible: (newsitemobject.messagetype!==2) + width: newsitem.width/5 + height: parent.height + 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()} + } + } + + Menu { + id:newsmenu + width: 10*root.fontFactor*osSettings.systemFontSize + delegate: MenuItem{ + contentItem: Text{ + font.pointSize: osSettings.systemFontSize + color: osSettings.secondaryTextColor + text: parent.text + } + } + onAboutToShow:{if(newsitemobject.hasOwnProperty("external_url")){ + insertAction(4,externalAction)} + } + Action { + text: qsTr("Repost") + onTriggered: { + Newsjs.retweetNews(root.login,db,newsitemobject.id,root,function(reply){ + Helperjs.showMessage("Repost",qsTr("Success!"),root) + }) + } + } + 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*root.fontFactor*osSettings.systemFontSize + delegate: MenuItem{ + contentItem: Text{ + font.pointSize: osSettings.systemFontSize + color: osSettings.secondaryTextColor + text: parent.text + } + } + Action{ + text:qsTr("yes") + onTriggered: {Newsjs.attend(root.login,db,"yes",newsitemobject.id,root,function(){ + model.newsitemobject.friendica_activities_view.self.attending="yes";attending="yes"}) + } + } + Action{text:qsTr("maybe") + onTriggered: {Newsjs.attend(root.login,db,"maybe",newsitemobject.id,root,function(){ + model.newsitemobject.friendica_activities_view.self.attending="maybe";attending="maybe"}) + } + } + Action{text:qsTr("no") + onTriggered: {Newsjs.attend(root.login,db,"no",newsitemobject.id,root,function(){ + model.newsitemobject.friendica_activities_view.self.attending="no";attending="no"})} + } + } + + Action { + text: qsTr("Delete") + onTriggered: { + Newsjs.deleteNews(root.login,root.db,newsitemobject.id,newsitemobject.messagetype,root,function(reply){ + var msg = {'deleteId': index, 'model': newsitem.ListView.view.model}; + newsWorker.sendMessage(msg); + }) + } + } + } + Column{ + id:conversationColumn + anchors.top:controlrow.bottom + 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/NewsYplayer.qml b/src/qml/newsqml/ReportUser.qml similarity index 55% rename from source-linux/qml/newsqml/NewsYplayer.qml rename to src/qml/newsqml/ReportUser.qml index 1702de0..2583785 100644 --- a/source-linux/qml/newsqml/NewsYplayer.qml +++ b/src/qml/newsqml/ReportUser.qml @@ -1,5 +1,3 @@ - - // This file is part of Friendiqa // https://git.friendi.ca/lubuwest/Friendiqa // Copyright (C) 2020 Marco R. @@ -31,48 +29,46 @@ // 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 6.3 +import QtQuick.Controls 6.3 import "qrc:/js/helper.js" as Helperjs -import QtWebView 1.1 -Rectangle{ - id:newsYplayer - color:"black" - width:root.width; - height:root.height - property string url:"" - property string ytcode:"" +Dialog { + id: userReportkDialog + anchors.centerIn: parent + property var newsitem:({}) + title: qsTr("Report contact?") - 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(); - //newsYplayer.destroy( - } - } + 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(); } + 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")] + } + + } + } diff --git a/src/qml/newsqml/SmileyDialog.qml b/src/qml/newsqml/SmileyDialog.qml new file mode 100644 index 0000000..613b696 --- /dev/null +++ b/src/qml/newsqml/SmileyDialog.qml @@ -0,0 +1,103 @@ +// 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 "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 72% rename from source-linux/qml/photoqml/ImageUploadDialog.qml rename to src/qml/photoqml/ImageUploadDialog.qml index 56a5a56..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))}; @@ -63,10 +62,9 @@ Rectangle{ } -function updateImage(){ - xhr.url= login.server + "/api/friendica/photo/update.json"; - xhr.setLogin(login.username+":"+Qt.atob(login.password)); - xhr.clearParams(); + function updateImage(){ + 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 @@ function updateImage(){ 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 @@ function updateImage(){ 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 @@ function updateImage(){ }else{ Imagejs.requestList(login,db, true,root,function(obj){ fotorectangle.newimages=obj; - imageDialog.destroy() + photoStack.pop() }) }} else{ @@ -118,8 +122,8 @@ function updateImage(){ anchors.right: parent.right anchors.rightMargin: 1*mm spacing:5*mm - Text{ - font.pixelSize: 3.5*mm + Label{ + font.pointSize: osSettings.bigFontSize font.bold: true text:qsTr("Upload to album") } @@ -132,129 +136,25 @@ function updateImage(){ // } // } - Button{ + MButton{ id:closeButton - height: 8*mm - text: "\uf057" - font.pixelSize: 3*mm - onClicked:{photoStack.pop(); - //imageDialog.destroy() - } + 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()} } } -// Text { -// text: qsTr("Album") -// x: 4*mm; y: 10*mm -// } - -// Text { -// text: qsTr("Image") -// x: 4*mm; y: 17*mm -// } - -// Text { -// text: qsTr("Description") -// x: 4*mm; y: 33*mm -// } - - ListView{ - id: imageUploadView - x:3*mm //23*mm - y:17*mm - width: imageDialog.width-5*mm //25*mm - height: root.width/2 //25*mm - model: imageUploadModel - delegate: imageDelegate - footer: imageId==""?imageFooter:null - clip:true - orientation: ListView.Horizontal - spacing: mm - } - BusyIndicator{ - id: uploadBusy - running: false - anchors.horizontalCenter: imageUploadView.horizontalCenter - anchors.top:imageUploadView.top - anchors.topMargin: 2*mm - width:10*mm - height: 10*mm - } - ListModel{ - id: imageUploadModel - } - - Component{ - id: imageDelegate - Rectangle{ - width:root.width/2 //Math.max(20*mm,descriptionInput.contentWidth) - height:imageUploadView.height-5*mm // 20*mm - Image{ - id: uploadImage - width: root.width/2-mm //20*mm - height: imageUploadView.height-6*mm//height: 14*mm - fillMode: Image.PreserveAspectFit - source:imageUrl - onVisibleChanged: descriptionInput.focus=true; - MouseArea{ - anchors.fill: parent - onClicked:{ - imageUploadModel.remove(index) -// attachImageURLs.splice(attachImageURLs.indexOf(imageUrl,1)) -// attachImage(imageUrl) - } - } - } - - Rectangle{ - color: "light grey" - border.color: "grey" - anchors.top: uploadImage.bottom - anchors.topMargin: mm - //x: mm; y: 15*mm; - width: root.width/2-mm //Math.max(root.width/2-mm, descriptionInput.contentWidth); - height: 5*mm; - TextField{ - //TextInput { - id: descriptionInput - anchors.fill: parent - font.pixelSize: 3*mm - selectByMouse: true - placeholderText: qsTr("Description") - text:description!=""?description:"" - onTextChanged: imageUploadModel.set(index,{"description":descriptionInput.text}); - } - } - } - } - 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() - } - } - } - } ComboBox{ id: album x: 3*mm - y: 10*mm + y: 3*root.fontFactor*osSettings.bigFontSize width: root.width/2; - height: 5*mm; - font.pixelSize: 3*mm + height: 2.5*root.fontFactor*osSettings.bigFontSize//5*mm; + font.pointSize: osSettings.bigFontSize editable:true model: albumModel @@ -279,15 +179,135 @@ function updateImage(){ } ListModel{id:albumModel} +// Text { +// text: qsTr("Album") +// x: 4*mm; y: 10*mm +// } + +// Text { +// text: qsTr("Image") +// x: 4*mm; y: 17*mm +// } + +// Text { +// text: qsTr("Description") +// x: 4*mm; y: 33*mm +// } + + ListView{ + id: imageUploadView + x:3*mm //23*mm + y: 11*mm + album.height + width: imageDialog.width-5*mm //25*mm + height: parent.height -(12*root.fontFactor*osSettings.bigFontSize)//root.width/2 //25*mm + model: imageUploadModel + delegate: imageDelegate + footer: imageId==""?imageFooter:null + clip:true + orientation: ListView.Horizontal + spacing: mm + DropArea{ + anchors.fill: parent + onDropped: { + if (drop.keys.includes('text/uri-list')){ + var urllist=drop.text.split('\n'); + for(var i=0;i< urllist.length;i++){ + var droptext = urllist[i].replace(/(\r\n|\n|\r)/gm, ""); + attachImage(droptext) + } + } + } + } + } + + BusyIndicator{ + id: uploadBusy + running: false + anchors.horizontalCenter: imageUploadView.horizontalCenter + anchors.top:imageUploadView.top + anchors.topMargin: 2*mm + width:10*mm + height: 10*mm + } + + ListModel{ + id: imageUploadModel + } + + Component{ + id: imageDelegate + Rectangle{ + width:root.width/2 //Math.max(20*mm,descriptionInput.contentWidth) + height:imageUploadView.height-3*root.fontFactor*osSettings.bigFontSize// 20*mm + color: osSettings.backgroundColor + Image{ + id: uploadImage + width: root.width/2-mm //20*mm + height: imageUploadView.height-(3*root.fontFactor*osSettings.bigFontSize+2*mm) + fillMode: Image.PreserveAspectFit + source:imageUrl + onVisibleChanged: descriptionInput.focus=true; + MouseArea{ + anchors.fill: parent + onClicked:{ + imageUploadModel.remove(index) +// attachImageURLs.splice(attachImageURLs.indexOf(imageUrl,1)) +// attachImage(imageUrl) + } + } + } + + Rectangle{ + color: osSettings.backgroundColor + border.color: "grey" + anchors.top: uploadImage.bottom + anchors.topMargin: mm + //x: mm; y: 15*mm; + width: root.width/2-mm //Math.max(root.width/2-mm, descriptionInput.contentWidth); + height: 2.5*root.fontFactor*osSettings.bigFontSize +2*mm //5*mm; + TextField{ + //TextInput { + id: descriptionInput + anchors.fill: parent + anchors.margins: mm + font.pointSize: osSettings.systemFontSize + selectByMouse: true + placeholderText: qsTr("Description") + text:description!=""?description:"" + onTextChanged: imageUploadModel.set(index,{"description":descriptionInput.text}); + } + } + } + } + Component{ + id: imageFooter + 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()} + } + } + Button{ id:uploadButton - height: 8*mm - x:4*mm; y:root.width/2+18*mm //40*mm + height: 2*root.fontFactor*osSettings.bigFontSize + x:4*mm; + anchors.top:imageUploadView.bottom + anchors.topMargin: mm + //y:root.width/2+18*mm //40*mm text: imageId==""?qsTr("Upload"):qsTr("Change") - font.pixelSize: 3*mm + 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 dd3e95c..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 { @@ -78,13 +78,13 @@ Package { width:15*mm anchors.bottom: photoWrapper.bottom color: "white" - font.pixelSize: 2*mm + font.pointSize: osSettings.systemFontSize wrapMode:Text.Wrap } 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 80% rename from source-linux/qml/photoqml/PhotogroupComponent.qml rename to src/qml/photoqml/PhotogroupComponent.qml index eb948f4..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 @@ -93,7 +93,7 @@ Package { wrapMode:Text.Wrap color: "white" font.family: "Monospace" - font.pixelSize: 2*mm + font.pointSize: osSettings.systemFontSize anchors.bottom: albumWrapper.bottom } @@ -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 + + + Error + Fehler + + + Nicknames containing @ symbol currently not supported + Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. + + + Confirm + Bestätigen + + + No server given! + Kein Server angegeben! + + + No nickname given! + Kein Kurzname angegeben! + + + No password given! + Kein Passwort angegeben! + + + No image directory given! + Kein Verzeichnis für Bilder angegeben! + + + Wrong password! + Falsches Passwort! + + + Success + Bestätigt + + + Name + Name + + + Timeline + Chronologisch + + + Conversations + Unterhaltungen + + + 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 + + + Server + Server + + + Nickname + Kurzname + + + Password + Passwort + + + Image dir. + Bildverz. + + + Max. News + Max. Nachr. + + + News as + Anzeige + + + Interval (0=None) + Intervall (0=keins) + + + Error + Fehler + + + Nickname not registered at given server! + Name auf der Seite nicht registriert! + + + Confirm + Bestätigen + + + No server given! + Kein Server angegeben! + + + No nickname given! + Kein Kurzname angegeben! + + + Nickname not registered at given server! + Name auf der Seite nicht registriert! + + + No username given! + Kein Nutzername angegeben! + + + Sync Interval (0=None) + Akt.-intervall (0=keine) + + + Nicknames containing @ symbol currently not supported + Kurznamen mit @ Zeichen werden derzeit nicht unterstützt. + + + Min. + Min. + + + No password given! + Kein Passwort angegeben! + + + No image directory given! + Kein Verzeichnis für Bilder angegeben! + + + No maximum news number given! + Maximale News-Anzahl nicht angegeben! + + + Wrong password! + Falsches Passwort! + + + Success + Bestätigt + + + Name + Name + + + Timeline + Chronologisch + + + Conversations + Unterhaltungen + + + + ContactComponent + + Connect + Kontaktanfrage + + + + ContactDetailsComponent + + Connect + Kontaktanfrage + + + Description + Beschreibung + + + Location + Ort + + + Posts + Beiträge + + + URL + Profilseite + + + Created at + 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 + + + + 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 + + + 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 + + + + GroupComponent + + Error + Fehler + + + No name given + Kein Name angegeben + + + Close + Schließen + + + Members + Mitglieder + + + + GroupsListTab + + refresh + Aktualisieren + + + + ImageUploadDialog + + Upload to album + In Album hochladen + + + Album + Album + + + Image + 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 + + + More + Mehr + + + Timeline + Chronologisch + + + Error + Fehler + + + Favorites + Markierte News + + + Conversations + Unterhaltungen + + + Network Error + Netzwerk-Fehler + + + Replies + Interaktionen + + + Public timeline + Gemeinschaft + + + Direct Messages + Direktnachrichten + + + Notifications + Meldungen + + + Group news + News Gruppe + + + Quit + 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 + + + Source: + Quelle: + + + Direct Message + Direktnachricht + + + In reply to + Antwort an + + + comments + 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 + + + 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. + + + + SyncConfig + + Sync Interval (0=None) + Akt.-intervall (0=keine) + + + Min. + Min. + + + Backgound Sync + Hintergrund-Aktualisierung + + + + friendiqa + + Refresh + Aktualisieren + + + Timeline + Chronologisch + + + Conversations + Unterhaltungen + + + Favorites + Markierte News + + + Replies + Interaktionen + + + Public Timeline + öff. Timeline + + + Group news + News Gruppe + + + Search + Suche + + + Settings + Einstellungen + + + Accounts + Konten + + + Quit + Schliessen + + + 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. + + + like this. + mögen das. + + + doesn't like this. + mag das nicht. + + + don't like this. + mögen das nicht. + + + will attend. + nehmen teil. + + + persons will attend. + Personen nehmen teil. + + + will not attend. + nimmt nicht teil. + + + persons will not attend. + Personen nehmen nicht teil. + + + may attend. + nimmt vielleicht teil. + + + persons may attend. + Personen nehmen vielleicht teil. + + + yes + ja + + + no + nein + + + maybe + vielleicht + + + seconds + Sekunden + + + ago + her + + + minute + Minute + + + minutes + Minuten + + + hour + Stunde + + + hours + Stunden + + + day + Tag + + + days + Tage + + + month + Monat + + + months + Monate + + + years + Jahre + + + + service + + Error + Fehler + + + Changelog + Ä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. + + + 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. + + + +