diff --git a/.gitignore b/.gitignore
index fbb2bbb..043d60a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,3 +56,6 @@ tdlibsecrets.h
#Convinience scripts
*.sh
+
+#vscode
+.vscode
diff --git a/db/emojis.db b/db/emojis.db
index 2b47472..602b83d 100644
Binary files a/db/emojis.db and b/db/emojis.db differ
diff --git a/harbour-fernschreiber.pro b/harbour-fernschreiber.pro
index 0a72651..d70eb3a 100644
--- a/harbour-fernschreiber.pro
+++ b/harbour-fernschreiber.pro
@@ -65,6 +65,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/PollPreview.qml \
qml/components/PressEffect.qml \
qml/components/ProfilePictureList.qml \
+ qml/components/ReactionButton.qml \
qml/components/ReplyMarkupButtons.qml \
qml/components/StickerPicker.qml \
qml/components/PhotoTextsListItem.qml \
diff --git a/qml/components/MessageListViewItem.qml b/qml/components/MessageListViewItem.qml
index b066bcb..5b597f6 100644
--- a/qml/components/MessageListViewItem.qml
+++ b/qml/components/MessageListViewItem.qml
@@ -39,7 +39,7 @@ ListItem {
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: Text.AlignLeft
+ readonly property int textAlign: isOwnMessage ? Text.AlignRight : Text.AlignLeft
readonly property Page page: precalculatedValues.page
readonly property bool isSelected: messageListItem.precalculatedValues.pageIsSelecting && page.selectedMessages.some(function(existingMessage) {
return existingMessage.id === messageId
@@ -446,15 +446,13 @@ ListItem {
anchors {
left: parent.left
- leftMargin: page.isPrivateChat ? (messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0) : 0 //левый марджин для собственных сообщений в приватных чатах. В остальных на полную ширину
+ leftMargin: messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0
verticalCenter: parent.verticalCenter
}
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
width: precalculatedValues.backgroundWidth
-
property bool isUnread: messageIndex > 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))
-
+ color: Theme.colorScheme === Theme.LightOnDark ? (isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor) : (isUnread ? Theme.backgroundGlowColor : Theme.overlayBackgroundColor)
radius: parent.width / 50
opacity: isUnread ? 0.5 : 0.2
visible: appSettings.showStickersAsImages || (myMessage.content['@type'] !== "messageSticker" && myMessage.content['@type'] !== "messageAnimatedEmoji")
@@ -489,7 +487,7 @@ ListItem {
truncationMode: TruncationMode.Fade
textFormat: Text.StyledText
horizontalAlignment: messageListItem.textAlign
- visible: messageListItem.isOwnMessage ? false : (precalculatedValues.showUserInfo || myMessage['@type'] === "sponsoredMessage")
+ visible: precalculatedValues.showUserInfo || myMessage['@type'] === "sponsoredMessage"
MouseArea {
anchors.fill: parent
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
diff --git a/qml/components/ReactionButton.qml b/qml/components/ReactionButton.qml
new file mode 100644
index 0000000..06bc908
--- /dev/null
+++ b/qml/components/ReactionButton.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Rectangle {
+ id: button
+
+ height: Theme.itemSizeExtraSmall
+ width: Theme.itemSizeExtraSmall
+ color: Theme.rgba(Theme.primaryColor, 0.4)
+ radius: width / 2
+
+ signal clicked()
+
+ IconButton {
+ icon.source: "image://theme/icon-s-favorite"
+ anchors.centerIn: parent
+ onClicked: button.clicked()
+ }
+}
diff --git a/qml/components/settingsPage/SettingsBehavior.qml b/qml/components/settingsPage/SettingsBehavior.qml
index c1d15ab..ae197a0 100644
--- a/qml/components/settingsPage/SettingsBehavior.qml
+++ b/qml/components/settingsPage/SettingsBehavior.qml
@@ -21,6 +21,8 @@ import QtQuick 2.6
import Sailfish.Silica 1.0
import WerkWolf.Fernschreiber 1.0
+import ".."
+
AccordionItem {
text: qsTr("Behavior")
Component {
@@ -114,6 +116,31 @@ AccordionItem {
}
}
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.showReactionButton
+ text: qsTr("Show reaction button on tap")
+ description: qsTr("The reaction button may appear when you tap the message bubble, to make access to the reactions even easier.")
+ automaticCheck: false
+ onClicked: {
+ appSettings.showReactionButton = !checked
+ }
+
+ ReactionButton {
+ Behavior on opacity { FadeAnimation {} }
+ opacity: appSettings.showReactionButton ? 1 : 0
+ visible: opacity > 0
+ anchors {
+ right: parent.right
+ rightMargin: parent.rightMargin
+ verticalCenter: parent.verticalCenter
+ }
+ onClicked: {
+ appSettings.showReactionButton = !parent.checked
+ }
+ }
+ }
+
ComboBox {
id: feedbackComboBox
width: parent.columnWidth
diff --git a/qml/js/emoji/1f426-200d-2b1b.svg b/qml/js/emoji/1f426-200d-2b1b.svg
new file mode 100644
index 0000000..0790872
--- /dev/null
+++ b/qml/js/emoji/1f426-200d-2b1b.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1f6dc.svg b/qml/js/emoji/1f6dc.svg
new file mode 100644
index 0000000..364a68e
--- /dev/null
+++ b/qml/js/emoji/1f6dc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fa75.svg b/qml/js/emoji/1fa75.svg
new file mode 100644
index 0000000..5a72101
--- /dev/null
+++ b/qml/js/emoji/1fa75.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fa76.svg b/qml/js/emoji/1fa76.svg
new file mode 100644
index 0000000..56e3ef1
--- /dev/null
+++ b/qml/js/emoji/1fa76.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fa77.svg b/qml/js/emoji/1fa77.svg
new file mode 100644
index 0000000..a372dcc
--- /dev/null
+++ b/qml/js/emoji/1fa77.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fa87.svg b/qml/js/emoji/1fa87.svg
new file mode 100644
index 0000000..fd8c53a
--- /dev/null
+++ b/qml/js/emoji/1fa87.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fa88.svg b/qml/js/emoji/1fa88.svg
new file mode 100644
index 0000000..633fa4c
--- /dev/null
+++ b/qml/js/emoji/1fa88.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faad.svg b/qml/js/emoji/1faad.svg
new file mode 100644
index 0000000..5036323
--- /dev/null
+++ b/qml/js/emoji/1faad.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faae.svg b/qml/js/emoji/1faae.svg
new file mode 100644
index 0000000..e8ad033
--- /dev/null
+++ b/qml/js/emoji/1faae.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faaf.svg b/qml/js/emoji/1faaf.svg
new file mode 100644
index 0000000..bfaceb5
--- /dev/null
+++ b/qml/js/emoji/1faaf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fabb.svg b/qml/js/emoji/1fabb.svg
new file mode 100644
index 0000000..3cae81a
--- /dev/null
+++ b/qml/js/emoji/1fabb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fabc.svg b/qml/js/emoji/1fabc.svg
new file mode 100644
index 0000000..cb8c4ee
--- /dev/null
+++ b/qml/js/emoji/1fabc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fabd.svg b/qml/js/emoji/1fabd.svg
new file mode 100644
index 0000000..9effe33
--- /dev/null
+++ b/qml/js/emoji/1fabd.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fabf.svg b/qml/js/emoji/1fabf.svg
new file mode 100644
index 0000000..7c0f6a6
--- /dev/null
+++ b/qml/js/emoji/1fabf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1face.svg b/qml/js/emoji/1face.svg
new file mode 100644
index 0000000..f419d66
--- /dev/null
+++ b/qml/js/emoji/1face.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1facf.svg b/qml/js/emoji/1facf.svg
new file mode 100644
index 0000000..030b0bd
--- /dev/null
+++ b/qml/js/emoji/1facf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fada.svg b/qml/js/emoji/1fada.svg
new file mode 100644
index 0000000..2094a77
--- /dev/null
+++ b/qml/js/emoji/1fada.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fadb.svg b/qml/js/emoji/1fadb.svg
new file mode 100644
index 0000000..e68a96d
--- /dev/null
+++ b/qml/js/emoji/1fadb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1fae8.svg b/qml/js/emoji/1fae8.svg
new file mode 100644
index 0000000..02ab52d
--- /dev/null
+++ b/qml/js/emoji/1fae8.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf7-1f3fb.svg b/qml/js/emoji/1faf7-1f3fb.svg
new file mode 100644
index 0000000..5df3bd1
--- /dev/null
+++ b/qml/js/emoji/1faf7-1f3fb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf7-1f3fc.svg b/qml/js/emoji/1faf7-1f3fc.svg
new file mode 100644
index 0000000..6633504
--- /dev/null
+++ b/qml/js/emoji/1faf7-1f3fc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf7-1f3fd.svg b/qml/js/emoji/1faf7-1f3fd.svg
new file mode 100644
index 0000000..752c49b
--- /dev/null
+++ b/qml/js/emoji/1faf7-1f3fd.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf7-1f3fe.svg b/qml/js/emoji/1faf7-1f3fe.svg
new file mode 100644
index 0000000..d4aaefc
--- /dev/null
+++ b/qml/js/emoji/1faf7-1f3fe.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf7-1f3ff.svg b/qml/js/emoji/1faf7-1f3ff.svg
new file mode 100644
index 0000000..6735ce3
--- /dev/null
+++ b/qml/js/emoji/1faf7-1f3ff.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf7.svg b/qml/js/emoji/1faf7.svg
new file mode 100644
index 0000000..1237887
--- /dev/null
+++ b/qml/js/emoji/1faf7.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf8-1f3fb.svg b/qml/js/emoji/1faf8-1f3fb.svg
new file mode 100644
index 0000000..3a28a11
--- /dev/null
+++ b/qml/js/emoji/1faf8-1f3fb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf8-1f3fc.svg b/qml/js/emoji/1faf8-1f3fc.svg
new file mode 100644
index 0000000..544719e
--- /dev/null
+++ b/qml/js/emoji/1faf8-1f3fc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf8-1f3fd.svg b/qml/js/emoji/1faf8-1f3fd.svg
new file mode 100644
index 0000000..607bcf2
--- /dev/null
+++ b/qml/js/emoji/1faf8-1f3fd.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf8-1f3fe.svg b/qml/js/emoji/1faf8-1f3fe.svg
new file mode 100644
index 0000000..378fa2e
--- /dev/null
+++ b/qml/js/emoji/1faf8-1f3fe.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf8-1f3ff.svg b/qml/js/emoji/1faf8-1f3ff.svg
new file mode 100644
index 0000000..b3cccfc
--- /dev/null
+++ b/qml/js/emoji/1faf8-1f3ff.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/emoji/1faf8.svg b/qml/js/emoji/1faf8.svg
new file mode 100644
index 0000000..fadecd8
--- /dev/null
+++ b/qml/js/emoji/1faf8.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml/js/twemoji.js b/qml/js/twemoji.js
index 044a067..0825c58 100644
--- a/qml/js/twemoji.js
+++ b/qml/js/twemoji.js
@@ -8,7 +8,7 @@
// RegExp based on emoji's official Unicode standards
// http://www.unicode.org/Public/UNIDATA/EmojiSources.txt
-var re = /(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd\udec3-\udec5\udef0-\udef6]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedd-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7c\ude80-\ude86\ude90-\udeac\udeb0-\udeba\udec0-\udec2\uded0-\uded9\udee0-\udee7]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,
+var re = /(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b|\ud83d\udc26\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|\ud83e\udef0|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd\udec3-\udec5\udef1-\udef8]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedc-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude7c\ude80-\ude88\ude90-\udebd\udebf-\udec2\udece-\udedb\udee0-\udee8]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,
// avoid runtime RegExp creation for not so smart,
// not JIT based, and old browsers / engines
diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml
index d20a373..6d4ecf0 100644
--- a/qml/pages/ChatPage.qml
+++ b/qml/pages/ChatPage.qml
@@ -417,7 +417,7 @@ Page {
chatPage.messageIdToScrollTo = messageId
}
if (chatPage.messageIdToScrollTo && chatPage.messageIdToScrollTo != "") {
- var index = chatModel.getMessageIndex(chatPage.messageIdToScrollTo);
+ var index = chatModel.getDisplayedMessageIndex(chatPage.messageIdToScrollTo);
if(index !== -1) {
chatPage.messageIdToScrollTo = "";
chatView.scrollToIndex(index);
@@ -796,7 +796,7 @@ Page {
NamedAction {
visible: messageOptionsDrawer.showCopyMessageToClipboardMenuItem
name: qsTr("Copy Message to Clipboard")
- action: messageOptionsDrawer.myMessage.copyMessageToClipboard
+ action: messageOptionsDrawer.sourceItem.copyMessageToClipboard
},
NamedAction {
visible: messageOptionsDrawer.showForwardMessageMenuItem && messageOptionsDrawer.myMessage.can_be_forwarded
@@ -1922,7 +1922,7 @@ Page {
Image {
id: emojiPicture
- source: "../js/emoji/" + modelData.file_name
+ source: "../js/emoji/" + modelData.file_name +".svg"
width: Theme.fontSizeLarge
height: Theme.fontSizeLarge
}
diff --git a/rpm/harbour-fernschreiber.spec b/rpm/harbour-fernschreiber.spec
index 41e8918..4188b01 100644
--- a/rpm/harbour-fernschreiber.spec
+++ b/rpm/harbour-fernschreiber.spec
@@ -9,6 +9,7 @@ Name: harbour-fernschreiber
# << macros
%define __provides_exclude_from ^%{_datadir}/.*$
%define __requires_exclude ^lib(tdjson|ssl|crypto).*$
+%define _binary_payload w6.xzdio
Summary: Fernschreiber is a Telegram client for Aurora OS
Version: 0.17
@@ -17,7 +18,6 @@ Group: Qt/Qt
License: LICENSE
URL: http://werkwolf.eu/
Source0: %{name}-%{version}.tar.bz2
-Source100: harbour-fernschreiber.yaml
Requires: sailfishsilica-qt5 >= 0.10.9
#Requires: nemo-qml-plugin-contacts-qt5
BuildRequires: pkgconfig(sailfishapp) >= 1.0.2
diff --git a/rpm/harbour-fernschreiber.yaml b/rpm/harbour-fernschreiber.yaml
new file mode 100644
index 0000000..368792c
--- /dev/null
+++ b/rpm/harbour-fernschreiber.yaml
@@ -0,0 +1,56 @@
+Name: harbour-fernschreiber
+Summary: Fernschreiber is a Telegram client for Sailfish OS
+Version: 0.17
+Release: 12
+# The contents of the Group field should be one of the groups listed here:
+# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
+Group: Qt/Qt
+URL: http://werkwolf.eu/
+License: LICENSE
+# This must be generated before uploading a package to a remote build service.
+# Usually this line does not need to be modified.
+Sources:
+- '%{name}-%{version}.tar.bz2'
+Description: |
+ Fernschreiber is a Telegram client for Sailfish OS
+Configure: none
+Builder: qmake5
+
+# This section specifies build dependencies that are resolved using pkgconfig.
+# This is the preferred way of specifying build dependencies for your package.
+PkgConfigBR:
+ - sailfishapp >= 1.0.2
+ - Qt5Core
+ - Qt5Qml
+ - Qt5Quick
+ - Qt5DBus
+ - Qt5Sql
+ - Qt5Multimedia
+ - Qt5Positioning
+ - nemonotifications-qt5
+ - openssl
+
+# NB: spectacle has a bug where it will remove custom "#<< macros" lines, so define them here:
+Macros:
+ - '__provides_exclude_from;^%{_datadir}/.*$'
+ - '__requires_exclude;^libtdjson.*$'
+ - '_binary_payload;w6.xzdio'
+
+# Build dependencies without a pkgconfig setup can be listed here
+PkgBR:
+ - gperf
+
+# Runtime dependencies which are not automatically detected
+Requires:
+ - sailfishsilica-qt5 >= 0.10.9
+ - nemo-qml-plugin-contacts-qt5
+
+# All installed files
+Files:
+ - '%{_bindir}/%{name}'
+ - '%{_datadir}/%{name}'
+ - '%{_datadir}/applications/%{name}.desktop'
+ - '%{_datadir}/icons/hicolor/*/apps/%{name}.png'
+
+# For more information about yaml and what's supported in Sailfish OS
+# build system, please see https://wiki.merproject.org/wiki/Spectacle
diff --git a/src/appsettings.cpp b/src/appsettings.cpp
index e1a92ad..e9a9ea3 100644
--- a/src/appsettings.cpp
+++ b/src/appsettings.cpp
@@ -42,6 +42,7 @@ namespace {
const QString KEY_FOCUS_TEXTAREA_ON_CHAT_OPEN("focusTextAreaOnChatOpen");
const QString KEY_SPONSORED_MESS("sponsoredMess");
const QString KEY_HIGHLIGHT_UNREADCONVS("highlightUnreadConversations");
+ const QString KEY_SHOW_REACTION_BUTTON("showReactionButton");
}
AppSettings::AppSettings(QObject *parent) : QObject(parent), settings(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/org.ygriega/fernschreiber/settings.conf", QSettings::NativeFormat)
@@ -329,6 +330,20 @@ void AppSettings::setFocusTextAreaOnChatOpen(bool focusTextAreaOnChatOpen)
}
}
+bool AppSettings::showReactionButton() const
+{
+ return settings.value(KEY_SHOW_REACTION_BUTTON, true).toBool();
+}
+
+void AppSettings::setShowReactionButton(bool enable)
+{
+ if (showReactionButton() != enable) {
+ LOG(KEY_SHOW_REACTION_BUTTON << enable);
+ settings.setValue(KEY_SHOW_REACTION_BUTTON, enable);
+ emit showReactionButtonChanged();
+ }
+}
+
AppSettings::SponsoredMess AppSettings::getSponsoredMess() const
{
return (SponsoredMess) settings.value(KEY_SPONSORED_MESS, (int)
diff --git a/src/appsettings.h b/src/appsettings.h
index acc38b2..9382fee 100644
--- a/src/appsettings.h
+++ b/src/appsettings.h
@@ -43,8 +43,9 @@ class AppSettings : public QObject {
Q_PROPERTY(bool onlineOnlyMode READ onlineOnlyMode WRITE setOnlineOnlyMode NOTIFY onlineOnlyModeChanged)
Q_PROPERTY(bool delayMessageRead READ delayMessageRead WRITE setDelayMessageRead NOTIFY delayMessageReadChanged)
Q_PROPERTY(bool focusTextAreaOnChatOpen READ getFocusTextAreaOnChatOpen WRITE setFocusTextAreaOnChatOpen NOTIFY focusTextAreaOnChatOpenChanged)
- Q_PROPERTY(SponsoredMess sponsoredMess READ getSponsoredMess WRITE setSponsoredMess NOTIFY sponsoredMessChanged)
Q_PROPERTY(bool highlightUnreadConversations READ highlightUnreadConversations WRITE setHighlightUnreadConversations NOTIFY highlightUnreadConversationsChanged)
+ Q_PROPERTY(bool showReactionButton READ showReactionButton WRITE setShowReactionButton NOTIFY showReactionButtonChanged)
+ Q_PROPERTY(SponsoredMess sponsoredMess READ getSponsoredMess WRITE setSponsoredMess NOTIFY sponsoredMessChanged)
public:
enum SponsoredMess {
@@ -121,12 +122,15 @@ public:
bool getFocusTextAreaOnChatOpen() const;
void setFocusTextAreaOnChatOpen(bool focusTextAreaOnChatOpen);
- SponsoredMess getSponsoredMess() const;
- void setSponsoredMess(SponsoredMess sponsoredMess);
-
bool highlightUnreadConversations() const;
void setHighlightUnreadConversations(bool enable);
+ bool showReactionButton() const;
+ void setShowReactionButton(bool enable);
+
+ SponsoredMess getSponsoredMess() const;
+ void setSponsoredMess(SponsoredMess sponsoredMess);
+
signals:
void sendByEnterChanged();
void focusTextAreaAfterSendChanged();
@@ -147,8 +151,9 @@ signals:
void onlineOnlyModeChanged();
void delayMessageReadChanged();
void focusTextAreaOnChatOpenChanged();
- void sponsoredMessChanged();
void highlightUnreadConversationsChanged();
+ void showReactionButtonChanged();
+ void sponsoredMessChanged();
private:
QSettings settings;
diff --git a/src/chatlistmodel.cpp b/src/chatlistmodel.cpp
index a361c18..7edfcb4 100644
--- a/src/chatlistmodel.cpp
+++ b/src/chatlistmodel.cpp
@@ -91,6 +91,7 @@ public:
QVector updateLastMessage(const QVariantMap &message);
QVector updateGroup(const TDLibWrapper::Group *group);
QVector updateSecretChat(const QVariantMap &secretChatDetails);
+ ChatData* clone();
TDLibWrapper *tdLibWrapper;
public:
@@ -384,6 +385,24 @@ QVector ChatListModel::ChatData::updateSecretChat(const QVariantMap &secret
return changedRoles;
}
+ChatListModel::ChatData* ChatListModel::ChatData::clone() {
+ QVariantMap clonedChatData;
+
+ QList keys = chatData.keys();
+ for(int i = 0; i < keys.count(); i++) {
+ clonedChatData.insert(keys[i], QVariant(chatData[keys[i]]));
+ }
+ ChatData* res = new ChatData(tdLibWrapper, clonedChatData);
+ res->chatId = chatId;
+ res->order = order;
+ res->groupId = groupId;
+ res->verified = verified;
+ res->chatType = chatType;
+ res->memberStatus = memberStatus;
+ res->secretChatState = secretChatState;
+ return res;
+}
+
ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper, AppSettings *appSettings) : showHiddenChats(false)
{
this->tdLibWrapper = tdLibWrapper;
@@ -426,6 +445,15 @@ ChatListModel::~ChatListModel()
qDeleteAll(hiddenChats.values());
}
+ChatListModel* ChatListModel::clone() {
+ ChatListModel* res = new ChatListModel(tdLibWrapper, appSettings);
+ res->relativeTimeRefreshTimer->stop();
+ for(int i = 0; i < chatList.count(); i++) {
+ res->chatList.append(chatList.at(i)->clone());
+ }
+ return res;
+}
+
void ChatListModel::reset()
{
chatList.clear();
diff --git a/src/chatlistmodel.h b/src/chatlistmodel.h
index af875df..f40cd12 100644
--- a/src/chatlistmodel.h
+++ b/src/chatlistmodel.h
@@ -75,6 +75,7 @@ public:
bool showAllChats() const;
void setShowAllChats(bool showAll);
+ ChatListModel* clone();
private slots:
void handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation);
diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp
index 7dad231..2c54827 100644
--- a/src/chatmodel.cpp
+++ b/src/chatmodel.cpp
@@ -472,13 +472,24 @@ QVariantMap ChatModel::getMessage(int index)
return QVariantMap();
}
-int ChatModel::getMessageIndex(qlonglong messageId)
+int ChatModel::getDisplayedMessageIndex(qlonglong messageId)
{
if (messages.size() == 0) {
return -1;
}
if (messageIndexMap.contains(messageId)) {
- return messageIndexMap.value(messageId);
+ int rawIndex = messageIndexMap.value(messageId);
+ // We need to substract number of albums which are shown before this item, because that's the index it's displayed on screen at.
+ int realIndex = rawIndex;
+ for(int i = 0; i < rawIndex; i++) {
+ MessageData *message = messages.at(i);
+ if(message->albumMessageIds.count() > 0) {
+ realIndex -= (message->albumMessageIds.count() - 1);
+ }
+ }
+ if(realIndex < -1)
+ return -1;
+ return realIndex;
}
return -1;
}
diff --git a/src/chatmodel.h b/src/chatmodel.h
index e2e8bbc..07753b7 100644
--- a/src/chatmodel.h
+++ b/src/chatmodel.h
@@ -49,7 +49,7 @@ public:
Q_INVOKABLE int getLastReadMessageIndex();
Q_INVOKABLE void setSearchQuery(const QString newSearchQuery);
- Q_INVOKABLE int getMessageIndex(qlonglong messageId);
+ Q_INVOKABLE int getDisplayedMessageIndex(qlonglong messageId);
QVariantMap smallPhoto() const;
qlonglong getChatId() const;
diff --git a/src/chatpermissionfiltermodel.cpp b/src/chatpermissionfiltermodel.cpp
index cd99678..6a53cf5 100644
--- a/src/chatpermissionfiltermodel.cpp
+++ b/src/chatpermissionfiltermodel.cpp
@@ -33,7 +33,9 @@ ChatPermissionFilterModel::ChatPermissionFilterModel(QObject *parent) : QSortFil
void ChatPermissionFilterModel::setSource(QObject *model)
{
- setSourceModel(qobject_cast(model));
+ ChatListModel* chatListModel = qobject_cast(model);
+ ChatListModel* chatListModelClone = chatListModel->clone();
+ setSourceModel(chatListModelClone);
}
void ChatPermissionFilterModel::setSourceModel(QAbstractItemModel *model)
@@ -45,6 +47,13 @@ void ChatPermissionFilterModel::setSourceModel(QAbstractItemModel *model)
}
}
+ChatPermissionFilterModel::~ChatPermissionFilterModel() {
+ QAbstractItemModel* _sourceModel = sourceModel();
+ if(_sourceModel != nullptr) {
+ delete _sourceModel;
+ }
+}
+
TDLibWrapper *ChatPermissionFilterModel::getTDLibWrapper() const
{
return tdLibWrapper;
diff --git a/src/chatpermissionfiltermodel.h b/src/chatpermissionfiltermodel.h
index d77b3f6..dc4f05b 100644
--- a/src/chatpermissionfiltermodel.h
+++ b/src/chatpermissionfiltermodel.h
@@ -31,7 +31,7 @@ class ChatPermissionFilterModel : public QSortFilterProxyModel
public:
ChatPermissionFilterModel(QObject *parent = Q_NULLPTR);
-
+ ~ChatPermissionFilterModel() override;
TDLibWrapper *getTDLibWrapper() const;
void setTDLibWrapper(QObject* obj);
diff --git a/src/tdlibreceiver.cpp b/src/tdlibreceiver.cpp
index 44034c7..fc6d7bd 100644
--- a/src/tdlibreceiver.cpp
+++ b/src/tdlibreceiver.cpp
@@ -81,6 +81,8 @@ namespace {
const QString TYPE_ANIMATED_EMOJI("animatedEmoji");
const QString TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE("inputMessageReplyToMessage");
const QString TYPE_DRAFT_MESSAGE("draftMessage");
+
+ const double POWERSAVING_TDLIB_REQUEST_INTERVAL = 100;
}
static QString getChatPositionOrder(const QVariantMap &position)
@@ -191,9 +193,15 @@ void TDLibReceiver::setActive(bool active)
} else {
LOG("Deactivating receiver loop, this may take a while...");
}
+ this->powerSavingMode = false;
this->isActive = active;
}
+void TDLibReceiver::setPowerSavingMode(bool powerSavingMode)
+{
+ this->powerSavingMode = powerSavingMode;
+}
+
void TDLibReceiver::receiverLoop()
{
LOG("Starting receiver loop");
@@ -205,6 +213,9 @@ void TDLibReceiver::receiverLoop()
VERBOSE("Raw result:" << receivedJsonDocument.toJson(QJsonDocument::Indented).constData());
processReceivedDocument(receivedJsonDocument);
}
+ if(this->powerSavingMode) {
+ msleep(POWERSAVING_TDLIB_REQUEST_INTERVAL);
+ }
}
LOG("Stopping receiver loop");
}
diff --git a/src/tdlibreceiver.h b/src/tdlibreceiver.h
index 33771b6..b235461 100644
--- a/src/tdlibreceiver.h
+++ b/src/tdlibreceiver.h
@@ -35,6 +35,7 @@ class TDLibReceiver : public QThread
public:
explicit TDLibReceiver(void *tdLibClient, QObject *parent = nullptr);
void setActive(bool active);
+ void setPowerSavingMode(bool active);
signals:
void versionDetected(const QString &version);
@@ -115,6 +116,7 @@ private:
QHash handlers;
void *tdLibClient;
bool isActive;
+ bool powerSavingMode;
private:
static const QVariantList cleanupList(const QVariantList& list, bool *updated = Q_NULLPTR);
diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp
index 4d9d186..4a8b0ce 100644
--- a/src/tdlibwrapper.cpp
+++ b/src/tdlibwrapper.cpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -102,7 +103,7 @@ TDLibWrapper::TDLibWrapper(AppSettings *settings, MceInterface *mce, QObject *pa
connect(this->appSettings, SIGNAL(useOpenWithChanged()), this, SLOT(handleOpenWithChanged()));
connect(this->appSettings, SIGNAL(storageOptimizerChanged()), this, SLOT(handleStorageOptimizerChanged()));
-
+ connect(qGuiApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(handleApplicationStateChanged(Qt::ApplicationState)));
connect(networkConfigurationManager, SIGNAL(configurationChanged(QNetworkConfiguration)), this, SLOT(handleNetworkConfigurationChanged(QNetworkConfiguration)));
this->setLogVerbosityLevel();
@@ -1573,17 +1574,17 @@ QVariantMap TDLibWrapper::getUserInformation()
QVariantMap TDLibWrapper::getUserInformation(const QString &userId)
{
// LOG("Returning user information for ID" << userId);
- return this->allUsers.value(userId).toMap();
+ return this->usersById.value(userId).toMap();
}
bool TDLibWrapper::hasUserInformation(const QString &userId)
{
- return this->allUsers.contains(userId);
+ return this->usersById.contains(userId);
}
QVariantMap TDLibWrapper::getUserInformationByName(const QString &userName)
{
- return this->allUserNames.value(userName).toMap();
+ return this->usersByName.value(userName).toMap();
}
TDLibWrapper::UserPrivacySettingRule TDLibWrapper::getUserPrivacySettingRule(TDLibWrapper::UserPrivacySetting userPrivacySetting)
@@ -1812,8 +1813,8 @@ void TDLibWrapper::handleAuthorizationStateChanged(const QString &authorizationS
LOG("Reloading TD Lib...");
this->basicGroups.clear();
this->superGroups.clear();
- this->allUsers.clear();
- this->allUserNames.clear();
+ this->usersById.clear();
+ this->usersByName.clear();
this->tdLibReceiver->setActive(false);
while (this->tdLibReceiver->isRunning()) {
QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
@@ -1864,18 +1865,17 @@ void TDLibWrapper::handleConnectionStateChanged(const QString &connectionState)
emit connectionStateChanged(this->connectionState);
}
-void TDLibWrapper::handleUserUpdated(const QVariantMap &userInformation)
+void TDLibWrapper::handleUserUpdated(const QVariantMap &updatedUserInformation)
{
- QString updatedUserId = userInformation.value(ID).toString();
+ QString updatedUserId = updatedUserInformation.value(ID).toString();
if (updatedUserId == this->options.value("my_id").toString()) {
LOG("Own user information updated :)");
- this->userInformation = userInformation;
- emit ownUserUpdated(userInformation);
+ this->userInformation = updatedUserInformation;
+ emit ownUserUpdated(updatedUserInformation);
}
- LOG("User information updated:" << userInformation.value(USERNAMES).toMap().value(EDITABLE_USERNAME).toString() << userInformation.value(FIRST_NAME).toString() << userInformation.value(LAST_NAME).toString());
- this->allUsers.insert(updatedUserId, userInformation);
- this->allUserNames.insert(userInformation.value(USERNAMES).toMap().value(EDITABLE_USERNAME).toString(), userInformation);
- emit userUpdated(updatedUserId, userInformation);
+ LOG("User information updated:" << updatedUserInformation.value(USERNAMES).toMap().value(EDITABLE_USERNAME).toString() << updatedUserInformation.value(FIRST_NAME).toString() << updatedUserInformation.value(LAST_NAME).toString());
+ updateUserInformation(updatedUserId, updatedUserInformation);
+ emit userUpdated(updatedUserId, updatedUserInformation);
}
void TDLibWrapper::handleUserStatusUpdated(const QString &userId, const QVariantMap &userStatusInformation)
@@ -1884,14 +1884,22 @@ void TDLibWrapper::handleUserStatusUpdated(const QString &userId, const QVariant
LOG("Own user status information updated :)");
this->userInformation.insert(STATUS, userStatusInformation);
}
+ QVariantMap updatedUserInformation = this->usersById.value(userId).toMap();
+ if(updatedUserInformation[STATUS] == userStatusInformation) {
+ return;
+ }
LOG("User status information updated:" << userId << userStatusInformation.value(_TYPE).toString());
- QVariantMap updatedUserInformation = this->allUsers.value(userId).toMap();
updatedUserInformation.insert(STATUS, userStatusInformation);
- this->allUsers.insert(userId, updatedUserInformation);
- this->allUserNames.insert(userInformation.value(USERNAMES).toMap().value(EDITABLE_USERNAME).toString(), userInformation);
+ updateUserInformation(userId, updatedUserInformation);
emit userUpdated(userId, updatedUserInformation);
}
+void TDLibWrapper::updateUserInformation(const QString &userId, const QVariantMap &userInformation)
+{
+ this->usersById.insert(userId, userInformation);
+ this->usersByName.insert(userInformation.value(USERNAMES).toMap().value(EDITABLE_USERNAME).toString(), userInformation);
+}
+
void TDLibWrapper::handleFileUpdated(const QVariantMap &fileInformation)
{
emit fileUpdated(fileInformation.value(ID).toInt(), fileInformation);
@@ -2204,6 +2212,10 @@ void TDLibWrapper::handleGetPageSourceFinished()
}
}
+void TDLibWrapper::handleApplicationStateChanged(Qt::ApplicationState state) {
+ this->tdLibReceiver->setPowerSavingMode(state != Qt::ApplicationState::ApplicationActive);
+}
+
QVariantMap& TDLibWrapper::fillTdlibParameters(QVariantMap& parameters)
{
parameters.insert("api_id", TDLIB_API_ID);
diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h
index 2487ae5..15fd7e7 100644
--- a/src/tdlibwrapper.h
+++ b/src/tdlibwrapper.h
@@ -348,7 +348,7 @@ public slots:
void handleAuthorizationStateChanged(const QString &authorizationState, const QVariantMap authorizationStateData);
void handleOptionUpdated(const QString &optionName, const QVariant &optionValue);
void handleConnectionStateChanged(const QString &connectionState);
- void handleUserUpdated(const QVariantMap &userInformation);
+ void handleUserUpdated(const QVariantMap &updatedUserInformation);
void handleUserStatusUpdated(const QString &userId, const QVariantMap &userStatusInformation);
void handleFileUpdated(const QVariantMap &fileInformation);
void handleNewChatDiscovered(const QVariantMap &chatInformation);
@@ -373,6 +373,7 @@ public slots:
void handleNetworkConfigurationChanged(const QNetworkConfiguration &config);
void handleActiveEmojiReactionsUpdated(const QStringList& emojis);
void handleGetPageSourceFinished();
+ void handleApplicationStateChanged(Qt::ApplicationState state);
private:
void setOption(const QString &name, const QString &type, const QVariant &value);
@@ -383,6 +384,7 @@ private:
const Group *updateGroup(qlonglong groupId, const QVariantMap &groupInfo, QHash *groups);
QVariantMap newSendMessageRequest(qlonglong chatId, qlonglong replyToMessageId);
void initializeTDLibReceiver();
+ void updateUserInformation(const QString &userId, const QVariantMap &userInformation);
private:
void *tdLibClient;
@@ -399,8 +401,8 @@ private:
QVariantMap options;
QVariantMap userInformation;
QMap userPrivacySettingRules;
- QVariantMap allUsers;
- QVariantMap allUserNames;
+ QVariantMap usersById;
+ QVariantMap usersByName;
QVariantMap chats;
QMap secretChats;
QVariantMap unreadMessageInformation;
diff --git a/translations/harbour-fernschreiber-de.ts b/translations/harbour-fernschreiber-de.ts
index ef14fdf..9712a28 100644
--- a/translations/harbour-fernschreiber-de.ts
+++ b/translations/harbour-fernschreiber-de.ts
@@ -499,6 +499,13 @@
Sie haben noch keine Chats.
+
+ ContactSync
+
+
+ Konnte Ihre Kontakte nicht mit Telegram synchronisieren.
+
+
CoverPage
@@ -901,7 +908,7 @@
dialog header
-
+
%Ln Nachricht weiterleiten
%Ln Nachrichten weiterleiten
diff --git a/translations/harbour-fernschreiber-en.ts b/translations/harbour-fernschreiber-en.ts
index 4f9f525..4251ba4 100644
--- a/translations/harbour-fernschreiber-en.ts
+++ b/translations/harbour-fernschreiber-en.ts
@@ -499,6 +499,13 @@
You don't have any chats yet.
+
+ ContactSync
+
+
+ Could not synchronize your contacts with Telegram.
+
+
CoverPage
@@ -903,7 +910,7 @@ messages
dialog header
-
+
Forward %Ln message
Forward %Ln messages
diff --git a/translations/harbour-fernschreiber-es.ts b/translations/harbour-fernschreiber-es.ts
index 0abb207..3754b0d 100644
--- a/translations/harbour-fernschreiber-es.ts
+++ b/translations/harbour-fernschreiber-es.ts
@@ -499,6 +499,13 @@
No hay charlas.
+
+ ContactSync
+
+
+ No se puede sincronizar los contactos con Telegrama.
+
+
CoverPage
@@ -880,11 +887,11 @@
myself
- envió juego
+ envió un juego
- envió juego
+ envió un juego
@@ -901,7 +908,7 @@
dialog header
-
+
Reenviar %Ln mensaje
Reenviar %Ln mensajes
@@ -1618,26 +1625,6 @@
Al Pulsar mensaje citado, abrirá en Charla en lugar de mostrarlo en una superposición.
-
-
- Agregar vista previa mensaje a notificaciones
-
-
-
- Mostrará cantidad mensajes no leídos, el último mensaje se agregará a notificaciones.
-
-
-
- Resaltar mensajes no leídos
-
-
-
- Resaltar conversaciones a mensajes no leídos
-
-
-
- Ocultar contenido a notificaciones
-
SettingsPage
diff --git a/translations/harbour-fernschreiber-fi.ts b/translations/harbour-fernschreiber-fi.ts
index 691fae8..df31ce8 100644
--- a/translations/harbour-fernschreiber-fi.ts
+++ b/translations/harbour-fernschreiber-fi.ts
@@ -499,6 +499,13 @@
Sinulla ei ole vielä keskusteluja.
+
+ ContactSync
+
+
+ Yhteystietojasi ei voitu synkronoida Telegramin kanssa.
+
+
CoverPage
@@ -902,7 +909,7 @@
dialog header
-
+
Välitä %Ln viesti
Välitä %Ln viestiä
diff --git a/translations/harbour-fernschreiber-fr.ts b/translations/harbour-fernschreiber-fr.ts
index 062a5c0..5cd7743 100644
--- a/translations/harbour-fernschreiber-fr.ts
+++ b/translations/harbour-fernschreiber-fr.ts
@@ -499,6 +499,13 @@
Vous n'avez aucune conversation.
+
+ ContactSync
+
+
+ Impossible de synchroniser vos contacts avec Telegram.
+
+
CoverPage
@@ -901,7 +908,7 @@
dialog header
-
+
Transférer %Ln message
Transférer %Ln messages
@@ -1618,18 +1625,6 @@
-
-
- Mettre en valeur les messages non-lus
-
-
-
- Mettre en valeur les conversations avec des messages non-lus
-
-
-
- Masquer le contenu dans les notifications
-
SettingsPage
diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts
index 67d1bdf..cf66d21 100644
--- a/translations/harbour-fernschreiber-it.ts
+++ b/translations/harbour-fernschreiber-it.ts
@@ -499,6 +499,13 @@
Nessuna chat presente
+
+ ContactSync
+
+
+ Sincronizzazione contatti con Telegram non riuscita
+
+
CoverPage
@@ -901,7 +908,7 @@
dialog header
-
+
Inoltra %Ln messaggio
Inoltra %Ln messaggi
diff --git a/translations/harbour-fernschreiber-pl.ts b/translations/harbour-fernschreiber-pl.ts
index 261f37d..4b8d589 100644
--- a/translations/harbour-fernschreiber-pl.ts
+++ b/translations/harbour-fernschreiber-pl.ts
@@ -509,6 +509,13 @@
Nie masz jeszcze żadnych czatów.
+
+ ContactSync
+
+
+ Nie można zsynchonizaować kontaktów z Telegramem.
+
+
CoverPage
@@ -915,7 +922,7 @@
dialog header
-
+
Przekaż %Ln wiadomość
Przekaż %Ln wiadomości
Przekaż %Ln wiadomości
diff --git a/translations/harbour-fernschreiber-ru.ts b/translations/harbour-fernschreiber-ru.ts
index b6dcd84..6724c98 100644
--- a/translations/harbour-fernschreiber-ru.ts
+++ b/translations/harbour-fernschreiber-ru.ts
@@ -509,6 +509,13 @@
Тут пока ничего нет
+
+ ContactSync
+
+
+ Невозможно синхронизировать ваши контакты с Телеграм.
+
+
CoverPage
@@ -918,7 +925,7 @@
dialog header
-
+
Перенаправить %Ln сообщение
Перенаправить %Ln сообщения
Перенаправить %Ln сообщений
@@ -1649,18 +1656,6 @@
По нажатию на цитируемое сообщение, переходить к нему в чате вместо отображения во всплывающем окне.
-
-
- Выделять непрочитанные сообщения
-
-
-
- Помечать чаты и каналы с непрочитанными сообщениями другим шрифтом и цветом.
-
-
-
- Не показывать содержимое сообщений в уведомлениях
-
SettingsPage
diff --git a/translations/harbour-fernschreiber-sk.ts b/translations/harbour-fernschreiber-sk.ts
index 36ab490..d7105c9 100644
--- a/translations/harbour-fernschreiber-sk.ts
+++ b/translations/harbour-fernschreiber-sk.ts
@@ -509,6 +509,13 @@
Nemáte žiadne čety.
+
+ ContactSync
+
+
+ Nemožno synchonizovať kontakty s Telegramom.
+
+
CoverPage
@@ -915,7 +922,7 @@
dialog header
-
+
Postúpená %Ln správa
Postúpené %Ln správy
Postúpených %Ln správ
diff --git a/translations/harbour-fernschreiber-sv.ts b/translations/harbour-fernschreiber-sv.ts
index 16953c3..4ed22c8 100644
--- a/translations/harbour-fernschreiber-sv.ts
+++ b/translations/harbour-fernschreiber-sv.ts
@@ -499,6 +499,13 @@
Du har inga chattar än.
+
+ ContactSync
+
+
+ Kunde inte synkronisera dina kontakter med Telegram.
+
+
CoverPage
@@ -901,7 +908,7 @@
dialog header
-
+
Vidarebefordra %Ln meddelande
Vidarebefordra %Ln meddelanden
diff --git a/translations/harbour-fernschreiber.ts b/translations/harbour-fernschreiber.ts
index 134628e..ddfce3b 100644
--- a/translations/harbour-fernschreiber.ts
+++ b/translations/harbour-fernschreiber.ts
@@ -499,6 +499,13 @@
You don't have any chats yet.
+
+ ContactSync
+
+
+
+
+
CoverPage
@@ -901,7 +908,7 @@
dialog header
-
+
Forward %Ln message
Forward %Ln messages