Compare commits
No commits in common. "master" and "tdlib17" have entirely different histories.
102
.github/workflows/main.yml
vendored
|
@ -1,102 +0,0 @@
|
||||||
name: Fernschreiber build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
# to prevent secrets leaking,
|
|
||||||
# we don't build on PRs
|
|
||||||
#pull_request:
|
|
||||||
# branches:
|
|
||||||
# - master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: 'true'
|
|
||||||
|
|
||||||
- name: Prepare
|
|
||||||
run: mkdir output
|
|
||||||
|
|
||||||
- name: Fetch TDLib
|
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
|
||||||
with:
|
|
||||||
repo: "Wunderfitz/td"
|
|
||||||
file: "tdlib.zip"
|
|
||||||
target: tdlib/tdlib.zip
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Decompress TDLib
|
|
||||||
uses: TonyBogdanov/zip@1.0
|
|
||||||
with:
|
|
||||||
args: unzip -qq ./tdlib/tdlib.zip -d ./tdlib
|
|
||||||
|
|
||||||
- name: Set Secrets
|
|
||||||
uses: DamianReeves/write-file-action@master
|
|
||||||
with:
|
|
||||||
path: ./src/tdlibsecrets.h
|
|
||||||
contents: |
|
|
||||||
#ifndef TDLIBSECRETS_H
|
|
||||||
#define TDLIBSECRETS_H
|
|
||||||
const char TDLIB_API_ID[] = "${{secrets.TDLIB_API_ID}}";
|
|
||||||
const char TDLIB_API_HASH[] = "${{secrets.TDLIB_API_HASH}}";
|
|
||||||
#endif // TDLIBSECRETS_H
|
|
||||||
write-mode: overwrite
|
|
||||||
|
|
||||||
- name: Build armv7hl
|
|
||||||
id: build_armv7hl
|
|
||||||
uses: coderus/github-sfos-build@master
|
|
||||||
with:
|
|
||||||
release: 4.4.0.58
|
|
||||||
|
|
||||||
- name: Build i486
|
|
||||||
id: build_i486
|
|
||||||
uses: coderus/github-sfos-build@master
|
|
||||||
with:
|
|
||||||
release: 4.4.0.58
|
|
||||||
arch: i486
|
|
||||||
|
|
||||||
- name: Build aarch64
|
|
||||||
id: build_aarch64
|
|
||||||
uses: coderus/github-sfos-build@master
|
|
||||||
with:
|
|
||||||
release: 4.4.0.58
|
|
||||||
arch: aarch64
|
|
||||||
|
|
||||||
- name: Upload build result
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: rpm-build-result
|
|
||||||
path: RPMS
|
|
||||||
|
|
||||||
- name: Create release
|
|
||||||
if: contains(github.ref, 'v')
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
assets=()
|
|
||||||
for asset in RPMS/*.rpm; do
|
|
||||||
assets+=("-a" "$asset")
|
|
||||||
done
|
|
||||||
tag_name="${GITHUB_REF##*/}"
|
|
||||||
gh release create "$tag_name" "${assets[@]}"
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Create prerelease
|
|
||||||
if: contains(github.ref, 'pre')
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
assets=()
|
|
||||||
for asset in RPMS/*.rpm; do
|
|
||||||
assets+=("-a" "$asset")
|
|
||||||
done
|
|
||||||
tag_name="${GITHUB_REF##*/}"
|
|
||||||
gh release create "$tag_name" -p -n "This is a pre-release for testing purposes only. It may or may not be unstable." "${assets[@]}"
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
3
.gitignore
vendored
|
@ -53,6 +53,3 @@ compile_commands.json
|
||||||
|
|
||||||
# TDLib API Secrets
|
# TDLib API Secrets
|
||||||
tdlibsecrets.h
|
tdlibsecrets.h
|
||||||
|
|
||||||
#Convinience scripts
|
|
||||||
*.sh
|
|
||||||
|
|
45
README.md
|
@ -1,7 +1,6 @@
|
||||||
# Fernschreiber
|
# Fernschreiber
|
||||||
A Telegram client for Sailfish OS
|
A Telegram client for Sailfish OS
|
||||||
|
|
||||||
[![Fernschreiber build](https://github.com/Wunderfitz/harbour-fernschreiber/actions/workflows/main.yml/badge.svg)](https://github.com/Wunderfitz/harbour-fernschreiber/actions/workflows/main.yml)
|
|
||||||
## Authors
|
## Authors
|
||||||
Sebastian J. Wolf [sebastian@ygriega.de](mailto:sebastian@ygriega.de) and several contributors
|
Sebastian J. Wolf [sebastian@ygriega.de](mailto:sebastian@ygriega.de) and several contributors
|
||||||
|
|
||||||
|
@ -11,27 +10,19 @@ Fernschreiber wouldn't be the same without all the people helping in making it b
|
||||||
|
|
||||||
### Code (Features, Bugfixes, Optimizations etc.)
|
### Code (Features, Bugfixes, Optimizations etc.)
|
||||||
- Chat list model, chat model, notifications, TDLib receiver, animated stickers, project dependencies, qml/c++ optimizations, chatPhoto, TDLibFile, code reviews, logging categories: [Slava Monich](https://github.com/monich)
|
- Chat list model, chat model, notifications, TDLib receiver, animated stickers, project dependencies, qml/c++ optimizations, chatPhoto, TDLibFile, code reviews, logging categories: [Slava Monich](https://github.com/monich)
|
||||||
- Chat info page, performance improvements to chat page, location support, app initialization/registration with Telegram, project dependencies, emoji handling, qml/js optimizations, multi-message actions, i18n fixes, chat permission handling, code reviews, logging categories, bot support, github build: [jgibbon](https://github.com/jgibbon)
|
- Chat info page, performance improvements to chat page, location support, app initialization/registration with Telegram, project dependencies, emoji handling, qml/js optimizations, multi-message actions, i18n fixes, chat permission handling, code reviews, logging categories: [jgibbon](https://github.com/jgibbon)
|
||||||
- Copy message to clipboard: [Christian Stemmle](https://github.com/chstem)
|
- Copy message to clipboard [Christian Stemmle](https://github.com/chstem)
|
||||||
- Hide send message button if send-by-enter is switched on, focus text input on entering a chat: [santhoshmanikandan](https://github.com/santhoshmanikandan)
|
|
||||||
- Integration of logout and sesison options to settings page, search results optimization, highlight unread conversations: [Peter G.](https://github.com/nephros)
|
|
||||||
- Option to always append last message in notifications: [Johannes Bachmann](https://github.com/dscheinah)
|
|
||||||
- Option to jump to quoted message, widescreen UI adjustments: [Mikhail Barashkov](https://github.com/mbarashkov)
|
|
||||||
|
|
||||||
This list might not be complete. In case I forgot something/somebody, please let me know or create a PR, thanks! :)
|
|
||||||
|
|
||||||
### Logo/Icon
|
### Logo/Icon
|
||||||
- Designed by [Matteo](https://github.com/iamnomeutente), adjustments by [Slava Monich](https://github.com/monich)
|
- Designed by [Matteo](https://github.com/iamnomeutente)
|
||||||
|
|
||||||
### Translations
|
### Translations
|
||||||
- Chinese: [dashinfantry](https://github.com/dashinfantry)
|
- Chinese: [dashinfantry](https://github.com/dashinfantry)
|
||||||
- Finnish: [jorm1s](https://github.com/jorm1s)
|
- Finnish: [jorm1s](https://github.com/jorm1s)
|
||||||
- French: [Patrick Hervieux](https://github.com/pherjung), [Nicolas Bourdais](https://github.com/nbourdais)
|
|
||||||
- Hungarian: [edp17](https://github.com/edp17)
|
- Hungarian: [edp17](https://github.com/edp17)
|
||||||
- Italian: [Matteo](https://github.com/iamnomeutente)
|
- Italian: [Matteo](https://github.com/iamnomeutente)
|
||||||
- Polish: [atlochowski](https://github.com/atlochowski)
|
- Polish: [atlochowski](https://github.com/atlochowski)
|
||||||
- Russian: [Rustem Abzalov](https://github.com/arustg) and [Slava Monich](https://github.com/monich)
|
- Russian: [Rustem Abzalov](https://github.com/arustg) and [Slava Monich](https://github.com/monich)
|
||||||
- Slovak: [okruhliak](https://github.com/okruhliak)
|
|
||||||
- Spanish: [carlosgonz](https://github.com/GNUuser)
|
- Spanish: [carlosgonz](https://github.com/GNUuser)
|
||||||
- Swedish: [Åke Engelbrektson](https://github.com/eson57)
|
- Swedish: [Åke Engelbrektson](https://github.com/eson57)
|
||||||
|
|
||||||
|
@ -39,7 +30,6 @@ This list might not be complete. In case I forgot something/somebody, please let
|
||||||
Licensed under GNU GPLv3
|
Licensed under GNU GPLv3
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
### Local build
|
|
||||||
Simply clone this repository and ensure to have all [submodules](https://git-scm.com/docs/git-submodule) imported as well (e.g. by using `git submodule update --init`). Then use the project file `harbour-fernschreiber.pro` to import the sources in your SailfishOS IDE. To build and run Fernschreiber or an application which is based on Fernschreiber, you need to create the file `harbour-fernschreiber/src/tdlibsecrets.h` and enter the required constants in the following format:
|
Simply clone this repository and ensure to have all [submodules](https://git-scm.com/docs/git-submodule) imported as well (e.g. by using `git submodule update --init`). Then use the project file `harbour-fernschreiber.pro` to import the sources in your SailfishOS IDE. To build and run Fernschreiber or an application which is based on Fernschreiber, you need to create the file `harbour-fernschreiber/src/tdlibsecrets.h` and enter the required constants in the following format:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -52,39 +42,15 @@ const char TDLIB_API_HASH[] = "1234567890abcdef1234567890abcdef";
|
||||||
|
|
||||||
You get the Telegram API ID and hash as soon as you've registered your own application on [https://my.telegram.org](https://my.telegram.org).
|
You get the Telegram API ID and hash as soon as you've registered your own application on [https://my.telegram.org](https://my.telegram.org).
|
||||||
|
|
||||||
Moreover, you need to have a compiled version of [TDLib 1.8.21](https://github.com/tdlib/td) or higher in the sub-directory `tdlib`. This sub-directory must contain another sub-directory that fits to the target device architecture (e.g. armv7hl, i486). Within this directory, there needs to be a folder called `lib` that contains at least `libtdjson.so`. For armv7hl the relative path would consequently be `tdlib/armv7hl/lib`.
|
Moreover, you need to have a compiled version of [TDLib 1.7](https://github.com/tdlib/td) in the sub-directory `tdlib`. This sub-directory must contain another sub-directory that fits to the target device architecture (e.g. armv7hl, i486). Within this directory, there needs to be a folder called `lib` that contains at least `libtdjson.so`. For armv7hl the relative path would consequently be `tdlib/armv7hl/lib`.
|
||||||
|
|
||||||
You may just want to download the [tdlib.zip from our fork](https://github.com/Wunderfitz/td/releases) to just use the exact version of the latest official Fernschreiber release. To use it, you need to extract it into your local `tdlib/` folder as described above. If so, you're done and can compile Fernschreiber using the Sailfish SDK. If you want to build TDLib for yourself, please keep on reading.
|
|
||||||
|
|
||||||
In case you want to use the same codebase which was used to compile the library that is shipped with Fernschreiber, please [check out the fork](https://github.com/Wunderfitz/td), be sure to use the branch `fernschreiber` and compile these sources using the following commands (be sure to have the Sailfish OS build engine running):
|
|
||||||
|
|
||||||
- `alias sfdk=~/SailfishOS/bin/sfdk`
|
|
||||||
- `sfdk config target=SailfishOS-4.4.0.58-armv7hl` (this compiles the sources on SFOS 4.4 and ARM - the target needs to be adjusted according to the running SDK engine and the platform)
|
|
||||||
- `mkdir build`
|
|
||||||
- `cd build`
|
|
||||||
- `sfdk build-init`
|
|
||||||
- `sfdk build-shell cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=../tdlib -DTD_ENABLE_LTO=ON ..` (in case of compilation issues, try removing the flag `-DTD_ENABLE_LTO=ON`)
|
|
||||||
- `sfdk build-shell cmake --build . --target install`
|
|
||||||
|
|
||||||
You'll find the compiled library in the directory `td/tdlib`.
|
|
||||||
|
|
||||||
### Github Action
|
|
||||||
Please read the "Local build" section anyway to understand what's going on before continuing. If you want to automatically build your fork on Github, you'll still need to get a Telegram API ID and hash. These are then [added as project secrets](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository) named `TDLIB_API_ID` and `TDLIB_API_HASH`.
|
|
||||||
|
|
||||||
By default, only commits to the master branch will be built. You may [change that for your fork](https://docs.github.com/en/actions/quickstart), but please don't create a pull request to the official repository changing the github action without consulting the [Fernschreiber contributors](https://github.com/Wunderfitz/harbour-fernschreiber/issues/162) first.
|
|
||||||
|
|
||||||
If you push a tag containing the letter "v" (for example "v0.99.3"), a github release will be created allowing easy download of the resulting rpms. If the tag is named for example "pre-0.99.3", the resulting release is marked as a pre-release for testing purposes.
|
|
||||||
|
|
||||||
|
In case you encounter strange performance issues on startup (several seconds delay, app seems to do nothing), please be sure to [follow the instructions from the respective GitHub issue](https://github.com/tdlib/td/issues/1322), i.e. let TDLib build SQLite with `-DOMIT_MEMLOCK` and be sure to comment the two lines 22558 (`#ifndef OMIT_MEMLOCK`) and 22567 (`#endif`) in the file `sqlite/sqlite/sqlite3.c`.
|
||||||
|
|
||||||
## Debug
|
## Debug
|
||||||
Fernschreiber does only output a few TDLib messages by default. To get its own debug log messages, you can either run a debug build to see all of them or use the environment variable `QT_LOGGING_RULES` to specify/filter which messages you'd like to see.
|
Fernschreiber does only output a few TDLib messages by default. To get its own debug log messages, you can either run a debug build to see all of them or use the environment variable `QT_LOGGING_RULES` to specify/filter which messages you'd like to see.
|
||||||
|
|
||||||
Run `QT_LOGGING_RULES="fernschreiber.*=true" harbour-fernschreiber` to see all messages or replace the `*` with specific logging categories. You'll find the logging category inside the corresponding `.cpp` file for backend usage or you can use `JS` to only see frontend messages.
|
Run `QT_LOGGING_RULES="fernschreiber.*=true" harbour-fernschreiber` to see all messages or replace the `*` with specific logging categories. You'll find the logging category inside the corresponding `.cpp` file for backend usage or you can use `JS` to only see frontend messages.
|
||||||
|
|
||||||
You can append ` &> fernschreiber.log` to the command to create a text file containing the debug messages.
|
|
||||||
|
|
||||||
**Please be aware that debug messages will most likely include personal information** including (but not limited to) chat content and user ids/names of yourself and all your chat partners. Do not share it publicly and, at your discretion, try to remove private info even from the parts you do share with a trusted person.
|
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
If you want to contribute bug fixes, improvements, new features etc. please create a pull request (PR). PRs are always welcome and will be reviewed as soon as possible, but may take some time. :)
|
If you want to contribute bug fixes, improvements, new features etc. please create a pull request (PR). PRs are always welcome and will be reviewed as soon as possible, but may take some time. :)
|
||||||
|
@ -96,6 +62,5 @@ This project uses
|
||||||
- The Telegram Database Library (TDLib) - available on [GitHub.com](https://github.com/tdlib/td). Thanks for making it available under the conditions of the Boost Software License 1.0! Details about the license of TDLib in [its license file](https://github.com/tdlib/td/blob/master/LICENSE_1_0.txt).
|
- The Telegram Database Library (TDLib) - available on [GitHub.com](https://github.com/tdlib/td). Thanks for making it available under the conditions of the Boost Software License 1.0! Details about the license of TDLib in [its license file](https://github.com/tdlib/td/blob/master/LICENSE_1_0.txt).
|
||||||
- Emoji parsing and artwork by [Twitter Emoji (Twemoji)](http://twitter.github.io/twemoji/), copyright 2018 Twitter, Inc and other contributors, Code licensed under the [MIT License](http://opensource.org/licenses/MIT), Graphics licensed under [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/)
|
- Emoji parsing and artwork by [Twitter Emoji (Twemoji)](http://twitter.github.io/twemoji/), copyright 2018 Twitter, Inc and other contributors, Code licensed under the [MIT License](http://opensource.org/licenses/MIT), Graphics licensed under [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/)
|
||||||
- Animated sticker parsing and animation by [rlottie](https://github.com/Samsung/rlottie), copyright 2020 Samsung Electronics Co., Ltd. and [other contributors](https://github.com/Samsung/rlottie/blob/master/AUTHORS), Code licensed under the [MIT License](https://github.com/Samsung/rlottie/blob/master/licenses/COPYING.MIT), some rlottie components [licensed under other licenses](https://github.com/Samsung/rlottie/blob/master/COPYING).
|
- Animated sticker parsing and animation by [rlottie](https://github.com/Samsung/rlottie), copyright 2020 Samsung Electronics Co., Ltd. and [other contributors](https://github.com/Samsung/rlottie/blob/master/AUTHORS), Code licensed under the [MIT License](https://github.com/Samsung/rlottie/blob/master/licenses/COPYING.MIT), some rlottie components [licensed under other licenses](https://github.com/Samsung/rlottie/blob/master/COPYING).
|
||||||
- Reverse geocoding for location attachments by [OpenStreetMap Nominatim](https://wiki.openstreetmap.org/wiki/Nominatim).
|
|
||||||
|
|
||||||
Thanks to the maintainers of the used components and - again - all contributors to Fernschreiber!
|
Thanks to the maintainers of the used components and - again - all contributors to Fernschreiber!
|
||||||
|
|
BIN
db/emojis.db
3288
doc/emojis.md
|
@ -4,8 +4,3 @@ X-Nemo-Application-Type=silica-qt5
|
||||||
Icon=harbour-fernschreiber
|
Icon=harbour-fernschreiber
|
||||||
Exec=harbour-fernschreiber
|
Exec=harbour-fernschreiber
|
||||||
Name=Fernschreiber
|
Name=Fernschreiber
|
||||||
|
|
||||||
[X-Sailjail]
|
|
||||||
Permissions=Audio;Documents;Downloads;Internet;Location;MediaIndexing;Microphone;Music;Pictures;PublicDir;RemovableMedia;UserDirs;Videos
|
|
||||||
OrganizationName=de.ygriega
|
|
||||||
ApplicationName=fernschreiber
|
|
||||||
|
|
|
@ -16,13 +16,12 @@ CONFIG += sailfishapp sailfishapp_i18n
|
||||||
|
|
||||||
PKGCONFIG += nemonotifications-qt5 zlib
|
PKGCONFIG += nemonotifications-qt5 zlib
|
||||||
|
|
||||||
QT += core dbus sql multimedia positioning
|
QT += core dbus sql
|
||||||
|
|
||||||
DEFINES += QT_STATICPLUGIN
|
DEFINES += QT_STATICPLUGIN
|
||||||
|
|
||||||
SOURCES += src/harbour-fernschreiber.cpp \
|
SOURCES += src/harbour-fernschreiber.cpp \
|
||||||
src/appsettings.cpp \
|
src/appsettings.cpp \
|
||||||
src/chatpermissionfiltermodel.cpp \
|
|
||||||
src/chatlistmodel.cpp \
|
src/chatlistmodel.cpp \
|
||||||
src/chatmodel.cpp \
|
src/chatmodel.cpp \
|
||||||
src/contactsmodel.cpp \
|
src/contactsmodel.cpp \
|
||||||
|
@ -39,89 +38,37 @@ SOURCES += src/harbour-fernschreiber.cpp \
|
||||||
src/tdlibfile.cpp \
|
src/tdlibfile.cpp \
|
||||||
src/tdlibreceiver.cpp \
|
src/tdlibreceiver.cpp \
|
||||||
src/tdlibwrapper.cpp \
|
src/tdlibwrapper.cpp \
|
||||||
src/textfiltermodel.cpp \
|
|
||||||
src/tgsplugin.cpp
|
src/tgsplugin.cpp
|
||||||
|
|
||||||
DISTFILES += qml/harbour-fernschreiber.qml \
|
DISTFILES += qml/harbour-fernschreiber.qml \
|
||||||
qml/components/AudioPreview.qml \
|
qml/components/AudioPreview.qml \
|
||||||
qml/components/BackgroundImage.qml \
|
qml/components/BackgroundImage.qml \
|
||||||
qml/components/ChatListViewItem.qml \
|
qml/components/ChatListViewItem.qml \
|
||||||
qml/components/ContactSync.qml \
|
|
||||||
qml/components/DocumentPreview.qml \
|
qml/components/DocumentPreview.qml \
|
||||||
qml/components/GamePreview.qml \
|
|
||||||
qml/components/ImagePreview.qml \
|
qml/components/ImagePreview.qml \
|
||||||
qml/components/InformationEditArea.qml \
|
|
||||||
qml/components/InformationTextItem.qml \
|
|
||||||
qml/components/InReplyToRow.qml \
|
qml/components/InReplyToRow.qml \
|
||||||
qml/components/InlineQuery.qml \
|
|
||||||
qml/components/LocationPreview.qml \
|
qml/components/LocationPreview.qml \
|
||||||
qml/components/MessageListViewItem.qml \
|
qml/components/MessageListViewItem.qml \
|
||||||
qml/components/MessageListViewItemSimple.qml \
|
qml/components/MessageListViewItemSimple.qml \
|
||||||
qml/components/MessageOverlayFlickable.qml \
|
qml/components/MessageOverlayFlickable.qml \
|
||||||
qml/components/MessageViaLabel.qml \
|
|
||||||
qml/components/MultilineEmojiLabel.qml \
|
|
||||||
qml/components/PinnedMessageItem.qml \
|
qml/components/PinnedMessageItem.qml \
|
||||||
qml/components/PollPreview.qml \
|
qml/components/PollPreview.qml \
|
||||||
qml/components/PressEffect.qml \
|
qml/components/PressEffect.qml \
|
||||||
qml/components/ProfilePictureList.qml \
|
|
||||||
qml/components/ReplyMarkupButtons.qml \
|
|
||||||
qml/components/StickerPicker.qml \
|
qml/components/StickerPicker.qml \
|
||||||
qml/components/PhotoTextsListItem.qml \
|
qml/components/PhotoTextsListItem.qml \
|
||||||
qml/components/StickerSetOverlay.qml \
|
qml/components/WebPagePreview.qml \
|
||||||
qml/components/TDLibImage.qml \
|
qml/components/chatInformationPage/ChatInformationEditArea.qml \
|
||||||
qml/components/TDLibMinithumbnail.qml \
|
|
||||||
qml/components/TDLibPhoto.qml \
|
|
||||||
qml/components/TDLibThumbnail.qml \
|
|
||||||
qml/components/VoiceNoteOverlay.qml \
|
|
||||||
qml/components/chatInformationPage/ChatInformationPageContent.qml \
|
qml/components/chatInformationPage/ChatInformationPageContent.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationProfilePicture.qml \
|
qml/components/chatInformationPage/ChatInformationProfilePicture.qml \
|
||||||
|
qml/components/chatInformationPage/ChatInformationProfilePictureList.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationTabItemBase.qml \
|
qml/components/chatInformationPage/ChatInformationTabItemBase.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationTabItemDebug.qml \
|
qml/components/chatInformationPage/ChatInformationTabItemDebug.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationTabItemMembersGroups.qml \
|
qml/components/chatInformationPage/ChatInformationTabItemMembersGroups.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationTabItemSettings.qml \
|
qml/components/chatInformationPage/ChatInformationTabItemSettings.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationTabView.qml \
|
qml/components/chatInformationPage/ChatInformationTabView.qml \
|
||||||
|
qml/components/chatInformationPage/ChatInformationTextItem.qml \
|
||||||
qml/components/chatInformationPage/EditGroupChatPermissionsColumn.qml \
|
qml/components/chatInformationPage/EditGroupChatPermissionsColumn.qml \
|
||||||
qml/components/chatInformationPage/EditSuperGroupSlowModeColumn.qml \
|
qml/components/chatInformationPage/EditSuperGroupSlowModeColumn.qml \
|
||||||
qml/components/inlineQueryResults/InlineQueryResult.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultAnimation.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultArticle.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultAudio.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultContact.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultDefaultBase.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultDocument.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultGame.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultLocation.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultPhoto.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultSticker.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultVenue.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultVideo.qml \
|
|
||||||
qml/components/inlineQueryResults/InlineQueryResultVoiceNote.qml \
|
|
||||||
qml/components/messageContent/MessageAnimatedEmoji.qml \
|
|
||||||
qml/components/messageContent/MessageAnimation.qml \
|
|
||||||
qml/components/messageContent/MessageAudio.qml \
|
|
||||||
qml/components/messageContent/MessageContentBase.qml \
|
|
||||||
qml/components/messageContent/MessageContentFileInfoBase.qml \
|
|
||||||
qml/components/messageContent/MessageDocument.qml \
|
|
||||||
qml/components/messageContent/MessageGame.qml \
|
|
||||||
qml/components/messageContent/MessageLocation.qml \
|
|
||||||
qml/components/messageContent/MessagePhoto.qml \
|
|
||||||
qml/components/messageContent/MessagePoll.qml \
|
|
||||||
qml/components/messageContent/MessageSticker.qml \
|
|
||||||
qml/components/messageContent/MessageVenue.qml \
|
|
||||||
qml/components/messageContent/MessageVideoNote.qml \
|
|
||||||
qml/components/messageContent/MessageVideo.qml \
|
|
||||||
qml/components/messageContent/MessageVoiceNote.qml \
|
|
||||||
qml/components/messageContent/SponsoredMessage.qml \
|
|
||||||
qml/components/messageContent/WebPagePreview.qml \
|
|
||||||
qml/components/settingsPage/Accordion.qml \
|
|
||||||
qml/components/settingsPage/AccordionItem.qml \
|
|
||||||
qml/components/settingsPage/ResponsiveGrid.qml \
|
|
||||||
qml/components/settingsPage/SettingsAppearance.qml \
|
|
||||||
qml/components/settingsPage/SettingsBehavior.qml \
|
|
||||||
qml/components/settingsPage/SettingsPrivacy.qml \
|
|
||||||
qml/components/settingsPage/SettingsSession.qml \
|
|
||||||
qml/components/settingsPage/SettingsStorage.qml \
|
|
||||||
qml/components/settingsPage/SettingsUserProfile.qml \
|
|
||||||
qml/js/debug.js \
|
qml/js/debug.js \
|
||||||
qml/js/functions.js \
|
qml/js/functions.js \
|
||||||
qml/pages/ChatInformationPage.qml \
|
qml/pages/ChatInformationPage.qml \
|
||||||
|
@ -135,11 +82,11 @@ DISTFILES += qml/harbour-fernschreiber.qml \
|
||||||
qml/pages/AboutPage.qml \
|
qml/pages/AboutPage.qml \
|
||||||
qml/pages/PollCreationPage.qml \
|
qml/pages/PollCreationPage.qml \
|
||||||
qml/pages/PollResultsPage.qml \
|
qml/pages/PollResultsPage.qml \
|
||||||
qml/pages/SearchChatsPage.qml \
|
|
||||||
qml/pages/SettingsPage.qml \
|
qml/pages/SettingsPage.qml \
|
||||||
qml/pages/VideoPage.qml \
|
qml/pages/VideoPage.qml \
|
||||||
rpm/harbour-fernschreiber.changes \
|
rpm/harbour-fernschreiber.changes \
|
||||||
rpm/harbour-fernschreiber.spec \
|
rpm/harbour-fernschreiber.spec \
|
||||||
|
rpm/harbour-fernschreiber.yaml \
|
||||||
translations/*.ts \
|
translations/*.ts \
|
||||||
harbour-fernschreiber.desktop
|
harbour-fernschreiber.desktop
|
||||||
|
|
||||||
|
@ -148,28 +95,19 @@ SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172 256x256
|
||||||
TRANSLATIONS += translations/harbour-fernschreiber-de.ts \
|
TRANSLATIONS += translations/harbour-fernschreiber-de.ts \
|
||||||
translations/harbour-fernschreiber-es.ts \
|
translations/harbour-fernschreiber-es.ts \
|
||||||
translations/harbour-fernschreiber-fi.ts \
|
translations/harbour-fernschreiber-fi.ts \
|
||||||
translations/harbour-fernschreiber-fr.ts \
|
|
||||||
translations/harbour-fernschreiber-hu.ts \
|
translations/harbour-fernschreiber-hu.ts \
|
||||||
translations/harbour-fernschreiber-it.ts \
|
translations/harbour-fernschreiber-it.ts \
|
||||||
translations/harbour-fernschreiber-pl.ts \
|
translations/harbour-fernschreiber-pl.ts \
|
||||||
translations/harbour-fernschreiber-ru.ts \
|
translations/harbour-fernschreiber-ru.ts \
|
||||||
translations/harbour-fernschreiber-sv.ts \
|
translations/harbour-fernschreiber-sv.ts \
|
||||||
translations/harbour-fernschreiber-sk.ts \
|
|
||||||
translations/harbour-fernschreiber-en.ts \
|
translations/harbour-fernschreiber-en.ts \
|
||||||
translations/harbour-fernschreiber-zh_CN.ts
|
translations/harbour-fernschreiber-zh_CN.ts
|
||||||
|
|
||||||
equals(QT_ARCH, arm) {
|
contains(QT_ARCH, arm) {
|
||||||
message(Building ARM)
|
|
||||||
TARGET_ARCHITECTURE = armv7hl
|
TARGET_ARCHITECTURE = armv7hl
|
||||||
}
|
} else {
|
||||||
equals(QT_ARCH, i386) {
|
|
||||||
message(Building i486)
|
|
||||||
TARGET_ARCHITECTURE = i486
|
TARGET_ARCHITECTURE = i486
|
||||||
}
|
}
|
||||||
equals(QT_ARCH, arm64){
|
|
||||||
message(Building aarch64)
|
|
||||||
TARGET_ARCHITECTURE = aarch64
|
|
||||||
}
|
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/tdlib/include
|
INCLUDEPATH += $$PWD/tdlib/include
|
||||||
DEPENDPATH += $$PWD/tdlib/include
|
DEPENDPATH += $$PWD/tdlib/include
|
||||||
|
@ -211,7 +149,6 @@ INSTALLS += telegram 86.png 108.png 128.png 172.png 256.png \
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/appsettings.h \
|
src/appsettings.h \
|
||||||
src/chatpermissionfiltermodel.h \
|
|
||||||
src/chatlistmodel.h \
|
src/chatlistmodel.h \
|
||||||
src/chatmodel.h \
|
src/chatmodel.h \
|
||||||
src/contactsmodel.h \
|
src/contactsmodel.h \
|
||||||
|
@ -231,7 +168,6 @@ HEADERS += \
|
||||||
src/tdlibreceiver.h \
|
src/tdlibreceiver.h \
|
||||||
src/tdlibsecrets.h \
|
src/tdlibsecrets.h \
|
||||||
src/tdlibwrapper.h \
|
src/tdlibwrapper.h \
|
||||||
src/textfiltermodel.h \
|
|
||||||
src/tgsplugin.h
|
src/tgsplugin.h
|
||||||
|
|
||||||
# https://github.com/Samsung/rlottie.git
|
# https://github.com/Samsung/rlottie.git
|
||||||
|
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 6.5 KiB |
|
@ -5,241 +5,60 @@
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
width="114.667"
|
||||||
|
height="114.667"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
xml:space="preserve"
|
id="svg19">
|
||||||
width="114.66667"
|
<metadata
|
||||||
height="114.66667"
|
id="metadata23">
|
||||||
viewBox="0 0 114.66667 114.66667"
|
<rdf:RDF>
|
||||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
<cc:Work
|
||||||
sodipodi:docname="background-black.svg"
|
rdf:about="">
|
||||||
id="svg60"><sodipodi:namedview
|
<dc:format>image/svg+xml</dc:format>
|
||||||
pagecolor="#ffffff"
|
<dc:type
|
||||||
bordercolor="#666666"
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
borderopacity="1"
|
<dc:title></dc:title>
|
||||||
objecttolerance="10"
|
</cc:Work>
|
||||||
gridtolerance="10"
|
</rdf:RDF>
|
||||||
guidetolerance="10"
|
</metadata>
|
||||||
inkscape:pageopacity="0"
|
<defs
|
||||||
inkscape:pageshadow="2"
|
id="defs9">
|
||||||
inkscape:window-width="1920"
|
<linearGradient
|
||||||
inkscape:window-height="1015"
|
id="linearGradient4649">
|
||||||
id="namedview62"
|
<stop
|
||||||
showgrid="false"
|
style="stop-color:#979797;stop-opacity:1"
|
||||||
inkscape:zoom="2.0581394"
|
|
||||||
inkscape:cx="57.333336"
|
|
||||||
inkscape:cy="57.333336"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="g67" /><metadata
|
|
||||||
id="metadata64"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs8"><clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath18"><path
|
|
||||||
d="M 0.301,43 C 0.301,42.364 0.3,1.723 0.3,1.723 v 0 C 0.3,0.938 0.938,0.3 1.723,0.3 v 0 H 43 c 23.584,0 42.7,19.117 42.7,42.7 v 0 C 85.7,66.583 66.584,85.7 43,85.7 v 0 C 19.417,85.7 0.301,66.583 0.301,43"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path2" /></clipPath><linearGradient
|
|
||||||
x1="0"
|
|
||||||
y1="0"
|
|
||||||
x2="1"
|
|
||||||
y2="0"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(-72.476372,-72.476372,72.476372,-72.476372,73.193359,73.192871)"
|
|
||||||
spreadMethod="pad"
|
|
||||||
id="linearGradient30"><stop
|
|
||||||
style="stop-opacity:1;stop-color:#727272;opacity:1"
|
|
||||||
offset="0"
|
offset="0"
|
||||||
id="stop5" /><stop
|
id="stop4645" />
|
||||||
style="stop-opacity:1;stop-color:#898989;opacity:1"
|
<stop
|
||||||
offset="0.959184"
|
style="stop-color:#797979;stop-opacity:1"
|
||||||
id="stop7" /><stop
|
|
||||||
style="stop-opacity:1;stop-color:#898989;opacity:1"
|
|
||||||
offset="1"
|
offset="1"
|
||||||
id="stop9" /></linearGradient><linearGradient
|
id="stop4647" />
|
||||||
x1="0"
|
</linearGradient>
|
||||||
y1="0"
|
<linearGradient
|
||||||
x2="1"
|
xlink:href="#linearGradient4649"
|
||||||
y2="0"
|
id="linearGradient4651"
|
||||||
gradientUnits="userSpaceOnUse"
|
x1="0.81535178"
|
||||||
gradientTransform="matrix(-72.476372,-72.476372,72.476372,-72.476372,73.193359,73.192871)"
|
y1="0.99882859"
|
||||||
spreadMethod="pad"
|
x2="71.914337"
|
||||||
id="linearGradient30-529"><stop
|
y2="74.307625"
|
||||||
style="stop-opacity:1;stop-color:#727272;opacity:1"
|
gradientUnits="userSpaceOnUse" />
|
||||||
offset="0"
|
</defs>
|
||||||
id="stop74" /><stop
|
<path
|
||||||
style="stop-opacity:1;stop-color:#898989;opacity:1"
|
d="M 0.301,43 0.3,1.723 C 0.3,0.938 0.938,0.3 1.723,0.3 H 43 C 66.584,0.3 85.7,19.417 85.7,43 85.7,66.583 66.584,85.7 43,85.7 19.417,85.7 0.301,66.583 0.301,43"
|
||||||
offset="0.959184"
|
transform="matrix(1.33333,0,0,-1.33333,0,114.667)"
|
||||||
id="stop76" /><stop
|
id="path11"
|
||||||
style="stop-opacity:1;stop-color:#898989;opacity:1"
|
style="fill:url(#linearGradient4651);fill-opacity:1" />
|
||||||
offset="1"
|
<path
|
||||||
id="stop78" /></linearGradient><linearGradient
|
d="m 100,57.117 c 0,-23.408 -19.043,-42.45 -42.45,-42.45 -23.409,0 -42.451,19.042 -42.451,42.45 v 42.45 h 42.45 C 80.957,99.567 100,80.525 100,57.117"
|
||||||
x1="0"
|
id="path13"
|
||||||
y1="0"
|
style="fill:#444444;fill-opacity:1" />
|
||||||
x2="1"
|
<path
|
||||||
y2="0"
|
d="m 81.517,53.646 c -0.0573,2.403947 3.578298,2.403947 3.521,0 0.0573,-2.403947 -3.578298,-2.403947 -3.521,0 m -8.73,0 c 0.09308,2.256331 3.433918,2.256331 3.527,0 0,-2.351999 -3.528,-2.351999 -3.528,0 m -8.723,0 c 0,2.347999 3.522,2.347999 3.522,0 0,-2.347999 -3.522,-2.347999 -3.522,0 m -8.727,0 c -0.101696,2.44622 3.621306,2.447277 3.521,10e-4 -0.09236,-2.252442 -3.427362,-2.253389 -3.521,-10e-4 m -8.728,0 c -0.05733,2.406646 3.58233,2.406646 3.525,0 -0.05466,-2.294686 -3.470338,-2.294686 -3.525,0 m -8.726,0 c 6.67e-4,2.350666 3.526667,2.349666 3.526,-10e-4 0,-2.350666 -3.526,-2.350666 -3.526,0 m -8.726,0 c -0.05801,2.406625 3.581643,2.407658 3.525,10e-4 -0.05466,-2.294686 -3.470338,-2.294686 -3.525,0 m -8.728,0 c 0,2.353332 3.53,2.353332 3.53,0 0,-0.973 -0.79,-1.763 -1.766,-1.763 -0.975,0 -1.764,0.79 -1.764,1.763"
|
||||||
gradientUnits="userSpaceOnUse"
|
id="path15"
|
||||||
gradientTransform="matrix(-72.476372,-72.476372,72.476372,-72.476372,73.193359,73.192871)"
|
style="fill:#000000;fill-opacity:1" />
|
||||||
spreadMethod="pad"
|
<path
|
||||||
id="linearGradient30-529-824"><stop
|
d="m 79.751,79.82 c -0.08052,4.780502 7.131515,4.780502 7.051,0 -0.109325,-4.589371 -6.940675,-4.589371 -7.05,0 m 0,-8.722 c 0.0022,1.946378 1.578625,3.524144 3.525,3.528 4.703331,0 4.703331,-7.055 0,-7.055 -1.946832,0.0022 -3.524347,1.580167 -3.526,3.527 m 0,-8.727 c 0.0017,1.946995 1.579006,3.525244 3.526,3.528 4.703998,0 4.703998,-7.056 0,-7.056 -1.946994,0.0028 -3.524348,1.581005 -3.526,3.528 M 71.025,44.92 c 0.0018,3.140416 3.799089,4.710649 6.018485,2.489364 C 79.262881,45.188079 77.689416,41.39211 74.549,41.393 c -1.946965,0.0011 -3.524552,1.580034 -3.524,3.527 m 0,-8.728 c -0.0013,4.699998 7.048667,4.701998 7.05,0.002 0.0013,-4.699998 -7.048667,-4.701998 -7.05,-0.002 m -8.727,34.906 c 0.0011,1.946833 1.578168,3.525243 3.525,3.528 4.624805,-0.07787 4.624805,-6.977129 0,-7.055 -1.946899,0.0017 -3.524449,1.580101 -3.525,3.527 m 0,-26.178 c 0,1.946804 1.578196,3.525 3.525,3.525 4.701331,0 4.701331,-7.052 0,-7.052 -1.947127,0.0011 -3.525,1.579872 -3.525,3.527 m -8.73,34.9 c -5.53e-4,1.948689 1.579311,3.528553 3.528,3.528 1.94947,0.0017 3.530553,-1.578529 3.53,-3.528 -0.0033,-1.946737 -1.583261,-3.522659 -3.53,-3.521 -1.946186,-0.0011 -3.525241,1.574816 -3.528,3.521 m 0,-8.722 c 0.0028,1.947319 1.580681,3.525246 3.528,3.528 1.9481,-0.0017 3.527244,-1.579902 3.53,-3.528 -0.0022,-1.948165 -1.581834,-3.52645 -3.53,-3.527 -1.947613,0.0011 -3.526345,1.579387 -3.528,3.527 m 0,-26.178 c 0.0017,1.947289 1.58071,3.525001 3.528,3.525 1.947842,5.53e-4 3.527792,-1.577159 3.53,-3.525 -0.109388,-4.594641 -6.948612,-4.594641 -7.058,0 m -8.723,-8.728 c -5.53e-4,1.948528 1.579472,3.528105 3.528,3.527 4.701331,0 4.701331,-7.052 0,-7.052 -1.947518,-5.52e-4 -3.526896,1.577482 -3.528,3.525 M 36.12,79.82 c -0.0017,1.948757 1.578243,3.529106 3.527,3.528 1.948435,0.0011 3.527766,-1.579567 3.525,-3.528 -5.52e-4,-1.945928 -1.579072,-3.522658 -3.525,-3.521 -1.946252,-0.0017 -3.525344,1.574748 -3.527,3.521 m 0,-34.9 c 0.0013,4.701331 7.053333,4.699331 7.052,-0.002 -0.0013,-4.701331 -7.053333,-4.699331 -7.052,0.002 m -8.726,-8.728 c -6.67e-4,4.701331 7.051333,4.702331 7.052,10e-4 6.67e-4,-4.701331 -7.051333,-4.702331 -7.052,-10e-4 M 18.667,79.82 c -0.0022,1.948204 1.576795,3.528554 3.525,3.528 4.699998,0 4.699998,-7.05 0,-7.05 -1.94609,-0.0011 -3.524448,1.57591 -3.525,3.522"
|
||||||
style="stop-opacity:1;stop-color:#8d8d8d;opacity:1"
|
id="path17"
|
||||||
offset="0"
|
style="fill:#000000;fill-opacity:1" />
|
||||||
id="stop290" /><stop
|
</svg>
|
||||||
style="stop-opacity:1;stop-color:#767676;opacity:1"
|
|
||||||
offset="0.959184"
|
|
||||||
id="stop292" /><stop
|
|
||||||
style="stop-opacity:1;stop-color:#767676;opacity:1"
|
|
||||||
offset="1"
|
|
||||||
id="stop294" /></linearGradient></defs><g
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
inkscape:label="harbour-fernschreiber"
|
|
||||||
transform="matrix(1.3333333,0,0,-1.3333333,0,114.66667)"
|
|
||||||
id="g67"><g
|
|
||||||
id="g18"><g
|
|
||||||
clip-path="url(#clipPath18)"
|
|
||||||
id="g16"><path
|
|
||||||
d="M 0.301,43 C 0.301,42.364 0.3,1.723 0.3,1.723 v 0 C 0.3,0.938 0.938,0.3 1.723,0.3 v 0 H 43 c 23.584,0 42.7,19.117 42.7,42.7 v 0 C 85.7,66.583 66.584,85.7 43,85.7 v 0 C 19.417,85.7 0.301,66.583 0.301,43"
|
|
||||||
style="fill:url(#linearGradient30-529-824);stroke:none;opacity:1"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path14" /></g></g><g
|
|
||||||
transform="translate(75,43.1621)"
|
|
||||||
id="g20" /><path
|
|
||||||
style="opacity:0.9;fill:#464646;fill-opacity:1;stroke-width:0.9930262"
|
|
||||||
d="M 42.700457,74.178768 C 24.766404,74.178768 10.2285,60.954638 10.2285,44.643189 V 15.107611 5.2627488 c 5.978017,0 10.823985,4.255117 10.823985,9.6909432 h 21.647972 c 17.934054,0 32.471954,13.377056 32.471954,29.689497 0,16.311449 -14.5379,29.535579 -32.471954,29.535579 z"
|
|
||||||
id="path10-3"
|
|
||||||
inkscape:connector-curvature="0" /><g
|
|
||||||
id="g46"
|
|
||||||
transform="translate(15.3208,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.592,-1.322 1.323,-1.322 0.732,0 1.324,0.593 1.324,1.322 0,0.73 -0.592,1.322 -1.324,1.322 C 0.592,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path48"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g50"
|
|
||||||
transform="translate(21.8672,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.591,-1.322 1.321,-1.322 0.732,0 1.323,0.593 1.323,1.322 0,0.73 -0.591,1.322 -1.323,1.322 C 0.591,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path52"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g54"
|
|
||||||
transform="translate(28.4116,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.591,-1.322 1.323,-1.322 0.729,0 1.321,0.593 1.321,1.322 0,0.73 -0.592,1.322 -1.321,1.322 C 0.591,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path56"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g58"
|
|
||||||
transform="translate(34.9561,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.592,-1.322 1.323,-1.322 0.73,0 1.321,0.593 1.321,1.322 0,0.73 -0.591,1.322 -1.321,1.322 C 0.592,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path60"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g62"
|
|
||||||
transform="translate(41.502,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.593,-1.322 1.32,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.593,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path64"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g66"
|
|
||||||
transform="translate(48.0469,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.59,-1.322 1.32,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.59,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path68"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g70"
|
|
||||||
transform="translate(54.5898,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.594,-1.322 1.32,-1.322 0.735,0 1.326,0.593 1.326,1.322 0,0.73 -0.591,1.322 -1.326,1.322 C 0.594,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path72"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g74"
|
|
||||||
transform="translate(61.1377,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.59,-1.322 1.319,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.59,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path76"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g78"
|
|
||||||
transform="translate(14,26.1348)"><path
|
|
||||||
d="m 0,0 c 0,-1.465 1.184,-2.646 2.644,-2.646 1.461,0 2.645,1.181 2.645,2.646 0,1.459 -1.184,2.641 -2.645,2.641 C 1.184,2.641 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path80"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g82"
|
|
||||||
transform="translate(20.5444,58.856)"><path
|
|
||||||
d="m 0,0 c 0,-1.462 1.185,-2.645 2.644,-2.645 1.461,0 2.645,1.183 2.645,2.645 0,1.459 -1.184,2.644 -2.645,2.644 C 1.185,2.644 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path84"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g86"
|
|
||||||
transform="translate(27.0894,52.3101)"><path
|
|
||||||
d="m 0,0 c 0,-1.461 1.185,-2.644 2.645,-2.644 1.461,0 2.644,1.183 2.644,2.644 0,1.46 -1.183,2.645 -2.644,2.645 C 1.185,2.645 0,1.46 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path88"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g90"
|
|
||||||
transform="translate(27.0894,26.1348)"><path
|
|
||||||
d="m 0,0 c 0,-1.465 1.185,-2.646 2.645,-2.646 1.461,0 2.644,1.181 2.644,2.646 0,1.459 -1.183,2.641 -2.644,2.641 C 1.185,2.641 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path92"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g94"
|
|
||||||
transform="translate(33.6338,58.856)"><path
|
|
||||||
d="M 0,0 C 0,-1.462 1.184,-2.645 2.646,-2.645 4.106,-2.645 5.29,-1.462 5.29,0 5.29,1.459 4.106,2.644 2.646,2.644 1.184,2.644 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path96"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g98"
|
|
||||||
transform="translate(40.1758,52.3101)"><path
|
|
||||||
d="m 0,0 c 0,-1.461 1.187,-2.644 2.646,-2.644 1.461,0 2.648,1.183 2.648,2.644 0,1.46 -1.187,2.645 -2.648,2.645 C 1.187,2.645 0,1.46 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path100"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g102"
|
|
||||||
transform="translate(40.1758,32.6768)"><path
|
|
||||||
d="m 0,0 c 0,-1.458 1.187,-2.646 2.646,-2.646 1.461,0 2.648,1.188 2.648,2.646 0,1.459 -1.187,2.645 -2.648,2.645 C 1.187,2.645 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path104"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g106"
|
|
||||||
transform="translate(40.1758,26.1348)"><path
|
|
||||||
d="m 0,0 c 0,-1.465 1.187,-2.646 2.646,-2.646 1.461,0 2.648,1.181 2.648,2.646 0,1.459 -1.187,2.641 -2.648,2.641 C 1.187,2.641 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path108"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g110"
|
|
||||||
transform="translate(46.7236,52.3101)"><path
|
|
||||||
d="m 0,0 c 0,-1.461 1.184,-2.644 2.644,-2.644 1.461,0 2.645,1.183 2.645,2.644 0,1.46 -1.184,2.645 -2.645,2.645 C 1.184,2.645 0,1.46 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path112"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g114"
|
|
||||||
transform="translate(46.7236,32.6768)"><path
|
|
||||||
d="m 0,0 c 0,-1.458 1.184,-2.646 2.644,-2.646 1.461,0 2.645,1.188 2.645,2.646 0,1.459 -1.184,2.645 -2.645,2.645 C 1.184,2.645 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path116"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g118"
|
|
||||||
transform="translate(53.2686,58.856)"><path
|
|
||||||
d="m 0,0 c 0,-1.462 1.183,-2.645 2.643,-2.645 1.461,0 2.645,1.183 2.645,2.645 0,1.459 -1.184,2.644 -2.645,2.644 C 1.183,2.644 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path120"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g122"
|
|
||||||
transform="translate(53.2686,52.3101)"><path
|
|
||||||
d="m 0,0 c 0,-1.461 1.183,-2.644 2.643,-2.644 1.461,0 2.645,1.183 2.645,2.644 0,1.46 -1.184,2.645 -2.645,2.645 C 1.183,2.645 0,1.46 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path124"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g126"
|
|
||||||
transform="translate(59.8135,39.2217)"><path
|
|
||||||
d="m 0,0 c 0,-1.459 1.187,-2.646 2.644,-2.646 1.461,0 2.644,1.187 2.644,2.646 0,1.459 -1.183,2.646 -2.644,2.646 C 1.187,2.646 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path128"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g130"
|
|
||||||
transform="translate(59.8135,32.6768)"><path
|
|
||||||
d="m 0,0 c 0,-1.458 1.187,-2.646 2.644,-2.646 1.461,0 2.644,1.188 2.644,2.646 0,1.459 -1.183,2.645 -2.644,2.645 C 1.187,2.645 0,1.459 0,0"
|
|
||||||
style="fill:#040404;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
id="path132"
|
|
||||||
inkscape:connector-curvature="0" /></g></g></svg>
|
|
||||||
|
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 4.9 KiB |
|
@ -5,224 +5,60 @@
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
id="svg19"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
xml:space="preserve"
|
height="114.667"
|
||||||
width="114.66667"
|
width="114.667">
|
||||||
height="114.66667"
|
<metadata
|
||||||
viewBox="0 0 114.66667 114.66667"
|
id="metadata23">
|
||||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
<rdf:RDF>
|
||||||
sodipodi:docname="background-white.svg"
|
<cc:Work
|
||||||
id="svg60"><sodipodi:namedview
|
rdf:about="">
|
||||||
pagecolor="#ffffff"
|
<dc:format>image/svg+xml</dc:format>
|
||||||
bordercolor="#666666"
|
<dc:type
|
||||||
borderopacity="1"
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
objecttolerance="10"
|
<dc:title></dc:title>
|
||||||
gridtolerance="10"
|
</cc:Work>
|
||||||
guidetolerance="10"
|
</rdf:RDF>
|
||||||
inkscape:pageopacity="0"
|
</metadata>
|
||||||
inkscape:pageshadow="2"
|
<defs
|
||||||
inkscape:window-width="1920"
|
id="defs9">
|
||||||
inkscape:window-height="1015"
|
<linearGradient
|
||||||
id="namedview62"
|
id="linearGradient4649">
|
||||||
showgrid="false"
|
<stop
|
||||||
inkscape:zoom="2.0581394"
|
id="stop4645"
|
||||||
inkscape:cx="57.333336"
|
|
||||||
inkscape:cy="57.333336"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="g67" /><metadata
|
|
||||||
id="metadata64"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs8"><clipPath
|
|
||||||
id="clipPath18"
|
|
||||||
clipPathUnits="userSpaceOnUse"><path
|
|
||||||
id="path2"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
d="M 0.301,43 C 0.301,42.364 0.3,1.723 0.3,1.723 v 0 C 0.3,0.938 0.938,0.3 1.723,0.3 v 0 H 43 c 23.584,0 42.7,19.117 42.7,42.7 v 0 C 85.7,66.583 66.584,85.7 43,85.7 v 0 C 19.417,85.7 0.301,66.583 0.301,43" /></clipPath><linearGradient
|
|
||||||
id="linearGradient30"
|
|
||||||
spreadMethod="pad"
|
|
||||||
gradientTransform="matrix(-72.476372,-72.476372,72.476372,-72.476372,73.193359,73.192871)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
y2="0"
|
|
||||||
x2="1"
|
|
||||||
y1="0"
|
|
||||||
x1="0"><stop
|
|
||||||
id="stop5"
|
|
||||||
offset="0"
|
offset="0"
|
||||||
style="stop-opacity:1;stop-color:#8d8d8d;opacity:1" /><stop
|
style="stop-color:#686868;stop-opacity:1" />
|
||||||
id="stop7"
|
<stop
|
||||||
offset="0.959184"
|
id="stop4647"
|
||||||
style="stop-opacity:1;stop-color:#767676;opacity:1" /><stop
|
|
||||||
id="stop9"
|
|
||||||
offset="1"
|
offset="1"
|
||||||
style="stop-opacity:1;stop-color:#767676;opacity:1" /></linearGradient><linearGradient
|
style="stop-color:#868686;stop-opacity:1" />
|
||||||
id="linearGradient30-529"
|
</linearGradient>
|
||||||
spreadMethod="pad"
|
<linearGradient
|
||||||
gradientTransform="matrix(-72.476372,-72.476372,72.476372,-72.476372,73.193359,73.192871)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
gradientUnits="userSpaceOnUse"
|
||||||
y2="0"
|
y2="74.307625"
|
||||||
x2="1"
|
x2="71.914337"
|
||||||
y1="0"
|
y1="0.99882859"
|
||||||
x1="0"><stop
|
x1="0.81535178"
|
||||||
id="stop74"
|
id="linearGradient4651"
|
||||||
offset="0"
|
xlink:href="#linearGradient4649" />
|
||||||
style="stop-opacity:1;stop-color:#8d8d8d;opacity:1" /><stop
|
</defs>
|
||||||
id="stop76"
|
<path
|
||||||
offset="0.959184"
|
style="fill:url(#linearGradient4651);fill-opacity:1"
|
||||||
style="stop-opacity:1;stop-color:#767676;opacity:1" /><stop
|
id="path11"
|
||||||
id="stop78"
|
transform="matrix(1.33333,0,0,-1.33333,0,114.667)"
|
||||||
offset="1"
|
d="M 0.301,43 0.3,1.723 C 0.3,0.938 0.938,0.3 1.723,0.3 H 43 C 66.584,0.3 85.7,19.417 85.7,43 85.7,66.583 66.584,85.7 43,85.7 19.417,85.7 0.301,66.583 0.301,43" />
|
||||||
style="stop-opacity:1;stop-color:#767676;opacity:1" /></linearGradient></defs><g
|
<path
|
||||||
id="g67"
|
style="fill:#bbbbbb;fill-opacity:1"
|
||||||
transform="matrix(1.3333333,0,0,-1.3333333,0,114.66667)"
|
id="path13"
|
||||||
inkscape:label="harbour-fernschreiber"
|
d="m 100,57.117 c 0,-23.408 -19.043,-42.45 -42.45,-42.45 -23.409,0 -42.451,19.042 -42.451,42.45 v 42.45 h 42.45 C 80.957,99.567 100,80.525 100,57.117" />
|
||||||
inkscape:groupmode="layer"><g
|
<path
|
||||||
id="g18"><g
|
style="fill:#f7f7f7;fill-opacity:1"
|
||||||
id="g16"
|
id="path15"
|
||||||
clip-path="url(#clipPath18)"><path
|
d="m 81.517,53.646 c -0.0573,2.403947 3.578298,2.403947 3.521,0 0.0573,-2.403947 -3.578298,-2.403947 -3.521,0 m -8.73,0 c 0.09308,2.256331 3.433918,2.256331 3.527,0 0,-2.351999 -3.528,-2.351999 -3.528,0 m -8.723,0 c 0,2.347999 3.522,2.347999 3.522,0 0,-2.347999 -3.522,-2.347999 -3.522,0 m -8.727,0 c -0.101696,2.44622 3.621306,2.447277 3.521,10e-4 -0.09236,-2.252442 -3.427362,-2.253389 -3.521,-10e-4 m -8.728,0 c -0.05733,2.406646 3.58233,2.406646 3.525,0 -0.05466,-2.294686 -3.470338,-2.294686 -3.525,0 m -8.726,0 c 6.67e-4,2.350666 3.526667,2.349666 3.526,-10e-4 0,-2.350666 -3.526,-2.350666 -3.526,0 m -8.726,0 c -0.05801,2.406625 3.581643,2.407658 3.525,10e-4 -0.05466,-2.294686 -3.470338,-2.294686 -3.525,0 m -8.728,0 c 0,2.353332 3.53,2.353332 3.53,0 0,-0.973 -0.79,-1.763 -1.766,-1.763 -0.975,0 -1.764,0.79 -1.764,1.763" />
|
||||||
id="path14"
|
<path
|
||||||
inkscape:connector-curvature="0"
|
style="fill:#fcfcfc;fill-opacity:1"
|
||||||
style="fill:url(#linearGradient30-529);stroke:none;opacity:1"
|
id="path17"
|
||||||
d="M 0.301,43 C 0.301,42.364 0.3,1.723 0.3,1.723 v 0 C 0.3,0.938 0.938,0.3 1.723,0.3 v 0 H 43 c 23.584,0 42.7,19.117 42.7,42.7 v 0 C 85.7,66.583 66.584,85.7 43,85.7 v 0 C 19.417,85.7 0.301,66.583 0.301,43" /></g></g><g
|
d="m 79.751,79.82 c -0.08052,4.780502 7.131515,4.780502 7.051,0 -0.109325,-4.589371 -6.940675,-4.589371 -7.05,0 m 0,-8.722 c 0.0022,1.946378 1.578625,3.524144 3.525,3.528 4.703331,0 4.703331,-7.055 0,-7.055 -1.946832,0.0022 -3.524347,1.580167 -3.526,3.527 m 0,-8.727 c 0.0017,1.946995 1.579006,3.525244 3.526,3.528 4.703998,0 4.703998,-7.056 0,-7.056 -1.946994,0.0028 -3.524348,1.581005 -3.526,3.528 M 71.025,44.92 c 0.0018,3.140416 3.799089,4.710649 6.018485,2.489364 C 79.262881,45.188079 77.689416,41.39211 74.549,41.393 c -1.946965,0.0011 -3.524552,1.580034 -3.524,3.527 m 0,-8.728 c -0.0013,4.699998 7.048667,4.701998 7.05,0.002 0.0013,-4.699998 -7.048667,-4.701998 -7.05,-0.002 m -8.727,34.906 c 0.0011,1.946833 1.578168,3.525243 3.525,3.528 4.624805,-0.07787 4.624805,-6.977129 0,-7.055 -1.946899,0.0017 -3.524449,1.580101 -3.525,3.527 m 0,-26.178 c 0,1.946804 1.578196,3.525 3.525,3.525 4.701331,0 4.701331,-7.052 0,-7.052 -1.947127,0.0011 -3.525,1.579872 -3.525,3.527 m -8.73,34.9 c -5.53e-4,1.948689 1.579311,3.528553 3.528,3.528 1.94947,0.0017 3.530553,-1.578529 3.53,-3.528 -0.0033,-1.946737 -1.583261,-3.522659 -3.53,-3.521 -1.946186,-0.0011 -3.525241,1.574816 -3.528,3.521 m 0,-8.722 c 0.0028,1.947319 1.580681,3.525246 3.528,3.528 1.9481,-0.0017 3.527244,-1.579902 3.53,-3.528 -0.0022,-1.948165 -1.581834,-3.52645 -3.53,-3.527 -1.947613,0.0011 -3.526345,1.579387 -3.528,3.527 m 0,-26.178 c 0.0017,1.947289 1.58071,3.525001 3.528,3.525 1.947842,5.53e-4 3.527792,-1.577159 3.53,-3.525 -0.109388,-4.594641 -6.948612,-4.594641 -7.058,0 m -8.723,-8.728 c -5.53e-4,1.948528 1.579472,3.528105 3.528,3.527 4.701331,0 4.701331,-7.052 0,-7.052 -1.947518,-5.52e-4 -3.526896,1.577482 -3.528,3.525 M 36.12,79.82 c -0.0017,1.948757 1.578243,3.529106 3.527,3.528 1.948435,0.0011 3.527766,-1.579567 3.525,-3.528 -5.52e-4,-1.945928 -1.579072,-3.522658 -3.525,-3.521 -1.946252,-0.0017 -3.525344,1.574748 -3.527,3.521 m 0,-34.9 c 0.0013,4.701331 7.053333,4.699331 7.052,-0.002 -0.0013,-4.701331 -7.053333,-4.699331 -7.052,0.002 m -8.726,-8.728 c -6.67e-4,4.701331 7.051333,4.702331 7.052,10e-4 6.67e-4,-4.701331 -7.051333,-4.702331 -7.052,-10e-4 M 18.667,79.82 c -0.0022,1.948204 1.576795,3.528554 3.525,3.528 4.699998,0 4.699998,-7.05 0,-7.05 -1.94609,-0.0011 -3.524448,1.57591 -3.525,3.522" />
|
||||||
id="g20"
|
</svg>
|
||||||
transform="translate(75,43.1621)" /><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path10-3"
|
|
||||||
d="M 42.700457,74.178768 C 24.766404,74.178768 10.2285,60.954638 10.2285,44.643189 V 15.107611 5.2627488 c 5.978017,0 10.823985,4.255117 10.823985,9.6909432 h 21.647972 c 17.934054,0 32.471954,13.377056 32.471954,29.689497 0,16.311449 -14.5379,29.535579 -32.471954,29.535579 z"
|
|
||||||
style="opacity:0.9;fill:#b9b9b9;fill-opacity:1;stroke-width:0.9930262" /><g
|
|
||||||
transform="translate(15.3208,45.7656)"
|
|
||||||
id="g46"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path48"
|
|
||||||
style="fill:#f4f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-0.729 0.592,-1.322 1.323,-1.322 0.732,0 1.324,0.593 1.324,1.322 0,0.73 -0.592,1.322 -1.324,1.322 C 0.592,1.322 0,0.73 0,0" /></g><g
|
|
||||||
transform="translate(21.8672,45.7656)"
|
|
||||||
id="g50"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path52"
|
|
||||||
style="fill:#f4f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-0.729 0.591,-1.322 1.321,-1.322 0.732,0 1.323,0.593 1.323,1.322 0,0.73 -0.591,1.322 -1.323,1.322 C 0.591,1.322 0,0.73 0,0" /></g><g
|
|
||||||
transform="translate(28.4116,45.7656)"
|
|
||||||
id="g54"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path56"
|
|
||||||
style="fill:#f4f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-0.729 0.591,-1.322 1.323,-1.322 0.729,0 1.321,0.593 1.321,1.322 0,0.73 -0.592,1.322 -1.321,1.322 C 0.591,1.322 0,0.73 0,0" /></g><g
|
|
||||||
transform="translate(34.9561,45.7656)"
|
|
||||||
id="g58"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path60"
|
|
||||||
style="fill:#f4f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-0.729 0.592,-1.322 1.323,-1.322 0.73,0 1.321,0.593 1.321,1.322 0,0.73 -0.591,1.322 -1.321,1.322 C 0.592,1.322 0,0.73 0,0" /></g><g
|
|
||||||
transform="translate(41.502,45.7656)"
|
|
||||||
id="g62"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path64"
|
|
||||||
style="fill:#f4f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-0.729 0.593,-1.322 1.32,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.593,1.322 0,0.73 0,0" /></g><g
|
|
||||||
transform="translate(48.0469,45.7656)"
|
|
||||||
id="g66"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path68"
|
|
||||||
style="fill:#f4f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-0.729 0.59,-1.322 1.32,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.59,1.322 0,0.73 0,0" /></g><g
|
|
||||||
transform="translate(54.5898,45.7656)"
|
|
||||||
id="g70"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path72"
|
|
||||||
style="fill:#f4f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-0.729 0.594,-1.322 1.32,-1.322 0.735,0 1.326,0.593 1.326,1.322 0,0.73 -0.591,1.322 -1.326,1.322 C 0.594,1.322 0,0.73 0,0" /></g><g
|
|
||||||
transform="translate(61.1377,45.7656)"
|
|
||||||
id="g74"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path76"
|
|
||||||
style="fill:#f4f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-0.729 0.59,-1.322 1.319,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.59,1.322 0,0.73 0,0" /></g><g
|
|
||||||
transform="translate(14,26.1348)"
|
|
||||||
id="g78"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path80"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.465 1.184,-2.646 2.644,-2.646 1.461,0 2.645,1.181 2.645,2.646 0,1.459 -1.184,2.641 -2.645,2.641 C 1.184,2.641 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(20.5444,58.856)"
|
|
||||||
id="g82"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path84"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.462 1.185,-2.645 2.644,-2.645 1.461,0 2.645,1.183 2.645,2.645 0,1.459 -1.184,2.644 -2.645,2.644 C 1.185,2.644 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(27.0894,52.3101)"
|
|
||||||
id="g86"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path88"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.461 1.185,-2.644 2.645,-2.644 1.461,0 2.644,1.183 2.644,2.644 0,1.46 -1.183,2.645 -2.644,2.645 C 1.185,2.645 0,1.46 0,0" /></g><g
|
|
||||||
transform="translate(27.0894,26.1348)"
|
|
||||||
id="g90"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path92"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.465 1.185,-2.646 2.645,-2.646 1.461,0 2.644,1.181 2.644,2.646 0,1.459 -1.183,2.641 -2.644,2.641 C 1.185,2.641 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(33.6338,58.856)"
|
|
||||||
id="g94"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path96"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="M 0,0 C 0,-1.462 1.184,-2.645 2.646,-2.645 4.106,-2.645 5.29,-1.462 5.29,0 5.29,1.459 4.106,2.644 2.646,2.644 1.184,2.644 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(40.1758,52.3101)"
|
|
||||||
id="g98"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path100"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.461 1.187,-2.644 2.646,-2.644 1.461,0 2.648,1.183 2.648,2.644 0,1.46 -1.187,2.645 -2.648,2.645 C 1.187,2.645 0,1.46 0,0" /></g><g
|
|
||||||
transform="translate(40.1758,32.6768)"
|
|
||||||
id="g102"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path104"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.458 1.187,-2.646 2.646,-2.646 1.461,0 2.648,1.188 2.648,2.646 0,1.459 -1.187,2.645 -2.648,2.645 C 1.187,2.645 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(40.1758,26.1348)"
|
|
||||||
id="g106"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path108"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.465 1.187,-2.646 2.646,-2.646 1.461,0 2.648,1.181 2.648,2.646 0,1.459 -1.187,2.641 -2.648,2.641 C 1.187,2.641 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(46.7236,52.3101)"
|
|
||||||
id="g110"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path112"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.461 1.184,-2.644 2.644,-2.644 1.461,0 2.645,1.183 2.645,2.644 0,1.46 -1.184,2.645 -2.645,2.645 C 1.184,2.645 0,1.46 0,0" /></g><g
|
|
||||||
transform="translate(46.7236,32.6768)"
|
|
||||||
id="g114"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path116"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.458 1.184,-2.646 2.644,-2.646 1.461,0 2.645,1.188 2.645,2.646 0,1.459 -1.184,2.645 -2.645,2.645 C 1.184,2.645 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(53.2686,58.856)"
|
|
||||||
id="g118"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path120"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.462 1.183,-2.645 2.643,-2.645 1.461,0 2.645,1.183 2.645,2.645 0,1.459 -1.184,2.644 -2.645,2.644 C 1.183,2.644 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(53.2686,52.3101)"
|
|
||||||
id="g122"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path124"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.461 1.183,-2.644 2.643,-2.644 1.461,0 2.645,1.183 2.645,2.644 0,1.46 -1.184,2.645 -2.645,2.645 C 1.183,2.645 0,1.46 0,0" /></g><g
|
|
||||||
transform="translate(59.8135,39.2217)"
|
|
||||||
id="g126"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path128"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.459 1.187,-2.646 2.644,-2.646 1.461,0 2.644,1.187 2.644,2.646 0,1.459 -1.183,2.646 -2.644,2.646 C 1.187,2.646 0,1.459 0,0" /></g><g
|
|
||||||
transform="translate(59.8135,32.6768)"
|
|
||||||
id="g130"><path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path132"
|
|
||||||
style="fill:#fbfbfb;fill-opacity:1;fill-rule:nonzero;stroke:none;opacity:1"
|
|
||||||
d="m 0,0 c 0,-1.458 1.187,-2.646 2.644,-2.646 1.461,0 2.644,1.188 2.644,2.646 0,1.459 -1.183,2.645 -2.644,2.645 C 1.187,2.645 0,1.459 0,0" /></g></g></svg>
|
|
||||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 6 KiB |
|
@ -1,204 +1,66 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<svg
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
id="svg19"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.1"
|
version="1.1"
|
||||||
xml:space="preserve"
|
height="114.667"
|
||||||
width="114.66667"
|
width="114.667">
|
||||||
height="114.66667"
|
<metadata
|
||||||
viewBox="0 0 114.66667 114.66667"
|
id="metadata23">
|
||||||
inkscape:version="0.92.4 (unknown)"
|
<rdf:RDF>
|
||||||
sodipodi:docname="harbour-fernschreiber-3.svg">
|
<cc:Work
|
||||||
<defs>
|
rdf:about="">
|
||||||
<clipPath
|
<dc:format>image/svg+xml</dc:format>
|
||||||
clipPathUnits="userSpaceOnUse"
|
<dc:type
|
||||||
id="clipPath18">
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
<path
|
<dc:title></dc:title>
|
||||||
d="M 0.301,43 C 0.301,42.364 0.3,1.723 0.3,1.723 v 0 C 0.3,0.938 0.938,0.3 1.723,0.3 v 0 H 43 c 23.584,0 42.7,19.117 42.7,42.7 v 0 C 85.7,66.583 66.584,85.7 43,85.7 v 0 C 19.417,85.7 0.301,66.583 0.301,43"
|
</cc:Work>
|
||||||
inkscape:connector-curvature="0"
|
</rdf:RDF>
|
||||||
id="path2" />
|
</metadata>
|
||||||
</clipPath>
|
<defs
|
||||||
|
id="defs9">
|
||||||
<linearGradient
|
<linearGradient
|
||||||
x1="0"
|
id="a"
|
||||||
y1="0"
|
spreadMethod="pad"
|
||||||
x2="1"
|
gradientTransform="rotate(-135 51.755 21.438) scale(102.49707)"
|
||||||
y2="0"
|
gradientUnits="userSpaceOnUse"
|
||||||
gradientUnits="userSpaceOnUse"
|
y2="0"
|
||||||
gradientTransform="matrix(-72.476372,-72.476372,72.476372,-72.476372,73.193359,73.192871)"
|
x2="1"
|
||||||
spreadMethod="pad"
|
y1="0"
|
||||||
id="linearGradient30">
|
x1="0">
|
||||||
<stop
|
<stop
|
||||||
style="stop-opacity:1;stop-color:#ec7221"
|
id="stop2"
|
||||||
offset="0"
|
stop-color="#ec7221"
|
||||||
id="stop5" />
|
offset="0" />
|
||||||
<stop
|
<stop
|
||||||
style="stop-opacity:1;stop-color:#e7454c"
|
id="stop4"
|
||||||
offset="0.959184"
|
stop-color="#e7454c"
|
||||||
id="stop7" />
|
offset=".959" />
|
||||||
<stop
|
<stop
|
||||||
style="stop-opacity:1;stop-color:#e7454c"
|
id="stop6"
|
||||||
offset="1"
|
stop-color="#e7454c"
|
||||||
id="stop9" />
|
offset="1" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
<g
|
<path
|
||||||
inkscape:groupmode="layer"
|
id="path11"
|
||||||
inkscape:label="harbour-fernschreiber"
|
transform="matrix(1.33333 0 0 -1.33333 0 114.667)"
|
||||||
transform="matrix(1.3333333,0,0,-1.3333333,0,114.66667)"
|
fill="url(#a)"
|
||||||
id="g67">
|
d="M.301 43L.3 1.723C.3.938.938.3 1.723.3H43C66.584.3 85.7 19.417 85.7 43c0 23.583-19.116 42.7-42.7 42.7C19.417 85.7.301 66.583.301 43" />
|
||||||
<g
|
<path
|
||||||
id="g18">
|
id="path13"
|
||||||
<g
|
fill="#fcba02"
|
||||||
clip-path="url(#clipPath18)"
|
d="M100 57.117c0-23.408-19.043-42.45-42.45-42.45-23.409 0-42.451 19.042-42.451 42.45v42.45h42.45c23.408 0 42.451-19.042 42.451-42.45" />
|
||||||
id="g16">
|
<path
|
||||||
<path
|
style="fill:#fffda9"
|
||||||
d="M 0.301,43 C 0.301,42.364 0.3,1.723 0.3,1.723 v 0 C 0.3,0.938 0.938,0.3 1.723,0.3 v 0 H 43 c 23.584,0 42.7,19.117 42.7,42.7 v 0 C 85.7,66.583 66.584,85.7 43,85.7 v 0 C 19.417,85.7 0.301,66.583 0.301,43"
|
id="path15"
|
||||||
style="fill:url(#linearGradient30);stroke:none"
|
d="m 81.517,53.646 c -0.0573,2.403947 3.578298,2.403947 3.521,0 0.0573,-2.403947 -3.578298,-2.403947 -3.521,0 m -8.73,0 c 0.09308,2.256331 3.433918,2.256331 3.527,0 0,-2.351999 -3.528,-2.351999 -3.528,0 m -8.723,0 c 0,2.347999 3.522,2.347999 3.522,0 0,-2.347999 -3.522,-2.347999 -3.522,0 m -8.727,0 c -0.101696,2.44622 3.621306,2.447277 3.521,10e-4 -0.09236,-2.252442 -3.427362,-2.253389 -3.521,-10e-4 m -8.728,0 c -0.05733,2.406646 3.58233,2.406646 3.525,0 -0.05466,-2.294686 -3.470338,-2.294686 -3.525,0 m -8.726,0 c 6.67e-4,2.350666 3.526667,2.349666 3.526,-10e-4 0,-2.350666 -3.526,-2.350666 -3.526,0 m -8.726,0 c -0.05801,2.406625 3.581643,2.407658 3.525,10e-4 -0.05466,-2.294686 -3.470338,-2.294686 -3.525,0 m -8.728,0 c 0,2.353332 3.53,2.353332 3.53,0 0,-0.973 -0.79,-1.763 -1.766,-1.763 -0.975,0 -1.764,0.79 -1.764,1.763" />
|
||||||
inkscape:connector-curvature="0"
|
<path
|
||||||
id="path14" />
|
style="fill:#fffee3"
|
||||||
</g>
|
id="path17"
|
||||||
</g>
|
d="m 79.751,79.82 c -0.08052,4.780502 7.131515,4.780502 7.051,0 -0.109325,-4.589371 -6.940675,-4.589371 -7.05,0 m 0,-8.722 c 0.0022,1.946378 1.578625,3.524144 3.525,3.528 4.703331,0 4.703331,-7.055 0,-7.055 -1.946832,0.0022 -3.524347,1.580167 -3.526,3.527 m 0,-8.727 c 0.0017,1.946995 1.579006,3.525244 3.526,3.528 4.703998,0 4.703998,-7.056 0,-7.056 -1.946994,0.0028 -3.524348,1.581005 -3.526,3.528 M 71.025,44.92 c 0.0018,3.140416 3.799089,4.710649 6.018485,2.489364 C 79.262881,45.188079 77.689416,41.39211 74.549,41.393 c -1.946965,0.0011 -3.524552,1.580034 -3.524,3.527 m 0,-8.728 c -0.0013,4.699998 7.048667,4.701998 7.05,0.002 0.0013,-4.699998 -7.048667,-4.701998 -7.05,-0.002 m -8.727,34.906 c 0.0011,1.946833 1.578168,3.525243 3.525,3.528 4.624805,-0.07787 4.624805,-6.977129 0,-7.055 -1.946899,0.0017 -3.524449,1.580101 -3.525,3.527 m 0,-26.178 c 0,1.946804 1.578196,3.525 3.525,3.525 4.701331,0 4.701331,-7.052 0,-7.052 -1.947127,0.0011 -3.525,1.579872 -3.525,3.527 m -8.73,34.9 c -5.53e-4,1.948689 1.579311,3.528553 3.528,3.528 1.94947,0.0017 3.530553,-1.578529 3.53,-3.528 -0.0033,-1.946737 -1.583261,-3.522659 -3.53,-3.521 -1.946186,-0.0011 -3.525241,1.574816 -3.528,3.521 m 0,-8.722 c 0.0028,1.947319 1.580681,3.525246 3.528,3.528 1.9481,-0.0017 3.527244,-1.579902 3.53,-3.528 -0.0022,-1.948165 -1.581834,-3.52645 -3.53,-3.527 -1.947613,0.0011 -3.526345,1.579387 -3.528,3.527 m 0,-26.178 c 0.0017,1.947289 1.58071,3.525001 3.528,3.525 1.947842,5.53e-4 3.527792,-1.577159 3.53,-3.525 -0.109388,-4.594641 -6.948612,-4.594641 -7.058,0 m -8.723,-8.728 c -5.53e-4,1.948528 1.579472,3.528105 3.528,3.527 4.701331,0 4.701331,-7.052 0,-7.052 -1.947518,-5.52e-4 -3.526896,1.577482 -3.528,3.525 M 36.12,79.82 c -0.0017,1.948757 1.578243,3.529106 3.527,3.528 1.948435,0.0011 3.527766,-1.579567 3.525,-3.528 -5.52e-4,-1.945928 -1.579072,-3.522658 -3.525,-3.521 -1.946252,-0.0017 -3.525344,1.574748 -3.527,3.521 m 0,-34.9 c 0.0013,4.701331 7.053333,4.699331 7.052,-0.002 -0.0013,-4.701331 -7.053333,-4.699331 -7.052,0.002 m -8.726,-8.728 c -6.67e-4,4.701331 7.051333,4.702331 7.052,10e-4 6.67e-4,-4.701331 -7.051333,-4.702331 -7.052,-10e-4 M 18.667,79.82 c -0.0022,1.948204 1.576795,3.528554 3.525,3.528 4.699998,0 4.699998,-7.05 0,-7.05 -1.94609,-0.0011 -3.524448,1.57591 -3.525,3.522" />
|
||||||
<g
|
|
||||||
transform="translate(75,43.1621)"
|
|
||||||
id="g20" />
|
|
||||||
<path
|
|
||||||
style="opacity:0.9;fill:#fcba02;fill-opacity:1;stroke-width:0.9930262"
|
|
||||||
d="M 42.700457,74.178768 C 24.766404,74.178768 10.2285,60.954638 10.2285,44.643189 V 15.107611 5.2627488 c 5.978017,0 10.823985,4.255117 10.823985,9.6909432 h 21.647972 c 17.934054,0 32.471954,13.377056 32.471954,29.689497 0,16.311449 -14.5379,29.535579 -32.471954,29.535579 z"
|
|
||||||
id="path10-3"
|
|
||||||
inkscape:connector-curvature="0" /><g
|
|
||||||
id="g46"
|
|
||||||
transform="translate(15.3208,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.592,-1.322 1.323,-1.322 0.732,0 1.324,0.593 1.324,1.322 0,0.73 -0.592,1.322 -1.324,1.322 C 0.592,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#fffda9;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path48"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g50"
|
|
||||||
transform="translate(21.8672,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.591,-1.322 1.321,-1.322 0.732,0 1.323,0.593 1.323,1.322 0,0.73 -0.591,1.322 -1.323,1.322 C 0.591,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#fffda9;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path52"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g54"
|
|
||||||
transform="translate(28.4116,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.591,-1.322 1.323,-1.322 0.729,0 1.321,0.593 1.321,1.322 0,0.73 -0.592,1.322 -1.321,1.322 C 0.591,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#fffda9;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path56"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g58"
|
|
||||||
transform="translate(34.9561,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.592,-1.322 1.323,-1.322 0.73,0 1.321,0.593 1.321,1.322 0,0.73 -0.591,1.322 -1.321,1.322 C 0.592,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#fffda9;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path60"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g62"
|
|
||||||
transform="translate(41.502,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.593,-1.322 1.32,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.593,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#fffda9;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path64"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g66"
|
|
||||||
transform="translate(48.0469,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.59,-1.322 1.32,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.59,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#fffda9;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path68"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g70"
|
|
||||||
transform="translate(54.5898,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.594,-1.322 1.32,-1.322 0.735,0 1.326,0.593 1.326,1.322 0,0.73 -0.591,1.322 -1.326,1.322 C 0.594,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#fffda9;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path72"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g74"
|
|
||||||
transform="translate(61.1377,45.7656)"><path
|
|
||||||
d="m 0,0 c 0,-0.729 0.59,-1.322 1.319,-1.322 0.732,0 1.322,0.593 1.322,1.322 0,0.73 -0.59,1.322 -1.322,1.322 C 0.59,1.322 0,0.73 0,0"
|
|
||||||
style="fill:#fffda9;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path76"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g78"
|
|
||||||
transform="translate(14,26.1348)"><path
|
|
||||||
d="m 0,0 c 0,-1.465 1.184,-2.646 2.644,-2.646 1.461,0 2.645,1.181 2.645,2.646 0,1.459 -1.184,2.641 -2.645,2.641 C 1.184,2.641 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path80"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g82"
|
|
||||||
transform="translate(20.5444,58.856)"><path
|
|
||||||
d="m 0,0 c 0,-1.462 1.185,-2.645 2.644,-2.645 1.461,0 2.645,1.183 2.645,2.645 0,1.459 -1.184,2.644 -2.645,2.644 C 1.185,2.644 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path84"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g86"
|
|
||||||
transform="translate(27.0894,52.3101)"><path
|
|
||||||
d="m 0,0 c 0,-1.461 1.185,-2.644 2.645,-2.644 1.461,0 2.644,1.183 2.644,2.644 0,1.46 -1.183,2.645 -2.644,2.645 C 1.185,2.645 0,1.46 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path88"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g90"
|
|
||||||
transform="translate(27.0894,26.1348)"><path
|
|
||||||
d="m 0,0 c 0,-1.465 1.185,-2.646 2.645,-2.646 1.461,0 2.644,1.181 2.644,2.646 0,1.459 -1.183,2.641 -2.644,2.641 C 1.185,2.641 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path92"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g94"
|
|
||||||
transform="translate(33.6338,58.856)"><path
|
|
||||||
d="M 0,0 C 0,-1.462 1.184,-2.645 2.646,-2.645 4.106,-2.645 5.29,-1.462 5.29,0 5.29,1.459 4.106,2.644 2.646,2.644 1.184,2.644 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path96"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g98"
|
|
||||||
transform="translate(40.1758,52.3101)"><path
|
|
||||||
d="m 0,0 c 0,-1.461 1.187,-2.644 2.646,-2.644 1.461,0 2.648,1.183 2.648,2.644 0,1.46 -1.187,2.645 -2.648,2.645 C 1.187,2.645 0,1.46 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path100"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g102"
|
|
||||||
transform="translate(40.1758,32.6768)"><path
|
|
||||||
d="m 0,0 c 0,-1.458 1.187,-2.646 2.646,-2.646 1.461,0 2.648,1.188 2.648,2.646 0,1.459 -1.187,2.645 -2.648,2.645 C 1.187,2.645 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path104"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g106"
|
|
||||||
transform="translate(40.1758,26.1348)"><path
|
|
||||||
d="m 0,0 c 0,-1.465 1.187,-2.646 2.646,-2.646 1.461,0 2.648,1.181 2.648,2.646 0,1.459 -1.187,2.641 -2.648,2.641 C 1.187,2.641 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path108"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g110"
|
|
||||||
transform="translate(46.7236,52.3101)"><path
|
|
||||||
d="m 0,0 c 0,-1.461 1.184,-2.644 2.644,-2.644 1.461,0 2.645,1.183 2.645,2.644 0,1.46 -1.184,2.645 -2.645,2.645 C 1.184,2.645 0,1.46 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path112"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g114"
|
|
||||||
transform="translate(46.7236,32.6768)"><path
|
|
||||||
d="m 0,0 c 0,-1.458 1.184,-2.646 2.644,-2.646 1.461,0 2.645,1.188 2.645,2.646 0,1.459 -1.184,2.645 -2.645,2.645 C 1.184,2.645 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path116"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g118"
|
|
||||||
transform="translate(53.2686,58.856)"><path
|
|
||||||
d="m 0,0 c 0,-1.462 1.183,-2.645 2.643,-2.645 1.461,0 2.645,1.183 2.645,2.645 0,1.459 -1.184,2.644 -2.645,2.644 C 1.183,2.644 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path120"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g122"
|
|
||||||
transform="translate(53.2686,52.3101)"><path
|
|
||||||
d="m 0,0 c 0,-1.461 1.183,-2.644 2.643,-2.644 1.461,0 2.645,1.183 2.645,2.644 0,1.46 -1.184,2.645 -2.645,2.645 C 1.183,2.645 0,1.46 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path124"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g126"
|
|
||||||
transform="translate(59.8135,39.2217)"><path
|
|
||||||
d="m 0,0 c 0,-1.459 1.187,-2.646 2.644,-2.646 1.461,0 2.644,1.187 2.644,2.646 0,1.459 -1.183,2.646 -2.644,2.646 C 1.187,2.646 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path128"
|
|
||||||
inkscape:connector-curvature="0" /></g><g
|
|
||||||
id="g130"
|
|
||||||
transform="translate(59.8135,32.6768)"><path
|
|
||||||
d="m 0,0 c 0,-1.458 1.187,-2.646 2.644,-2.646 1.461,0 2.644,1.188 2.644,2.646 0,1.459 -1.183,2.645 -2.644,2.645 C 1.187,2.645 0,1.459 0,0"
|
|
||||||
style="fill:#fffee3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
id="path132"
|
|
||||||
inkscape:connector-curvature="0" /></g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 4.8 KiB |
|
@ -1,39 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="enable-background:new 0 0 64 64;"
|
|
||||||
viewBox="0 0 64 64"
|
|
||||||
y="0px"
|
|
||||||
x="0px"
|
|
||||||
id="Layer_1"
|
|
||||||
version="1.1"><metadata
|
|
||||||
id="metadata17"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs15">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</defs>
|
|
||||||
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
d="m 37.855477,15.759299 c -1.73926,0.0029 -4.47725,1.553014 -6.64098,2.8829 -1.6826,1.034172 -3.75291,1.108852 -5.69886,1.124912 h -8.64063 c -1.034,0 -1.875,0.841 -1.875,1.875 v 8.070312 l 2,1.359376 v -9.304688 h 8.51563 c 2.75742,-0.06081 4.84074,-0.2051 6.5836,-1.513027 2.1377,-1.604239 4.80361,-2.501457 7.17616,-2.486973 h 18.51758 c 0.666,0 1.20703,0.541031 1.20703,1.207031 v 31.542969 c 0,0.689 -0.561,1.25 -1.25,1.25 h -39.5 c -0.689,0 -1.25,-0.561 -1.25,-1.25 V 42.08547 l -2,1.359375 v 7.072266 c 0,1.792 1.458,3.25 3.25,3.25 h 39.5 c 1.792,0 3.25,-1.458 3.25,-3.25 V 18.974142 c 0,-1.769 -1.43803,-3.207984 -3.20703,-3.208984 h -18.51758 c -0.4765,0 -0.94899,-0.01047 -1.41992,-0.0059 z"
|
|
||||||
id="path6-9" /><path
|
|
||||||
id="path11-6"
|
|
||||||
d="m 12.995027,29.476688 10.626,7.222 -10.626,7.222 v -14.444 m -2,-1.778 v 18 c 0,1.1 0.744,1.494 1.654,0.876 l 12.875,-8.752 c 0.455,-0.309 0.682,-0.717 0.682,-1.124 0,-0.408 -0.227,-0.815 -0.682,-1.124 l -12.875,-8.751 c -0.91,-0.619 -1.654,-0.225 -1.654,0.875 z"
|
|
||||||
style="fill:#ffffff" /><path
|
|
||||||
id="path5-0"
|
|
||||||
d="m 15.000437,21.683979 v -6.5 c 0,-1.832003 1.6,-3.500003 3.357,-3.500003 h 10.636 c 1.967,0 3.809,0.854 4.848,2.238003 l 3.457,2.756 c -2.99546,1.819905 -4.21018,2.916329 -6.43718,3.672261 -5.13259,1.742208 -10.47736,1.018549 -15.86082,1.333739 z"
|
|
||||||
style="opacity:0.6;fill:#ffffff" /><path
|
|
||||||
id="path9-3-6"
|
|
||||||
d="m 3.3670166,11.247132 c -0.004,1.278302 0.0179,17.502612 0.0179,17.502612 v 0.0059 0.0059 c 0.0626,4.141039 2.28159,6.407836 4.41211,7.382812 2.13052,0.974976 4.2070304,0.853516 4.2070304,0.853516"
|
|
||||||
style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" /></svg>
|
|
Before Width: | Height: | Size: 2.4 KiB |
|
@ -1,35 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="enable-background:new 0 0 32 32;"
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
height="32"
|
|
||||||
width="32"
|
|
||||||
y="0px"
|
|
||||||
x="0px"
|
|
||||||
id="Layer_1"
|
|
||||||
version="1.1"><metadata
|
|
||||||
id="metadata19"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs17" />
|
|
||||||
|
|
||||||
<circle
|
|
||||||
r="4"
|
|
||||||
cy="16"
|
|
||||||
cx="16"
|
|
||||||
id="path861-7"
|
|
||||||
style="opacity:0.6;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /><path
|
|
||||||
id="path826-6"
|
|
||||||
d="m 16.013202,10.0161 c -5.135781,-0.0066 -9.7712792,2.35462 -11.74455,5.983307 1.9732708,3.628688 6.608769,5.991032 11.74455,5.984494 5.107193,-0.0065 9.706497,-2.355358 11.682549,-5.954838 h 0.03565 c -0.0054,-0.01005 -0.01159,-0.01962 -0.01705,-0.02966 0.0055,-0.01002 0.01164,-0.01961 0.01705,-0.02966 h -0.03565 c -1.976079,-3.599428 -6.575398,-5.947148 -11.682549,-5.95365 z"
|
|
||||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /><circle
|
|
||||||
r="2"
|
|
||||||
cy="16"
|
|
||||||
cx="16"
|
|
||||||
id="path861"
|
|
||||||
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /></svg>
|
|
Before Width: | Height: | Size: 1.9 KiB |
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="enable-background:new 0 0 32 32;"
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
height="32"
|
|
||||||
width="32"
|
|
||||||
y="0px"
|
|
||||||
x="0px"
|
|
||||||
id="Layer_1"
|
|
||||||
version="1.1"><metadata
|
|
||||||
id="metadata19"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs17" />
|
|
||||||
|
|
||||||
<path
|
|
||||||
id="rect853-3-7"
|
|
||||||
d="m 5.2218178,19.08774 c -2.1185651,2.118565 -2.1185651,5.573984 -4e-7,7.692548 2.1185648,2.118565 5.5739836,2.118565 7.6925486,0 l 4.866883,-4.866883 c 2.118565,-2.118565 2.118565,-5.573984 0,-7.692549 -2.118564,-2.118564 -5.573983,-2.118564 -7.692548,0 z m 1.4142135,1.414213 4.8668837,-4.866883 c 1.359552,-1.359552 3.504569,-1.359552 4.864121,0 1.359553,1.359553 1.359552,3.504569 0,4.864121 l -4.866884,4.866883 c -1.359552,1.359553 -3.5045682,1.359554 -4.864121,10e-7 -1.3595521,-1.359552 -1.3595521,-3.504569 3e-7,-4.864122 z"
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
|
|
||||||
id="rect853-6"
|
|
||||||
d="m 17.290288,17.295275 c -0.604056,-0.141842 -1.179293,-0.451814 -1.657396,-0.929916 -1.359554,-1.359552 -1.358171,-3.503188 0.0014,-4.86274 l -1.7e-5,-4e-6 4.866884,-4.8668837 c 1.359553,-1.3595528 3.503187,-1.3609338 4.86274,-0.00138 1.359553,1.3595528 1.359553,3.5045687 1e-6,4.8641217 l -4.866884,4.866883 c -0.354012,0.354012 -0.76128,0.615843 -1.19407,0.785494 0.09971,0.686342 0.114666,1.379464 -0.04531,2.08658 0.973641,-0.21685 1.898514,-0.702806 2.653575,-1.457867 l 4.866884,-4.866884 c 2.118565,-2.118565 2.118564,-5.5739835 0,-7.6925482 -2.118565,-2.1185648 -5.572602,-2.1171831 -7.691168,0.00138 l -4.866865,4.8668902 c -2.118564,2.118564 -2.119946,5.572602 -0.0014,7.691167 0.825683,0.825683 1.854427,1.329567 2.927951,1.511652 0.245536,-0.61844 0.301651,-1.33063 0.143675,-1.995945 z"
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /></svg>
|
|
Before Width: | Height: | Size: 4.5 KiB |
|
@ -1,27 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="enable-background:new 0 0 32 32;"
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
height="32px"
|
|
||||||
width="32px"
|
|
||||||
y="0px"
|
|
||||||
x="0px"
|
|
||||||
id="Layer_1"
|
|
||||||
version="1.1"><metadata
|
|
||||||
id="metadata17"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs3" /> Updated upstream
|
|
||||||
id="defs15" /><path
|
|
||||||
id="path4567-6-9-2-9-0-3"
|
|
||||||
d="m 18.070362,15.595073 11.557261,13.3774 c 1.011409,0.983239 0.324995,1.686796 -0.658223,0.67537 L 15.619387,18.059831 Z"
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
|
|
||||||
id="rect814-5-6"
|
|
||||||
d="M 10.644531,1.8125 C 10.384078,1.8161365 10.13532,1.9212454 9.9511719,2.1054688 L 2.1210938,9.9355469 c -0.3903681,0.3905301 -0.3903681,1.0235321 0,1.4140621 l 4.4667968,4.46875 0.78125,8.173829 c 0.079282,0.842901 1.1046782,1.212138 1.703125,0.613281 l 7.7734374,-7.775391 7.775391,-7.7734374 c 0.598857,-0.5984471 0.22962,-1.623844 -0.613282,-1.703125 L 15.832031,6.5722656 11.365234,2.1054688 C 11.174385,1.9145467 10.91446,1.8088858 10.644531,1.8125 Z"
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.6;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /></svg>
|
|
Before Width: | Height: | Size: 3.8 KiB |
422
qml/components/AudioPreview.qml
Normal file
|
@ -0,0 +1,422 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber 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.
|
||||||
|
|
||||||
|
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import QtMultimedia 5.6
|
||||||
|
import "../js/functions.js" as Functions
|
||||||
|
import "../js/debug.js" as Debug
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: audioMessageComponent
|
||||||
|
|
||||||
|
property ListItem messageListItem
|
||||||
|
property MessageOverlayFlickable overlayFlickable
|
||||||
|
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
||||||
|
|
||||||
|
property var audioData: ( rawMessage.content['@type'] === "messageVoiceNote" ) ? rawMessage.content.voice_note : ( ( rawMessage.content['@type'] === "messageAudio" ) ? rawMessage.content.audio : "");
|
||||||
|
property string audioUrl;
|
||||||
|
property int previewFileId;
|
||||||
|
property int audioFileId;
|
||||||
|
property bool onScreen: messageListItem ? messageListItem.page.status === PageStatus.Active : true
|
||||||
|
property string audioType : "voiceNote";
|
||||||
|
property bool highlighted;
|
||||||
|
signal clicked();
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: width / 2
|
||||||
|
|
||||||
|
function getTimeString(rawSeconds) {
|
||||||
|
var minutes = Math.floor( rawSeconds / 60 );
|
||||||
|
var seconds = rawSeconds - ( minutes * 60 );
|
||||||
|
|
||||||
|
if ( minutes < 10 ) {
|
||||||
|
minutes = "0" + minutes;
|
||||||
|
}
|
||||||
|
if ( seconds < 10 ) {
|
||||||
|
seconds = "0" + seconds;
|
||||||
|
}
|
||||||
|
return minutes + ":" + seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
updateAudioThumbnail();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAudioThumbnail() {
|
||||||
|
if (audioData) {
|
||||||
|
audioType = ( audioData['@type'] === "voiceNote" ) ? "voice" : "audio";
|
||||||
|
audioFileId = audioData[audioType].id;
|
||||||
|
if (typeof audioData.album_cover_thumbnail !== "undefined") {
|
||||||
|
previewFileId = audioData.album_cover_thumbnail.photo.id;
|
||||||
|
if (audioData.album_cover_thumbnail.photo.local.is_downloading_completed) {
|
||||||
|
placeholderImage.source = audioData.album_cover_thumbnail.photo.local.path;
|
||||||
|
} else {
|
||||||
|
tdLibWrapper.downloadFile(previewFileId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
placeholderImage.source = "image://theme/icon-l-music?white";
|
||||||
|
placeholderImage.width = Theme.itemSizeLarge
|
||||||
|
placeholderImage.height = Theme.itemSizeLarge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePlay() {
|
||||||
|
if (audioData[audioType].local.is_downloading_completed) {
|
||||||
|
audioUrl = audioData[audioType].local.path;
|
||||||
|
audioComponentLoader.active = true;
|
||||||
|
} else {
|
||||||
|
audioDownloadBusyIndicator.running = true;
|
||||||
|
tdLibWrapper.downloadFile(audioFileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
onFileUpdated: {
|
||||||
|
if (typeof audioData === "object") {
|
||||||
|
if (fileInformation.local.is_downloading_completed) {
|
||||||
|
if (fileId === previewFileId) {
|
||||||
|
audioData.thumbnail.photo = fileInformation;
|
||||||
|
placeholderImage.source = fileInformation.local.path;
|
||||||
|
}
|
||||||
|
if (fileId === audioFileId) {
|
||||||
|
audioDownloadBusyIndicator.running = false;
|
||||||
|
audioData[audioType] = fileInformation;
|
||||||
|
audioUrl = fileInformation.local.path;
|
||||||
|
if (onScreen) {
|
||||||
|
audioComponentLoader.active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fileId === audioFileId) {
|
||||||
|
downloadingProgressBar.maximumValue = fileInformation.size;
|
||||||
|
downloadingProgressBar.value = fileInformation.local.downloaded_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: placeholderImage
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
anchors.centerIn: parent
|
||||||
|
asynchronous: true
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
visible: status === Image.Ready ? true : false
|
||||||
|
layer.enabled: audioMessageComponent.highlighted
|
||||||
|
layer.effect: PressEffect { source: singleImage }
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundImage {
|
||||||
|
visible: placeholderImage.status !== Image.Ready
|
||||||
|
layer.enabled: audioMessageComponent.highlighted
|
||||||
|
layer.effect: PressEffect { source: singleImage }
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: placeholderBackground
|
||||||
|
color: "black"
|
||||||
|
opacity: 0.3
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width
|
||||||
|
visible: playButton.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
height: downloadingProgressBar.height + audioControlRow.height
|
||||||
|
anchors.centerIn: parent
|
||||||
|
Row {
|
||||||
|
id: audioControlRow
|
||||||
|
width: parent.width
|
||||||
|
height: Theme.iconSizeLarge
|
||||||
|
Item {
|
||||||
|
height: Theme.iconSizeLarge
|
||||||
|
width: parent.width
|
||||||
|
IconButton {
|
||||||
|
id: playButton
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: Theme.iconSizeLarge
|
||||||
|
height: Theme.iconSizeLarge
|
||||||
|
icon {
|
||||||
|
source: "image://theme/icon-l-play?white"
|
||||||
|
asynchronous: true
|
||||||
|
}
|
||||||
|
highlighted: audioMessageComponent.highlighted || down
|
||||||
|
visible: placeholderImage.status === Image.Ready ? true : false
|
||||||
|
onClicked: {
|
||||||
|
handlePlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BusyIndicator {
|
||||||
|
id: audioDownloadBusyIndicator
|
||||||
|
running: false
|
||||||
|
visible: running
|
||||||
|
anchors.centerIn: parent
|
||||||
|
size: BusyIndicatorSize.Large
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProgressBar {
|
||||||
|
id: downloadingProgressBar
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 100
|
||||||
|
value: 0
|
||||||
|
visible: audioDownloadBusyIndicator.visible
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: audioErrorShade
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
color: "lightgrey"
|
||||||
|
visible: placeholderImage.status === Image.Error ? true : false
|
||||||
|
opacity: 0.3
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: errorTextOverlay
|
||||||
|
color: "black"
|
||||||
|
opacity: 0.8
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: errorText
|
||||||
|
visible: false
|
||||||
|
width: parent.width
|
||||||
|
color: Theme.primaryColor
|
||||||
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: audioComponentLoader
|
||||||
|
active: false
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
sourceComponent: audioComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: audioComponent
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent ? parent.width : 0
|
||||||
|
height: parent ? parent.height : 0
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: messageAudio
|
||||||
|
onPlaying: {
|
||||||
|
playButton.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: audioMessageComponent
|
||||||
|
onClicked: {
|
||||||
|
if (messageAudio.playbackState === MediaPlayer.PlayingState) {
|
||||||
|
messageAudio.pause();
|
||||||
|
timeLeftItem.visible = true;
|
||||||
|
} else {
|
||||||
|
messageAudio.play();
|
||||||
|
timeLeftTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio {
|
||||||
|
id: messageAudio
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (messageAudio.error === MediaPlayer.NoError) {
|
||||||
|
messageAudio.play();
|
||||||
|
timeLeftTimer.start();
|
||||||
|
} else {
|
||||||
|
errorText.text = qsTr("Error loading audio! " + messageAudio.errorString)
|
||||||
|
errorTextOverlay.visible = true;
|
||||||
|
errorText.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status == MediaPlayer.NoMedia) {
|
||||||
|
Debug.log("No Media");
|
||||||
|
audioBusyIndicator.visible = false;
|
||||||
|
}
|
||||||
|
if (status == MediaPlayer.Loading) {
|
||||||
|
Debug.log("Loading");
|
||||||
|
audioBusyIndicator.visible = true;
|
||||||
|
}
|
||||||
|
if (status == MediaPlayer.Loaded) {
|
||||||
|
Debug.log("Loaded");
|
||||||
|
audioBusyIndicator.visible = false;
|
||||||
|
}
|
||||||
|
if (status == MediaPlayer.Buffering) {
|
||||||
|
Debug.log("Buffering");
|
||||||
|
audioBusyIndicator.visible = true;
|
||||||
|
}
|
||||||
|
if (status == MediaPlayer.Stalled) {
|
||||||
|
Debug.log("Stalled");
|
||||||
|
audioBusyIndicator.visible = true;
|
||||||
|
}
|
||||||
|
if (status == MediaPlayer.Buffered) {
|
||||||
|
Debug.log("Buffered");
|
||||||
|
audioBusyIndicator.visible = false;
|
||||||
|
}
|
||||||
|
if (status == MediaPlayer.EndOfMedia) {
|
||||||
|
Debug.log("End of Media");
|
||||||
|
audioBusyIndicator.visible = false;
|
||||||
|
}
|
||||||
|
if (status == MediaPlayer.InvalidMedia) {
|
||||||
|
Debug.log("Invalid Media");
|
||||||
|
audioBusyIndicator.visible = false;
|
||||||
|
}
|
||||||
|
if (status == MediaPlayer.UnknownStatus) {
|
||||||
|
Debug.log("Unknown Status");
|
||||||
|
audioBusyIndicator.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source: audioUrl
|
||||||
|
|
||||||
|
onStopped: {
|
||||||
|
playButton.visible = true;
|
||||||
|
audioComponentLoader.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
id: audioBusyIndicator
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: false
|
||||||
|
running: visible
|
||||||
|
size: BusyIndicatorSize.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: timeLeftTimer
|
||||||
|
repeat: false
|
||||||
|
interval: 2000
|
||||||
|
onTriggered: {
|
||||||
|
timeLeftItem.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: timeLeftItem
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { NumberAnimation {} }
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: positionTextOverlay
|
||||||
|
color: "black"
|
||||||
|
opacity: 0.3
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: pausedRow.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: pausedRow
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - ( messageAudioSlider.visible ? messageAudioSlider.height : 0 ) - ( positionText.visible ? positionText.height : 0 )
|
||||||
|
visible: audioComponentLoader.active && messageAudio.playbackState === MediaPlayer.PausedState
|
||||||
|
Item {
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width
|
||||||
|
IconButton {
|
||||||
|
id: pausedPlayButton
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: Theme.iconSizeLarge
|
||||||
|
height: Theme.iconSizeLarge
|
||||||
|
highlighted: videoMessageComponent.highlighted || down
|
||||||
|
icon {
|
||||||
|
asynchronous: true
|
||||||
|
source: "image://theme/icon-l-play?white"
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
messageAudio.play();
|
||||||
|
timeLeftTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
id: messageAudioSlider
|
||||||
|
width: parent.width
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: positionText.top
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: messageAudio.duration ? messageAudio.duration : 0
|
||||||
|
stepSize: 1
|
||||||
|
value: messageAudio.position
|
||||||
|
enabled: messageAudio.seekable
|
||||||
|
visible: (messageAudio.duration > 0)
|
||||||
|
highlighted: videoMessageComponent.highlighted || down
|
||||||
|
onReleased: {
|
||||||
|
messageAudio.seek(Math.floor(value));
|
||||||
|
messageAudio.play();
|
||||||
|
timeLeftTimer.start();
|
||||||
|
}
|
||||||
|
valueText: getTimeString(Math.round((messageAudio.duration - messageAudioSlider.value) / 1000))
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: positionText
|
||||||
|
visible: messageAudio.duration === 0
|
||||||
|
color: Theme.primaryColor
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: Theme.paddingSmall
|
||||||
|
horizontalCenter: positionTextOverlay.horizontalCenter
|
||||||
|
}
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: ( messageAudio.duration - messageAudio.position ) > 0 ? getTimeString(Math.round((messageAudio.duration - messageAudio.position) / 1000)) : "-:-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,98 +9,54 @@ PhotoTextsListItem {
|
||||||
id: listItem
|
id: listItem
|
||||||
pictureThumbnail {
|
pictureThumbnail {
|
||||||
photoData: photo_small || ({})
|
photoData: photo_small || ({})
|
||||||
highlighted: listItem.highlighted && !listItem.menuOpen
|
|
||||||
}
|
}
|
||||||
property int ownUserId
|
property int ownUserId
|
||||||
property bool showDraft: !!draft_message_text && draft_message_date > last_message_date
|
|
||||||
property string previewText: showDraft ? draft_message_text : last_message_text
|
|
||||||
|
|
||||||
// chat title
|
// chat title
|
||||||
primaryText.text: title ? Emoji.emojify(title, Theme.fontSizeMedium) : qsTr("Unknown")
|
primaryText.text: title ? Emoji.emojify(title + ( display.notification_settings.mute_for > 0 ? " 🔇" : "" ), Theme.fontSizeMedium) : qsTr("Unknown")
|
||||||
// last user
|
// last user
|
||||||
prologSecondaryText.text: showDraft ? "<i>"+qsTr("Draft")+"</i>" : (is_channel ? "" : ( last_message_sender_id ? ( last_message_sender_id !== ownUserId ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(last_message_sender_id)), Theme.fontSizeExtraSmall) : qsTr("You") ) : "" ))
|
prologSecondaryText.text: is_channel ? "" : ( last_message_sender_id ? ( last_message_sender_id !== ownUserId ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(last_message_sender_id)), primaryText.font.pixelSize) : qsTr("You") ) : "" )
|
||||||
// last message
|
// last message
|
||||||
secondaryText.text: previewText ? Emoji.emojify(Functions.enhanceHtmlEntities(previewText), Theme.fontSizeExtraSmall) : "<i>" + qsTr("No message in this chat.") + "</i>"
|
secondaryText.text: last_message_text ? Emoji.emojify(Functions.enhanceHtmlEntities(last_message_text), Theme.fontSizeExtraSmall) : "<i>" + qsTr("No message in this chat.") + "</i>"
|
||||||
// message date
|
// message date
|
||||||
tertiaryText.text: showDraft ? Functions.getDateTimeElapsed(draft_message_date) : ( last_message_date ? ( last_message_date.length === 0 ? "" : Functions.getDateTimeElapsed(last_message_date) + Emoji.emojify(last_message_status, tertiaryText.font.pixelSize) ) : "" )
|
tertiaryText.text: ( last_message_date ? ( last_message_date.length === 0 ? "" : Functions.getDateTimeElapsed(last_message_date) + Emoji.emojify(last_message_status, tertiaryText.font.pixelSize) ) : "" )
|
||||||
unreadCount: unread_count
|
unreadCount: unread_count
|
||||||
unreadReactionCount: unread_reaction_count
|
|
||||||
unreadMentionCount: unread_mention_count
|
|
||||||
isSecret: ( chat_type === TelegramAPI.ChatTypeSecret )
|
isSecret: ( chat_type === TelegramAPI.ChatTypeSecret )
|
||||||
isMarkedAsUnread: is_marked_as_unread
|
|
||||||
isPinned: is_pinned
|
|
||||||
isMuted: display.notification_settings.mute_for > 0
|
|
||||||
|
|
||||||
openMenuOnPressAndHold: true//chat_id != overviewPage.ownUserId
|
openMenuOnPressAndHold: true//chat_id != overviewPage.ownUserId
|
||||||
|
menu: ContextMenu {
|
||||||
onPressAndHold: {
|
MenuItem {
|
||||||
contextMenuLoader.active = true;
|
visible: unread_count > 0
|
||||||
}
|
onClicked: {
|
||||||
|
tdLibWrapper.viewMessage(chat_id, display.last_message.id, true);
|
||||||
Loader {
|
|
||||||
id: contextMenuLoader
|
|
||||||
active: false
|
|
||||||
asynchronous: true
|
|
||||||
onStatusChanged: {
|
|
||||||
if(status === Loader.Ready) {
|
|
||||||
listItem.menu = item;
|
|
||||||
listItem.openMenu();
|
|
||||||
}
|
}
|
||||||
|
text: qsTr("Mark all messages as read")
|
||||||
}
|
}
|
||||||
sourceComponent: Component {
|
|
||||||
ContextMenu {
|
|
||||||
MenuItem {
|
|
||||||
visible: unread_count > 0 || unread_reaction_count > 0 || unread_mention_count > 0
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.viewMessage(chat_id, display.last_message.id, true);
|
|
||||||
tdLibWrapper.readAllChatMentions(chat_id);
|
|
||||||
tdLibWrapper.readAllChatReactions(chat_id);
|
|
||||||
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, false);
|
|
||||||
}
|
|
||||||
text: qsTr("Mark all messages as read")
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
visible: unread_count === 0 && unread_reaction_count === 0 && unread_mention_count === 0
|
visible: chat_id != listItem.ownUserId
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, !is_marked_as_unread);
|
var newNotificationSettings = display.notification_settings;
|
||||||
}
|
if (newNotificationSettings.mute_for > 0) {
|
||||||
text: is_marked_as_unread ? qsTr("Mark chat as read") : qsTr("Mark chat as unread")
|
newNotificationSettings.mute_for = 0;
|
||||||
}
|
} else {
|
||||||
|
newNotificationSettings.mute_for = 6666666;
|
||||||
MenuItem {
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.toggleChatIsPinned(chat_id, !is_pinned);
|
|
||||||
}
|
|
||||||
text: is_pinned ? qsTr("Unpin chat") : qsTr("Pin chat")
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
visible: chat_id != listItem.ownUserId
|
|
||||||
onClicked: {
|
|
||||||
var newNotificationSettings = display.notification_settings;
|
|
||||||
if (newNotificationSettings.mute_for > 0) {
|
|
||||||
newNotificationSettings.mute_for = 0;
|
|
||||||
} else {
|
|
||||||
newNotificationSettings.mute_for = 6666666;
|
|
||||||
}
|
|
||||||
newNotificationSettings.use_default_mute_for = false;
|
|
||||||
tdLibWrapper.setChatNotificationSettings(chat_id, newNotificationSettings);
|
|
||||||
}
|
|
||||||
text: display.notification_settings.mute_for > 0 ? qsTr("Unmute chat") : qsTr("Mute chat")
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
onClicked: {
|
|
||||||
if(pageStack.depth > 2) {
|
|
||||||
pageStack.pop(pageStack.find( function(page){ return(page._depth === 0)} ), PageStackAction.Immediate);
|
|
||||||
}
|
|
||||||
|
|
||||||
pageStack.push(Qt.resolvedUrl("../pages/ChatInformationPage.qml"), { "chatInformation" : display});
|
|
||||||
}
|
|
||||||
text: model.display.type['@type'] === "chatTypePrivate" ? qsTr("User Info") : qsTr("Group Info")
|
|
||||||
}
|
}
|
||||||
|
newNotificationSettings.use_default_mute_for = false;
|
||||||
|
tdLibWrapper.setChatNotificationSettings(chat_id, newNotificationSettings);
|
||||||
}
|
}
|
||||||
|
text: display.notification_settings.mute_for > 0 ? qsTr("Unmute Chat") : qsTr("Mute Chat")
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
onClicked: {
|
||||||
|
if(pageStack.depth > 2) {
|
||||||
|
pageStack.pop(pageStack.find( function(page){ return(page._depth === 0)} ), PageStackAction.Immediate);
|
||||||
|
}
|
||||||
|
|
||||||
|
pageStack.push(Qt.resolvedUrl("../pages/ChatInformationPage.qml"), { "chatInformation" : display});
|
||||||
|
}
|
||||||
|
text: model.display.type['@type'] === "chatTypePrivate" ? qsTr("User Info") : qsTr("Group Info")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.0
|
|
||||||
//import org.nemomobile.contacts 1.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
|
|
||||||
// signal syncError();
|
|
||||||
|
|
||||||
// function synchronize() {
|
|
||||||
// if (peopleModel.count === 0) {
|
|
||||||
// appNotification.show(qsTr("Could not synchronize your contacts with Telegram."));
|
|
||||||
// syncError();
|
|
||||||
// } else {
|
|
||||||
// contactsModel.startImportingContacts();
|
|
||||||
// for (var i = 0; i < peopleModel.count; i++ ) {
|
|
||||||
// contactsModel.importContact(peopleModel.get(i));
|
|
||||||
// }
|
|
||||||
// contactsModel.stopImportingContacts();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// PeopleModel {
|
|
||||||
// id: peopleModel
|
|
||||||
// requiredProperty: PeopleModel.PhoneNumberRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
111
qml/components/DocumentPreview.qml
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber 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.
|
||||||
|
|
||||||
|
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
|
||||||
|
id: documentPreviewItem
|
||||||
|
width: parent.width
|
||||||
|
height: Theme.itemSizeLarge
|
||||||
|
|
||||||
|
property ListItem messageListItem
|
||||||
|
property MessageOverlayFlickable overlayFlickable
|
||||||
|
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
||||||
|
|
||||||
|
property var documentData: rawMessage.content.document
|
||||||
|
property bool openRequested: false;
|
||||||
|
property bool highlighted;
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
updateDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDocument() {
|
||||||
|
if (documentData) {
|
||||||
|
if (documentData.document.local.is_downloading_completed) {
|
||||||
|
downloadDocumentButton.visible = false;
|
||||||
|
openDocumentButton.visible = true;
|
||||||
|
} else {
|
||||||
|
openDocumentButton.visible = false;
|
||||||
|
downloadDocumentButton.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
onFileUpdated: {
|
||||||
|
if (documentData) {
|
||||||
|
if (!fileInformation.remote.is_uploading_active && fileId === documentData.document.id && fileInformation.local.is_downloading_completed) {
|
||||||
|
downloadingProgressBar.visible = false;
|
||||||
|
documentData.document = fileInformation;
|
||||||
|
downloadDocumentButton.visible = false;
|
||||||
|
openDocumentButton.visible = true;
|
||||||
|
if (documentPreviewItem.openRequested) {
|
||||||
|
documentPreviewItem.openRequested = false;
|
||||||
|
tdLibWrapper.openFileOnDevice(documentData.document.local.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fileId === documentData.document.id) {
|
||||||
|
downloadingProgressBar.maximumValue = fileInformation.size;
|
||||||
|
downloadingProgressBar.value = fileInformation.local.downloaded_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: downloadDocumentButton
|
||||||
|
preferredWidth: Theme.buttonWidthMedium
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: qsTr("Download Document")
|
||||||
|
visible: false
|
||||||
|
highlighted: videoMessageComponent.highlighted || down
|
||||||
|
onClicked: {
|
||||||
|
downloadDocumentButton.visible = false;
|
||||||
|
downloadingProgressBar.visible = true;
|
||||||
|
tdLibWrapper.downloadFile(documentData.document.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressBar {
|
||||||
|
id: downloadingProgressBar
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 100
|
||||||
|
value: 0
|
||||||
|
visible: false
|
||||||
|
width: parent.width
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: openDocumentButton
|
||||||
|
preferredWidth: Theme.buttonWidthMedium
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: qsTr("Open Document")
|
||||||
|
visible: false
|
||||||
|
highlighted: videoMessageComponent.highlighted || down
|
||||||
|
onClicked: {
|
||||||
|
documentPreviewItem.openRequested = true;
|
||||||
|
tdLibWrapper.openFileOnDevice(documentData.document.local.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
86
qml/components/ImagePreview.qml
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber 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.
|
||||||
|
|
||||||
|
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: imagePreviewItem
|
||||||
|
|
||||||
|
property ListItem messageListItem
|
||||||
|
property MessageOverlayFlickable overlayFlickable
|
||||||
|
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
||||||
|
property var photoData: rawMessage.content.photo
|
||||||
|
readonly property int defaultHeight: Math.round(width * 2 / 3)
|
||||||
|
property bool highlighted
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: singleImage.visible ? Math.min(defaultHeight, singleImage.bestHeight + Theme.paddingSmall) : defaultHeight
|
||||||
|
|
||||||
|
function clicked() {
|
||||||
|
pageStack.push(Qt.resolvedUrl("../pages/ImagePage.qml"), {
|
||||||
|
"photoData" : imagePreviewItem.photoData,
|
||||||
|
"pictureFileInformation" : imageFile.fileInformation
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (photoData) {
|
||||||
|
// Check first which size fits best...
|
||||||
|
var photo
|
||||||
|
for (var i = 0; i < photoData.sizes.length; i++) {
|
||||||
|
photo = photoData.sizes[i].photo
|
||||||
|
if (photoData.sizes[i].width >= imagePreviewItem.width) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (photo) {
|
||||||
|
imageFile.fileInformation = photo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: imageFile
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
autoLoad: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: singleImage
|
||||||
|
width: parent.width - Theme.paddingSmall
|
||||||
|
height: parent.height - Theme.paddingSmall
|
||||||
|
readonly property int bestHeight: (status === Image.Ready) ? Math.round(implicitHeight * width / implicitWidth) : 0
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
autoTransform: true
|
||||||
|
asynchronous: true
|
||||||
|
source: imageFile.isDownloadingCompleted ? imageFile.path : ""
|
||||||
|
visible: status === Image.Ready
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
layer.enabled: imagePreviewItem.highlighted
|
||||||
|
layer.effect: PressEffect { source: singleImage }
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundImage {
|
||||||
|
visible: singleImage.status !== Image.Ready
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,21 +31,13 @@ Row {
|
||||||
property string myUserId;
|
property string myUserId;
|
||||||
property var inReplyToMessage;
|
property var inReplyToMessage;
|
||||||
property bool editable: false;
|
property bool editable: false;
|
||||||
property bool inReplyToMessageDeleted: false;
|
|
||||||
|
|
||||||
signal clearRequested()
|
signal clearRequested()
|
||||||
|
|
||||||
onInReplyToMessageChanged: {
|
onInReplyToMessageChanged: {
|
||||||
if (inReplyToMessage) {
|
if (inReplyToMessage) {
|
||||||
inReplyToUserText.text = (inReplyToMessage.sender_id["@type"] === "messageSenderChat" ? page.chatInformation.title : (inReplyToRow.inReplyToMessage.sender_id.user_id !== inReplyToRow.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(inReplyToRow.inReplyToMessage.sender_id.user_id)), inReplyToUserText.font.pixelSize) : qsTr("You"));
|
inReplyToUserText.text = (inReplyToRow.inReplyToMessage.sender.user_id !== inReplyToRow.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(inReplyToRow.inReplyToMessage.sender.user_id)), inReplyToUserText.font.pixelSize) : qsTr("You");
|
||||||
inReplyToMessageText.text = Emoji.emojify(Functions.getMessageText(inReplyToRow.inReplyToMessage, true, inReplyToRow.myUserId, false), inReplyToMessageText.font.pixelSize);
|
inReplyToMessageText.text = Emoji.emojify(Functions.getMessageText(inReplyToRow.inReplyToMessage, true, inReplyToRow.inReplyToMessage.sender.user_id === inReplyToRow.myUserId, false), inReplyToMessageText.font.pixelSize);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onInReplyToMessageDeletedChanged: {
|
|
||||||
if (inReplyToMessageDeleted) {
|
|
||||||
inReplyToUserText.text = qsTr("Unknown")
|
|
||||||
inReplyToMessageText.text = "<i>" + qsTr("This message was deleted") + "</i>";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,399 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "../js/debug.js" as Debug
|
|
||||||
import "../js/twemoji.js" as Emoji
|
|
||||||
import "../js/functions.js" as Functions
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: inlineQueryLoader
|
|
||||||
active: userName.length > 1
|
|
||||||
asynchronous: true
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
bottom: active ? parent.bottom : parent.top
|
|
||||||
}
|
|
||||||
property bool hasOverlay: active && userNameIsValid && status === Loader.Ready && item.overlay && item.overlay.status === Loader.Ready
|
|
||||||
property bool hasButton: active && userNameIsValid && status === Loader.Ready && item.button && item.button.status === Loader.Ready
|
|
||||||
|
|
||||||
property int buttonPadding: hasButton ? item.button.height + Theme.paddingSmall : 0
|
|
||||||
Behavior on buttonPadding { NumberAnimation { duration: 200} }
|
|
||||||
|
|
||||||
property string chatId
|
|
||||||
property string userName
|
|
||||||
property bool userNameIsValid: userName !== "" && inlineBotInformation && userName.toLowerCase() === inlineBotInformation.usernames.editable_username.toLowerCase()
|
|
||||||
property string query
|
|
||||||
property int currentOffset: 0
|
|
||||||
property string responseExtra: chatId+"|"+userName+"|"+query+"|"+currentOffset
|
|
||||||
|
|
||||||
property bool queued: false
|
|
||||||
property TextArea textField
|
|
||||||
property bool isLoading
|
|
||||||
property var inlineBotInformation: null
|
|
||||||
onIsLoadingChanged: {
|
|
||||||
requestTimeout.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
onStatusChanged: {
|
|
||||||
inlineBotInformation = null;
|
|
||||||
if(status === Loader.Ready && userName !== "") {
|
|
||||||
isLoading = true; inlineQueryLoader.chatId
|
|
||||||
tdLibWrapper.searchPublicChat(userName, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onUserNameChanged: {
|
|
||||||
inlineBotInformation = null;
|
|
||||||
|
|
||||||
if(status === Loader.Ready && userName !== "") {
|
|
||||||
isLoading = true;
|
|
||||||
tdLibWrapper.searchPublicChat(userName, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onQueryChanged: {
|
|
||||||
if(userName.length > 0) {
|
|
||||||
isLoading = true;
|
|
||||||
requestTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleQuery(name, query, offset) {
|
|
||||||
if(!name) {
|
|
||||||
inlineQueryLoader.userName = "";
|
|
||||||
inlineQueryLoader.query = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(inlineQueryLoader.userName !== name) {
|
|
||||||
inlineQueryLoader.userName = name
|
|
||||||
}
|
|
||||||
if(inlineQueryLoader.query !== query) {
|
|
||||||
inlineQueryLoader.query = query
|
|
||||||
}
|
|
||||||
inlineQueryLoader.currentOffset = offset || 0
|
|
||||||
}
|
|
||||||
|
|
||||||
function request() {
|
|
||||||
if(!inlineBotInformation || !userNameIsValid) {
|
|
||||||
queued = true;
|
|
||||||
} else {
|
|
||||||
queued = false;
|
|
||||||
var location = null;
|
|
||||||
if(inlineBotInformation.type.need_location && fernschreiberUtils.supportsGeoLocation()) {
|
|
||||||
fernschreiberUtils.startGeoLocationUpdates();
|
|
||||||
if(!attachmentPreviewRow.locationData.latitude) {
|
|
||||||
queued = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tdLibWrapper.getInlineQueryResults(inlineBotInformation.id, chatId, location, query, inlineQueryLoader.currentOffset, inlineQueryLoader.responseExtra);
|
|
||||||
isLoading = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: requestTimeout
|
|
||||||
interval: 5000
|
|
||||||
onTriggered: {
|
|
||||||
inlineQueryLoader.isLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: requestTimer
|
|
||||||
interval: 1000
|
|
||||||
onTriggered: {
|
|
||||||
request();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: fernschreiberUtils
|
|
||||||
onNewPositionInformation: {
|
|
||||||
attachmentPreviewRow.locationData = positionInformation;
|
|
||||||
if (inlineQueryLoader.queued) {
|
|
||||||
inlineQueryLoader.queued = false;
|
|
||||||
inlineQueryLoader.request()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: textField
|
|
||||||
onTextChanged: {
|
|
||||||
if(textField.text.charAt(0) === '@') {
|
|
||||||
var queryMatch = textField.text.match(/^@([a-zA-Z0-9_]+)\s(.*)/);
|
|
||||||
if(queryMatch) {
|
|
||||||
inlineQueryLoader.handleQuery(queryMatch[1], queryMatch[2]);
|
|
||||||
} else {
|
|
||||||
inlineQueryLoader.handleQuery();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
inlineQueryLoader.handleQuery();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: Component {
|
|
||||||
Item {
|
|
||||||
id: inlineQueryComponent
|
|
||||||
anchors.fill: parent
|
|
||||||
property alias overlay: resultsOverlay
|
|
||||||
property alias button: switchToPmLoader
|
|
||||||
property string nextOffset
|
|
||||||
property string inlineQueryId
|
|
||||||
property string switchPmText
|
|
||||||
property string switchPmParameter
|
|
||||||
property ListModel resultModel: ListModel {
|
|
||||||
dynamicRoles: true
|
|
||||||
}
|
|
||||||
property string inlineQueryPlaceholder: inlineBotInformation ? inlineBotInformation.type.inline_query_placeholder : ""
|
|
||||||
property bool showInlineQueryPlaceholder: !!inlineQueryPlaceholder && query === ""
|
|
||||||
property string useDelegateSize: "default"
|
|
||||||
property var dimensions: ({
|
|
||||||
"default": [[Screen.width, Screen.height / 2], [Theme.itemSizeLarge, Theme.itemSizeLarge]], // whole line (portrait half)
|
|
||||||
"inlineQueryResultAnimation": [[Screen.width / 3, Screen.height / 6], [Screen.width / 3, Screen.height / 6]],
|
|
||||||
"inlineQueryResultVideo": [[Screen.width / 2, Screen.height / 4], [Theme.itemSizeLarge, Theme.itemSizeLarge]],
|
|
||||||
"inlineQueryResultSticker": [[Screen.width / 3, Screen.height / 6], [Screen.width / 3, Screen.height / 6]],
|
|
||||||
"inlineQueryResultPhoto": [[Screen.width/2, Screen.height / 3], [Theme.itemSizeExtraLarge, Theme.itemSizeExtraLarge]],
|
|
||||||
})
|
|
||||||
property int delegateWidth: chatPage.isPortrait ? dimensions[useDelegateSize][0][0] : dimensions[useDelegateSize][0][1]
|
|
||||||
property int delegateHeight: chatPage.isPortrait ? dimensions[useDelegateSize][1][0] : dimensions[useDelegateSize][1][1]
|
|
||||||
|
|
||||||
function setDelegateSizes() {
|
|
||||||
var sizeKey = "default";
|
|
||||||
var modelCount = resultModel.count;
|
|
||||||
if(modelCount > 0) {
|
|
||||||
var firstType = resultModel.get(0)["@type"];
|
|
||||||
if(firstType && dimensions[firstType]) {
|
|
||||||
var startIndex = inlineQueryLoader.currentOffset === 0 ? 1 : inlineQueryLoader.currentOffset;
|
|
||||||
var same = true;
|
|
||||||
for(var i = startIndex; i < modelCount; i += 1) {
|
|
||||||
if(resultModel.get(i)["@type"] !== firstType) {
|
|
||||||
same = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(same) {
|
|
||||||
sizeKey = firstType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
useDelegateSize = sizeKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadMore() {
|
|
||||||
if(nextOffset && inlineQueryLoader.userNameIsValid) {
|
|
||||||
inlineQueryLoader.currentOffset = nextOffset;
|
|
||||||
inlineQueryLoader.request();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
|
|
||||||
onChatReceived: {
|
|
||||||
if(chat["@extra"] === "searchPublicChat:"+inlineQueryLoader.userName) {
|
|
||||||
requestTimeout.stop();
|
|
||||||
inlineQueryLoader.isLoading = false;
|
|
||||||
var inlineBotInformation = tdLibWrapper.getUserInformation(chat.type.user_id);
|
|
||||||
if(inlineBotInformation && inlineBotInformation.type["@type"] === "userTypeBot" && inlineBotInformation.type.is_inline) {
|
|
||||||
inlineQueryLoader.inlineBotInformation = inlineBotInformation;
|
|
||||||
requestTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onInlineQueryResults: {
|
|
||||||
if(extra === inlineQueryLoader.responseExtra) {
|
|
||||||
requestTimeout.stop();
|
|
||||||
inlineQueryLoader.isLoading = false;
|
|
||||||
inlineQueryComponent.inlineQueryId = inlineQueryId
|
|
||||||
inlineQueryComponent.nextOffset = nextOffset
|
|
||||||
inlineQueryComponent.switchPmText = switchPmText
|
|
||||||
inlineQueryComponent.switchPmParameter = switchPmParameter
|
|
||||||
|
|
||||||
if(inlineQueryLoader.currentOffset === 0) {
|
|
||||||
inlineQueryComponent.resultModel.clear()
|
|
||||||
}
|
|
||||||
for(var i = 0; i < results.length; i++) {
|
|
||||||
inlineQueryComponent.resultModel.append(results[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(inlineQueryLoader.currentOffset === 0 || inlineQueryLoader.useDelegateSize !== "default") {
|
|
||||||
inlineQueryComponent.setDelegateSizes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// switch to pm Button
|
|
||||||
Loader {
|
|
||||||
id: switchToPmLoader
|
|
||||||
asynchronous: true
|
|
||||||
active: inlineQueryComponent.switchPmText.length > 0
|
|
||||||
opacity: status === Loader.Ready ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
height: Theme.itemSizeSmall
|
|
||||||
anchors {
|
|
||||||
top: parent.bottom
|
|
||||||
topMargin: Theme.paddingSmall
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: Theme.horizontalPageMargin
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: Theme.horizontalPageMargin
|
|
||||||
}
|
|
||||||
sourceComponent: Component {
|
|
||||||
MouseArea {
|
|
||||||
id: customButton
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.createPrivateChat(inlineQueryLoader.inlineBotInformation.id, "openAndSendStartToBot:"+(inlineQueryComponent.switchPmParameter.length > 0 ? " "+inlineQueryComponent.switchPmParameter:""));
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: Theme.paddingSmall
|
|
||||||
color: parent.pressed ? Theme.highlightBackgroundColor : Theme.rgba(Theme.DarkOnLight ? Qt.lighter(Theme.primaryColor) : Qt.darker(Theme.primaryColor), Theme.opacityFaint)
|
|
||||||
Label {
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
leftMargin: Theme.paddingLarge
|
|
||||||
rightMargin: Theme.paddingLarge
|
|
||||||
}
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
|
|
||||||
fontSizeMode: Text.Fit;
|
|
||||||
minimumPixelSize: Theme.fontSizeTiny;
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
|
|
||||||
color: customButton.pressed ? Theme.highlightColor : Theme.primaryColor
|
|
||||||
text: Emoji.emojify(inlineQueryComponent.switchPmText, font.pixelSize)// + "we are gonna make this a bit longer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// results grid overlay
|
|
||||||
Loader {
|
|
||||||
id: resultsOverlay
|
|
||||||
asynchronous: true
|
|
||||||
active: inlineQueryComponent.resultModel.count > 0
|
|
||||||
anchors.fill: parent
|
|
||||||
opacity: !!item ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
property var supportedResultTypes: [
|
|
||||||
"inlineQueryResultAnimation",
|
|
||||||
"inlineQueryResultArticle",
|
|
||||||
"inlineQueryResultAudio",
|
|
||||||
"inlineQueryResultContact",
|
|
||||||
"inlineQueryResultDocument",
|
|
||||||
"inlineQueryResultGame",
|
|
||||||
"inlineQueryResultLocation",
|
|
||||||
"inlineQueryResultPhoto",
|
|
||||||
"inlineQueryResultSticker",
|
|
||||||
"inlineQueryResultVenue",
|
|
||||||
"inlineQueryResultVideo",
|
|
||||||
"inlineQueryResultVoiceNote",
|
|
||||||
]
|
|
||||||
sourceComponent: Component {
|
|
||||||
Item {
|
|
||||||
Rectangle {
|
|
||||||
id: messageContentBackground
|
|
||||||
color: Theme.overlayBackgroundColor
|
|
||||||
opacity: 0.7
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
Timer {
|
|
||||||
id: autoLoadMoreTimer
|
|
||||||
interval: 400
|
|
||||||
onTriggered: {
|
|
||||||
if (inlineQueryComponent.nextOffset && resultView.height > resultView.contentHeight - Theme.itemSizeHuge) {
|
|
||||||
inlineQueryComponent.loadMore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SilicaGridView {
|
|
||||||
id: resultView
|
|
||||||
anchors.fill: parent
|
|
||||||
cellWidth: inlineQueryComponent.delegateWidth
|
|
||||||
cellHeight: inlineQueryComponent.delegateHeight
|
|
||||||
|
|
||||||
signal requestPlayback(url playbackSource)
|
|
||||||
clip: true
|
|
||||||
model: inlineQueryComponent.resultModel
|
|
||||||
delegate: Loader {
|
|
||||||
id: queryResultDelegate
|
|
||||||
height: resultView.cellHeight
|
|
||||||
width: resultView.cellWidth
|
|
||||||
source: "inlineQueryResults/" + (resultsOverlay.supportedResultTypes.indexOf(model["@type"]) > -1 ? (model["@type"].charAt(0).toUpperCase() + model["@type"].substring(1)) : "InlineQueryResultDefaultBase") +".qml"
|
|
||||||
}
|
|
||||||
footer: Component {
|
|
||||||
Item {
|
|
||||||
width: resultView.width
|
|
||||||
visible: height > 0
|
|
||||||
height: inlineQueryComponent.nextOffset ? Theme.itemSizeLarge : 0
|
|
||||||
Behavior on height { NumberAnimation { duration: 500 } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onContentYChanged: {
|
|
||||||
if(!inlineQueryLoader.isLoading && inlineQueryComponent.nextOffset && contentHeight - contentY - height < Theme.itemSizeHuge) {
|
|
||||||
inlineQueryComponent.loadMore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollDecorator { flickable: resultView }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// textarea placeholder
|
|
||||||
Loader {
|
|
||||||
asynchronous: true
|
|
||||||
active: inlineQueryComponent.showInlineQueryPlaceholder
|
|
||||||
sourceComponent: Component {
|
|
||||||
Label {
|
|
||||||
text: Emoji.emojify(inlineQueryComponent.inlineQueryPlaceholder, font.pixelSize);
|
|
||||||
parent: textField
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.leftMargin: textMetrics.boundingRect.width + Theme.paddingSmall
|
|
||||||
font: textField.font
|
|
||||||
color: Theme.secondaryColor
|
|
||||||
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
TextMetrics {
|
|
||||||
id: textMetrics
|
|
||||||
font: textField.font
|
|
||||||
text: textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
112
qml/components/LocationPreview.qml
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber 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.
|
||||||
|
|
||||||
|
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
|
||||||
|
id: imagePreviewItem
|
||||||
|
|
||||||
|
property ListItem messageListItem
|
||||||
|
property MessageOverlayFlickable overlayFlickable
|
||||||
|
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
||||||
|
property bool highlighted
|
||||||
|
|
||||||
|
property var locationData : ( rawMessage.content['@type'] === "messageLocation" ) ? rawMessage.content.location : ( ( rawMessage.content['@type'] === "messageVenue" ) ? rawMessage.content.venue.location : "" )
|
||||||
|
|
||||||
|
property string chatId: rawMessage.chat_id
|
||||||
|
property var pictureFileInformation;
|
||||||
|
width: parent.width
|
||||||
|
height: width / 2
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
updatePicture();
|
||||||
|
}
|
||||||
|
function clicked(){
|
||||||
|
if(!processLauncher.launchProgram('harbour-pure-maps', ["geo:"+locationData.latitude+","+locationData.longitude])) {
|
||||||
|
imageNotification.show(qsTr("Install Pure Maps to inspect this location."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function updatePicture() {
|
||||||
|
imagePreviewItem.pictureFileInformation = null;
|
||||||
|
if (locationData) {
|
||||||
|
tdLibWrapper.getMapThumbnailFile(chatId, locationData.latitude, locationData.longitude, Math.round(imagePreviewItem.width), Math.round(imagePreviewItem.height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
onFileUpdated: {
|
||||||
|
// we do not have a way of knowing if this is the correct file, so we have to guess the first new one should be right.
|
||||||
|
if(!imagePreviewItem.pictureFileInformation) {
|
||||||
|
imagePreviewItem.pictureFileInformation = fileInformation;
|
||||||
|
tdLibWrapper.downloadFile(imagePreviewItem.pictureFileInformation.id);
|
||||||
|
} else if(imagePreviewItem.pictureFileInformation && fileInformation.id === imagePreviewItem.pictureFileInformation.id) {
|
||||||
|
imagePreviewItem.pictureFileInformation = fileInformation;
|
||||||
|
singleImage.source = fileInformation.local.path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AppNotification {
|
||||||
|
id: imageNotification
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: singleImage
|
||||||
|
width: parent.width - Theme.paddingSmall
|
||||||
|
height: parent.height - Theme.paddingSmall
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
autoTransform: true
|
||||||
|
asynchronous: true
|
||||||
|
visible: status === Image.Ready
|
||||||
|
opacity: status === Image.Ready ? 1 : 0
|
||||||
|
Behavior on opacity { NumberAnimation {} }
|
||||||
|
|
||||||
|
layer.enabled: imagePreviewItem.highlighted
|
||||||
|
layer.effect: PressEffect { source: singleImage }
|
||||||
|
Item {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: markerImage.width
|
||||||
|
height: markerImage.height * 1.75 // 0.875 (vertical pin point) * 2
|
||||||
|
Image {
|
||||||
|
id: markerImage
|
||||||
|
source: 'image://theme/icon-m-location'
|
||||||
|
}
|
||||||
|
|
||||||
|
DropShadow {
|
||||||
|
anchors.fill: markerImage
|
||||||
|
horizontalOffset: 3
|
||||||
|
verticalOffset: 3
|
||||||
|
radius: 8.0
|
||||||
|
samples: 17
|
||||||
|
color: Theme.colorScheme ? Theme.lightPrimaryColor : Theme.darkPrimaryColor
|
||||||
|
source: markerImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundImage {
|
||||||
|
visible: singleImage.status !== Image.Ready
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,200 +18,57 @@
|
||||||
*/
|
*/
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import "./messageContent"
|
|
||||||
import "../js/twemoji.js" as Emoji
|
import "../js/twemoji.js" as Emoji
|
||||||
import "../js/functions.js" as Functions
|
import "../js/functions.js" as Functions
|
||||||
import "../js/debug.js" as Debug
|
import "../js/debug.js" as Debug
|
||||||
|
|
||||||
ListItem {
|
ListItem {
|
||||||
id: messageListItem
|
id: messageListItem
|
||||||
contentHeight: messageBackground.height + Theme.paddingMedium + ( reactionsColumn.visible ? reactionsColumn.height : 0 )
|
contentHeight: messageBackground.height + Theme.paddingMedium
|
||||||
Behavior on contentHeight { NumberAnimation { duration: 200 } }
|
|
||||||
property var chatId
|
property var chatId
|
||||||
property var messageId
|
property var messageId
|
||||||
property int messageIndex
|
|
||||||
property int messageViewCount
|
|
||||||
property var myMessage
|
property var myMessage
|
||||||
property var reactions
|
|
||||||
property bool canReplyToMessage
|
property bool canReplyToMessage
|
||||||
readonly property bool isAnonymous: myMessage.sender_id["@type"] === "messageSenderChat"
|
readonly property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender.user_id)
|
||||||
readonly property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender_id.user_id)
|
|
||||||
property QtObject precalculatedValues: ListView.view.precalculatedValues
|
property QtObject precalculatedValues: ListView.view.precalculatedValues
|
||||||
readonly property color textColor: isOwnMessage ? Theme.highlightColor : Theme.primaryColor
|
readonly property color textColor: isOwnMessage ? Theme.highlightColor : Theme.primaryColor
|
||||||
readonly property int textAlign: Text.AlignLeft
|
readonly property int textAlign: isOwnMessage ? Text.AlignRight : Text.AlignLeft
|
||||||
readonly property Page page: precalculatedValues.page
|
readonly property Page page: precalculatedValues.page
|
||||||
readonly property bool isSelected: messageListItem.precalculatedValues.pageIsSelecting && page.selectedMessages.some(function(existingMessage) {
|
readonly property bool isSelected: messageListItem.precalculatedValues.pageIsSelecting && page.selectedMessages.some(function(existingMessage) {
|
||||||
return existingMessage.id === messageId
|
return existingMessage.id === messageId
|
||||||
});
|
});
|
||||||
readonly property bool isOwnMessage: page.myUserId === myMessage.sender_id.user_id
|
readonly property bool isOwnMessage: page.myUserId === myMessage.sender.user_id
|
||||||
readonly property bool canDeleteMessage: myMessage.can_be_deleted_for_all_users || (myMessage.can_be_deleted_only_for_self && myMessage.chat_id === page.myUserId)
|
property string extraContentComponentName
|
||||||
property bool hasContentComponent
|
|
||||||
property bool additionalOptionsOpened
|
|
||||||
property bool wasNavigatedTo: false
|
|
||||||
|
|
||||||
readonly property var additionalItemsModel: (extraContentLoader.item && ("extraContextMenuItems" in extraContentLoader.item)) ?
|
highlighted: (down || isSelected) && !menuOpen
|
||||||
extraContentLoader.item.extraContextMenuItems : 0
|
|
||||||
readonly property int numberOfExtraOptionsOtherThanDeleteMessage:
|
|
||||||
(showCopyMessageToClipboardMenuItem ? 0 : 1) +
|
|
||||||
(showForwardMessageMenuItem ? 0 : 1) +
|
|
||||||
(page.canPinMessages() ? 1 : 0) +
|
|
||||||
(additionalItemsModel ? additionalItemsModel.length : 0)
|
|
||||||
readonly property bool deleteMessageIsOnlyExtraOption: canDeleteMessage && !numberOfExtraOptionsOtherThanDeleteMessage
|
|
||||||
|
|
||||||
readonly property int maxContextMenuItemCount: page.isPortrait ? 5 : 4
|
|
||||||
readonly property int baseContextMenuItemCount: (canReplyToMessage ? 1 : 0) +
|
|
||||||
(myMessage.can_be_edited ? 1 : 0) + 2 /* "Select Message" and "More Options..." */
|
|
||||||
readonly property bool showCopyMessageToClipboardMenuItem: (baseContextMenuItemCount + 1) <= maxContextMenuItemCount
|
|
||||||
readonly property bool showForwardMessageMenuItem: (baseContextMenuItemCount + 2) <= maxContextMenuItemCount
|
|
||||||
// And don't count "More Options..." for "Delete Message" if "Delete Message" is the only extra option
|
|
||||||
readonly property bool haveSpaceForDeleteMessageMenuItem: (baseContextMenuItemCount + 3 - (deleteMessageIsOnlyExtraOption ? 1 : 0)) <= maxContextMenuItemCount
|
|
||||||
property var chatReactions
|
|
||||||
property var messageReactions
|
|
||||||
|
|
||||||
highlighted: (down || isSelected || additionalOptionsOpened || wasNavigatedTo) && !menuOpen
|
|
||||||
openMenuOnPressAndHold: !messageListItem.precalculatedValues.pageIsSelecting
|
openMenuOnPressAndHold: !messageListItem.precalculatedValues.pageIsSelecting
|
||||||
|
|
||||||
signal replyToMessage()
|
signal replyToMessage()
|
||||||
signal editMessage()
|
signal editMessage()
|
||||||
signal forwardMessage()
|
|
||||||
|
|
||||||
function deleteMessage() {
|
|
||||||
var chatId = page.chatInformation.id
|
|
||||||
var messageId = myMessage.id
|
|
||||||
Remorse.itemAction(messageListItem, qsTr("Message deleted"), function() {
|
|
||||||
tdLibWrapper.deleteMessages(chatId, [ messageId ]);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyMessageToClipboard() {
|
|
||||||
Clipboard.text = Functions.getMessageText(myMessage, true, userInformation.id, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
function openContextMenu() {
|
|
||||||
messageOptionsDrawer.open = false
|
|
||||||
if (menu) {
|
|
||||||
openMenu()
|
|
||||||
} else {
|
|
||||||
contextMenuLoader.active = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getInteractionText(viewCount, reactions, size, highlightColor) {
|
|
||||||
var interactionText = "";
|
|
||||||
if (viewCount > 0) {
|
|
||||||
interactionText = Emoji.emojify("👁️ ", size) + Functions.getShortenedCount(viewCount);
|
|
||||||
}
|
|
||||||
for (var i = 0; i < reactions.length; i++) {
|
|
||||||
var reaction = reactions[i]
|
|
||||||
var reactionText = reaction.reaction ? reaction.reaction : (reaction.type && reaction.type.emoji) ? reaction.type.emoji : ""
|
|
||||||
if (reactionText) {
|
|
||||||
interactionText += ( " " + Emoji.emojify(reactionText, size) );
|
|
||||||
if (!chatPage.isPrivateChat) {
|
|
||||||
var count = Functions.getShortenedCount(reaction.total_count)
|
|
||||||
interactionText += " "
|
|
||||||
interactionText += (reaction.is_chosen ? ( "<font color='" + highlightColor + "'><b>" + count + "</b></font>" ) : count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return interactionText;
|
|
||||||
}
|
|
||||||
|
|
||||||
function openReactions() {
|
|
||||||
if (messageListItem.chatReactions) {
|
|
||||||
Debug.log("Using chat reactions")
|
|
||||||
messageListItem.messageReactions = chatReactions
|
|
||||||
showItemCompletelyTimer.requestedIndex = index;
|
|
||||||
showItemCompletelyTimer.start();
|
|
||||||
} else {
|
|
||||||
Debug.log("Obtaining message reactions")
|
|
||||||
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
|
|
||||||
}
|
|
||||||
selectReactionBubble.visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getContentWidthMultiplier() {
|
|
||||||
return Functions.isWidescreen(appWindow) ? 0.4 : 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (messageListItem.precalculatedValues.pageIsSelecting) {
|
if(messageListItem.precalculatedValues.pageIsSelecting) {
|
||||||
page.toggleMessageSelection(myMessage);
|
page.toggleMessageSelection(myMessage);
|
||||||
} else {
|
} else {
|
||||||
if (messageOptionsDrawer.sourceItem !== messageListItem) {
|
|
||||||
messageOptionsDrawer.open = false
|
|
||||||
}
|
|
||||||
// Allow extra context to react to click
|
// Allow extra context to react to click
|
||||||
var extraContent = extraContentLoader.item
|
var extraContent = extraContentLoader.item
|
||||||
if (extraContent && extraContentLoader.contains(mapToItem(extraContentLoader, mouse.x, mouse.y))) {
|
if (extraContent && ("clicked" in extraContent) && (typeof extraContent.clicked === "function") &&
|
||||||
|
mouseX >= extraContentLoader.x && mouseY >= extraContentLoader.y &&
|
||||||
|
mouseX < (extraContentLoader.x + extraContentLoader.width) &&
|
||||||
|
mouseY < (extraContentLoader.y + extraContentLoader.height)) {
|
||||||
extraContent.clicked()
|
extraContent.clicked()
|
||||||
} else if (webPagePreviewLoader.item) {
|
|
||||||
webPagePreviewLoader.item.clicked()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageListItem.messageReactions) {
|
|
||||||
messageListItem.messageReactions = null;
|
|
||||||
selectReactionBubble.visible = false;
|
|
||||||
} else {
|
|
||||||
selectReactionBubble.visible = !selectReactionBubble.visible;
|
|
||||||
elementSelected(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onDoubleClicked: {
|
|
||||||
if (messageListItem.chatReactions) {
|
|
||||||
Debug.log("Using chat reactions")
|
|
||||||
messageListItem.messageReactions = chatReactions
|
|
||||||
showItemCompletelyTimer.requestedIndex = index;
|
|
||||||
showItemCompletelyTimer.start();
|
|
||||||
} else {
|
|
||||||
Debug.log("Obtaining message reactions")
|
|
||||||
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPressAndHold: {
|
onPressAndHold: {
|
||||||
if (openMenuOnPressAndHold) {
|
if(messageListItem.precalculatedValues.pageIsSelecting) {
|
||||||
openContextMenu()
|
page.selectedMessages = [];
|
||||||
} else {
|
|
||||||
page.selectedMessages = []
|
|
||||||
page.state = ""
|
page.state = ""
|
||||||
|
} else {
|
||||||
|
contextMenuLoader.active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMenuOpenChanged: {
|
|
||||||
// When opening/closing the context menu, we no longer scroll automatically
|
|
||||||
chatView.manuallyScrolledToBottom = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: additionalOptionsOpened ? messageOptionsDrawer : null
|
|
||||||
onOpenChanged: {
|
|
||||||
if (!messageOptionsDrawer.open) {
|
|
||||||
additionalOptionsOpened = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: chatPage
|
|
||||||
onResetElements: {
|
|
||||||
messageListItem.messageReactions = null;
|
|
||||||
selectReactionBubble.visible = false;
|
|
||||||
}
|
|
||||||
onElementSelected: {
|
|
||||||
if (elementIndex !== index) {
|
|
||||||
selectReactionBubble.visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onNavigatedTo: {
|
|
||||||
if (targetIndex === index) {
|
|
||||||
messageListItem.wasNavigatedTo = true;
|
|
||||||
restoreNormalityTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: contextMenuLoader
|
id: contextMenuLoader
|
||||||
active: false
|
active: false
|
||||||
|
@ -224,50 +81,53 @@ ListItem {
|
||||||
}
|
}
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
ContextMenu {
|
ContextMenu {
|
||||||
|
Repeater {
|
||||||
|
model: (extraContentLoader.item && ("extraContextMenuItems" in extraContentLoader.item)) ?
|
||||||
|
extraContentLoader.item.extraContextMenuItems : 0
|
||||||
|
delegate: MenuItem {
|
||||||
|
visible: modelData.visible
|
||||||
|
text: modelData.name
|
||||||
|
onClicked: modelData.action()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
visible: canReplyToMessage
|
visible: messageListItem.canReplyToMessage
|
||||||
onClicked: replyToMessage()
|
onClicked: messageListItem.replyToMessage()
|
||||||
text: qsTr("Reply to Message")
|
text: qsTr("Reply to Message")
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
visible: typeof myMessage.can_be_edited !== "undefined" && myMessage.can_be_edited
|
visible: myMessage.can_be_edited
|
||||||
onClicked: editMessage()
|
onClicked: messageListItem.editMessage()
|
||||||
text: qsTr("Edit Message")
|
text: qsTr("Edit Message")
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
onClicked: page.toggleMessageSelection(myMessage)
|
onClicked: {
|
||||||
text: qsTr("Select Message")
|
Clipboard.text = Functions.getMessageText(myMessage, true, false, true);
|
||||||
}
|
}
|
||||||
MenuItem {
|
|
||||||
visible: showCopyMessageToClipboardMenuItem
|
|
||||||
onClicked: copyMessageToClipboard()
|
|
||||||
text: qsTr("Copy Message to Clipboard")
|
text: qsTr("Copy Message to Clipboard")
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
visible: showForwardMessageMenuItem
|
|
||||||
onClicked: forwardMessage()
|
|
||||||
text: qsTr("Forward Message")
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
visible: canDeleteMessage && haveSpaceForDeleteMessageMenuItem
|
|
||||||
onClicked: deleteMessage()
|
|
||||||
text: qsTr("Delete Message")
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
visible: (numberOfExtraOptionsOtherThanDeleteMessage > 0) ||
|
|
||||||
(deleteMessageIsOnlyExtraOption && !haveSpaceForDeleteMessageMenuItem)
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
messageOptionsDrawer.myMessage = myMessage;
|
page.toggleMessageSelection(myMessage);
|
||||||
messageOptionsDrawer.userInformation = userInformation;
|
|
||||||
messageOptionsDrawer.sourceItem = messageListItem
|
|
||||||
messageOptionsDrawer.additionalItemsModel = additionalItemsModel
|
|
||||||
messageOptionsDrawer.showCopyMessageToClipboardMenuItem = !showCopyMessageToClipboardMenuItem
|
|
||||||
messageOptionsDrawer.showForwardMessageMenuItem = !showForwardMessageMenuItem
|
|
||||||
messageOptionsDrawer.showDeleteMessageMenuItem = canDeleteMessage && !haveSpaceForDeleteMessageMenuItem
|
|
||||||
messageListItem.additionalOptionsOpened = true;
|
|
||||||
messageOptionsDrawer.open = true;
|
|
||||||
}
|
}
|
||||||
text: qsTr("More Options...")
|
text: qsTr("Select Message")
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
onClicked: {
|
||||||
|
tdLibWrapper.pinMessage(page.chatInformation.id, messageId)
|
||||||
|
}
|
||||||
|
text: qsTr("Pin Message")
|
||||||
|
visible: canPinMessages()
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
onClicked: {
|
||||||
|
var chatId = page.chatInformation.id;
|
||||||
|
var messageId = messageListItem.messageId;
|
||||||
|
Remorse.itemAction(messageListItem, qsTr("Message deleted"), function() { tdLibWrapper.deleteMessages(chatId, [ messageId]); })
|
||||||
|
}
|
||||||
|
text: qsTr("Delete Message")
|
||||||
|
visible: myMessage.can_be_deleted_for_all_users || (myMessage.can_be_deleted_only_for_self && myMessage.chat_id === page.myUserId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,103 +136,44 @@ ListItem {
|
||||||
Connections {
|
Connections {
|
||||||
target: chatModel
|
target: chatModel
|
||||||
onMessagesReceived: {
|
onMessagesReceived: {
|
||||||
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
|
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
|
||||||
}
|
}
|
||||||
onMessagesIncrementalUpdate: {
|
onMessagesIncrementalUpdate: {
|
||||||
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
|
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
|
||||||
}
|
}
|
||||||
onNewMessageReceived: {
|
onNewMessageReceived: {
|
||||||
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
|
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
|
||||||
}
|
}
|
||||||
onUnreadCountUpdated: {
|
onUnreadCountUpdated: {
|
||||||
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
|
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
|
||||||
}
|
}
|
||||||
onLastReadSentMessageUpdated: {
|
onLastReadSentMessageUpdated: {
|
||||||
Debug.log("[ChatModel] Messages in this chat were read, new last read: ", lastReadSentIndex, ", updating description for index ", index, ", status: ", (index <= lastReadSentIndex));
|
Debug.log("[ChatModel] Messages in this chat were read, new last read: ", lastReadSentIndex, ", updating description for index ", index, ", status: ", (index <= lastReadSentIndex));
|
||||||
messageDateText.text = getMessageStatusText(myMessage, index, lastReadSentIndex, messageDateText.useElapsed);
|
messageDateText.text = getMessageStatusText(myMessage, index, lastReadSentIndex, messageDateText.useElapsed);
|
||||||
}
|
}
|
||||||
|
onMessageUpdated: {
|
||||||
|
if (index === modelIndex) {
|
||||||
|
Debug.log("[ChatModel] This message was updated, index ", index, ", updating content...");
|
||||||
|
messageDateText.text = getMessageStatusText(myMessage, index, chatView.lastReadSentIndex, messageDateText.useElapsed);
|
||||||
|
messageText.text = Emoji.emojify(Functions.getMessageText(myMessage, false, messageListItem.isOwnMessage. false), messageText.font.pixelSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: tdLibWrapper
|
target: tdLibWrapper
|
||||||
onReceivedMessage: {
|
onReceivedMessage: {
|
||||||
if (messageId === myMessage.reply_to_message_id) {
|
if (messageId === myMessage.reply_to_message_id.toString()) {
|
||||||
messageInReplyToLoader.inReplyToMessage = message;
|
messageInReplyToLoader.inReplyToMessage = message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMessageNotFound: {
|
|
||||||
if (messageId === myMessage.reply_to_message_id) {
|
|
||||||
messageInReplyToLoader.inReplyToMessageDeleted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onAvailableReactionsReceived: {
|
|
||||||
if (messageListItem.messageId === messageId &&
|
|
||||||
pageStack.currentPage === chatPage) {
|
|
||||||
Debug.log("Available reactions for this message: " + reactions);
|
|
||||||
messageListItem.messageReactions = reactions;
|
|
||||||
showItemCompletelyTimer.requestedIndex = index;
|
|
||||||
showItemCompletelyTimer.start();
|
|
||||||
} else {
|
|
||||||
messageListItem.messageReactions = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onReactionsUpdated: {
|
|
||||||
chatReactions = tdLibWrapper.getChatReactions(page.chatInformation.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: showItemCompletelyTimer
|
|
||||||
|
|
||||||
property int requestedIndex: (chatView.count - 1)
|
|
||||||
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
interval: 200
|
|
||||||
triggeredOnStart: false
|
|
||||||
onTriggered: {
|
|
||||||
Debug.log("Show item completely timer triggered, requested index: " + requestedIndex + ", current index: " + index)
|
|
||||||
if (requestedIndex === index) {
|
|
||||||
var p = chatView.contentItem.mapFromItem(reactionsColumn, 0, 0)
|
|
||||||
if (chatView.contentY > p.y || p.y + reactionsColumn.height > chatView.contentY + chatView.height) {
|
|
||||||
Debug.log("Moving reactions for item at", requestedIndex, "info the view")
|
|
||||||
chatView.highlightMoveDuration = -1
|
|
||||||
chatView.highlightResizeDuration = -1
|
|
||||||
chatView.scrollToIndex(requestedIndex, height <= chatView.height ? ListView.Contain : ListView.End)
|
|
||||||
chatView.highlightMoveDuration = 0
|
|
||||||
chatView.highlightResizeDuration = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: restoreNormalityTimer
|
|
||||||
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
interval: 1000
|
|
||||||
triggeredOnStart: false
|
|
||||||
onTriggered: {
|
|
||||||
Debug.log("Restore normality for index " + index);
|
|
||||||
messageListItem.wasNavigatedTo = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
delegateComponentLoadingTimer.start();
|
delegateComponentLoadingTimer.start();
|
||||||
if (myMessage.reply_to_message_id) {
|
|
||||||
tdLibWrapper.getMessage(myMessage.reply_in_chat_id ? myMessage.reply_in_chat_id : page.chatInformation.id,
|
|
||||||
myMessage.reply_to_message_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMyMessageChanged: {
|
if (myMessage.reply_to_message_id !== 0) {
|
||||||
Debug.log("[ChatModel] This message was updated, index", messageIndex, ", updating content...");
|
tdLibWrapper.getMessage(page.chatInformation.id, myMessage.reply_to_message_id);
|
||||||
messageDateText.text = getMessageStatusText(myMessage, messageIndex, chatView.lastReadSentIndex, messageDateText.useElapsed);
|
|
||||||
messageText.text = Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), Theme.fontSizeSmall);
|
|
||||||
if (webPagePreviewLoader.item) {
|
|
||||||
webPagePreviewLoader.item.webPageData = myMessage.content.web_page;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,16 +183,17 @@ ListItem {
|
||||||
repeat: false
|
repeat: false
|
||||||
running: false
|
running: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (messageListItem.hasContentComponent) {
|
if (typeof myMessage.content !== "undefined") {
|
||||||
var type = myMessage.content["@type"];
|
if (messageListItem.extraContentComponentName !== "") {
|
||||||
extraContentLoader.setSource(
|
extraContentLoader.setSource(
|
||||||
"../components/messageContent/" + type.charAt(0).toUpperCase() + type.substring(1) + ".qml",
|
"../components/" +messageListItem.extraContentComponentName +".qml",
|
||||||
{
|
{
|
||||||
messageListItem: messageListItem
|
messageListItem: messageListItem
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (typeof myMessage.content.web_page !== "undefined") { // only in messageText
|
if (typeof myMessage.content.web_page !== "undefined") { // only in messageText
|
||||||
webPagePreviewLoader.active = true;
|
webPagePreviewLoader.active = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,10 +203,7 @@ ListItem {
|
||||||
id: messageTextRow
|
id: messageTextRow
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
width: precalculatedValues.entryWidth
|
width: precalculatedValues.entryWidth
|
||||||
anchors.horizontalCenter: Functions.isWidescreen(appWindow) ? undefined : parent.horizontalCenter
|
anchors.centerIn: parent
|
||||||
anchors.left: Functions.isWidescreen(appWindow) ? parent.left : undefined
|
|
||||||
y: Theme.paddingSmall
|
|
||||||
anchors.leftMargin: Functions.isWidescreen(appWindow) ? Theme.paddingMedium : undefined
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: profileThumbnailLoader
|
id: profileThumbnailLoader
|
||||||
|
@ -417,16 +216,16 @@ ListItem {
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
ProfileThumbnail {
|
ProfileThumbnail {
|
||||||
id: messagePictureThumbnail
|
id: messagePictureThumbnail
|
||||||
photoData: messageListItem.isAnonymous ? ((typeof page.chatInformation.photo !== "undefined") ? page.chatInformation.photo.small : {}) : ((typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : ({}))
|
photoData: (typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : ({})
|
||||||
replacementStringHint: userText.text
|
replacementStringHint: userText.text
|
||||||
width: Theme.itemSizeSmall
|
width: Theme.itemSizeSmall
|
||||||
height: Theme.itemSizeSmall
|
height: Theme.itemSizeSmall
|
||||||
visible: precalculatedValues.showUserInfo
|
visible: precalculatedValues.showUserInfo
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
|
enabled: !messageListItem.precalculatedValues.pageIsSelecting
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id, "openDirectly");
|
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,16 +243,16 @@ ListItem {
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
leftMargin: page.isPrivateChat ? (messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0) : 0 //левый марджин для собственных сообщений в приватных чатах. В остальных на полную ширину
|
leftMargin: messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
|
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
|
||||||
width: precalculatedValues.backgroundWidth
|
width: precalculatedValues.backgroundWidth
|
||||||
property bool isUnread: index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage"
|
property bool isUnread: index > chatModel.getLastReadMessageIndex()
|
||||||
color: Theme.colorScheme === Theme.LightOnDark ? (isOwnMessage ? Theme.highlightBackgroundColor : (isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor)) : (isOwnMessage ? Theme.highlightBackgroundColor : (isUnread ? Theme.backgroundGlowColor : Theme.overlayBackgroundColor))
|
color: isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
||||||
radius: parent.width / 50
|
radius: parent.width / 50
|
||||||
opacity: isUnread ? 0.5 : 0.2
|
opacity: isUnread ? 0.5 : 0.2
|
||||||
visible: appSettings.showStickersAsImages || (myMessage.content['@type'] !== "messageSticker" && myMessage.content['@type'] !== "messageAnimatedEmoji")
|
visible: appSettings.showStickersAsImages || myMessage.content['@type'] !== "messageSticker"
|
||||||
Behavior on color { ColorAnimation { duration: 200 } }
|
Behavior on color { ColorAnimation { duration: 200 } }
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { FadeAnimation {} }
|
||||||
}
|
}
|
||||||
|
@ -471,7 +270,7 @@ ListItem {
|
||||||
id: userText
|
id: userText
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: messageListItem.isOwnMessage ? qsTr("You") : Emoji.emojify( myMessage['@type'] === "sponsoredMessage" ? tdLibWrapper.getChat(myMessage.sponsor_chat_id).title : ( messageListItem.isAnonymous ? page.chatInformation.title : Functions.getUserName(messageListItem.userInformation) ), font.pixelSize)
|
text: messageListItem.isOwnMessage ? qsTr("You") : Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize)
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
font.weight: Font.ExtraBold
|
font.weight: Font.ExtraBold
|
||||||
color: messageListItem.textColor
|
color: messageListItem.textColor
|
||||||
|
@ -479,28 +278,23 @@ ListItem {
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
horizontalAlignment: messageListItem.textAlign
|
horizontalAlignment: messageListItem.textAlign
|
||||||
visible: messageListItem.isOwnMessage ? false : (precalculatedValues.showUserInfo || myMessage['@type'] === "sponsoredMessage")
|
visible: precalculatedValues.showUserInfo
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
|
enabled: !messageListItem.precalculatedValues.pageIsSelecting
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id, "openDirectly");
|
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageViaLabel {
|
|
||||||
message: myMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: messageInReplyToLoader
|
id: messageInReplyToLoader
|
||||||
active: typeof myMessage.reply_to_message_id !== "undefined" && myMessage.reply_to_message_id !== 0
|
active: myMessage.reply_to_message_id !== 0
|
||||||
width: parent.width
|
width: parent.width
|
||||||
// text height ~= 1,28*font.pixelSize
|
// text height ~= 1,28*font.pixelSize
|
||||||
height: active ? precalculatedValues.messageInReplyToHeight : 0
|
height: active ? precalculatedValues.messageInReplyToHeight : 0
|
||||||
property var inReplyToMessage;
|
property var inReplyToMessage;
|
||||||
property bool inReplyToMessageDeleted: false;
|
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
Item {
|
Item {
|
||||||
width: messageInReplyToRow.width
|
width: messageInReplyToRow.width
|
||||||
|
@ -508,31 +302,14 @@ ListItem {
|
||||||
InReplyToRow {
|
InReplyToRow {
|
||||||
id: messageInReplyToRow
|
id: messageInReplyToRow
|
||||||
myUserId: page.myUserId
|
myUserId: page.myUserId
|
||||||
layer.enabled: messageInReplyToMouseArea.pressed && !messageListItem.highlighted && !messageListItem.menuOpen
|
visible: true
|
||||||
layer.effect: PressEffect { source: messageInReplyToRow }
|
|
||||||
inReplyToMessage: messageInReplyToLoader.inReplyToMessage
|
inReplyToMessage: messageInReplyToLoader.inReplyToMessage
|
||||||
inReplyToMessageDeleted: messageInReplyToLoader.inReplyToMessageDeleted
|
|
||||||
}
|
}
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: messageInReplyToMouseArea
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (precalculatedValues.pageIsSelecting) {
|
messageOverlayLoader.overlayMessage = messageInReplyToRow.inReplyToMessage;
|
||||||
page.toggleMessageSelection(myMessage)
|
messageOverlayLoader.active = true;
|
||||||
} else {
|
|
||||||
messageOptionsDrawer.open = false
|
|
||||||
if(appSettings.goToQuotedMessage) {
|
|
||||||
chatPage.showMessage(messageInReplyToRow.inReplyToMessage.id, true)
|
|
||||||
} else {
|
|
||||||
messageOverlayLoader.active = true
|
|
||||||
messageOverlayLoader.overlayMessage = messageInReplyToRow.inReplyToMessage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onPressAndHold: {
|
|
||||||
if (openMenuOnPressAndHold) {
|
|
||||||
openContextMenu()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,12 +329,11 @@ ListItem {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
var originType = myMessage.forward_info.origin["@type"]
|
if (myMessage.forward_info.origin["@type"] === "messageForwardOriginChannel") {
|
||||||
if (originType === "messageOriginChannel" || originType === "messageForwardOriginChannel") {
|
|
||||||
var otherChatInformation = tdLibWrapper.getChat(myMessage.forward_info.origin.chat_id);
|
var otherChatInformation = tdLibWrapper.getChat(myMessage.forward_info.origin.chat_id);
|
||||||
forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : {};
|
forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : {};
|
||||||
forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall);
|
forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall);
|
||||||
} else if (originType === "messageOriginUser" || originType === "messageForwardOriginUser") {
|
} else if (myMessage.forward_info.origin["@type"] === "messageForwardOriginUser") {
|
||||||
var otherUserInformation = tdLibWrapper.getUserInformation(myMessage.forward_info.origin.sender_user_id);
|
var otherUserInformation = tdLibWrapper.getUserInformation(myMessage.forward_info.origin.sender_user_id);
|
||||||
forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : {};
|
forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : {};
|
||||||
forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall);
|
forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall);
|
||||||
|
@ -603,46 +379,35 @@ ListItem {
|
||||||
Text {
|
Text {
|
||||||
id: messageText
|
id: messageText
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), Theme.fontSizeMedium)
|
text: Emoji.emojify(Functions.getMessageText(myMessage, false, messageListItem.isOwnMessage, false), font.pixelSize)
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: messageListItem.textColor
|
color: messageListItem.textColor
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
var chatCommand = Functions.handleLink(link);
|
Functions.handleLink(link);
|
||||||
if(chatCommand) {
|
|
||||||
tdLibWrapper.sendTextMessage(chatInformation.id, chatCommand);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
horizontalAlignment: messageListItem.textAlign
|
horizontalAlignment: messageListItem.textAlign
|
||||||
linkColor: Theme.highlightColor
|
linkColor: Theme.highlightColor
|
||||||
visible: (text !== "")
|
visible: (text !== "")
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: sponsoredMessageButtonLoader
|
|
||||||
active: myMessage['@type'] === "sponsoredMessage"
|
|
||||||
asynchronous: true
|
|
||||||
width: parent.width
|
|
||||||
height: (status === Loader.Ready) ? item.implicitHeight : myMessage['@type'] === "sponsoredMessage" ? Theme.itemSizeMedium : 0
|
|
||||||
|
|
||||||
sourceComponent: Component {
|
|
||||||
SponsoredMessage {
|
|
||||||
sponsoredMessageData: myMessage
|
|
||||||
width: parent.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: webPagePreviewLoader
|
id: webPagePreviewLoader
|
||||||
active: false
|
active: false
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
width: parent.width * getContentWidthMultiplier()
|
width: parent.width
|
||||||
height: (status === Loader.Ready) ? item.implicitHeight : myMessage.content.web_page ? precalculatedValues.webPagePreviewHeight : 0
|
height: typeof myMessage.content.web_page !== "undefined" ? precalculatedValues.webPagePreviewHeight : 0
|
||||||
|
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
|
id: webPagePreviewComponent
|
||||||
WebPagePreview {
|
WebPagePreview {
|
||||||
|
id: webPagePreview
|
||||||
|
|
||||||
|
onImplicitHeightChanged: {
|
||||||
|
webPagePreviewLoader.height = webPagePreview.implicitHeight;
|
||||||
|
}
|
||||||
|
|
||||||
webPageData: myMessage.content.web_page
|
webPageData: myMessage.content.web_page
|
||||||
width: parent.width
|
width: parent.width
|
||||||
highlighted: messageListItem.highlighted
|
highlighted: messageListItem.highlighted
|
||||||
|
@ -652,9 +417,9 @@ ListItem {
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: extraContentLoader
|
id: extraContentLoader
|
||||||
width: parent.width * getContentWidthMultiplier()
|
width: parent.width
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
height: item ? item.height : (messageListItem.hasContentComponent ? chatView.getContentComponentHeight(model.content_type, myMessage.content, width) : 0)
|
height: item ? item.height : (messageListItem.extraContentComponentName !== "" ? chatView.getContentComponentHeight(messageListItem.extraContentComponentName, myMessage.content, width) : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
|
@ -664,15 +429,6 @@ ListItem {
|
||||||
value: messageListItem.highlighted
|
value: messageListItem.highlighted
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: replyMarkupLoader
|
|
||||||
width: parent.width
|
|
||||||
height: active ? (myMessage.reply_markup.rows.length * (Theme.itemSizeSmall + Theme.paddingSmall) - Theme.paddingSmall) : 0
|
|
||||||
asynchronous: true
|
|
||||||
active: !!myMessage.reply_markup && myMessage.reply_markup.rows
|
|
||||||
source: Qt.resolvedUrl("ReplyMarkupButtons.qml")
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: messageDateUpdater
|
id: messageDateUpdater
|
||||||
interval: 60000
|
interval: 60000
|
||||||
|
@ -683,6 +439,7 @@ ListItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
@ -703,85 +460,10 @@ ListItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: interactionLoader
|
|
||||||
width: parent.width
|
|
||||||
asynchronous: true
|
|
||||||
active: ( chatPage.isChannel && messageViewCount > 0 ) || reactions.length > 0
|
|
||||||
height: ( ( chatPage.isChannel && messageViewCount > 0 ) || reactions.length > 0 ) ? ( Theme.fontSizeExtraSmall + Theme.paddingSmall ) : 0
|
|
||||||
sourceComponent: Component {
|
|
||||||
Label {
|
|
||||||
text: getInteractionText(messageViewCount, reactions, font.pixelSize, Theme.highlightColor)
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: messageListItem.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
|
||||||
horizontalAlignment: messageListItem.textAlign
|
|
||||||
textFormat: Text.StyledText
|
|
||||||
maximumLineCount: 1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
id: reactionsColumn
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
anchors.top: messageTextRow.bottom
|
|
||||||
anchors.topMargin: Theme.paddingSmall
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: messageListItem.messageReactions ? ( messageListItem.messageReactions.length > 0 ? true : false ) : false
|
|
||||||
opacity: messageListItem.messageReactions ? ( messageListItem.messageReactions.length > 0 ? 1 : 0 ) : 0
|
|
||||||
Behavior on opacity { NumberAnimation {} }
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
|
|
||||||
Flickable {
|
|
||||||
width: parent.width
|
|
||||||
height: reactionsResultRow.height + Theme.paddingSmall
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
contentWidth: reactionsResultRow.width
|
|
||||||
clip: true
|
|
||||||
Row {
|
|
||||||
id: reactionsResultRow
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
Repeater {
|
|
||||||
model: messageListItem.messageReactions
|
|
||||||
|
|
||||||
Item {
|
|
||||||
height: singleReactionRow.height
|
|
||||||
width: singleReactionRow.width
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: singleReactionRow
|
|
||||||
spacing: Theme.paddingSmall
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: emojiPicture
|
|
||||||
source: Emoji.getEmojiPath(modelData)
|
|
||||||
width: status === Image.Ready ? Theme.fontSizeLarge : 0
|
|
||||||
height: Theme.fontSizeLarge
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setMessageReaction(messageListItem.chatId, messageListItem.messageId, modelData);
|
|
||||||
messageListItem.messageReactions = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,15 +20,12 @@ import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import "../js/twemoji.js" as Emoji
|
import "../js/twemoji.js" as Emoji
|
||||||
import "../js/functions.js" as Functions
|
import "../js/functions.js" as Functions
|
||||||
import "../js/debug.js" as Debug
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: messageListItem
|
id: messageListItem
|
||||||
property var myMessage: display
|
property var myMessage: display
|
||||||
property bool senderIsUser: myMessage.sender_id["@type"] === "messageSenderUser"
|
property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender.user_id)
|
||||||
property var userInformation: senderIsUser ? tdLibWrapper.getUserInformation(myMessage.sender_id.user_id) : null
|
property bool isOwnMessage: chatPage.myUserId === myMessage.sender.user_id
|
||||||
property bool isOwnMessage: senderIsUser && chatPage.myUserId === myMessage.sender_id.user_id
|
|
||||||
property var linkedMessage
|
|
||||||
height: backgroundRectangle.height + Theme.paddingMedium
|
height: backgroundRectangle.height + Theme.paddingMedium
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
@ -36,7 +33,7 @@ Item {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
height: messageText.height + Theme.paddingMedium * 2
|
height: messageText.height + Theme.paddingMedium * 2
|
||||||
width: Math.min(messageText.implicitWidth, messageText.contentWidth) + Theme.paddingMedium * 2
|
width: Math.min(messageText.implicitWidth, messageText.contentWidth) + Theme.paddingMedium * 2
|
||||||
color: Theme.colorScheme === Theme.LightOnDark ? Theme.rgba(Theme.secondaryColor, 0.1) : Theme.rgba(Theme.overlayBackgroundColor, 0.1)
|
color: Theme.rgba(Theme.secondaryColor, 0.1)
|
||||||
radius: parent.width / 50
|
radius: parent.width / 50
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
|
@ -46,43 +43,11 @@ Item {
|
||||||
color: Theme.highlightColor
|
color: Theme.highlightColor
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
property string messageContentText: Functions.getMessageText(messageListItem.myMessage, false, chatPage.myUserId, false)
|
text: "<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.primaryColor+"\" href=\"userId://" + messageListItem.userInformation.id + "\">" + (!messageListItem.isOwnMessage ? Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize) : qsTr("You")) + "</a> " + Emoji.emojify(Functions.getMessageText(messageListItem.myMessage, false, messageListItem.isOwnMessage, false), font.pixelSize)
|
||||||
text: (messageListItem.senderIsUser
|
|
||||||
? "<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.primaryColor+"\" href=\"userId://" + messageListItem.userInformation.id + "\">" + (!messageListItem.isOwnMessage ? Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize) : qsTr("You")) + "</a> "
|
|
||||||
: "<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.secondaryHighlightColor+"\">" + Emoji.emojify(chatPage.chatInformation.title || "") + "</a> ")
|
|
||||||
+ Emoji.emojify(messageContentText, font.pixelSize)
|
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
if(link === "linkedmessage" && linkedMessage) {
|
Functions.handleLink(link);
|
||||||
messageOverlayLoader.overlayMessage = linkedMessage;
|
|
||||||
messageOverlayLoader.active = true;
|
|
||||||
} else {
|
|
||||||
Functions.handleLink(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loader {
|
|
||||||
id: gameScoreInfoLoader
|
|
||||||
active: myMessage.content["@type"] === "messageGameScore"
|
|
||||||
asynchronous: true
|
|
||||||
sourceComponent: Component {
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onReceivedMessage: {
|
|
||||||
if(chatId === chatPage.chatInformation.id && messageId === myMessage.content.game_message_id) {
|
|
||||||
messageListItem.linkedMessage = message;
|
|
||||||
messageText.messageContentText = messageListItem.isOwnMessage ?
|
|
||||||
qsTr("scored %Ln points in %2", "myself", myMessage.content.score).arg("<a href=\"linkedmessage\" style=\"text-decoration: none; color:"+Theme.primaryColor+"\">"+message.content.game.title+"</a>") :
|
|
||||||
|
|
||||||
qsTr("scored %Ln points in %2", "", myMessage.content.score).arg("<a href=\"linkedmessage\" style=\"text-decoration: none; color:"+Theme.primaryColor+"\" >"+message.content.game.title+"</a>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
tdLibWrapper.getMessage(chatPage.chatInformation.id, myMessage.content.game_message_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,9 @@
|
||||||
*/
|
*/
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import "./messageContent"
|
import "../components"
|
||||||
import "../js/functions.js" as Functions
|
import "../js/functions.js" as Functions
|
||||||
import "../js/twemoji.js" as Emoji
|
import "../js/twemoji.js" as Emoji
|
||||||
import "../js/debug.js" as Debug
|
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
id: messageOverlayFlickable
|
id: messageOverlayFlickable
|
||||||
|
@ -32,21 +31,19 @@ Flickable {
|
||||||
|
|
||||||
property var overlayMessage;
|
property var overlayMessage;
|
||||||
property bool showHeader: true
|
property bool showHeader: true
|
||||||
readonly property var userInformation: tdLibWrapper.getUserInformation(overlayMessage.sender_id.user_id);
|
readonly property var userInformation: tdLibWrapper.getUserInformation(overlayMessage.sender.user_id);
|
||||||
readonly property bool isOwnMessage: tdLibWrapper.getUserInformation().id === overlayMessage.sender_id.user_id;
|
readonly property bool isOwnMessage: tdLibWrapper.getUserInformation().id === overlayMessage.sender.user_id;
|
||||||
readonly property bool isAnonymous: overlayMessage.sender_id["@type"] === "messageSenderChat"
|
readonly property string extraContentComponentName: (typeof overlayMessage.content !== "undefined" && typeof chatView.contentComponentNames[overlayMessage.content['@type']] !== "undefined" )
|
||||||
property bool hasContentComponent: overlayMessage.content && chatView.delegateMessagesContent.indexOf(overlayMessage.content['@type']) > -1
|
? chatView.contentComponentNames[overlayMessage.content['@type']] : ""
|
||||||
signal requestClose;
|
signal requestClose;
|
||||||
|
|
||||||
function getOriginalAuthor(forwardInformation, fontSize) {
|
function getOriginalAuthor(forwardInformation, fontSize) {
|
||||||
switch (forwardInformation.origin["@type"]) {
|
switch (forwardInformation.origin["@type"]) {
|
||||||
case "messageOriginChannel":
|
|
||||||
case "messageForwardOriginChannel":
|
case "messageForwardOriginChannel":
|
||||||
var otherChatInformation = tdLibWrapper.getChat(forwardInformation.origin.chat_id);
|
var otherChatInformation = tdLibWrapper.getChat(forwardInformation.origin.chat_id);
|
||||||
return Emoji.emojify(otherChatInformation.title, fontSize);
|
return Emoji.emojify(otherChatInformation.title, fontSize);
|
||||||
case "messageOriginUser":
|
|
||||||
case "messageForwardOriginUser":
|
case "messageForwardOriginUser":
|
||||||
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender_id.user_id);
|
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender.user_id);
|
||||||
return Emoji.emojify(Functions.getUserName(otherUserInformation), fontSize);
|
return Emoji.emojify(Functions.getUserName(otherUserInformation), fontSize);
|
||||||
default:
|
default:
|
||||||
return Emoji.emojify(forwardInformation.origin.sender_name, fontSize);
|
return Emoji.emojify(forwardInformation.origin.sender_name, fontSize);
|
||||||
|
@ -63,15 +60,18 @@ Flickable {
|
||||||
repeat: false
|
repeat: false
|
||||||
running: false
|
running: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (messageOverlayFlickable.hasContentComponent) {
|
if (typeof overlayMessage.content !== "undefined") {
|
||||||
var type = overlayMessage.content["@type"];
|
if (messageOverlayFlickable.extraContentComponentName !== "") {
|
||||||
overlayExtraContentLoader.setSource(
|
overlayExtraContentLoader.setSource(
|
||||||
"../components/messageContent/" + type.charAt(0).toUpperCase() + type.substring(1) + ".qml",
|
"../components/" + messageOverlayFlickable.extraContentComponentName + ".qml",
|
||||||
{
|
{
|
||||||
overlayFlickable: messageOverlayFlickable
|
overlayFlickable: messageOverlayFlickable
|
||||||
})
|
})
|
||||||
} else if(overlayMessage.content && overlayMessage.content.web_page) {
|
} else {
|
||||||
overlayWebPagePreviewLoader.active = true;
|
if (typeof overlayMessage.content.web_page !== "undefined") {
|
||||||
|
overlayWebPagePreviewLoader.active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ Flickable {
|
||||||
spacing: Theme.paddingMedium
|
spacing: Theme.paddingMedium
|
||||||
ProfileThumbnail {
|
ProfileThumbnail {
|
||||||
id: overlayMessagePictureThumbnail
|
id: overlayMessagePictureThumbnail
|
||||||
photoData: messageOverlayFlickable.isAnonymous ? ((typeof chatPage.chatInformation.photo !== "undefined") ? chatPage.chatInformation.photo.small : {}) : ((typeof messageOverlayFlickable.userInformation.profile_photo !== "undefined") ? messageOverlayFlickable.userInformation.profile_photo.small : ({}))
|
photoData: (typeof messageOverlayFlickable.userInformation.profile_photo !== "undefined") ? messageOverlayFlickable.userInformation.profile_photo.small : ({})
|
||||||
replacementStringHint: overlayMessageUserText.text
|
replacementStringHint: overlayMessageUserText.text
|
||||||
width: Theme.itemSizeLarge
|
width: Theme.itemSizeLarge
|
||||||
height: Theme.itemSizeLarge
|
height: Theme.itemSizeLarge
|
||||||
|
@ -114,7 +114,7 @@ Flickable {
|
||||||
|
|
||||||
width: parent.width - overlayMessagePictureThumbnail.width
|
width: parent.width - overlayMessagePictureThumbnail.width
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: messageOverlayFlickable.isOwnMessage ? qsTr("You") : Emoji.emojify(messageOverlayFlickable.isAnonymous ? chatPage.chatInformation.title : Functions.getUserName(messageOverlayFlickable.userInformation), font.pixelSize)
|
text: messageOverlayFlickable.isOwnMessage ? qsTr("You") : Emoji.emojify(Functions.getUserName(messageOverlayFlickable.userInformation), font.pixelSize)
|
||||||
font.pixelSize: Theme.fontSizeExtraLarge
|
font.pixelSize: Theme.fontSizeExtraLarge
|
||||||
font.weight: Font.ExtraBold
|
font.weight: Font.ExtraBold
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
|
@ -123,10 +123,6 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageViaLabel {
|
|
||||||
message: overlayMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: overlayForwardedInfoText
|
id: overlayForwardedInfoText
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -142,7 +138,7 @@ Flickable {
|
||||||
Text {
|
Text {
|
||||||
id: overlayMessageText
|
id: overlayMessageText
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: Emoji.emojify(Functions.getMessageText(overlayMessage, false, tdLibWrapper.getUserInformation().id, false), font.pixelSize)
|
text: Emoji.emojify(Functions.getMessageText(overlayMessage, false, messageOverlayFlickable.isOwnMessage, false), font.pixelSize)
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Theme.primaryColor
|
color: Theme.primaryColor
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
@ -182,16 +178,6 @@ Flickable {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: replyMarkupLoader
|
|
||||||
property var myMessage: overlayMessage
|
|
||||||
width: parent.width
|
|
||||||
height: active ? (overlayMessage.reply_markup.rows.length * (Theme.itemSizeSmall + Theme.paddingSmall) - Theme.paddingSmall) : 0
|
|
||||||
asynchronous: true
|
|
||||||
active: !!overlayMessage.reply_markup && myMessage.reply_markup.rows
|
|
||||||
source: Qt.resolvedUrl("ReplyMarkupButtons.qml")
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: messageDateUpdater
|
id: messageDateUpdater
|
||||||
interval: 60000
|
interval: 60000
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "../js/functions.js" as Functions
|
|
||||||
import "../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: botUserLoader
|
|
||||||
active: !!message.via_bot_user_id
|
|
||||||
width: parent.width
|
|
||||||
asynchronous: true
|
|
||||||
sourceComponent: Label {
|
|
||||||
property var botUserInformation: tdLibWrapper.getUserInformation(message.via_bot_user_id)
|
|
||||||
color: Theme.secondaryColor
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
text: qsTr("via %1", "message posted via bot user").arg("<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.primaryColor+"\" href=\"userId://" + message.via_bot_user_id + "\">@" + Emoji.emojify(botUserInformation.usernames.editable_username, font.pixelSize)+"</a>")
|
|
||||||
textFormat: Text.RichText
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
onLinkActivated: {
|
|
||||||
if(link === "userId://" + message.via_bot_user_id && botUserInformation.type.is_inline) {
|
|
||||||
newMessageTextField.text = "@"+botUserInformation.usernames.editable_username+" "
|
|
||||||
newMessageTextField.cursorPosition = newMessageTextField.text.length
|
|
||||||
lostFocusTimer.start();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Functions.handleLink(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
property var message
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Slava Monich and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.0
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
// Combination of maximumLineCount and TruncationMode.Elide (or Fade) breaks
|
|
||||||
// Emoji image alignment, pushing the image down. This one aligns the image
|
|
||||||
// correctly on its line.
|
|
||||||
Label {
|
|
||||||
property string rawText
|
|
||||||
property int maxLineCount
|
|
||||||
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
textFormat: Text.StyledText
|
|
||||||
truncationMode: TruncationMode.Elide
|
|
||||||
|
|
||||||
// lineCount is unreliable for StyledText with images and line breaks
|
|
||||||
readonly property int fontSize: font.pixelSize
|
|
||||||
readonly property int actualLineHeight: (text === rawText) ? fontSize : (fontSize * 6 / 5)
|
|
||||||
readonly property int actualLineCount: Math.floor(implicitHeight/actualLineHeight)
|
|
||||||
|
|
||||||
Component.onCompleted: refitText()
|
|
||||||
onFontSizeChanged: refitText()
|
|
||||||
onWidthChanged: refitText()
|
|
||||||
onRawTextChanged: refitText()
|
|
||||||
onMaxLineCountChanged: refitText()
|
|
||||||
|
|
||||||
function emojify(str) {
|
|
||||||
return Emoji.emojify(str, fontSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
function refitText() {
|
|
||||||
text = emojify(rawText)
|
|
||||||
if (maxLineCount > 0) {
|
|
||||||
var divisor = 1
|
|
||||||
var max = rawText.length
|
|
||||||
var min = max
|
|
||||||
while (actualLineCount > maxLineCount && divisor < rawText.length) {
|
|
||||||
max = min
|
|
||||||
divisor++
|
|
||||||
min = rawText.length/divisor
|
|
||||||
text = emojify(rawText.substr(0, min) + "…")
|
|
||||||
}
|
|
||||||
while (min < max) {
|
|
||||||
var mid = Math.floor((min + max)/2)
|
|
||||||
if (mid === min) {
|
|
||||||
text = emojify(rawText.substr(0, min) + "…")
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
text = emojify(rawText.substr(0, mid) + "…")
|
|
||||||
if (actualLineCount > maxLineCount) {
|
|
||||||
max = mid
|
|
||||||
} else {
|
|
||||||
min = mid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,6 @@
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import WerkWolf.Fernschreiber 1.0
|
import WerkWolf.Fernschreiber 1.0
|
||||||
import "../js/functions.js" as Functions
|
|
||||||
|
|
||||||
ListItem {
|
ListItem {
|
||||||
id: chatListViewItem
|
id: chatListViewItem
|
||||||
|
@ -12,217 +11,150 @@ ListItem {
|
||||||
property alias tertiaryText: tertiaryText //usually last message date
|
property alias tertiaryText: tertiaryText //usually last message date
|
||||||
|
|
||||||
property int unreadCount: 0
|
property int unreadCount: 0
|
||||||
property int unreadMentionCount: 0
|
|
||||||
property int unreadReactionCount: 0
|
|
||||||
property bool isSecret: false
|
property bool isSecret: false
|
||||||
property bool isVerified: false
|
property bool isVerified: false
|
||||||
property bool isMarkedAsUnread: false
|
|
||||||
property bool isPinned: false
|
|
||||||
property bool isMuted: false
|
|
||||||
property alias pictureThumbnail: pictureThumbnail
|
property alias pictureThumbnail: pictureThumbnail
|
||||||
|
|
||||||
contentHeight: Theme.itemSizeExtraLarge
|
contentHeight: mainRow.height + separator.height + 2 * Theme.paddingMedium
|
||||||
contentWidth: parent.width
|
contentWidth: parent.width
|
||||||
|
|
||||||
|
|
||||||
ShaderEffectSource {
|
|
||||||
id: pictureItem
|
|
||||||
height: Theme.itemSizeLarge
|
|
||||||
width: height
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: Theme.horizontalPageMargin
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceItem: Item {
|
|
||||||
width: pictureItem.width
|
|
||||||
height: pictureItem.width
|
|
||||||
|
|
||||||
ProfileThumbnail {
|
|
||||||
id: pictureThumbnail
|
|
||||||
replacementStringHint: primaryText.text
|
|
||||||
width: parent.width
|
|
||||||
height: parent.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: chatPinnedBackground
|
|
||||||
color: Theme.rgba(Theme.overlayBackgroundColor, Theme.opacityFaint)
|
|
||||||
width: Theme.fontSizeLarge
|
|
||||||
height: Theme.fontSizeLarge
|
|
||||||
anchors.top: parent.top
|
|
||||||
radius: parent.width / 2
|
|
||||||
visible: chatListViewItem.isPinned
|
|
||||||
}
|
|
||||||
|
|
||||||
Icon {
|
|
||||||
source: "../../images/icon-s-pin.svg"
|
|
||||||
height: Theme.iconSizeExtraSmall
|
|
||||||
width: Theme.iconSizeExtraSmall
|
|
||||||
highlighted: chatListViewItem.highlighted
|
|
||||||
sourceSize: Qt.size(Theme.iconSizeExtraSmall, Theme.iconSizeExtraSmall)
|
|
||||||
anchors.centerIn: chatPinnedBackground
|
|
||||||
visible: chatListViewItem.isPinned
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: chatSecretBackground
|
|
||||||
color: Theme.rgba(Theme.overlayBackgroundColor, Theme.opacityFaint)
|
|
||||||
width: Theme.fontSizeLarge
|
|
||||||
height: Theme.fontSizeLarge
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
radius: parent.width / 2
|
|
||||||
visible: chatListViewItem.isSecret
|
|
||||||
}
|
|
||||||
|
|
||||||
Icon {
|
|
||||||
source: "image://theme/icon-s-secure"
|
|
||||||
height: Theme.iconSizeExtraSmall
|
|
||||||
width: Theme.iconSizeExtraSmall
|
|
||||||
highlighted: chatListViewItem.highlighted
|
|
||||||
anchors.centerIn: chatSecretBackground
|
|
||||||
visible: chatListViewItem.isSecret
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: chatUnreadMessagesCountBackground
|
|
||||||
color: isMuted ? ((Theme.colorScheme === Theme.DarkOnLight) ? "lightgray" : "dimgray") : Theme.highlightBackgroundColor
|
|
||||||
width: chatUnreadMessagesCount.width + Theme.fontSizeLarge / 2
|
|
||||||
height: Theme.fontSizeLarge
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
radius: parent.width / 2
|
|
||||||
visible: chatListViewItem.unreadCount > 0 || chatListViewItem.isMarkedAsUnread
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: chatUnreadMessagesCount
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
font.bold: true
|
|
||||||
color: Theme.primaryColor
|
|
||||||
anchors.centerIn: chatUnreadMessagesCountBackground
|
|
||||||
visible: chatListViewItem.unreadCount > 0
|
|
||||||
opacity: isMuted ? Theme.opacityHigh : 1.0
|
|
||||||
text: Functions.formatUnreadCount(chatListViewItem.unreadCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
color: isMuted ? ((Theme.colorScheme === Theme.DarkOnLight) ? "lightgray" : "dimgray") : Theme.highlightBackgroundColor
|
|
||||||
width: Theme.fontSizeLarge
|
|
||||||
height: Theme.fontSizeLarge
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
radius: parent.width / 2
|
|
||||||
visible: chatListViewItem.unreadReactionCount > 0 || chatListViewItem.unreadMentionCount > 0
|
|
||||||
|
|
||||||
Icon {
|
|
||||||
source: "image://theme/icon-s-favorite"
|
|
||||||
height: Theme.iconSizeExtraSmall
|
|
||||||
width: Theme.iconSizeExtraSmall
|
|
||||||
highlighted: chatListViewItem.highlighted
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: chatListViewItem.unreadReactionCount > 0 && !chatListViewItem.unreadMentionCount
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
font {
|
|
||||||
pixelSize: Theme.iconSizeExtraSmall
|
|
||||||
bold: true
|
|
||||||
}
|
|
||||||
color: Theme.primaryColor
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: chatListViewItem.unreadMentionCount > 0
|
|
||||||
opacity: isMuted ? Theme.opacityHigh : 1.0
|
|
||||||
text: "@"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: contentColumn
|
id: mainColumn
|
||||||
|
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
||||||
|
spacing: Theme.paddingSmall
|
||||||
anchors {
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
left: pictureItem.right
|
|
||||||
leftMargin: Theme.paddingSmall
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: Theme.horizontalPageMargin
|
|
||||||
}
|
}
|
||||||
spacing: Theme.paddingSmall / 2
|
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: primaryTextRow
|
id: mainRow
|
||||||
|
height: contentColumn.height
|
||||||
spacing: Theme.paddingMedium
|
spacing: Theme.paddingMedium
|
||||||
|
|
||||||
Label {
|
Column {
|
||||||
id: primaryText
|
id: pictureColumn
|
||||||
textFormat: Text.StyledText
|
width: contentColumn.height - Theme.paddingSmall
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
height: contentColumn.height - Theme.paddingSmall
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: Math.min(contentColumn.width - (verifiedImage.visible ? (verifiedImage.width + primaryTextRow.spacing) : 0) - (mutedImage.visible ? (mutedImage.width + primaryTextRow.spacing) : 0), implicitWidth)
|
|
||||||
font.bold: appSettings.highlightUnreadConversations && ( !chatListViewItem.isMuted && (chatListViewItem.unreadCount > 0 || chatListViewItem.isMarkedAsUnread) )
|
Item {
|
||||||
font.italic: appSettings.highlightUnreadConversations && (chatListViewItem.unreadReactionCount > 0)
|
width: parent.width
|
||||||
color: (appSettings.highlightUnreadConversations && (chatListViewItem.unreadCount > 0)) ? Theme.highlightColor : Theme.primaryColor
|
height: parent.width
|
||||||
|
|
||||||
|
ProfileThumbnail {
|
||||||
|
id: pictureThumbnail
|
||||||
|
replacementStringHint: primaryText.text
|
||||||
|
width: parent.width
|
||||||
|
height: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: chatSecretBackground
|
||||||
|
color: Theme.overlayBackgroundColor
|
||||||
|
width: Theme.fontSizeExtraLarge
|
||||||
|
height: Theme.fontSizeExtraLarge
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
radius: parent.width / 2
|
||||||
|
visible: chatListViewItem.isSecret
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
source: "image://theme/icon-s-secure"
|
||||||
|
height: Theme.fontSizeMedium
|
||||||
|
width: Theme.fontSizeMedium
|
||||||
|
anchors.centerIn: chatSecretBackground
|
||||||
|
visible: chatListViewItem.isSecret
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: chatUnreadMessagesCountBackground
|
||||||
|
color: Theme.highlightBackgroundColor
|
||||||
|
width: Theme.fontSizeLarge
|
||||||
|
height: Theme.fontSizeLarge
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
radius: parent.width / 2
|
||||||
|
visible: chatListViewItem.unreadCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: chatUnreadMessagesCount
|
||||||
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
|
font.bold: true
|
||||||
|
color: Theme.primaryColor
|
||||||
|
anchors.centerIn: chatUnreadMessagesCountBackground
|
||||||
|
visible: chatUnreadMessagesCountBackground.visible
|
||||||
|
text: chatListViewItem.unreadCount > 99 ? "99+" : chatListViewItem.unreadCount
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Column {
|
||||||
id: verifiedImage
|
id: contentColumn
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
width: mainColumn.width - pictureColumn.width - mainRow.spacing
|
||||||
source: chatListViewItem.isVerified ? "../../images/icon-verified.svg" : ""
|
spacing: Theme.paddingSmall
|
||||||
sourceSize: Qt.size(Theme.iconSizeExtraSmall, Theme.iconSizeExtraSmall)
|
|
||||||
width: Theme.iconSizeSmall
|
|
||||||
height: Theme.iconSizeSmall
|
|
||||||
visible: status === Image.Ready
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
Row {
|
||||||
id: mutedImage
|
id: primaryTextRow
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
spacing: Theme.paddingMedium
|
||||||
source: chatListViewItem.isMuted ? "../js/emoji/1f507.svg" : ""
|
|
||||||
sourceSize: Qt.size(Theme.iconSizeExtraSmall, Theme.iconSizeExtraSmall)
|
|
||||||
width: Theme.iconSizeSmall
|
|
||||||
height: Theme.iconSizeSmall
|
|
||||||
visible: status === Image.Ready
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
Label {
|
||||||
width: parent.width
|
id: primaryText
|
||||||
spacing: Theme.paddingSmall
|
textFormat: Text.StyledText
|
||||||
Label {
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
id: prologSecondaryText
|
truncationMode: TruncationMode.Fade
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: Math.min(implicitWidth, parent.width)
|
width: Math.min(contentColumn.width - (verifiedImage.visible ? (verifiedImage.width + primaryTextRow.spacing) : 0), implicitWidth)
|
||||||
color: Theme.highlightColor
|
}
|
||||||
textFormat: Text.StyledText
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: secondaryText
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
width: parent.width - Theme.paddingMedium - prologSecondaryText.width
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
textFormat: Text.StyledText
|
|
||||||
visible: prologSecondaryText.width < ( parent.width - Theme.paddingLarge )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
Image {
|
||||||
id: tertiaryText
|
id: verifiedImage
|
||||||
width: parent.width
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
source: chatListViewItem.isVerified ? "../../images/icon-verified.svg" : ""
|
||||||
color: Theme.secondaryColor
|
sourceSize.width: Theme.iconSizeExtraSmall
|
||||||
truncationMode: TruncationMode.Fade
|
width: Theme.iconSizeExtraSmall
|
||||||
|
visible: status === Image.Ready
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.paddingSmall
|
||||||
|
Label {
|
||||||
|
id: prologSecondaryText
|
||||||
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
|
width: Math.min(implicitWidth, parent.width)
|
||||||
|
color: Theme.highlightColor
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: secondaryText
|
||||||
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
|
width: parent.width - Theme.paddingMedium - prologSecondaryText.width
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
visible: prologSecondaryText.width < ( parent.width - Theme.paddingLarge )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: tertiaryText
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
color: Theme.secondaryColor
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Separator {
|
Separator {
|
||||||
id: separator
|
id: separator
|
||||||
anchors {
|
anchors {
|
||||||
bottom: parent.bottom
|
top: mainColumn.bottom
|
||||||
bottomMargin: -1
|
topMargin: Theme.paddingMedium
|
||||||
}
|
}
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
|
@ -33,9 +33,9 @@ Item {
|
||||||
onPinnedMessageChanged: {
|
onPinnedMessageChanged: {
|
||||||
if (pinnedMessage) {
|
if (pinnedMessage) {
|
||||||
Debug.log("[ChatPage] Activating pinned message");
|
Debug.log("[ChatPage] Activating pinned message");
|
||||||
var messageUserText = (pinnedMessage.sender_id.user_id !== chatPage.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(pinnedMessage.sender_id.user_id)), pinnedMessageUserText.font.pixelSize) : qsTr("You");
|
var messageUserText = (pinnedMessage.sender.user_id !== chatPage.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(pinnedMessage.sender.user_id)), pinnedMessageUserText.font.pixelSize) : qsTr("You");
|
||||||
pinnedMessageUserText.text = (messageUserText === "" ? qsTr("Pinned Message") : messageUserText );
|
pinnedMessageUserText.text = (messageUserText === "" ? qsTr("Pinned Message") : messageUserText );
|
||||||
pinnedMessageText.text = Emoji.emojify(Functions.getMessageText(pinnedMessage, true, chatPage.myUserId, false), pinnedMessageText.font.pixelSize);
|
pinnedMessageText.text = Emoji.emojify(Functions.getMessageText(pinnedMessage, true, pinnedMessage.sender.user_id === chatPage.myUserId, false), pinnedMessageText.font.pixelSize);
|
||||||
pinnedMessageItem.visible = true;
|
pinnedMessageItem.visible = true;
|
||||||
} else {
|
} else {
|
||||||
pinnedMessageItem.visible = false;
|
pinnedMessageItem.visible = false;
|
||||||
|
@ -123,7 +123,7 @@ Item {
|
||||||
id: unpinMessageIconButton
|
id: unpinMessageIconButton
|
||||||
icon.source: "image://theme/icon-m-remove"
|
icon.source: "image://theme/icon-m-remove"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Remorse.itemAction(pinnedMessageRow, qsTr("Message unpinned"), function() { tdLibWrapper.unpinMessage(chatPage.chatInformation.id, pinnedMessage.id);
|
Remorse.itemAction(pinnedMessageRow, qsTr("Message unpinned"), function() { tdLibWrapper.unpinMessage(chatPage.chatInformation.id);
|
||||||
pinnedMessageItem.requestCloseMessage(); });
|
pinnedMessageItem.requestCloseMessage(); });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,15 @@ import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import WerkWolf.Fernschreiber 1.0
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
|
||||||
import "../../js/functions.js" as Functions
|
import "../js/functions.js" as Functions
|
||||||
import "../../js/twemoji.js" as Emoji
|
import "../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
MessageContentBase {
|
Item {
|
||||||
id: pollMessageComponent
|
id: pollMessageComponent
|
||||||
height: pollColumn.height
|
|
||||||
|
|
||||||
|
property ListItem messageListItem
|
||||||
|
property MessageOverlayFlickable overlayFlickable
|
||||||
|
readonly property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
||||||
readonly property string chatId: rawMessage.chat_id
|
readonly property string chatId: rawMessage.chat_id
|
||||||
readonly property bool isOwnMessage: messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
|
readonly property bool isOwnMessage: messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
|
||||||
readonly property string messageId: rawMessage.id
|
readonly property string messageId: rawMessage.id
|
||||||
|
@ -42,6 +44,9 @@ MessageContentBase {
|
||||||
}
|
}
|
||||||
readonly property bool canAnswer: !hasAnswered && !pollData.is_closed
|
readonly property bool canAnswer: !hasAnswered && !pollData.is_closed
|
||||||
readonly property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz"
|
readonly property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz"
|
||||||
|
property bool highlighted
|
||||||
|
width: parent.width
|
||||||
|
height: pollColumn.height
|
||||||
property list<NamedAction> extraContextMenuItems: [
|
property list<NamedAction> extraContextMenuItems: [
|
||||||
NamedAction {
|
NamedAction {
|
||||||
visible: !pollData.is_closed && pollMessageComponent.canEdit
|
visible: !pollData.is_closed && pollMessageComponent.canEdit
|
||||||
|
@ -230,24 +235,6 @@ MessageContentBase {
|
||||||
width: 1
|
width: 1
|
||||||
height: Theme.paddingSmall
|
height: Theme.paddingSmall
|
||||||
}
|
}
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
visible: isQuiz && text.length > 0
|
|
||||||
text: Emoji.emojify(Functions.enhanceMessageText(pollData.type.explanation) || "", font.pixelSize)
|
|
||||||
textFormat: Text.StyledText
|
|
||||||
color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.highlightColor : Theme.primaryColor
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
leftPadding: Theme.iconSizeSmall
|
|
||||||
bottomPadding: Theme.paddingSmall
|
|
||||||
Icon {
|
|
||||||
source: "image://theme/icon-s-high-importance"
|
|
||||||
asynchronous: true
|
|
||||||
width: Theme.iconSizeExtraSmall
|
|
||||||
height: Theme.iconSizeExtraSmall
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
x: -Theme.horizontalPageMargin/2
|
x: -Theme.horizontalPageMargin/2
|
||||||
|
@ -277,7 +264,7 @@ MessageContentBase {
|
||||||
visible: !pollMessageComponent.canAnswer && !pollData.is_anonymous && pollData.total_voter_count > 0
|
visible: !pollMessageComponent.canAnswer && !pollData.is_anonymous && pollData.total_voter_count > 0
|
||||||
icon.source: "image://theme/icon-m-media-artists"
|
icon.source: "image://theme/icon-m-media-artists"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
pageStack.push(Qt.resolvedUrl("../../pages/PollResultsPage.qml"), { chatId:chatId, message:pollMessageComponent.rawMessage});
|
pageStack.push(Qt.resolvedUrl("../pages/PollResultsPage.qml"), { chatId:chatId, message:pollMessageComponent.message});
|
||||||
}
|
}
|
||||||
Icon {
|
Icon {
|
||||||
opacity: 0.8
|
opacity: 0.8
|
|
@ -22,6 +22,7 @@ import Sailfish.Silica 1.0
|
||||||
import WerkWolf.Fernschreiber 1.0
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
||||||
id: profileThumbnail
|
id: profileThumbnail
|
||||||
|
|
||||||
property alias photoData: file.fileInformation
|
property alias photoData: file.fileInformation
|
||||||
|
@ -29,10 +30,6 @@ Item {
|
||||||
property int radius: width / 2
|
property int radius: width / 2
|
||||||
property int imageStatus: -1
|
property int imageStatus: -1
|
||||||
property bool optimizeImageSize: true
|
property bool optimizeImageSize: true
|
||||||
property bool highlighted
|
|
||||||
|
|
||||||
layer.enabled: highlighted
|
|
||||||
layer.effect: PressEffect { source: profileThumbnail }
|
|
||||||
|
|
||||||
function getReplacementString() {
|
function getReplacementString() {
|
||||||
if (replacementStringHint.length > 2) {
|
if (replacementStringHint.length > 2) {
|
||||||
|
@ -69,6 +66,7 @@ Item {
|
||||||
id: singleImage
|
id: singleImage
|
||||||
width: parent.width - Theme.paddingSmall
|
width: parent.width - Theme.paddingSmall
|
||||||
height: width
|
height: width
|
||||||
|
anchors.centerIn: parent
|
||||||
source: file.path
|
source: file.path
|
||||||
sourceSize.width: optimizeImageSize ? width : undefined
|
sourceSize.width: optimizeImageSize ? width : undefined
|
||||||
sourceSize.height: optimizeImageSize ? height : undefined
|
sourceSize.height: optimizeImageSize ? height : undefined
|
||||||
|
|
|
@ -1,121 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "../js/twemoji.js" as Emoji
|
|
||||||
import "../js/functions.js" as Functions
|
|
||||||
import "../js/debug.js" as Debug
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: replyMarkupButtons
|
|
||||||
width: parent.width
|
|
||||||
height: childrenRect.height
|
|
||||||
spacing: Theme.paddingSmall
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: myMessage.reply_markup.rows
|
|
||||||
delegate: Row {
|
|
||||||
width: parent.width
|
|
||||||
height: Theme.itemSizeSmall
|
|
||||||
spacing: Theme.paddingSmall
|
|
||||||
Repeater {
|
|
||||||
id: buttonsRepeater
|
|
||||||
model: modelData
|
|
||||||
property int itemWidth: replyMarkupButtons.width / count
|
|
||||||
delegate: MouseArea {
|
|
||||||
/*
|
|
||||||
Unimplemented callback types:
|
|
||||||
inlineKeyboardButtonTypeBuy
|
|
||||||
inlineKeyboardButtonTypeCallbackGame
|
|
||||||
inlineKeyboardButtonTypeCallbackWithPassword
|
|
||||||
inlineKeyboardButtonTypeLoginUrl
|
|
||||||
inlineKeyboardButtonTypeSwitchInline
|
|
||||||
*/
|
|
||||||
property var callbacks: ({
|
|
||||||
inlineKeyboardButtonTypeCallback: function(){
|
|
||||||
tdLibWrapper.getCallbackQueryAnswer(myMessage.chat_id, myMessage.id, {data: modelData.type.data, "@type": "callbackQueryPayloadData"})
|
|
||||||
},
|
|
||||||
|
|
||||||
inlineKeyboardButtonTypeCallbackGame: function(){
|
|
||||||
tdLibWrapper.getCallbackQueryAnswer(myMessage.chat_id, myMessage.id, {game_short_name: myMessage.content.game.short_name, "@type": "callbackQueryPayloadGame"})
|
|
||||||
},
|
|
||||||
inlineKeyboardButtonTypeUrl: function() {
|
|
||||||
Functions.handleLink(modelData.type.url);
|
|
||||||
},
|
|
||||||
inlineKeyboardButtonTypeSwitchInline: function() {
|
|
||||||
if(modelData.type.in_current_chat) {
|
|
||||||
chatPage.setMessageText("@" + userInformation.usernames.editable_username + " "+(modelData.type.query || ""))
|
|
||||||
} else {
|
|
||||||
|
|
||||||
pageStack.push(Qt.resolvedUrl("../pages/ChatSelectionPage.qml"), {
|
|
||||||
myUserId: chatPage.myUserId,
|
|
||||||
payload: { neededPermissions: ["can_send_other_messages"], text:"@" + userInformation.usernames.editable_username + " "+(modelData.type.query || "")},
|
|
||||||
state: "fillTextArea"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
keyboardButtonTypeText: function() {
|
|
||||||
chatPage.setMessageText(modelData.text, true);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
enabled: !!callbacks[modelData.type["@type"]]
|
|
||||||
height: Theme.itemSizeSmall
|
|
||||||
width: (replyMarkupButtons.width + Theme.paddingSmall) / buttonsRepeater.count - (Theme.paddingSmall)
|
|
||||||
onClicked: {
|
|
||||||
callbacks[modelData.type["@type"]]();
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: Theme.paddingSmall
|
|
||||||
color: parent.pressed ? Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
|
|
||||||
: Theme.rgba(Theme.primaryColor, Theme.opacityFaint)
|
|
||||||
opacity: parent.enabled ? 1.0 : Theme.opacityLow
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: Math.min(parent.width - Theme.paddingSmall*2, contentWidth)
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
text: Emoji.emojify(modelData.text, Theme.fontSizeSmall)
|
|
||||||
color: parent.parent.pressed ? Theme.highlightColor : Theme.primaryColor
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
}
|
|
||||||
Icon {
|
|
||||||
property var sources: ({
|
|
||||||
inlineKeyboardButtonTypeUrl: "../../images/icon-s-link.svg",
|
|
||||||
inlineKeyboardButtonTypeSwitchInline: !modelData.type.in_current_chat ? "image://theme/icon-s-repost" : "image://theme/icon-s-edit",
|
|
||||||
inlineKeyboardButtonTypeCallbackWithPassword: "image://theme/icon-s-asterisk"
|
|
||||||
})
|
|
||||||
visible: !!sources[modelData.type["@type"]]
|
|
||||||
opacity: 0.6
|
|
||||||
source: sources[modelData.type["@type"]] || ""
|
|
||||||
sourceSize: Qt.size(Theme.iconSizeSmall, Theme.iconSizeSmall)
|
|
||||||
highlighted: parent.pressed
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,52 +25,22 @@ Item {
|
||||||
id: stickerPickerOverlayItem
|
id: stickerPickerOverlayItem
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
property var recentStickers: stickerManager.getRecentStickers();
|
property var recentStickers: stickerManager.getRecentStickers()
|
||||||
property var installedStickerSets: stickerManager.getInstalledStickerSets();
|
property var installedStickerSets: stickerManager.getInstalledStickerSets()
|
||||||
|
property bool pickerLoaded: false
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onOkReceived: {
|
|
||||||
if (request === "removeStickerSet") {
|
|
||||||
appNotification.show(qsTr("Sticker set successfully removed!"));
|
|
||||||
tdLibWrapper.getInstalledStickerSets();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: stickerManager
|
|
||||||
onStickerSetsReceived: {
|
|
||||||
installedStickerSets = stickerManager.getInstalledStickerSets();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: stickerComponent
|
|
||||||
BackgroundItem {
|
|
||||||
id: stickerSetItem
|
|
||||||
width: Theme.itemSizeExtraLarge
|
|
||||||
height: Theme.itemSizeExtraLarge
|
|
||||||
|
|
||||||
onClicked: stickerPickerOverlayItem.stickerPicked(modelData.sticker.remote.id)
|
|
||||||
|
|
||||||
TDLibThumbnail {
|
|
||||||
thumbnail: modelData.thumbnail
|
|
||||||
anchors.fill: parent
|
|
||||||
highlighted: stickerSetItem.highlighted
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
text: Emoji.emojify(modelData.emoji, font.pixelSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
signal stickerPicked(var stickerId)
|
signal stickerPicked(var stickerId)
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: stickerPickerLoadedTimer
|
||||||
|
interval: 100
|
||||||
|
running: true
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
stickerPickerOverlayItem.pickerLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: stickerPickerOverlayBackground
|
id: stickerPickerOverlayBackground
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -79,32 +49,35 @@ Item {
|
||||||
opacity: 0.7
|
opacity: 0.7
|
||||||
}
|
}
|
||||||
|
|
||||||
SilicaListView {
|
Flickable {
|
||||||
id: stickerPickerListView
|
id: stickerPickerFlickable
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.paddingMedium
|
||||||
|
|
||||||
|
opacity: stickerPickerOverlayItem.pickerLoaded ? 1 : 0
|
||||||
|
Behavior on opacity { NumberAnimation {} }
|
||||||
|
visible: stickerPickerOverlayItem.pickerLoaded
|
||||||
|
|
||||||
|
contentHeight: stickerPickerColumn.height
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
model: stickerPickerOverlayItem.installedStickerSets
|
Column {
|
||||||
|
id: stickerPickerColumn
|
||||||
header: Column {
|
spacing: Theme.paddingMedium
|
||||||
spacing: Theme.paddingSmall
|
width: stickerPickerFlickable.width
|
||||||
width: stickerPickerListView.width
|
|
||||||
height: recentStickersGridView.count > 0 ? ( Theme.fontSizeLarge + Theme.itemSizeExtraLarge + 4 * Theme.paddingSmall ) : 0
|
|
||||||
topPadding: Theme.paddingSmall
|
|
||||||
Label {
|
Label {
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.bold: true
|
font.bold: true
|
||||||
width: recentStickersGridView.width
|
width: parent.width
|
||||||
leftPadding: Theme.paddingMedium
|
|
||||||
visible: recentStickersGridView.count > 0
|
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
text: qsTr("Recently used")
|
text: qsTr("Recently used")
|
||||||
}
|
}
|
||||||
|
|
||||||
SilicaGridView {
|
SilicaGridView {
|
||||||
id: recentStickersGridView
|
id: recentStickersGridView
|
||||||
width: stickerPickerListView.width
|
width: parent.width
|
||||||
height: Theme.itemSizeExtraLarge + Theme.paddingSmall
|
height: Theme.itemSizeExtraLarge
|
||||||
cellWidth: Theme.itemSizeExtraLarge;
|
cellWidth: Theme.itemSizeExtraLarge;
|
||||||
cellHeight: Theme.itemSizeExtraLarge;
|
cellHeight: Theme.itemSizeExtraLarge;
|
||||||
visible: count > 0
|
visible: count > 0
|
||||||
|
@ -112,132 +85,119 @@ Item {
|
||||||
flow: GridView.FlowTopToBottom
|
flow: GridView.FlowTopToBottom
|
||||||
|
|
||||||
model: stickerPickerOverlayItem.recentStickers
|
model: stickerPickerOverlayItem.recentStickers
|
||||||
delegate: stickerComponent
|
|
||||||
|
delegate: Item {
|
||||||
|
width: recentStickersGridView.cellWidth
|
||||||
|
height: recentStickersGridView.cellHeight
|
||||||
|
|
||||||
|
Image {
|
||||||
|
source: modelData.thumbnail.file.local.path
|
||||||
|
anchors.fill: parent
|
||||||
|
asynchronous: true
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Image.Ready) {
|
||||||
|
stickerPickerLoadedTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: stickerPickerOverlayItem.stickerPicked(modelData.sticker.remote.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
HorizontalScrollDecorator {}
|
HorizontalScrollDecorator {}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
delegate: Column {
|
|
||||||
id: stickerSetColumn
|
|
||||||
|
|
||||||
property bool isExpanded: false
|
|
||||||
function toggleDisplaySet() {
|
|
||||||
stickerSetColumn.isExpanded = !stickerSetColumn.isExpanded;
|
|
||||||
if (stickerSetColumn.isExpanded) {
|
|
||||||
stickerSetLoader.myStickerSet = modelData.stickers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spacing: Theme.paddingSmall
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: stickerSetTitleRow
|
|
||||||
width: parent.width
|
|
||||||
height: Theme.itemSizeMedium + ( 2 * Theme.paddingSmall )
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
BackgroundItem {
|
|
||||||
id: stickerSetToggle
|
|
||||||
width: parent.width - removeSetButton.width - Theme.paddingMedium * 2
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
toggleDisplaySet();
|
|
||||||
}
|
|
||||||
TDLibThumbnail {
|
|
||||||
id: stickerSetThumbnail
|
|
||||||
thumbnail: modelData.thumbnail ? modelData.thumbnail : modelData.stickers[0].thumbnail
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
leftMargin: Theme.paddingMedium
|
|
||||||
}
|
|
||||||
width: Theme.itemSizeMedium
|
|
||||||
height: Theme.itemSizeMedium
|
|
||||||
highlighted: stickerSetToggle.down
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: stickerPickerOverlayItem.installedStickerSets
|
||||||
|
width: stickerPickerFlickable.width
|
||||||
|
Column {
|
||||||
|
spacing: Theme.paddingMedium
|
||||||
|
width: parent.width
|
||||||
Label {
|
Label {
|
||||||
id: setTitleText
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.bold: true
|
font.bold: true
|
||||||
|
width: parent.width
|
||||||
anchors {
|
maximumLineCount: 1
|
||||||
left: stickerSetThumbnail.right
|
|
||||||
right: expandSetButton.left
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
margins: Theme.paddingSmall
|
|
||||||
}
|
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
text: modelData.title
|
text: modelData.title
|
||||||
}
|
}
|
||||||
|
|
||||||
Icon {
|
SilicaGridView {
|
||||||
id: expandSetButton
|
|
||||||
source: stickerSetColumn.isExpanded ? "image://theme/icon-m-up" : "image://theme/icon-m-down"
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
rightMargin: Theme.paddingMedium
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
id: removeSetButton
|
|
||||||
icon.source: "image://theme/icon-m-remove"
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onClicked: {
|
|
||||||
var stickerSetId = modelData.id;
|
|
||||||
Remorse.popupAction(chatPage, qsTr("Removing sticker set"), function() {
|
|
||||||
tdLibWrapper.changeStickerSet(stickerSetId, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: stickerSetLoader
|
|
||||||
width: parent.width
|
|
||||||
active: stickerSetColumn.isExpanded || height > 0
|
|
||||||
height: stickerSetColumn.isExpanded ? Theme.itemSizeExtraLarge + Theme.paddingSmall : 0
|
|
||||||
opacity: stickerSetColumn.isExpanded ? 1.0 : 0.0
|
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
NumberAnimation { duration: 200 }
|
|
||||||
}
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 200 }
|
|
||||||
}
|
|
||||||
|
|
||||||
property var myStickerSet
|
|
||||||
onActiveChanged: {
|
|
||||||
if(!active) {
|
|
||||||
myStickerSet = ({});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: Component {
|
|
||||||
SilicaListView {
|
|
||||||
id: installedStickerSetGridView
|
id: installedStickerSetGridView
|
||||||
width: stickerSetLoader.width
|
width: parent.width
|
||||||
height: stickerSetLoader.height
|
height: Theme.itemSizeExtraLarge
|
||||||
|
cellWidth: Theme.itemSizeExtraLarge;
|
||||||
orientation: Qt.Horizontal
|
cellHeight: Theme.itemSizeExtraLarge;
|
||||||
visible: count > 0
|
visible: count > 0
|
||||||
|
clip: true
|
||||||
|
flow: GridView.FlowTopToBottom
|
||||||
|
|
||||||
model: stickerSetLoader.myStickerSet
|
model: modelData.stickers
|
||||||
delegate: stickerComponent
|
delegate: Item {
|
||||||
|
width: installedStickerSetGridView.cellWidth
|
||||||
|
height: installedStickerSetGridView.cellHeight
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: singleStickerImage
|
||||||
|
source: modelData.thumbnail.file.local.is_downloading_completed ? modelData.thumbnail.file.local.path : ""
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: modelData.thumbnail.file.local.is_downloading_completed
|
||||||
|
asynchronous: true
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Image.Ready) {
|
||||||
|
stickerPickerLoadedTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
font.pixelSize: Theme.fontSizeHuge
|
||||||
|
anchors.fill: parent
|
||||||
|
maximumLineCount: 1
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
text: Emoji.emojify(modelData.emoji, font.pixelSize)
|
||||||
|
visible: !modelData.thumbnail.file.local.is_downloading_completed
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: stickerPickerOverlayItem.stickerPicked(modelData.sticker.remote.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HorizontalScrollDecorator {}
|
HorizontalScrollDecorator {}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.paddingMedium
|
||||||
|
|
||||||
|
opacity: stickerPickerOverlayItem.pickerLoaded ? 0 : 1
|
||||||
|
Behavior on opacity { NumberAnimation {} }
|
||||||
|
visible: !stickerPickerOverlayItem.pickerLoaded
|
||||||
|
|
||||||
|
InfoLabel {
|
||||||
|
id: loadingLabel
|
||||||
|
text: qsTr("Loading stickers...")
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
id: loadingBusyIndicator
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
running: !stickerPickerOverlayItem.pickerLoaded
|
||||||
|
size: BusyIndicatorSize.Large
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
@ -19,23 +19,25 @@
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import WerkWolf.Fernschreiber 1.0
|
import WerkWolf.Fernschreiber 1.0
|
||||||
import "../"
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
MessageContentBase {
|
Item {
|
||||||
id: thisItem
|
property ListItem messageListItem
|
||||||
|
property MessageOverlayFlickable overlayFlickable
|
||||||
|
|
||||||
property var stickerData: messageListItem ? messageListItem.myMessage.content.sticker : overlayFlickable.overlayMessage.content.sticker;
|
readonly property var stickerData: messageListItem ? messageListItem.myMessage.content.sticker : overlayFlickable.overlayMessage.content.sticker;
|
||||||
readonly property bool asEmoji: appSettings.showStickersAsEmojis
|
readonly property bool animated: stickerData.is_animated && appSettings.animateStickers
|
||||||
readonly property bool animated: stickerData.format["@type"] === "stickerFormatTgs" && appSettings.animateStickers
|
|
||||||
readonly property bool stickerVisible: staticStickerLoader.item ? staticStickerLoader.item.visible :
|
readonly property bool stickerVisible: staticStickerLoader.item ? staticStickerLoader.item.visible :
|
||||||
animatedStickerLoader.item ? animatedStickerLoader.item.visible : false
|
animatedStickerLoader.item ? animatedStickerLoader.item.visible : false
|
||||||
readonly property bool isOwnSticker : messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
|
readonly property bool isOwnSticker : messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
|
||||||
readonly property real aspectRatio: stickerData.width / stickerData.height
|
property real aspectRatio: stickerData.width / stickerData.height
|
||||||
|
property bool highlighted
|
||||||
|
|
||||||
implicitWidth: stickerData.width
|
implicitWidth: stickerData.width
|
||||||
implicitHeight: stickerData.height
|
implicitHeight: stickerData.height
|
||||||
|
|
||||||
|
layer.enabled: highlighted
|
||||||
|
layer.effect: PressEffect { source: singleImage }
|
||||||
|
|
||||||
TDLibFile {
|
TDLibFile {
|
||||||
id: file
|
id: file
|
||||||
tdlib: tdLibWrapper
|
tdlib: tdLibWrapper
|
||||||
|
@ -44,7 +46,6 @@ MessageContentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
||||||
width: Math.min( stickerData.width, parent.width )
|
width: Math.min( stickerData.width, parent.width )
|
||||||
height: width * aspectRatio
|
height: width * aspectRatio
|
||||||
// (centered in image mode, text-like in sticker mode)
|
// (centered in image mode, text-like in sticker mode)
|
||||||
|
@ -55,17 +56,14 @@ MessageContentBase {
|
||||||
Loader {
|
Loader {
|
||||||
id: animatedStickerLoader
|
id: animatedStickerLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: animated && !asEmoji
|
active: animated
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
AnimatedImage {
|
AnimatedImage {
|
||||||
id: animatedSticker
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: file.path
|
source: file.path
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
paused: !Qt.application.active
|
paused: !Qt.application.active
|
||||||
cache: false
|
cache: false
|
||||||
layer.enabled: thisItem.highlighted
|
|
||||||
layer.effect: PressEffect { source: animatedSticker }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,24 +71,17 @@ MessageContentBase {
|
||||||
Loader {
|
Loader {
|
||||||
id: staticStickerLoader
|
id: staticStickerLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: !animated || asEmoji
|
active: !animated
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
Image {
|
Image {
|
||||||
id: staticSticker
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: asEmoji ? Emoji.getEmojiPath(stickerData.emoji) : file.path
|
source: file.path
|
||||||
sourceSize {
|
|
||||||
width: width
|
|
||||||
height: height
|
|
||||||
}
|
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
autoTransform: true
|
autoTransform: true
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
opacity: status === Image.Ready ? 1 : 0
|
opacity: status === Image.Ready ? 1 : 0
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { FadeAnimation {} }
|
||||||
layer.enabled: thisItem.highlighted
|
|
||||||
layer.effect: PressEffect { source: staticSticker }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,11 +98,6 @@ MessageContentBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
stickerSetOverlayLoader.stickerSetId = stickerData.set_id
|
|
||||||
stickerSetOverlayLoader.active = true
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: placeHolderDelayTimer
|
id: placeHolderDelayTimer
|
||||||
interval: 1000
|
interval: 1000
|
|
@ -1,173 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "./messageContent"
|
|
||||||
import "../js/functions.js" as Functions
|
|
||||||
import "../js/twemoji.js" as Emoji
|
|
||||||
import "../js/debug.js" as Debug
|
|
||||||
|
|
||||||
Flickable {
|
|
||||||
id: stickerSetOverlayFlickable
|
|
||||||
anchors.fill: parent
|
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
|
||||||
contentHeight: stickerSetContentColumn.height
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
property string stickerSetId;
|
|
||||||
property var stickerSet;
|
|
||||||
signal requestClose;
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (!stickerManager.hasStickerSet(stickerSetId)) {
|
|
||||||
tdLibWrapper.getStickerSet(stickerSetId);
|
|
||||||
} else {
|
|
||||||
stickerSet = stickerManager.getStickerSet(stickerSetId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onStickerSetReceived: {
|
|
||||||
if (stickerSet.id === stickerSetOverlayFlickable.stickerSetId) {
|
|
||||||
stickerSetOverlayFlickable.stickerSet = stickerSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onOkReceived: {
|
|
||||||
if (request === "installStickerSet") {
|
|
||||||
appNotification.show(qsTr("Sticker set successfully installed!"));
|
|
||||||
installSetButton.visible = false;
|
|
||||||
tdLibWrapper.getInstalledStickerSets();
|
|
||||||
}
|
|
||||||
if (request === "removeStickerSet") {
|
|
||||||
appNotification.show(qsTr("Sticker set successfully removed!"));
|
|
||||||
installSetButton.visible = true;
|
|
||||||
tdLibWrapper.getInstalledStickerSets();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: stickerSetContentBackground
|
|
||||||
color: Theme.overlayBackgroundColor
|
|
||||||
opacity: 0.7
|
|
||||||
anchors.fill: parent
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
stickerSetOverlayFlickable.requestClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: stickerSetContentColumn
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: stickerSetTitleRow
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
height: overlayStickerTitleText.height + ( 2 * Theme.paddingMedium )
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: overlayStickerTitleText
|
|
||||||
|
|
||||||
width: parent.width - installSetButton.width - closeSetButton.width
|
|
||||||
text: stickerSet.title
|
|
||||||
font.pixelSize: Theme.fontSizeExtraLarge
|
|
||||||
font.weight: Font.ExtraBold
|
|
||||||
maximumLineCount: 1
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
textFormat: Text.StyledText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
id: installSetButton
|
|
||||||
icon.source: "image://theme/icon-m-add"
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !stickerManager.isStickerSetInstalled(stickerSet.id)
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.changeStickerSet(stickerSet.id, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
id: removeSetButton
|
|
||||||
icon.source: "image://theme/icon-m-remove"
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !installSetButton.visible
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.changeStickerSet(stickerSet.id, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
id: closeSetButton
|
|
||||||
icon.source: "image://theme/icon-m-clear"
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onClicked: {
|
|
||||||
stickerSetOverlayFlickable.requestClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SilicaGridView {
|
|
||||||
id: stickerSetGridView
|
|
||||||
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
height: parent.height - stickerSetTitleRow.height - Theme.paddingMedium
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
cellWidth: chatPage.isLandscape ? (width / 5) : (width / 3);
|
|
||||||
cellHeight: cellWidth
|
|
||||||
|
|
||||||
visible: count > 0
|
|
||||||
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
model: stickerSet.stickers
|
|
||||||
delegate: Item {
|
|
||||||
width: stickerSetGridView.cellWidth - Theme.paddingSmall
|
|
||||||
height: stickerSetGridView.cellHeight - Theme.paddingSmall
|
|
||||||
|
|
||||||
TDLibThumbnail {
|
|
||||||
id: singleStickerThumbnail
|
|
||||||
thumbnail: modelData.thumbnail
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
text: Emoji.emojify(modelData.emoji, font.pixelSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
VerticalScrollDecorator {}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
|
|
||||||
import "../js/debug.js" as Debug
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: tdLibImage
|
|
||||||
property alias fileInformation: file.fileInformation
|
|
||||||
readonly property alias file: file
|
|
||||||
property bool highlighted
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
enabled: !!file.fileId
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
clip: true
|
|
||||||
opacity: status === Image.Ready ? 1.0 : 0.0
|
|
||||||
source: enabled && file.isDownloadingCompleted ? file.path : ""
|
|
||||||
visible: opacity > 0
|
|
||||||
sourceSize {
|
|
||||||
width: width
|
|
||||||
height: height
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
|
|
||||||
layer {
|
|
||||||
enabled: tdLibImage.enabled && tdLibImage.highlighted
|
|
||||||
effect: PressEffect { source: tdLibImage }
|
|
||||||
}
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: file
|
|
||||||
autoLoad: true
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: loader
|
|
||||||
property var minithumbnail
|
|
||||||
property bool highlighted
|
|
||||||
anchors.fill: parent
|
|
||||||
active: !!minithumbnail
|
|
||||||
sourceComponent: Component {
|
|
||||||
Item {
|
|
||||||
Image {
|
|
||||||
id: minithumbnailImage
|
|
||||||
anchors.fill: parent
|
|
||||||
source: "data:image/jpg;base64,"+minithumbnail.data
|
|
||||||
fillMode: tdLibImage.fillMode
|
|
||||||
opacity: status === Image.Ready ? 1.0 : 0.0
|
|
||||||
cache: false
|
|
||||||
visible: opacity > 0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
|
|
||||||
layer {
|
|
||||||
enabled: loader.highlighted
|
|
||||||
effect: PressEffect { source: minithumbnailImage }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FastBlur {
|
|
||||||
anchors.fill: parent
|
|
||||||
source: minithumbnailImage
|
|
||||||
radius: Theme.paddingLarge
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: tdLibPhoto
|
|
||||||
property var photo
|
|
||||||
property bool highlighted
|
|
||||||
readonly property alias fileInformation: tdLibImage.fileInformation
|
|
||||||
readonly property alias image: tdLibImage
|
|
||||||
|
|
||||||
onWidthChanged: setImageFile()
|
|
||||||
onPhotoChanged: setImageFile()
|
|
||||||
|
|
||||||
function setImageFile() {
|
|
||||||
if (photo) {
|
|
||||||
var photoSize;
|
|
||||||
for (var i = 0; i < photo.sizes.length; i++) {
|
|
||||||
photoSize = photo.sizes[i].photo;
|
|
||||||
if (photo.sizes[i].width >= width) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (photoSize && photoSize.id !== tdLibImage.fileInformation.id) {
|
|
||||||
tdLibImage.fileInformation = photoSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TDLibMinithumbnail {
|
|
||||||
id: minithumbnailLoader
|
|
||||||
active: !!minithumbnail && tdLibImage.opacity < 1.0
|
|
||||||
minithumbnail: tdLibPhoto.photo.minithumbnail
|
|
||||||
highlighted: parent.highlighted
|
|
||||||
}
|
|
||||||
|
|
||||||
BackgroundImage {
|
|
||||||
visible: !tdLibImage.visible && !(minithumbnailLoader.item && minithumbnailLoader.item.visible)
|
|
||||||
}
|
|
||||||
|
|
||||||
TDLibImage {
|
|
||||||
id: tdLibImage
|
|
||||||
width: parent.width //don't use anchors here for easier custom scaling
|
|
||||||
height: parent.height
|
|
||||||
cache: false
|
|
||||||
highlighted: parent.highlighted
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: setImageFile()
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import Nemo.Thumbnailer 1.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: tdlibThumbnail
|
|
||||||
/*
|
|
||||||
Optional thumbnail, usually as property "thumbnail".
|
|
||||||
The following TDLib objects can have it:
|
|
||||||
- animation
|
|
||||||
- audio (as "album_cover_thumbnail")
|
|
||||||
- document
|
|
||||||
- sticker (no minithumbnail)
|
|
||||||
- video
|
|
||||||
- videoNote
|
|
||||||
- stickerSet (no minithumbnail)
|
|
||||||
- stickerSetInfo (no minithumbnail)
|
|
||||||
- inlineQueryResultArticle (no minithumbnail)
|
|
||||||
- inlineQueryResultContact (no minithumbnail)
|
|
||||||
- inlineQueryResultLocation (no minithumbnail)
|
|
||||||
- inlineQueryResultVenue (no minithumbnail)
|
|
||||||
*/
|
|
||||||
property var thumbnail
|
|
||||||
/*
|
|
||||||
Optional minithumbnail, usually as property "minithumbnail".
|
|
||||||
Has data inline: If present, it doesn't need another request.
|
|
||||||
The following TDLib objects can have it:
|
|
||||||
- animation
|
|
||||||
- audio (as "album_cover_minithumbnail")
|
|
||||||
- document
|
|
||||||
- photo / chatPhoto (Note: No thumbnail, so not applicable here)
|
|
||||||
- video
|
|
||||||
- videoNote
|
|
||||||
*/
|
|
||||||
property alias minithumbnail: minithumbnailLoader.minithumbnail
|
|
||||||
property bool useBackgroundImage: true
|
|
||||||
property bool highlighted
|
|
||||||
|
|
||||||
property bool isVideo: !!thumbnail && thumbnail.format["@type"] === "thumbnailFormatMpeg4"
|
|
||||||
property string videoMimeType: "video/mp4"
|
|
||||||
|
|
||||||
readonly property bool hasVisibleThumbnail: thumbnailImage.opacity !== 1.0
|
|
||||||
&& !(videoThumbnailLoader.item && videoThumbnailLoader.item.opacity === 1.0)
|
|
||||||
|
|
||||||
layer {
|
|
||||||
enabled: highlighted
|
|
||||||
effect: PressEffect { source: tdlibThumbnail }
|
|
||||||
}
|
|
||||||
|
|
||||||
TDLibMinithumbnail {
|
|
||||||
id: minithumbnailLoader
|
|
||||||
active: !!minithumbnail && thumbnailImage.opacity < 1.0
|
|
||||||
}
|
|
||||||
BackgroundImage {
|
|
||||||
visible: tdlibThumbnail.useBackgroundImage && thumbnailImage.opacity < 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
// image thumbnail
|
|
||||||
TDLibImage {
|
|
||||||
id: thumbnailImage
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: !parent.isVideo
|
|
||||||
fileInformation: tdlibThumbnail.thumbnail ? tdlibThumbnail.thumbnail.file : {}
|
|
||||||
onStatusChanged: { //TODO check if this is really how it is ;)
|
|
||||||
if(status === Image.Error) {
|
|
||||||
// in some cases, webp is used (without correct mime type).
|
|
||||||
// we just try it blindly and cross our fingers:
|
|
||||||
tdlibThumbnail.videoMimeType = "image/webp";
|
|
||||||
tdlibThumbnail.isVideo = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback for video thumbnail format: try to use Nemo.Thumbnailer
|
|
||||||
Loader {
|
|
||||||
id: videoThumbnailLoader
|
|
||||||
active: parent.isVideo
|
|
||||||
asynchronous: true
|
|
||||||
anchors.fill: parent
|
|
||||||
sourceComponent: Component {
|
|
||||||
id: videoThumbnail
|
|
||||||
Thumbnail {
|
|
||||||
id: thumbnail
|
|
||||||
source: thumbnailImage.file.path
|
|
||||||
sourceSize.width: width
|
|
||||||
sourceSize.height: height
|
|
||||||
mimeType: tdlibThumbnail.videoMimeType
|
|
||||||
visible: opacity > 0
|
|
||||||
opacity: status === Thumbnail.Ready ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,13 +19,16 @@
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import QtMultimedia 5.6
|
import QtMultimedia 5.6
|
||||||
import "../"
|
import "../js/functions.js" as Functions
|
||||||
import "../../js/functions.js" as Functions
|
import "../js/debug.js" as Debug
|
||||||
import "../../js/debug.js" as Debug
|
|
||||||
|
|
||||||
MessageContentBase {
|
Item {
|
||||||
id: videoMessageComponent
|
id: videoMessageComponent
|
||||||
|
|
||||||
|
property ListItem messageListItem
|
||||||
|
property MessageOverlayFlickable overlayFlickable
|
||||||
|
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
||||||
|
|
||||||
property var videoData: ( rawMessage.content['@type'] === "messageVideo" ) ? rawMessage.content.video : ( ( rawMessage.content['@type'] === "messageAnimation" ) ? rawMessage.content.animation : rawMessage.content.video_note )
|
property var videoData: ( rawMessage.content['@type'] === "messageVideo" ) ? rawMessage.content.video : ( ( rawMessage.content['@type'] === "messageAnimation" ) ? rawMessage.content.animation : rawMessage.content.video_note )
|
||||||
property string videoUrl;
|
property string videoUrl;
|
||||||
property int previewFileId;
|
property int previewFileId;
|
||||||
|
@ -35,7 +38,10 @@ MessageContentBase {
|
||||||
property bool onScreen: messageListItem ? messageListItem.page.status === PageStatus.Active : true;
|
property bool onScreen: messageListItem ? messageListItem.page.status === PageStatus.Active : true;
|
||||||
property string videoType : "video";
|
property string videoType : "video";
|
||||||
property bool playRequested: false;
|
property bool playRequested: false;
|
||||||
|
property bool highlighted;
|
||||||
|
signal clicked();
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
height: videoMessageComponent.isVideoNote ? width : Functions.getVideoHeight(width, videoData)
|
height: videoMessageComponent.isVideoNote ? width : Functions.getVideoHeight(width, videoData)
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
@ -83,7 +89,7 @@ MessageContentBase {
|
||||||
|
|
||||||
videoMessageComponent.videoType = videoMessageComponent.isVideoNote ? "video" : videoData['@type'];
|
videoMessageComponent.videoType = videoMessageComponent.isVideoNote ? "video" : videoData['@type'];
|
||||||
videoFileId = videoData[videoType].id;
|
videoFileId = videoData[videoType].id;
|
||||||
if (typeof rawMessage !== "undefined" && rawMessage.content['@type'] === "messageAnimation") {
|
if (rawMessage.content['@type'] === "messageAnimation") {
|
||||||
playButton.visible = true;
|
playButton.visible = true;
|
||||||
fullscreenButton.visible = !videoMessageComponent.fullscreen;
|
fullscreenButton.visible = !videoMessageComponent.fullscreen;
|
||||||
handlePlay();
|
handlePlay();
|
||||||
|
@ -95,7 +101,7 @@ MessageContentBase {
|
||||||
tdLibWrapper.downloadFile(previewFileId);
|
tdLibWrapper.downloadFile(previewFileId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
placeholderImage.source = "image://theme/icon-m-video?white";
|
placeholderImage.source = "image://theme/icon-l-video?white";
|
||||||
placeholderImage.width = Theme.itemSizeLarge
|
placeholderImage.width = Theme.itemSizeLarge
|
||||||
placeholderImage.height = Theme.itemSizeLarge
|
placeholderImage.height = Theme.itemSizeLarge
|
||||||
}
|
}
|
||||||
|
@ -147,7 +153,7 @@ MessageContentBase {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
visible: status === Image.Ready ? true : false
|
visible: status === Image.Ready ? true : false
|
||||||
layer.enabled: videoMessageComponent.highlighted
|
layer.enabled: videoMessageComponent.highlighted
|
||||||
layer.effect: PressEffect { source: placeholderImage }
|
layer.effect: PressEffect { source: singleImage }
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundImage {
|
BackgroundImage {
|
||||||
|
@ -155,6 +161,7 @@ MessageContentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: placeholderBackground
|
||||||
color: "black"
|
color: "black"
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
@ -209,7 +216,7 @@ MessageContentBase {
|
||||||
height: Theme.iconSizeLarge
|
height: Theme.iconSizeLarge
|
||||||
icon {
|
icon {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
source: "../../../images/icon-l-fullscreen.svg"
|
source: "../../images/icon-l-fullscreen.svg"
|
||||||
sourceSize {
|
sourceSize {
|
||||||
width: Theme.iconSizeLarge
|
width: Theme.iconSizeLarge
|
||||||
height: Theme.iconSizeLarge
|
height: Theme.iconSizeLarge
|
||||||
|
@ -218,7 +225,7 @@ MessageContentBase {
|
||||||
highlighted: videoMessageComponent.highlighted || down
|
highlighted: videoMessageComponent.highlighted || down
|
||||||
visible: ( placeholderImage.status === Image.Ready && !videoMessageComponent.fullscreen ) ? true : false
|
visible: ( placeholderImage.status === Image.Ready && !videoMessageComponent.fullscreen ) ? true : false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
pageStack.push(Qt.resolvedUrl("../../pages/VideoPage.qml"), {"videoData": videoData, "sourceMessage": rawMessage});
|
pageStack.push(Qt.resolvedUrl("../pages/VideoPage.qml"), {"videoData": videoData});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,6 +241,7 @@ MessageContentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: videoErrorShade
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
color: "lightgrey"
|
color: "lightgrey"
|
||||||
|
@ -288,6 +296,21 @@ MessageContentBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: videoMessageComponent
|
||||||
|
onClicked: {
|
||||||
|
if (messageVideo.playbackState === MediaPlayer.PlayingState) {
|
||||||
|
enableScreensaver();
|
||||||
|
messageVideo.pause();
|
||||||
|
timeLeftItem.visible = true;
|
||||||
|
} else {
|
||||||
|
disableScreensaver();
|
||||||
|
messageVideo.play();
|
||||||
|
timeLeftTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Video {
|
Video {
|
||||||
id: messageVideo
|
id: messageVideo
|
||||||
|
|
||||||
|
@ -346,7 +369,7 @@ MessageContentBase {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
source: videoUrl
|
source: videoUrl
|
||||||
layer.enabled: videoMessageComponent.highlighted
|
layer.enabled: videoMessageComponent.highlighted
|
||||||
layer.effect: PressEffect { source: messageVideo }
|
layer.effect: PressEffect { source: singleImage }
|
||||||
onStopped: {
|
onStopped: {
|
||||||
enableScreensaver();
|
enableScreensaver();
|
||||||
messageVideo.visible = false;
|
messageVideo.visible = false;
|
||||||
|
@ -355,21 +378,6 @@ MessageContentBase {
|
||||||
videoComponentLoader.active = false;
|
videoComponentLoader.active = false;
|
||||||
fullscreenItem.visible = !videoMessageComponent.fullscreen;
|
fullscreenItem.visible = !videoMessageComponent.fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
if (messageVideo.playbackState === MediaPlayer.PlayingState) {
|
|
||||||
enableScreensaver();
|
|
||||||
messageVideo.pause();
|
|
||||||
timeLeftItem.visible = true;
|
|
||||||
} else {
|
|
||||||
disableScreensaver();
|
|
||||||
messageVideo.play();
|
|
||||||
timeLeftTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
|
@ -456,7 +464,7 @@ MessageContentBase {
|
||||||
highlighted: videoMessageComponent.highlighted || down
|
highlighted: videoMessageComponent.highlighted || down
|
||||||
icon {
|
icon {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
source: "../../../images/icon-l-fullscreen.svg"
|
source: "../../images/icon-l-fullscreen.svg"
|
||||||
sourceSize {
|
sourceSize {
|
||||||
width: Theme.iconSizeLarge
|
width: Theme.iconSizeLarge
|
||||||
height: Theme.iconSizeLarge
|
height: Theme.iconSizeLarge
|
||||||
|
@ -464,7 +472,7 @@ MessageContentBase {
|
||||||
}
|
}
|
||||||
visible: ( videoComponentLoader.active && messageVideo.playbackState === MediaPlayer.PausedState ) ? true : false
|
visible: ( videoComponentLoader.active && messageVideo.playbackState === MediaPlayer.PausedState ) ? true : false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
pageStack.push(Qt.resolvedUrl("../../pages/VideoPage.qml"), {"videoData": videoData, "sourceMessage": rawMessage});
|
pageStack.push(Qt.resolvedUrl("../pages/VideoPage.qml"), {"videoData": videoData});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,7 +484,7 @@ MessageContentBase {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.bottom: positionText.top
|
anchors.bottom: positionText.top
|
||||||
minimumValue: 0
|
minimumValue: 0
|
||||||
maximumValue: messageVideo.duration ? messageVideo.duration : 0.1
|
maximumValue: messageVideo.duration ? messageVideo.duration : 0
|
||||||
|
|
||||||
highlighted: videoMessageComponent.highlighted || down
|
highlighted: videoMessageComponent.highlighted || down
|
||||||
stepSize: 1
|
stepSize: 1
|
||||||
|
@ -508,6 +516,7 @@ MessageContentBase {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,221 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../components"
|
|
||||||
import "../js/twemoji.js" as Emoji
|
|
||||||
import "../js/debug.js" as Debug
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: voiceNoteOverlayItem
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
property int recordingState: fernschreiberUtils.getVoiceNoteRecordingState();
|
|
||||||
property int recordingDuration: 0;
|
|
||||||
property bool recordingDone: false;
|
|
||||||
|
|
||||||
function handleRecordingState() {
|
|
||||||
switch (recordingState) {
|
|
||||||
case FernschreiberUtilities.Unavailable:
|
|
||||||
recordingStateLabel.text = qsTr("Unavailable");
|
|
||||||
break;
|
|
||||||
case FernschreiberUtilities.Ready:
|
|
||||||
recordingStateLabel.text = qsTr("Ready");
|
|
||||||
break;
|
|
||||||
case FernschreiberUtilities.Starting:
|
|
||||||
recordingStateLabel.text = qsTr("Starting");
|
|
||||||
break;
|
|
||||||
case FernschreiberUtilities.Recording:
|
|
||||||
recordingStateLabel.text = qsTr("Recording");
|
|
||||||
break;
|
|
||||||
case FernschreiberUtilities.Stopping:
|
|
||||||
recordingStateLabel.text = qsTr("Stopping");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTwoDigitString(numberToBeConverted) {
|
|
||||||
var numberString = "00";
|
|
||||||
if (numberToBeConverted > 0 && numberToBeConverted < 10) {
|
|
||||||
numberString = "0" + String(numberToBeConverted);
|
|
||||||
}
|
|
||||||
if (numberToBeConverted >= 10) {
|
|
||||||
numberString = String(numberToBeConverted);
|
|
||||||
}
|
|
||||||
return numberString;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRecordingDuration() {
|
|
||||||
var minutes = Math.floor(recordingDuration / 60);
|
|
||||||
var seconds = recordingDuration % 60;
|
|
||||||
recordingDurationLabel.text = getTwoDigitString(minutes) + ":" + getTwoDigitString(seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
handleRecordingState();
|
|
||||||
handleRecordingDuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: fernschreiberUtils
|
|
||||||
onVoiceNoteDurationChanged: {
|
|
||||||
Debug.log("New duration received: " + duration);
|
|
||||||
recordingDuration = Math.round(duration / 1000);
|
|
||||||
handleRecordingDuration();
|
|
||||||
}
|
|
||||||
onVoiceNoteRecordingStateChanged: {
|
|
||||||
Debug.log("New state received: " + state);
|
|
||||||
recordingState = state;
|
|
||||||
handleRecordingState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: stickerPickerOverlayBackground
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
color: Theme.overlayBackgroundColor
|
|
||||||
opacity: Theme.opacityHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
Flickable {
|
|
||||||
id: voiceNoteFlickable
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.paddingMedium
|
|
||||||
|
|
||||||
Behavior on opacity { NumberAnimation {} }
|
|
||||||
|
|
||||||
contentHeight: voiceNoteColumn.height
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: voiceNoteColumn
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
width: voiceNoteFlickable.width
|
|
||||||
|
|
||||||
InfoLabel {
|
|
||||||
text: qsTr("Record a Voice Note")
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("Press the button to start recording")
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: Theme.iconSizeExtraLarge
|
|
||||||
height: Theme.iconSizeExtraLarge
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
color: Theme.primaryColor
|
|
||||||
opacity: Theme.opacityOverlay
|
|
||||||
width: Theme.iconSizeExtraLarge
|
|
||||||
height: Theme.iconSizeExtraLarge
|
|
||||||
anchors.centerIn: parent
|
|
||||||
radius: width / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: recordButton
|
|
||||||
color: "red"
|
|
||||||
width: Theme.iconSizeExtraLarge * 0.6
|
|
||||||
height: Theme.iconSizeExtraLarge * 0.6
|
|
||||||
anchors.centerIn: parent
|
|
||||||
radius: width / 2
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
recordButton.visible = false;
|
|
||||||
recordingDone = false;
|
|
||||||
recordingDuration = 0;
|
|
||||||
handleRecordingDuration();
|
|
||||||
fernschreiberUtils.startRecordingVoiceNote();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: stopButton
|
|
||||||
visible: !recordButton.visible
|
|
||||||
color: Theme.overlayBackgroundColor
|
|
||||||
width: Theme.iconSizeExtraLarge * 0.4
|
|
||||||
height: Theme.iconSizeExtraLarge * 0.4
|
|
||||||
anchors.centerIn: parent
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
recordButton.visible = true;
|
|
||||||
fernschreiberUtils.stopRecordingVoiceNote();
|
|
||||||
recordingDone = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: recordingStateLabel
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: recordingDurationLabel
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
visible: recordingDone
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
text: qsTr("Use recording")
|
|
||||||
onClicked: {
|
|
||||||
attachmentOptionsFlickable.isNeeded = false;
|
|
||||||
attachmentPreviewRow.isVoiceNote = true;
|
|
||||||
attachmentPreviewRow.attachmentDescription = qsTr("Voice Note (%1)").arg(recordingDurationLabel.text);
|
|
||||||
controlSendButton();
|
|
||||||
voiceNoteOverlayLoader.active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,92 +19,101 @@
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import WerkWolf.Fernschreiber 1.0
|
import "../components"
|
||||||
import "../"
|
import "../js/twemoji.js" as Emoji
|
||||||
import "../../js/functions.js" as Functions
|
import "../js/functions.js" as Functions
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|
||||||
id: webPagePreviewColumn
|
id: webPagePreviewColumn
|
||||||
|
|
||||||
property var webPageData;
|
property var webPageData;
|
||||||
|
property var pictureFileInformation;
|
||||||
|
property bool hasImage: false;
|
||||||
property bool largerFontSize: false;
|
property bool largerFontSize: false;
|
||||||
property bool highlighted
|
property bool highlighted
|
||||||
readonly property bool hasImage: picture.fileId !== 0
|
|
||||||
readonly property int fontSize: largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
|
|
||||||
|
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
|
|
||||||
Component.onCompleted: updatePhoto()
|
Component.onCompleted: {
|
||||||
|
updateWebPage();
|
||||||
|
}
|
||||||
|
|
||||||
onWebPageDataChanged: updatePhoto()
|
function updateWebPage() {
|
||||||
|
|
||||||
function updatePhoto() {
|
|
||||||
if (webPageData) {
|
if (webPageData) {
|
||||||
if (webPageData.photo) {
|
if (typeof webPageData.photo !== "undefined") {
|
||||||
|
hasImage = true;
|
||||||
// Check first which size fits best...
|
// Check first which size fits best...
|
||||||
var photo
|
|
||||||
for (var i = 0; i < webPageData.photo.sizes.length; i++) {
|
for (var i = 0; i < webPageData.photo.sizes.length; i++) {
|
||||||
photo = webPageData.photo.sizes[i].photo;
|
pictureFileInformation = webPageData.photo.sizes[i].photo;
|
||||||
if (webPageData.photo.sizes[i].width >= webPagePreviewColumn.width) {
|
if (webPageData.photo.sizes[i].width >= webPagePreviewColumn.width) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (photo) {
|
if (pictureFileInformation.local.is_downloading_completed) {
|
||||||
picture.fileInformation = photo
|
singleImage.source = pictureFileInformation.local.path;
|
||||||
|
} else {
|
||||||
|
tdLibWrapper.downloadFile(pictureFileInformation.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clicked() {
|
Connections {
|
||||||
descriptionText.toggleMaxLineCount()
|
target: tdLibWrapper
|
||||||
|
onFileUpdated: {
|
||||||
|
if (typeof pictureFileInformation !== "undefined" && fileId === pictureFileInformation.id) {
|
||||||
|
if (fileInformation.local.is_downloading_completed) {
|
||||||
|
pictureFileInformation = fileInformation;
|
||||||
|
singleImage.source = fileInformation.local.path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TDLibFile {
|
Label {
|
||||||
id: picture
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
autoLoad: true
|
|
||||||
}
|
|
||||||
|
|
||||||
MultilineEmojiLabel {
|
|
||||||
id: siteNameText
|
id: siteNameText
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
rawText: webPageData.site_name ? webPageData.site_name : ""
|
text: webPageData.site_name ? Emoji.emojify(webPageData.site_name, font.pixelSize) : ""
|
||||||
font.pixelSize: webPagePreviewColumn.fontSize
|
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
|
||||||
font.bold: true
|
font.bold: true
|
||||||
color: Theme.secondaryHighlightColor
|
color: Theme.secondaryHighlightColor
|
||||||
visible: (rawText !== "")
|
truncationMode: TruncationMode.Fade
|
||||||
maxLineCount: 1
|
maximumLineCount: 1
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
visible: (text !== "")
|
||||||
}
|
}
|
||||||
|
|
||||||
MultilineEmojiLabel {
|
Label {
|
||||||
id: titleText
|
id: titleText
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
rawText: webPageData.title ? webPageData.title : ""
|
text: webPageData.title ? Emoji.emojify(webPageData.title, font.pixelSize) : ""
|
||||||
font.pixelSize: webPagePreviewColumn.fontSize
|
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
|
||||||
font.bold: true
|
font.bold: true
|
||||||
visible: (rawText !== "")
|
truncationMode: TruncationMode.Fade
|
||||||
maxLineCount: 2
|
wrapMode: Text.Wrap
|
||||||
|
maximumLineCount: 2
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
visible: (text !== "")
|
||||||
}
|
}
|
||||||
|
|
||||||
MultilineEmojiLabel {
|
Label {
|
||||||
id: descriptionText
|
id: descriptionText
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
rawText: webPageData.description ? Functions.enhanceMessageText(webPageData.description) : ""
|
text: webPageData.description ? Emoji.emojify(Functions.enhanceMessageText(webPageData.description), font.pixelSize) : ""
|
||||||
font.pixelSize: webPagePreviewColumn.fontSize
|
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
|
||||||
visible: (rawText !== "")
|
truncationMode: TruncationMode.Fade
|
||||||
readonly property int defaultMaxLineCount: 3
|
wrapMode: Text.Wrap
|
||||||
maxLineCount: defaultMaxLineCount
|
maximumLineCount: 3
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
visible: (text !== "")
|
||||||
linkColor: Theme.highlightColor
|
linkColor: Theme.highlightColor
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
Functions.handleLink(link);
|
Functions.handleLink(link);
|
||||||
}
|
}
|
||||||
function toggleMaxLineCount() {
|
|
||||||
maxLineCount = maxLineCount > 0 ? 0 : defaultMaxLineCount
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
@ -124,35 +133,38 @@ Column {
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
autoTransform: true
|
autoTransform: true
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
source: picture.isDownloadingCompleted ? picture.path : ""
|
visible: hasImage && status === Image.Ready
|
||||||
visible: opacity > 0
|
|
||||||
opacity: hasImage && status === Image.Ready ? 1 : 0
|
opacity: hasImage && status === Image.Ready ? 1 : 0
|
||||||
layer.enabled: webPagePreviewColumn.highlighted
|
layer.enabled: webPagePreviewColumn.highlighted
|
||||||
layer.effect: PressEffect { source: singleImage }
|
layer.effect: PressEffect { source: singleImage }
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { NumberAnimation {} }
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
pageStack.push(Qt.resolvedUrl("../../pages/ImagePage.qml"), { "photoData" : webPageData.photo, "pictureFileInformation" : picture.fileInformation });
|
pageStack.push(Qt.resolvedUrl("../pages/ImagePage.qml"), { "photoData" : webPageData.photo, "pictureFileInformation" : pictureFileInformation });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundImage {
|
BackgroundImage {
|
||||||
id: backgroundImage
|
|
||||||
visible: hasImage && singleImage.status !== Image.Ready
|
visible: hasImage && singleImage.status !== Image.Ready
|
||||||
layer.enabled: webPagePreviewColumn.highlighted
|
layer.enabled: webPagePreviewColumn.highlighted
|
||||||
layer.effect: PressEffect { source: backgroundImage }
|
layer.effect: PressEffect { source: singleImage }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
id: noPreviewAvailableText
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: qsTr("Preview not supported for this link...")
|
text: qsTr("Preview not supported for this link...")
|
||||||
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeExtraSmall : Theme.fontSizeTiny
|
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeExtraSmall : Theme.fontSizeTiny
|
||||||
font.italic: true
|
font.italic: true
|
||||||
color: Theme.secondaryColor
|
color: Theme.secondaryColor
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
maximumLineCount: 1
|
||||||
|
textFormat: Text.StyledText
|
||||||
visible: !siteNameText.visible && !titleText.visible && !descriptionText.visible && !webPagePreviewImageItem.visible
|
visible: !siteNameText.visible && !titleText.visible && !descriptionText.visible && !webPagePreviewImageItem.visible
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ Column {
|
||||||
property string emptyPlaceholderText
|
property string emptyPlaceholderText
|
||||||
property string text
|
property string text
|
||||||
property bool multiLine
|
property bool multiLine
|
||||||
property bool headerLeftAligned
|
|
||||||
|
|
||||||
property bool isEditing
|
property bool isEditing
|
||||||
property Item editItem: multiLine ? editAreaTextArea : editAreaTextField
|
property Item editItem: multiLine ? editAreaTextArea : editAreaTextField
|
||||||
|
@ -43,7 +41,6 @@ Column {
|
||||||
id: editAreaHeader
|
id: editAreaHeader
|
||||||
height: parent.visible && text !== "" ? Theme.itemSizeExtraSmall : 0
|
height: parent.visible && text !== "" ? Theme.itemSizeExtraSmall : 0
|
||||||
x: 0
|
x: 0
|
||||||
horizontalAlignment: headerLeftAligned ? Text.AlignLeft : Text.AlignRight
|
|
||||||
}
|
}
|
||||||
Row {
|
Row {
|
||||||
id: editAreaTextRow
|
id: editAreaTextRow
|
||||||
|
@ -53,24 +50,20 @@ Column {
|
||||||
id: editAreaTextArea
|
id: editAreaTextArea
|
||||||
visible: editAreaColumn.isEditing && editAreaColumn.multiLine
|
visible: editAreaColumn.isEditing && editAreaColumn.multiLine
|
||||||
width: parent.width - editAreaButton.width
|
width: parent.width - editAreaButton.width
|
||||||
textLeftMargin: 0
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: editAreaTextField
|
id: editAreaTextField
|
||||||
visible: editAreaColumn.isEditing && !editAreaColumn.multiLine
|
visible: editAreaColumn.isEditing && !editAreaColumn.multiLine
|
||||||
width: parent.width - editAreaButton.width
|
width: parent.width - editAreaButton.width
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
textLeftMargin: 0
|
|
||||||
EnterKey.onClicked: {
|
EnterKey.onClicked: {
|
||||||
editAreaColumn.isEditing = false;
|
editAreaColumn.isEditing = false;
|
||||||
editAreaColumn.saveButtonClicked(editAreaColumn.editItem.text);
|
editAreaColumn.saveButtonClicked(editAreaColumn.editItem.text);
|
||||||
}
|
}
|
||||||
EnterKey.iconSource: editAreaButton.icon.source
|
EnterKey.iconSource: editAreaButton.icon.source
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
}
|
}
|
||||||
InformationTextItem {
|
ChatInformationTextItem {
|
||||||
id: editAreaTextItem
|
id: editAreaTextItem
|
||||||
visible: !editAreaColumn.isEditing
|
visible: !editAreaColumn.isEditing
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
|
@ -98,7 +98,7 @@ SilicaFlickable {
|
||||||
if(groupFullInfo.members && groupFullInfo.members.length > 0) {
|
if(groupFullInfo.members && groupFullInfo.members.length > 0) {
|
||||||
for(var memberIndex in groupFullInfo.members) {
|
for(var memberIndex in groupFullInfo.members) {
|
||||||
var memberData = groupFullInfo.members[memberIndex];
|
var memberData = groupFullInfo.members[memberIndex];
|
||||||
var userInfo = tdLibWrapper.getUserInformation(memberData.member_id.user_id) || {user:{}, bot_info:{}};
|
var userInfo = tdLibWrapper.getUserInformation(memberData.user_id) || {user:{}, bot_info:{}};
|
||||||
memberData.user = userInfo;
|
memberData.user = userInfo;
|
||||||
memberData.bot_info = memberData.bot_info || {};
|
memberData.bot_info = memberData.bot_info || {};
|
||||||
membersList.append(memberData);
|
membersList.append(memberData);
|
||||||
|
@ -187,14 +187,6 @@ SilicaFlickable {
|
||||||
chatInformationPage.chatInformation = newInformation
|
chatInformationPage.chatInformation = newInformation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onChatNotificationSettingsUpdated: {
|
|
||||||
if (chatInformationPage.chatInformation.id.toString() === chatId) {
|
|
||||||
// set whole object to trigger change
|
|
||||||
var newInformation = chatInformation;
|
|
||||||
newInformation.notification_settings = chatNotificationSettings;
|
|
||||||
chatInformationPage.chatInformation = newInformation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
@ -240,7 +232,7 @@ SilicaFlickable {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
visible: chatInformationPage.isPrivateChat
|
visible: chatInformationPage.isPrivateChat
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createNewSecretChat(chatInformationPage.chatPartnerGroupId, "openDirectly");
|
tdLibWrapper.createNewSecretChat(chatInformationPage.chatPartnerGroupId);
|
||||||
}
|
}
|
||||||
text: qsTr("New Secret Chat")
|
text: qsTr("New Secret Chat")
|
||||||
}
|
}
|
||||||
|
@ -264,10 +256,6 @@ SilicaFlickable {
|
||||||
}
|
}
|
||||||
return 1 - Math.max(0, Math.min(1, contentFlickable.contentY / maxDimension))
|
return 1 - Math.max(0, Math.min(1, contentFlickable.contentY / maxDimension))
|
||||||
}
|
}
|
||||||
property bool thumbnailVisible: imageContainer.tweenFactor > 0.8
|
|
||||||
property bool thumbnailActive: imageContainer.tweenFactor === 1.0
|
|
||||||
property var thumbnailModel: chatInformationPage.chatPartnerProfilePhotos
|
|
||||||
property int thumbnailRadius: imageContainer.minDimension / 2
|
|
||||||
|
|
||||||
function getEased(min,max,factor) {
|
function getEased(min,max,factor) {
|
||||||
return min + (max-min)*factor
|
return min + (max-min)*factor
|
||||||
|
@ -283,25 +271,23 @@ SilicaFlickable {
|
||||||
replacementStringHint: headerItem.title
|
replacementStringHint: headerItem.title
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: width
|
height: width
|
||||||
radius: imageContainer.thumbnailRadius
|
radius: imageContainer.minDimension / 2
|
||||||
opacity: profilePictureLoader.status !== Loader.Ready || profilePictureLoader.item.opacity < 1 ? 1.0 : 0.0
|
opacity: profilePictureLoader.status !== Loader.Ready || profilePictureLoader.item.opacity < 1 ? 1.0 : 0.0
|
||||||
optimizeImageSize: false
|
optimizeImageSize: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: profilePictureLoader
|
id: profilePictureLoader
|
||||||
active: imageContainer.hasImage
|
active: imageContainer.hasImage
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
anchors.fill: chatPictureThumbnail
|
anchors.fill: chatPictureThumbnail
|
||||||
source: ( chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat)
|
source: ( chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat)
|
||||||
? "../ProfilePictureList.qml"
|
? "ChatInformationProfilePictureList.qml"
|
||||||
: "ChatInformationProfilePicture.qml"
|
: "ChatInformationProfilePicture.qml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leftMargin: imageContainer.getEased((imageContainer.minDimension + Theme.paddingMedium), 0, imageContainer.tweenFactor) + Theme.horizontalPageMargin
|
leftMargin: imageContainer.getEased((imageContainer.minDimension + Theme.paddingMedium), 0, imageContainer.tweenFactor) + Theme.horizontalPageMargin
|
||||||
title: chatInformationPage.chatInformation.title !== "" ? Emoji.emojify(chatInformationPage.chatInformation.title, Theme.fontSizeLarge) : qsTr("Unknown")
|
title: chatInformationPage.chatInformation.title !== "" ? Emoji.emojify(chatInformationPage.chatInformation.title, Theme.fontSizeLarge) : qsTr("Unknown")
|
||||||
description: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.usernames.editable_username)
|
description: (chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? ("@"+(chatInformationPage.privateChatUserInformation.username || chatInformationPage.chatPartnerGroupId)) : ""
|
||||||
? ("@"+chatInformationPage.privateChatUserInformation.usernames.editable_username) : ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SilicaFlickable {
|
SilicaFlickable {
|
||||||
|
@ -364,28 +350,7 @@ SilicaFlickable {
|
||||||
height: imageContainer.hasImage ? imageContainer.maxDimension : 0
|
height: imageContainer.hasImage ? imageContainer.maxDimension : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
ChatInformationEditArea {
|
||||||
id: copyIdText
|
|
||||||
x: Math.max(headerItem.x + imageContainer.x - groupInfoItem.x + (imageContainer.width - width)/2, 0)
|
|
||||||
text: chatInformationPage.chatPartnerGroupId
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: copyIdMouseArea.pressed ? Theme.secondaryHighlightColor : Theme.highlightColor
|
|
||||||
visible: text !== ""
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: copyIdMouseArea
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
margins: -Theme.paddingLarge
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
Clipboard.text = copyIdText.text
|
|
||||||
appNotification.show(qsTr("ID has been copied to the clipboard."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InformationEditArea {
|
|
||||||
visible: canEdit
|
visible: canEdit
|
||||||
canEdit: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.groupInformation.status && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator")
|
canEdit: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.groupInformation.status && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator")
|
||||||
headerText: qsTr("Chat Title", "group title header")
|
headerText: qsTr("Chat Title", "group title header")
|
||||||
|
@ -411,7 +376,7 @@ SilicaFlickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InformationEditArea {
|
ChatInformationEditArea {
|
||||||
canEdit: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.id === chatInformationPage.myUserId) || ((chatInformationPage.isBasicGroup || chatInformationPage.isSuperGroup) && chatInformationPage.groupInformation && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator"))
|
canEdit: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.id === chatInformationPage.myUserId) || ((chatInformationPage.isBasicGroup || chatInformationPage.isSuperGroup) && chatInformationPage.groupInformation && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator"))
|
||||||
emptyPlaceholderText: qsTr("There is no information text available, yet.")
|
emptyPlaceholderText: qsTr("There is no information text available, yet.")
|
||||||
headerText: qsTr("Info", "group or user infotext header")
|
headerText: qsTr("Info", "group or user infotext header")
|
||||||
|
@ -426,7 +391,7 @@ SilicaFlickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InformationTextItem {
|
ChatInformationTextItem {
|
||||||
headerText: qsTr("Phone Number", "user phone number header")
|
headerText: qsTr("Phone Number", "user phone number header")
|
||||||
text: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.phone_number ? "+"+chatInformationPage.privateChatUserInformation.phone_number : "") || ""
|
text: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.phone_number ? "+"+chatInformationPage.privateChatUserInformation.phone_number : "") || ""
|
||||||
isLinkedLabel: true
|
isLinkedLabel: true
|
||||||
|
@ -443,7 +408,7 @@ SilicaFlickable {
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: !!inviteLinkItem.text
|
visible: !!inviteLinkItem.text
|
||||||
InformationTextItem {
|
ChatInformationTextItem {
|
||||||
id: inviteLinkItem
|
id: inviteLinkItem
|
||||||
text: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? chatInformationPage.groupFullInformation.invite_link : ""
|
text: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? chatInformationPage.groupFullInformation.invite_link : ""
|
||||||
width: parent.width - inviteLinkButton.width
|
width: parent.width - inviteLinkButton.width
|
||||||
|
|
|
@ -22,8 +22,8 @@ import Sailfish.Silica 1.0
|
||||||
import "../"
|
import "../"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
visible: parent.thumbnailVisible && chatPictureDetail.imageStatus === Image.Ready
|
visible: imageContainer.tweenFactor > 0.8 && chatPictureDetail.imageStatus === Image.Ready
|
||||||
property bool isActive: parent.thumbnailActive
|
property bool isActive: imageContainer.tweenFactor === 1.0
|
||||||
opacity: isActive ? 1.0 : 0.0
|
opacity: isActive ? 1.0 : 0.0
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { FadeAnimation {} }
|
||||||
ProfileThumbnail {
|
ProfileThumbnail {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
@ -18,25 +18,25 @@
|
||||||
*/
|
*/
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
|
import "../"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: profilePictureListItem
|
visible: imageContainer.tweenFactor > 0.8 && bigProfilePictureList.count > 0
|
||||||
visible: imageContainer.thumbnailVisible && bigProfilePictureList.count > 0
|
property bool isActive: imageContainer.tweenFactor === 1.0
|
||||||
property bool isActive: imageContainer.thumbnailActive
|
|
||||||
readonly property int currentPictureIndex: bigProfilePictureList.currentIndex
|
|
||||||
|
|
||||||
opacity: isActive ? 1.0 : 0.0
|
opacity: isActive ? 1.0 : 0.0
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
|
||||||
SlideshowView {
|
SlideshowView {
|
||||||
id: bigProfilePictureList
|
id: bigProfilePictureList
|
||||||
|
property bool isActive: imageContainer.tweenFactor === 1.0
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
clip: true
|
clip: true
|
||||||
itemWidth: width
|
itemWidth: width
|
||||||
itemHeight: height
|
itemHeight: height
|
||||||
interactive: parent.isActive
|
interactive: parent.isActive
|
||||||
model: imageContainer.thumbnailModel
|
model: chatInformationPage.chatPartnerProfilePhotos
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
width: bigProfilePictureList.itemWidth
|
width: bigProfilePictureList.itemWidth
|
||||||
height: bigProfilePictureList.itemHeight
|
height: bigProfilePictureList.itemHeight
|
||||||
|
@ -44,13 +44,13 @@ Item {
|
||||||
id: chatPictureDetail
|
id: chatPictureDetail
|
||||||
photoData: modelData.sizes[modelData.sizes.length - 1].photo
|
photoData: modelData.sizes[modelData.sizes.length - 1].photo
|
||||||
replacementStringHint: ""
|
replacementStringHint: ""
|
||||||
radius: imageContainer.thumbnailRadius
|
radius: chatPictureThumbnail.radius
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
pageStack.push(Qt.resolvedUrl("../pages/ImagePage.qml"), { "photoData" : modelData });
|
pageStack.push(Qt.resolvedUrl("../../pages/ImagePage.qml"), { "photoData" : modelData });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,18 +58,16 @@ Item {
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
visible: bigProfilePictureList.count > 1
|
visible: bigProfilePictureList.count > 1
|
||||||
width: parent.width - Theme.paddingSmall
|
width: parent.width
|
||||||
anchors {
|
anchors {
|
||||||
bottomMargin: Theme.paddingSmall
|
bottomMargin: Theme.paddingSmall
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
}
|
}
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
property var baseString: new Array(bigProfilePictureList.count+1).join(" ○ ")
|
property var baseString: new Array(bigProfilePictureList.count+1).join(" ○ ")
|
||||||
text: (baseString.substring(0,bigProfilePictureList.currentIndex*3) + " ● " + baseString.substring((bigProfilePictureList.currentIndex+1)*3)).trim()
|
text: baseString.substring(0,bigProfilePictureList.currentIndex*3) + " ● " + baseString.substring((bigProfilePictureList.currentIndex+1)*3)
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: Theme.primaryColor
|
color: Theme.primaryColor
|
||||||
style: Text.Raised
|
style: Text.Raised
|
||||||
styleColor: Theme.highlightDimmerColor
|
styleColor: Theme.highlightDimmerColor
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -38,18 +38,18 @@ ChatInformationTabItemBase {
|
||||||
width: tabBase.width - Theme.horizontalPageMargin * 2
|
width: tabBase.width - Theme.horizontalPageMargin * 2
|
||||||
x: Theme.horizontalPageMargin
|
x: Theme.horizontalPageMargin
|
||||||
|
|
||||||
InformationTextItem {
|
ChatInformationTextItem {
|
||||||
headerText: "chatInformation"
|
headerText: "chatInformation"
|
||||||
text:chatInformationPage.chatInformation ? JSON.stringify(chatInformationPage.chatInformation, null, 2) : ""
|
text:chatInformationPage.chatInformation ? JSON.stringify(chatInformationPage.chatInformation, null, 2) : ""
|
||||||
isLinkedLabel: true
|
isLinkedLabel: true
|
||||||
}
|
}
|
||||||
InformationTextItem {
|
ChatInformationTextItem {
|
||||||
headerText: "groupInformation"
|
headerText: "groupInformation"
|
||||||
text: chatInformationPage.groupInformation ? JSON.stringify(chatInformationPage.groupInformation, null, 2) : ""
|
text: chatInformationPage.groupInformation ? JSON.stringify(chatInformationPage.groupInformation, null, 2) : ""
|
||||||
isLinkedLabel: true
|
isLinkedLabel: true
|
||||||
}
|
}
|
||||||
|
|
||||||
InformationTextItem {
|
ChatInformationTextItem {
|
||||||
headerText: "groupFullInformation"
|
headerText: "groupFullInformation"
|
||||||
text: chatInformationPage.groupFullInformation ? JSON.stringify(chatInformationPage.groupFullInformation, null, 2) : ""
|
text: chatInformationPage.groupFullInformation ? JSON.stringify(chatInformationPage.groupFullInformation, null, 2) : ""
|
||||||
isLinkedLabel: true
|
isLinkedLabel: true
|
||||||
|
|
|
@ -72,14 +72,14 @@ ChatInformationTabItemBase {
|
||||||
}
|
}
|
||||||
delegate: PhotoTextsListItem {
|
delegate: PhotoTextsListItem {
|
||||||
pictureThumbnail {
|
pictureThumbnail {
|
||||||
photoData: user.profile_photo ? user.profile_photo.small : null
|
photoData: (typeof user.profile_photo !== "undefined") ? user.profile_photo.small : ""
|
||||||
}
|
}
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
// chat title
|
// chat title
|
||||||
primaryText.text: Emoji.emojify(Functions.getUserName(user), primaryText.font.pixelSize)
|
primaryText.text: Emoji.emojify(Functions.getUserName(user), primaryText.font.pixelSize)
|
||||||
// last user
|
// last user
|
||||||
prologSecondaryText.text: "@"+(user.username ? user.username : member_id.user_id) + (member_id.user_id === chatInformationPage.myUserId ? " " + qsTr("You") : "")
|
prologSecondaryText.text: "@"+(user.username !== "" ? user.username : user_id) + (user_id === chatInformationPage.myUserId ? " " + qsTr("You") : "")
|
||||||
secondaryText {
|
secondaryText {
|
||||||
horizontalAlignment: Text.AlignRight
|
horizontalAlignment: Text.AlignRight
|
||||||
property string statusText: Functions.getChatMemberStatusText(model.status["@type"])
|
property string statusText: Functions.getChatMemberStatusText(model.status["@type"])
|
||||||
|
@ -92,7 +92,7 @@ ChatInformationTabItemBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createPrivateChat(member_id.user_id, "openDirectly");
|
tdLibWrapper.createPrivateChat(user_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
footer: Component {
|
footer: Component {
|
||||||
|
@ -154,6 +154,15 @@ ChatInformationTabItemBase {
|
||||||
pageStack.pop(pageStack.find( function(page){ return(page._depth === 0)} ), PageStackAction.Immediate);
|
pageStack.pop(pageStack.find( function(page){ return(page._depth === 0)} ), PageStackAction.Immediate);
|
||||||
pageStack.push(Qt.resolvedUrl("../../pages/ChatPage.qml"), { "chatInformation" : display });
|
pageStack.push(Qt.resolvedUrl("../../pages/ChatPage.qml"), { "chatInformation" : display });
|
||||||
}
|
}
|
||||||
|
Connections {
|
||||||
|
target: chatListModel
|
||||||
|
onChatChanged: {
|
||||||
|
if (changedChatId === chat_id) {
|
||||||
|
// Force update of some list item elements (currently only last message text seems to create problems). dataChanged() doesn't seem to trigger them all :(
|
||||||
|
secondaryText.text = last_message_text ? Emoji.emojify(Functions.enhanceHtmlEntities(last_message_text), Theme.fontSizeExtraSmall) : qsTr("Unknown")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +171,7 @@ ChatInformationTabItemBase {
|
||||||
interval: 600
|
interval: 600
|
||||||
property int fetchLimit: 50
|
property int fetchLimit: 50
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if(chatInformationPage.isSuperGroup && (!chatInformationPage.isChannel || chatInformationPage.canGetMembers) && (chatInformationPage.groupInformation.member_count > membersView.count)) {
|
if(chatInformationPage.isSuperGroup && !chatInformationPage.isChannel && (chatInformationPage.groupInformation.member_count > membersView.count)) { //
|
||||||
tabBase.loading = true
|
tabBase.loading = true
|
||||||
tdLibWrapper.getSupergroupMembers(chatInformationPage.chatPartnerGroupId, fetchLimit, pageContent.membersList.count);
|
tdLibWrapper.getSupergroupMembers(chatInformationPage.chatPartnerGroupId, fetchLimit, pageContent.membersList.count);
|
||||||
fetchLimit = 200
|
fetchLimit = 200
|
||||||
|
@ -179,10 +188,7 @@ ChatInformationTabItemBase {
|
||||||
if(members && members.length > 0 && chatInformationPage.groupInformation.member_count > membersView.count) {
|
if(members && members.length > 0 && chatInformationPage.groupInformation.member_count > membersView.count) {
|
||||||
for(var memberIndex in members) {
|
for(var memberIndex in members) {
|
||||||
var memberData = members[memberIndex];
|
var memberData = members[memberIndex];
|
||||||
var userInfo = tdLibWrapper.getUserInformation(memberData.member_id.user_id) || {user:{}, bot_info:{}};
|
var userInfo = tdLibWrapper.getUserInformation(memberData.user_id) || {user:{}, bot_info:{}};
|
||||||
if (!userInfo.username && userInfo.usernames && userInfo.usernames.active_usernames) {
|
|
||||||
userInfo.username = userInfo.usernames.active_usernames[0]
|
|
||||||
}
|
|
||||||
memberData.user = userInfo;
|
memberData.user = userInfo;
|
||||||
memberData.bot_info = memberData.bot_info || {};
|
memberData.bot_info = memberData.bot_info || {};
|
||||||
pageContent.membersList.append(memberData);
|
pageContent.membersList.append(memberData);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
@ -16,12 +16,11 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
import "../js/twemoji.js" as Emoji
|
import "../../js/twemoji.js" as Emoji
|
||||||
import "../js/functions.js" as Functions
|
import "../../js/functions.js" as Functions
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: textItem
|
id: textItem
|
||||||
|
@ -48,7 +47,7 @@ Column {
|
||||||
id: labelComponent
|
id: labelComponent
|
||||||
Label {
|
Label {
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
color: Theme.primaryColor
|
color: Theme.primaryColor
|
||||||
text: Emoji.emojify( Functions.replaceUrlsWithLinks(textItem.text).replace(/\n/g, "<br>"), Theme.fontSizeExtraSmall)
|
text: Emoji.emojify( Functions.replaceUrlsWithLinks(textItem.text).replace(/\n/g, "<br>"), Theme.fontSizeExtraSmall)
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
|
|
||||||
BackgroundItem {
|
|
||||||
id: queryResultItem
|
|
||||||
|
|
||||||
function sendInlineQueryResultMessage() {
|
|
||||||
tdLibWrapper.sendInlineQueryResultMessage(inlineQueryLoader.chatId, 0, 0, inlineQueryComponent.inlineQueryId, model.id);
|
|
||||||
inlineQueryLoader.textField.text = "";
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
sendInlineQueryResultMessage()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,291 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import QtMultimedia 5.6
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
import Nemo.Thumbnailer 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
import "../../js/debug.js" as Debug
|
|
||||||
|
|
||||||
InlineQueryResult {
|
|
||||||
id: queryResultItem
|
|
||||||
property bool isAnimation: true
|
|
||||||
property bool loopPreview: isAnimation
|
|
||||||
property bool mutePreview: isAnimation
|
|
||||||
enabled: false // don't send on click
|
|
||||||
layer.enabled: mouseArea.pressed
|
|
||||||
layer.effect: PressEffect { source: queryResultItem }
|
|
||||||
|
|
||||||
property string animationKey: "animation"
|
|
||||||
property bool hasThumbnail: !!model[queryResultItem.animationKey].thumbnail
|
|
||||||
|
|
||||||
property string videoMimeType: "video/mp4"
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: file
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
autoLoad: true
|
|
||||||
fileInformation: hasThumbnail ? model[queryResultItem.animationKey].thumbnail.file : (queryResultItem.isAnimation ? model[queryResultItem.animationKey].animation : model[queryResultItem.animationKey].video)
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: miniThumbnail
|
|
||||||
asynchronous: true
|
|
||||||
source: model[queryResultItem.animationKey].minithumbnail ? "data:image/jpg;base64,"+model[queryResultItem.animationKey].minithumbnail.data : ""
|
|
||||||
anchors.fill: parent
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
layer.enabled: queryResultItem.pressed
|
|
||||||
layer.effect: PressEffect { source: miniThumbnail }
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: videoThumbnail
|
|
||||||
Thumbnail {
|
|
||||||
id: thumbnail
|
|
||||||
source: file.path
|
|
||||||
sourceSize.width: width
|
|
||||||
sourceSize.height: height
|
|
||||||
mimeType: queryResultItem.videoMimeType
|
|
||||||
layer.enabled: queryResultItem.pressed
|
|
||||||
layer.effect: PressEffect { source: thumbnail }
|
|
||||||
opacity: status === Thumbnail.Ready ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: imageThumbnail
|
|
||||||
Image {
|
|
||||||
id: thumbnail
|
|
||||||
source: file.path
|
|
||||||
sourceSize.width: width
|
|
||||||
sourceSize.height: height
|
|
||||||
layer.enabled: queryResultItem.pressed
|
|
||||||
layer.effect: PressEffect { source: thumbnail }
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
opacity: status === Image.Ready ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
onStatusChanged: {
|
|
||||||
// we don't get many hints what may be wrong, so we guess it may be a webp image ;)
|
|
||||||
if(status === Image.Error) {
|
|
||||||
Debug.log("Inline Query Video: Thumbnail invalid. Blindly trying webp, which might work.")
|
|
||||||
queryResultItem.videoMimeType = "image/webp";
|
|
||||||
thumbnailLoader.sourceComponent = videoThumbnail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loader {
|
|
||||||
id: thumbnailLoader
|
|
||||||
asynchronous: true
|
|
||||||
active: file.isDownloadingCompleted
|
|
||||||
anchors.fill: parent
|
|
||||||
sourceComponent: queryResultItem.hasThumbnail ? (model[queryResultItem.animationKey].thumbnail.format["@type"] === "thumbnailFormatMpeg4" ? videoThumbnail : imageThumbnail) : model[queryResultItem.animationKey].mime_type === "video/mp4" ? videoThumbnail : imageThumbnail
|
|
||||||
}
|
|
||||||
Column {
|
|
||||||
id: texts
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
margins: Theme.paddingSmall
|
|
||||||
right: parent.right
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: titleLabel
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
visible: text.length > 0
|
|
||||||
text: Emoji.emojify(model.title || "", font.pixelSize);
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: descriptionLabel
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
visible: text.length > 0
|
|
||||||
text: Emoji.emojify(model.description || "", font.pixelSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
anchors.fill: texts
|
|
||||||
asynchronous: true
|
|
||||||
active: titleLabel.visible || descriptionLabel.visible
|
|
||||||
sourceComponent: Component {
|
|
||||||
DropShadow {
|
|
||||||
horizontalOffset: 0
|
|
||||||
verticalOffset: 0
|
|
||||||
radius: Theme.paddingSmall
|
|
||||||
spread: 0.5
|
|
||||||
samples: 17
|
|
||||||
color: Theme.overlayBackgroundColor
|
|
||||||
source: texts
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
// dialog
|
|
||||||
|
|
||||||
var dialog = pageStack.push(dialogComponent,{})
|
|
||||||
dialog.accepted.connect(function() {
|
|
||||||
queryResultItem.sendInlineQueryResultMessage();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: dialogComponent
|
|
||||||
Dialog {
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: previewFile
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
autoLoad: model[queryResultItem.animationKey].mime_type !== "text/html"
|
|
||||||
fileInformation: queryResultItem.isAnimation ? model[queryResultItem.animationKey].animation : model[queryResultItem.animationKey].video
|
|
||||||
}
|
|
||||||
|
|
||||||
DialogHeader { id: dialogHeader }
|
|
||||||
|
|
||||||
ProgressCircle {
|
|
||||||
value: previewFile.downloadedSize / previewFile.expectedSize
|
|
||||||
width: Theme.iconSizeMedium
|
|
||||||
height: Theme.iconSizeMedium
|
|
||||||
anchors.centerIn: parent
|
|
||||||
opacity: previewFile.isDownloadingActive ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
}
|
|
||||||
Column {
|
|
||||||
visible: !previewFile.autoLoad
|
|
||||||
spacing: Theme.paddingLarge
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: Theme.horizontalPageMargin
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: Theme.horizontalPageMargin
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
color: Theme.secondaryHighlightColor
|
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
|
||||||
text: Emoji.emojify(model.title || "", font.pixelSize);
|
|
||||||
visible: text.length > 1
|
|
||||||
linkColor: Theme.primaryColor
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
color: Theme.highlightColor
|
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
|
||||||
text: '<a href="'+Emoji.emojify(previewFile.fileInformation.remote.id, font.pixelSize)+'">'+Emoji.emojify(previewFile.fileInformation.remote.id, font.pixelSize)+'</a> '
|
|
||||||
linkColor: Theme.primaryColor
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
color: Theme.secondaryHighlightColor
|
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
|
||||||
text: Emoji.emojify(model.description || "", font.pixelSize)
|
|
||||||
visible: text.length > 1
|
|
||||||
linkColor: Theme.secondaryColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: videoLoader
|
|
||||||
anchors {
|
|
||||||
top: dialogHeader.bottom
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
active: previewFile.isDownloadingCompleted
|
|
||||||
asynchronous: true
|
|
||||||
sourceComponent: Component {
|
|
||||||
Item {
|
|
||||||
Connections {
|
|
||||||
target: resultView
|
|
||||||
onRequestPlayback: {
|
|
||||||
if(previewVideo.playbackState === MediaPlayer.PlayingState && previewVideo.source !== playbackSource) {
|
|
||||||
previewVideo.pause()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Timer {
|
|
||||||
id: loopTimer
|
|
||||||
interval: 0
|
|
||||||
onTriggered: previewVideo.play()
|
|
||||||
}
|
|
||||||
|
|
||||||
Video {
|
|
||||||
id: previewVideo
|
|
||||||
source: previewFile.path
|
|
||||||
autoPlay: true
|
|
||||||
muted: queryResultItem.mutePreview
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
onStatusChanged: {
|
|
||||||
if (status == MediaPlayer.EndOfMedia) {
|
|
||||||
if(queryResultItem.loopPreview) {
|
|
||||||
loopTimer.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onPlaybackStateChanged: {
|
|
||||||
if(playbackState === MediaPlayer.PlayingState) {
|
|
||||||
resultView.requestPlayback(source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
layer.enabled: playPauseMouseArea.pressed
|
|
||||||
layer.effect: PressEffect { source: previewVideo }
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
id: playPauseMouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
if(previewVideo.playbackState === MediaPlayer.PlayingState) {
|
|
||||||
previewVideo.pause();
|
|
||||||
} else {
|
|
||||||
previewVideo.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
InlineQueryResultDefaultBase {
|
|
||||||
id: queryResultItem
|
|
||||||
|
|
||||||
title: Emoji.emojify(model.title || "", titleLable.font.pixelSize)
|
|
||||||
description: Emoji.emojify(model.description || "", descriptionLabel.font.pixelSize)
|
|
||||||
descriptionLabel {
|
|
||||||
maximumLineCount: 3
|
|
||||||
wrapMode: extraText.length === 0 ? Text.Wrap : Text.NoWrap
|
|
||||||
}
|
|
||||||
|
|
||||||
extraText: model.url || ""
|
|
||||||
extraTextLabel.visible: !model.hide_url && extraText.length > 0
|
|
||||||
|
|
||||||
thumbnailFileInformation: model.thumbnail ? model.thumbnail.file : {}
|
|
||||||
|
|
||||||
icon.source: "image://theme/icon-m-link"
|
|
||||||
icon.visible: thumbnail.visible && thumbnail.opacity === 0
|
|
||||||
|
|
||||||
thumbnail.visible: model.thumbnail || !!model.url
|
|
||||||
}
|
|
|
@ -1,183 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import QtMultimedia 5.6
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
InlineQueryResult {
|
|
||||||
id: queryResultItem
|
|
||||||
property var resultData: model.audio || model.voice_note
|
|
||||||
property var audioData: resultData.audio || resultData.voice
|
|
||||||
|
|
||||||
enabled: false // don't send on click
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: resultView
|
|
||||||
onRequestPlayback: {
|
|
||||||
if(audioPlayer.playbackState === Audio.PlayingState && audioPlayer.source !== playbackSource) {
|
|
||||||
audioPlayer.pause()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: file
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
autoLoad: false
|
|
||||||
fileInformation: queryResultItem.audioData
|
|
||||||
}
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: thumbnail
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
autoLoad: true
|
|
||||||
fileInformation: queryResultItem.resultData.album_cover_thumbnail ? queryResultItem.resultData.album_cover_thumbnail.file : {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: thumbnailLoader
|
|
||||||
asynchronous: true
|
|
||||||
active: thumbnail.isDownloadingCompleted
|
|
||||||
height: parent.height
|
|
||||||
width: height
|
|
||||||
opacity: item && item.status === Image.Ready ? 0.5 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
sourceComponent: Component {
|
|
||||||
Image {
|
|
||||||
id: thumbnailImage
|
|
||||||
source: thumbnail.path
|
|
||||||
sourceSize.width: width
|
|
||||||
sourceSize.height: height
|
|
||||||
|
|
||||||
layer.enabled: playPauseButton.pressed
|
|
||||||
layer.effect: PressEffect { source: thumbnailImage }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
id: playPauseButton
|
|
||||||
anchors.centerIn: thumbnailLoader
|
|
||||||
icon {
|
|
||||||
asynchronous: true
|
|
||||||
source: audioPlayer.playbackState === Audio.PlayingState || (file.isDownloadingActive && audioPlayer.autoPlay) ? "image://theme/icon-m-pause": "image://theme/icon-m-play"
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
if(!file.isDownloadingCompleted && !file.isDownloadingActive) {
|
|
||||||
file.load();
|
|
||||||
audioPlayer.autoPlay = true
|
|
||||||
} else if(file.isDownloadingActive) {
|
|
||||||
// cancel playback intent?
|
|
||||||
audioPlayer.autoPlay = false
|
|
||||||
} else if(file.isDownloadingCompleted) {
|
|
||||||
//playPause
|
|
||||||
if(audioPlayer.playbackState === Audio.PlayingState) {
|
|
||||||
audioPlayer.pause();
|
|
||||||
} else {
|
|
||||||
audioPlayer.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ProgressCircle {
|
|
||||||
value: file.downloadedSize / file.expectedSize
|
|
||||||
width: Theme.iconSizeMedium
|
|
||||||
height: Theme.iconSizeMedium
|
|
||||||
anchors.centerIn: playPauseButton
|
|
||||||
opacity: file.isDownloadingActive ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio {
|
|
||||||
id: audioPlayer
|
|
||||||
source: file.isDownloadingCompleted ? file.path : ""
|
|
||||||
autoPlay: false
|
|
||||||
onPlaybackStateChanged: {
|
|
||||||
if(playbackState === Audio.PlayingState) {
|
|
||||||
resultView.requestPlayback(source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors {
|
|
||||||
left: thumbnailLoader.right
|
|
||||||
leftMargin: Theme.paddingSmall
|
|
||||||
right: sendButton.left
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.highlightColor
|
|
||||||
text: Emoji.emojify(queryResultItem.resultData.performer || "", font.pixelSize)
|
|
||||||
visible: text.length > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: Theme.secondaryHighlightColor
|
|
||||||
text: Emoji.emojify(queryResultItem.resultData.title || model.title || "", font.pixelSize)
|
|
||||||
visible: text.length > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
height: sizeLabel.height
|
|
||||||
width: parent.width
|
|
||||||
Label {
|
|
||||||
id: durationLabel
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: Theme.secondaryColor
|
|
||||||
text: (audioPlayer.position > 0 || audioPlayer.playbackState === Audio.PlayingState ? (Format.formatDuration(audioPlayer.position/1000, Formatter.DurationShort)+" / ") : "") + Format.formatDuration(queryResultItem.audioData.duration || (audioPlayer.duration/1000), Formatter.DurationShort)
|
|
||||||
visible: (queryResultItem.audioData.duration || (audioPlayer.duration/1000)) > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: sizeLabel
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: Theme.secondaryColor
|
|
||||||
text: Format.formatFileSize(file.expectedSize)
|
|
||||||
visible: file.expectedSize > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
id: sendButton
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: Theme.horizontalPageMargin
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
icon {
|
|
||||||
asynchronous: true
|
|
||||||
source: "image://theme/icon-m-send"
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
queryResultItem.sendInlineQueryResultMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
InlineQueryResultDefaultBase {
|
|
||||||
id: queryResultItem
|
|
||||||
property string namesSeparator: model.contact.first_name && model.contact.last_name ? " " : ""
|
|
||||||
|
|
||||||
title: Emoji.emojify(model.contact.first_name + namesSeparator + model.contact.last_name || "", titleLable.font.pixelSize)
|
|
||||||
description: Emoji.emojify(model.contact.phone_number || "", descriptionLabel.font.pixelSize)
|
|
||||||
|
|
||||||
extraText: model.url || ""
|
|
||||||
extraTextLabel.visible: !model.hide_url && extraText.length > 0
|
|
||||||
|
|
||||||
thumbnailFileInformation: model.thumbnail ? model.thumbnail.file : {}
|
|
||||||
|
|
||||||
icon.source: "image://theme/icon-m-contact"
|
|
||||||
icon.visible: thumbnail.visible && thumbnail.opacity === 0
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../"
|
|
||||||
|
|
||||||
InlineQueryResult {
|
|
||||||
id: queryResultItem
|
|
||||||
|
|
||||||
property alias title: titleLabel.text
|
|
||||||
property alias titleLable: titleLabel
|
|
||||||
|
|
||||||
property alias description: descriptionLabel.text
|
|
||||||
property alias descriptionLabel: descriptionLabel
|
|
||||||
|
|
||||||
property alias extraText: extraTextLabel.text
|
|
||||||
property alias extraTextLabel: extraTextLabel
|
|
||||||
|
|
||||||
property alias thumbnailFileInformation: thumbnailFile.fileInformation
|
|
||||||
property alias thumbnail: thumbnail
|
|
||||||
|
|
||||||
property alias icon: icon
|
|
||||||
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: thumbnail
|
|
||||||
source: thumbnailFile.isDownloadingCompleted ? thumbnailFile.path : ""
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
asynchronous: true
|
|
||||||
width: visible ? Theme.itemSizeLarge : 0
|
|
||||||
height: width
|
|
||||||
opacity: status === Image.Ready ? 1.0 : 0.0
|
|
||||||
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
layer.enabled: queryResultItem.pressed
|
|
||||||
layer.effect: PressEffect { source: thumbnail }
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: thumbnailFile
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
autoLoad: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Icon {
|
|
||||||
id: icon
|
|
||||||
asynchronous: true
|
|
||||||
anchors.centerIn: thumbnail
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors {
|
|
||||||
left: thumbnail.right
|
|
||||||
leftMargin: thumbnail.visible ? Theme.paddingLarge : Theme.horizontalPageMargin
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: Theme.horizontalPageMargin
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: titleLabel
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: highlighted || !queryResultItem.enabled ? Theme.highlightColor : Theme.primaryColor
|
|
||||||
visible: text.length > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: descriptionLabel
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: highlighted || !queryResultItem.enabled ? Theme.secondaryColor : Theme.secondaryHighlightColor
|
|
||||||
visible: text.length > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: extraTextLabel
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: highlighted || !queryResultItem.enabled ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
|
||||||
visible: text.length > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
Component {
|
|
||||||
id: documentComponent
|
|
||||||
InlineQueryResultDefaultBase {
|
|
||||||
id: queryResultItem
|
|
||||||
|
|
||||||
title: Emoji.emojify(model.title || model.document.file_name || "", titleLable.font.pixelSize)
|
|
||||||
description: Emoji.emojify(model.description || model.document.file_name || "", descriptionLabel.font.pixelSize)
|
|
||||||
extraText: Format.formatFileSize(model.document.document.expected_size)
|
|
||||||
|
|
||||||
thumbnailFileInformation: model.thumbnail ? model.thumbnail.file : {}
|
|
||||||
|
|
||||||
icon.source: Theme.iconForMimeType(model.document.mime_type)
|
|
||||||
icon.visible: thumbnail.visible && thumbnail.opacity === 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: voiceNoteDocumentComponent
|
|
||||||
InlineQueryResultVoiceNote {
|
|
||||||
resultData: model.document
|
|
||||||
audioData: model.document.document
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sourceComponent: model.document.mime_type === "audio/ogg" ? voiceNoteDocumentComponent : documentComponent
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
InlineQueryResultDefaultBase {
|
|
||||||
id: queryResultItem
|
|
||||||
|
|
||||||
title: Emoji.emojify(model.game.title || "", titleLable.font.pixelSize)
|
|
||||||
description: Emoji.emojify(model.game.description || "", descriptionLabel.font.pixelSize)
|
|
||||||
descriptionLabel {
|
|
||||||
maximumLineCount: 3
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
}
|
|
||||||
|
|
||||||
icon.source: "image://theme/icon-m-game-controller"
|
|
||||||
icon.visible: thumbnail.opacity === 0
|
|
||||||
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (model.game.photo) {
|
|
||||||
// Check first which size fits best...
|
|
||||||
var photo
|
|
||||||
for (var i = 0; i < model.game.photo.sizes.length; i++) {
|
|
||||||
photo = model.game.photo.sizes[i].photo
|
|
||||||
if (model.game.photo.sizes[i].width >= queryResultItem.width) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (photo) {
|
|
||||||
thumbnailFileInformation = photo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
|
|
||||||
InlineQueryResultVenue {
|
|
||||||
resultData: model
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import "../"
|
|
||||||
|
|
||||||
InlineQueryResult {
|
|
||||||
id: queryResultItem
|
|
||||||
|
|
||||||
TDLibPhoto {
|
|
||||||
anchors.fill: parent
|
|
||||||
photo: model.photo
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import Nemo.Thumbnailer 1.0
|
|
||||||
import "../"
|
|
||||||
|
|
||||||
InlineQueryResult {
|
|
||||||
id: queryResultItem
|
|
||||||
|
|
||||||
property bool animate
|
|
||||||
property bool animating: animate && model.sticker.is_animated
|
|
||||||
property url stickerId: "http://sticker/" + model.sticker.sticker.remote.id
|
|
||||||
onAnimatingChanged: {
|
|
||||||
if(animating) {
|
|
||||||
resultView.requestPlayback(stickerId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: resultView
|
|
||||||
onRequestPlayback: {
|
|
||||||
if(queryResultItem.animating && queryResultItem.stickerId !== playbackSource) {
|
|
||||||
animate = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onPressAndHold: {
|
|
||||||
animate = !animate
|
|
||||||
}
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: file
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
fileInformation: model.sticker.sticker
|
|
||||||
autoLoad: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: animatedStickerLoader
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
margins: Theme.paddingLarge
|
|
||||||
}
|
|
||||||
active: queryResultItem.animating
|
|
||||||
sourceComponent: Component {
|
|
||||||
AnimatedImage {
|
|
||||||
id: animatedSticker
|
|
||||||
anchors.fill: parent
|
|
||||||
source: file.path
|
|
||||||
asynchronous: true
|
|
||||||
paused: !Qt.application.active
|
|
||||||
cache: false
|
|
||||||
layer.enabled: highlighted
|
|
||||||
layer.effect: PressEffect { source: animatedSticker }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: staticSticker
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
margins: Theme.paddingLarge
|
|
||||||
}
|
|
||||||
source: file.path
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
autoTransform: true
|
|
||||||
asynchronous: true
|
|
||||||
visible: !queryResultItem.animating && opacity > 0
|
|
||||||
opacity: status === Image.Ready ? 1 : 0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
layer.enabled: queryResultItem.highlighted
|
|
||||||
layer.effect: PressEffect { source: staticSticker }
|
|
||||||
}
|
|
||||||
|
|
||||||
Icon {
|
|
||||||
source: "image://theme/icon-m-video"
|
|
||||||
width: Theme.iconSizeExtraSmall
|
|
||||||
height: width
|
|
||||||
visible: model.sticker.is_animated
|
|
||||||
highlighted: queryResultItem.highlighted || queryResultItem.animating
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
InlineQueryResultDefaultBase {
|
|
||||||
id: queryResultItem
|
|
||||||
property string locationId
|
|
||||||
property var resultData: model.venue
|
|
||||||
|
|
||||||
title: Emoji.emojify(queryResultItem.resultData.title || (queryResultItem.resultData.location.latitude + ":" + queryResultItem.resultData.location.longitude), titleLable.font.pixelSize)
|
|
||||||
description: Emoji.emojify(queryResultItem.resultData.address || "", descriptionLabel.font.pixelSize)
|
|
||||||
extraText: Emoji.emojify(queryResultItem.resultData.type || "", extraTextLabel.font.pixelSize)
|
|
||||||
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onFileUpdated: {
|
|
||||||
if(fileInformation["@extra"] === queryResultItem.locationId) {
|
|
||||||
thumbnailFileInformation = fileInformation
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
var dimensions = [ Math.round(thumbnail.width), Math.round(thumbnail.height)];
|
|
||||||
|
|
||||||
locationId = "location:" + resultData.location.latitude + ":" + resultData.location.longitude + ":" + dimensions[0] + ":" + dimensions[1];
|
|
||||||
|
|
||||||
tdLibWrapper.getMapThumbnailFile(chatId, resultData.location.latitude, resultData.location.longitude, dimensions[0], dimensions[1], locationId);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
|
|
||||||
InlineQueryResultAnimation {
|
|
||||||
isAnimation: false
|
|
||||||
animationKey: "video"
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
|
|
||||||
InlineQueryResultAudio {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
MessageSticker {
|
|
||||||
stickerData: messageListItem ? messageListItem.myMessage.content.animated_emoji.sticker : overlayFlickable.overlayMessage.content.animated_emoji.sticker;
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
|
|
||||||
MessageVideo {}
|
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import QtMultimedia 5.6
|
|
||||||
import "../"
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
import "../../js/functions.js" as Functions
|
|
||||||
import "../../js/debug.js" as Debug
|
|
||||||
|
|
||||||
|
|
||||||
MessageContentFileInfoBase {
|
|
||||||
id: contentItem
|
|
||||||
|
|
||||||
fileInformation: rawMessage.content.audio.audio
|
|
||||||
thumbnail: rawMessage.content.audio.album_cover_thumbnail
|
|
||||||
minithumbnail: rawMessage.content.audio.album_cover_minithumbnail
|
|
||||||
|
|
||||||
primaryText: Emoji.emojify(rawMessage.content.audio.performer, primaryLabel.font.pixelSize)
|
|
||||||
secondaryText: Emoji.emojify(rawMessage.content.audio.title, secondaryLabel.font.pixelSize)
|
|
||||||
tertiaryLabel.visible: (duration || (audioPlayer.duration/1000)) > 0
|
|
||||||
tertiaryText: (audioPlayer.position > 0 || audioPlayer.playbackState === Audio.PlayingState ? (Format.formatDuration(audioPlayer.position/1000, Formatter.DurationShort)+" / ") : "") + Format.formatDuration(contentItem.duration > 0 ? contentItem.duration : (audioPlayer.duration/1000), Formatter.DurationShort)
|
|
||||||
|
|
||||||
leftButton {
|
|
||||||
icon.source: audioPlayer.playbackState === Audio.PlayingState || (file.isDownloadingActive && audioPlayer.autoPlay) ? "image://theme/icon-m-pause": "image://theme/icon-m-play"
|
|
||||||
onClicked: {
|
|
||||||
if(!file.isDownloadingCompleted && !file.isDownloadingActive) {
|
|
||||||
file.load();
|
|
||||||
audioPlayer.autoPlay = true;
|
|
||||||
} else if(file.isDownloadingActive) {
|
|
||||||
audioPlayer.autoPlay = false;
|
|
||||||
file.cancel();
|
|
||||||
} else if(file.isDownloadingCompleted) {
|
|
||||||
//playPause
|
|
||||||
if(audioPlayer.playbackState === Audio.PlayingState) {
|
|
||||||
audioPlayer.pause();
|
|
||||||
} else {
|
|
||||||
audioPlayer.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
property int duration: rawMessage.content.audio.duration
|
|
||||||
|
|
||||||
Audio {
|
|
||||||
id: audioPlayer
|
|
||||||
source: file.isDownloadingCompleted ? file.path : ""
|
|
||||||
autoPlay: false
|
|
||||||
}
|
|
||||||
|
|
||||||
Slider {
|
|
||||||
width: parent.width
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: -Screen.width/16
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: -Screen.width/16
|
|
||||||
top: primaryItem.bottom
|
|
||||||
topMargin: -height/3
|
|
||||||
}
|
|
||||||
minimumValue: 0
|
|
||||||
maximumValue: audioPlayer.duration ? audioPlayer.duration : 0.1
|
|
||||||
stepSize: 1
|
|
||||||
value: audioPlayer.position
|
|
||||||
enabled: audioPlayer.seekable
|
|
||||||
visible: file.isDownloadingCompleted && audioPlayer.playbackState === Audio.PlayingState || audioPlayer.playbackState === Audio.PausedState
|
|
||||||
opacity: visible ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
height: visible ? implicitHeight : 0
|
|
||||||
Behavior on height { NumberAnimation { duration: 200 } }
|
|
||||||
|
|
||||||
highlighted: contentItem.highlighted || down
|
|
||||||
onReleased: {
|
|
||||||
audioPlayer.seek(Math.floor(value));
|
|
||||||
audioPlayer.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import QtMultimedia 5.6
|
|
||||||
import "../"
|
|
||||||
import "../../js/functions.js" as Functions
|
|
||||||
import "../../js/debug.js" as Debug
|
|
||||||
|
|
||||||
Item {
|
|
||||||
property ListItem messageListItem
|
|
||||||
property MessageOverlayFlickable overlayFlickable
|
|
||||||
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
|
||||||
property bool highlighted
|
|
||||||
signal clicked()
|
|
||||||
}
|
|
|
@ -1,201 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import QtMultimedia 5.6
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../js/functions.js" as Functions
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
import "../../js/debug.js" as Debug
|
|
||||||
|
|
||||||
MessageContentBase {
|
|
||||||
id: contentItem
|
|
||||||
height: childrenRect.height
|
|
||||||
property alias fileInformation: file.fileInformation
|
|
||||||
property alias primaryLabel: primaryLabel
|
|
||||||
property alias primaryText: primaryLabel.text
|
|
||||||
property alias secondaryLabel: secondaryLabel
|
|
||||||
property alias secondaryText: secondaryLabel.text
|
|
||||||
property alias tertiaryLabel: tertiaryLabel
|
|
||||||
property alias tertiaryText: tertiaryLabel.text
|
|
||||||
property var thumbnail
|
|
||||||
property var minithumbnail
|
|
||||||
|
|
||||||
readonly property alias file: file
|
|
||||||
readonly property alias primaryItem: primaryItem
|
|
||||||
readonly property alias leftButton: leftButton
|
|
||||||
readonly property alias labelsColumn: labelsColumn
|
|
||||||
readonly property alias copyButton: copyButton
|
|
||||||
// readonly property alias downloadNeededIndicatorIcon: downloadNeededIndicatorIcon
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: file
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
autoLoad: false
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: primaryItem
|
|
||||||
width: parent.width
|
|
||||||
height: Theme.itemSizeLarge
|
|
||||||
Loader {
|
|
||||||
active: contentItem.thumbnail || contentItem.minithumbnail
|
|
||||||
visible: active
|
|
||||||
anchors.fill: leftButton
|
|
||||||
sourceComponent: Component {
|
|
||||||
TDLibThumbnail {
|
|
||||||
opacity: 0.3
|
|
||||||
thumbnail: contentItem.thumbnail
|
|
||||||
minithumbnail: contentItem.minithumbnail
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
id: leftButton
|
|
||||||
highlighted: down || contentItem.highlighted
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
icon {
|
|
||||||
asynchronous: true
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgressCircle {
|
|
||||||
value: file.downloadedSize / file.expectedSize
|
|
||||||
progressColor: Theme.highlightColor
|
|
||||||
backgroundColor: Theme.highlightDimmerColor
|
|
||||||
width: Theme.iconSizeMedium
|
|
||||||
height: Theme.iconSizeMedium
|
|
||||||
visible: opacity > 0
|
|
||||||
opacity: file.isDownloadingActive ? 1.0 : 0.0
|
|
||||||
anchors.centerIn: parent
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.centerIn: downloadNeededIndicatorIcon
|
|
||||||
width: downloadNeededIndicatorIcon.width + Theme.paddingMedium
|
|
||||||
height: width
|
|
||||||
|
|
||||||
color: Theme.rgba(Theme.overlayBackgroundColor, 0.2)
|
|
||||||
opacity: file.isDownloadingActive ? 1.0 : 0.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
visible: opacity > 0
|
|
||||||
radius: width/2
|
|
||||||
}
|
|
||||||
|
|
||||||
Icon {
|
|
||||||
id: downloadNeededIndicatorIcon
|
|
||||||
source: file.isDownloadingActive || file.isDownloadingCompleted ? "image://theme/icon-s-clear-opaque-cross" : "image://theme/icon-s-cloud-download"
|
|
||||||
asynchronous: true
|
|
||||||
width: Theme.iconSizeExtraSmall
|
|
||||||
height: width
|
|
||||||
visible: opacity > 0
|
|
||||||
sourceSize.width: width
|
|
||||||
sourceSize.height: height
|
|
||||||
opacity: file.isDownloadingCompleted ? 0.0 : 1.0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
bottom: parent.bottom
|
|
||||||
margins: Theme.paddingSmall
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: labelsColumn
|
|
||||||
anchors {
|
|
||||||
left: leftButton.right
|
|
||||||
leftMargin: Theme.paddingSmall
|
|
||||||
right: copyButton.left
|
|
||||||
verticalCenter: leftButton.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: primaryLabel
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
fontSizeMode: Text.HorizontalFit
|
|
||||||
minimumPixelSize: Theme.fontSizeTiny
|
|
||||||
color: Theme.highlightColor
|
|
||||||
visible: text.length > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: secondaryLabel
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
fontSizeMode: Text.HorizontalFit
|
|
||||||
minimumPixelSize: Theme.fontSizeTiny
|
|
||||||
color: Theme.secondaryHighlightColor
|
|
||||||
visible: text.length > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
height: sizeLabel.height
|
|
||||||
width: parent.width
|
|
||||||
Label {
|
|
||||||
id: tertiaryLabel
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
|
||||||
visible: text.length > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: sizeLabel
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
|
||||||
color: tertiaryLabel.color
|
|
||||||
text: Format.formatFileSize(file.size || file.expectedSize)
|
|
||||||
visible: (file.size || file.expectedSize) > 0
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IconButton {
|
|
||||||
id: copyButton
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
opacity: file.isDownloadingCompleted ? 1.0 : 0.0
|
|
||||||
width: file.isDownloadingCompleted ? Theme.itemSizeMedium : 0
|
|
||||||
visible: opacity > 0
|
|
||||||
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
Behavior on width { NumberAnimation { duration: 200 } }
|
|
||||||
icon {
|
|
||||||
asynchronous: true
|
|
||||||
source: "../../../images/icon-m-copy-to-folder.svg"
|
|
||||||
sourceSize {
|
|
||||||
width: Theme.iconSizeMedium
|
|
||||||
height: Theme.iconSizeMedium
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.copyFileToDownloads(file.path);
|
|
||||||
// not persistent:
|
|
||||||
opacity = 0;
|
|
||||||
width = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
MessageContentFileInfoBase {
|
|
||||||
id: contentItem
|
|
||||||
fileInformation: rawMessage.content.document.document
|
|
||||||
|
|
||||||
primaryText: Emoji.emojify(rawMessage.content.document.file_name || "", primaryLabel.font.pixelSize)
|
|
||||||
secondaryText: Emoji.emojify(Functions.enhanceMessageText(rawMessage.content.caption) || "", secondaryLabel.font.pixelSize)
|
|
||||||
|
|
||||||
minithumbnail: rawMessage.content.document.minithumbnail
|
|
||||||
thumbnail: rawMessage.content.document.thumbnail
|
|
||||||
|
|
||||||
leftButton {
|
|
||||||
icon.source: Theme.iconForMimeType(rawMessage.content.document.mime_type)
|
|
||||||
onClicked: {
|
|
||||||
if(file.isDownloadingCompleted) {
|
|
||||||
// in this case, the MouseArea should take over
|
|
||||||
tdLibWrapper.copyFileToDownloads(file.path, true);
|
|
||||||
} else if(!file.isDownloadingActive) {
|
|
||||||
file.load();
|
|
||||||
} else {
|
|
||||||
file.cancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
when: file.isDownloadingCompleted
|
|
||||||
PropertyChanges { target: openMouseArea; enabled: true }
|
|
||||||
PropertyChanges {
|
|
||||||
target: primaryLabel
|
|
||||||
color: (contentItem.highlighted || openMouseArea.pressed) ? Theme.highlightColor : Theme.primaryColor
|
|
||||||
}
|
|
||||||
PropertyChanges {
|
|
||||||
target: secondaryLabel
|
|
||||||
color: (contentItem.highlighted || openMouseArea.pressed) ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
|
||||||
}
|
|
||||||
PropertyChanges {
|
|
||||||
target: tertiaryLabel
|
|
||||||
color: (contentItem.highlighted || openMouseArea.pressed) ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
|
||||||
}
|
|
||||||
PropertyChanges {
|
|
||||||
target: leftButton
|
|
||||||
highlighted: contentItem.highlighted || openMouseArea.pressed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
]
|
|
||||||
MouseArea {
|
|
||||||
id: openMouseArea
|
|
||||||
enabled: file.isDownloadingCompleted
|
|
||||||
visible: enabled
|
|
||||||
anchors {
|
|
||||||
fill: primaryItem
|
|
||||||
rightMargin: copyButton.width
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.copyFileToDownloads(file.path, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../js/functions.js" as Functions
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
|
|
||||||
|
|
||||||
MessageContentBase {
|
|
||||||
id: messageContent
|
|
||||||
height: gamePreviewItem.height
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: gamePreviewItem
|
|
||||||
width: parent.width
|
|
||||||
height: childrenRect.height
|
|
||||||
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
text: Emoji.emojify(rawMessage.content.game.title || "", font.pixelSize)
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
textFormat: Text.StyledText
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
text: Emoji.emojify(rawMessage.content.game.description || "", font.pixelSize)
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
textFormat: Text.StyledText
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
text: Emoji.emojify(Functions.enhanceMessageText(rawMessage.content.game.text) || "", font.pixelSize)
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
textFormat: Text.StyledText
|
|
||||||
onLinkActivated: {
|
|
||||||
var chatCommand = Functions.handleLink(link);
|
|
||||||
if(chatCommand) {
|
|
||||||
tdLibWrapper.sendTextMessage(chatInformation.id, chatCommand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
width: parent.width
|
|
||||||
height: Theme.paddingLarge
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: thumbnail
|
|
||||||
source: thumbnailFile.isDownloadingCompleted ? thumbnailFile.path : ""
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
asynchronous: true
|
|
||||||
visible: opacity > 0
|
|
||||||
opacity: status === Image.Ready ? 1.0 : 0.0
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
layer.enabled: messageContent.highlighted
|
|
||||||
layer.effect: PressEffect { source: thumbnail }
|
|
||||||
|
|
||||||
TDLibFile {
|
|
||||||
id: thumbnailFile
|
|
||||||
tdlib: tdLibWrapper
|
|
||||||
autoLoad: true
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
width: Theme.iconSizeMedium
|
|
||||||
height: width
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
topMargin: Theme.paddingSmall
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: Theme.paddingSmall
|
|
||||||
}
|
|
||||||
|
|
||||||
color: Theme.rgba(Theme.overlayBackgroundColor, 0.2)
|
|
||||||
radius: Theme.paddingSmall
|
|
||||||
Icon {
|
|
||||||
id: icon
|
|
||||||
source: "image://theme/icon-m-game-controller"
|
|
||||||
asynchronous: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (rawMessage.content.game.photo) {
|
|
||||||
// Check first which size fits best...
|
|
||||||
var photo
|
|
||||||
for (var i = 0; i < rawMessage.content.game.photo.sizes.length; i++) {
|
|
||||||
photo = rawMessage.content.game.photo.sizes[i].photo
|
|
||||||
if (rawMessage.content.game.photo.sizes[i].width >= gamePreviewItem.width) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (photo) {
|
|
||||||
thumbnailFile.fileInformation = photo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "../"
|
|
||||||
|
|
||||||
MessageContentBase {
|
|
||||||
id: contentItem
|
|
||||||
height: width * 0.66666666;
|
|
||||||
|
|
||||||
property var locationData : rawMessage.content.location
|
|
||||||
property string fileExtra;
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
Qt.openUrlExternally("geo:" + locationData.latitude + "," + locationData.longitude);
|
|
||||||
}
|
|
||||||
onLocationDataChanged: updatePicture()
|
|
||||||
onWidthChanged: updatePicture()
|
|
||||||
|
|
||||||
function updatePicture() {
|
|
||||||
if (locationData) {
|
|
||||||
fileExtra = "location:" + locationData.latitude + ":" + locationData.longitude + ":" + Math.round(contentItem.width) + ":" + Math.round(contentItem.height);
|
|
||||||
tdLibWrapper.getMapThumbnailFile(rawMessage.chat_id, locationData.latitude, locationData.longitude, Math.round(contentItem.width), Math.round(contentItem.height), fileExtra);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onFileUpdated: {
|
|
||||||
if(fileInformation["@extra"] === contentItem.fileExtra) {
|
|
||||||
if(fileInformation.id !== image.file.fileId) {
|
|
||||||
image.fileInformation = fileInformation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AppNotification {
|
|
||||||
id: imageNotification
|
|
||||||
}
|
|
||||||
TDLibImage {
|
|
||||||
id: image
|
|
||||||
anchors.fill: parent
|
|
||||||
cache: false
|
|
||||||
highlighted: contentItem.highlighted
|
|
||||||
Item {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: markerImage.width
|
|
||||||
height: markerImage.height * 1.75 // 0.875 (vertical pin point) * 2
|
|
||||||
Icon {
|
|
||||||
id: markerImage
|
|
||||||
source: 'image://theme/icon-m-location'
|
|
||||||
}
|
|
||||||
|
|
||||||
DropShadow {
|
|
||||||
anchors.fill: markerImage
|
|
||||||
horizontalOffset: 3
|
|
||||||
verticalOffset: 3
|
|
||||||
radius: 8.0
|
|
||||||
samples: 17
|
|
||||||
color: Theme.colorScheme ? Theme.lightPrimaryColor : Theme.darkPrimaryColor
|
|
||||||
source: markerImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BackgroundImage {
|
|
||||||
visible: image.status !== Image.Ready
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
updatePicture();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "../"
|
|
||||||
|
|
||||||
MessageContentBase {
|
|
||||||
|
|
||||||
function calculateBiggest() {
|
|
||||||
var candidateBiggest = rawMessage.content.photo.sizes[rawMessage.content.photo.sizes.length - 1];
|
|
||||||
if (candidateBiggest.width === 0 && rawMessage.content.photo.sizes.length > 1) {
|
|
||||||
for (var i = (rawMessage.content.photo.sizes.length - 2); i >= 0; i--) {
|
|
||||||
candidateBiggest = rawMessage.content.photo.sizes[i];
|
|
||||||
if (candidateBiggest.width > 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return candidateBiggest;
|
|
||||||
}
|
|
||||||
|
|
||||||
height: Math.max(Theme.itemSizeExtraSmall, Math.min(defaultHeight, width / (biggest.width/biggest.height)))
|
|
||||||
readonly property int defaultHeight: Math.round(width * 0.66666666)
|
|
||||||
readonly property var biggest: calculateBiggest();
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
pageStack.push(Qt.resolvedUrl("../../pages/ImagePage.qml"), {
|
|
||||||
"photoData" : photo.photo,
|
|
||||||
// "pictureFileInformation" : photo.fileInformation
|
|
||||||
})
|
|
||||||
}
|
|
||||||
TDLibPhoto {
|
|
||||||
id: photo
|
|
||||||
anchors.fill: parent
|
|
||||||
photo: rawMessage.content.photo
|
|
||||||
highlighted: parent.highlighted
|
|
||||||
}
|
|
||||||
BackgroundImage {
|
|
||||||
visible: !rawMessage.content.photo.minithumbnail && photo.image.status !== Image.Ready
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
|
|
||||||
MessageLocation {
|
|
||||||
locationData: rawMessage.content.venue.location
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
|
|
||||||
MessageVideo {}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
|
|
||||||
MessageAudio {
|
|
||||||
fileInformation: rawMessage.content.voice_note.voice
|
|
||||||
primaryText: qsTr("Voice Note")
|
|
||||||
secondaryText: ""
|
|
||||||
duration: rawMessage.content.voice_note.duration
|
|
||||||
thumbnail: null
|
|
||||||
minithumbnail: null
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick 2.6
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../js/functions.js" as Functions
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: sponsoredMessageColumn
|
|
||||||
|
|
||||||
property var sponsoredMessageData;
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onMessageLinkInfoReceived: {
|
|
||||||
if (sponsoredMessageData.link.url === url) {
|
|
||||||
messageOverlayLoader.overlayMessage = messageLinkInfo.message;
|
|
||||||
messageOverlayLoader.active = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (sponsoredMessageData) {
|
|
||||||
if (typeof sponsoredMessageData.link === "undefined") {
|
|
||||||
sponsoredMessageButton.text = qsTr("Go to Channel");
|
|
||||||
sponsoredMessageButton.advertisesChannel = true;
|
|
||||||
} else if (sponsoredMessageData.link['@type'] === "internalLinkTypeMessage") {
|
|
||||||
sponsoredMessageButton.text = qsTr("Go to Message");
|
|
||||||
sponsoredMessageButton.advertisesMessage = true;
|
|
||||||
} else {
|
|
||||||
sponsoredMessageButton.text = qsTr("Start Bot");
|
|
||||||
sponsoredMessageButton.advertisesBot = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: sponsoredMessageButton
|
|
||||||
property bool advertisesChannel: false;
|
|
||||||
property bool advertisesMessage: false;
|
|
||||||
property bool advertisesBot: false;
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
if (advertisesChannel) {
|
|
||||||
tdLibWrapper.createSupergroupChat(tdLibWrapper.getChat(sponsoredMessageData.sponsor_chat_id).type.supergroup_id, "openDirectly");
|
|
||||||
}
|
|
||||||
if (advertisesMessage) {
|
|
||||||
tdLibWrapper.getMessageLinkInfo(sponsoredMessageData.link.url);
|
|
||||||
}
|
|
||||||
if (advertisesBot) {
|
|
||||||
tdLibWrapper.createPrivateChat(tdLibWrapper.getUserInformationByName(sponsoredMessageData.link.bot_username).id, "openAndSendStartToBot:" + sponsoredMessageData.link.start_parameter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
|
|
||||||
|
|
||||||
Column {
|
|
||||||
width: parent.width
|
|
||||||
property SilicaFlickable flickable
|
|
||||||
property bool animate: false
|
|
||||||
signal setActiveArea(string activeAreaTitle)
|
|
||||||
function scrollUpFlickable(amount) {
|
|
||||||
if(flickable) {
|
|
||||||
flickableAnimation.to = Math.max(0, flickable.contentY - amount);
|
|
||||||
flickableAnimation.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
id: flickableAnimation
|
|
||||||
target: flickable
|
|
||||||
property: "contentY"
|
|
||||||
duration: 200
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: area
|
|
||||||
width: parent.width
|
|
||||||
height: button.height + content.height
|
|
||||||
property alias icon: image
|
|
||||||
property alias text: label.text
|
|
||||||
property alias asynchronous: content.asynchronous
|
|
||||||
property bool expanded: false
|
|
||||||
default property alias els: content.sourceComponent
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
when: area.expanded
|
|
||||||
PropertyChanges { target: image; rotation: 90 }
|
|
||||||
PropertyChanges { target: content; height: content.implicitHeight + Theme.paddingLarge; opacity: 1.0 }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
transitions: Transition {
|
|
||||||
to: "*"
|
|
||||||
enabled: area.parent.animate
|
|
||||||
NumberAnimation { target: content; properties: "height, opacity"; duration: 200}
|
|
||||||
NumberAnimation { target: image; properties: "rotation"; duration: 200}
|
|
||||||
}
|
|
||||||
Connections {
|
|
||||||
target: area.parent
|
|
||||||
onSetActiveArea: {
|
|
||||||
var expand = (activeAreaTitle === area.text);
|
|
||||||
if(area.expanded && !expand && area.parent.scrollUpFlickable) {
|
|
||||||
area.parent.scrollUpFlickable(content.implicitHeight + Theme.paddingLarge);
|
|
||||||
}
|
|
||||||
|
|
||||||
area.expanded = expand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BackgroundItem {
|
|
||||||
id: button
|
|
||||||
height: Theme.itemSizeMedium
|
|
||||||
onClicked: {
|
|
||||||
area.parent.animate = true;
|
|
||||||
area.parent.setActiveArea(area.expanded ? -1 : area.text)
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
gradient: Gradient {
|
|
||||||
GradientStop { position: 0.0; color: Theme.rgba(Theme.highlightBackgroundColor, 0.15) }
|
|
||||||
GradientStop { position: 1.0; color: "transparent" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: label
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: image.left
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
leftMargin: Theme.horizontalPageMargin + Theme.paddingLarge
|
|
||||||
rightMargin: Theme.paddingMedium
|
|
||||||
}
|
|
||||||
horizontalAlignment: Text.AlignRight
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
color: button.highlighted ? Theme.highlightColor : Theme.primaryColor
|
|
||||||
textFormat: Text.PlainText
|
|
||||||
}
|
|
||||||
HighlightImage {
|
|
||||||
id: image
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
rightMargin: Theme.horizontalPageMargin
|
|
||||||
}
|
|
||||||
width: visible ? Theme.iconSizeMedium : 0
|
|
||||||
highlighted: parent.highlighted
|
|
||||||
source: "image://theme/icon-m-left"
|
|
||||||
rotation: -90
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loader {
|
|
||||||
id: content
|
|
||||||
width: parent.width
|
|
||||||
height: 0
|
|
||||||
opacity: 0
|
|
||||||
anchors.top: button.bottom
|
|
||||||
asynchronous: true
|
|
||||||
clip: true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import "../../js/functions.js" as Functions
|
|
||||||
|
|
||||||
Grid {
|
|
||||||
width: parent.width - ( 2 * x )
|
|
||||||
columns: Functions.isWidescreen(appWindow) ? 2 : 1
|
|
||||||
readonly property real columnWidth: width/columns
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
|
|
||||||
AccordionItem {
|
|
||||||
text: qsTr("Appearance")
|
|
||||||
clip: heightBehavior.enabled || heightAnimation.running
|
|
||||||
|
|
||||||
// One-shot behavior
|
|
||||||
Behavior on height {
|
|
||||||
id: heightBehavior
|
|
||||||
enabled: false
|
|
||||||
SequentialAnimation {
|
|
||||||
id: heightAnimation
|
|
||||||
SmoothedAnimation { duration: 200 }
|
|
||||||
ScriptAction { script: heightBehavior.enabled = false }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
ResponsiveGrid {
|
|
||||||
bottomPadding: Theme.paddingMedium
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.showStickersAsEmojis
|
|
||||||
text: qsTr("Show stickers as emojis")
|
|
||||||
description: qsTr("Only display emojis instead of the actual stickers")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
heightBehavior.enabled = true
|
|
||||||
appSettings.showStickersAsEmojis = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.showStickersAsImages
|
|
||||||
text: qsTr("Show stickers as images")
|
|
||||||
description: qsTr("Show background for stickers and align them centrally like images")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.showStickersAsImages = !checked
|
|
||||||
}
|
|
||||||
visible: !appSettings.showStickersAsEmojis
|
|
||||||
opacity: visible ? 1 : 0
|
|
||||||
Behavior on opacity { FadeAnimation { } }
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
// Placeholder to move the next switch to the second column
|
|
||||||
visible: parent.columns === 2
|
|
||||||
width: 1
|
|
||||||
height: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.animateStickers
|
|
||||||
text: qsTr("Animate stickers")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.animateStickers = !checked
|
|
||||||
}
|
|
||||||
visible: !appSettings.showStickersAsEmojis
|
|
||||||
opacity: visible ? 1 : 0
|
|
||||||
Behavior on opacity { FadeAnimation { } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,221 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
|
|
||||||
AccordionItem {
|
|
||||||
text: qsTr("Behavior")
|
|
||||||
Component {
|
|
||||||
ResponsiveGrid {
|
|
||||||
bottomPadding: Theme.paddingMedium
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.sendByEnter
|
|
||||||
text: qsTr("Send message by enter")
|
|
||||||
description: qsTr("Send your message by pressing the enter key")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.sendByEnter = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.focusTextAreaOnChatOpen
|
|
||||||
text: qsTr("Focus text input on chat open")
|
|
||||||
description: qsTr("Focus the text input area when entering a chat")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.focusTextAreaOnChatOpen = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.focusTextAreaAfterSend
|
|
||||||
text: qsTr("Focus text input area after send")
|
|
||||||
description: qsTr("Focus the text input area after sending a message")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.focusTextAreaAfterSend = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.delayMessageRead
|
|
||||||
text: qsTr("Delay before marking messages as read")
|
|
||||||
description: qsTr("Fernschreiber will wait a bit before messages are marked as read")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.delayMessageRead = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.highlightUnreadConversations
|
|
||||||
text: qsTr("Highlight unread messages")
|
|
||||||
description: qsTr("Highlight Conversations with unread messages")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.highlightUnreadConversations = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.useOpenWith
|
|
||||||
text: qsTr("Open-with menu integration")
|
|
||||||
description: qsTr("Integrate Fernschreiber into open-with menu of Sailfish OS")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.useOpenWith = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.notificationAlwaysShowPreview
|
|
||||||
text: qsTr("Always append message preview to notifications")
|
|
||||||
description: qsTr("In addition to showing the number of unread messages, the latest message will also be appended to notifications.")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationAlwaysShowPreview = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.goToQuotedMessage
|
|
||||||
text: qsTr("Go to quoted message")
|
|
||||||
description: qsTr("When tapping a quoted message, open it in chat instead of showing it in an overlay.")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.goToQuotedMessage = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
id: feedbackComboBox
|
|
||||||
width: parent.columnWidth
|
|
||||||
label: qsTr("Notification feedback")
|
|
||||||
description: qsTr("Use non-graphical feedback (sound, vibration) for notifications")
|
|
||||||
menu: ContextMenu {
|
|
||||||
id: feedbackMenu
|
|
||||||
x: 0
|
|
||||||
width: feedbackComboBox.width
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
readonly property int value: AppSettings.NotificationFeedbackAll
|
|
||||||
text: qsTr("All events")
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationFeedback = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
readonly property int value: AppSettings.NotificationFeedbackNew
|
|
||||||
text: qsTr("Only new events")
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationFeedback = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
readonly property int value: AppSettings.NotificationFeedbackNone
|
|
||||||
text: qsTr("None")
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationFeedback = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: updateFeedbackSelection()
|
|
||||||
|
|
||||||
function updateFeedbackSelection() {
|
|
||||||
var menuItems = feedbackMenu.children
|
|
||||||
var n = menuItems.length
|
|
||||||
for (var i=0; i<n; i++) {
|
|
||||||
if (menuItems[i].value === appSettings.notificationFeedback) {
|
|
||||||
currentIndex = i
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: appSettings
|
|
||||||
onNotificationFeedbackChanged: {
|
|
||||||
feedbackComboBox.updateFeedbackSelection()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
// Occupies one grid cell so that the column ends up under the combo box
|
|
||||||
// in the landscape layout
|
|
||||||
visible: parent.columns === 2
|
|
||||||
width: 1
|
|
||||||
height: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
enabled: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
|
|
||||||
width: parent.columnWidth
|
|
||||||
height: enabled ? implicitHeight: 0
|
|
||||||
clip: height < implicitHeight
|
|
||||||
visible: height > 0
|
|
||||||
|
|
||||||
Behavior on height { SmoothedAnimation { duration: 200 } }
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
checked: appSettings.notificationSuppressContent && enabled
|
|
||||||
text: qsTr("Hide content in notifications")
|
|
||||||
enabled: parent.enabled
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationSuppressContent = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
checked: appSettings.notificationTurnsDisplayOn && enabled
|
|
||||||
text: qsTr("Notification turns on the display")
|
|
||||||
enabled: parent.enabled
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationTurnsDisplayOn = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
checked: appSettings.notificationSoundsEnabled && enabled
|
|
||||||
text: qsTr("Enable notification sounds")
|
|
||||||
description: qsTr("When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.")
|
|
||||||
enabled: parent.enabled
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationSoundsEnabled = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,266 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
|
|
||||||
AccordionItem {
|
|
||||||
text: qsTr("Privacy")
|
|
||||||
Component {
|
|
||||||
Column {
|
|
||||||
bottomPadding: Theme.paddingMedium
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onUserPrivacySettingUpdated: {
|
|
||||||
Debug.log("Received updated privacy setting: " + setting + ":" + rule);
|
|
||||||
switch (setting) {
|
|
||||||
case TelegramAPI.SettingAllowChatInvites:
|
|
||||||
allowChatInvitesComboBox.currentIndex = rule;
|
|
||||||
break;
|
|
||||||
case TelegramAPI.SettingAllowFindingByPhoneNumber:
|
|
||||||
allowFindingByPhoneNumberComboBox.currentIndex = rule;
|
|
||||||
break;
|
|
||||||
case TelegramAPI.SettingShowLinkInForwardedMessages:
|
|
||||||
showLinkInForwardedMessagesComboBox.currentIndex = rule;
|
|
||||||
break;
|
|
||||||
case TelegramAPI.SettingShowPhoneNumber:
|
|
||||||
showPhoneNumberComboBox.currentIndex = rule;
|
|
||||||
break;
|
|
||||||
case TelegramAPI.SettingShowProfilePhoto:
|
|
||||||
showProfilePhotoComboBox.currentIndex = rule;
|
|
||||||
break;
|
|
||||||
case TelegramAPI.SettingShowStatus:
|
|
||||||
showStatusComboBox.currentIndex = rule;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ResponsiveGrid {
|
|
||||||
ComboBox {
|
|
||||||
id: allowChatInvitesComboBox
|
|
||||||
width: parent.columnWidth
|
|
||||||
label: qsTr("Allow chat invites")
|
|
||||||
description: qsTr("Privacy setting for managing whether you can be invited to chats.")
|
|
||||||
menu: ContextMenu {
|
|
||||||
x: 0
|
|
||||||
width: allowChatInvitesComboBox.width
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Yes")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleAllowAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Your contacts only")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleAllowContacts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("No")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleRestrictAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
id: allowFindingByPhoneNumberComboBox
|
|
||||||
width: parent.columnWidth
|
|
||||||
label: qsTr("Allow finding by phone number")
|
|
||||||
description: qsTr("Privacy setting for managing whether you can be found by your phone number.")
|
|
||||||
menu: ContextMenu {
|
|
||||||
x: 0
|
|
||||||
width: allowFindingByPhoneNumberComboBox.width
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Yes")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber, TelegramAPI.RuleAllowAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Your contacts only")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber, TelegramAPI.RuleAllowContacts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
id: showLinkInForwardedMessagesComboBox
|
|
||||||
width: parent.columnWidth
|
|
||||||
label: qsTr("Show link in forwarded messages")
|
|
||||||
description: qsTr("Privacy setting for managing whether a link to your account is included in forwarded messages.")
|
|
||||||
menu: ContextMenu {
|
|
||||||
x: 0
|
|
||||||
width: showLinkInForwardedMessagesComboBox.width
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Yes")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleAllowAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Your contacts only")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleAllowContacts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("No")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleRestrictAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
id: showPhoneNumberComboBox
|
|
||||||
width: parent.columnWidth
|
|
||||||
label: qsTr("Show phone number")
|
|
||||||
description: qsTr("Privacy setting for managing whether your phone number is visible.")
|
|
||||||
menu: ContextMenu {
|
|
||||||
x: 0
|
|
||||||
width: showPhoneNumberComboBox.width
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Yes")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleAllowAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Your contacts only")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleAllowContacts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("No")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleRestrictAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
id: showProfilePhotoComboBox
|
|
||||||
width: parent.columnWidth
|
|
||||||
label: qsTr("Show profile photo")
|
|
||||||
description: qsTr("Privacy setting for managing whether your profile photo is visible.")
|
|
||||||
menu: ContextMenu {
|
|
||||||
x: 0
|
|
||||||
width: showProfilePhotoComboBox.width
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Yes")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleAllowAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Your contacts only")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleAllowContacts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("No")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleRestrictAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
id: showStatusComboBox
|
|
||||||
width: parent.columnWidth
|
|
||||||
label: qsTr("Show status")
|
|
||||||
description: qsTr("Privacy setting for managing whether your online status is visible.")
|
|
||||||
menu: ContextMenu {
|
|
||||||
x: 0
|
|
||||||
width: showStatusComboBox.width
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Yes")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleAllowAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Your contacts only")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleAllowContacts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("No")
|
|
||||||
onClicked: {
|
|
||||||
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleRestrictAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
checked: appSettings.allowInlineBotLocationAccess
|
|
||||||
text: qsTr("Allow sending Location to inline bots")
|
|
||||||
description: qsTr("Some inline bots request location data when using them")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.allowInlineBotLocationAccess = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,216 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../../components"
|
|
||||||
import "../../js/functions.js" as Functions
|
|
||||||
|
|
||||||
AccordionItem {
|
|
||||||
text: qsTr("Sessions")
|
|
||||||
property SilicaFlickable flickable: parent.flickable
|
|
||||||
Component {
|
|
||||||
Column {
|
|
||||||
id: activeSessionsItem
|
|
||||||
bottomPadding: Theme.paddingMedium
|
|
||||||
property variant activeSessions
|
|
||||||
property int inactiveSessionsTtlDays
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (!activeSessions) {
|
|
||||||
tdLibWrapper.getActiveSessions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onSessionsReceived: {
|
|
||||||
activeSessionsItem.activeSessions = sessions
|
|
||||||
activeSessionsItem.inactiveSessionsTtlDays = inactive_session_ttl_days
|
|
||||||
}
|
|
||||||
onOkReceived: {
|
|
||||||
if (request === "terminateSession") {
|
|
||||||
appNotification.show(qsTr("Session was terminated"));
|
|
||||||
tdLibWrapper.getActiveSessions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
active: tdLibWrapper.authorizationState === TelegramAPI.AuthorizationReady
|
|
||||||
width: parent.width
|
|
||||||
sourceComponent: Component {
|
|
||||||
Column {
|
|
||||||
BusyIndicator {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
running: !activeSessionsListView.count && !activeSessionsItem.inactiveSessionsTtlDays
|
|
||||||
size: BusyIndicatorSize.Medium
|
|
||||||
visible: opacity > 0
|
|
||||||
height: running ? implicitHeight : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
SilicaListView {
|
|
||||||
id: activeSessionsListView
|
|
||||||
width: parent.width
|
|
||||||
height: contentHeight
|
|
||||||
model: activeSessionsItem.activeSessions
|
|
||||||
headerPositioning: ListView.OverlayHeader
|
|
||||||
header: Separator {
|
|
||||||
width: parent.width
|
|
||||||
color: Theme.primaryColor
|
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
|
||||||
visible: activeSessionsListView.count > 0
|
|
||||||
}
|
|
||||||
delegate: ListItem {
|
|
||||||
id: activeSessionListItem
|
|
||||||
width: parent.width
|
|
||||||
contentHeight: activeSessionColumn.height + ( 2 * Theme.paddingMedium )
|
|
||||||
|
|
||||||
menu: ContextMenu {
|
|
||||||
hasContent: !modelData.is_current
|
|
||||||
onHeightChanged: {
|
|
||||||
if (parent && flickable) {
|
|
||||||
// Make sure we are inside the screen area
|
|
||||||
var bottom = parent.mapToItem(flickable, x, y).y + height
|
|
||||||
if (bottom > flickable.height) {
|
|
||||||
flickable.contentY += bottom - flickable.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
onClicked: {
|
|
||||||
var sessionId = modelData.id;
|
|
||||||
Remorse.itemAction(activeSessionListItem, qsTr("Terminating session"), function() { tdLibWrapper.terminateSession(sessionId); });
|
|
||||||
}
|
|
||||||
text: qsTr("Terminate Session")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: activeSessionColumn
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
spacing: Theme.paddingSmall
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
text: qsTr("This app")
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
font.bold: true
|
|
||||||
visible: modelData.is_current
|
|
||||||
color: Theme.highlightColor
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
text: modelData.application_name + " " + modelData.application_version
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
font.bold: true
|
|
||||||
maximumLineCount: 1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
text: modelData.device_model + ", " + (modelData.platform + " " + modelData.system_version).trim()
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
maximumLineCount: 1
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
text: qsTr("Active since: %1, last online: %2").arg(Functions.getDateTimeTimepoint(modelData.log_in_date)).arg(Functions.getDateTimeElapsed(modelData.last_active_date))
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
maximumLineCount: 1
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Separator {
|
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
color: Theme.primaryColor
|
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
readonly property int ttl: activeSessionsItem.inactiveSessionsTtlDays
|
|
||||||
label: qsTr("Session Timeout")
|
|
||||||
description: qsTr("Inactive sessions will be terminated after this timeframe")
|
|
||||||
value: (currentItem && currentItem.text) ? currentItem.text : qsTr("%1 day(s)", "", ttl).arg(ttl)
|
|
||||||
visible: ttl > 0
|
|
||||||
menu: ContextMenu {
|
|
||||||
id: ttlMenu
|
|
||||||
MenuItem {
|
|
||||||
readonly property int days: 7
|
|
||||||
text: qsTr("1 week")
|
|
||||||
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
readonly property int days: 30
|
|
||||||
text: qsTr("1 month")
|
|
||||||
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
readonly property int days: 90
|
|
||||||
text: qsTr("3 months")
|
|
||||||
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
readonly property int days: 180
|
|
||||||
text: qsTr("6 months")
|
|
||||||
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
readonly property int days: 365
|
|
||||||
text: qsTr("1 year")
|
|
||||||
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: updateSelection()
|
|
||||||
|
|
||||||
onTtlChanged: updateSelection()
|
|
||||||
|
|
||||||
function updateSelection() {
|
|
||||||
var menuItems = ttlMenu.children
|
|
||||||
var n = menuItems.length
|
|
||||||
for (var i = 0; i < n; i++) {
|
|
||||||
if (menuItems[i].days === ttl) {
|
|
||||||
currentIndex = i
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentIndex = -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
|
|
||||||
AccordionItem {
|
|
||||||
text: qsTr("Storage")
|
|
||||||
Component {
|
|
||||||
ResponsiveGrid {
|
|
||||||
bottomPadding: Theme.paddingMedium
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.onlineOnlyMode
|
|
||||||
text: qsTr("Enable online-only mode")
|
|
||||||
description: qsTr("Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.onlineOnlyMode = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextSwitch {
|
|
||||||
width: parent.columnWidth
|
|
||||||
checked: appSettings.storageOptimizer
|
|
||||||
text: qsTr("Enable storage optimizer")
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.storageOptimizer = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,346 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2021 Sebastian J. Wolf and other contributors
|
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
|
||||||
|
|
||||||
Fernschreiber 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.
|
|
||||||
|
|
||||||
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import Sailfish.Pickers 1.0
|
|
||||||
import WerkWolf.Fernschreiber 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../pages/"
|
|
||||||
import "../../js/twemoji.js" as Emoji
|
|
||||||
import "../../js/functions.js" as Functions
|
|
||||||
|
|
||||||
AccordionItem {
|
|
||||||
text: qsTr("User Profile")
|
|
||||||
Component {
|
|
||||||
Column {
|
|
||||||
id: accordionContent
|
|
||||||
bottomPadding: Theme.paddingMedium
|
|
||||||
|
|
||||||
readonly property var userInformation: tdLibWrapper.getUserInformation()
|
|
||||||
property bool uploadInProgress: false
|
|
||||||
property bool contactSyncEnabled: false
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onOwnUserUpdated: {
|
|
||||||
firstNameEditArea.text = userInformation.first_name;
|
|
||||||
lastNameEditArea.text = userInformation.last_name;
|
|
||||||
userNameEditArea.text = userInformation.username;
|
|
||||||
}
|
|
||||||
onUserProfilePhotosReceived: {
|
|
||||||
if (extra === userInformation.id.toString()) {
|
|
||||||
imageContainer.thumbnailModel = photos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFileUpdated: {
|
|
||||||
if (uploadInProgress) {
|
|
||||||
profilePictureButtonColumn.visible = !fileInformation.remote.is_uploading_active;
|
|
||||||
uploadInProgress = fileInformation.remote.is_uploading_active;
|
|
||||||
if (!fileInformation.remote.is_uploading_active) {
|
|
||||||
uploadInProgress = false;
|
|
||||||
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onOkReceived: {
|
|
||||||
if (request === "deleteProfilePhoto") {
|
|
||||||
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
|
|
||||||
}
|
|
||||||
if (request === "setProfilePhoto") {
|
|
||||||
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
|
|
||||||
profilePictureButtonColumn.visible = true;
|
|
||||||
uploadInProgress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ResponsiveGrid {
|
|
||||||
x: Theme.horizontalPageMargin
|
|
||||||
|
|
||||||
InformationEditArea {
|
|
||||||
id: firstNameEditArea
|
|
||||||
visible: true
|
|
||||||
canEdit: true
|
|
||||||
headerText: qsTr("First Name", "first name of the logged-in profile - header")
|
|
||||||
text: userInformation.first_name
|
|
||||||
width: parent.columnWidth
|
|
||||||
headerLeftAligned: true
|
|
||||||
|
|
||||||
onSaveButtonClicked: {
|
|
||||||
if(!editItem.errorHighlight) {
|
|
||||||
tdLibWrapper.setName(textValue, lastNameEditArea.text);
|
|
||||||
} else {
|
|
||||||
isEditing = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onTextEdited: {
|
|
||||||
if(textValue.length > 0 && textValue.length < 65) {
|
|
||||||
editItem.errorHighlight = false;
|
|
||||||
editItem.label = "";
|
|
||||||
editItem.placeholderText = "";
|
|
||||||
} else {
|
|
||||||
editItem.label = qsTr("Enter 1-64 characters");
|
|
||||||
editItem.placeholderText = editItem.label;
|
|
||||||
editItem.errorHighlight = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InformationEditArea {
|
|
||||||
id: lastNameEditArea
|
|
||||||
visible: true
|
|
||||||
canEdit: true
|
|
||||||
headerText: qsTr("Last Name", "last name of the logged-in profile - header")
|
|
||||||
text: userInformation.last_name
|
|
||||||
width: parent.columnWidth
|
|
||||||
headerLeftAligned: true
|
|
||||||
|
|
||||||
onSaveButtonClicked: {
|
|
||||||
if(!editItem.errorHighlight) {
|
|
||||||
tdLibWrapper.setName(firstNameEditArea.text, textValue);
|
|
||||||
} else {
|
|
||||||
isEditing = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onTextEdited: {
|
|
||||||
if(textValue.length >= 0 && textValue.length < 65) {
|
|
||||||
editItem.errorHighlight = false;
|
|
||||||
editItem.label = "";
|
|
||||||
editItem.placeholderText = "";
|
|
||||||
} else {
|
|
||||||
editItem.label = qsTr("Enter 0-64 characters");
|
|
||||||
editItem.placeholderText = editItem.label;
|
|
||||||
editItem.errorHighlight = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InformationEditArea {
|
|
||||||
id: userNameEditArea
|
|
||||||
visible: true
|
|
||||||
canEdit: true
|
|
||||||
headerText: qsTr("Username", "user name of the logged-in profile - header")
|
|
||||||
text: userInformation.usernames.editable_username
|
|
||||||
width: parent.columnWidth
|
|
||||||
headerLeftAligned: true
|
|
||||||
|
|
||||||
onSaveButtonClicked: {
|
|
||||||
tdLibWrapper.setUsername(textValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: contactSyncItem
|
|
||||||
width: parent.width
|
|
||||||
height: syncInProgress ? ( syncContactsBusyIndicator.height + Theme.paddingMedium ) : ( syncContactsButton.height + Theme.paddingMedium )
|
|
||||||
visible: accordionContent.contactSyncEnabled
|
|
||||||
|
|
||||||
property bool syncInProgress: false
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: contactSyncLoader.item
|
|
||||||
onSyncError: {
|
|
||||||
contactSyncItem.syncInProgress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onContactsImported: {
|
|
||||||
appNotification.show(qsTr("Contacts successfully synchronized with Telegram."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: syncContactsButton
|
|
||||||
text: qsTr("Synchronize Contacts with Telegram")
|
|
||||||
visible: !contactSyncItem.syncInProgress
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
contactSyncLoader.item.synchronize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BusyIndicator {
|
|
||||||
id: syncContactsBusyIndicator
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
running: contactSyncItem.syncInProgress
|
|
||||||
size: BusyIndicatorSize.Small
|
|
||||||
visible: running
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionHeader {
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
text: qsTr("Profile Pictures")
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: imageContainer
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
width: parent.width / 2
|
|
||||||
height: profilePictureLoader.height
|
|
||||||
property var thumbnailModel: ({})
|
|
||||||
property bool thumbnailVisible: true
|
|
||||||
property bool thumbnailActive: thumbnailModel.length > 0
|
|
||||||
property int thumbnailRadius: imageContainer.width / 2
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: profilePictureLoader
|
|
||||||
active: imageContainer.thumbnailActive
|
|
||||||
asynchronous: true
|
|
||||||
width: Theme.itemSizeExtraLarge
|
|
||||||
height: Theme.itemSizeExtraLarge
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
source: "../ProfilePictureList.qml"
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfileThumbnail {
|
|
||||||
id: chatPictureReplacement
|
|
||||||
visible: !profilePictureLoader.active
|
|
||||||
replacementStringHint: Functions.getUserName(accordionContent.userInformation)
|
|
||||||
radius: imageContainer.thumbnailRadius
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
width: Theme.itemSizeExtraLarge
|
|
||||||
height: Theme.itemSizeExtraLarge
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: profilePictureButtonColumn
|
|
||||||
spacing: Theme.paddingSmall
|
|
||||||
width: parent.width / 2
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: addProfilePictureButton
|
|
||||||
text: qsTr("Add Picture")
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
pageStack.push(imagePickerPage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: removeProfilePictureButton
|
|
||||||
text: qsTr("Delete Picture")
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
var pictureIdForDeletion = imageContainer.thumbnailModel[profilePictureLoader.item.currentPictureIndex].id;
|
|
||||||
Remorse.popupAction(settingsPage, qsTr("Deleting profile picture"), function() { tdLibWrapper.deleteProfilePhoto(pictureIdForDeletion) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: uploadStatusColumn
|
|
||||||
visible: !profilePictureButtonColumn.visible
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
width: parent.width / 2
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: uploadingText
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
text: qsTr("Uploading...")
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
color: Theme.secondaryColor
|
|
||||||
width: parent.width
|
|
||||||
}
|
|
||||||
|
|
||||||
BusyIndicator {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
running: uploadStatusColumn.visible
|
|
||||||
size: BusyIndicatorSize.Medium
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: contactSyncLoader
|
|
||||||
source: "../ContactSync.qml"
|
|
||||||
active: true
|
|
||||||
onLoaded: {
|
|
||||||
accordionContent.contactSyncEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: imagePickerPage
|
|
||||||
ImagePickerPage {
|
|
||||||
onSelectedContentPropertiesChanged: {
|
|
||||||
profilePictureButtonColumn.visible = false;
|
|
||||||
uploadInProgress = true;
|
|
||||||
tdLibWrapper.setProfilePhoto(selectedContentProperties.filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
|
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
height: Theme.fontSizeExtraLarge
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
text: qsTr("Phone number: +%1").arg(accordionContent.userInformation.phone_number)
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: logOutButton
|
|
||||||
text: qsTr("Log Out")
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
onClicked: Remorse.popupAction(settingsPage, qsTr("Logged out"), function() {
|
|
||||||
tdLibWrapper.logout();
|
|
||||||
pageStack.pop();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -40,16 +40,6 @@ ApplicationWindow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: tdLibWrapper
|
|
||||||
onOpenFileExternally: {
|
|
||||||
Qt.openUrlExternally(filePath);
|
|
||||||
}
|
|
||||||
onTgUrlFound: {
|
|
||||||
Functions.handleLink(tgUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AppNotification {
|
AppNotification {
|
||||||
id: appNotification
|
id: appNotification
|
||||||
parent: pageStack.currentPage
|
parent: pageStack.currentPage
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" xml:space="preserve"><path fill="#141414" d="M7 5a4 4 0 0 0-4 4v18a4 4 0 0 0 4 4h6V5H7z"/><path fill="#FDDA24" d="M13 5h10v26H13z"/><path fill="#EF3340" d="M29 5h-6v26h6a4 4 0 0 0 4-4V9a4 4 0 0 0-4-4z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#141414" d="M4 5C1.791 5 0 6.791 0 9v18c0 2.209 1.791 4 4 4h8V5H4z"/><path fill="#FEE833" d="M12 5h12v26H12z"/><path fill="#EE232C" d="M32 5h-8v26h8c2.209 0 4-1.791 4-4V9c0-2.209-1.791-4-4-4z"/></svg>
|
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 272 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" xml:space="preserve"><path fill="#138808" d="M0 27a4 4 0 0 0 4 4h28a4 4 0 0 0 4-4v-5H0v5z"/><path fill="#F93" d="M36 14V9a4 4 0 0 0-4-4H4a4 4 0 0 0-4 4v5h36z"/><path fill="#F7F7F7" d="M0 13.667h36v8.667H0z"/><circle fill="navy" cx="18" cy="18" r="4"/><circle fill="#F7F7F7" cx="18" cy="18" r="3.375"/><path d="m18.1 16.75-.1.65-.1-.65.1-1.95zm-.928-1.841.408 1.909.265.602-.072-.653zm-.772.32.888 1.738.412.513-.238-.613zm-.663.508 1.308 1.45.531.389-.389-.531zm-.508.663 1.638 1.062.613.238-.513-.412zm-.32.772 1.858.601.653.072-.602-.265zM14.8 18l1.95.1.65-.1-.65-.1zm.109.828 1.909-.408.602-.265-.653.072zm.32.772 1.738-.888.513-.412-.613.238zm.508.663 1.45-1.308.389-.531-.531.389zm.663.508 1.062-1.638.238-.613-.412.513zm.772.32.601-1.858.072-.653-.265.602zM18 21.2l.1-1.95-.1-.65-.1.65zm.828-.109-.408-1.909-.265-.602.072.653zm.772-.32-.888-1.738-.412-.513.238.613zm.663-.508-1.308-1.45-.531-.389.389.531zm.508-.663-1.638-1.062-.613-.238.513.412zm.32-.772-1.858-.601-.653-.072.602.265zM21.2 18l-1.95-.1-.65.1.65.1zm-.109-.828-1.909.408-.602.265.653-.072zm-.32-.772-1.738.888-.513.412.613-.238zm-.508-.663-1.45 1.308-.389.531.531-.389zm-.663-.508-1.062 1.638-.238.613.412-.513zm-.772-.32-.601 1.858-.072.653.265-.602z" fill="#6666B3"/><g fill="navy"><circle cx="17.56" cy="14.659" r=".2"/><circle cx="16.71" cy="14.887" r=".2"/><circle cx="15.948" cy="15.326" r=".2"/><circle cx="15.326" cy="15.948" r=".2"/><circle cx="14.887" cy="16.71" r=".2"/><circle cx="14.659" cy="17.56" r=".2"/><circle cx="14.659" cy="18.44" r=".2"/><circle cx="14.887" cy="19.29" r=".2"/><circle cx="15.326" cy="20.052" r=".2"/><circle cx="15.948" cy="20.674" r=".2"/><circle cx="16.71" cy="21.113" r=".2"/><circle cx="17.56" cy="21.341" r=".2"/><circle cx="18.44" cy="21.341" r=".2"/><circle cx="19.29" cy="21.113" r=".2"/><circle cx="20.052" cy="20.674" r=".2"/><circle cx="20.674" cy="20.052" r=".2"/><circle cx="21.113" cy="19.29" r=".2"/><circle cx="21.341" cy="18.44" r=".2"/><circle cx="21.341" cy="17.56" r=".2"/><circle cx="21.113" cy="16.71" r=".2"/><circle cx="20.674" cy="15.948" r=".2"/><circle cx="20.052" cy="15.326" r=".2"/><circle cx="19.29" cy="14.887" r=".2"/><circle cx="18.44" cy="14.659" r=".2"/><circle cx="18" cy="18" r=".9"/></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#138808" d="M0 27c0 2.209 1.791 4 4 4h28c2.209 0 4-1.791 4-4v-4H0v4z"/><path fill="#EEE" d="M0 13h36v10H0z"/><path fill="#F93" d="M36 13V9c0-2.209-1.791-4-4-4H4C1.791 5 0 6.791 0 9v4h36z"/><circle fill="navy" cx="18" cy="18" r="4"/><circle fill="#EEE" cx="18" cy="18" r="3"/><path fill="#6666B3" d="M18 15l.146 2.264 1.001-2.035-.73 2.147 1.704-1.498-1.497 1.705 2.147-.731-2.035 1.002L21 18l-2.264.146 2.035 1.001-2.147-.73 1.497 1.704-1.704-1.497.73 2.147-1.001-2.035L18 21l-.146-2.264-1.002 2.035.731-2.147-1.705 1.497 1.498-1.704-2.147.73 2.035-1.001L15 18l2.264-.146-2.035-1.002 2.147.731-1.498-1.705 1.705 1.498-.731-2.147 1.002 2.035z"/><circle fill="navy" cx="18" cy="18" r="1"/></svg>
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 765 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#060" d="M36 27c0 2.209-1.791 4-4 4H4c-2.209 0-4-1.791-4-4V9c0-2.209 1.791-4 4-4h28c2.209 0 4 1.791 4 4v18z"/><path fill="#D52B1E" d="M32 5H15v26h17c2.209 0 4-1.791 4-4V9c0-2.209-1.791-4-4-4z"/><path fill="#FFCC4D" d="M15 10c-4.419 0-8 3.581-8 8 0 4.418 3.581 8 8 8 4.418 0 8-3.582 8-8 0-4.419-3.582-8-8-8zm-6.113 4.594l1.602 1.602-2.46 1.23c.083-1.022.383-1.981.858-2.832zm-.858 3.979l4.4 2.207-2.706 1.804.014.021c-.96-1.097-1.583-2.492-1.708-4.032zM14 24.92c-.937-.134-1.813-.453-2.592-.92H14v.92zM14 23h-3.099L14 20.934V23zm0-3.268l-.607.405L9.118 18l2.116-1.058L14 19.707v.025zm0-1.439l-3.543-3.543 3.543.59v2.953zm0-3.992l-4.432-.713c1.084-1.333 2.65-2.253 4.432-2.508v3.221zm7.113.293c.475.851.775 1.81.858 2.833l-2.46-1.23 1.602-1.603zM16 11.08c1.782.256 3.348 1.175 4.432 2.508L16 14.301V11.08zm0 4.26l3.543-.591L16 18.293V15.34zm0 4.367l2.765-2.765L20.882 18l-4.274 2.137-.608-.405v-.025zm0 5.213V24h2.592c-.779.467-1.655.786-2.592.92zM16 23v-2.066L19.099 23H16zm4.264-.395l.014-.021-2.706-1.804 4.4-2.207c-.126 1.54-.749 2.935-1.708 4.032z"/><path fill="#D52B1E" d="M11 13v7c0 2.209 1.791 4 4 4s4-1.791 4-4v-7h-8z"/><path fill="#FFF" d="M12 14v6c0 1.656 1.343 3 3 3s3-1.344 3-3v-6h-6z"/><path fill="#829ACD" d="M13 17h4v2h-4z"/><path fill="#829ACD" d="M14 16h2v4h-2z"/><path fill="#039" d="M12 17h1v2h-1zm2 0h2v2h-2zm3 0h1v2h-1zm-3 3h2v2h-2zm0-6h2v2h-2z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#060" d="M36 27c0 2.209-1.791 4-4 4H4c-2.209 0-4-1.791-4-4V9c0-2.209 1.791-4 4-4h28c2.209 0 4 1.791 4 4v18z"/><path fill="#D52B1E" d="M32 5H15v26h17c2.209 0 4-1.791 4-4V9c0-2.209-1.791-4-4-4z"/><path fill="#FFCC4D" d="M15 10c-4.418 0-8 3.582-8 8s3.582 8 8 8 8-3.582 8-8-3.582-8-8-8zm3.994 5.938l2.089-1.393c.491.863.803 1.839.888 2.881l-2.977-1.488zM16 24h2.592c-.779.467-1.655.786-2.592.92V24zm-7.971-6.574c.083-1.022.383-1.982.858-2.832l1.602 1.602-2.46 1.23zm0 1.147l3.747 1.874.447-.895L9.118 18l2.116-1.058 1.412 1.412.707-.707-1.176-1.176.046-.023-.447-.895-.344.172-.975-.975 1.461.244.164-.986-2.514-.419c1.084-1.333 2.65-2.253 4.432-2.508V23h-3.099l2.376-1.584-.555-.832-3 2 .014.021c-.959-1.097-1.582-2.492-1.707-4.032zM14 24.92c-.937-.135-1.813-.453-2.592-.92H14v.92zm6.287-2.34l-2.933-2.933-.707.707.471.471-.395.592L19.099 23H16V11.08c1.321.189 2.524.741 3.499 1.561l-2.657.886.316.948 3-1-.103-.308c.167.174.323.357.471.548l-2.804 1.869L18 16l-.224.447L20.882 18l-3.105 1.553.447.895 3.747-1.874c-.124 1.527-.737 2.913-1.684 4.006z"/><path fill="#D52B1E" d="M11 13v7c0 2.209 1.791 4 4 4s4-1.791 4-4v-7h-8z"/><path fill="#FFF" d="M12 14v6c0 1.656 1.343 3 3 3s3-1.344 3-3v-6h-6z"/><path fill="#829ACD" d="M13 17h4v2h-4z"/><path fill="#829ACD" d="M14 16h2v4h-2z"/><path fill="#039" d="M12 17h1v2h-1zm2 0h2v2h-2zm3 0h1v2h-1zm-3 3h2v2h-2zm0-6h2v2h-2z"/></svg>
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#A7122D" d="M0 26.518V27c0 2.209 1.791 4 4 4h28c2.209 0 4-1.791 4-4v-.482H0z"/><path fill="#EEE" d="M0 22.181h36v4.485H0z"/><path fill="#292648" d="M0 13.513h36v8.821H0z"/><path fill="#EEE" d="M0 9.181h36v4.485H0z"/><path fill="#A7122D" d="M0 9.333V9c0-2.209 1.791-4 4-4h28c2.209 0 4 1.791 4 4v.333H0z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#ED1C24" d="M32 5H4C1.791 5 0 6.791 0 9h36c0-2.209-1.791-4-4-4z"/><path fill="#EEE" d="M0 9h36v4H0z"/><path fill="#ED1C24" d="M32 31H4c-2.209 0-4-1.791-4-4h36c0 2.209-1.791 4-4 4z"/><path fill="#EEE" d="M0 23h36v4H0z"/><path fill="#241D4F" d="M0 13h36v10H0z"/></svg>
|
Before Width: | Height: | Size: 382 B After Width: | Height: | Size: 338 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#DD2E44" cx="18" cy="18" r="18"/><circle fill="#FFF" cx="18" cy="18" r="13.5"/><circle fill="#DD2E44" cx="18" cy="18" r="10"/><circle fill="#FFF" cx="18" cy="18" r="6"/><circle fill="#DD2E44" cx="18" cy="18" r="3"/><path opacity=".2" d="M18.24 18.282l13.144 11.754s-2.647 3.376-7.89 5.109L17.579 18.42l.661-.138z"/><path fill="#FFAC33" d="M18.294 19c-.255 0-.509-.097-.704-.292-.389-.389-.389-1.018 0-1.407l.563-.563c.389-.389 1.018-.389 1.408 0 .388.389.388 1.018 0 1.407l-.564.563c-.194.195-.448.292-.703.292z"/><path fill="#55ACEE" d="M24.016 6.981c-.403 2.079 0 4.691 0 4.691l7.054-7.388c.291-1.454-.528-3.932-1.718-4.238-1.19-.306-4.079.803-5.336 6.935zm5.003 5.003c-2.079.403-4.691 0-4.691 0l7.388-7.054c1.454-.291 3.932.528 4.238 1.718.306 1.19-.803 4.079-6.935 5.336z"/><path fill="#3A87C2" d="M32.798 4.485L21.176 17.587c-.362.362-1.673.882-2.51.046-.836-.836-.419-2.08-.057-2.443L31.815 3.501s.676-.635 1.159-.152-.176 1.136-.176 1.136z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#CCD6DD" cx="18" cy="18" r="18"/><circle fill="#3B88C3" cx="18" cy="18" r="14"/><circle fill="#DD2E44" cx="18" cy="18" r="10"/><circle fill="#FFAC33" cx="18" cy="18" r="6"/><path d="M34.864 29.199c-.42.306-1.257.592-1.934.592-1.965 0-4.654-.717-6.334-2.386l-2.954-3.872c-.274-.275-.357-.575-.21-.932.148-.359-.73-.601-.342-.601h5.058c1.867 0 4.308 1.256 5.925 3.018l.371.351c.772.843 1.183 1.629 1.182 2.386 0 .621-.272 1.087-.762 1.444z"/><path d="M28.305 35.204c-.771 0-1.632-.417-2.49-1.204l-.488-.378C23.532 31.977 22 29.491 22 27.59v-5.164c0-.396.5.514.865.363.363-.15.915-.066 1.195.214l3.166 3.124c1.699 1.711 3.061 4.619 3.061 6.62 0 .689-.143 1.255-.452 1.682-.364.499-.897.775-1.53.775z"/><path fill="#C1694F" d="M31.345 31.964c-.256 0-.487-.122-.683-.317l-14-14c-.391-.391-.391-1.023 0-1.415.391-.391 1.023-.39 1.414 0l14 14c.391.391.378 1.036-.013 1.427-.194.195-.461.305-.718.305z"/></svg>
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 976 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" xml:space="preserve"><path fill="#880082" d="M0 27a4 4 0 0 0 4 4h28a4 4 0 0 0 4-4v-.5H0v.5z"/><path fill="#3558A0" d="M0 22.07h36v4.6H0z"/><path fill="#138F3E" d="M0 17.83h36v4.5H0z"/><path fill="#FAD220" d="M0 13.5h36V18H0z"/><path fill="#FF7300" d="M0 9.17h36v4.5H0z"/><path fill="#FF000E" d="M32 5H4a4 4 0 0 0-4 4v.33h36V9a4 4 0 0 0-4-4z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#880082" d="M0 27c0 2.209 1.791 4 4 4h28c2.209 0 4-1.791 4-4v-.5H0v.5z"/><path fill="#3558A0" d="M0 22.07h36v4.6H0z"/><path fill="#138F3E" d="M0 17.83h36v4.5H0z"/><path fill="#FAD220" d="M0 13.5h36V18H0z"/><path fill="#FF5000" d="M0 9.17h36v4.5H0z"/><path fill="#FF000E" d="M32 5H4C1.791 5 0 6.791 0 9v.33h36V9c0-2.209-1.791-4-4-4z"/></svg>
|
Before Width: | Height: | Size: 409 B After Width: | Height: | Size: 412 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#5BCEFA" d="M0 27c0 2.209 1.791 4 4 4h28c2.209 0 4-1.791 4-4v-1.3H0V27z"/><path fill="#F5A9B8" d="M.026 20.5L0 25.8h36v-5.3z"/><path fill="#EEE" d="M0 15.3h36v5.3H0z"/><path fill="#F5A9B8" d="M0 9.902h36V15.4H0z"/><path fill="#5BCEFA" d="M36 9c0-2.209-1.791-4-4-4H4C1.791 5 0 6.791 0 9v1.2h36V9z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#5BCEFA" d="M0 27c0 2.209 1.791 4 4 4h28c2.209 0 4-1.791 4-4v-1.3H0V27z"/><path fill="#F5A9B8" d="M.026 20.5L0 25.8h36v-5.3z"/><path fill="#EEE" d="M0 15.3h36v5.3H0z"/><path fill="#F5A9B8" d="M.026 10.1L0 15.4h36v-5.3z"/><path fill="#5BCEFA" d="M36 9c0-2.209-1.791-4-4-4H4C1.791 5 0 6.791 0 9v1.2h36V9z"/></svg>
|
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 383 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#292F33" d="M11 11.844c-2.297-.669-3.315-3.565-3.734-5.369C6.313 7.952 4.23 10.155 0 11.28V.425C.955.154 1.959 0 3 0c6.075 0 11 4.925 11 11 0 3.009-1.211 5.733-3.168 7.719.107-.557.168-1.13.168-1.719v-5.156z"/><path fill="#F7DECE" d="M0 28.604L2 32l3-5v-1.523c2.968-1.051 5.222-3.607 5.832-6.757.107-.558.168-1.131.168-1.72v-5.156c-2.297-.669-3.315-3.565-3.734-5.369C6.313 7.952 4.23 10.155 0 11.28v17.324z"/><path fill="#3B94D9" d="M0 28.604L2 32l3-5h6c2.209 0 4 1.791 4 4v5H0v-7.396z"/><path fill="#1C6399" d="M10 32h1v4h-1z"/><path fill="#C1694F" d="M5 22h1s-1 2-4 2c-.809 0-1.462-.151-2-.363V22h5zm-2-2.5H1c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h2c.276 0 .5.224.5.5s-.224.5-.5.5z"/><path fill="#662113" d="M6 16c-.553 0-1-.448-1-1v-1c0-.552.447-1 1-1s1 .448 1 1v1c0 .552-.447 1-1 1z"/><path fill="#292F33" d="M25 11.844c2.297-.669 3.315-3.565 3.734-5.369.953 1.477 3.036 3.68 7.266 4.805V.425C35.045.154 34.041 0 33 0c-6.075 0-11 4.925-11 11 0 3.009 1.211 5.733 3.168 7.719C25.061 18.162 25 17.589 25 17v-5.156z"/><path fill="#F7DECE" d="M36 11.28c-4.23-1.125-6.313-3.328-7.266-4.804-.42 1.804-1.438 4.699-3.734 5.369V17c0 .589.061 1.162.168 1.719.61 3.15 2.863 5.706 5.832 6.757V27l3 5 2-3.396V11.28z"/><path fill="#3B94D9" d="M36 28.604L34 32l-3-5h-6c-2.209 0-4 1.791-4 4v5h15v-7.396z"/><path fill="#1C6399" d="M25 32h1v4h-1z"/><path fill="#C1694F" d="M31 22h-1s1 2 4 2c.809 0 1.462-.151 2-.363V22h-5zm2-2.5h2c.276 0 .5-.224.5-.5s-.224-.5-.5-.5h-2c-.276 0-.5.224-.5.5s.224.5.5.5z"/><path fill="#662113" d="M30 16c.553 0 1-.448 1-1v-1c0-.552-.447-1-1-1s-1 .448-1 1v1c0 .552.447 1 1 1z"/><path fill="#DD2E44" d="M26.539 4.711c0-2.602-2.11-4.711-4.711-4.711C20.249 0 18.855.78 18 1.972 17.144.78 15.751 0 14.172 0c-2.601 0-4.711 2.109-4.711 4.711 0 .369.047.727.127 1.07.654 4.065 5.173 8.353 8.411 9.529 3.238-1.177 7.758-5.465 8.412-9.528.081-.344.128-.702.128-1.071z"/></svg>
|
|
Before Width: | Height: | Size: 1.9 KiB |