Compare commits

...

694 commits

Author SHA1 Message Date
Sebastian Wolf
0236586e44 Switch to gh tool for release creation, see https://github.com/actions/runner-images/issues/8362 2023-12-03 23:52:21 +03:00
Sebastian Wolf
e13c7ae68c Prepare 0.17 release 2023-12-03 23:52:19 +03:00
Sebastian Wolf
1d68123ea1 Restore content width in landscape as per discussion in #540 2023-12-03 23:52:06 +03:00
Slava Monich
cf7b706582 Tweaked the logic of moving reactions into the view (#543)
There's no need to reposition list items if reactions bar are already
fully visible.
2023-12-03 23:50:55 +03:00
free software
c42d030d02 Update harbour-fernschreiber-es.ts (#542) 2023-12-03 23:50:55 +03:00
Sebastian Wolf
edfce9b492 Highlight message that was jumped to 2023-12-03 23:50:55 +03:00
mbarashkov
e5d1ecd9f3 Jump to post from quote (#538)
* Jump to post from quote

* Add a setting to go to quoted message.

---------

Co-authored-by: Mikhail Barashkov <git@mbarashkov.ru>
2023-12-03 23:50:23 +03:00
Sebastian Wolf
42a7813776 Not only tablets have widescreen ;) 2023-12-03 23:50:21 +03:00
mbarashkov
627faba0db Improve chat UI on tablets by making messages narrower and limiting content items width as well. (#540)
Co-authored-by: Mikhail Barashkov <git@mbarashkov.ru>
2023-12-03 23:49:14 +03:00
Slava Monich
a4ebaf52f5 Fix broken signal-slot connection (#541)
QObject::connect: No such signal TDLibWrapper::chatAvailableReactionsUpdated(qlonglong, QString) in src/chatlistmodel.cpp:410
2023-12-03 23:46:48 +03:00
Sebastian Wolf
660fe527f2 Handle event updateChatAvailableReactions 2023-12-03 23:46:46 +03:00
Sebastian Wolf
1a0ed7f298 Only one star per list, restore users in poll results 2023-12-03 23:46:30 +03:00
062f5d3811 Merge pull request 'upstream_changes_251123' (#14) from upstream_changes_251123 into master
Reviewed-on: medvedych/harbour-fernschreiber#14
2023-11-25 13:50:00 +03:00
034c70542f Update build number 2023-11-25 13:49:08 +03:00
Patrick Hervieux
ef244c3319 Update French translation (#532)
Co-authored-by: Patrick Hervieux <patrick.hervieux+git@pherjung.ch>
2023-11-25 13:34:26 +03:00
free software
556505894c Update harbour-fernschreiber-es.ts (#531) 2023-11-25 13:34:11 +03:00
Sebastian Wolf
7c63ad66f9 Interaction hint for new reactions behavior 2023-11-25 13:33:45 +03:00
Sebastian Wolf
26772a48eb Show reactions on double-click 2023-11-25 13:33:13 +03:00
Slava Monich
2ded14deda Added "unread mention" indicator to the chat list (#530)
It's displayed in place of the "unread reaction" indicator. In case
if there are both unread mentions and reactions, "unread mention"
takes precedence.
2023-11-25 13:31:50 +03:00
free software
465c082328 Update harbour-fernschreiber-es.ts (#529)
* Update harbour-fernschreiber-es.ts

* Update harbour-fernschreiber-es.ts
2023-11-25 13:31:35 +03:00
Slava Monich
25e6660e8e Updated Russian translation (#528) 2023-11-25 13:31:25 +03:00
f58afe92cb Merge pull request 'upstream_changes' (#13) from upstream_changes into master
Reviewed-on: medvedych/harbour-fernschreiber#13
2023-11-21 14:24:05 +03:00
2b3ca0dff9 Update gitignore 2023-11-21 14:23:24 +03:00
Sebastian Wolf
1e88a31f90 Display reactions on last message again 2023-11-21 14:18:20 +03:00
Sebastian Wolf
026d32c92a Restore search in chats 2023-11-21 14:18:20 +03:00
Sebastian Wolf
a28b9df6b5 Minor tweaks for the new session timout setting 2023-11-21 14:18:12 +03:00
d2bde99e1f Merge pull request 'Revert executable rename' (#12) from revert_executable_rename into master
Reviewed-on: medvedych/harbour-fernschreiber#12
2023-11-20 22:31:56 +03:00
f8ffedb5db Revert executable rename 2023-11-20 19:31:56 +00:00
4b7d17c02f Merge pull request 'upstream_changes' (#11) from upstream_changes into master
Reviewed-on: medvedych/harbour-fernschreiber#11
2023-11-20 00:54:47 +03:00
0ae98f96b5 Release version ++ 2023-11-19 21:54:39 +00:00
Slava Monich
fb3d314ee2 Added UI for configuring session inactivity timeout (#527) 2023-11-20 00:50:41 +03:00
Sebastian Wolf
b032b32db1 More places affected by new username handling 2023-11-20 00:50:37 +03:00
Sebastian Wolf
63f4b37655 Hide unsupported emojis for reactions 2023-11-20 00:49:35 +03:00
Sebastian Wolf
bdc0423bf3 Make replies backward-compatible again 2023-11-20 00:49:12 +03:00
749f05816c Merge pull request 'adapt_to_changes_in_tdlib' (#10) from adapt_to_changes_in_tdlib into master
Reviewed-on: medvedych/harbour-fernschreiber#10
2023-11-19 16:35:16 +03:00
06ebe95309 Fix some validator warnings 2023-11-19 16:35:45 +03:00
Sebastian Wolf
40ec4b0968 Fix chat permissions handling 2023-11-19 16:16:46 +03:00
Slava Monich
c4c9dc83c0 Tweaked notification feedback settings UI (#526) 2023-11-19 16:16:36 +03:00
9a37db94ae Update tdlib headers 2023-11-19 16:11:29 +03:00
Sebastian Wolf
0ba3a8cd7f Trouble with usernames 2023-11-19 12:23:42 +03:00
Sebastian Wolf
0aeaf50c92 Some minor adjustments 2023-11-19 12:23:23 +03:00
Johannes Bachmann
a9947ff9f7 Always append last message content to notifications (#514)
* always append last message content to notifications

* make "always show notification" configurable

* add unfinished translations

* Fix spacing if no sender is printed
2023-11-19 12:22:22 +03:00
Peter G
c7324c020b Add option to suppress notification previews (#521)
* Add Switch in Settings

* Don't set notification preview body

* Support the setting in appSettings

* fixup! Add Switch in Settings

* Just show message count

* Also show only when notifications are enabled at all

---------

Co-authored-by: nephros <nemo@pgxperiiia10>
2023-11-19 12:22:13 +03:00
Peter G
46419b0960 Highlight unread Converstations (#513)
* Highlight unread conversations

See: #512

* make highlighting configurable

* more verbose variable names

* remove the rectangle gain, it is too annoying

* respect the setting

---------

Co-authored-by: nephros <nemo@pgxperiiia10>
2023-11-19 12:22:04 +03:00
Slava Monich
c1c8729023 Adapt to changes in reply message info (#525)
1.8.14:
https://github.com/tdlib/td/commit/fa94aba

1.8.21:
https://github.com/tdlib/td/commit/811a7c6
https://github.com/tdlib/td/commit/5216ea1
2023-11-19 12:21:17 +03:00
Sebastian Wolf
9bcc9ab690 Only expect chat partner information in private chats 2023-11-19 12:01:42 +03:00
Slava Monich
0b6a2db2f1 Adapt to changes in TdLib (#524)
* Adapt setTdlibParameters for TdLib > 1.8.5

For some reason tdlibParameters were inlined between 1.8.5 and 1.8.6
See https://github.com/tdlib/td/commit/f6a2ecd

* sponsoredMessage => sponsoredMessages in TdLib 1.8.8

See https://github.com/tdlib/td/commit/ec1310a

* Support another variant of messageReaction

The reaction field has changed from string to ReactionType somewhere
between 1.8.5 and 1.8.6

See https://github.com/tdlib/td/commit/b14708f

* Add support for new message reactions API

It has changed between 1.8.5 and 1.8.6

https://github.com/tdlib/td/commit/b14708f (ReactionType)
https://github.com/tdlib/td/commit/0b8e143 (ChatAvailableReactions)
https://github.com/tdlib/td/commit/6b2f6b4 (addMessageReaction)
https://github.com/tdlib/td/commit/d29d367 (updateActiveEmojiReactions)

etc.

* Highlight chosen reaction

* Support username in the new format

username attribute has been replaced with usernames in 1.8.8 and
now looks like this:

    "usernames": {
        "@type": "usernames",
        "active_usernames": [
            "whatever"
        ],
        "disabled_usernames": [
        ],
        "editable_username": "whatever"
    }

See https://github.com/tdlib/td/commit/897032e

* Support new reply_to message attribute

Since 1.8.15 it replaces reply_to_message_id and reply_in_chat_id.
Looks like this:

    "reply_to": {
        "@type": "messageReplyToMessage",
        "chat_id": -1001234567890,
        "is_quote_manual": false,
        "message_id": 234567890,
        "origin_send_date": 0
    },

See https://github.com/tdlib/td/commit/6116573

* Added support for MessageOrigin values

All of a sudden MessageForwardOrigin has been renamed into MessageOrigin
in TdLib 1.8.20 just because why not:

https://github.com/tdlib/td/commit/10c9e40
2023-11-19 12:01:27 +03:00
61a04b034a Merge pull request 'improve_unread_ballons' (#9) from sprainbrains/harbour-fernschreiber:improve_unread_ballons into master
Reviewed-on: medvedych/harbour-fernschreiber#9
2023-11-18 22:38:58 +03:00
jgibbon
ca42a5e7e0 Add specific unread info for higher counts of unread messages 2023-11-18 22:38:44 +03:00
400cda8dcd Merge pull request 'origin_merged' (#8) from sprainbrains/harbour-fernschreiber:origin_merged into master
Reviewed-on: medvedych/harbour-fernschreiber#8
2023-11-18 22:36:19 +03:00
fe50ead4ee Merged 2023-10-14 00:21:35 +03:00
f1717cbd29 Merge remote-tracking branch 'origin_sailfish/master' into origin_merged 2023-10-14 00:19:37 +03:00
Sebastian Wolf
5394fde136
Update chat list more reliably 2023-08-08 22:50:04 +02:00
1ad324aa23 Merge pull request 'Fixed size of background circle for Unread messages' (#7) from sprainbrains/harbour-fernschreiber:unread_message_background_fix into master
Reviewed-on: medvedych/harbour-fernschreiber#7
2023-08-07 14:17:38 +03:00
59b99a0a28 Fixed size of background circle for Unread messages 2023-08-03 15:02:34 +03:00
12dbac7480 build number ++ 2023-07-12 01:31:25 +03:00
258466beeb Merge pull request 'remove own id from messages title' (#6) from remove_title_on_own_messages_4 into master
Reviewed-on: medvedych/harbour-fernschreiber#6
2023-07-12 01:28:18 +03:00
656e8ccfe7 left margin for own messages in private chats 2023-07-12 01:27:18 +03:00
22930628ae wide message without left margin 2023-07-12 01:12:53 +03:00
0d26167ee3 remove left margin on own messages 2023-07-10 01:29:00 +03:00
723105382d remove own id from messages title 2023-07-09 15:16:06 +03:00
c9773fb5ab Merge pull request 'fix_own_message_ui_3' (#4) from fix_own_message_ui_3 into master
Reviewed-on: medvedych/harbour-fernschreiber#4
2023-07-09 14:43:42 +03:00
51227c1323 forgot desktop file 2023-07-09 14:43:18 +03:00
aac7fd7328 remowed right align on own messages 2023-07-09 14:43:18 +03:00
f3dd33c4ca removed sailfish contact sync support 2023-07-09 14:43:18 +03:00
Sebastian Wolf
83f0c54f8b Switch to icon-m-video as placeholder 2023-07-09 14:43:18 +03:00
71d1831ed3 Merge pull request 'aurora_build' (#2) from aurora_build into master
Reviewed-on: medvedych/harbour-fernschreiber#2
2023-07-08 10:32:41 +03:00
Sebastian Wolf
29621b739a
Switch to icon-m-video as placeholder 2023-06-20 09:46:01 +02:00
Denis Fedoseev
0b91948141 project build settings were modified 2023-04-04 10:54:18 +03:00
Denis Fedoseev
9d37635500 мелкие фиксы для валидатора 2023-04-04 10:53:39 +03:00
okruhliak
df6322c712 Update harbour-fernschreiber-sk.ts 2023-02-27 21:27:26 +01:00
free software
5de2e94f32 Update harbour-fernschreiber-es.ts 2023-02-27 11:57:52 +01:00
Rustem Abzalov
85732c6fbc Update harbour-fernschreiber-ru.ts 2023-02-27 11:56:18 +01:00
Sebastian Wolf
a7ab0ed33a
Prepare support for contact sync with SFOS 4.5 2023-02-05 20:17:06 +01:00
Slava Monich
f152bbeb5b
Always show user or group id on the info page (#511)
And copy it to the clipboard on tap.
2023-02-05 15:52:06 +01:00
Peter G
b469135877
improve message when search yields no results (#507)
Co-authored-by: nephros <nemo@pgxperiiia10>
2023-02-05 15:41:04 +01:00
Sebastian Wolf
a9b6bf5817
React to network configuration changes, fixes #504 2022-07-10 22:39:52 +02:00
Sebastian Wolf
f91eb7936a
Release 0.16 2022-06-12 17:39:15 +02:00
Sebastian Wolf
5465d454f5
Pre-allocate vertical space for reactions 2022-06-08 23:13:34 +02:00
Sebastian Wolf
227c9146f2
Try Auto-Build with 4.4.0.58 2022-06-07 23:27:36 +02:00
Sebastian Wolf
ec2a1cf398
Changelog for 0.16 2022-06-07 22:51:39 +02:00
Sebastian Wolf
0a76ede35a
Only display reactions on chat list for now 2022-06-06 23:06:57 +02:00
Sebastian Wolf
99910a3f3a
Bring unread mention/reactions to chat list 2022-06-06 15:55:21 +02:00
Sebastian Wolf
9ff7a8371d
README: build instructions | Try to avoid ghost chats in main list 2022-05-30 23:22:57 +02:00
Sebastian Wolf
fa8a77a265
Next version will be 0.16 2022-05-29 22:17:37 +02:00
Sebastian Wolf
03fad6da6d
Reactions only for current message, restore animated stickers 2022-05-29 22:10:30 +02:00
Sebastian Wolf
0cc6f959fc
Option to mark all chat reactions as read 2022-05-24 21:19:15 +02:00
Sebastian Wolf
033f96b366
Display reactions to message 2022-05-23 23:33:17 +02:00
Sebastian Wolf
7c56bbeae4
Merge branch 'master' of github.com:Wunderfitz/harbour-fernschreiber 2022-05-01 23:51:53 +02:00
Sebastian Wolf
723371e9c9
Add reactions flickable to messages (on click) 2022-05-01 23:51:03 +02:00
Sebastian Wolf
2c53848d04
Merge pull request #493 from monich/sessions
Made sure that context menu stays inside the screen area
2022-05-01 23:50:34 +02:00
Slava Monich
23df9d05ee Made sure that context menu stays inside the screen area 2022-05-01 17:11:17 +03:00
Sebastian Wolf
0e7ae00a67
Workaround for t.me/+... links 2022-05-01 14:04:28 +02:00
Sebastian Wolf
81cf5b6852
Use normal URL dialog for t.me/+... links 2022-05-01 01:17:37 +02:00
Sebastian Wolf
6d6b07b9a9
Get available message reactions 2022-04-30 23:51:47 +02:00
Sebastian Wolf
4445be3302
Add 'RemovableMedia' to the list of requested permissions 2022-04-27 23:19:48 +02:00
Sebastian Wolf
d21cbc455a
Fix typo in changelog 2022-04-27 22:26:18 +02:00
Sebastian Wolf
32a55c48be
Bring notifications back to lock screen, changelog for 0.15 2022-04-27 22:06:57 +02:00
Sebastian Wolf
99bb0c7b85
Remove direct call to Pure Maps, use generic handler for geo: URIs now 2022-04-26 22:26:54 +02:00
Sebastian Wolf
46433109a6
Store own user information also when 'my_id' option arrives after user itself 2022-04-24 22:11:31 +02:00
Sebastian Wolf
679426abc1
xdg-open doesn't seem to work anymore on SFOS 4.4 2022-04-24 20:55:06 +02:00
Sebastian Wolf
1f589cc2da
Sailjail: Remove Contacts (Harbour-compliance), changelog for 0.14 2022-04-24 16:20:56 +02:00
Sebastian Wolf
856a16c640
Don't overwrite active status of attachment row for voice notes, fixes #481 2022-04-24 14:39:36 +02:00
Sebastian Wolf
ebe0143a8a
SFOS 4.4 removed notification categories, fixes #486 2022-04-22 00:08:04 +02:00
Sebastian Wolf
e40cf02baa
Merge pull request #485 from monich/view-mess
Adapt handling of sponsored messages to the new format
2022-04-21 22:57:36 +02:00
Sebastian Wolf
7c74c7c444
Merge pull request #487 from carlosgonz0/patch-37
Update harbour-fernschreiber-es.ts
2022-04-21 22:39:06 +02:00
Sebastian Wolf
9d6ff8e7d7
Some SailJail stuff, eventually need to become SFOS 4.4-ready 2022-04-21 22:37:14 +02:00
free software
3957cdbde4
Update harbour-fernschreiber-es.ts 2022-04-05 22:30:52 -04:00
Slava Monich
5f16156f01 Adapt handling of sponsored messages to the new format 2022-03-27 22:22:47 +03:00
Slava Monich
3c5bf563a6 Pass ids to TDLibWrapper::viewMessage as integers
Because they are integers
2022-03-27 22:22:47 +03:00
Sebastian Wolf
40f60cf4be
Add Emoji 14.0 support :) 2022-03-21 22:37:27 +01:00
Sebastian Wolf
ea409c4220
Merge pull request #484 from pherjung/french
Update French translation
2022-03-21 21:50:56 +01:00
Sebastian Wolf
016e0ffd51
Merge pull request #483 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2022-03-21 21:50:14 +01:00
Sebastian Wolf
8c725826cb
Merge pull request #482 from monich/strikethrough
Support textEntityTypeStrikethrough
2022-03-21 21:47:33 +01:00
Patrick Hervieux
01cbed675b Update French translation 2022-03-07 21:55:56 +01:00
okruhliak
da4393043f Update harbour-fernschreiber-sk.ts 2022-02-26 17:29:33 +01:00
Slava Monich
11f055932a Support textEntityTypeStrikethrough
It's not currently working because of this QtQuick bug:

  https://bugreports.qt.io/browse/QTBUG-72376

but maybe someday it will.
2022-02-20 18:58:38 +02:00
Sebastian Wolf
0b350d083e
Merge branch 'master' of github.com:Wunderfitz/harbour-fernschreiber 2022-01-13 21:49:50 +01:00
Sebastian Wolf
79b901b63f
Prepare release 0.13 2022-01-13 21:49:27 +01:00
Sebastian Wolf
6c78b9335e
Merge pull request #480 from mipstux/mipstux-patch-1
Update harbour-fernschreiber-fr.ts
2022-01-13 20:41:57 +01:00
mipstux
5e1d9c3bdb
Update harbour-fernschreiber-fr.ts
Correction of the word Apparance in Apparence (line 1480)
2022-01-11 15:11:28 +01:00
Sebastian Wolf
dc5e76e1e9
Merge pull request #479 from arustg/patch-19
Update harbour-fernschreiber-ru.ts
2022-01-10 22:06:33 +01:00
Rustem Abzalov
7ae3e25fb4
Update harbour-fernschreiber-ru.ts 2022-01-09 16:27:35 +03:00
Sebastian Wolf
338fd3edd1
New release somewhen after TDLib upgrade 2022-01-07 23:58:45 +01:00
Sebastian Wolf
60c1ed6bb1
Try to optimize sticker set handling (less reload) 2022-01-07 23:00:28 +01:00
Sebastian Wolf
932f483b7a
TDLib 1.8.0: New format for sponsored messages 2022-01-07 22:03:58 +01:00
Sebastian Wolf
fcbf9d65f1
TDLib 1.8.0: Headers and sender -> sender_id changes 2022-01-07 19:18:04 +01:00
Sebastian Wolf
3a8615dbe3
'getChats' becomes 'loadChats' with TDLib 1.8 2022-01-05 21:43:54 +01:00
Sebastian Wolf
fd46780b89
Merge pull request #477 from monich/replies
Fixed message reference in Replies chat
2022-01-05 21:07:30 +01:00
Sebastian Wolf
699d65ff4a
Merge pull request #478 from monich/zero-message-id
Don't try to load message with zero id
2022-01-05 21:00:16 +01:00
Sebastian Wolf
dfb3c58153
Merge pull request #476 from monich/forward-fix
Fix forwarding to channels with creator/admin access
2022-01-05 20:53:04 +01:00
Sebastian Wolf
29cc5968c0
Merge pull request #475 from arustg/patch-18
Update harbour-fernschreiber-ru.ts
2022-01-05 20:52:23 +01:00
Sebastian Wolf
964aa1a833
Merge pull request #474 from pherjung/french
Update French translation
2022-01-05 20:51:44 +01:00
Sebastian Wolf
c979e23084
Merge pull request #473 from atlochowski/patch-16
Update harbour-fernschreiber-pl.ts
2022-01-05 20:50:08 +01:00
Sebastian Wolf
6fecd5e217
Merge pull request #472 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2022-01-05 20:49:43 +01:00
Slava Monich
a6d469a999 Don't try to load message with zero id
chatPage.messageIdToShow can be defined and yet be zero
2021-12-26 04:50:37 +02:00
Slava Monich
af5a2b6c92 Fixed message reference in Replies chat
According to td_api.tl:

@reply_in_chat_id If non-zero, the identifier of the chat to which the
replied message belongs; Currently, only messages in the Replies chat
can have different reply_in_chat_id and chat_id
2021-12-26 04:46:52 +02:00
Slava Monich
326a789b01 Fix forwarding to channels with creator/admin access 2021-12-25 19:29:26 +02:00
Rustem Abzalov
0c3afffbac
Update harbour-fernschreiber-ru.ts 2021-12-24 19:48:35 +03:00
Patrick Hervieux
b6fa0413d4 Update French translation 2021-12-20 13:02:47 +01:00
Atlochowski
d243f130a2
Update harbour-fernschreiber-pl.ts 2021-12-20 09:38:21 +01:00
Åke Engelbrektson
effc1f0a3b
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2021-12-20 09:04:48 +01:00
Sebastian Wolf
985e7341dc
Changelog for 0.12 2021-12-19 22:07:16 +01:00
Sebastian Wolf
b4f64aaedd
Merge pull request #471 from monich/optimize
Remove (some) unused entries from QVariantMaps
2021-12-18 20:59:44 +01:00
Sebastian Wolf
55d046d318
Merge pull request #470 from monich/long-tap
Make "In reply to" properly react to taps
2021-12-18 20:37:44 +01:00
Slava Monich
7c8db1b739 Remove (some) unused entries from QVariantMaps
This may save megabytes of heap depending on how many stickers you have.
2021-12-18 06:40:06 +02:00
Slava Monich
1179c86a06 Make "In reply to" properly react to taps 2021-12-18 02:44:45 +02:00
Sebastian Wolf
833f5f1df7
Prepare 0.12 2021-12-16 21:54:30 +01:00
Sebastian Wolf
2d58239c34
Merge pull request #466 from monich/forward
Optimized forwarding
2021-12-16 21:19:50 +01:00
Sebastian Wolf
49b7047ac9
Some cleanup after #469 2021-12-15 23:56:46 +01:00
Sebastian Wolf
1ff1426b8b
Merge pull request #469 from nephros/sessions
Move Session options to Settings page
2021-12-15 22:34:08 +01:00
Sebastian Wolf
5ad93a777a
Try switching back to ChatListModel for opening chats via notifications 2021-12-15 22:07:14 +01:00
nephros
a5e5e36083 Use Remorse.popupAction instead of RemorseItem
RemorseItem sets anchors which we can't have in a Column
2021-12-15 12:17:05 +01:00
nephros
8349cb4377 fixup! fixup! Settings: add login info and logout to Profile 2021-12-15 12:02:32 +01:00
nephros
313a4d3827 fixup! Settings: add login info and logout to Profile 2021-12-15 11:57:48 +01:00
nephros
f33162801c Settings: add login info and logout to Profile 2021-12-15 11:55:29 +01:00
nephros
3786a0cb3f Sessions: remove profile info, restore list design 2021-12-15 10:36:26 +01:00
Slava Monich
68a2adc38d Optimized forwarding
It was a very strange experience. Now it's more like what an average
user would expect :)
2021-12-15 01:30:26 +02:00
Sebastian Wolf
fb4ce26dd3
Merge branch 'master' of github.com:Wunderfitz/harbour-fernschreiber 2021-12-14 23:22:40 +01:00
Sebastian Wolf
7bfa4a54e0
Some logging for some strange issues... 2021-12-14 23:22:21 +01:00
Sebastian Wolf
4929efadeb
Merge pull request #467 from carlosgonz0/patch-36
Update harbour-fernschreiber-es.ts
2021-12-14 22:02:10 +01:00
nephros
f8bc0df74a Tweak dimensions, fix ResponsiveGrid 2021-12-14 12:56:11 +01:00
nephros
4a04a55513 Move Session options to Settings page 2021-12-12 22:09:28 +01:00
Sebastian Wolf
fe9cd73798
Narrow down message link option for tg/resolve links 2021-12-11 23:22:32 +01:00
free software
7996291d0f
Update harbour-fernschreiber-es.ts 2021-12-11 16:07:30 -05:00
Sebastian Wolf
b8e5fb189c
Handle many direct message links properly, fixes #312 2021-12-11 18:29:31 +01:00
Sebastian Wolf
37518d06a6
Merge pull request #464 from monich/filter
Improve chat search performance
2021-12-09 22:11:05 +01:00
Sebastian Wolf
f6d6352879
Merge pull request #465 from monich/appearance
Hide appearance settings that are not applicable
2021-12-09 21:53:55 +01:00
Sebastian Wolf
02138e9115
Merge pull request #463 from carlosgonz0/patch-35
Add: Fully updated es.ts
2021-12-09 21:29:35 +01:00
Slava Monich
5da08c2a15 Hide appearance settings that are not applicable 2021-12-09 05:16:21 +02:00
Slava Monich
3c20eb7ca8 Improve chat search performance
Simple text search performs significantly better that regular
expressions.

Disconnecting search filter model from the source when search is off
should be good for performance because the filter model won't have to
unnecessarily react to the source model changes.
2021-12-09 02:13:18 +02:00
free software
65567b9a19
Add: Fully updated es.ts 2021-12-08 18:15:11 -05:00
Sebastian Wolf
5309dda94b
Avoid saving drafts for deleted users, fixes #439 2021-12-08 23:57:06 +01:00
Sebastian Wolf
02573e8d4e
Add option to delete private chat, see #439 2021-12-08 22:35:26 +01:00
Sebastian Wolf
c509616db9
Merge pull request #462 from monich/emoji-bg
Apply last remaining sticker option to animated emoji
2021-12-08 21:26:34 +01:00
Sebastian Wolf
57f2d71eca
Basic group chat members come in differently 2021-12-08 21:24:29 +01:00
Slava Monich
fb2c0a42c1 Apply last remaining sticker option to animated emoji
In all other respects their behavior is already equivalent
2021-12-08 20:52:57 +02:00
Sebastian Wolf
c6f50b8071
Merge pull request #461 from carlosgonz0/patch-34
Update harbour-fernschreiber-es.ts
2021-12-08 00:36:14 +01:00
Sebastian Wolf
54f4ce2dfe
Merge branch 'master' into patch-34 2021-12-08 00:36:02 +01:00
Sebastian Wolf
fcdf6cc4ed
Merge pull request #460 from monich/emoji
Describe emoji with emoji
2021-12-08 00:34:50 +01:00
Sebastian Wolf
0f4e0eaf58
Better support sponsored message types 2021-12-08 00:33:35 +01:00
Slava Monich
2fea47af1b Describe emoji with emoji
And stickers too
2021-12-08 00:57:54 +02:00
free software
25db7a5904
Update harbour-fernschreiber-es.ts 2021-12-07 16:58:23 -05:00
Sebastian Wolf
b5b0ec5ed1
Some fixes for #457 were missing... 2021-12-07 20:36:48 +01:00
Sebastian Wolf
b2e41a6421
Adapt to new chat member format, fixes #457 2021-12-06 23:51:54 +01:00
Sebastian Wolf
a92712d158
Merge pull request #456 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2021-12-06 22:28:08 +01:00
Sebastian Wolf
fa59ca0bb1
Merge pull request #455 from monich/optimal-mess
Attempt to optimize sponsored message handling
2021-12-06 22:27:31 +01:00
Sebastian Wolf
22f7a956dc
Merge pull request #454 from atlochowski/patch-15
Update harbour-fernschreiber-pl.ts
2021-12-06 22:22:24 +01:00
Åke Engelbrektson
2086a72e8c
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2021-12-06 07:18:57 +01:00
Slava Monich
84cfcb5150 Contigurable mess
There's no UI for that, you have to configure your mess manually))
Also, made sure that chats don't handle another char's mess.
2021-12-06 04:32:40 +02:00
Slava Monich
5a2596e9de Attempt to optimize sponsored message handling
By reducing number of QVariantMap lookups and various run-time
conversions to/from QString
2021-12-06 03:57:08 +02:00
Atlochowski
bf87aa723d
Update harbour-fernschreiber-pl.ts 2021-12-05 23:14:10 +01:00
Sebastian Wolf
4b744f300d
Prepare release 0.11 2021-12-05 22:29:30 +01:00
Sebastian Wolf
8573b3f6d9
Merge pull request #450 from monich/smarter-extra-options
Hide "Extra options..." context menu item if it's not needed
2021-12-05 22:10:14 +01:00
Sebastian Wolf
489c410b14
Merge branch 'master' into smarter-extra-options 2021-12-05 22:09:18 +01:00
Sebastian Wolf
a4dcec0540
Merge pull request #452 from carlosgonz0/patch-33
Finally i had the time to check & write on es.ts
2021-12-05 22:07:51 +01:00
Sebastian Wolf
9da9d22a71
Merge pull request #449 from monich/header-font-size
Use larger font for settings section headers
2021-12-05 22:06:59 +01:00
Sebastian Wolf
a59d32b29d
Update to TDLib 1.7.9, preliminary support for sponsored messages 2021-12-05 22:06:05 +01:00
free software
7657a6e4da
Finally i had the time to check & write es.ts 2021-12-05 11:31:51 -05:00
Slava Monich
9f4f3c9475 Hide "Extra options..." context menu item if it's not needed
If all context actions fit into the context menu limit (5 items in portrait,
4 items in landscape) it makes no sense to show this "Extra options..." thing.
2021-12-05 03:30:00 +02:00
Slava Monich
8a48982ca5 Use larger font for settings section headers 2021-12-05 01:12:49 +02:00
Sebastian Wolf
0400d12e52
Support for animated emoji 2021-12-04 22:05:22 +01:00
Sebastian Wolf
88d385ab0d
Don't forget the about page 2021-11-10 22:01:56 +01:00
Sebastian Wolf
7e985f5823
Changelog for 0.10.1 2021-11-09 22:49:12 +01:00
Sebastian Wolf
346ba3c8ef
Merge pull request #447 from atlochowski/patch-14
Update harbour-fernschreiber-pl.ts
2021-11-09 22:43:44 +01:00
Sebastian Wolf
406fbb04a4
MIME handling under SFOS is quite complicated 2021-11-09 22:42:54 +01:00
Atlochowski
4407d8f561
Update harbour-fernschreiber-pl.ts 2021-11-07 22:41:14 +01:00
Sebastian Wolf
f43364a71a
Changelog for 0.10 2021-11-07 20:10:19 +01:00
Sebastian Wolf
f3242bf7db
We only need the local .desktop files in Verla and earlier :) 2021-11-07 19:53:23 +01:00
Sebastian Wolf
a88abbb20f
Compatibility with earlier SFOS versions is hard... 2021-11-07 17:00:17 +01:00
Sebastian Wolf
db655d766f
No 'Recently used' section if there are no stickers, fixes #438 2021-11-07 15:09:33 +01:00
Sebastian Wolf
88d84caad9
New libcrypto dependencies, use Verla as build target for all archs 2021-11-07 14:43:19 +01:00
Sebastian Wolf
fd71c3c013
Complete build and run dependencies for TDLib 2021-11-04 20:16:19 +01:00
Sebastian Wolf
90b0a40824
Improve URL/open-with handler (hopefully) 2021-11-03 23:31:00 +01:00
Sebastian Wolf
0d01ad0b22
Update translation credits 2021-11-03 20:27:57 +01:00
Sebastian Wolf
f476239f3a
Merge pull request #446 from nbourdais/french_typo
fix for some typos
2021-11-03 20:21:40 +01:00
Sebastian Wolf
555b8320a6
Merge pull request #445 from nbourdais/french_sent
fix for 'sent' traduction
2021-11-03 20:21:10 +01:00
Nicolas Bourdais
9e45b8ee5c quelques corrections 2021-10-28 22:58:07 +02:00
Nicolas Bourdais
d336e6188e trad de sent
au passe simple
2021-10-28 22:22:55 +02:00
Sebastian Wolf
97ee0d7f1d
Merge pull request #443 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2021-10-26 21:25:39 +02:00
Sebastian Wolf
9ef5151fa4
Integrate French translation 2021-10-26 21:23:59 +02:00
Sebastian Wolf
4d4868377b
Merge pull request #444 from pherjung/french
Add French translation
2021-10-26 21:20:29 +02:00
Patrick Hervieux
dcb213fe8a Fix spelling error in French translation 2021-10-25 07:02:32 +02:00
Patrick Hervieux
972d74f3e2 Update French translation 2021-10-25 06:59:18 +02:00
Patrick Hervieux
9b85f2ed82 Update French translation 2021-10-24 15:08:37 +02:00
Patrick Hervieux
4f37fdeb67 Continue translation 2021-10-23 13:20:15 +02:00
Patrick Hervieux
76063e21cb Partial and unverified French translation 2021-10-23 12:12:10 +02:00
okruhliak
6bd869b542 Update harbour-fernschreiber-sk.ts 2021-10-19 17:21:42 +02:00
Sebastian Wolf
162a47fd26
Merge pull request #440 from monich/accordion-icon
Animate accordion image rotation
2021-09-28 21:31:46 +02:00
Slava Monich
481d6e88cc Animate accordion image rotation 2021-09-18 16:59:37 +03:00
Sebastian Wolf
dce28370b5
Development continues with 0.10 2021-08-30 20:07:11 +02:00
Sebastian Wolf
2f635395bc
Merge pull request #430 from Wunderfitz/feature/settings-page-accordion
settings page accordion
2021-08-30 19:47:41 +02:00
Sebastian Wolf
bb9cacb71e
Adjust accordion arrows to match default UX (see sample components) 2021-08-30 19:25:49 +02:00
John Gibbon
5a76303f4d fix long emoji names 2021-08-18 11:30:39 +02:00
Sebastian Wolf
1379d2883f
Merge pull request #434 from jgibbon/feature/document_emojis
Documentation: Add emoji list
2021-08-18 10:57:41 +02:00
John Gibbon
56fc96aafa Add emoji list 2021-08-18 09:56:58 +02:00
jngibbon
fa9e0c7d54 Update chatNotificationSettings in chat info page 2021-07-02 23:47:30 +02:00
jngibbon
8bd4ff9102 Manually include translation updates from #427 2021-06-09 08:55:11 +02:00
jngibbon
2ffe9ae885 Remove some unused code/comments and a few empty lines 2021-06-09 08:55:11 +02:00
jngibbon
fbf8671012 Re-enable translations "lost" by settings reorganization 2021-06-09 08:55:11 +02:00
jngibbon
0aba35d9bd Implement Settings Accordion
fixes #344
2021-06-09 08:55:11 +02:00
jngibbon
a2b05fc227 fix qml type warning
… I created myself in df1f20cb (oops)
2021-06-09 08:55:11 +02:00
Slava Monich
a1859c0333 Switch to generic booster
That seems to fix a mysterious aarch64 crash with some animated
stickers.
2021-06-09 08:53:36 +02:00
Sebastian Wolf
ded3735973
Merge pull request #426 from arustg/patch-17
Update harbour-fernschreiber-ru.ts
2021-05-31 22:42:33 +02:00
Sebastian Wolf
612ff05983
Merge pull request #425 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2021-05-31 22:40:45 +02:00
Sebastian Wolf
056b8b9aac
Merge pull request #424 from atlochowski/patch-13
Update harbour-fernschreiber-pl.ts
2021-05-31 22:39:35 +02:00
Sebastian Wolf
1eab3a0627
Merge pull request #423 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2021-05-31 22:38:27 +02:00
Rustem Abzalov
36947e8470
Update harbour-fernschreiber-ru.ts 2021-05-31 20:12:25 +03:00
okruhliak
5a2f250e39 Update harbour-fernschreiber-sk.ts 2021-05-30 22:07:22 +02:00
Atlochowski
d3a4c50e76
Update harbour-fernschreiber-pl.ts 2021-05-30 21:08:19 +02:00
Åke Engelbrektson
db8e1d6ba8
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2021-05-30 21:03:45 +02:00
Sebastian Wolf
d668c8666e
Prepare release 0.9 2021-05-30 19:16:03 +02:00
Sebastian Wolf
d2df4ddf16
Enhance location attachment information (accuracy, address) 2021-05-27 23:48:50 +02:00
Sebastian Wolf
78e578c5e2
Merge pull request #422 from Wunderfitz/feature/wait-for-link-handler
Delay link/notification handling until chatListCreated
2021-05-26 22:45:59 +02:00
jngibbon
df1f20cb30 Delay link/notification handling until chatListCreated
(hopefully) fixes #412
2021-05-26 22:21:53 +02:00
Sebastian Wolf
91ec56898a
Merge branch 'master' of github.com:Wunderfitz/harbour-fernschreiber 2021-05-26 21:53:43 +02:00
Sebastian Wolf
136e4328d7
A chat might become visible after first discovery 2021-05-26 21:53:10 +02:00
Sebastian Wolf
bd9df7b10c
Merge pull request #421 from jgibbon/master
Add Github action
2021-05-26 21:03:51 +02:00
jngibbon
942e51a36f Add Github action 2021-05-26 20:19:09 +02:00
Sebastian Wolf
b719d18a70
Remove debug statement from previous testing... 2021-05-26 15:16:05 +02:00
Sebastian Wolf
b350487fb9
Adjust scroll position handling when chat window height changes, fixes #418 2021-05-25 23:15:43 +02:00
Sebastian Wolf
388ea83e45
Disable auto-scroll when app is in background, fixes 410 2021-05-25 22:48:25 +02:00
Sebastian Wolf
29719c0764
Update message index map after message exchange, fixes #407 2021-05-25 22:28:48 +02:00
Sebastian Wolf
9339a2cdf5
Merge pull request #419 from Wunderfitz/feature/stickerpicker-listview
Speed up Sticker Picker
2021-05-24 21:47:14 +02:00
Sebastian Wolf
98307c59e4
New sticker picker: layout optimizations 2021-05-24 21:41:21 +02:00
Sebastian Wolf
3262835f1d
Merge branch 'master' into feature/stickerpicker-listview 2021-05-24 21:04:10 +02:00
Sebastian Wolf
b9917059ed
Merge pull request #420 from Wunderfitz/lottie-update
Lottie update & Option to display stickers as emojis
2021-05-24 20:52:12 +02:00
Sebastian Wolf
a9c0ae8f37
Remove TDLib provides section from spec (once again) 2021-05-24 20:40:08 +02:00
jngibbon
5c69119b38 Remove unnecessary maximumLineCount 2021-05-23 22:13:16 +02:00
jngibbon
9fded3d3a8 Speed up Sticker Picker 2021-05-22 21:19:59 +02:00
Sebastian Wolf
109913c9ca
Introduce possibility to display stickers as emojis 2021-05-20 23:41:55 +02:00
Sebastian Wolf
cefa87767a
Update README, add German translation for #417 2021-05-20 22:11:52 +02:00
Sebastian Wolf
2adb002c28
Merge pull request #417 from santhoshmanikandan/autofoucus-textarea#322
Add focus text on entering chat
2021-05-20 22:03:23 +02:00
Santhosh Manikandan S
f559b4892b Add focus text on entering chat option
Added an option to focus the text area when entering a chat has
been added and the same is exposed under Settings page.
2021-05-13 00:02:26 +05:30
Sebastian Wolf
c26ce4cd6b
Merge pull request #416 from santhoshmanikandan/bug-fix#406
Fix new line in TextInput when using Send By Enter
2021-05-06 20:53:49 +02:00
Santhosh Manikandan S
93da676e6b Fix new line in TextInput when using Send By Enter
Fixed the issue by removing the enter that gets added to textarea
when enter is pressed using string operations.
2021-05-04 20:16:42 +05:30
Sebastian Wolf
23d4ac6c02
Merge pull request #411 from monich/hide-drawer
Handle more cases when the drawer should be closed
2021-04-05 11:02:41 +02:00
Slava Monich
9a2b2b0ca8 Handle more cases when the drawer should be closed
1. Other item is pressed
2. Any item is long-pressed, including the selected one
3. ChatPage is getting deactivated
2021-03-27 01:27:47 +02:00
Sebastian Wolf
4f65b3b666
Patch release 0.8.2 2021-03-02 23:11:02 +01:00
Sebastian Wolf
f240845927
Prepare aarch64 build 2021-03-02 22:46:08 +01:00
Sebastian Wolf
ee4fd1bdbb
Merge branch 'master' of github.com:Wunderfitz/harbour-fernschreiber 2021-03-02 22:36:37 +01:00
Sebastian Wolf
72f3fddcb2
Merge pull request #405 from atlochowski/patch-12
Update harbour-fernschreiber-pl.ts
2021-03-02 22:34:37 +01:00
Atlochowski
bc2e92a285
Update harbour-fernschreiber-pl.ts 2021-03-02 08:35:16 +01:00
Sebastian Wolf
d3556d293d
Prepare patch release 0.8.1 2021-03-01 21:43:45 +01:00
Sebastian Wolf
2eb75929aa
Merge pull request #404 from arustg/patch-16
Update harbour-fernschreiber-ru.ts
2021-03-01 21:03:42 +01:00
Rustem Abzalov
d76d9bea0f
Update harbour-fernschreiber-ru.ts 2021-02-27 21:21:37 +03:00
Sebastian Wolf
edd9db186b
Contact registered message becoming simple 2021-02-25 21:38:55 +01:00
Sebastian Wolf
747e35dd4b
Merge pull request #402 from jorm1s/patch-9
Update harbour-fernschreiber-fi.ts
2021-02-25 21:27:23 +01:00
Sebastian Wolf
8fabca8a0d
Merge pull request #401 from monich/authorizationState
Don't show Active Sessions button when not authenticated
2021-02-25 21:25:35 +01:00
Sebastian Wolf
2540b4e28c
Merge pull request #400 from GNUuser/patch-32
Update harbour-fernschreiber-es.ts
2021-02-25 19:32:08 +01:00
Miikka Jormanainen
c8fe64e83f Update harbour-fernschreiber-fi.ts 2021-02-25 18:58:09 +02:00
Slava Monich
545b716f24 Don't show Active Sessions button when not authenticated
Also, expose authorizationState as TDLibWrapper property.
2021-02-25 02:59:51 +02:00
carlosgonz
330c642f00
Update harbour-fernschreiber-es.ts 2021-02-24 12:22:58 -05:00
carlosgonz
0e64c620dc
Update harbour-fernschreiber-es.ts 2021-02-24 12:18:57 -05:00
carlosgonz
b422c15b86
Update harbour-fernschreiber-es.ts 2021-02-24 12:17:22 -05:00
Sebastian Wolf
694cc0f453
Merge pull request #399 from GNUuser/patch-31
Updated spanish transtation
2021-02-23 22:17:36 +01:00
carlosgonz
dd55c91000
Updated spanish transtation
Can you explain me which  feature is Ln: 1705
2021-02-23 16:13:38 -05:00
Sebastian Wolf
612026f937
Merge pull request #398 from arustg/patch-15
Update harbour-fernschreiber-ru.ts
2021-02-23 20:30:05 +01:00
Sebastian Wolf
b8e512855d
Merge pull request #397 from atlochowski/patch-11
Update harbour-fernschreiber-pl.ts
2021-02-23 20:29:28 +01:00
Atlochowski
4e9eb36e40
Update harbour-fernschreiber-pl.ts 2021-02-23 19:55:38 +01:00
Atlochowski
43478b646e
Update harbour-fernschreiber-pl.ts 2021-02-23 10:51:07 +01:00
Atlochowski
d3f721fcce
Update harbour-fernschreiber-pl.ts 2021-02-23 10:49:36 +01:00
Rustem Abzalov
8647c24f23
Update harbour-fernschreiber-ru.ts 2021-02-23 12:26:24 +03:00
Atlochowski
88160cb621
Update harbour-fernschreiber-pl.ts 2021-02-23 09:13:03 +01:00
Sebastian Wolf
5e8584af79
Prepare release 0.8, including changelog 2021-02-22 21:46:55 +01:00
Sebastian Wolf
eae863172d
Merge pull request #396 from arustg/patch-14
Update harbour-fernschreiber-ru.ts
2021-02-22 20:51:08 +01:00
Sebastian Wolf
57267dc944
Merge pull request #395 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2021-02-22 20:49:55 +01:00
Sebastian Wolf
02f69c2a2c
Merge pull request #394 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2021-02-22 20:49:22 +01:00
Rustem Abzalov
d1043bc97e
Update harbour-fernschreiber-ru.ts 2021-02-22 12:24:28 +03:00
okruhliak
f0d1111c47 Update harbour-fernschreiber-sk.ts 2021-02-22 09:21:22 +01:00
okruhliak
e6471f3d54 Update harbour-fernschreiber-sk.ts 2021-02-22 09:13:09 +01:00
Åke Engelbrektson
f33f70d723
Update harbour-fernschreiber-sv.ts
add missing translation
2021-02-22 08:35:50 +01:00
Sebastian Wolf
3957ec27e4
Merge pull request #390 from monich/drawer
Don't have on-screen keyboard and drawer visible simultaneously
2021-02-21 23:35:13 +01:00
Slava Monich
4050f41ce2 Don't have on-screen keyboard and drawer visible simultaneously
Also, removed unnecessary closeRequested() signal.
2021-02-22 00:27:36 +02:00
Sebastian Wolf
15f33145a7
Merge pull request #393 from dashinfantry/patch-27
Update harbour-fernschreiber-zh_CN.ts
2021-02-21 22:36:07 +01:00
Sebastian Wolf
cca6e41369
Merge pull request #392 from GNUuser/patch-30
Update harbour-fernschreiber-es.ts
2021-02-21 22:34:12 +01:00
Sebastian Wolf
2ff093717c
Merge pull request #391 from monich/stickers
Fix MessageSticker highlight and click behavior
2021-02-21 22:31:37 +01:00
dashinfantry
525eba5be1
Update harbour-fernschreiber-zh_CN.ts 2021-02-21 23:09:36 +08:00
carlosgonz
426bf9c05e
Update harbour-fernschreiber-es.ts 2021-02-20 19:28:20 -05:00
Slava Monich
3497f9d0fc Fixed MessageSticker highlight and click behavior
The highlighted property has been moved to MessageContentBase and
the mouse area was stealing mouse events from the parent.
2021-02-21 01:47:05 +02:00
Sebastian Wolf
6ebe312651
Merge pull request #389 from arustg/patch-13
Update harbour-fernschreiber-ru.ts
2021-02-20 22:14:52 +01:00
Sebastian Wolf
45aaf50c40
Merge pull request #388 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2021-02-20 22:14:24 +01:00
Rustem Abzalov
6be12bd31c
Update harbour-fernschreiber-ru.ts 2021-02-20 11:56:40 +03:00
Åke Engelbrektson
bae1777df6
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2021-02-20 07:14:22 +01:00
Sebastian Wolf
250a83347c
Merge pull request #387 from eson57/patch-2
Update harbour-fernschreiber-sv.ts
2021-02-20 00:16:41 +01:00
Sebastian Wolf
aef9fd8391
Support for managing Telegram sessions 2021-02-20 00:14:43 +01:00
Åke Engelbrektson
cb16582722
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2021-02-19 16:52:31 +01:00
Sebastian Wolf
b2f2ee5453
Disable contacts sync on Sailfish OS 4.x 2021-02-18 22:48:01 +01:00
Sebastian Wolf
9715e03971
Merge pull request #382 from Wunderfitz/messageOptionsDrawer
Introduce message options drawer
2021-02-18 20:34:00 +01:00
Sebastian Wolf
aae881cec8
Merge pull request #386 from iamnomeutente/master
Update harbour-fernschreiber-it.ts
2021-02-18 20:30:20 +01:00
iamnomeutente
366b24bf02 Update harbour-fernschreiber-it.ts 2021-02-18 17:10:06 +01:00
Sebastian Wolf
58f6a26bff
Merge pull request #385 from dashinfantry/patch-25
Update harbour-fernschreiber-zh_CN.ts
2021-02-17 23:52:47 +01:00
Sebastian Wolf
1a409407c9
Add 'Forward Message' to options drawer, fix SFOS 4.0.1 bug 2021-02-17 23:48:08 +01:00
dashinfantry
4669d17cea
Update harbour-fernschreiber-zh_CN.ts 2021-02-17 16:32:06 +08:00
Sebastian Wolf
8ae148ec90
Merge remote-tracking branch 'origin/master' into messageOptionsDrawer 2021-02-16 21:55:04 +01:00
Sebastian Wolf
a432e91996
Trigger mark-as-read (almost) immediately after opening chat 2021-02-16 21:48:14 +01:00
Sebastian Wolf
7ae58badd9
Fix highlighted behavior after options drawer was opened 2021-02-16 21:36:29 +01:00
Sebastian Wolf
e2e78713df
Drawer: Replace Flickable/Column with SilicaListView 2021-02-16 20:54:48 +01:00
Sebastian Wolf
a734690d0d
Merge branch 'messageOptionsDrawer' of github.com:Wunderfitz/harbour-fernschreiber into messageOptionsDrawer 2021-02-16 18:52:13 +01:00
Sebastian Wolf
9688c09002
Define dock height/width more transparently 2021-02-16 18:51:50 +01:00
Sebastian Wolf
01cdb18b46
Reference chatPage correctly in new delete action
Co-authored-by: jgibbon <99138+jgibbon@users.noreply.github.com>
2021-02-16 18:47:12 +01:00
Sebastian Wolf
063d782001
Merge pull request #384 from arustg/patch-12
Update harbour-fernschreiber-ru.ts
2021-02-15 23:15:58 +01:00
Rustem Abzalov
7369eaec4f
Update harbour-fernschreiber-ru.ts 2021-02-16 01:02:11 +03:00
Sebastian Wolf
532b35e9f3
Adjust changed localization files 2021-02-15 21:57:44 +01:00
Sebastian Wolf
27f33d1883
Merge pull request #381 from arustg/patch-10
Update harbour-fernschreiber-ru.ts
2021-02-15 21:56:56 +01:00
Rustem Abzalov
2e3fbb0fd3
Update harbour-fernschreiber-ru.ts 2021-02-15 23:51:26 +03:00
Sebastian Wolf
1dcaaa7169
Merge remote-tracking branch 'origin/master' into messageOptionsDrawer 2021-02-15 21:27:50 +01:00
Sebastian Wolf
0a8f507f6f
Message option drawer: This crazy idea really seems to work... 2021-02-15 21:20:38 +01:00
Sebastian Wolf
41e9efb8e5
Merge pull request #376 from Wunderfitz/newStickerSets
Redesign sticker picker, show sticker sets, install/remove sticker sets
2021-02-15 21:19:13 +01:00
Sebastian Wolf
034069320f
Merge pull request #380 from arustg/patch-9
Update harbour-fernschreiber-ru.ts
2021-02-15 21:18:08 +01:00
Sebastian Wolf
fe6e1db689
Merge pull request #378 from iamnomeutente/master
Update harbour-fernschreiber-it.ts
2021-02-15 21:16:09 +01:00
Sebastian Wolf
20fd359fb1
Merge pull request #377 from GNUuser/patch-29
Update harbour-fernschreiber-es.ts
2021-02-15 21:15:32 +01:00
Rustem Abzalov
8cdfb8a30b
Update harbour-fernschreiber-ru.ts 2021-02-15 22:00:02 +03:00
iamnomeutente
1f832d6511 Update harbour-fernschreiber-it.ts 2021-02-15 18:29:25 +01:00
carlosgonz
3210bab4e3
Update harbour-fernschreiber-es.ts 2021-02-14 19:47:28 -05:00
Sebastian Wolf
d9991cce79
Try something for the too large context menu 2021-02-14 21:57:48 +01:00
Sebastian Wolf
22c30f334d
Merge remote-tracking branch 'origin/master' into newStickerSets 2021-02-14 12:56:28 +01:00
Sebastian Wolf
9ebe33a419
Relax rule for hiding private chats 2021-02-14 12:55:54 +01:00
Sebastian Wolf
257fc749ee
Merge remote-tracking branch 'origin/master' into newStickerSets 2021-02-14 11:57:36 +01:00
Sebastian Wolf
352789f79d
Disable auto-scroll after context menu interaction, fixes #139 2021-02-14 11:51:26 +01:00
Sebastian Wolf
ade5cb34fb
Stickers can now also be send as replies 2021-02-14 10:46:29 +01:00
Sebastian Wolf
42a697591d
Show first sticker in picker if no set thumbnail is available 2021-02-14 10:17:26 +01:00
Sebastian Wolf
23fd7cb7cd
Potentially fix another bug 2021-02-13 20:01:42 +01:00
Sebastian Wolf
8fc499582b
Redesign sticker picker, fix one sticker reload bug 2021-02-13 18:55:49 +01:00
Sebastian Wolf
ef9a999994
Properly add/remove sticker sets (almost ;)) 2021-02-13 00:34:01 +01:00
Sebastian Wolf
94aee83936
Showing new sticker sets 2021-02-11 23:39:56 +01:00
Sebastian Wolf
4435828ff7
Sort text replacements better to avoid overlaps, fixes #334 2021-02-10 22:02:53 +01:00
Sebastian Wolf
fc2c53f840
Show in-reply-to message if it was deleted, fixes #374 2021-02-09 22:35:19 +01:00
Sebastian Wolf
0a4fd6be93
Enable storage optimizer per default 2021-02-09 21:55:45 +01:00
Sebastian Wolf
3575e1674c
[SFOS4] Documents app can't access our files anymore, always use Downloads 2021-02-08 22:49:34 +01:00
Sebastian Wolf
5de6ea4f11
Next release will be 0.7.1 (patches/fixes only) 2021-02-07 18:28:07 +01:00
Sebastian Wolf
b0ed187bb4
Merge branch 'master' of github.com:Wunderfitz/harbour-fernschreiber 2021-02-07 18:24:26 +01:00
Sebastian Wolf
08b004f6a5
Hide empty private chats from list 2021-02-07 18:23:59 +01:00
Sebastian Wolf
40edb2069a
Merge pull request #373 from monich/break
Hardcode line break in "unread messages"
2021-02-07 18:22:35 +01:00
Sebastian Wolf
98eaf699bc
Merge pull request #370 from monich/muted
Use different badge colors for muted chats
2021-02-07 18:21:50 +01:00
Slava Monich
64ef10a10c Hardcode line break in "unread messages"
To avoid cover layout change when number of unread messages goes 9 => 10
2021-02-07 16:01:25 +02:00
Sebastian Wolf
9280236743
Merge pull request #372 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2021-02-07 14:49:52 +01:00
okruhliak
bcff42c449 Update harbour-fernschreiber-sk.ts 2021-02-07 11:26:00 +01:00
Slava Monich
8f345174ab Use different badge colors for muted chats 2021-02-07 02:29:50 +02:00
Sebastian Wolf
4cf12cfd15
Merge pull request #369 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2021-02-06 22:05:23 +01:00
Åke Engelbrektson
472d07721f
Update harbour-fernschreiber-sv.ts
Minor correction!
2021-02-06 07:42:48 +01:00
Sebastian Wolf
f6e21b6428
Use default landscape format for settings page 2021-02-05 22:49:56 +01:00
Sebastian Wolf
cbee948e09
Avoid display errors on chat information page for multi-line infos 2021-02-05 22:16:26 +01:00
Sebastian Wolf
4b0f8f3166
Mark new messages as read when automatically scrolling down 2021-02-05 21:57:22 +01:00
Sebastian Wolf
35ed5879bc
Merge pull request #368 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2021-02-05 21:25:43 +01:00
Sebastian Wolf
42f55db3f4
Merge pull request #367 from monich/ru
Updated Russian translation
2021-02-05 21:24:45 +01:00
Åke Engelbrektson
58e0ecce1f
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2021-02-05 10:11:00 +01:00
Slava Monich
0b7c6cd75f Updated Russian translation 2021-02-05 03:15:40 +02:00
Sebastian Wolf
299ab8d7a0
Adjust settings page layout 2021-02-04 23:46:06 +01:00
Sebastian Wolf
2d5798e182
Prepare changelog for 0.7 2021-02-04 23:04:56 +01:00
Sebastian Wolf
aa2d47cb11
Merge pull request #366 from jorm1s/patch-8
Update harbour-fernschreiber-fi.ts
2021-02-04 21:46:10 +01:00
Sebastian Wolf
1dee780d0b
Merge pull request #365 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2021-02-04 21:41:53 +01:00
Sebastian Wolf
530afe2714
Merge pull request #364 from dashinfantry/patch-24
Update harbour-fernschreiber-zh_CN.ts
2021-02-04 21:40:14 +01:00
Miikka Jormanainen
0948d32fe1 Update harbour-fernschreiber-fi.ts 2021-02-04 19:59:46 +02:00
dashinfantry
1f4b9ce082
Update harbour-fernschreiber-zh_CN.ts 2021-02-04 22:21:18 +08:00
okruhliak
84752798f3 Update harbour-fernschreiber-sk.ts 2021-02-04 15:07:32 +01:00
dashinfantry
66dc268efc
Update harbour-fernschreiber-zh_CN.ts 2021-02-04 14:26:35 +08:00
Sebastian Wolf
40fea18a46
Try to fix video page (without refactoring ;)) 2021-02-03 23:12:24 +01:00
Sebastian Wolf
31ee65fc98
Introduce configurable delay for marking messages as read 2021-02-03 22:16:22 +01:00
Sebastian Wolf
ca94e7971b
Merge privacy settings 2021-02-03 21:54:46 +01:00
Sebastian Wolf
8d6d88de5f
Update logo, original by @iamnomeutente, adjustments by @monich 2021-02-03 21:48:59 +01:00
Sebastian Wolf
1a3767e599
Merge pull request #359 from Wunderfitz/chatIndexHandling
Improved chat message index handling
2021-02-03 21:42:01 +01:00
Sebastian Wolf
c12c9e2ac6
Merge pull request #362 from dashinfantry/patch-23
Update harbour-fernschreiber-zh_CN.ts
2021-02-03 19:55:08 +01:00
Sebastian Wolf
a6e0c9b3ab
Merge pull request #361 from jgibbon/bugfix/extraContent_click
Fix click signal forwarding for extra content items
2021-02-03 19:54:08 +01:00
dashinfantry
9219495081
Update harbour-fernschreiber-zh_CN.ts 2021-02-03 21:52:22 +08:00
John Gibbon
42f3cfb155 Fix click signal forwarding for extra content items 2021-02-03 11:47:03 +01:00
Sebastian Wolf
8b8756cbdb
Increase release number for test build 2021-02-02 23:24:25 +01:00
Sebastian Wolf
978ee5a334
Handle last read sent message better, might address #301 2021-02-02 23:19:02 +01:00
Sebastian Wolf
fba20712b2
Merge pull request #358 from iamnomeutente/master
Update harbour-fernschreiber-it.ts
2021-02-02 22:07:02 +01:00
Sebastian Wolf
3176c3dc8c
Chat page: Adjust initial scroll position, honoring #243 2021-02-02 22:05:24 +01:00
Sebastian Wolf
c6f0a41559
Fix default value if no own message was found 2021-02-02 20:27:42 +01:00
iamnomeutente
910e261ad9 Update harbour-fernschreiber-it.ts 2021-02-02 18:46:47 +01:00
Sebastian Wolf
fd6ebae7c0
Better chat index handling, see #235 & #271 2021-02-02 00:42:42 +01:00
Sebastian Wolf
2eec79dd31
Merge pull request #357 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2021-02-01 20:39:06 +01:00
Sebastian Wolf
0e401fd18b
Merge pull request #354 from monich/image-path
Explicitly set image-path notification hint to empty string
2021-02-01 20:38:25 +01:00
okruhliak
add07be887 Update harbour-fernschreiber-sk.ts 2021-02-01 16:47:34 +01:00
Slava Monich
903cb02919 Explicitly set image-path notification hint to empty string
To stop home screen from using app icon as a default.
2021-02-01 02:04:35 +02:00
Sebastian Wolf
55ce5c36d8
Merge pull request #353 from monich/view_count
Update message view counts in real time
2021-01-31 22:42:18 +01:00
Sebastian Wolf
c7392af6b9
Merge pull request #352 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2021-01-31 22:08:56 +01:00
Sebastian Wolf
453ce8f4ac
README: Include logo update 2021-01-31 22:05:11 +01:00
Sebastian Wolf
ced51ade64
Update logo, original by @iamnomeutente, adjustments by @monich 2021-01-31 22:03:06 +01:00
Sebastian Wolf
18cf86b75c
Adjust explanatory text and update English & German localization 2021-01-31 22:00:35 +01:00
Slava Monich
b1c4311990 Update message view counts in real time 2021-01-31 22:10:45 +02:00
okruhliak
2a229dae3b Update harbour-fernschreiber-sk.ts 2021-01-31 21:01:34 +01:00
okruhliak
f7ba5ebe45 Update harbour-fernschreiber-sk.ts 2021-01-31 20:57:51 +01:00
Sebastian Wolf
444649c3b2
Merge pull request #349 from monich/sound
Made notification sound configurable
2021-01-31 20:41:34 +01:00
Sebastian Wolf
3bc97f2739
Cover: Smaller font sizes, enable numerus forms, fixes #350 2021-01-31 20:23:59 +01:00
Slava Monich
3433ec547e Made notification sound configurable 2021-01-31 20:46:26 +02:00
okruhliak
02d1583d6c Update harbour-fernschreiber-sk.ts 2021-01-31 16:18:08 +01:00
okruhliak
ec6461ba42 Update harbour-fernschreiber-sk.ts 2021-01-31 14:37:00 +01:00
Sebastian Wolf
f65a62d61f
Merge pull request #348 from monich/superlowres
Don't display default and superlowres images at the same time
2021-01-31 12:20:39 +01:00
Sebastian Wolf
fcb7dae081
Merge pull request #347 from monich/contextmenu
Don't allow ContextMenu to be wider than its ComboBox
2021-01-31 12:16:28 +01:00
Sebastian Wolf
7077a22be8
Merge pull request #346 from okruhliak/master
Update harbour-fernschreiber-sk.ts
2021-01-31 12:13:57 +01:00
Sebastian Wolf
f82c2683e2
Merge pull request #345 from dashinfantry/patch-22
Update harbour-fernschreiber-zh_CN.ts
2021-01-31 12:13:15 +01:00
dashinfantry
199fc0d60c
Update harbour-fernschreiber-zh_CN.ts 2021-01-31 11:37:40 +08:00
Slava Monich
5d1af66c38 Don't display default and superlowres images at the same time 2021-01-30 05:35:45 +02:00
Slava Monich
f7bcec0456 Don't allow ContextMenu to be wider than its ComboBox
That looks ridiculous.
2021-01-30 01:16:13 +02:00
Sebastian Wolf
af4a1f3a69
Chat list: Don't cache user information (wasn't set properly anyway) 2021-01-29 22:53:28 +01:00
okruhliak
27e8b234fc Update harbour-fernschreiber-sk.ts 2021-01-29 20:18:39 +01:00
okruhliak
8634e730ff Update harbour-fernschreiber-sk.ts 2021-01-29 20:12:33 +01:00
okruhliak
0955a9fda0 Update harbour-fernschreiber-sk.ts 2021-01-29 20:07:08 +01:00
okruhliak
84a5c19e27 Update harbour-fernschreiber-sk.ts 2021-01-29 16:59:31 +01:00
dashinfantry
431eacad78
Update harbour-fernschreiber-zh_CN.ts 2021-01-29 05:24:23 +08:00
Sebastian Wolf
fe4d3c79d7
Merge pull request #340 from Wunderfitz/userPreferences
User profile and privacy settings
2021-01-28 21:58:56 +01:00
Sebastian Wolf
d30d80abd8
Merge pull request #343 from okruhliak/master
Updated harbour-fernschreiber-sk.ts
2021-01-28 21:38:01 +01:00
okruhliak
f7e057833b Updated harbour-fernschreiber-sk.ts 2021-01-28 17:47:47 +01:00
Sebastian Wolf
c0a6c2566a
Merge pull request #342 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2021-01-27 22:16:45 +01:00
Sebastian Wolf
ed41f96ed2
Merge pull request #341 from dashinfantry/patch-21
Update harbour-fernschreiber-zh_CN.ts
2021-01-27 22:11:45 +01:00
Åke Engelbrektson
48cf0c00f7
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2021-01-27 22:07:35 +01:00
okruhliak
460b1485a8
Updated harbour-fernschreiber-sk.ts 2021-01-27 22:03:18 +01:00
okruhliak
d8b42b9d87
Updated harbour-fernschreiber-sk.ts 2021-01-27 22:03:10 +01:00
okruhliak
ed57ef6d5d
Update harbour-fernschreiber-sk.ts 2021-01-27 22:02:21 +01:00
okruhliak
d5c1122052
Update harbour-fernschreiber-sk.ts 2021-01-27 22:02:12 +01:00
okruhliak
5ac48cd171
Update harbour-fernschreiber-sk.ts 2021-01-27 22:01:57 +01:00
Sebastian Wolf
436b21ab51
Update Slovak translation 2021-01-27 21:59:18 +01:00
dashinfantry
742baebe94
Update harbour-fernschreiber-zh_CN.ts 2021-01-27 17:26:08 +08:00
Sebastian Wolf
e2b6d25aa8
Show picture placeholder in settings, handle first upload properly 2021-01-26 23:54:37 +01:00
Sebastian Wolf
fb225390c6
Merge remote-tracking branch 'origin/master' into userPreferences 2021-01-26 23:29:45 +01:00
Sebastian Wolf
9b820dad2b
Add and delete profile pictures 2021-01-26 23:26:40 +01:00
Sebastian Wolf
5e6cd6f4b4
Prepare adding/deleting profile pictures 2021-01-25 23:39:54 +01:00
Sebastian Wolf
1b653eb554
Translation files for user preferences 2021-01-25 21:29:40 +01:00
Sebastian Wolf
bcbbf5616d
Fix two bugs in user privacy settings 2021-01-25 20:52:40 +01:00
John Gibbon
1701562c42 Add sk translation + build it. 2021-01-25 10:22:13 +01:00
okruhliak
91b86c6566 Update harbour-fernschreiber-sk.ts 2021-01-25 10:17:03 +01:00
okruhliak
607b13cf7f Update README.md 2021-01-25 10:17:03 +01:00
okruhliak
a28475c6a0 Create harbour-fernschreiber-sk.ts
First translation Fernschreiber to Slovak
2021-01-25 10:17:03 +01:00
Miikka Jormanainen
17bdadea16 Update harbour-fernschreiber-fi.ts 2021-01-25 09:17:25 +01:00
Sebastian Wolf
9a5db3e83f
Next steps towards supporting user preferences 2021-01-24 23:46:30 +01:00
Sebastian Wolf
ac8a2f549b
Merge pull request #333 from arustg/patch-8
Update harbour-fernschreiber-ru.ts
2021-01-24 13:11:50 +01:00
Rustem Abzalov
595c7734eb
Update harbour-fernschreiber-ru.ts 2021-01-23 10:44:12 +03:00
Sebastian Wolf
2fcacef6d4
Merge remote-tracking branch 'origin/master' into userPreferences 2021-01-22 22:14:25 +01:00
Sebastian Wolf
e7c075edb7
Video notes text on chat list was missing 2021-01-22 22:05:32 +01:00
Sebastian Wolf
12280c7321
Merge pull request #332 from jgibbon/feature/poll-changes
Poll changes
2021-01-22 21:23:45 +01:00
John Gibbon
2ed3bacd98 Implement viewing Quiz explanations
TDLib 1.7 feature
2021-01-22 11:14:55 +01:00
John Gibbon
e6e63622e5 Implement sending Quiz explanations
TDLib 1.7 feature
2021-01-22 11:13:51 +01:00
John Gibbon
c5640ec13f Fix poll results page
fixes #331
2021-01-22 10:02:32 +01:00
Sebastian Wolf
741ad78602
Sometimes images don't come with a proper width/height 2021-01-21 23:33:54 +01:00
Sebastian Wolf
bd53d1435d
Merge pull request #330 from jgibbon/feature/messageContent_photo
Feature/message content photo
2021-01-21 23:13:00 +01:00
John Gibbon
6eaea9221b Add highlight to location images 2021-01-20 00:57:31 +01:00
Sebastian Wolf
f0d14bc440
Change username, prepare privacy setting rules 2021-01-19 23:58:58 +01:00
John Gibbon
844498ee46 Remove unused TDLibFile from image page 2021-01-19 22:52:49 +01:00
John Gibbon
b6468ec924 Remove useless output 2021-01-19 22:43:12 +01:00
John Gibbon
117e7e9310 Use biggest image for detail page 2021-01-19 22:42:53 +01:00
John Gibbon
bba5bf94b8 Use TDLibImage in location content 2021-01-19 22:41:06 +01:00
John Gibbon
710254dc0f Use TDLibPhoto in inline query result 2021-01-19 22:40:28 +01:00
John Gibbon
5a720c1a00 Use TDLibPhoto in MessagePhoto 2021-01-19 22:39:46 +01:00
John Gibbon
b61bf2a46b Implement TDLibPhoto qml element 2021-01-19 22:39:05 +01:00
John Gibbon
290114f3f2 Extract minithumbnail into own Loader 2021-01-19 22:38:34 +01:00
Sebastian Wolf
3a59ec54ba
Merge remote-tracking branch 'origin/master' into userPreferences 2021-01-19 22:31:30 +01:00
Sebastian Wolf
066037f1a5
Notifications: Avoid popup in current chat, play sound (again), fixes #233 2021-01-19 21:48:28 +01:00
Sebastian Wolf
390f6eaca6
Merge pull request #329 from jgibbon/feature/channel-layout
Change channel messages layout
2021-01-19 19:36:02 +01:00
Sebastian Wolf
52be4901db
Merge pull request #328 from jgibbon/feature/chat-indicators
Visually optimize chat list
2021-01-19 19:28:15 +01:00
John Gibbon
a48260a998 Change pin icon head 2021-01-19 09:14:05 +01:00
John Gibbon
fa232a4cbf Change channel messages layout
- make text wider
- add view count
2021-01-19 00:12:59 +01:00
Sebastian Wolf
4e6d012a7d
Start with personal profile settings 2021-01-19 00:02:37 +01:00
John Gibbon
4cf5f661c4 Visually optimize chat list
- work on pin icon (mirrored/pointier)
- align profile thumbnail the same as the text fallback
- harmonize list delegate (and profile thumbnail) height (no more variable height)
- minimally reduce column spacing
2021-01-18 22:55:15 +01:00
Sebastian Wolf
32f884e547
Merge pull request #327 from jgibbon/feature/messageContent_fileinfo_items
Add TDLibImage/TDLibThumbnail; rework Audio/VoiceNote/Document
2021-01-18 19:21:23 +01:00
Sebastian Wolf
c992c3ed00
Merge pull request #326 from monich/landscape-settings
Optimize settings page for landscape layout
2021-01-18 18:45:48 +01:00
John Gibbon
703931a5a1 Add TDLibImage/TDLibThumbnail; rework Audio/VoiceNote/Document
also, again, a quick Location fix before its real turn
2021-01-17 22:38:20 +01:00
jgibbon
55fefdd96d
Merge pull request #323 from jgibbon/feature/messageContent_refactor
Message content refactor
2021-01-17 22:08:08 +01:00
jgibbon
077c928b27
Merge pull request #325 from monich/warning-fix
Fix QML runtime warning in ChatInformationTabItemMembersGroups
2021-01-17 21:48:30 +01:00
dashinfantry
eef961926f Update harbour-fernschreiber-zh_CN.ts 2021-01-17 21:24:32 +01:00
dashinfantry
3b26021221 Update harbour-fernschreiber-zh_CN.ts 2021-01-17 21:24:32 +01:00
Slava Monich
e6ca239acd Optimize settings page for landscape layout 2021-01-17 22:05:30 +02:00
Slava Monich
14f73dbb48 Fixed QML runtime warning in ChatInformationTabItemMembersGroups
ChatInformationTabItemMembersGroups.qml:75:28: Unable to assign QString to QVariantMap
2021-01-17 21:37:47 +02:00
Sebastian Wolf
9bf9a1a1eb
Tweak emoji size a bit... 2021-01-17 11:56:56 +01:00
John Gibbon
74ccbccf45 Rebuild Translations
(and mark some ES unfinished)
2021-01-16 00:40:02 +01:00
John Gibbon
921f58e8c0 Fix Game Layout 2021-01-16 00:40:02 +01:00
John Gibbon
935bcaeb85 Fix Locations 2021-01-16 00:40:02 +01:00
John Gibbon
e6748dbc18 Adapt to changed path 2021-01-16 00:40:02 +01:00
John Gibbon
aa7a1f28ce Use dedicated Files for message content 2021-01-16 00:40:02 +01:00
John Gibbon
282ab1d2b9 Prepare dedicated QML files for all supported message content types 2021-01-16 00:40:02 +01:00
Sebastian Wolf
ab879f8db3
Translations and cleanup after latest changes 2021-01-15 23:08:58 +01:00
Sebastian Wolf
875028c7b0
Merge pull request #319 from jgibbon/feature/channel_simple_message_username
Display chat title in SimpleMessageDelegate if sender is chat
2021-01-15 22:55:41 +01:00
Sebastian Wolf
2459aa70e0
Merge branch 'master' into feature/channel_simple_message_username 2021-01-15 22:41:37 +01:00
Sebastian Wolf
94b33d1d92
Merge pull request #311 from santhoshmanikandan/logout
Log out and log in as a different user
2021-01-15 22:29:01 +01:00
Sebastian Wolf
063df54e94
Merge branch 'master' into logout 2021-01-15 22:00:04 +01:00
Sebastian Wolf
74d584fdcc
Merge pull request #318 from monich/can_get_members
Show channel members on chat information page
2021-01-15 21:52:06 +01:00
Sebastian Wolf
907a4580fc
Merge pull request #307 from jgibbon/feature/inline_queries
Implement inline queries (among others)
2021-01-15 21:49:26 +01:00
John Gibbon
c9ab840b97 Make inline bot name check case insensitive 2021-01-15 21:37:55 +01:00
John Gibbon
954986edee Merge branch 'master' into feature/inline_queries 2021-01-15 08:18:12 +01:00
Santhosh Manikandan S
f471ef2683 1. Merged "Loading Chat Lists" and "Logging Out" BusyIndicator to one
2. Use QT in-built API to get the application storage location rather than
hardcoding the path when clearing tdlib files
2021-01-14 23:07:09 +05:30
John Gibbon
919eacdec7 Clean up GamePreview thumbnail properties 2021-01-14 10:40:02 +01:00
John Gibbon
2f11b6c67c Display Chat title in SimpleMessageDelegate if sender is chat
On overviewPage I found it sufficient being empty, since the title is directly above it, anyway. But in the channel itself it looked wrong without a user name.

The name link doesn't have a href – this would only be useful for edge cases like someone sharing a "changed title" message to another chat. I did not consider that relevant enough.
2021-01-14 10:22:23 +01:00
Slava Monich
08a95d4f07 Show channel members on chat information page
if can_get_members in supergroupFullInfo is true.
2021-01-14 01:38:23 +02:00
Sebastian Wolf
3abdbe6a58
Merge pull request #316 from monich/image
Handle message data change in ImagePreview
2021-01-13 22:49:41 +01:00
Sebastian Wolf
3b6a1843c0
Merge pull request #317 from arustg/patch-7
Update harbour-fernschreiber-ru.ts
2021-01-13 22:35:52 +01:00
Rustem Abzalov
3fb66af0fe
Update harbour-fernschreiber-ru.ts 2021-01-13 20:17:05 +03:00
John Gibbon
4fbd55c184 Merge remote-tracking branch 'upstream/master' into feature/inline_queries 2021-01-13 09:50:30 +01:00
Slava Monich
a4dbc26e70 Handle message data change in ImagePreview
And use TDLibFile to load image in ImagePage
2021-01-13 04:19:16 +02:00
dashinfantry
769ae8af21 Update harbour-fernschreiber-zh_CN.ts 2021-01-12 21:28:20 +01:00
John Gibbon
5f1befe443 Merge remote-tracking branch 'upstream/master' into feature/inline_queries
# Conflicts:
#	translations/harbour-fernschreiber-ru.ts
#	translations/harbour-fernschreiber-zh_CN.ts
2021-01-12 20:46:53 +01:00
carlosgonz
72d6ceb259 Update harbour-fernschreiber-es.ts 2021-01-12 20:00:53 +01:00
Rustem Abzalov
ce2bd3260b Update harbour-fernschreiber-ru.ts 2021-01-12 20:00:44 +01:00
dashinfantry
08d2832198 Update harbour-fernschreiber-zh_CN.ts 2021-01-12 20:00:30 +01:00
dashinfantry
c0270b9908 Update harbour-fernschreiber-zh_CN.ts 2021-01-12 20:00:30 +01:00
John Gibbon
37ad9441f2 Inline query cleanup; Fix ChatPage scrolling issue 2021-01-12 19:39:15 +01:00
Santhosh Manikandan S
de9112cc8a Reordered translation text 2021-01-12 22:32:44 +05:30
Santhosh Manikandan S
8786bdbf5e Fixed merge issue of traslation files which duplicated "Connecting to Network.." string 2021-01-12 22:29:43 +05:30
Santhosh Manikandan S
756a96e92c Merge branch 'master' into logout 2021-01-11 23:57:31 +05:30
Santhosh Manikandan S
62a17f722f Added option to logout and login 2021-01-11 23:35:55 +05:30
John Gibbon
8607f1000b Only show inline query element mode if username is valid 2021-01-11 10:22:54 +01:00
John Gibbon
c031e56284 Reduce invalid inline requests + error messages 2021-01-11 10:19:00 +01:00
John Gibbon
fe6ba8ac0d Prevent int overflow for chat id by using string :( 2021-01-11 09:50:36 +01:00
John Gibbon
3473fb995c Fix imports for photo inline result 2021-01-11 09:28:07 +01:00
John Gibbon
1ce981c147 Implement inline queries (among others) 2021-01-10 22:20:05 +01:00
Sebastian Wolf
be2f08553b
Add button to copy document to Downloads folder 2021-01-10 20:26:29 +01:00
Sebastian Wolf
d4935a4968
Introduce online-only mode as non-default option, fixes #77 2021-01-10 13:35:34 +01:00
Sebastian Wolf
90a3d8ad2b
Merge pull request #303 from monich/thumbnail-press
Apply press effect to profile thumbnail in chat list?
2021-01-10 10:35:59 +01:00
Slava Monich
b70a4427e0 Apply press effect to profile thumbnail in chat list 2021-01-10 04:25:02 +02:00
Sebastian Wolf
1523d62362
Chat List: Muted icon now always visible, fixes #156 2021-01-09 22:25:58 +01:00
Sebastian Wolf
a06f384e1a
Merge pull request #300 from iamnomeutente/master
Update harbour-fernschreiber-it.ts
2021-01-08 23:35:39 +01:00
Sebastian Wolf
233515474f
Merge pull request #297 from monich/fileId
Update webPage photo id when message gets updated
2021-01-08 23:33:52 +01:00
Sebastian Wolf
b9933dd706
Merge pull request #296 from monich/retry
Don't retry downloading too often
2021-01-08 22:34:30 +01:00
Sebastian Wolf
2798a0f56a
Merge pull request #295 from monich/searchModeActive
Initialize ChatModel::searchModeActive
2021-01-08 22:22:09 +01:00
iamnomeutente
01ffec0a0c Update harbour-fernschreiber-it.ts 2021-01-08 20:19:00 +01:00
Slava Monich
92655b4417 Update webPage photo id when message gets updated 2021-01-08 05:36:34 +02:00
Slava Monich
4f275a5405 Don't retry downloading too often 2021-01-08 04:12:16 +02:00
Slava Monich
7f9166d1ae Initialize ChatModel::searchModeActive 2021-01-08 01:03:22 +02:00
Sebastian Wolf
e3370bf73e
Add chat list menu option to pin/unpin chat 2021-01-07 22:47:42 +01:00
Sebastian Wolf
7453c60052
Add sourceSize to pin icon 2021-01-07 21:52:26 +01:00
Sebastian Wolf
5e52b47fc0
Merge pull request #294 from atlochowski/patch-10
Update harbour-fernschreiber-pl.ts
2021-01-07 21:06:59 +01:00
Sebastian Wolf
da36f4966e
Merge pull request #293 from arustg/patch-5
Update harbour-fernschreiber-ru.ts
2021-01-07 21:05:27 +01:00
Sebastian Wolf
62295b55fc
Merge pull request #292 from GNUuser/patch-27
Update harbour-fernschreiber-es.ts
2021-01-07 21:03:37 +01:00
A
d64ab2f7ea
Update harbour-fernschreiber-pl.ts 2021-01-07 10:32:35 +01:00
Sebastian Wolf
f104ac0cab
Changelog for 0.6.1 2021-01-06 21:50:53 +01:00
Rustem Abzalov
a30dd23ed8
Update harbour-fernschreiber-ru.ts 2021-01-06 23:31:11 +03:00
carlosgonz
68f60f5b8a
Update harbour-fernschreiber-es.ts 2021-01-06 15:23:11 -05:00
Sebastian Wolf
fb161f3d24
Take chat list type into account when receiving new chat positions 2021-01-06 16:54:23 +01:00
Sebastian Wolf
de51bbffc0
Harmonize chat attribute bubble sizes 2021-01-06 16:07:23 +01:00
Sebastian Wolf
cc65c694c0
Use highlightBackgroundColor consistently for all chat attributes 2021-01-06 14:01:55 +01:00
Sebastian Wolf
348b26d6ec
Add build requirements to Qt Multimedia and Positioning 2021-01-06 13:29:51 +01:00
Sebastian Wolf
5ca6dd1ca0
Use dedicated pin icon, thanks to @jgibbon 2021-01-06 13:24:37 +01:00
Sebastian Wolf
03ea136905
Merge pull request #289 from jorm1s/patch-6
Update harbour-fernschreiber-fi.ts
2021-01-06 13:01:27 +01:00
Sebastian Wolf
7e6c871261
Make VideoPage work again 2021-01-06 12:58:16 +01:00
Sebastian Wolf
9299205379
Show pinned chat icon in list 2021-01-06 10:42:12 +01:00
Miikka Jormanainen
3334f487d7 Update harbour-fernschreiber-fi.ts 2021-01-06 11:06:28 +02:00
Sebastian Wolf
26c1677993
Merge pull request #288 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2021-01-06 09:39:04 +01:00
Åke Engelbrektson
07798dae02
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2021-01-06 08:09:04 +01:00
Sebastian Wolf
18371912e5
Release 0.6 - it's a wrap! 2021-01-05 21:47:51 +01:00
Sebastian Wolf
49223f98f6
Merge pull request #283 from dashinfantry/patch-16
Update harbour-fernschreiber-zh_CN.ts
2021-01-05 16:04:17 +01:00
Sebastian Wolf
3250ebae5c
Mark new Russian translation strings as finished 2021-01-05 15:46:00 +01:00
Sebastian Wolf
b789a3a066
Merge pull request #282 from arustg/patch-4
One more update harbour-fernschreiber-ru.ts
2021-01-05 15:44:25 +01:00
dashinfantry
c4fd46212e
Update harbour-fernschreiber-zh_CN.ts 2021-01-05 22:21:16 +08:00
Rustem Abzalov
39bbd111fa
Update harbour-fernschreiber-ru.ts 2021-01-05 17:17:26 +03:00
Sebastian Wolf
bdd6a8df27
Yet another 0.6 test build 2021-01-05 14:00:59 +01:00
Sebastian Wolf
d8b0ff6fca
Merge branch 'master' of github.com:Wunderfitz/harbour-fernschreiber 2021-01-05 14:00:16 +01:00
Sebastian Wolf
158419f15f
Merge pull request #281 from GNUuser/patch-26
Update harbour-fernschreiber-es.ts
2021-01-05 14:00:04 +01:00
Sebastian Wolf
d34538a868
Mark some Russian translations as finished 2021-01-05 13:59:44 +01:00
Sebastian Wolf
001b7bbef0
It's 2021, not 2020 anymore... 2021-01-05 13:38:23 +01:00
carlosgonz
58f154b3c3
Update harbour-fernschreiber-es.ts 2021-01-05 07:36:15 -05:00
Sebastian Wolf
1e89a4357a
Changelog for 0.6 2021-01-05 13:34:02 +01:00
Sebastian Wolf
dffe4d708f
Merge pull request #280 from dashinfantry/patch-15
Update harbour-fernschreiber-zh_CN.ts
2021-01-05 12:57:19 +01:00
Sebastian Wolf
2f5376b864
Merge pull request #279 from arustg/patch-3
Tiny update harbour-fernschreiber-ru.ts
2021-01-05 12:56:22 +01:00
Sebastian Wolf
ea0984bc7f
Merge pull request #278 from arustg/patch-2
Update harbour-fernschreiber-ru.ts
2021-01-05 12:55:29 +01:00
dashinfantry
b7738e7fb8
Update harbour-fernschreiber-zh_CN.ts 2021-01-05 19:54:57 +08:00
dashinfantry
e2b99bafaf
Update harbour-fernschreiber-zh_CN.ts 2021-01-05 19:51:52 +08:00
Rustem Abzalov
3eb63a6dd7
Update harbour-fernschreiber-ru.ts 2021-01-05 14:14:19 +03:00
Rustem Abzalov
258c533ff0
Update harbour-fernschreiber-ru.ts 2021-01-05 13:31:46 +03:00
Sebastian Wolf
4bcb96055b
Increase release number for next test build 2021-01-04 22:19:49 +01:00
Sebastian Wolf
71283df6c5
Merge pull request #268 from Wunderfitz/voicenotes
Support sending voice notes and locations
2021-01-04 22:04:19 +01:00
Sebastian Wolf
e0b94a0487
One dedicated file per voice note recording 2021-01-04 22:03:04 +01:00
John Gibbon
81ffb53062
Use OpacityRamp to hint at scrollable attachmentsOptions 2021-01-04 20:50:20 +01:00
Sebastian Wolf
9314c56e5b
Merge pull request #270 from atlochowski/patch-9
Update harbour-fernschreiber-pl.ts
2021-01-04 19:46:40 +01:00
A
4dc05e2e10
Update harbour-fernschreiber-pl.ts 2021-01-03 22:53:20 +01:00
Sebastian Wolf
b6f77bbf8b
Merge pull request #269 from dashinfantry/patch-14
Update harbour-fernschreiber-zh_CN.ts
2021-01-03 19:21:41 +01:00
dashinfantry
e623635be5
Update harbour-fernschreiber-zh_CN.ts 2021-01-03 22:52:00 +08:00
dashinfantry
62805434f1
Update harbour-fernschreiber-zh_CN.ts 2021-01-03 22:48:06 +08:00
Sebastian Wolf
2b634471dc
Sending locations seems to work as well... 2021-01-03 01:22:30 +01:00
Sebastian Wolf
53441b5554
Merge pull request #266 from jgibbon/feature/filtered-chat-placeholder
Add a different placeholder text for no filtered chats
2021-01-02 21:13:10 +01:00
John Gibbon
cc0cc94dc5 Add a different placeholder text for no filtered chats 2021-01-02 20:46:24 +01:00
Sebastian Wolf
7c615b5cff
Merge remote-tracking branch 'origin/master' into voicenotes 2021-01-02 20:33:03 +01:00
Sebastian Wolf
fd7de65c19
Merge pull request #263 from Wunderfitz/lean-overview
Remove magnifying glass, reorganize title bar, introduce interaction hint
2021-01-02 20:30:04 +01:00
John Gibbon
54602d8a6c
Remove obsolete Row; Enable animations; Change Hint 2021-01-02 20:15:25 +01:00
Sebastian Wolf
e620c41e17
Merge branch 'master' of github.com:Wunderfitz/harbour-fernschreiber 2021-01-02 20:07:23 +01:00
Sebastian Wolf
f26820ef75
AboutPage: React properly if no profile pic is defined, fixes #264 2021-01-02 20:06:53 +01:00
Sebastian Wolf
1b83fddfe6
No strange debug logging ;) 2021-01-02 19:57:36 +01:00
Sebastian Wolf
be404d0e55
Put attachment row in a Flickable 2021-01-02 18:08:33 +01:00
Sebastian Wolf
5213084fb1
Sending voice notes seems to work... 2021-01-02 17:22:09 +01:00
Sebastian Wolf
473c603451
Reorganize title bar, introduce interaction hint 2021-01-02 16:10:01 +01:00
Sebastian Wolf
21810b05aa
Merge pull request #261 from jgibbon/bugfix/fix_some_warnings
Bugfix/fix some warnings
2021-01-02 14:17:57 +01:00
Sebastian Wolf
9453ce4ec2
Merge pull request #260 from GNUuser/patch-24
Update harbour-fernschreiber-es.ts
2021-01-02 14:12:26 +01:00
Sebastian Wolf
d38f56b9fe
Recording Vorbis files works & connected to UI 2021-01-02 00:15:25 +01:00
John Gibbon
d3eac32216 Remove warnings about Slider maximumValue not > minimumValue 2021-01-01 21:13:14 +01:00
John Gibbon
04f6c14e86 Remove warning if no draft_message is present 2021-01-01 21:06:38 +01:00
carlosgonz
732af7c334
Update harbour-fernschreiber-es.ts 2021-01-01 10:38:36 -05:00
Sebastian Wolf
fd0d188030
Merge remote-tracking branch 'origin/master' into voicenotes 2021-01-01 15:03:22 +01:00
Sebastian Wolf
2c078307dc
Add singular/plural forms to search chats page 2021-01-01 14:39:22 +01:00
Sebastian Wolf
53e0400e0c
Merge pull request #259 from jgibbon/feature/focus-textarea-on-send-option
Implement TextArea focus after message send option
2021-01-01 14:18:30 +01:00
Sebastian Wolf
01cc85f817
Merge pull request #258 from GNUuser/patch-23
Update harbour-fernschreiber-es.ts
2021-01-01 14:03:10 +01:00
Sebastian Wolf
f1b14f41ae
Merge pull request #257 from monich/badge-opacity
Apply opacity to picture and badge as a group
2021-01-01 14:01:19 +01:00
John Gibbon
42398eee96 Implement TextArea focus after message send option
fixes #149
2021-01-01 01:34:11 +01:00
carlosgonz
c3f5fee378
Update harbour-fernschreiber-es.ts 2020-12-31 15:00:32 -05:00
Sebastian Wolf
1e4455482c
Only draft message if allowed (last commit in 2020 :D) 2020-12-31 19:27:44 +01:00
Sebastian Wolf
9662df3c74
Start with voice notes 2020-12-31 19:12:50 +01:00
Slava Monich
f9a824ca2c Apply opacity to picture and badge as a group
It matters when page is being dimmed
2020-12-31 17:30:55 +02:00
Sebastian Wolf
a8ad2a6a22
Merge pull request #256 from eson57/patch-1
Update harbour-fernschreiber-sv.ts
2020-12-31 13:21:18 +01:00
Sebastian Wolf
d108cb109d
Merge pull request #255 from jgibbon/feature/draft-messages
implement message drafts
2020-12-31 13:17:17 +01:00
Åke Engelbrektson
1e478aa3d5
Update harbour-fernschreiber-sv.ts
Update Swedish translation
2020-12-31 08:04:14 +01:00
John Gibbon
753f322053 implement message drafts 2020-12-31 01:18:14 +01:00
Sebastian Wolf
232049422a
Add 'mark chat as read/unread' feature, fixes #240 2020-12-31 00:19:36 +01:00
Sebastian Wolf
fa0aaf431e
Merge pull request #254 from monich/messageApiCleanup
Message API usage cleanup
2020-12-30 23:07:04 +01:00
Slava Monich
0cb19d833c Message API usage cleanup
1. Pass chat_id where appropriate
2. Pass message_id and chat_id (which are numbers) as numbers
3. Use pre-initialized QStrings more often
4. Don't pass numbers by const reference, it doesn't make sense
5. Removed some redundant const modifiers
2020-12-30 18:20:50 +02:00
Sebastian Wolf
6b731486cb
Merge pull request #253 from monich/stickerPreviewFix
Fixed invalid component reference in StickerPreview
2020-12-30 16:59:46 +01:00
Slava Monich
cd0eace631 Fixed invalid component reference in StickerPreview 2020-12-30 17:46:28 +02:00
Sebastian Wolf
11058bc05a
Chat List: Let a timer do the model change 2020-12-30 16:44:23 +01:00
Sebastian Wolf
e15c171640
Show send message button also if attachments are there, fixes #143 2020-12-30 16:18:50 +01:00
Sebastian Wolf
7dfe7ddc3e
Change message bubble colors for light ambiences, fixes #239 2020-12-30 13:49:57 +01:00
Sebastian Wolf
33878bb480
Merge pull request #250 from Wunderfitz/searching
Fernschreiber learns filtering and searching
2020-12-30 13:09:13 +01:00
Sebastian Wolf
8282c6e8dc
Extended credits in README 2020-12-30 12:50:37 +01:00
Sebastian Wolf
d10b6dc227
Merge pull request #252 from santhoshmanikandan/hiding-send-new-message-button
Implements Remove send new message button when "Send message by enter" is chosen
2020-12-30 12:44:13 +01:00
Santhosh Manikandan S
ba42aa061b Send message button will now be hidden by default if Send message by Enter
option is used

Ref: https://github.com/Wunderfitz/harbour-fernschreiber/issues/143
2020-12-29 23:04:28 +05:30
Sebastian Wolf
b4b1eb4bc0
Merge remote-tracking branch 'origin/master' into searching 2020-12-29 16:33:40 +01:00
Sebastian Wolf
775a31cecb
Implement delete/add chat members properly, fixes #131 2020-12-29 16:32:39 +01:00
Sebastian Wolf
65c3871b4a
Merge pull request #251 from dashinfantry/patch-13
Update harbour-fernschreiber-zh_CN.ts
2020-12-29 11:20:04 +01:00
Sebastian Wolf
283466ae95
Merging should be done right... :/ 2020-12-29 09:12:57 +01:00
dashinfantry
6a51be4806
Update harbour-fernschreiber-zh_CN.ts 2020-12-29 10:03:57 +08:00
Sebastian Wolf
78a71cfbab
Merge remote-tracking branch 'origin/master' into searching 2020-12-28 22:16:59 +01:00
Sebastian Wolf
e6fd5885aa
Force read all mentions in a chat when nothing is unread 2020-12-28 21:57:34 +01:00
Sebastian Wolf
ef1f824cd8
Add download option to audio preview 2020-12-28 21:20:10 +01:00
Sebastian Wolf
2f52a87e2b
Remove debug log for cooldown 2020-12-28 19:40:27 +01:00
Sebastian Wolf
72fd008dfc
Disable some stuff that is not needed in search mode 2020-12-28 17:12:21 +01:00
Sebastian Wolf
225eb76899
Fix crash on incoming message deletions & minor other fixes 2020-12-28 14:35:27 +01:00
Sebastian Wolf
2e970f2003
Search for public chats... 2020-12-27 23:30:25 +01:00
Sebastian Wolf
0f28db0115
Merge remote-tracking branch 'origin/master' into searching 2020-12-27 12:06:54 +01:00
Sebastian Wolf
f7c6f8a399
Merge pull request #249 from jgibbon/feature/basic-bot-interaction
support basic bot messages (reply markup)
2020-12-27 11:34:23 +01:00
Sebastian Wolf
23641b24a1
Proper height for chat page search field 2020-12-27 00:38:20 +01:00
Sebastian Wolf
19a17ed3f3
Now you can search in a chat... 2020-12-27 00:16:25 +01:00
John Gibbon
d0f33969eb support basic bot messages (reply markup)
only inlineKeyboardButtonTypeCallback and inlineKeyboardButtonTypeUrl are implemented.
2020-12-27 00:01:59 +01:00
Sebastian Wolf
461b724d15
Merge latest upstream changes 2020-12-26 16:28:03 +01:00
Sebastian Wolf
13a91fa0e7
Remove pinned message workaround, add more build information 2020-12-26 15:43:10 +01:00
Sebastian Wolf
d619b97ee4
Increase chatListCreatedTimer to 100ms, update translation files 2020-12-26 14:58:10 +01:00
Sebastian Wolf
13f21916f8
Merge pull request #248 from jgibbon/feature/overviewpage-speedup
speed up overview page loading
2020-12-26 14:50:55 +01:00
John Gibbon
653a35500c speed up overview page loading
contributes to #198
2020-12-25 23:22:11 +01:00
Sebastian Wolf
c83fcda617
Merge remote-tracking branch 'origin/master' into searching 2020-12-25 22:40:37 +01:00
Sebastian Wolf
fe0b390a87
TDLib 1.7: Bring back pinned messages (nobody noticed so far?) 2020-12-25 22:38:13 +01:00
Sebastian Wolf
4e680a9a3f
Don't display empty in-reply-to section if message wasn't found 2020-12-25 15:33:53 +01:00
Sebastian Wolf
ff399a524c
Display group information for anonymous messages 2020-12-25 13:50:13 +01:00
Sebastian Wolf
039aca14bf
Always scroll to top at startup 2020-12-25 12:55:46 +01:00
Sebastian Wolf
d0ebbc7170
Bring proper link coloring in web page descriptions back 2020-12-25 12:31:32 +01:00
Sebastian Wolf
4aa8ff3d8a
Merge pull request #247 from monich/emoji-image-pos
Fixed Emoji image positioning in multiline StyledText
2020-12-25 12:27:14 +01:00
Slava Monich
d2d6fac778 Fixed Emoji image positioning in multiline StyledText
Combination of maximumLineCount and TruncationMode.Elide (or Fade)
breaks Emoji image alignment, pushing the image down. Explicitly
truncating the text fixes the problem, at expense of certain runtime
overhead.

Also, toggle full and truncated Web page preview on tap.
2020-12-24 05:45:27 +02:00
Sebastian Wolf
a0a2e6bdca
Merge remote-tracking branch 'origin/master' into searching 2020-12-21 23:33:51 +01:00
Sebastian Wolf
c10819b12e
Merge pull request #246 from monich/placeholderImage
Fixed invalid reference
2020-12-21 23:33:04 +01:00
Sebastian Wolf
fe4b330479
Merge pull request #245 from monich/ampersandRe
Removed unnecessary ampersand replacement
2020-12-21 23:31:43 +01:00
Sebastian Wolf
00287ea89c
Merge pull request #237 from Wunderfitz/tdlib17
Migration to TDLib 1.7
2020-12-21 23:22:52 +01:00
Slava Monich
88b79236e7 Fixed invalid reference 2020-12-21 04:42:40 +02:00
Slava Monich
a2bd181911 Removed unnecessary ampersand replacement 2020-12-21 04:35:35 +02:00
Sebastian Wolf
1317f6532e
Use chat list proxy model only if filtering is active 2020-12-17 09:24:20 +01:00
Sebastian Wolf
87255e123a
Merge remote-tracking branch 'origin/tdlib17' into searching 2020-12-16 23:55:58 +01:00
Sebastian Wolf
45bcc4f33d
Introduce filter capabilities for chat list 2020-12-16 23:32:42 +01:00
Sebastian Wolf
b9502d35ee
Merge pull request #242 from monich/join-by-id
Added  a few items to the Debug page
2020-12-16 20:46:34 +01:00
Slava Monich
25efbb8bc2 Added "Show all chats" switch to the Debug page 2020-12-16 16:04:15 +02:00
Slava Monich
72582c26f4 Added "Join chat by id" to the Debug page 2020-12-16 03:45:32 +02:00
512 changed files with 53166 additions and 7961 deletions

102
.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,102 @@
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
View file

@ -53,3 +53,6 @@ compile_commands.json
# TDLib API Secrets
tdlibsecrets.h
#Convinience scripts
*.sh

View file

@ -1,6 +1,7 @@
# Fernschreiber
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
Sebastian J. Wolf [sebastian@ygriega.de](mailto:sebastian@ygriega.de) and several contributors
@ -10,19 +11,27 @@ Fernschreiber wouldn't be the same without all the people helping in making it b
### 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 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)
- 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)
- 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
- Designed by [Matteo](https://github.com/iamnomeutente)
- Designed by [Matteo](https://github.com/iamnomeutente), adjustments by [Slava Monich](https://github.com/monich)
### Translations
- Chinese: [dashinfantry](https://github.com/dashinfantry)
- 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)
- Italian: [Matteo](https://github.com/iamnomeutente)
- Polish: [atlochowski](https://github.com/atlochowski)
- 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)
- Swedish: [Åke Engelbrektson](https://github.com/eson57)
@ -30,6 +39,7 @@ Fernschreiber wouldn't be the same without all the people helping in making it b
Licensed under GNU GPLv3
## 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:
```
@ -42,15 +52,39 @@ 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).
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`.
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`.
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
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.
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
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. :)
@ -62,5 +96,6 @@ 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).
- 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).
- 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!

Binary file not shown.

3288
doc/emojis.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -4,3 +4,8 @@ X-Nemo-Application-Type=silica-qt5
Icon=harbour-fernschreiber
Exec=harbour-fernschreiber
Name=Fernschreiber
[X-Sailjail]
Permissions=Audio;Documents;Downloads;Internet;Location;MediaIndexing;Microphone;Music;Pictures;PublicDir;RemovableMedia;UserDirs;Videos
OrganizationName=de.ygriega
ApplicationName=fernschreiber

View file

@ -16,12 +16,13 @@ CONFIG += sailfishapp sailfishapp_i18n
PKGCONFIG += nemonotifications-qt5 zlib
QT += core dbus sql
QT += core dbus sql multimedia positioning
DEFINES += QT_STATICPLUGIN
SOURCES += src/harbour-fernschreiber.cpp \
src/appsettings.cpp \
src/chatpermissionfiltermodel.cpp \
src/chatlistmodel.cpp \
src/chatmodel.cpp \
src/contactsmodel.cpp \
@ -38,37 +39,89 @@ SOURCES += src/harbour-fernschreiber.cpp \
src/tdlibfile.cpp \
src/tdlibreceiver.cpp \
src/tdlibwrapper.cpp \
src/textfiltermodel.cpp \
src/tgsplugin.cpp
DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/AudioPreview.qml \
qml/components/BackgroundImage.qml \
qml/components/ChatListViewItem.qml \
qml/components/ContactSync.qml \
qml/components/DocumentPreview.qml \
qml/components/GamePreview.qml \
qml/components/ImagePreview.qml \
qml/components/InformationEditArea.qml \
qml/components/InformationTextItem.qml \
qml/components/InReplyToRow.qml \
qml/components/InlineQuery.qml \
qml/components/LocationPreview.qml \
qml/components/MessageListViewItem.qml \
qml/components/MessageListViewItemSimple.qml \
qml/components/MessageOverlayFlickable.qml \
qml/components/MessageViaLabel.qml \
qml/components/MultilineEmojiLabel.qml \
qml/components/PinnedMessageItem.qml \
qml/components/PollPreview.qml \
qml/components/PressEffect.qml \
qml/components/ProfilePictureList.qml \
qml/components/ReplyMarkupButtons.qml \
qml/components/StickerPicker.qml \
qml/components/PhotoTextsListItem.qml \
qml/components/WebPagePreview.qml \
qml/components/chatInformationPage/ChatInformationEditArea.qml \
qml/components/StickerSetOverlay.qml \
qml/components/TDLibImage.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/ChatInformationProfilePicture.qml \
qml/components/chatInformationPage/ChatInformationProfilePictureList.qml \
qml/components/chatInformationPage/ChatInformationTabItemBase.qml \
qml/components/chatInformationPage/ChatInformationTabItemDebug.qml \
qml/components/chatInformationPage/ChatInformationTabItemMembersGroups.qml \
qml/components/chatInformationPage/ChatInformationTabItemSettings.qml \
qml/components/chatInformationPage/ChatInformationTabView.qml \
qml/components/chatInformationPage/ChatInformationTextItem.qml \
qml/components/chatInformationPage/EditGroupChatPermissionsColumn.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/functions.js \
qml/pages/ChatInformationPage.qml \
@ -82,11 +135,11 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/pages/AboutPage.qml \
qml/pages/PollCreationPage.qml \
qml/pages/PollResultsPage.qml \
qml/pages/SearchChatsPage.qml \
qml/pages/SettingsPage.qml \
qml/pages/VideoPage.qml \
rpm/harbour-fernschreiber.changes \
rpm/harbour-fernschreiber.spec \
rpm/harbour-fernschreiber.yaml \
translations/*.ts \
harbour-fernschreiber.desktop
@ -95,19 +148,28 @@ SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172 256x256
TRANSLATIONS += translations/harbour-fernschreiber-de.ts \
translations/harbour-fernschreiber-es.ts \
translations/harbour-fernschreiber-fi.ts \
translations/harbour-fernschreiber-fr.ts \
translations/harbour-fernschreiber-hu.ts \
translations/harbour-fernschreiber-it.ts \
translations/harbour-fernschreiber-pl.ts \
translations/harbour-fernschreiber-ru.ts \
translations/harbour-fernschreiber-sv.ts \
translations/harbour-fernschreiber-sk.ts \
translations/harbour-fernschreiber-en.ts \
translations/harbour-fernschreiber-zh_CN.ts
contains(QT_ARCH, arm) {
equals(QT_ARCH, arm) {
message(Building ARM)
TARGET_ARCHITECTURE = armv7hl
} else {
}
equals(QT_ARCH, i386) {
message(Building i486)
TARGET_ARCHITECTURE = i486
}
equals(QT_ARCH, arm64){
message(Building aarch64)
TARGET_ARCHITECTURE = aarch64
}
INCLUDEPATH += $$PWD/tdlib/include
DEPENDPATH += $$PWD/tdlib/include
@ -149,6 +211,7 @@ INSTALLS += telegram 86.png 108.png 128.png 172.png 256.png \
HEADERS += \
src/appsettings.h \
src/chatpermissionfiltermodel.h \
src/chatlistmodel.h \
src/chatmodel.h \
src/contactsmodel.h \
@ -168,6 +231,7 @@ HEADERS += \
src/tdlibreceiver.h \
src/tdlibsecrets.h \
src/tdlibwrapper.h \
src/textfiltermodel.h \
src/tgsplugin.h
# https://github.com/Samsung/rlottie.git

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View file

@ -5,60 +5,241 @@
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"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="114.667"
height="114.667"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg19">
<metadata
id="metadata23">
<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="defs9">
<linearGradient
id="linearGradient4649">
<stop
style="stop-color:#979797;stop-opacity:1"
xml:space="preserve"
width="114.66667"
height="114.66667"
viewBox="0 0 114.66667 114.66667"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="background-black.svg"
id="svg60"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1015"
id="namedview62"
showgrid="false"
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"
id="stop4645" />
<stop
style="stop-color:#797979;stop-opacity:1"
id="stop5" /><stop
style="stop-opacity:1;stop-color:#898989;opacity:1"
offset="0.959184"
id="stop7" /><stop
style="stop-opacity:1;stop-color:#898989;opacity:1"
offset="1"
id="stop4647" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient4649"
id="linearGradient4651"
x1="0.81535178"
y1="0.99882859"
x2="71.914337"
y2="74.307625"
gradientUnits="userSpaceOnUse" />
</defs>
<path
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"
transform="matrix(1.33333,0,0,-1.33333,0,114.667)"
id="path11"
style="fill:url(#linearGradient4651);fill-opacity:1" />
<path
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"
id="path13"
style="fill:#444444;fill-opacity:1" />
<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="path15"
style="fill:#000000;fill-opacity:1" />
<path
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="path17"
style="fill:#000000;fill-opacity:1" />
</svg>
id="stop9" /></linearGradient><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-529"><stop
style="stop-opacity:1;stop-color:#727272;opacity:1"
offset="0"
id="stop74" /><stop
style="stop-opacity:1;stop-color:#898989;opacity:1"
offset="0.959184"
id="stop76" /><stop
style="stop-opacity:1;stop-color:#898989;opacity:1"
offset="1"
id="stop78" /></linearGradient><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-529-824"><stop
style="stop-opacity:1;stop-color:#8d8d8d;opacity:1"
offset="0"
id="stop290" /><stop
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: 4.9 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -5,60 +5,224 @@
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"
xmlns:xlink="http://www.w3.org/1999/xlink"
id="svg19"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
height="114.667"
width="114.667">
<metadata
id="metadata23">
<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="defs9">
<linearGradient
id="linearGradient4649">
<stop
id="stop4645"
offset="0"
style="stop-color:#686868;stop-opacity:1" />
<stop
id="stop4647"
offset="1"
style="stop-color:#868686;stop-opacity:1" />
</linearGradient>
<linearGradient
xml:space="preserve"
width="114.66667"
height="114.66667"
viewBox="0 0 114.66667 114.66667"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="background-white.svg"
id="svg60"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1015"
id="namedview62"
showgrid="false"
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
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="74.307625"
x2="71.914337"
y1="0.99882859"
x1="0.81535178"
id="linearGradient4651"
xlink:href="#linearGradient4649" />
</defs>
<path
style="fill:url(#linearGradient4651);fill-opacity:1"
id="path11"
transform="matrix(1.33333,0,0,-1.33333,0,114.667)"
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" />
<path
style="fill:#bbbbbb;fill-opacity:1"
id="path13"
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" />
<path
style="fill:#f7f7f7;fill-opacity:1"
id="path15"
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" />
<path
style="fill:#fcfcfc;fill-opacity:1"
id="path17"
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" />
</svg>
y2="0"
x2="1"
y1="0"
x1="0"><stop
id="stop5"
offset="0"
style="stop-opacity:1;stop-color:#8d8d8d;opacity:1" /><stop
id="stop7"
offset="0.959184"
style="stop-opacity:1;stop-color:#767676;opacity:1" /><stop
id="stop9"
offset="1"
style="stop-opacity:1;stop-color:#767676;opacity:1" /></linearGradient><linearGradient
id="linearGradient30-529"
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="stop74"
offset="0"
style="stop-opacity:1;stop-color:#8d8d8d;opacity:1" /><stop
id="stop76"
offset="0.959184"
style="stop-opacity:1;stop-color:#767676;opacity:1" /><stop
id="stop78"
offset="1"
style="stop-opacity:1;stop-color:#767676;opacity:1" /></linearGradient></defs><g
id="g67"
transform="matrix(1.3333333,0,0,-1.3333333,0,114.66667)"
inkscape:label="harbour-fernschreiber"
inkscape:groupmode="layer"><g
id="g18"><g
id="g16"
clip-path="url(#clipPath18)"><path
id="path14"
inkscape:connector-curvature="0"
style="fill:url(#linearGradient30-529);stroke:none;opacity:1"
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
id="g20"
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: 4.9 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -1,66 +1,204 @@
<?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"
id="svg19"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
height="114.667"
width="114.667">
<metadata
id="metadata23">
<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="defs9">
xml:space="preserve"
width="114.66667"
height="114.66667"
viewBox="0 0 114.66667 114.66667"
inkscape:version="0.92.4 (unknown)"
sodipodi:docname="harbour-fernschreiber-3.svg">
<defs>
<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
id="a"
spreadMethod="pad"
gradientTransform="rotate(-135 51.755 21.438) scale(102.49707)"
gradientUnits="userSpaceOnUse"
y2="0"
x2="1"
y1="0"
x1="0">
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
id="stop2"
stop-color="#ec7221"
offset="0" />
style="stop-opacity:1;stop-color:#ec7221"
offset="0"
id="stop5" />
<stop
id="stop4"
stop-color="#e7454c"
offset=".959" />
style="stop-opacity:1;stop-color:#e7454c"
offset="0.959184"
id="stop7" />
<stop
id="stop6"
stop-color="#e7454c"
offset="1" />
style="stop-opacity:1;stop-color:#e7454c"
offset="1"
id="stop9" />
</linearGradient>
</defs>
<path
id="path11"
transform="matrix(1.33333 0 0 -1.33333 0 114.667)"
fill="url(#a)"
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" />
<path
id="path13"
fill="#fcba02"
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" />
<path
style="fill:#fffda9"
id="path15"
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" />
<path
style="fill:#fffee3"
id="path17"
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
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);stroke:none"
inkscape:connector-curvature="0"
id="path14" />
</g>
</g>
<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>

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View file

@ -0,0 +1,39 @@
<?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>

After

Width:  |  Height:  |  Size: 2.4 KiB

35
images/icon-s-eye.svg Normal file
View file

@ -0,0 +1,35 @@
<?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>

After

Width:  |  Height:  |  Size: 1.9 KiB

28
images/icon-s-link.svg Normal file
View file

@ -0,0 +1,28 @@
<?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>

After

Width:  |  Height:  |  Size: 4.5 KiB

27
images/icon-s-pin.svg Normal file
View file

@ -0,0 +1,27 @@
<?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=&quot;defs15&quot; /&gt;<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>

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -1,422 +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 "../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)) : "-:-"
}
}
}
}
}

View file

@ -9,54 +9,98 @@ PhotoTextsListItem {
id: listItem
pictureThumbnail {
photoData: photo_small || ({})
highlighted: listItem.highlighted && !listItem.menuOpen
}
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
primaryText.text: title ? Emoji.emojify(title + ( display.notification_settings.mute_for > 0 ? " 🔇" : "" ), Theme.fontSizeMedium) : qsTr("Unknown")
primaryText.text: title ? Emoji.emojify(title, Theme.fontSizeMedium) : qsTr("Unknown")
// last user
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") ) : "" )
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") ) : "" ))
// last message
secondaryText.text: last_message_text ? Emoji.emojify(Functions.enhanceHtmlEntities(last_message_text), Theme.fontSizeExtraSmall) : "<i>" + qsTr("No message in this chat.") + "</i>"
secondaryText.text: previewText ? Emoji.emojify(Functions.enhanceHtmlEntities(previewText), Theme.fontSizeExtraSmall) : "<i>" + qsTr("No message in this chat.") + "</i>"
// message date
tertiaryText.text: ( last_message_date ? ( last_message_date.length === 0 ? "" : Functions.getDateTimeElapsed(last_message_date) + Emoji.emojify(last_message_status, tertiaryText.font.pixelSize) ) : "" )
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) ) : "" )
unreadCount: unread_count
unreadReactionCount: unread_reaction_count
unreadMentionCount: unread_mention_count
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
menu: ContextMenu {
MenuItem {
visible: unread_count > 0
onClicked: {
tdLibWrapper.viewMessage(chat_id, display.last_message.id, true);
}
text: qsTr("Mark all messages as read")
}
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")
}
onPressAndHold: {
contextMenuLoader.active = true;
}
MenuItem {
onClicked: {
if(pageStack.depth > 2) {
pageStack.pop(pageStack.find( function(page){ return(page._depth === 0)} ), PageStackAction.Immediate);
Loader {
id: contextMenuLoader
active: false
asynchronous: true
onStatusChanged: {
if(status === Loader.Ready) {
listItem.menu = item;
listItem.openMenu();
}
}
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")
}
pageStack.push(Qt.resolvedUrl("../pages/ChatInformationPage.qml"), { "chatInformation" : display});
MenuItem {
visible: unread_count === 0 && unread_reaction_count === 0 && unread_mention_count === 0
onClicked: {
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, !is_marked_as_unread);
}
text: is_marked_as_unread ? qsTr("Mark chat as read") : qsTr("Mark chat as unread")
}
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")
}
}
text: model.display.type['@type'] === "chatTypePrivate" ? qsTr("User Info") : qsTr("Group Info")
}
}

View file

@ -0,0 +1,44 @@
/*
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
// }
}

View file

@ -1,111 +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
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);
}
}
}

View file

@ -1,86 +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
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
}
}

View file

@ -31,13 +31,21 @@ Row {
property string myUserId;
property var inReplyToMessage;
property bool editable: false;
property bool inReplyToMessageDeleted: false;
signal clearRequested()
onInReplyToMessageChanged: {
if (inReplyToMessage) {
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.inReplyToMessage.sender.user_id === inReplyToRow.myUserId, false), inReplyToMessageText.font.pixelSize);
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"));
inReplyToMessageText.text = Emoji.emojify(Functions.getMessageText(inReplyToRow.inReplyToMessage, true, inReplyToRow.myUserId, false), inReplyToMessageText.font.pixelSize);
}
}
onInReplyToMessageDeletedChanged: {
if (inReplyToMessageDeleted) {
inReplyToUserText.text = qsTr("Unknown")
inReplyToMessageText.text = "<i>" + qsTr("This message was deleted") + "</i>";
}
}

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2020 Sebastian J. Wolf and other contributors
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber.
@ -16,6 +16,7 @@
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
@ -27,6 +28,7 @@ Column {
property string emptyPlaceholderText
property string text
property bool multiLine
property bool headerLeftAligned
property bool isEditing
property Item editItem: multiLine ? editAreaTextArea : editAreaTextField
@ -41,6 +43,7 @@ Column {
id: editAreaHeader
height: parent.visible && text !== "" ? Theme.itemSizeExtraSmall : 0
x: 0
horizontalAlignment: headerLeftAligned ? Text.AlignLeft : Text.AlignRight
}
Row {
id: editAreaTextRow
@ -50,20 +53,24 @@ Column {
id: editAreaTextArea
visible: editAreaColumn.isEditing && editAreaColumn.multiLine
width: parent.width - editAreaButton.width
textLeftMargin: 0
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: Theme.fontSizeMedium
}
TextField {
id: editAreaTextField
visible: editAreaColumn.isEditing && !editAreaColumn.multiLine
width: parent.width - editAreaButton.width
anchors.verticalCenter: parent.verticalCenter
textLeftMargin: 0
EnterKey.onClicked: {
editAreaColumn.isEditing = false;
editAreaColumn.saveButtonClicked(editAreaColumn.editItem.text);
}
EnterKey.iconSource: editAreaButton.icon.source
font.pixelSize: Theme.fontSizeMedium
}
ChatInformationTextItem {
InformationTextItem {
id: editAreaTextItem
visible: !editAreaColumn.isEditing
anchors.verticalCenter: parent.verticalCenter

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2020 Sebastian J. Wolf and other contributors
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber.
@ -16,11 +16,12 @@
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/twemoji.js" as Emoji
import "../js/functions.js" as Functions
Column {
id: textItem
@ -47,7 +48,7 @@ Column {
id: labelComponent
Label {
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pixelSize: Theme.fontSizeSmall
font.pixelSize: Theme.fontSizeMedium
textFormat: Text.StyledText
color: Theme.primaryColor
text: Emoji.emojify( Functions.replaceUrlsWithLinks(textItem.text).replace(/\n/g, "<br>"), Theme.fontSizeExtraSmall)

View file

@ -0,0 +1,399 @@
/*
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
}
}
}
}
}
}
}

View file

@ -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 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
}
}

View file

@ -18,57 +18,200 @@
*/
import QtQuick 2.6
import Sailfish.Silica 1.0
import "./messageContent"
import "../js/twemoji.js" as Emoji
import "../js/functions.js" as Functions
import "../js/debug.js" as Debug
ListItem {
id: messageListItem
contentHeight: messageBackground.height + Theme.paddingMedium
contentHeight: messageBackground.height + Theme.paddingMedium + ( reactionsColumn.visible ? reactionsColumn.height : 0 )
Behavior on contentHeight { NumberAnimation { duration: 200 } }
property var chatId
property var messageId
property int messageIndex
property int messageViewCount
property var myMessage
property var reactions
property bool canReplyToMessage
readonly property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender.user_id)
readonly property bool isAnonymous: myMessage.sender_id["@type"] === "messageSenderChat"
readonly property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender_id.user_id)
property QtObject precalculatedValues: ListView.view.precalculatedValues
readonly property color textColor: isOwnMessage ? Theme.highlightColor : Theme.primaryColor
readonly property int textAlign: isOwnMessage ? Text.AlignRight : Text.AlignLeft
readonly property int textAlign: Text.AlignLeft
readonly property Page page: precalculatedValues.page
readonly property bool isSelected: messageListItem.precalculatedValues.pageIsSelecting && page.selectedMessages.some(function(existingMessage) {
return existingMessage.id === messageId
});
readonly property bool isOwnMessage: page.myUserId === myMessage.sender.user_id
property string extraContentComponentName
readonly property bool isOwnMessage: page.myUserId === myMessage.sender_id.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 bool hasContentComponent
property bool additionalOptionsOpened
property bool wasNavigatedTo: false
highlighted: (down || isSelected) && !menuOpen
readonly property var additionalItemsModel: (extraContentLoader.item && ("extraContextMenuItems" in extraContentLoader.item)) ?
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
signal replyToMessage()
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 += ( "&nbsp;" + 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: {
if(messageListItem.precalculatedValues.pageIsSelecting) {
if (messageListItem.precalculatedValues.pageIsSelecting) {
page.toggleMessageSelection(myMessage);
} else {
if (messageOptionsDrawer.sourceItem !== messageListItem) {
messageOptionsDrawer.open = false
}
// Allow extra context to react to click
var extraContent = extraContentLoader.item
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)) {
if (extraContent && extraContentLoader.contains(mapToItem(extraContentLoader, mouse.x, mouse.y))) {
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);
}
}
}
onPressAndHold: {
if(messageListItem.precalculatedValues.pageIsSelecting) {
page.selectedMessages = [];
page.state = ""
onDoubleClicked: {
if (messageListItem.chatReactions) {
Debug.log("Using chat reactions")
messageListItem.messageReactions = chatReactions
showItemCompletelyTimer.requestedIndex = index;
showItemCompletelyTimer.start();
} else {
contextMenuLoader.active = true;
Debug.log("Obtaining message reactions")
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
}
}
onPressAndHold: {
if (openMenuOnPressAndHold) {
openContextMenu()
} else {
page.selectedMessages = []
page.state = ""
}
}
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 {
id: contextMenuLoader
active: false
@ -81,53 +224,50 @@ ListItem {
}
sourceComponent: Component {
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 {
visible: messageListItem.canReplyToMessage
onClicked: messageListItem.replyToMessage()
visible: canReplyToMessage
onClicked: replyToMessage()
text: qsTr("Reply to Message")
}
MenuItem {
visible: myMessage.can_be_edited
onClicked: messageListItem.editMessage()
visible: typeof myMessage.can_be_edited !== "undefined" && myMessage.can_be_edited
onClicked: editMessage()
text: qsTr("Edit Message")
}
MenuItem {
onClicked: {
Clipboard.text = Functions.getMessageText(myMessage, true, false, true);
}
text: qsTr("Copy Message to Clipboard")
}
MenuItem {
onClicked: {
page.toggleMessageSelection(myMessage);
}
onClicked: page.toggleMessageSelection(myMessage)
text: qsTr("Select Message")
}
MenuItem {
onClicked: {
tdLibWrapper.pinMessage(page.chatInformation.id, messageId)
}
text: qsTr("Pin Message")
visible: canPinMessages()
visible: showCopyMessageToClipboardMenuItem
onClicked: copyMessageToClipboard()
text: qsTr("Copy Message to Clipboard")
}
MenuItem {
onClicked: {
var chatId = page.chatInformation.id;
var messageId = messageListItem.messageId;
Remorse.itemAction(messageListItem, qsTr("Message deleted"), function() { tdLibWrapper.deleteMessages(chatId, [ messageId]); })
}
visible: showForwardMessageMenuItem
onClicked: forwardMessage()
text: qsTr("Forward Message")
}
MenuItem {
visible: canDeleteMessage && haveSpaceForDeleteMessageMenuItem
onClicked: deleteMessage()
text: qsTr("Delete Message")
visible: myMessage.can_be_deleted_for_all_users || (myMessage.can_be_deleted_only_for_self && myMessage.chat_id === page.myUserId)
}
MenuItem {
visible: (numberOfExtraOptionsOtherThanDeleteMessage > 0) ||
(deleteMessageIsOnlyExtraOption && !haveSpaceForDeleteMessageMenuItem)
onClicked: {
messageOptionsDrawer.myMessage = 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...")
}
}
}
@ -136,44 +276,103 @@ ListItem {
Connections {
target: chatModel
onMessagesReceived: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
}
onMessagesIncrementalUpdate: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
}
onNewMessageReceived: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
}
onUnreadCountUpdated: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
}
onLastReadSentMessageUpdated: {
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);
}
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 {
target: tdLibWrapper
onReceivedMessage: {
if (messageId === myMessage.reply_to_message_id.toString()) {
if (messageId === myMessage.reply_to_message_id) {
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: {
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)
}
}
if (myMessage.reply_to_message_id !== 0) {
tdLibWrapper.getMessage(page.chatInformation.id, myMessage.reply_to_message_id);
onMyMessageChanged: {
Debug.log("[ChatModel] This message was updated, index", messageIndex, ", updating content...");
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;
}
}
@ -183,17 +382,16 @@ ListItem {
repeat: false
running: false
onTriggered: {
if (typeof myMessage.content !== "undefined") {
if (messageListItem.extraContentComponentName !== "") {
extraContentLoader.setSource(
"../components/" +messageListItem.extraContentComponentName +".qml",
{
messageListItem: messageListItem
})
} else {
if (typeof myMessage.content.web_page !== "undefined") { // only in messageText
webPagePreviewLoader.active = true;
}
if (messageListItem.hasContentComponent) {
var type = myMessage.content["@type"];
extraContentLoader.setSource(
"../components/messageContent/" + type.charAt(0).toUpperCase() + type.substring(1) + ".qml",
{
messageListItem: messageListItem
})
} else {
if (typeof myMessage.content.web_page !== "undefined") { // only in messageText
webPagePreviewLoader.active = true;
}
}
}
@ -203,7 +401,10 @@ ListItem {
id: messageTextRow
spacing: Theme.paddingSmall
width: precalculatedValues.entryWidth
anchors.centerIn: parent
anchors.horizontalCenter: Functions.isWidescreen(appWindow) ? undefined : parent.horizontalCenter
anchors.left: Functions.isWidescreen(appWindow) ? parent.left : undefined
y: Theme.paddingSmall
anchors.leftMargin: Functions.isWidescreen(appWindow) ? Theme.paddingMedium : undefined
Loader {
id: profileThumbnailLoader
@ -216,16 +417,16 @@ ListItem {
sourceComponent: Component {
ProfileThumbnail {
id: messagePictureThumbnail
photoData: (typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : ({})
photoData: messageListItem.isAnonymous ? ((typeof page.chatInformation.photo !== "undefined") ? page.chatInformation.photo.small : {}) : ((typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : ({}))
replacementStringHint: userText.text
width: Theme.itemSizeSmall
height: Theme.itemSizeSmall
visible: precalculatedValues.showUserInfo
MouseArea {
anchors.fill: parent
enabled: !messageListItem.precalculatedValues.pageIsSelecting
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
onClicked: {
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id);
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id, "openDirectly");
}
}
}
@ -243,16 +444,16 @@ ListItem {
anchors {
left: parent.left
leftMargin: messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0
leftMargin: page.isPrivateChat ? (messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0) : 0 //левый марджин для собственных сообщений в приватных чатах. В остальных на полную ширину
verticalCenter: parent.verticalCenter
}
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
width: precalculatedValues.backgroundWidth
property bool isUnread: index > chatModel.getLastReadMessageIndex()
color: isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor
property bool isUnread: index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage"
color: Theme.colorScheme === Theme.LightOnDark ? (isOwnMessage ? Theme.highlightBackgroundColor : (isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor)) : (isOwnMessage ? Theme.highlightBackgroundColor : (isUnread ? Theme.backgroundGlowColor : Theme.overlayBackgroundColor))
radius: parent.width / 50
opacity: isUnread ? 0.5 : 0.2
visible: appSettings.showStickersAsImages || myMessage.content['@type'] !== "messageSticker"
visible: appSettings.showStickersAsImages || (myMessage.content['@type'] !== "messageSticker" && myMessage.content['@type'] !== "messageAnimatedEmoji")
Behavior on color { ColorAnimation { duration: 200 } }
Behavior on opacity { FadeAnimation {} }
}
@ -270,7 +471,7 @@ ListItem {
id: userText
width: parent.width
text: messageListItem.isOwnMessage ? qsTr("You") : Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize)
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)
font.pixelSize: Theme.fontSizeExtraSmall
font.weight: Font.ExtraBold
color: messageListItem.textColor
@ -278,23 +479,28 @@ ListItem {
truncationMode: TruncationMode.Fade
textFormat: Text.StyledText
horizontalAlignment: messageListItem.textAlign
visible: precalculatedValues.showUserInfo
visible: messageListItem.isOwnMessage ? false : (precalculatedValues.showUserInfo || myMessage['@type'] === "sponsoredMessage")
MouseArea {
anchors.fill: parent
enabled: !messageListItem.precalculatedValues.pageIsSelecting
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
onClicked: {
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id);
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id, "openDirectly");
}
}
}
MessageViaLabel {
message: myMessage
}
Loader {
id: messageInReplyToLoader
active: myMessage.reply_to_message_id !== 0
active: typeof myMessage.reply_to_message_id !== "undefined" && myMessage.reply_to_message_id !== 0
width: parent.width
// text height ~= 1,28*font.pixelSize
height: active ? precalculatedValues.messageInReplyToHeight : 0
property var inReplyToMessage;
property bool inReplyToMessageDeleted: false;
sourceComponent: Component {
Item {
width: messageInReplyToRow.width
@ -302,14 +508,31 @@ ListItem {
InReplyToRow {
id: messageInReplyToRow
myUserId: page.myUserId
visible: true
layer.enabled: messageInReplyToMouseArea.pressed && !messageListItem.highlighted && !messageListItem.menuOpen
layer.effect: PressEffect { source: messageInReplyToRow }
inReplyToMessage: messageInReplyToLoader.inReplyToMessage
inReplyToMessageDeleted: messageInReplyToLoader.inReplyToMessageDeleted
}
MouseArea {
id: messageInReplyToMouseArea
anchors.fill: parent
onClicked: {
messageOverlayLoader.overlayMessage = messageInReplyToRow.inReplyToMessage;
messageOverlayLoader.active = true;
if (precalculatedValues.pageIsSelecting) {
page.toggleMessageSelection(myMessage)
} 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()
}
}
}
}
@ -329,11 +552,12 @@ ListItem {
width: parent.width
Component.onCompleted: {
if (myMessage.forward_info.origin["@type"] === "messageForwardOriginChannel") {
var originType = myMessage.forward_info.origin["@type"]
if (originType === "messageOriginChannel" || originType === "messageForwardOriginChannel") {
var otherChatInformation = tdLibWrapper.getChat(myMessage.forward_info.origin.chat_id);
forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : {};
forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall);
} else if (myMessage.forward_info.origin["@type"] === "messageForwardOriginUser") {
} else if (originType === "messageOriginUser" || originType === "messageForwardOriginUser") {
var otherUserInformation = tdLibWrapper.getUserInformation(myMessage.forward_info.origin.sender_user_id);
forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : {};
forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall);
@ -379,35 +603,46 @@ ListItem {
Text {
id: messageText
width: parent.width
text: Emoji.emojify(Functions.getMessageText(myMessage, false, messageListItem.isOwnMessage, false), font.pixelSize)
text: Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), Theme.fontSizeMedium)
font.pixelSize: Theme.fontSizeSmall
color: messageListItem.textColor
wrapMode: Text.Wrap
textFormat: Text.StyledText
onLinkActivated: {
Functions.handleLink(link);
var chatCommand = Functions.handleLink(link);
if(chatCommand) {
tdLibWrapper.sendTextMessage(chatInformation.id, chatCommand);
}
}
horizontalAlignment: messageListItem.textAlign
linkColor: Theme.highlightColor
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 {
id: webPagePreviewLoader
active: false
asynchronous: true
width: parent.width
height: typeof myMessage.content.web_page !== "undefined" ? precalculatedValues.webPagePreviewHeight : 0
width: parent.width * getContentWidthMultiplier()
height: (status === Loader.Ready) ? item.implicitHeight : myMessage.content.web_page ? precalculatedValues.webPagePreviewHeight : 0
sourceComponent: Component {
id: webPagePreviewComponent
WebPagePreview {
id: webPagePreview
onImplicitHeightChanged: {
webPagePreviewLoader.height = webPagePreview.implicitHeight;
}
webPageData: myMessage.content.web_page
width: parent.width
highlighted: messageListItem.highlighted
@ -417,9 +652,9 @@ ListItem {
Loader {
id: extraContentLoader
width: parent.width
width: parent.width * getContentWidthMultiplier()
asynchronous: true
height: item ? item.height : (messageListItem.extraContentComponentName !== "" ? chatView.getContentComponentHeight(messageListItem.extraContentComponentName, myMessage.content, width) : 0)
height: item ? item.height : (messageListItem.hasContentComponent ? chatView.getContentComponentHeight(model.content_type, myMessage.content, width) : 0)
}
Binding {
@ -429,6 +664,15 @@ ListItem {
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 {
id: messageDateUpdater
interval: 60000
@ -439,7 +683,6 @@ ListItem {
}
}
Text {
width: parent.width
@ -460,10 +703,85 @@ 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;
}
}
}
}
}
}
}
}

View file

@ -20,12 +20,15 @@ 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
Item {
id: messageListItem
property var myMessage: display
property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender.user_id)
property bool isOwnMessage: chatPage.myUserId === myMessage.sender.user_id
property bool senderIsUser: myMessage.sender_id["@type"] === "messageSenderUser"
property var userInformation: senderIsUser ? tdLibWrapper.getUserInformation(myMessage.sender_id.user_id) : null
property bool isOwnMessage: senderIsUser && chatPage.myUserId === myMessage.sender_id.user_id
property var linkedMessage
height: backgroundRectangle.height + Theme.paddingMedium
Rectangle {
@ -33,7 +36,7 @@ Item {
anchors.centerIn: parent
height: messageText.height + Theme.paddingMedium * 2
width: Math.min(messageText.implicitWidth, messageText.contentWidth) + Theme.paddingMedium * 2
color: Theme.rgba(Theme.secondaryColor, 0.1)
color: Theme.colorScheme === Theme.LightOnDark ? Theme.rgba(Theme.secondaryColor, 0.1) : Theme.rgba(Theme.overlayBackgroundColor, 0.1)
radius: parent.width / 50
}
Text {
@ -43,11 +46,43 @@ Item {
color: Theme.highlightColor
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Theme.fontSizeExtraSmall
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)
property string messageContentText: Functions.getMessageText(messageListItem.myMessage, false, chatPage.myUserId, false)
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
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
onLinkActivated: {
Functions.handleLink(link);
if(link === "linkedmessage" && linkedMessage) {
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);
}
}
}
}
}

View file

@ -18,9 +18,10 @@
*/
import QtQuick 2.6
import Sailfish.Silica 1.0
import "../components"
import "./messageContent"
import "../js/functions.js" as Functions
import "../js/twemoji.js" as Emoji
import "../js/debug.js" as Debug
Flickable {
id: messageOverlayFlickable
@ -31,19 +32,21 @@ Flickable {
property var overlayMessage;
property bool showHeader: true
readonly property var userInformation: tdLibWrapper.getUserInformation(overlayMessage.sender.user_id);
readonly property bool isOwnMessage: tdLibWrapper.getUserInformation().id === overlayMessage.sender.user_id;
readonly property string extraContentComponentName: (typeof overlayMessage.content !== "undefined" && typeof chatView.contentComponentNames[overlayMessage.content['@type']] !== "undefined" )
? chatView.contentComponentNames[overlayMessage.content['@type']] : ""
readonly property var userInformation: tdLibWrapper.getUserInformation(overlayMessage.sender_id.user_id);
readonly property bool isOwnMessage: tdLibWrapper.getUserInformation().id === overlayMessage.sender_id.user_id;
readonly property bool isAnonymous: overlayMessage.sender_id["@type"] === "messageSenderChat"
property bool hasContentComponent: overlayMessage.content && chatView.delegateMessagesContent.indexOf(overlayMessage.content['@type']) > -1
signal requestClose;
function getOriginalAuthor(forwardInformation, fontSize) {
switch (forwardInformation.origin["@type"]) {
case "messageOriginChannel":
case "messageForwardOriginChannel":
var otherChatInformation = tdLibWrapper.getChat(forwardInformation.origin.chat_id);
return Emoji.emojify(otherChatInformation.title, fontSize);
case "messageOriginUser":
case "messageForwardOriginUser":
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender.user_id);
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender_id.user_id);
return Emoji.emojify(Functions.getUserName(otherUserInformation), fontSize);
default:
return Emoji.emojify(forwardInformation.origin.sender_name, fontSize);
@ -60,18 +63,15 @@ Flickable {
repeat: false
running: false
onTriggered: {
if (typeof overlayMessage.content !== "undefined") {
if (messageOverlayFlickable.extraContentComponentName !== "") {
overlayExtraContentLoader.setSource(
"../components/" + messageOverlayFlickable.extraContentComponentName + ".qml",
{
overlayFlickable: messageOverlayFlickable
})
} else {
if (typeof overlayMessage.content.web_page !== "undefined") {
overlayWebPagePreviewLoader.active = true;
}
}
if (messageOverlayFlickable.hasContentComponent) {
var type = overlayMessage.content["@type"];
overlayExtraContentLoader.setSource(
"../components/messageContent/" + type.charAt(0).toUpperCase() + type.substring(1) + ".qml",
{
overlayFlickable: messageOverlayFlickable
})
} else if(overlayMessage.content && overlayMessage.content.web_page) {
overlayWebPagePreviewLoader.active = true;
}
}
}
@ -104,7 +104,7 @@ Flickable {
spacing: Theme.paddingMedium
ProfileThumbnail {
id: overlayMessagePictureThumbnail
photoData: (typeof messageOverlayFlickable.userInformation.profile_photo !== "undefined") ? messageOverlayFlickable.userInformation.profile_photo.small : ({})
photoData: messageOverlayFlickable.isAnonymous ? ((typeof chatPage.chatInformation.photo !== "undefined") ? chatPage.chatInformation.photo.small : {}) : ((typeof messageOverlayFlickable.userInformation.profile_photo !== "undefined") ? messageOverlayFlickable.userInformation.profile_photo.small : ({}))
replacementStringHint: overlayMessageUserText.text
width: Theme.itemSizeLarge
height: Theme.itemSizeLarge
@ -114,7 +114,7 @@ Flickable {
width: parent.width - overlayMessagePictureThumbnail.width
anchors.verticalCenter: parent.verticalCenter
text: messageOverlayFlickable.isOwnMessage ? qsTr("You") : Emoji.emojify(Functions.getUserName(messageOverlayFlickable.userInformation), font.pixelSize)
text: messageOverlayFlickable.isOwnMessage ? qsTr("You") : Emoji.emojify(messageOverlayFlickable.isAnonymous ? chatPage.chatInformation.title : Functions.getUserName(messageOverlayFlickable.userInformation), font.pixelSize)
font.pixelSize: Theme.fontSizeExtraLarge
font.weight: Font.ExtraBold
maximumLineCount: 1
@ -123,6 +123,10 @@ Flickable {
}
}
MessageViaLabel {
message: overlayMessage
}
Text {
id: overlayForwardedInfoText
width: parent.width
@ -138,7 +142,7 @@ Flickable {
Text {
id: overlayMessageText
width: parent.width
text: Emoji.emojify(Functions.getMessageText(overlayMessage, false, messageOverlayFlickable.isOwnMessage, false), font.pixelSize)
text: Emoji.emojify(Functions.getMessageText(overlayMessage, false, tdLibWrapper.getUserInformation().id, false), font.pixelSize)
font.pixelSize: Theme.fontSizeMedium
color: Theme.primaryColor
wrapMode: Text.Wrap
@ -178,6 +182,16 @@ Flickable {
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 {
id: messageDateUpdater
interval: 60000

View file

@ -0,0 +1,49 @@
/*
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
}

View file

@ -0,0 +1,78 @@
/*
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
}
}
}
}
}
}

View file

@ -1,6 +1,7 @@
import QtQuick 2.6
import Sailfish.Silica 1.0
import WerkWolf.Fernschreiber 1.0
import "../js/functions.js" as Functions
ListItem {
id: chatListViewItem
@ -11,150 +12,217 @@ ListItem {
property alias tertiaryText: tertiaryText //usually last message date
property int unreadCount: 0
property int unreadMentionCount: 0
property int unreadReactionCount: 0
property bool isSecret: false
property bool isVerified: false
property bool isMarkedAsUnread: false
property bool isPinned: false
property bool isMuted: false
property alias pictureThumbnail: pictureThumbnail
contentHeight: mainRow.height + separator.height + 2 * Theme.paddingMedium
contentHeight: Theme.itemSizeExtraLarge
contentWidth: parent.width
Column {
id: mainColumn
width: parent.width - ( 2 * Theme.horizontalPageMargin )
spacing: Theme.paddingSmall
ShaderEffectSource {
id: pictureItem
height: Theme.itemSizeLarge
width: height
anchors {
horizontalCenter: parent.horizontalCenter
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 {
id: contentColumn
anchors {
verticalCenter: parent.verticalCenter
left: pictureItem.right
leftMargin: Theme.paddingSmall
right: parent.right
rightMargin: Theme.horizontalPageMargin
}
spacing: Theme.paddingSmall / 2
Row {
id: mainRow
height: contentColumn.height
id: primaryTextRow
spacing: Theme.paddingMedium
Column {
id: pictureColumn
width: contentColumn.height - Theme.paddingSmall
height: contentColumn.height - Theme.paddingSmall
Label {
id: primaryText
textFormat: Text.StyledText
font.pixelSize: Theme.fontSizeMedium
truncationMode: TruncationMode.Fade
anchors.verticalCenter: parent.verticalCenter
Item {
width: parent.width
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
}
}
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) )
font.italic: appSettings.highlightUnreadConversations && (chatListViewItem.unreadReactionCount > 0)
color: (appSettings.highlightUnreadConversations && (chatListViewItem.unreadCount > 0)) ? Theme.highlightColor : Theme.primaryColor
}
Column {
id: contentColumn
width: mainColumn.width - pictureColumn.width - mainRow.spacing
spacing: Theme.paddingSmall
Row {
id: primaryTextRow
spacing: Theme.paddingMedium
Label {
id: primaryText
textFormat: Text.StyledText
font.pixelSize: Theme.fontSizeMedium
truncationMode: TruncationMode.Fade
anchors.verticalCenter: parent.verticalCenter
width: Math.min(contentColumn.width - (verifiedImage.visible ? (verifiedImage.width + primaryTextRow.spacing) : 0), implicitWidth)
}
Image {
id: verifiedImage
anchors.verticalCenter: parent.verticalCenter
source: chatListViewItem.isVerified ? "../../images/icon-verified.svg" : ""
sourceSize.width: Theme.iconSizeExtraSmall
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
}
Image {
id: verifiedImage
anchors.verticalCenter: parent.verticalCenter
source: chatListViewItem.isVerified ? "../../images/icon-verified.svg" : ""
sourceSize: Qt.size(Theme.iconSizeExtraSmall, Theme.iconSizeExtraSmall)
width: Theme.iconSizeSmall
height: Theme.iconSizeSmall
visible: status === Image.Ready
}
Image {
id: mutedImage
anchors.verticalCenter: parent.verticalCenter
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 {
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 {
id: separator
anchors {
top: mainColumn.bottom
topMargin: Theme.paddingMedium
bottom: parent.bottom
bottomMargin: -1
}
width: parent.width

View file

@ -33,9 +33,9 @@ Item {
onPinnedMessageChanged: {
if (pinnedMessage) {
Debug.log("[ChatPage] Activating pinned message");
var messageUserText = (pinnedMessage.sender.user_id !== chatPage.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(pinnedMessage.sender.user_id)), pinnedMessageUserText.font.pixelSize) : qsTr("You");
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");
pinnedMessageUserText.text = (messageUserText === "" ? qsTr("Pinned Message") : messageUserText );
pinnedMessageText.text = Emoji.emojify(Functions.getMessageText(pinnedMessage, true, pinnedMessage.sender.user_id === chatPage.myUserId, false), pinnedMessageText.font.pixelSize);
pinnedMessageText.text = Emoji.emojify(Functions.getMessageText(pinnedMessage, true, chatPage.myUserId, false), pinnedMessageText.font.pixelSize);
pinnedMessageItem.visible = true;
} else {
pinnedMessageItem.visible = false;
@ -123,7 +123,7 @@ Item {
id: unpinMessageIconButton
icon.source: "image://theme/icon-m-remove"
onClicked: {
Remorse.itemAction(pinnedMessageRow, qsTr("Message unpinned"), function() { tdLibWrapper.unpinMessage(chatPage.chatInformation.id);
Remorse.itemAction(pinnedMessageRow, qsTr("Message unpinned"), function() { tdLibWrapper.unpinMessage(chatPage.chatInformation.id, pinnedMessage.id);
pinnedMessageItem.requestCloseMessage(); });
}

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2020 Sebastian J. Wolf and other contributors
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber.
@ -18,25 +18,25 @@
*/
import QtQuick 2.6
import Sailfish.Silica 1.0
import "../"
Item {
visible: imageContainer.tweenFactor > 0.8 && bigProfilePictureList.count > 0
property bool isActive: imageContainer.tweenFactor === 1.0
id: profilePictureListItem
visible: imageContainer.thumbnailVisible && bigProfilePictureList.count > 0
property bool isActive: imageContainer.thumbnailActive
readonly property int currentPictureIndex: bigProfilePictureList.currentIndex
opacity: isActive ? 1.0 : 0.0
Behavior on opacity { FadeAnimation {} }
SlideshowView {
id: bigProfilePictureList
property bool isActive: imageContainer.tweenFactor === 1.0
width: parent.width
height: parent.height
clip: true
itemWidth: width
itemHeight: height
interactive: parent.isActive
model: chatInformationPage.chatPartnerProfilePhotos
model: imageContainer.thumbnailModel
delegate: Item {
width: bigProfilePictureList.itemWidth
height: bigProfilePictureList.itemHeight
@ -44,13 +44,13 @@ Item {
id: chatPictureDetail
photoData: modelData.sizes[modelData.sizes.length - 1].photo
replacementStringHint: ""
radius: chatPictureThumbnail.radius
radius: imageContainer.thumbnailRadius
anchors.fill: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
pageStack.push(Qt.resolvedUrl("../../pages/ImagePage.qml"), { "photoData" : modelData });
pageStack.push(Qt.resolvedUrl("../pages/ImagePage.qml"), { "photoData" : modelData });
}
}
}
@ -58,16 +58,18 @@ Item {
Text {
visible: bigProfilePictureList.count > 1
width: parent.width
width: parent.width - Theme.paddingSmall
anchors {
bottomMargin: Theme.paddingSmall
bottom: parent.bottom
}
horizontalAlignment: Text.AlignHCenter
property var baseString: new Array(bigProfilePictureList.count+1).join(" ○ ")
text: baseString.substring(0,bigProfilePictureList.currentIndex*3) + " ● " + baseString.substring((bigProfilePictureList.currentIndex+1)*3)
text: (baseString.substring(0,bigProfilePictureList.currentIndex*3) + " ● " + baseString.substring((bigProfilePictureList.currentIndex+1)*3)).trim()
font.pixelSize: Theme.fontSizeTiny
color: Theme.primaryColor
style: Text.Raised
styleColor: Theme.highlightDimmerColor
}
}

View file

@ -22,7 +22,6 @@ import Sailfish.Silica 1.0
import WerkWolf.Fernschreiber 1.0
Item {
id: profileThumbnail
property alias photoData: file.fileInformation
@ -30,6 +29,10 @@ Item {
property int radius: width / 2
property int imageStatus: -1
property bool optimizeImageSize: true
property bool highlighted
layer.enabled: highlighted
layer.effect: PressEffect { source: profileThumbnail }
function getReplacementString() {
if (replacementStringHint.length > 2) {
@ -66,7 +69,6 @@ Item {
id: singleImage
width: parent.width - Theme.paddingSmall
height: width
anchors.centerIn: parent
source: file.path
sourceSize.width: optimizeImageSize ? width : undefined
sourceSize.height: optimizeImageSize ? height : undefined

View file

@ -0,0 +1,121 @@
/*
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
}
}
}
}
}
}
}
}

View file

@ -25,22 +25,52 @@ Item {
id: stickerPickerOverlayItem
anchors.fill: parent
property var recentStickers: stickerManager.getRecentStickers()
property var installedStickerSets: stickerManager.getInstalledStickerSets()
property bool pickerLoaded: false
property var recentStickers: stickerManager.getRecentStickers();
property var installedStickerSets: stickerManager.getInstalledStickerSets();
signal stickerPicked(var stickerId)
Timer {
id: stickerPickerLoadedTimer
interval: 100
running: true
repeat: false
onTriggered: {
stickerPickerOverlayItem.pickerLoaded = true;
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)
Rectangle {
id: stickerPickerOverlayBackground
anchors.fill: parent
@ -49,35 +79,32 @@ Item {
opacity: 0.7
}
Flickable {
id: stickerPickerFlickable
SilicaListView {
id: stickerPickerListView
anchors.fill: parent
anchors.margins: Theme.paddingMedium
opacity: stickerPickerOverlayItem.pickerLoaded ? 1 : 0
Behavior on opacity { NumberAnimation {} }
visible: stickerPickerOverlayItem.pickerLoaded
contentHeight: stickerPickerColumn.height
clip: true
Column {
id: stickerPickerColumn
spacing: Theme.paddingMedium
width: stickerPickerFlickable.width
model: stickerPickerOverlayItem.installedStickerSets
header: Column {
spacing: Theme.paddingSmall
width: stickerPickerListView.width
height: recentStickersGridView.count > 0 ? ( Theme.fontSizeLarge + Theme.itemSizeExtraLarge + 4 * Theme.paddingSmall ) : 0
topPadding: Theme.paddingSmall
Label {
font.pixelSize: Theme.fontSizeMedium
font.pixelSize: Theme.fontSizeLarge
font.bold: true
width: parent.width
width: recentStickersGridView.width
leftPadding: Theme.paddingMedium
visible: recentStickersGridView.count > 0
maximumLineCount: 1
truncationMode: TruncationMode.Fade
text: qsTr("Recently used")
}
SilicaGridView {
id: recentStickersGridView
width: parent.width
height: Theme.itemSizeExtraLarge
width: stickerPickerListView.width
height: Theme.itemSizeExtraLarge + Theme.paddingSmall
cellWidth: Theme.itemSizeExtraLarge;
cellHeight: Theme.itemSizeExtraLarge;
visible: count > 0
@ -85,119 +112,132 @@ Item {
flow: GridView.FlowTopToBottom
model: stickerPickerOverlayItem.recentStickers
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)
}
}
delegate: stickerComponent
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 {
font.pixelSize: Theme.fontSizeMedium
id: setTitleText
font.pixelSize: Theme.fontSizeLarge
font.bold: true
width: parent.width
maximumLineCount: 1
anchors {
left: stickerSetThumbnail.right
right: expandSetButton.left
verticalCenter: parent.verticalCenter
margins: Theme.paddingSmall
}
truncationMode: TruncationMode.Fade
text: modelData.title
}
SilicaGridView {
id: installedStickerSetGridView
width: parent.width
height: Theme.itemSizeExtraLarge
cellWidth: Theme.itemSizeExtraLarge;
cellHeight: Theme.itemSizeExtraLarge;
visible: count > 0
clip: true
flow: GridView.FlowTopToBottom
model: modelData.stickers
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)
}
Icon {
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
width: stickerSetLoader.width
height: stickerSetLoader.height
orientation: Qt.Horizontal
visible: count > 0
model: stickerSetLoader.myStickerSet
delegate: stickerComponent
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
}
}
}

View file

@ -0,0 +1,173 @@
/*
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 {}
}
}
}

View file

@ -0,0 +1,55 @@
/*
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
}
}

View file

@ -0,0 +1,54 @@
/*
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
}
}
}
}

View file

@ -0,0 +1,69 @@
/*
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()
}

View 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 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 {} }
}
}
}
}

View file

@ -0,0 +1,221 @@
/*
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;
}
}
}
}
}

View file

@ -98,7 +98,7 @@ SilicaFlickable {
if(groupFullInfo.members && groupFullInfo.members.length > 0) {
for(var memberIndex in groupFullInfo.members) {
var memberData = groupFullInfo.members[memberIndex];
var userInfo = tdLibWrapper.getUserInformation(memberData.user_id) || {user:{}, bot_info:{}};
var userInfo = tdLibWrapper.getUserInformation(memberData.member_id.user_id) || {user:{}, bot_info:{}};
memberData.user = userInfo;
memberData.bot_info = memberData.bot_info || {};
membersList.append(memberData);
@ -187,6 +187,14 @@ SilicaFlickable {
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: {
@ -232,7 +240,7 @@ SilicaFlickable {
MenuItem {
visible: chatInformationPage.isPrivateChat
onClicked: {
tdLibWrapper.createNewSecretChat(chatInformationPage.chatPartnerGroupId);
tdLibWrapper.createNewSecretChat(chatInformationPage.chatPartnerGroupId, "openDirectly");
}
text: qsTr("New Secret Chat")
}
@ -256,6 +264,10 @@ SilicaFlickable {
}
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) {
return min + (max-min)*factor
@ -271,23 +283,25 @@ SilicaFlickable {
replacementStringHint: headerItem.title
width: parent.width
height: width
radius: imageContainer.minDimension / 2
radius: imageContainer.thumbnailRadius
opacity: profilePictureLoader.status !== Loader.Ready || profilePictureLoader.item.opacity < 1 ? 1.0 : 0.0
optimizeImageSize: false
}
Loader {
id: profilePictureLoader
active: imageContainer.hasImage
asynchronous: true
anchors.fill: chatPictureThumbnail
source: ( chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat)
? "ChatInformationProfilePictureList.qml"
? "../ProfilePictureList.qml"
: "ChatInformationProfilePicture.qml"
}
}
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")
description: (chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? ("@"+(chatInformationPage.privateChatUserInformation.username || chatInformationPage.chatPartnerGroupId)) : ""
description: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.usernames.editable_username)
? ("@"+chatInformationPage.privateChatUserInformation.usernames.editable_username) : ""
}
SilicaFlickable {
@ -350,7 +364,28 @@ SilicaFlickable {
height: imageContainer.hasImage ? imageContainer.maxDimension : 0
}
ChatInformationEditArea {
Label {
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
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")
@ -376,7 +411,7 @@ SilicaFlickable {
}
}
}
ChatInformationEditArea {
InformationEditArea {
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.")
headerText: qsTr("Info", "group or user infotext header")
@ -391,7 +426,7 @@ SilicaFlickable {
}
}
ChatInformationTextItem {
InformationTextItem {
headerText: qsTr("Phone Number", "user phone number header")
text: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.phone_number ? "+"+chatInformationPage.privateChatUserInformation.phone_number : "") || ""
isLinkedLabel: true
@ -408,7 +443,7 @@ SilicaFlickable {
Row {
width: parent.width
visible: !!inviteLinkItem.text
ChatInformationTextItem {
InformationTextItem {
id: inviteLinkItem
text: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? chatInformationPage.groupFullInformation.invite_link : ""
width: parent.width - inviteLinkButton.width

View file

@ -22,8 +22,8 @@ import Sailfish.Silica 1.0
import "../"
Item {
visible: imageContainer.tweenFactor > 0.8 && chatPictureDetail.imageStatus === Image.Ready
property bool isActive: imageContainer.tweenFactor === 1.0
visible: parent.thumbnailVisible && chatPictureDetail.imageStatus === Image.Ready
property bool isActive: parent.thumbnailActive
opacity: isActive ? 1.0 : 0.0
Behavior on opacity { FadeAnimation {} }
ProfileThumbnail {

View file

@ -38,18 +38,18 @@ ChatInformationTabItemBase {
width: tabBase.width - Theme.horizontalPageMargin * 2
x: Theme.horizontalPageMargin
ChatInformationTextItem {
InformationTextItem {
headerText: "chatInformation"
text:chatInformationPage.chatInformation ? JSON.stringify(chatInformationPage.chatInformation, null, 2) : ""
isLinkedLabel: true
}
ChatInformationTextItem {
InformationTextItem {
headerText: "groupInformation"
text: chatInformationPage.groupInformation ? JSON.stringify(chatInformationPage.groupInformation, null, 2) : ""
isLinkedLabel: true
}
ChatInformationTextItem {
InformationTextItem {
headerText: "groupFullInformation"
text: chatInformationPage.groupFullInformation ? JSON.stringify(chatInformationPage.groupFullInformation, null, 2) : ""
isLinkedLabel: true

View file

@ -72,14 +72,14 @@ ChatInformationTabItemBase {
}
delegate: PhotoTextsListItem {
pictureThumbnail {
photoData: (typeof user.profile_photo !== "undefined") ? user.profile_photo.small : ""
photoData: user.profile_photo ? user.profile_photo.small : null
}
width: parent.width
// chat title
primaryText.text: Emoji.emojify(Functions.getUserName(user), primaryText.font.pixelSize)
// last user
prologSecondaryText.text: "@"+(user.username !== "" ? user.username : user_id) + (user_id === chatInformationPage.myUserId ? " " + qsTr("You") : "")
prologSecondaryText.text: "@"+(user.username ? user.username : member_id.user_id) + (member_id.user_id === chatInformationPage.myUserId ? " " + qsTr("You") : "")
secondaryText {
horizontalAlignment: Text.AlignRight
property string statusText: Functions.getChatMemberStatusText(model.status["@type"])
@ -92,7 +92,7 @@ ChatInformationTabItemBase {
}
onClicked: {
tdLibWrapper.createPrivateChat(user_id);
tdLibWrapper.createPrivateChat(member_id.user_id, "openDirectly");
}
}
footer: Component {
@ -154,15 +154,6 @@ ChatInformationTabItemBase {
pageStack.pop(pageStack.find( function(page){ return(page._depth === 0)} ), PageStackAction.Immediate);
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")
}
}
}
}
}
@ -171,7 +162,7 @@ ChatInformationTabItemBase {
interval: 600
property int fetchLimit: 50
onTriggered: {
if(chatInformationPage.isSuperGroup && !chatInformationPage.isChannel && (chatInformationPage.groupInformation.member_count > membersView.count)) { //
if(chatInformationPage.isSuperGroup && (!chatInformationPage.isChannel || chatInformationPage.canGetMembers) && (chatInformationPage.groupInformation.member_count > membersView.count)) {
tabBase.loading = true
tdLibWrapper.getSupergroupMembers(chatInformationPage.chatPartnerGroupId, fetchLimit, pageContent.membersList.count);
fetchLimit = 200
@ -188,7 +179,10 @@ ChatInformationTabItemBase {
if(members && members.length > 0 && chatInformationPage.groupInformation.member_count > membersView.count) {
for(var memberIndex in members) {
var memberData = members[memberIndex];
var userInfo = tdLibWrapper.getUserInformation(memberData.user_id) || {user:{}, bot_info:{}};
var userInfo = tdLibWrapper.getUserInformation(memberData.member_id.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.bot_info = memberData.bot_info || {};
pageContent.membersList.append(memberData);

View file

@ -0,0 +1,33 @@
/*
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()
}
}

View file

@ -0,0 +1,291 @@
/*
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();
}
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,43 @@
/*
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
}

View file

@ -0,0 +1,183 @@
/*
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();
}
}
}

View file

@ -0,0 +1,39 @@
/*
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
}

View file

@ -0,0 +1,103 @@
/*
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
}
}
}

View file

@ -0,0 +1,49 @@
/*
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
}

View file

@ -0,0 +1,53 @@
/*
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
}
}
}
}

View file

@ -0,0 +1,23 @@
/*
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
}

View file

@ -0,0 +1,29 @@
/*
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
}
}

View file

@ -0,0 +1,106 @@
/*
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
}
}
}

View file

@ -0,0 +1,51 @@
/*
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);
}
}

View file

@ -0,0 +1,25 @@
/*
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"
}

View file

@ -0,0 +1,24 @@
/*
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 {
}

View file

@ -0,0 +1,27 @@
/*
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;
}

View file

@ -0,0 +1,21 @@
/*
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 {}

View file

@ -0,0 +1,96 @@
/*
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();
}
}
}

View file

@ -0,0 +1,32 @@
/*
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()
}

View file

@ -0,0 +1,201 @@
/*
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;
}
}
}
}

View file

@ -0,0 +1,82 @@
/*
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);
}
}
}

View file

@ -0,0 +1,128 @@
/*
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
}
}
}
}
}

View file

@ -0,0 +1,91 @@
/*
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();
}
}

View file

@ -0,0 +1,57 @@
/*
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
}
}

View file

@ -21,15 +21,13 @@ import QtQuick 2.6
import Sailfish.Silica 1.0
import WerkWolf.Fernschreiber 1.0
import "../js/functions.js" as Functions
import "../js/twemoji.js" as Emoji
import "../../js/functions.js" as Functions
import "../../js/twemoji.js" as Emoji
Item {
MessageContentBase {
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 bool isOwnMessage: messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
readonly property string messageId: rawMessage.id
@ -44,9 +42,6 @@ Item {
}
readonly property bool canAnswer: !hasAnswered && !pollData.is_closed
readonly property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz"
property bool highlighted
width: parent.width
height: pollColumn.height
property list<NamedAction> extraContextMenuItems: [
NamedAction {
visible: !pollData.is_closed && pollMessageComponent.canEdit
@ -235,6 +230,24 @@ Item {
width: 1
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 {
x: -Theme.horizontalPageMargin/2
@ -264,7 +277,7 @@ Item {
visible: !pollMessageComponent.canAnswer && !pollData.is_anonymous && pollData.total_voter_count > 0
icon.source: "image://theme/icon-m-media-artists"
onClicked: {
pageStack.push(Qt.resolvedUrl("../pages/PollResultsPage.qml"), { chatId:chatId, message:pollMessageComponent.message});
pageStack.push(Qt.resolvedUrl("../../pages/PollResultsPage.qml"), { chatId:chatId, message:pollMessageComponent.rawMessage});
}
Icon {
opacity: 0.8

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2020 Sebastian J. Wolf and other contributors
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber.
@ -19,25 +19,23 @@
import QtQuick 2.6
import Sailfish.Silica 1.0
import WerkWolf.Fernschreiber 1.0
import "../"
import "../../js/twemoji.js" as Emoji
Item {
property ListItem messageListItem
property MessageOverlayFlickable overlayFlickable
MessageContentBase {
id: thisItem
readonly property var stickerData: messageListItem ? messageListItem.myMessage.content.sticker : overlayFlickable.overlayMessage.content.sticker;
readonly property bool animated: stickerData.is_animated && appSettings.animateStickers
property var stickerData: messageListItem ? messageListItem.myMessage.content.sticker : overlayFlickable.overlayMessage.content.sticker;
readonly property bool asEmoji: appSettings.showStickersAsEmojis
readonly property bool animated: stickerData.format["@type"] === "stickerFormatTgs" && appSettings.animateStickers
readonly property bool stickerVisible: staticStickerLoader.item ? staticStickerLoader.item.visible :
animatedStickerLoader.item ? animatedStickerLoader.item.visible : false
readonly property bool isOwnSticker : messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
property real aspectRatio: stickerData.width / stickerData.height
property bool highlighted
readonly property real aspectRatio: stickerData.width / stickerData.height
implicitWidth: stickerData.width
implicitHeight: stickerData.height
layer.enabled: highlighted
layer.effect: PressEffect { source: singleImage }
TDLibFile {
id: file
tdlib: tdLibWrapper
@ -46,6 +44,7 @@ Item {
}
Item {
width: Math.min( stickerData.width, parent.width )
height: width * aspectRatio
// (centered in image mode, text-like in sticker mode)
@ -56,14 +55,17 @@ Item {
Loader {
id: animatedStickerLoader
anchors.fill: parent
active: animated
active: animated && !asEmoji
sourceComponent: Component {
AnimatedImage {
id: animatedSticker
anchors.fill: parent
source: file.path
asynchronous: true
paused: !Qt.application.active
cache: false
layer.enabled: thisItem.highlighted
layer.effect: PressEffect { source: animatedSticker }
}
}
}
@ -71,17 +73,24 @@ Item {
Loader {
id: staticStickerLoader
anchors.fill: parent
active: !animated
active: !animated || asEmoji
sourceComponent: Component {
Image {
id: staticSticker
anchors.fill: parent
source: file.path
source: asEmoji ? Emoji.getEmojiPath(stickerData.emoji) : file.path
sourceSize {
width: width
height: height
}
fillMode: Image.PreserveAspectFit
autoTransform: true
asynchronous: true
visible: opacity > 0
opacity: status === Image.Ready ? 1 : 0
Behavior on opacity { FadeAnimation {} }
layer.enabled: thisItem.highlighted
layer.effect: PressEffect { source: staticSticker }
}
}
}
@ -98,6 +107,11 @@ Item {
}
}
onClicked: {
stickerSetOverlayLoader.stickerSetId = stickerData.set_id
stickerSetOverlayLoader.active = true
}
Timer {
id: placeHolderDelayTimer
interval: 1000

View file

@ -0,0 +1,24 @@
/*
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
}

View file

@ -19,16 +19,13 @@
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
import "../"
import "../../js/functions.js" as Functions
import "../../js/debug.js" as Debug
Item {
MessageContentBase {
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 string videoUrl;
property int previewFileId;
@ -38,10 +35,7 @@ Item {
property bool onScreen: messageListItem ? messageListItem.page.status === PageStatus.Active : true;
property string videoType : "video";
property bool playRequested: false;
property bool highlighted;
signal clicked();
width: parent.width
height: videoMessageComponent.isVideoNote ? width : Functions.getVideoHeight(width, videoData)
Timer {
@ -89,7 +83,7 @@ Item {
videoMessageComponent.videoType = videoMessageComponent.isVideoNote ? "video" : videoData['@type'];
videoFileId = videoData[videoType].id;
if (rawMessage.content['@type'] === "messageAnimation") {
if (typeof rawMessage !== "undefined" && rawMessage.content['@type'] === "messageAnimation") {
playButton.visible = true;
fullscreenButton.visible = !videoMessageComponent.fullscreen;
handlePlay();
@ -101,7 +95,7 @@ Item {
tdLibWrapper.downloadFile(previewFileId);
}
} else {
placeholderImage.source = "image://theme/icon-l-video?white";
placeholderImage.source = "image://theme/icon-m-video?white";
placeholderImage.width = Theme.itemSizeLarge
placeholderImage.height = Theme.itemSizeLarge
}
@ -153,7 +147,7 @@ Item {
asynchronous: true
visible: status === Image.Ready ? true : false
layer.enabled: videoMessageComponent.highlighted
layer.effect: PressEffect { source: singleImage }
layer.effect: PressEffect { source: placeholderImage }
}
BackgroundImage {
@ -161,7 +155,6 @@ Item {
}
Rectangle {
id: placeholderBackground
color: "black"
opacity: 0.3
height: parent.height
@ -216,7 +209,7 @@ Item {
height: Theme.iconSizeLarge
icon {
asynchronous: true
source: "../../images/icon-l-fullscreen.svg"
source: "../../../images/icon-l-fullscreen.svg"
sourceSize {
width: Theme.iconSizeLarge
height: Theme.iconSizeLarge
@ -225,7 +218,7 @@ Item {
highlighted: videoMessageComponent.highlighted || down
visible: ( placeholderImage.status === Image.Ready && !videoMessageComponent.fullscreen ) ? true : false
onClicked: {
pageStack.push(Qt.resolvedUrl("../pages/VideoPage.qml"), {"videoData": videoData});
pageStack.push(Qt.resolvedUrl("../../pages/VideoPage.qml"), {"videoData": videoData, "sourceMessage": rawMessage});
}
}
}
@ -241,7 +234,6 @@ Item {
}
Rectangle {
id: videoErrorShade
width: parent.width
height: parent.height
color: "lightgrey"
@ -296,21 +288,6 @@ Item {
}
}
Connections {
target: videoMessageComponent
onClicked: {
if (messageVideo.playbackState === MediaPlayer.PlayingState) {
enableScreensaver();
messageVideo.pause();
timeLeftItem.visible = true;
} else {
disableScreensaver();
messageVideo.play();
timeLeftTimer.start();
}
}
}
Video {
id: messageVideo
@ -369,7 +346,7 @@ Item {
height: parent.height
source: videoUrl
layer.enabled: videoMessageComponent.highlighted
layer.effect: PressEffect { source: singleImage }
layer.effect: PressEffect { source: messageVideo }
onStopped: {
enableScreensaver();
messageVideo.visible = false;
@ -378,6 +355,21 @@ Item {
videoComponentLoader.active = false;
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 {
@ -464,7 +456,7 @@ Item {
highlighted: videoMessageComponent.highlighted || down
icon {
asynchronous: true
source: "../../images/icon-l-fullscreen.svg"
source: "../../../images/icon-l-fullscreen.svg"
sourceSize {
width: Theme.iconSizeLarge
height: Theme.iconSizeLarge
@ -472,7 +464,7 @@ Item {
}
visible: ( videoComponentLoader.active && messageVideo.playbackState === MediaPlayer.PausedState ) ? true : false
onClicked: {
pageStack.push(Qt.resolvedUrl("../pages/VideoPage.qml"), {"videoData": videoData});
pageStack.push(Qt.resolvedUrl("../../pages/VideoPage.qml"), {"videoData": videoData, "sourceMessage": rawMessage});
}
}
}
@ -484,7 +476,7 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: positionText.top
minimumValue: 0
maximumValue: messageVideo.duration ? messageVideo.duration : 0
maximumValue: messageVideo.duration ? messageVideo.duration : 0.1
highlighted: videoMessageComponent.highlighted || down
stepSize: 1
@ -516,7 +508,6 @@ Item {
}
}
}

View file

@ -0,0 +1,21 @@
/*
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 {}

View file

@ -0,0 +1,28 @@
/*
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
}

View file

@ -0,0 +1,77 @@
/*
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);
}
}
}
}

View file

@ -19,101 +19,92 @@
import QtQuick 2.6
import QtGraphicalEffects 1.0
import Sailfish.Silica 1.0
import "../components"
import "../js/twemoji.js" as Emoji
import "../js/functions.js" as Functions
import WerkWolf.Fernschreiber 1.0
import "../"
import "../../js/functions.js" as Functions
Column {
id: webPagePreviewColumn
property var webPageData;
property var pictureFileInformation;
property bool hasImage: false;
property bool largerFontSize: false;
property bool highlighted
readonly property bool hasImage: picture.fileId !== 0
readonly property int fontSize: largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
spacing: Theme.paddingSmall
Component.onCompleted: {
updateWebPage();
}
Component.onCompleted: updatePhoto()
function updateWebPage() {
onWebPageDataChanged: updatePhoto()
function updatePhoto() {
if (webPageData) {
if (typeof webPageData.photo !== "undefined") {
hasImage = true;
if (webPageData.photo) {
// Check first which size fits best...
var photo
for (var i = 0; i < webPageData.photo.sizes.length; i++) {
pictureFileInformation = webPageData.photo.sizes[i].photo;
photo = webPageData.photo.sizes[i].photo;
if (webPageData.photo.sizes[i].width >= webPagePreviewColumn.width) {
break;
}
}
if (pictureFileInformation.local.is_downloading_completed) {
singleImage.source = pictureFileInformation.local.path;
} else {
tdLibWrapper.downloadFile(pictureFileInformation.id);
if (photo) {
picture.fileInformation = photo
}
}
}
}
Connections {
target: tdLibWrapper
onFileUpdated: {
if (typeof pictureFileInformation !== "undefined" && fileId === pictureFileInformation.id) {
if (fileInformation.local.is_downloading_completed) {
pictureFileInformation = fileInformation;
singleImage.source = fileInformation.local.path;
}
}
}
function clicked() {
descriptionText.toggleMaxLineCount()
}
Label {
TDLibFile {
id: picture
tdlib: tdLibWrapper
autoLoad: true
}
MultilineEmojiLabel {
id: siteNameText
width: parent.width
text: webPageData.site_name ? Emoji.emojify(webPageData.site_name, font.pixelSize) : ""
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
rawText: webPageData.site_name ? webPageData.site_name : ""
font.pixelSize: webPagePreviewColumn.fontSize
font.bold: true
color: Theme.secondaryHighlightColor
truncationMode: TruncationMode.Fade
maximumLineCount: 1
textFormat: Text.StyledText
visible: (text !== "")
visible: (rawText !== "")
maxLineCount: 1
}
Label {
MultilineEmojiLabel {
id: titleText
width: parent.width
text: webPageData.title ? Emoji.emojify(webPageData.title, font.pixelSize) : ""
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
rawText: webPageData.title ? webPageData.title : ""
font.pixelSize: webPagePreviewColumn.fontSize
font.bold: true
truncationMode: TruncationMode.Fade
wrapMode: Text.Wrap
maximumLineCount: 2
textFormat: Text.StyledText
visible: (text !== "")
visible: (rawText !== "")
maxLineCount: 2
}
Label {
MultilineEmojiLabel {
id: descriptionText
width: parent.width
text: webPageData.description ? Emoji.emojify(Functions.enhanceMessageText(webPageData.description), font.pixelSize) : ""
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
truncationMode: TruncationMode.Fade
wrapMode: Text.Wrap
maximumLineCount: 3
textFormat: Text.StyledText
visible: (text !== "")
rawText: webPageData.description ? Functions.enhanceMessageText(webPageData.description) : ""
font.pixelSize: webPagePreviewColumn.fontSize
visible: (rawText !== "")
readonly property int defaultMaxLineCount: 3
maxLineCount: defaultMaxLineCount
linkColor: Theme.highlightColor
onLinkActivated: {
Functions.handleLink(link);
}
function toggleMaxLineCount() {
maxLineCount = maxLineCount > 0 ? 0 : defaultMaxLineCount
}
}
Item {
@ -133,38 +124,35 @@ Column {
fillMode: Image.PreserveAspectCrop
autoTransform: true
asynchronous: true
visible: hasImage && status === Image.Ready
source: picture.isDownloadingCompleted ? picture.path : ""
visible: opacity > 0
opacity: hasImage && status === Image.Ready ? 1 : 0
layer.enabled: webPagePreviewColumn.highlighted
layer.effect: PressEffect { source: singleImage }
Behavior on opacity { NumberAnimation {} }
Behavior on opacity { FadeAnimation {} }
MouseArea {
anchors.fill: parent
onClicked: {
pageStack.push(Qt.resolvedUrl("../pages/ImagePage.qml"), { "photoData" : webPageData.photo, "pictureFileInformation" : pictureFileInformation });
pageStack.push(Qt.resolvedUrl("../../pages/ImagePage.qml"), { "photoData" : webPageData.photo, "pictureFileInformation" : picture.fileInformation });
}
}
}
BackgroundImage {
id: backgroundImage
visible: hasImage && singleImage.status !== Image.Ready
layer.enabled: webPagePreviewColumn.highlighted
layer.effect: PressEffect { source: singleImage }
layer.effect: PressEffect { source: backgroundImage }
}
}
Label {
id: noPreviewAvailableText
width: parent.width
text: qsTr("Preview not supported for this link...")
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeExtraSmall : Theme.fontSizeTiny
font.italic: true
color: Theme.secondaryColor
truncationMode: TruncationMode.Fade
wrapMode: Text.Wrap
maximumLineCount: 1
textFormat: Text.StyledText
visible: !siteNameText.visible && !titleText.visible && !descriptionText.visible && !webPagePreviewImageItem.visible
}

View file

@ -0,0 +1,42 @@
/*
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
}
}

View file

@ -0,0 +1,106 @@
/*
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
}
}

View file

@ -0,0 +1,28 @@
/*
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
}

View file

@ -0,0 +1,89 @@
/*
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 { } }
}
}
}
}

View file

@ -0,0 +1,221 @@
/*
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
}
}
}
}
}
}

View file

@ -0,0 +1,266 @@
/*
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
}
}
}
}
}

View file

@ -0,0 +1,216 @@
/*
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
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,51 @@
/*
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
}
}
}
}
}

View file

@ -0,0 +1,346 @@
/*
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();
});
}
}
}
}
}

View file

@ -40,6 +40,16 @@ ApplicationWindow
}
}
Connections {
target: tdLibWrapper
onOpenFileExternally: {
Qt.openUrlExternally(filePath);
}
onTgUrlFound: {
Functions.handleLink(tgUrl);
}
}
AppNotification {
id: appNotification
parent: pageStack.currentPage

View file

@ -1 +1 @@
<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>
<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>

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 269 B

View file

@ -1 +1 @@
<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>
<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>

Before

Width:  |  Height:  |  Size: 765 B

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -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.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>
<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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -1 +1 @@
<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>
<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>

Before

Width:  |  Height:  |  Size: 338 B

After

Width:  |  Height:  |  Size: 382 B

View file

@ -1 +1 @@
<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>
<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>

Before

Width:  |  Height:  |  Size: 976 B

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1 +1 @@
<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>
<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>

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 409 B

View file

@ -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="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>
<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>

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 376 B

View file

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 1.9 KiB

Some files were not shown because too many files have changed in this diff Show more